Comparing version 0.2.4 to 0.2.5
@@ -0,1 +1,5 @@ | ||
# 0.2.5 | ||
- added `.stats()` API | ||
- fixed bug where `flow.dispose()` was not called on child nodes | ||
- the default node name is now an empty string(rather than the guid) | ||
@@ -15,2 +19,1 @@ # 0.2.0 | ||
- `flow.parented` internal event has been added | ||
@@ -160,2 +160,6 @@ (function(e, a) { for(var i in a) e[i] = a[i]; }(this, /******/ (function(modules) { // webpackBootstrap | ||
var _disposable = __webpack_require__(22); | ||
var _disposable2 = _interopRequireDefault(_disposable); | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } | ||
@@ -167,2 +171,3 @@ | ||
create: _create2['default'], | ||
disposable: _disposable2['default'], | ||
emit: _emit2['default'], | ||
@@ -294,3 +299,3 @@ identify: _identify2['default'], | ||
}, | ||
behaviours: ['identify', 'stateful', 'connect', 'create', 'emit', 'listen', 'cancellable', 'loggable', 'stats'], | ||
behaviours: ['identify', 'stateful', 'connect', 'create', 'disposable', 'emit', 'listen', 'cancellable', 'loggable', 'stats'], | ||
direction: DIRECTION.DEFAULT | ||
@@ -311,3 +316,4 @@ }; | ||
invalidStopPropagationArgs: 'Invalid Argument. The .stopPropagation(direction) API requires either no parameters or a valid flow direction(eg. flow.direction.UPSTREAM)', | ||
invalidRoot: 'Invalid Argument. The .parents.root() API is read only' | ||
invalidRoot: 'Invalid Argument. The .parents.root() API is read only', | ||
invalidStatsArgs: 'Invalid Argument. The .stats() API requires an object' | ||
}; | ||
@@ -387,2 +393,3 @@ | ||
function dispatchInternalEvent(flow, name, newData, oldData) { | ||
if (isIgnored(flow)) return; | ||
var e = (0, _factory2['default'])(_consts.DEFAULTS, "flow." + name); | ||
@@ -410,2 +417,8 @@ e.name.isInternal = true; | ||
function isIgnored(flow) { | ||
return [flow].concat(flow.parents()).some(function (e) { | ||
return e.stats.value.ignore; | ||
}); | ||
} | ||
function replacer() { | ||
@@ -656,2 +669,4 @@ var stack = [], | ||
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; | ||
var _factory = __webpack_require__(2); | ||
@@ -681,2 +696,3 @@ | ||
flow.children.value.push(instance); | ||
inheritStats(instance); | ||
(0, _utils.dispatchInternalEvent)(flow, 'create', instance); | ||
@@ -710,2 +726,11 @@ | ||
}; | ||
function inheritStats(flow) { | ||
var p = flow.parent(); | ||
if (p) { | ||
var defaults = p.stats.value.defaults || {}; | ||
var nodeDefaults = defaults[flow.name.value] || {}; | ||
flow.stats.value = _extends({}, nodeDefaults); | ||
} | ||
} | ||
@@ -1096,3 +1121,3 @@ /***/ }, | ||
}; | ||
flow.name.value = name || flow.guid(); | ||
flow.name.value = name || ''; | ||
flow.name.isFlow = true; | ||
@@ -1364,2 +1389,6 @@ flow.name.isInternal = false; | ||
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; | ||
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol ? "symbol" : typeof obj; }; | ||
var _logger = __webpack_require__(7); | ||
@@ -1377,14 +1406,54 @@ | ||
flow.stats = function () { | ||
(0, _utils.assert)(arguments.length, _consts.ERRORS.invalidStatsArgs); | ||
flow.stats = function (d) { | ||
if (d === undefined) return flow.stats.value; | ||
(0, _utils.assert)((typeof d === 'undefined' ? 'undefined' : _typeof(d)) !== 'object', _consts.ERRORS.invalidStatsArgs); | ||
flow.stats.value = _extends({}, flow.stats.value, d); | ||
return flow; | ||
}; | ||
return flow.stats.value; | ||
flow.stats.value = { | ||
ignore: false, // do not track this node | ||
collapsed: false | ||
}; | ||
flow.stats.value = {}; | ||
flow.version = ("0.2.4"); | ||
flow.version = ("0.2.5"); | ||
}; | ||
/***/ }, | ||
/* 22 */ | ||
/***/ function(module, exports, __webpack_require__) { | ||
'use strict'; | ||
Object.defineProperty(exports, "__esModule", { | ||
value: true | ||
}); | ||
var _utils = __webpack_require__(6); | ||
var _consts = __webpack_require__(5); | ||
exports['default'] = function (flow, defaults) { | ||
flow.dispose = function () { | ||
(0, _utils.assert)(arguments.length, _consts.ERRORS.invalidDisposeArgs); | ||
if (flow.dispose.value == true) return; | ||
//recursively(depth first) dispose all downstream nodes | ||
flow.children().forEach(function (f) { | ||
return f.dispose(); | ||
}); | ||
(0, _utils.dispatchInternalEvent)(flow, 'dispose', true); | ||
flow.parent(null); | ||
flow.dispose.value = true; | ||
flow.on.listenerMap = {}; | ||
return flow; | ||
}; | ||
flow.dispose.value = false; | ||
}; | ||
/***/ } | ||
/******/ ]))); | ||
//# sourceMappingURL=nflow.js.map |
{ | ||
"name": "nflow", | ||
"version": "0.2.4", | ||
"version": "0.2.5", | ||
"description": "event/data/control flow", | ||
@@ -5,0 +5,0 @@ "main": "dist/nflow.js", |
@@ -1,5 +0,5 @@ | ||
<img height=80 src="http://nflow-js.github.io/assets/logo.svg"> | ||
# nFlow JS | ||
<img height=80 align="left" src="http://nflow-js.github.io/assets/logo.svg"> | ||
# nflow JS | ||
Event/data/control flow | ||
@@ -9,23 +9,21 @@ | ||
> Work in progress, decent docs and examples are on the way | ||
http://nflow-js.github.io | ||
### What is it? | ||
// TODO | ||
nflow is a hierarchical event dispatcher for managing you application's event/data/control flow. | ||
For docs and examples visit: http://nflow-js.github.io | ||
### Installation | ||
// TODO | ||
`npm i nflow --save` | ||
### | ||
### How to develop | ||
nFlow uses a single build script that compiles the code and the tests, creates a dev server and watches all source files for changes. | ||
nFlow uses webpack to compile the code, run the tests and run a local dev server: | ||
Clone this repo and run: | ||
- `npm start` | ||
- navigate to `http://localhost:4000/webpack-dev-server/` | ||
- `npm start` | ||
- navigate to `http://localhost:5000/webpack-dev-server/` to run the tests in the browser | ||
@@ -32,0 +30,0 @@ ### Unit tests |
@@ -17,2 +17,3 @@ import factory from '../factory' | ||
flow.children.value.push(instance) | ||
inheritStats(instance) | ||
dispatchInternalEvent(flow, 'create', instance) | ||
@@ -33,3 +34,3 @@ | ||
if (flow.dispose.value == true) return; | ||
dispatchInternalEvent(flow, 'dispose', true) | ||
@@ -39,3 +40,3 @@ flow.parent(null) | ||
flow.on.listenerMap = {} | ||
//recursively dispose all downstream nodes | ||
@@ -46,4 +47,11 @@ flow.children().forEach(f=>f.dispose()) | ||
flow.dispose.value = false | ||
} | ||
} | ||
function inheritStats(flow){ | ||
let p = flow.parent() | ||
if (p) { | ||
let defaults = p.stats.value.defaults||{} | ||
let nodeDefaults = defaults[flow.name.value]||{} | ||
flow.stats.value = {...nodeDefaults} | ||
} | ||
} |
@@ -12,3 +12,3 @@ import { DEFAULTS | ||
export default (flow, defaults, name)=>{ | ||
flow.guid = (...args) => { | ||
@@ -30,3 +30,3 @@ assert(args.length | ||
} | ||
flow.name.value = name || flow.guid() | ||
flow.name.value = name || '' | ||
flow.name.isFlow = true | ||
@@ -33,0 +33,0 @@ flow.name.isInternal = false |
@@ -12,2 +12,3 @@ | ||
import stats from './stats' | ||
import disposable from './disposable' | ||
@@ -18,2 +19,3 @@ export default { | ||
create, | ||
disposable, | ||
emit, | ||
@@ -27,2 +29,1 @@ identify, | ||
} | ||
@@ -5,3 +5,2 @@ import logger from '../logger' | ||
, ERRORS | ||
, STATUS | ||
, DIRECTION | ||
@@ -13,10 +12,13 @@ , UNSET } from '../consts' | ||
flow.stats = (...args) => { | ||
assert(args.length | ||
flow.stats = (d) => { | ||
if (d===undefined) return flow.stats.value | ||
assert(typeof(d)!=='object' | ||
, ERRORS.invalidStatsArgs) | ||
return flow.stats.value | ||
flow.stats.value = {...flow.stats.value, ...d} | ||
return flow | ||
} | ||
flow.stats.value = { | ||
ignore: false, // do not track this node | ||
collapsed: false | ||
} | ||
@@ -27,2 +29,2 @@ | ||
} | ||
} |
@@ -38,2 +38,3 @@ /** | ||
'create', | ||
'disposable', | ||
'emit', | ||
@@ -61,2 +62,3 @@ 'listen', | ||
, invalidRoot:'Invalid Argument. The .parents.root() API is read only' | ||
, invalidStatsArgs:'Invalid Argument. The .stats() API requires an object' | ||
} |
@@ -22,3 +22,3 @@ import factory from './factory' | ||
export function isFlow(flow){ | ||
return flow | ||
return flow | ||
&& flow.name | ||
@@ -29,3 +29,3 @@ && flow.name.isFlow | ||
export function isInternal(flow){ | ||
return flow | ||
return flow | ||
&& flow.name | ||
@@ -36,3 +36,3 @@ && flow.name.isInternal | ||
export function detach(flow){ | ||
flow.parent() | ||
flow.parent() | ||
&& flow.parent().children.detach(flow) | ||
@@ -57,2 +57,3 @@ } | ||
export function dispatchInternalEvent(flow, name, newData, oldData){ | ||
if (isIgnored(flow)) return | ||
var e= factory(DEFAULTS, "flow."+name) | ||
@@ -68,7 +69,7 @@ e.name.isInternal = true | ||
e.emit() | ||
e.direction.value= DIRECTION.DOWNSTREAM | ||
e.name.value="flow.parent."+name | ||
e.emit() | ||
logger.log(flow, name, newData, oldData) | ||
@@ -79,2 +80,8 @@ } | ||
function isIgnored(flow){ | ||
return [flow] | ||
.concat(flow.parents()) | ||
.some(e=>e.stats.value.ignore) | ||
} | ||
function replacer() { | ||
@@ -109,2 +116,2 @@ let stack = [] | ||
}; | ||
} | ||
} |
@@ -7,3 +7,3 @@ import flow from 'nflow' | ||
describe('Construction', function(){ | ||
beforeEach(function(){ | ||
@@ -17,4 +17,4 @@ testFlow = flow | ||
it('should create unique guids', function(){ | ||
var sut1 = testFlow.create() | ||
var sut2 = testFlow.create() | ||
var sut1 = testFlow.create() | ||
var sut2 = testFlow.create() | ||
expect(sut1.guid()).to.not.equal(sut2.guid()) | ||
@@ -26,3 +26,3 @@ }) | ||
it('should store name', function(){ | ||
var sut = testFlow.create('test') | ||
var sut = testFlow.create('test') | ||
expect(sut.name()).to.equal('test') | ||
@@ -34,3 +34,3 @@ }) | ||
it('should have globally unique ID-s', function(){ | ||
var sut1 = testFlow.create('test') | ||
var sut1 = testFlow.create('test') | ||
var sut2 = testFlow.create('test') | ||
@@ -82,6 +82,18 @@ console.log(sut1.guid()) | ||
}) | ||
sut1.emit('foo') | ||
assert.ok(sut1) | ||
}) | ||
it('should emit flow.dispose events on all disposed child nodes', function(){ | ||
var sut1 = testFlow.create() | ||
var child1 = sut1.create().on('flow.dispose', d=>child1.disposed=true) | ||
var child2 = sut1.create().on('flow.dispose', d=>child2.disposed=true) | ||
var child3 = child2.create().on('flow.dispose', d=>child3.disposed=true) | ||
sut1.dispose() | ||
expect(child1.disposed).to.be.true | ||
expect(child2.disposed).to.be.true | ||
expect(child3.disposed).to.be.true | ||
}) | ||
}) | ||
@@ -104,3 +116,3 @@ | ||
expect(sut.data()).to.equal(0) | ||
var sut = testFlow.create('test', false) | ||
@@ -107,0 +119,0 @@ expect(sut.data()).to.equal(false) |
@@ -15,3 +15,3 @@ import flow from 'nflow' | ||
}) | ||
describe('Flow Logging', ()=>{ | ||
@@ -27,3 +27,3 @@ | ||
}) | ||
it('Should use global logger', (done)=>{ | ||
@@ -52,3 +52,3 @@ var test = sut.create("test") | ||
.on('bar',()=>{},function namedFunction(){}) | ||
expect(sut.toObj()).to.have.deep.property('listeners.foo'); | ||
@@ -68,3 +68,3 @@ expect(sut.toObj()).to.have.deep.property('listeners.bar'); | ||
describe('Remote Logger API', ()=>{ | ||
it('Should use remote logger', (done)=>{ | ||
@@ -75,3 +75,2 @@ var test = sut.create("test") | ||
test.done = true | ||
console.log(log) | ||
expect(log.flow.guid).to.eql(test.guid()) | ||
@@ -124,2 +123,24 @@ done() | ||
}) | ||
it('Should not log ignored nodes', ()=>{ | ||
var test = sut.create("test") | ||
.stats({ignore:true}) | ||
flow.logger(log=>{ | ||
assert.fail('should not log ignored nodes') | ||
},true) | ||
test.name('bar') | ||
}) | ||
it('Should not log children of ignored nodes', ()=>{ | ||
var test = sut.create("test") | ||
.stats({ignore:true}) | ||
.create('test1') | ||
flow.logger(log=>{ | ||
assert.fail('should not log ignored nodes') | ||
},true) | ||
test.name('bar') | ||
}) | ||
it('Should log .data(x) API', (done)=>{ | ||
@@ -157,3 +178,3 @@ var test = sut.create("test", "foo") | ||
}) | ||
it('Should log reparenting (.parent(node))', (done)=>{ | ||
@@ -174,3 +195,3 @@ var test = sut.create("test", "foo") | ||
flow.logger(log=>{ | ||
expect(log.action).to.equal('emit') | ||
@@ -196,3 +217,3 @@ expect(log.flow.name).to.equal('sut') | ||
}) | ||
it('Should log .emitted("foo") API', (done)=>{ | ||
@@ -283,3 +304,3 @@ var test = sut.create("test") | ||
o.bar = o.foo | ||
test.data(o) | ||
@@ -318,2 +339,2 @@ }) | ||
}) | ||
}) | ||
}) |
@@ -10,1 +10,2 @@ import './spec/propagation.js' | ||
import './spec/routes.js' | ||
import './spec/stats.js' |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
2611572
53
26149
35