npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

babel-plugin-cycle-circular

v0.1.0

Published

Babel plugin allowing to have circular dependencies in cycle.js functions.

Downloads

16

Readme

babel-plugin-cycle-circular

Babel plugin allowing to have circular dependencies with cycle.js

What?

This (note that bar is used before declared in the code):

  const foo = Foo({value$: bar.value$, DOM})
  const bar = Bar({HTTP, prop$: foo.prop$})

will just work.

This is experimented feature - try and see if it fits your needs, if something wrong or it doesn't cover you usage scenarios just create an issue and we'll try to fix it.

How does it work

This is your ES6 source:

import {ComponentFoo} from './ComponentFoo'
import {ComponentBar} from './ComponentBar'

const main = ({DOM, HTTP}) => {

  const componentFoo = ComponentFoo({value$: componentBar.value$, DOM})
  const componentBar = ComponentBar({HTTP, componentFoo.prop$})

  return {
    DOM: componentFoo.DOM,
    HTTP: componentBar.HTTP
  }
}

To get the same result without this plugin you may sacrifice functional style and do the following with your hands:

// import subject which is usually not needed
import {Subject} from 'rx'
import {ComponentFoo} from './ComponentFoo'
import {ComponentBar} from './ComponentBar'

const main = ({DOM, HTTP}) => {
  // declare proxy subject which will be used to subscribe 
  // to target stream, and be a source for consumption
  const valueProxy$ = new Subject()
  // make proxy stream safe - when it ends (or terminates) 
  // remove subscription to prevent memory leak 
  const valueSafeProxy$ = valueProxy$.finally(() => {
    valueProxySub.dispose()
  })

  const componentFoo = ComponentFoo({valueSafeProxy$, DOM})
  const componentBar = ComponentBar({HTTP, componentFoo.prop$})

  // create subscription for target stream 
  // subscription is actually `side effect`   
  const valueProxySub = componentBar.value$.subscribe(valueProxy$)

  return {
    DOM: componentFoo.DOM,
    HTTP: componentBar.HTTP
  }
}

This also work for most.js library, as if you write this:

import {subject} from 'most-subject'
import {ComponentFoo} from './ComponentFoo'
import {ComponentBar} from './ComponentBar'

const main = ({DOM, HTTP}) => {

  const proxy = subject()

  const componentFoo = ComponentFoo({proxy.stream, DOM})
  const componentBar = ComponentBar({HTTP, componentFoo.prop$})

  const valueProxySub = componentBar.value$
     .observe(proxy.observer.next)
     .then(proxy.observer.complete)
     .catch(proxy.observer.error)

  return {
    DOM: componentFoo.DOM,
    HTTP: componentBar.HTTP
  }
}

Usage

npm install babel-plugin-cycle-circular

Just add plugin to to your .babelrc file or transform options:

{
  "presets": ["es2015"],
  "plugins": ["cycle-circular"]
}

Conventions

NB! Works with rxjs v4, rxjs v5 and most.js ES6 sources. If you want to use CJS source you should require Subject manually.

Options

There are some options that you can supply to the plugin:

  • lib (default: 'rx') - what library rules to use for creating proxies, possilbe values: "rx", "rxjs", "most".
  • identifiers (default: null) - regExp pattern(s) for matching identifiers names that should be proxied.
  • include (default: '') - includes files my minimatch mask (can be array)
  • exclude (default: '') - includes files my minimatch mask (can be array)

Options example: This options for plugin will exclude from processing all files in models/ folder and will proxy only if last identifier of reference ends with $ for example component.value$, (references like component.value won't be handled)

{
  "presets": ["es2015"],
  "plugins": [
    ["cycle-circular", {
        "lib": "rxjs",
        "identifiers": ["\\$$"],
        "exlude": ["**/models/**"]  
    }]
  ]
}

Is it safe to use?

Technically, it just traverse (scans) each function during babel transpilation of your code to find variable references that go before declaration and applies proxy via subject . It was said that the plugin is experimental so if something goes wrong you should see it during development.

Tests

Tests checks if actual transformed source from fixtures corresponds to fixed transformed version in the same fixtures/{case} folder.

npm run test