New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

babel-plugin-cycle-circular

Package Overview
Dependencies
Maintainers
1
Versions
2
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

babel-plugin-cycle-circular - npm Package Compare versions

Comparing version

to
0.1.0

lib/most.js

4

HISTORY.md

@@ -0,1 +1,5 @@

### v0.1.0 Imports insertion and rxjs/most support
* imports of `Subject` object are added if not found
* added initial most.js and rxjs5 support
### v0.0.1 Initial pre-release

@@ -2,0 +6,0 @@ * only rx@4.x.x

123

lib/index.js

@@ -7,8 +7,6 @@ 'use strict';

exports.default = function (_ref2) {
var t = _ref2.types;
exports.default = function (_ref) {
var t = _ref.types;
var makeVisitor = function makeVisitor(scope, options) {
var subjectLiteral = getSubjectLiteral(scope, options);
var subjectIdentifier = t.identifier(subjectLiteral);
var makeVisitor = function makeVisitor(scope, options, lib) {

@@ -30,34 +28,8 @@ var matchIdentifiers = toArray(options.identifiers).map(function (match) {

var getSubFinallyExpression = function getSubFinallyExpression(proxyIdentifier, subIdentifier) {
var disposeExpression = t.callExpression(t.memberExpression(subIdentifier, t.identifier('dispose')), []);
return t.callExpression(t.memberExpression(proxyIdentifier, t.identifier('finally')), [t.arrowFunctionExpression([], disposeExpression)]);
};
var makeProxy = function makeProxy(toProxy) {
var idName = toProxy.name + '__Proxy';
var identifier = t.identifier(idName);
var newExpression = t.newExpression(subjectIdentifier, []);
var declaration = t.variableDeclaration('const', [t.variableDeclarator(identifier, newExpression)]);
var originIdentifier = t.identifier(toProxy.source + '.subscribe');
var subscriberIdentifier = t.identifier(idName + '.asObserver()');
var subCallExpression = t.callExpression(originIdentifier, [subscriberIdentifier]);
var subIdentifier = t.identifier(toProxy.name + '__ProxySub');
var subscription = t.variableDeclaration('const', [t.variableDeclarator(subIdentifier, subCallExpression)]);
mainScope._hasCircularProxies = true;
return {
identifier: identifier,
declaration: declaration, subscription: subscription,
finally: getSubFinallyExpression(identifier, subIdentifier)
};
};
return {
ReferencedIdentifier: function ReferencedIdentifier(path) {
if (!checkScope(path.scope)) return;
if (!checkScopeIsFunction(path.scope)) return;
var _circular = getScopeCircular(path.scope);
var name = path.node.name;
var name = '__' + path.node.name;

@@ -71,8 +43,9 @@ if (_circular.declarations[name]) {

VariableDeclaration: function VariableDeclaration(path) {
if (!checkScope(path.scope)) return;
if (!checkScopeIsFunction(path.scope)) return;
var _circular = getScopeCircular(path.scope);
var body = path.scope.block.body.body;
path.node.declarations.forEach(function (dec) {
var identifier = _circular.identifiers[dec.id.name];
var identifier = _circular.identifiers['__' + dec.id.name];
if (identifier) {

@@ -82,15 +55,10 @@ identifier.paths.forEach(function (path) {

var proxyName = identifierToProxy.name;
if (!matchIdentifierName(proxyName)) {
if (!matchIdentifierName(identifierToProxy.source)) {
return;
}
var proxyName = '__Proxy' + _circular.proxiesCount;
var proxy = lib.makeProxy(proxyName, identifierToProxy.source);
var proxyIndex = _circular.proxies[proxyName] || 0;
identifierToProxy.name += '_' + proxyIndex;
var proxy = makeProxy(identifierToProxy);
body.unshift(proxy.declaration);
identifierToProxy.path.replaceWith(proxy.finally);
identifierToProxy.path.replaceWith(proxy.replaceWith);

@@ -101,3 +69,4 @@ var ret = body[body.length - 1].type == 'ReturnStatement' ? body.pop() : null;

_circular.proxies[proxyName] = proxyIndex + 1;
_circular.proxiesCount++;
mainScope._hasCircularProxies = true;
});

@@ -113,4 +82,3 @@ }

visitor: {
Program: function Program(path) {
Program: function Program(path, state) {
var scope = path.context.scope;

@@ -130,4 +98,10 @@ var options = this.opts;

if (canMakeCircular(scope, options)) {
path.traverse(makeVisitor(scope, options));
var lib = void 0,
libName = options.lib || 'rx';
lib = require('./' + libName);
path.traverse(makeVisitor(scope, options, lib));
if (scope._hasCircularProxies) {
lib.addImports(path.node, scope);
}

@@ -145,8 +119,11 @@ }

var getIdentifierNameFromNode = function getIdentifierNameFromNode(node) {
if (node.name || node.value) {
return node.name || 'V' + node.value;
} else {
return getIdentifierNameFromNode(node.object) + '_' + getIdentifierNameFromNode(node.property);
var getIdentifierFromPath = function getIdentifierFromPath(path) {
while (path.parentPath.type == 'MemberExpression') {
path = path.parentPath;
}
var node = path.node;
return {
source: path.getSource(),
path: path
};
};

@@ -164,16 +141,3 @@

var getIdentifierFromPath = function getIdentifierFromPath(path) {
// path.parentPath.node.type === 'Identifier'
while (path.parentPath.type == 'MemberExpression') {
path = path.parentPath;
}
var node = path.node;
return {
source: path.getSource(),
name: getIdentifierNameFromNode(node),
path: path
};
};
var checkScope = function checkScope(scope) {
var checkScopeIsFunction = function checkScopeIsFunction(scope) {
// FunctionDeclaration

@@ -192,25 +156,6 @@ // ArrowFunctionExpression

declarations: {},
proxies: {}
proxies: {},
proxiesCount: 0
};
return scope._cycleCircular;
};
var getSubjectLiteral = function getSubjectLiteral(_ref, options) {
var globals = _ref.globals;
var references = _ref.references;
if (references.Subject) {
return 'Subject';
} else {
var rxRef = checkItems([options.rxRef, 'Rx', 'rx'], function (prop) {
return (references[prop] || globals[prop]) && prop;
});
if (rxRef) {
return rxRef + '.Subject';
}
}
};
var canMakeCircular = function canMakeCircular(scope, options) {
return getSubjectLiteral(scope, options);
};
{
"name": "babel-plugin-cycle-circular",
"version": "0.0.1",
"version": "0.1.0",
"description": "Babel plugin allowing to have circular dependencies in cycle.js functions.",

@@ -5,0 +5,0 @@ "main": "lib/index.js",

@@ -7,7 +7,7 @@ # babel-plugin-cycle-circular

This (note that `componentBar` is *used* **before** *declared*):
This (note that **`bar`** is **used before declared** in the code):
```js
const componentFoo = ComponentFoo({value$: componentBar.value$, DOM})
const componentBar = ComponentBar({HTTP, componentFoo.prop$})
const foo = Foo({value$: bar.value$, DOM})
const bar = Bar({HTTP, prop$: foo.prop$})
```

@@ -17,4 +17,7 @@

## How does it
**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](issues) and we'll try to fix it.
## How does it work
This is your ES6 source:

@@ -72,6 +75,31 @@

This also work for [`most.js`](https://github.com/cujojs/most) library, as if you write this:
```js
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
```bash
npm install bable-plugin-cycle-circular
npm install babel-plugin-cycle-circular
```

@@ -90,10 +118,5 @@

*NB!*
Current version works only with `rx@4.x.x` requires that you have `Subject`, or `Rx` **imported**:
```js
import {Subject} from 'rx'
```
or
```js
const Rx = require('rx')
```
Works with [`rxjs v4`](https://github.com/Reactive-Extensions/RxJS),
[`rxjs v5`](https://github.com/ReactiveX/rxjs) and [`most.js`](https://github.com/cujojs/most) ES6 sources.
If you want to use CJS source you should `require` `Subject` manually.

@@ -103,3 +126,4 @@ ### Options

There are some options that you can supply to the plugin:
* **identifiers** (default: null) - regExp pattern(s) for matching identifiers names that should be proxied.
* **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)

@@ -117,2 +141,3 @@ * **exclude** (default: '') - includes files my `minimatch` mask (can be array)

["cycle-circular", {
"lib": "rxjs",
"identifiers": ["\\$$"],

@@ -125,2 +150,8 @@ "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

@@ -127,0 +158,0 @@ Tests checks if actual transformed source from `fixtures`

import minimatch from 'minimatch'
const getIdentifierNameFromNode = (node) => {
if (node.name || node.value){
return node.name || ('V' + node.value)
const getIdentifierFromPath = (path) => {
while (path.parentPath.type == 'MemberExpression') {
path = path.parentPath
}
else {
return getIdentifierNameFromNode(node.object)
+ '_' + getIdentifierNameFromNode(node.property)
var node = path.node
return {
source: path.getSource(),
path
}

@@ -22,16 +23,3 @@ }

const getIdentifierFromPath = (path) => {
// path.parentPath.node.type === 'Identifier'
while (path.parentPath.type == 'MemberExpression') {
path = path.parentPath
}
var node = path.node
return {
source: path.getSource(),
name: getIdentifierNameFromNode(node),
path
}
}
const checkScope = (scope) => {
const checkScopeIsFunction = (scope) => {
// FunctionDeclaration

@@ -49,3 +37,4 @@ // ArrowFunctionExpression

declarations: {},
proxies: {}
proxies: {},
proxiesCount: 0
}

@@ -55,24 +44,5 @@ return scope._cycleCircular

const getSubjectLiteral = ({globals, references}, options) => {
if (references.Subject){
return 'Subject'
} else {
const rxRef = checkItems([options.rxRef, 'Rx', 'rx'],
(prop) => ((references[prop] || globals[prop]) && prop)
)
if (rxRef){
return rxRef + '.Subject'
}
}
}
const canMakeCircular = (scope, options) => {
return getSubjectLiteral(scope, options)
}
export default function ({types: t}) {
const makeVisitor = (scope, options) => {
let subjectLiteral = getSubjectLiteral(scope, options)
let subjectIdentifier = t.identifier(subjectLiteral)
const makeVisitor = (scope, options, lib) => {
let matchIdentifiers = toArray(options.identifiers)

@@ -91,45 +61,9 @@ .map(match => new RegExp(match))

}
const getSubFinallyExpression = function(proxyIdentifier, subIdentifier){
const disposeExpression = t.callExpression(
t.memberExpression(subIdentifier, t.identifier('dispose')),
[]
)
return t.callExpression(
t.memberExpression(proxyIdentifier, t.identifier('finally')),
[t.arrowFunctionExpression([], disposeExpression)]
)
}
const makeProxy = (toProxy) => {
let idName = toProxy.name + '__Proxy'
let identifier = t.identifier(idName)
let newExpression = t.newExpression(subjectIdentifier, [])
let declaration = t.variableDeclaration('const', [
t.variableDeclarator(identifier, newExpression)
])
let originIdentifier = t.identifier(toProxy.source + '.subscribe')
let subscriberIdentifier = t.identifier(idName + '.asObserver()')
let subCallExpression = t.callExpression(originIdentifier, [subscriberIdentifier])
let subIdentifier = t.identifier(toProxy.name + '__ProxySub')
let subscription = t.variableDeclaration('const', [
t.variableDeclarator(subIdentifier, subCallExpression)
])
mainScope._hasCircularProxies = true
return {
identifier,
declaration, subscription,
finally: getSubFinallyExpression(identifier, subIdentifier)
}
}
return {
ReferencedIdentifier (path) {
if (!checkScope(path.scope)) return
if (!checkScopeIsFunction(path.scope)) return
let _circular = getScopeCircular(path.scope)
let name = path.node.name
let name = '__' + path.node.name

@@ -144,26 +78,21 @@ if (_circular.declarations[name]){

VariableDeclaration (path) {
if (!checkScope(path.scope)) return
if (!checkScopeIsFunction(path.scope)) return
let _circular = getScopeCircular(path.scope)
var body = path.scope.block.body.body
path.node.declarations.forEach(dec => {
let identifier = _circular.identifiers[dec.id.name]
let identifier = _circular.identifiers['__' + dec.id.name]
if (identifier){
identifier.paths.forEach((path) => {
var identifierToProxy = getIdentifierFromPath(path)
let proxyName = identifierToProxy.name
if (!matchIdentifierName(proxyName)){
if (!matchIdentifierName(identifierToProxy.source)){
return
}
let proxyIndex =
(_circular.proxies[proxyName] || 0)
identifierToProxy.name += '_' + proxyIndex
let proxy = makeProxy(identifierToProxy)
let proxyName = '__Proxy' + _circular.proxiesCount
let proxy = lib.makeProxy(proxyName, identifierToProxy.source)
body.unshift(proxy.declaration)
identifierToProxy.path.replaceWith(proxy.finally)
identifierToProxy.path.replaceWith(proxy.replaceWith)

@@ -175,3 +104,4 @@ let ret = body[body.length - 1].type == 'ReturnStatement'

_circular.proxies[proxyName] = proxyIndex + 1
_circular.proxiesCount++
mainScope._hasCircularProxies = true
})

@@ -187,8 +117,7 @@ }

visitor: {
Program (path) {
Program (path, state) {
const scope = path.context.scope
const options = this.opts
const filename = this.file.opts.filename
const filterFiles = options.include || options.exclude

@@ -204,4 +133,9 @@ if (filterFiles){

if (canMakeCircular(scope, options)){
path.traverse(makeVisitor(scope, options))
let lib, libName = options.lib || 'rx'
lib = require('./' + libName)
path.traverse(makeVisitor(scope, options, lib))
if (scope._hasCircularProxies){
lib.addImports(path.node, scope)
}

@@ -208,0 +142,0 @@ }

Sorry, the diff of this file is not supported yet