Comparing version 0.2.1 to 0.2.2
@@ -156,2 +156,6 @@ (function(e, a) { for(var i in a) e[i] = a[i]; }(this, /******/ (function(modules) { // webpackBootstrap | ||
var _stats = __webpack_require__(21); | ||
var _stats2 = _interopRequireDefault(_stats); | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } | ||
@@ -168,3 +172,4 @@ | ||
stateful: _stateful2['default'], | ||
get: _get2['default'] | ||
get: _get2['default'], | ||
stats: _stats2['default'] | ||
}; | ||
@@ -190,10 +195,12 @@ | ||
(0, _utils.assert)(arguments.length, _consts.ERRORS.invalidCancelArgs); | ||
flow.status.value = _consts.STATUS.CANCELLED; | ||
(0, _utils.dispatchInternalEvent)(flow, 'cancel', true); | ||
var previousValue = flow.cancel.value; | ||
flow.cancel.value = true; | ||
(0, _utils.dispatchInternalEvent)(flow, 'cancel', true, previousValue); | ||
return flow; | ||
}; | ||
flow.cancel.value = false; | ||
flow.isCancelled = function () { | ||
return [flow].concat(flow.parents()).some(function (e) { | ||
return e.status.value == _consts.STATUS.CANCELLED || e.status.value == _consts.STATUS.DISPOSED; | ||
return e.status() == _consts.STATUS.CANCELLED || e.status() == _consts.STATUS.DISPOSED; | ||
}); | ||
@@ -203,12 +210,43 @@ }; | ||
flow.stopPropagation = function () { | ||
(0, _utils.assert)(arguments.length, _consts.ERRORS.invalidStopPropagationArgs); | ||
flow.status.value = _consts.STATUS.STOPPED; | ||
(0, _utils.dispatchInternalEvent)(flow, 'propagationStopped', true); | ||
var direction = arguments.length <= 0 || arguments[0] === undefined ? _consts.UNSET : arguments[0]; | ||
direction !== _consts.UNSET && (0, _utils.assert)(!_consts.DIRECTION[direction.toUpperCase()], _consts.ERRORS.invalidStopPropagationArgs); | ||
if (direction == _consts.UNSET) { | ||
flow.status.value = _consts.STATUS.STOPPED; | ||
flow.stopPropagation.value = true; | ||
flow.stopPropagation.modifiers[flow.target.guid] = -1; //bitmask fill | ||
(0, _utils.dispatchInternalEvent)(flow, 'propagationStopped', true); | ||
} else { | ||
var d = _consts.DIRECTION[direction.toUpperCase()]; | ||
(0, _utils.dispatchInternalEvent)(flow, 'propagationAugmented', { | ||
direction: d, | ||
target: flow.target.toObj('name', 'guid') | ||
}); | ||
flow.stopPropagation.modifiers[flow.target.guid.value] |= _consts.DIRECTION_BITMASK[d]; | ||
} | ||
return flow; | ||
}; | ||
flow.stopPropagation.value = false; | ||
flow.stopPropagation.modifiers = {}; | ||
createStopPropagationModifiers(flow); | ||
flow.propagationStopped = function () { | ||
return flow.status.value == _consts.STATUS.STOPPED; | ||
return flow.stopPropagation.value; | ||
}; | ||
}; | ||
/** | ||
* create directional (eg. `flow.stopPropagation.dowsntream(...)`) API | ||
*/ | ||
function createStopPropagationModifiers(flow) { | ||
Object.keys(_consts.DIRECTION).forEach(function (direction) { | ||
flow.stopPropagation[direction] = flow.stopPropagation[direction.toLowerCase()] = function () { | ||
return flow.stopPropagation(direction); | ||
}; | ||
}); | ||
} | ||
@@ -230,3 +268,4 @@ /***/ }, | ||
var DIRECTION = exports.DIRECTION = { | ||
NONE: "NONE", | ||
CURRENT: "CURRENT", | ||
NONE: "CURRENT", // deprecated | ||
DEFAULT: "DEFAULT", | ||
@@ -237,2 +276,10 @@ UPSTREAM: "UPSTREAM", | ||
var DIRECTION_BITMASK = exports.DIRECTION_BITMASK = { | ||
CURRENT: 1 << 0, | ||
NONE: 1 << 0, // deprecated | ||
DEFAULT: 1 << 1, | ||
UPSTREAM: 1 << 2, | ||
DOWNSTREAM: 1 << 3 | ||
}; | ||
var STATUS = exports.STATUS = { | ||
@@ -251,3 +298,3 @@ IDLE: "IDLE", | ||
}, | ||
behaviours: ['identify', 'stateful', 'connect', 'create', 'emit', 'listen', 'cancellable', 'loggable'], | ||
behaviours: ['identify', 'stateful', 'connect', 'create', 'emit', 'listen', 'cancellable', 'loggable', 'stats'], | ||
direction: DIRECTION.DEFAULT | ||
@@ -267,3 +314,3 @@ }; | ||
invalidCancelArgs: 'Invalid Argument. The .cancel() API requires no parameters', | ||
invalidStopPropagationArgs: 'Invalid Argument. The .stopPropagation() API requires no parameters', | ||
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' | ||
@@ -281,2 +328,6 @@ }; | ||
}); | ||
exports.serialise = undefined; | ||
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; }; | ||
exports.assert = assert; | ||
@@ -303,2 +354,3 @@ exports.isFlow = isFlow; | ||
var RECURSION_LIMIT = 1024; | ||
/** | ||
@@ -344,3 +396,3 @@ * utils | ||
e.data.value = [newData, oldData]; | ||
e.direction.value = _consts.DIRECTION.NONE; | ||
e.direction.value = _consts.DIRECTION.CURRENT; | ||
e.parent.value = flow; | ||
@@ -359,2 +411,31 @@ e.emit(); | ||
} | ||
var serialise = exports.serialise = function serialise(o) { | ||
return JSON.stringify(o, replacer()); | ||
}; | ||
function replacer() { | ||
var stack = [], | ||
r = 0, | ||
i = void 0; | ||
return function replacer(key, value) { | ||
if (key === "") { | ||
stack = []; | ||
r = 0; | ||
} | ||
switch (typeof value === 'undefined' ? 'undefined' : _typeof(value)) { | ||
case "function": | ||
return "".concat("function ", value.name || "anonymous", "(", Array(value.length + 1).join(",arg").slice(1), "){...}"); | ||
case "boolean": | ||
case "number": | ||
case "string": | ||
return value; | ||
default: | ||
if (!value || RECURSION_LIMIT < ++r) return undefined; | ||
i = stack.indexOf(value); | ||
if (i < 0) return stack.push(value) && value; | ||
return "*Recursive" + i; | ||
} | ||
}; | ||
} | ||
@@ -365,3 +446,3 @@ /***/ }, | ||
'use strict'; | ||
/* WEBPACK VAR INJECTION */(function(global) {'use strict'; | ||
@@ -382,41 +463,42 @@ Object.defineProperty(exports, "__esModule", { | ||
var devToolsEnabled = false; | ||
var loggers = []; | ||
function log(flow, name, newData, oldData) { | ||
!(0, _utils.isInternal)(flow) && loggers.forEach(function (f) { | ||
return f(flow, name, newData, oldData); | ||
}); | ||
!(0, _utils.isInternal)(flow) && devToolsEnabled && debug(flow, name, newData, oldData); | ||
if (!(0, _utils.isInternal)(flow)) { | ||
loggers.forEach(function (f) { | ||
f.isRemote ? f.logger(remoteLog(flow, name, newData, oldData)) : f.logger(flow, name, newData, oldData); | ||
}); | ||
debug(flow, name, newData, oldData); | ||
} | ||
} | ||
function debug(flow, name, d, d0) { | ||
sendToDevTools(name, { | ||
flow: flow.toObj(), | ||
name: name, | ||
d: d && (d.toObj ? d.toObj() : d), | ||
d0: d0 && (d0.toObj ? d0.toObj() : d0) | ||
}); | ||
function debug(flow, name, newData, oldData) { | ||
global.__nflow_devtools_hook__ && global.__nflow_devtools_hook__(remoteLog(flow, name, newData, oldData)); | ||
} | ||
function sendToDevTools(action, payload) { | ||
var eventDetail = { | ||
action: action, | ||
payload: payload | ||
/** | ||
* Converts a local log message(direct references) to a remote one(unmarshallable) | ||
*/ | ||
function remoteLog(flow, name, d, d0) { | ||
var o = { | ||
flow: flow.toObj('name', 'guid'), | ||
action: name | ||
}; | ||
var flowEvent = new document.defaultView.CustomEvent("FlowEvent", { detail: eventDetail }); | ||
document.dispatchEvent(flowEvent); | ||
var props = ['name', 'guid']; | ||
if (name == 'start') props.push('version', 'status'); | ||
if (name == 'create') props.push('status'); | ||
if (name == 'create' && d.data() !== undefined) props.push('data'); | ||
if (name == 'emitted') props.push('recipients'); | ||
var newData = d && d.toObj ? d.toObj.apply(d, props) : (0, _utils.serialise)(d); | ||
var oldData = d0 && d0.toObj ? d0.toObj.apply(d0, props) : (0, _utils.serialise)(d0); | ||
if (newData !== undefined) o.d = newData; | ||
if (oldData !== undefined) o.d0 = oldData; | ||
return o; | ||
} | ||
function init(flow) { | ||
flow.enableDevTools = function () { | ||
var enabled = arguments.length <= 0 || arguments[0] === undefined ? true : arguments[0]; | ||
devToolsEnabled = enabled; | ||
if (enabled) { | ||
debug(flow, 'start', flow, flow); | ||
} | ||
console.warn('flow.enableDevtools() is now deprecated. nflow-devtools will automatically start logging when Chrome devtools is open'); | ||
return flow; | ||
@@ -427,7 +509,11 @@ }; | ||
var logger = arguments.length <= 0 || arguments[0] === undefined ? _consts.UNSET : arguments[0]; | ||
var isRemote = arguments.length <= 1 || arguments[1] === undefined ? false : arguments[1]; | ||
if (logger === _consts.UNSET) return loggers; | ||
loggers.push(logger); | ||
if (logger === _consts.UNSET) return loggers;else loggers.push({ logger: logger, isRemote: isRemote }); | ||
return flow; | ||
}; | ||
flow.logger.reset = function () { | ||
return loggers = []; | ||
}; | ||
debug(flow, 'start', flow); | ||
} | ||
@@ -437,5 +523,5 @@ | ||
init: init, | ||
log: log, | ||
sendToDevTools: sendToDevTools | ||
log: log | ||
}; | ||
/* WEBPACK VAR INJECTION */}.call(exports, (function() { return this; }()))) | ||
@@ -517,5 +603,5 @@ /***/ }, | ||
(0, _utils.detach)(flow); | ||
(0, _utils.dispatchInternalEvent)(flow, 'childRemoved', previousParent); | ||
(0, _utils.dispatchInternalEvent)(flow, 'parent', parent, previousParent); | ||
attach(parent); | ||
(0, _utils.dispatchInternalEvent)(flow, 'childAdded', parent, previousParent); | ||
(0, _utils.dispatchInternalEvent)(flow, 'parented', parent, previousParent); | ||
return flow; | ||
@@ -563,2 +649,4 @@ }; | ||
flow.target = flow; | ||
function attach(parent) { | ||
@@ -601,13 +689,7 @@ parent && parent.children.value.push(flow); | ||
var instance = flow.get(name); | ||
if (instance) { | ||
var _instance; | ||
(_instance = instance).data.apply(_instance, data); | ||
return instance; | ||
} | ||
instance = (0, _factory2['default'])(flow.create.defaults, name, data); | ||
var instance = (0, _factory2['default'])(flow.create.defaults, name, data); | ||
instance.parent.value = flow; | ||
flow.children.value.push(instance); | ||
(0, _utils.dispatchInternalEvent)(flow, 'create', instance); | ||
return instance; | ||
@@ -620,3 +702,2 @@ }; | ||
direction: defaults.direction | ||
}; | ||
@@ -626,7 +707,7 @@ | ||
(0, _utils.assert)(arguments.length, _consts.ERRORS.invalidDisposeArgs); | ||
if (flow.status.value == _consts.STATUS.DISPOSED) return; | ||
if (flow.dispose.value == true) return; | ||
(0, _utils.dispatchInternalEvent)(flow, 'dispose', true); | ||
flow.parent(null); | ||
flow.status.value = _consts.STATUS.DISPOSED; | ||
flow.dispose.value = true; | ||
flow.on.listenerMap = {}; | ||
@@ -640,2 +721,3 @@ | ||
}; | ||
flow.dispose.value = false; | ||
}; | ||
@@ -655,2 +737,6 @@ | ||
var _factory = __webpack_require__(2); | ||
var _factory2 = _interopRequireDefault(_factory); | ||
var _utils = __webpack_require__(6); | ||
@@ -676,2 +762,4 @@ | ||
(0, _utils.assert)(arguments.length, _consts.ERRORS.invalidStatus); | ||
if (flow.cancel.value) return _consts.STATUS.CANCELLED; | ||
if (flow.dispose.value) return _consts.STATUS.DISPOSED; | ||
return flow.status.value; | ||
@@ -686,3 +774,5 @@ }; | ||
if (direction === _consts.UNSET) return flow.direction.value; | ||
var oldDirection = flow.direction.value; | ||
flow.direction.value = direction; | ||
(0, _utils.dispatchInternalEvent)(flow, 'direction', direction, oldDirection); | ||
return flow; | ||
@@ -713,8 +803,9 @@ }; | ||
direction && flow.direction(direction); | ||
log(flow, 'emit', flow); | ||
!flow.name.isInternal && (0, _utils.dispatchInternalEvent)(flow.parent(), 'emit', flow); | ||
flow.emit.route(flow); | ||
log(flow, 'emitted', flow); | ||
!flow.name.isInternal && (0, _utils.dispatchInternalEvent)(flow.parent(), 'emitted', flow); | ||
return flow; | ||
} | ||
if ((0, _utils.isFlow)(name)) { | ||
//1. reparent the passed in flow object where it's emitted from | ||
@@ -725,8 +816,10 @@ name.parent(flow); | ||
direction && name.direction(direction); | ||
log(name, 'emit', name); | ||
name.data.apply(name, _toConsumableArray(args)); | ||
(0, _utils.dispatchInternalEvent)(flow, 'emit', name); | ||
flow.emit.route(name); | ||
log(name, 'emitted', name); | ||
(0, _utils.dispatchInternalEvent)(flow, 'emitted', name); | ||
return flow; | ||
} | ||
// create and emit a new event | ||
(0, _utils.assert)(typeof name != 'string', _consts.ERRORS.invalidEventName); | ||
@@ -736,6 +829,6 @@ | ||
(0, _utils.detach)(event); | ||
direction && event.direction(direction); | ||
log(event, 'emit', event); | ||
if (direction) event.direction.value = direction; | ||
(0, _utils.dispatchInternalEvent)(flow, 'emit', event); | ||
flow.emit.route(event); | ||
log(event, 'emitted', event); | ||
(0, _utils.dispatchInternalEvent)(flow, 'emitted', event); | ||
return event; | ||
@@ -753,4 +846,3 @@ } | ||
flow.emit.targets = flow.emit.route[flow.direction()](flow).filter(function (f) { | ||
if (flow.emit.recipientsMap[f.flow.guid()]) return false; | ||
return flow.emit.recipientsMap[f.flow.guid()] = true; | ||
return !flow.emit.recipientsMap[f.flow.guid()]; | ||
}); | ||
@@ -765,13 +857,19 @@ | ||
} | ||
if (!flow.isCancelled() && !flow.propagationStopped()) { | ||
flow.status.value = _consts.STATUS.COMPLETED; | ||
} | ||
}; | ||
flow.emit.route.DOWNSTREAM = _routes2['default'].downstream; | ||
flow.emit.route.UPSTREAM = _routes2['default'].upstream; | ||
flow.emit.route.DEFAULT = _routes2['default']['default']; | ||
flow.emit.route.NONE = _routes2['default'].none; | ||
Object.keys(_routes2['default']).forEach(function (route) { | ||
flow.emit.route[route] = flow.emit.route[route.toUpperCase()] = _routes2['default'][route]; | ||
}); | ||
function notify(flow, currentNode) { | ||
if (currentNode.flow.on.notifyListeners(flow)) { | ||
//if (unreachable(flow, currentNode)) return; | ||
var result = currentNode.flow.on.notifyListeners(flow); | ||
if (result) { | ||
result.route = currentNode.route; | ||
result.direction = flow.direction(); | ||
flow.emit.recipientsMap[currentNode.flow.guid()] = flow.direction(); | ||
flow.emit.recipients.push(currentNode); | ||
flow.emit.recipients.push(result); | ||
} | ||
@@ -810,5 +908,5 @@ } | ||
var _none = __webpack_require__(13); | ||
var _current = __webpack_require__(13); | ||
var _none2 = _interopRequireDefault(_none); | ||
var _current2 = _interopRequireDefault(_current); | ||
@@ -819,5 +917,5 @@ var _downstream = __webpack_require__(14); | ||
var _default = __webpack_require__(15); | ||
var _default2 = __webpack_require__(15); | ||
var _default2 = _interopRequireDefault(_default); | ||
var _default3 = _interopRequireDefault(_default2); | ||
@@ -829,4 +927,5 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } | ||
downstream: _downstream2['default'], | ||
none: _none2['default'], | ||
"default": _default2['default'] // IE8 compatibility fix | ||
none: // deprecated | ||
_current2['default'], current: _current2['default'], | ||
"default": _default3['default'] // IE8 compatibility fix | ||
}; | ||
@@ -836,5 +935,5 @@ | ||
/* 12 */ | ||
/***/ function(module, exports) { | ||
/***/ function(module, exports, __webpack_require__) { | ||
"use strict"; | ||
'use strict'; | ||
@@ -844,2 +943,5 @@ Object.defineProperty(exports, "__esModule", { | ||
}); | ||
var _consts = __webpack_require__(5); | ||
/** | ||
@@ -849,7 +951,12 @@ * returns: all parent nodes | ||
exports["default"] = function (flow) { | ||
exports['default'] = function (flow) { | ||
return [flow].concat(flow.parents()).map(function (flow, i, arr) { | ||
return { | ||
flow: flow, | ||
route: arr.slice(0, i + 1).reverse() | ||
route: arr.slice(0, i + 1).map(function (f) { | ||
return { | ||
flow: f, | ||
direction: _consts.DIRECTION.UPSTREAM | ||
}; | ||
}) | ||
}; | ||
@@ -861,5 +968,5 @@ }); | ||
/* 13 */ | ||
/***/ function(module, exports) { | ||
/***/ function(module, exports, __webpack_require__) { | ||
"use strict"; | ||
'use strict'; | ||
@@ -869,2 +976,5 @@ Object.defineProperty(exports, "__esModule", { | ||
}); | ||
var _consts = __webpack_require__(5); | ||
/** | ||
@@ -874,7 +984,12 @@ * returns: only itself and the node emitting it | ||
exports["default"] = function (flow) { | ||
exports['default'] = function (flow) { | ||
return [flow].concat(flow.parent()).map(function (flow, i, arr) { | ||
return { | ||
flow: flow, | ||
route: arr.slice(0, i + 1).reverse() | ||
route: arr.slice(0, i + 1).map(function (f) { | ||
return { | ||
flow: f, | ||
direction: _consts.DIRECTION.CURRENT | ||
}; | ||
}) | ||
}; | ||
@@ -886,5 +1001,5 @@ }); | ||
/* 14 */ | ||
/***/ function(module, exports) { | ||
/***/ function(module, exports, __webpack_require__) { | ||
"use strict"; | ||
'use strict'; | ||
@@ -895,6 +1010,8 @@ Object.defineProperty(exports, "__esModule", { | ||
exports["default"] = function (flow) { | ||
var _consts = __webpack_require__(5); | ||
exports['default'] = function (flow) { | ||
var visitedNodesMap = {}; | ||
var route = getChildren(flow, []).concat(getChildren(flow.parent(), [flow])); | ||
var route = getChildren(flow, []).concat(getChildren(flow.parent(), [{ flow: flow, direction: _consts.DIRECTION.DOWNSTREAM }])); | ||
@@ -905,3 +1022,3 @@ return route; | ||
visitedNodesMap[flow.guid()] = true; | ||
route = [flow].concat(route); | ||
route = route.concat([{ flow: flow, direction: _consts.DIRECTION.DOWNSTREAM }]); | ||
var nodes = [{ flow: flow, route: route }]; | ||
@@ -927,2 +1044,4 @@ flow.children().forEach(function (f) { | ||
var _consts = __webpack_require__(5); | ||
exports['default'] = function (flow) { | ||
@@ -934,3 +1053,8 @@ var visitedNodesMap = {}; | ||
flow: flow, | ||
route: arr.slice(0, i) | ||
route: arr.slice(0, i + 1).map(function (f) { | ||
return { | ||
flow: f, | ||
direction: _consts.DIRECTION.UPSTREAM | ||
}; | ||
}) | ||
}; | ||
@@ -941,18 +1065,18 @@ }); | ||
// traverse downstream on detached nodes: | ||
visitedNodesMap[f.flow.guid()] = true; | ||
route.push(f); | ||
if ((0, _utils.isDetached)(f.flow)) { | ||
route = route.concat(getChildren(f.flow, f.route.reverse())); | ||
} else { | ||
visitedNodesMap[f.flow.guid()] = true; | ||
var r = [f.flow].concat(f.route.reverse()); | ||
route.push({ flow: f.flow, route: r }); | ||
route = route.concat(getChildren(f.flow, f.route)); | ||
} | ||
}); | ||
return route; | ||
function getChildren(flow, route) { | ||
var visited = visitedNodesMap[flow.guid()]; | ||
visitedNodesMap[flow.guid()] = true; | ||
route = [flow].concat(route); | ||
//route = route | ||
var nodes = visited ? [] : [{ flow: flow, route: route }]; | ||
flow.children().forEach(function (f) { | ||
return nodes = nodes.concat(getChildren(f, route)); | ||
return nodes = nodes.concat(getChildren(f, route.concat([{ flow: f, direction: _consts.DIRECTION.DOWNSTREAM }]))); | ||
}); | ||
@@ -991,3 +1115,3 @@ return nodes; | ||
}; | ||
flow.guid.value = "" + guid++; | ||
flow.guid.value = createGuid(); | ||
@@ -1016,3 +1140,3 @@ flow.name = function () { | ||
}).forEach(function (f) { | ||
return f(flow); | ||
return f.call(flow, flow); | ||
}); | ||
@@ -1022,2 +1146,10 @@ return flow; | ||
}; | ||
function createGuid() { | ||
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) { | ||
var r = Math.random() * 16 | 0, | ||
v = c == 'x' ? r : r & 0x3 | 0x8; | ||
return v.toString(16); | ||
}); | ||
} | ||
@@ -1062,3 +1194,3 @@ /***/ }, | ||
if (args.length == 1 && args[0] == null) { | ||
(0, _utils.dispatchInternalEvent)(flow, 'listenerRemoved', name); | ||
(0, _utils.dispatchInternalEvent)(flow, 'listenerRemoved', { name: name }); | ||
delete flow.on.listenerMap[name]; | ||
@@ -1071,3 +1203,5 @@ return flow; | ||
}); | ||
(0, _utils.dispatchInternalEvent)(flow, oldListeners ? 'listenerChanged' : 'listenerAdded', name); | ||
(0, _utils.dispatchInternalEvent)(flow, oldListeners ? 'listenerChanged' : 'listenerAdded', { name: name, handlers: args.map(function (d) { | ||
return d.name || 'function'; | ||
}) }); | ||
return flow; | ||
@@ -1079,8 +1213,30 @@ }; | ||
if (flow.on.listenerMap[event.name()]) { | ||
event.target = flow; | ||
flow.on.listenerMap[event.name()].every(function (listener) { | ||
listener.apply(event, event.data.value); | ||
return event.status() == _consts.STATUS.FLOWING; | ||
}); | ||
return true; | ||
var _ret = function () { | ||
var listeners = []; | ||
event.target = flow; | ||
flow.on.listenerMap[event.name()].forEach(function (listener) { | ||
var l = { | ||
listener: listener | ||
}; | ||
listeners.push(l); | ||
if (event.status() != _consts.STATUS.FLOWING) { | ||
l.status = event.status(); | ||
return; | ||
} | ||
if (event.stopPropagation.modifiers[flow.guid.value] & _consts.DIRECTION_BITMASK['CURRENT']) { | ||
l.status = 'SKIPPED'; | ||
return; | ||
} | ||
l.status = 'DELIVERED'; | ||
listener.apply(event, event.data.value); | ||
}); | ||
return { | ||
v: { | ||
flow: flow, | ||
listeners: listeners | ||
} | ||
}; | ||
}(); | ||
if ((typeof _ret === 'undefined' ? 'undefined' : _typeof(_ret)) === "object") return _ret.v; | ||
} | ||
@@ -1092,5 +1248,5 @@ }; | ||
/* 18 */ | ||
/***/ function(module, exports) { | ||
/***/ function(module, exports, __webpack_require__) { | ||
"use strict"; | ||
'use strict'; | ||
@@ -1101,3 +1257,5 @@ Object.defineProperty(exports, "__esModule", { | ||
exports["default"] = function (flow) { | ||
var _utils = __webpack_require__(6); | ||
exports['default'] = function (flow) { | ||
flow.toString = function () { | ||
@@ -1108,25 +1266,68 @@ return JSON.stringify(flow.toObj()); | ||
flow.toObj = function () { | ||
return { | ||
name: flow.name(), | ||
guid: flow.guid(), | ||
parentName: flow.parent() && flow.parent().name(), | ||
parentGuid: flow.parent() && flow.parent().guid(), | ||
status: flow.status(), | ||
listeners: Object.keys(flow.on()), | ||
children: flow.children().map(function (f) { | ||
return { name: f.name(), guid: f.guid() }; | ||
}), | ||
recipients: flow.emit.recipients && flow.emit.recipients.map(function (f) { | ||
for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) { | ||
args[_key] = arguments[_key]; | ||
} | ||
var props = args.reduce(function (a, b) { | ||
return a[b] = 1, a; | ||
}, {}); | ||
var hasProp = function hasProp(prop) { | ||
return !args.length || props[prop]; | ||
}; | ||
var add = function add(name, valueF) { | ||
if (hasProp(name)) obj[name] = valueF(); | ||
}; | ||
var obj = {}; | ||
add('name', flow.name); | ||
add('guid', flow.guid); | ||
add('version', function () { | ||
return flow.version; | ||
}); | ||
add('status', flow.status); | ||
add('data', function () { | ||
return (0, _utils.serialise)(flow.data()); | ||
}); | ||
add('parent', function () { | ||
return { | ||
name: flow.parent.value && flow.parent.value.name.value, | ||
guid: flow.parent.value && flow.parent.value.guid.value | ||
}; | ||
}); | ||
add('listeners', function () { | ||
var l = flow.on(); | ||
var o = {}; | ||
Object.keys(l).forEach(function (key) { | ||
return o[key] = l[key].map(function (f) { | ||
return f.name || 'function'; | ||
}); | ||
}); | ||
return o; | ||
}); | ||
add('children', function () { | ||
return flow.children().map(function (f) { | ||
return f.toObj('name', 'guid'); | ||
}); | ||
}); | ||
add('recipients', function () { | ||
return flow.emit.recipients && flow.emit.recipients.map(function (f) { | ||
return { | ||
flow: { | ||
guid: f.flow.guid(), | ||
name: f.flow.name() }, | ||
flow: f.flow.toObj('name', 'guid'), | ||
route: f.route.map(function (f) { | ||
return { | ||
guid: f.guid(), | ||
name: f.name() }; | ||
flow: f.flow.toObj('name', 'guid'), | ||
direction: f.direction | ||
}; | ||
}), | ||
listeners: f.listeners.map(function (l) { | ||
return { | ||
name: (0, _utils.serialise)(l.listener), | ||
status: l.status | ||
}; | ||
}) | ||
}; | ||
}) | ||
}; | ||
}); | ||
}); | ||
return obj; | ||
}; | ||
@@ -1192,4 +1393,36 @@ }; | ||
/***/ }, | ||
/* 21 */ | ||
/***/ function(module, exports, __webpack_require__) { | ||
'use strict'; | ||
Object.defineProperty(exports, "__esModule", { | ||
value: true | ||
}); | ||
var _logger = __webpack_require__(7); | ||
var _logger2 = _interopRequireDefault(_logger); | ||
var _utils = __webpack_require__(6); | ||
var _consts = __webpack_require__(5); | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } | ||
exports['default'] = function (flow, defaults) { | ||
flow.stats = function () { | ||
(0, _utils.assert)(arguments.length, _consts.ERRORS.invalidStatsArgs); | ||
return flow.stats.value; | ||
}; | ||
flow.stats.value = {}; | ||
flow.version = ("0.2.2"); | ||
}; | ||
/***/ } | ||
/******/ ]))); | ||
//# sourceMappingURL=nflow.js.map |
{ | ||
"name": "nflow", | ||
"version": "0.2.1", | ||
"version": "0.2.2", | ||
"description": "event/data/control flow", | ||
@@ -24,5 +24,7 @@ "main": "dist/nflow.js", | ||
"babel-core": "^6.2.1", | ||
"babel-helper-function-name": "^6.6.0", | ||
"babel-loader": "^6.2.0", | ||
"babel-preset-es2015": "^6.1.18", | ||
"babel-preset-stage-0": "^6.3.13", | ||
"chai": "^3.5.0", | ||
"babel-plugin-transform-es3-property-literals":"*", | ||
@@ -36,3 +38,5 @@ "babel-plugin-transform-es3-member-expression-literals":"*", | ||
"less-loader": "^2.2.2", | ||
"mocha-circleci-reporter": "^0.0.1", | ||
"mocha-loader": "^0.7.1", | ||
"publish": "0.5.0", | ||
"raw-loader": "^0.5.1", | ||
@@ -44,4 +48,3 @@ "style-loader": "^0.13.0", | ||
"publish": "0.5.0", | ||
"mocha-circleci-reporter": "^0.0.1", | ||
"chai": "^3.5.0" | ||
"mocha-circleci-reporter": "^0.0.1" | ||
}, | ||
@@ -48,0 +51,0 @@ "directories": { |
@@ -5,2 +5,3 @@ import { DEFAULTS | ||
, DIRECTION | ||
, DIRECTION_BITMASK | ||
, UNSET } from '../consts' | ||
@@ -14,6 +15,8 @@ import {assert, detach, dispatchInternalEvent} from '../utils' | ||
, ERRORS.invalidCancelArgs) | ||
flow.status.value = STATUS.CANCELLED | ||
dispatchInternalEvent(flow, 'cancel', true) | ||
let previousValue = flow.cancel.value | ||
flow.cancel.value = true | ||
dispatchInternalEvent(flow, 'cancel', true, previousValue) | ||
return flow | ||
} | ||
flow.cancel.value = false | ||
@@ -23,18 +26,51 @@ flow.isCancelled = () => { | ||
.concat(flow.parents()) | ||
.some(e=>e.status.value == STATUS.CANCELLED | ||
|| e.status.value == STATUS.DISPOSED | ||
.some(e=>e.status() == STATUS.CANCELLED | ||
|| e.status() == STATUS.DISPOSED | ||
) | ||
} | ||
flow.stopPropagation = (...args) => { | ||
assert(args.length | ||
flow.stopPropagation = (direction=UNSET) => { | ||
direction!==UNSET && assert(!DIRECTION[direction.toUpperCase()] | ||
, ERRORS.invalidStopPropagationArgs) | ||
flow.status.value = STATUS.STOPPED | ||
dispatchInternalEvent(flow, 'propagationStopped', true) | ||
if (direction==UNSET){ | ||
flow.status.value = STATUS.STOPPED | ||
flow.stopPropagation.value = true; | ||
flow.stopPropagation.modifiers[flow.target.guid] = -1 //bitmask fill | ||
dispatchInternalEvent(flow, 'propagationStopped', true) | ||
} | ||
else { | ||
let d = DIRECTION[direction.toUpperCase()] | ||
dispatchInternalEvent(flow, 'propagationAugmented', { | ||
direction:d, | ||
target: flow.target.toObj('name', 'guid') | ||
}) | ||
flow.stopPropagation.modifiers[flow.target.guid.value] |= DIRECTION_BITMASK[d] | ||
} | ||
return flow | ||
} | ||
flow.stopPropagation.value = false | ||
flow.stopPropagation.modifiers = {} | ||
createStopPropagationModifiers(flow) | ||
flow.propagationStopped = () => { | ||
return flow.status.value == STATUS.STOPPED | ||
return flow.stopPropagation.value | ||
} | ||
} | ||
/** | ||
* create directional (eg. `flow.stopPropagation.dowsntream(...)`) API | ||
*/ | ||
function createStopPropagationModifiers(flow){ | ||
Object.keys(DIRECTION) | ||
.forEach(direction=>{ | ||
flow.stopPropagation[direction] | ||
= flow.stopPropagation[direction.toLowerCase()] | ||
= ()=>{ | ||
return flow.stopPropagation(direction) | ||
} | ||
}) | ||
} |
@@ -61,5 +61,5 @@ import {assert, detach, dispatchInternalEvent, isFlow} from '../utils' | ||
detach(flow) | ||
dispatchInternalEvent(flow, 'childRemoved', previousParent) | ||
dispatchInternalEvent(flow, 'parent', parent, previousParent) | ||
attach(parent) | ||
dispatchInternalEvent(flow, 'childAdded', parent, previousParent) | ||
dispatchInternalEvent(flow, 'parented', parent, previousParent) | ||
return flow | ||
@@ -107,2 +107,4 @@ } | ||
} | ||
flow.target = flow | ||
@@ -109,0 +111,0 @@ function attach(parent) { |
@@ -14,12 +14,7 @@ import factory from '../factory' | ||
flow.create = (name, ...data) => { | ||
var instance = flow.get(name) | ||
if (instance){ | ||
instance.data(...data) | ||
return instance | ||
} | ||
instance = factory(flow.create.defaults, name, data) | ||
var instance = factory(flow.create.defaults, name, data) | ||
instance.parent.value = flow | ||
flow.children.value.push(instance) | ||
dispatchInternalEvent(flow, 'create', instance) | ||
return instance | ||
@@ -32,3 +27,2 @@ } | ||
direction: defaults.direction | ||
} | ||
@@ -39,7 +33,7 @@ | ||
, ERRORS.invalidDisposeArgs) | ||
if (flow.status.value == STATUS.DISPOSED) return; | ||
if (flow.dispose.value == true) return; | ||
dispatchInternalEvent(flow, 'dispose', true) | ||
flow.parent(null) | ||
flow.status.value = STATUS.DISPOSED | ||
flow.dispose.value = true | ||
flow.on.listenerMap = {} | ||
@@ -51,4 +45,5 @@ | ||
} | ||
flow.dispose.value = false | ||
} |
@@ -6,4 +6,4 @@ import { DEFAULTS | ||
, UNSET } from '../consts' | ||
import {merge, detach, flatten, assert, isDetached, isFlow} from '../utils' | ||
import factory from '../factory' | ||
import {merge, detach, flatten, assert, isDetached, isFlow, dispatchInternalEvent} from '../utils' | ||
import logger from '../logger' | ||
@@ -18,2 +18,4 @@ import routes from '../routes' | ||
, ERRORS.invalidStatus) | ||
if (flow.cancel.value) return STATUS.CANCELLED | ||
if (flow.dispose.value) return STATUS.DISPOSED | ||
return flow.status.value | ||
@@ -27,3 +29,5 @@ } | ||
if (direction===UNSET) return flow.direction.value | ||
let oldDirection = flow.direction.value | ||
flow.direction.value = direction | ||
dispatchInternalEvent(flow, 'direction', direction, oldDirection) | ||
return flow | ||
@@ -44,8 +48,9 @@ } | ||
direction && flow.direction(direction) | ||
log(flow, 'emit', flow) | ||
!flow.name.isInternal && dispatchInternalEvent(flow.parent(), 'emit', flow) | ||
flow.emit.route(flow) | ||
log(flow, 'emitted', flow) | ||
!flow.name.isInternal && dispatchInternalEvent(flow.parent(), 'emitted', flow) | ||
return flow | ||
} | ||
if (isFlow(name)) { | ||
//1. reparent the passed in flow object where it's emitted from | ||
@@ -56,17 +61,20 @@ name.parent(flow) | ||
direction && name.direction(direction) | ||
log(name, 'emit', name) | ||
name.data(...args) | ||
dispatchInternalEvent(flow, 'emit', name) | ||
flow.emit.route(name) | ||
log(name, 'emitted', name) | ||
dispatchInternalEvent(flow, 'emitted', name) | ||
return flow | ||
} | ||
// create and emit a new event | ||
assert(typeof(name)!='string' | ||
, ERRORS.invalidEventName) | ||
var event = flow.create(name, ...args) | ||
var event = flow.create(name, ...args) | ||
detach(event) | ||
direction && event.direction(direction) | ||
log(event, 'emit', event) | ||
if (direction) event.direction.value = direction | ||
dispatchInternalEvent(flow, 'emit', event) | ||
flow.emit.route(event) | ||
log(event, 'emitted', event) | ||
dispatchInternalEvent(flow, 'emitted', event) | ||
return event | ||
@@ -84,6 +92,3 @@ } | ||
flow.emit.targets = flow.emit.route[flow.direction()](flow) | ||
.filter(f=>{ | ||
if (flow.emit.recipientsMap[f.flow.guid()]) return false | ||
return flow.emit.recipientsMap[f.flow.guid()] = true | ||
}) | ||
.filter(f=>!flow.emit.recipientsMap[f.flow.guid()]) | ||
@@ -97,13 +102,22 @@ while (flow.emit.targets.length){ | ||
} | ||
if (!flow.isCancelled() && !flow.propagationStopped()) { | ||
flow.status.value = STATUS.COMPLETED | ||
} | ||
} | ||
flow.emit.route.DOWNSTREAM = routes.downstream | ||
flow.emit.route.UPSTREAM = routes.upstream | ||
flow.emit.route.DEFAULT = routes.default | ||
flow.emit.route.NONE = routes.none | ||
Object.keys(routes).forEach(route=>{ | ||
flow.emit.route[route] | ||
= flow.emit.route[route.toUpperCase()] | ||
= routes[route] | ||
}) | ||
function notify(flow, currentNode){ | ||
if (currentNode.flow.on.notifyListeners(flow)) { | ||
//if (unreachable(flow, currentNode)) return; | ||
let result = currentNode.flow.on.notifyListeners(flow) | ||
if (result){ | ||
result.route = currentNode.route | ||
result.direction = flow.direction() | ||
flow.emit.recipientsMap[currentNode.flow.guid()] = flow.direction() | ||
flow.emit.recipients.push(currentNode) | ||
flow.emit.recipients.push(result) | ||
} | ||
@@ -110,0 +124,0 @@ } |
@@ -18,3 +18,3 @@ import { DEFAULTS | ||
} | ||
flow.guid.value = ""+guid++ | ||
flow.guid.value = createGuid() | ||
@@ -37,3 +37,3 @@ flow.name = (name=UNSET) => { | ||
.filter(f=>typeof(f)=='function') | ||
.forEach(f=>f(flow)) | ||
.forEach(f=>f.call(flow,flow)) | ||
return flow | ||
@@ -43,1 +43,9 @@ } | ||
} | ||
function createGuid(){ | ||
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx' | ||
.replace(/[xy]/g, function(c) { | ||
var r = Math.random()*16|0, v = c == 'x' ? r : (r&0x3|0x8); | ||
return v.toString(16); | ||
}); | ||
} |
@@ -0,1 +1,2 @@ | ||
import cancellable from './cancellable' | ||
@@ -10,2 +11,3 @@ import connect from './connect' | ||
import get from './get' | ||
import stats from './stats' | ||
@@ -21,3 +23,5 @@ export default { | ||
stateful, | ||
get | ||
get, | ||
stats | ||
} | ||
@@ -1,2 +0,2 @@ | ||
import { ERRORS, UNSET, STATUS } from '../consts' | ||
import { ERRORS, UNSET, STATUS, DIRECTION_BITMASK } from '../consts' | ||
import {assert, dispatchInternalEvent} from '../utils' | ||
@@ -16,3 +16,3 @@ import logger from '../logger' | ||
if (args.length==1 && args[0]==null) { | ||
dispatchInternalEvent(flow, 'listenerRemoved', name) | ||
dispatchInternalEvent(flow, 'listenerRemoved', {name}) | ||
delete flow.on.listenerMap[name] | ||
@@ -29,3 +29,3 @@ return flow; | ||
: 'listenerAdded' | ||
, name) | ||
, {name, handlers:args.map( d=>d.name||'function' )}) | ||
return flow | ||
@@ -37,11 +37,29 @@ } | ||
if (flow.on.listenerMap[event.name()]) { | ||
let listeners = [] | ||
event.target = flow | ||
flow.on.listenerMap[event.name()] | ||
.every(listener=>{ | ||
.forEach(listener=>{ | ||
let l = { | ||
listener | ||
} | ||
listeners.push(l) | ||
if (event.status() != STATUS.FLOWING) { | ||
l.status = event.status() | ||
return; | ||
} | ||
if (event.stopPropagation.modifiers[flow.guid.value] | ||
& DIRECTION_BITMASK['CURRENT']) { | ||
l.status = 'SKIPPED' | ||
return; | ||
} | ||
l.status='DELIVERED' | ||
listener.apply(event, event.data.value) | ||
return (event.status() == STATUS.FLOWING) | ||
}) | ||
return true | ||
return { | ||
flow, | ||
listeners | ||
} | ||
} | ||
} | ||
} |
@@ -0,1 +1,2 @@ | ||
import {serialise} from '../utils' | ||
export default (flow)=>{ | ||
@@ -6,19 +7,44 @@ flow.toString = () => { | ||
flow.toObj = () => ({ | ||
name: flow.name(), | ||
guid: flow.guid(), | ||
parentName: flow.parent() && flow.parent().name(), | ||
parentGuid: flow.parent() && flow.parent().guid(), | ||
status: flow.status(), | ||
listeners: Object.keys(flow.on()), | ||
children: flow.children().map(f=>({ name: f.name(), guid: f.guid() })), | ||
recipients: flow.emit.recipients && flow.emit.recipients.map(f=>({ | ||
flow: { | ||
guid: f.flow.guid(), | ||
name: f.flow.name() }, | ||
route: f.route.map(f=>({ | ||
guid: f.guid(), | ||
name: f.name() })) | ||
flow.toObj = (...args) => { | ||
const props = args.reduce((a,b)=>(a[b]=1,a),{}) | ||
const hasProp = prop=>!args.length || props[prop] | ||
const add = (name, valueF)=>{if(hasProp(name)) obj[name]=valueF() } | ||
let obj = {} | ||
add('name', flow.name) | ||
add('guid', flow.guid) | ||
add('version',()=>flow.version) | ||
add('status', flow.status) | ||
add('data', ()=>serialise(flow.data())) | ||
add('parent', ()=>({ | ||
name: flow.parent.value && flow.parent.value.name.value, | ||
guid: flow.parent.value && flow.parent.value.guid.value | ||
})) | ||
}) | ||
add('listeners', ()=>{ | ||
const l = flow.on() | ||
let o = {} | ||
Object.keys(l) | ||
.forEach(key=>o[key]=l[key] | ||
.map(f=>f.name||'function')) | ||
return o; | ||
}) | ||
add('children', ()=>flow.children() | ||
.map(f=>f.toObj('name','guid'))) | ||
add('recipients', ()=>{ | ||
return flow.emit.recipients | ||
&& flow.emit.recipients.map(f=>({ | ||
flow: f.flow.toObj('name','guid'), | ||
route: f.route.map(f=>({ | ||
flow: f.flow.toObj('name','guid'), | ||
direction: f.direction | ||
})), | ||
listeners: f.listeners.map(l=>({ | ||
name: serialise(l.listener), | ||
status:l.status | ||
})) | ||
})) | ||
}) | ||
return obj; | ||
} | ||
} |
@@ -7,3 +7,4 @@ /** | ||
export const DIRECTION = { | ||
NONE: "NONE", | ||
CURRENT: "CURRENT", | ||
NONE: "CURRENT", // deprecated | ||
DEFAULT: "DEFAULT", | ||
@@ -14,2 +15,10 @@ UPSTREAM: "UPSTREAM", | ||
export const DIRECTION_BITMASK = { | ||
CURRENT: 1<<0, | ||
NONE: 1<<0, // deprecated | ||
DEFAULT: 1<<1, | ||
UPSTREAM: 1<<2, | ||
DOWNSTREAM: 1<<3 | ||
} | ||
export const STATUS = { | ||
@@ -34,3 +43,4 @@ IDLE: "IDLE", | ||
'cancellable', | ||
'loggable' | ||
'loggable', | ||
'stats' | ||
], | ||
@@ -51,4 +61,4 @@ direction: DIRECTION.DEFAULT | ||
, invalidCancelArgs:'Invalid Argument. The .cancel() API requires no parameters' | ||
, invalidStopPropagationArgs:'Invalid Argument. The .stopPropagation() API requires no parameters' | ||
, 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' | ||
} |
@@ -1,2 +0,2 @@ | ||
import {isInternal} from './utils' | ||
import {isInternal, serialise} from './utils' | ||
import { DEFAULTS | ||
@@ -9,59 +9,59 @@ , ERRORS | ||
var devToolsEnabled = false | ||
var loggers = [] | ||
function log(flow, name, newData, oldData){ | ||
!isInternal(flow) | ||
&& loggers.forEach(f=>f(flow, name, newData, oldData)) | ||
!isInternal(flow) | ||
&& devToolsEnabled | ||
&& debug(flow, name, newData, oldData) | ||
if (!isInternal(flow)){ | ||
loggers.forEach(f=>{ | ||
f.isRemote | ||
? f.logger(remoteLog(flow, name, newData, oldData)) | ||
: f.logger(flow, name, newData, oldData) | ||
}) | ||
debug(flow, name, newData, oldData) | ||
} | ||
} | ||
function debug(flow, name, d, d0){ | ||
sendToDevTools(name, | ||
{ | ||
flow: flow.toObj(), | ||
name: name, | ||
d: d && (d.toObj? d.toObj():d), | ||
d0: d0 && (d0.toObj? d0.toObj():d0) | ||
}) | ||
function debug(flow, name, newData, oldData){ | ||
global.__nflow_devtools_hook__ && | ||
global.__nflow_devtools_hook__( | ||
remoteLog(flow, name, newData, oldData)) | ||
} | ||
function sendToDevTools(action, payload){ | ||
var eventDetail = { | ||
action: action, | ||
payload:payload | ||
}; | ||
var flowEvent = new document.defaultView.CustomEvent("FlowEvent", {detail: eventDetail}); | ||
document.dispatchEvent(flowEvent); | ||
/** | ||
* Converts a local log message(direct references) to a remote one(unmarshallable) | ||
*/ | ||
function remoteLog(flow, name, d, d0){ | ||
let o = { | ||
flow: flow.toObj('name','guid'), | ||
action: name | ||
} | ||
let props = ['name', 'guid'] | ||
if (name=='start') props.push('version', 'status') | ||
if (name=='create') props.push('status') | ||
if (name=='create' && d.data()!==undefined) props.push('data') | ||
if (name=='emitted' ) props.push('recipients') | ||
let newData = (d && d.toObj? d.toObj(...props):serialise(d)) | ||
let oldData = (d0 && d0.toObj? d0.toObj(...props):serialise(d0)) | ||
if (newData!==undefined) o.d=newData | ||
if (oldData!==undefined) o.d0=oldData | ||
return o | ||
} | ||
function init(flow){ | ||
flow.enableDevTools = (enabled=true)=>{ | ||
devToolsEnabled = enabled | ||
if (enabled) { | ||
debug(flow, 'start', flow, flow) | ||
} | ||
console.warn('flow.enableDevtools() is now deprecated. nflow-devtools will automatically start logging when Chrome devtools is open') | ||
return flow | ||
} | ||
flow.logger = (logger=UNSET) => { | ||
flow.logger = (logger=UNSET, isRemote=false) => { | ||
if (logger===UNSET) return loggers | ||
loggers.push(logger) | ||
else loggers.push({logger,isRemote}) | ||
return flow | ||
} | ||
flow.logger.reset = ()=>loggers=[]; | ||
debug(flow, 'start', flow) | ||
} | ||
export default { | ||
init | ||
, log | ||
, sendToDevTools | ||
} |
import {isDetached} from '../utils' | ||
import {DIRECTION} from '../consts' | ||
export default (flow)=>{ | ||
@@ -8,3 +10,7 @@ var visitedNodesMap = {} | ||
flow, | ||
route: arr.slice(0,i) | ||
route: arr.slice(0,i+1) | ||
.map(f=>({ | ||
flow:f, | ||
direction: DIRECTION.UPSTREAM | ||
})) | ||
})) | ||
@@ -14,23 +20,21 @@ | ||
// traverse downstream on detached nodes: | ||
visitedNodesMap[f.flow.guid()] = true | ||
route.push(f) | ||
if (isDetached(f.flow)) { | ||
route = route.concat(getChildren(f.flow, f.route.reverse())) | ||
route = route.concat(getChildren(f.flow, f.route)) | ||
} | ||
else { | ||
visitedNodesMap[f.flow.guid()] = true | ||
var r = [f.flow].concat(f.route.reverse()) | ||
route.push({ flow:f.flow, route:r}) | ||
} | ||
}) | ||
return route; | ||
function getChildren(flow, route){ | ||
var visited = (visitedNodesMap[flow.guid()]) | ||
visitedNodesMap[flow.guid()] = true | ||
route = [flow].concat(route) | ||
//route = route | ||
var nodes = visited? []:[{ flow, route }] | ||
flow.children() | ||
.forEach(f=>nodes = nodes.concat(getChildren(f,route))) | ||
.forEach(f=>nodes = nodes.concat(getChildren(f,route | ||
.concat([{flow:f, direction: DIRECTION.DOWNSTREAM}])))) | ||
return nodes | ||
} | ||
} | ||
} |
@@ -0,1 +1,3 @@ | ||
import {DIRECTION} from '../consts' | ||
export default (flow)=>{ | ||
@@ -5,3 +7,4 @@ var visitedNodesMap = {} | ||
var route = getChildren(flow, []) | ||
.concat(getChildren(flow.parent(), [flow])) | ||
.concat(getChildren(flow.parent() | ||
,[{flow:flow, direction: DIRECTION.DOWNSTREAM}])) | ||
@@ -12,3 +15,3 @@ return route; | ||
visitedNodesMap[flow.guid()] = true | ||
route = [flow].concat(route) | ||
route = route.concat([{flow:flow, direction: DIRECTION.DOWNSTREAM}]) | ||
var nodes = [{ flow, route }] | ||
@@ -15,0 +18,0 @@ flow.children() |
import upstream from './upstream' | ||
import none from './none' | ||
import current from './current' | ||
import downstream from './downstream' | ||
import defaultDirection from './default' | ||
import _default from './default' | ||
@@ -9,4 +9,5 @@ export default { | ||
downstream, | ||
none, | ||
"default": defaultDirection // IE8 compatibility fix | ||
} | ||
none:current, // deprecated | ||
current, | ||
"default": _default // IE8 compatibility fix | ||
} |
@@ -0,1 +1,2 @@ | ||
import {DIRECTION} from '../consts' | ||
/** | ||
@@ -9,5 +10,9 @@ * returns: all parent nodes | ||
flow, | ||
route: arr.slice(0,i+1).reverse() | ||
route: arr.slice(0,i+1) | ||
.map(f=>({ | ||
flow:f, | ||
direction: DIRECTION.UPSTREAM | ||
})) | ||
})) | ||
} | ||
@@ -8,2 +8,4 @@ import factory from './factory' | ||
import logger from './logger' | ||
const RECURSION_LIMIT = 1024; | ||
/** | ||
@@ -56,3 +58,3 @@ * utils | ||
e.data.value = [newData, oldData] | ||
e.direction.value= DIRECTION.NONE | ||
e.direction.value= DIRECTION.CURRENT | ||
e.parent.value = flow | ||
@@ -70,2 +72,35 @@ e.emit() | ||
logger.log(flow, name, newData, oldData) | ||
} | ||
} | ||
export const serialise = o=>JSON.stringify(o, replacer()) | ||
function replacer() { | ||
let stack = [] | ||
, r = 0 | ||
, i | ||
return function replacer(key, value) { | ||
if (key === "") { | ||
stack = []; | ||
r = 0; | ||
} | ||
switch(typeof value) { | ||
case "function": | ||
return "".concat( | ||
"function ", | ||
value.name || "anonymous", | ||
"(", | ||
Array(value.length + 1).join(",arg").slice(1), | ||
"){...}" | ||
); | ||
case "boolean": | ||
case "number": | ||
case "string": | ||
return value; | ||
default: | ||
if (!value || RECURSION_LIMIT < ++r) return undefined; | ||
i = stack.indexOf(value); | ||
if (i < 0) return stack.push(value) && value; | ||
return "*Recursive" + i; | ||
} | ||
}; | ||
} |
@@ -114,63 +114,6 @@ import flow from 'nflow' | ||
describe('Flow stopPropagation()', function(){ | ||
it('should stop event delegation', function(done){ | ||
function shouldCall(){ | ||
this.stopPropagation() | ||
} | ||
function shouldNotCall(){ | ||
done('stopped event should not call subsequent listeners') | ||
} | ||
var a = sut | ||
.create('a') // parent | ||
.on('test', shouldNotCall) | ||
.create('b') | ||
.on('test', shouldCall) | ||
.create('c') | ||
.emit("test") | ||
setTimeout(done, 10) | ||
}) | ||
it('should stop event delivery on same listener', function(done){ | ||
function shouldCall(){ | ||
this.stopPropagation() | ||
} | ||
function shouldNotCall(){ | ||
done('stopped event should not call subsequent listeners') | ||
} | ||
var a = sut | ||
.create('b') | ||
.on('test', shouldCall, shouldNotCall) | ||
.create('c') | ||
.emit("test") | ||
setTimeout(done, 10) | ||
}) | ||
it('should still emit events on stopped nodes', function(done){ | ||
function shouldCall(){ | ||
done() | ||
} | ||
var a = sut | ||
.create('b') | ||
.on('test',shouldCall) | ||
.stopPropagation() | ||
.create('c') | ||
.stopPropagation() | ||
.create('d') | ||
.emit("test") | ||
}) | ||
}) | ||
}) |
@@ -29,7 +29,17 @@ import flow from 'nflow' | ||
describe('guid API', function(){ | ||
it('should have globally unique ID-s', function(){ | ||
var sut1 = testFlow.create('test') | ||
var sut2 = testFlow.create('test') | ||
console.log(sut1.guid()) | ||
console.log(sut2.guid()) | ||
expect(sut1.guid()).to.not.equal(sut2.guid()) | ||
}) | ||
}) | ||
describe('.create() API', function(){ | ||
it('should reuse existing flow objects', function(){ | ||
it('should create new flow objects', function(){ | ||
var sut1 = testFlow.create('test') | ||
var sut2 = testFlow.create('test') | ||
expect(sut1).to.equal(sut2) | ||
expect(sut1).to.not.equal(sut2) | ||
}) | ||
@@ -36,0 +46,0 @@ |
@@ -14,5 +14,6 @@ import flow from 'nflow' | ||
describe('parent() API', function(){ | ||
it('should dispatch flow.childRemoved internal event', function(done){ | ||
it('should dispatch flow.parent internal event', function(done){ | ||
var payload = {} | ||
var listener = function(oldParent){ | ||
var listener = function(newParent,oldParent){ | ||
expect(newParent).to.equal(null) | ||
expect(oldParent).to.equal(sut) | ||
@@ -26,7 +27,7 @@ done() | ||
.create('test') | ||
.on('flow.childRemoved', listener) | ||
.parent(sut1) | ||
.on('flow.parent', listener) | ||
.parent(null) | ||
}) | ||
it('should dispatch flow.childAdded internal event on reparenting', function(done){ | ||
it('should dispatch flow.parent internal event on reparenting', function(done){ | ||
var payload = {} | ||
@@ -43,9 +44,10 @@ var listener = function(newParent, oldParent){ | ||
.create('test') | ||
.on('flow.childAdded', listener) | ||
.on('flow.parent', listener) | ||
.parent(sut1) | ||
}) | ||
it('should dispatch flow.children.childRemoved internal event', function(done){ | ||
it('should dispatch flow.children.parent internal event', function(done){ | ||
var payload = {} | ||
var listener = function(f, oldParent){ | ||
var listener = function(f, newParent, oldParent){ | ||
expect(newParent).to.equal(sut1) | ||
expect(oldParent).to.equal(sut) | ||
@@ -58,3 +60,3 @@ done() | ||
sut | ||
.on('flow.children.childRemoved', listener) | ||
.on('flow.children.parent', listener) | ||
.create('test') | ||
@@ -64,3 +66,3 @@ .parent(sut1) | ||
it('should dispatch flow.children.childAdded internal event', function(done){ | ||
it('should dispatch flow.children.parent internal event', function(done){ | ||
var payload = {} | ||
@@ -77,3 +79,3 @@ var listener = function(f, newParent, oldParent){ | ||
sut | ||
.on('flow.children.childAdded', listener) | ||
.on('flow.children.parent', listener) | ||
.create('test0') | ||
@@ -80,0 +82,0 @@ .create('test1') |
import flow from 'nflow' | ||
import assert from 'assert' | ||
import {expect} from 'chai' | ||
var sut | ||
@@ -8,2 +9,3 @@ | ||
beforeEach(function(){ | ||
flow.logger.reset() | ||
sut = flow | ||
@@ -14,3 +16,5 @@ .create('sut') | ||
}) | ||
describe('Flow Logging', ()=>{ | ||
it('Should toString', ()=>{ | ||
@@ -20,2 +24,7 @@ expect(String(sut)).to.be.contain("sut") | ||
it('Should expose version', ()=>{ | ||
expect(sut.version).to.exist | ||
expect(sut.version).to.equal(VERSION) | ||
}) | ||
it('Should use global logger', (done)=>{ | ||
@@ -34,2 +43,270 @@ var test = sut.create("test") | ||
}) | ||
describe('toObj() API', ()=>{ | ||
it('Should log all properties', ()=>{ | ||
expect(sut.toObj()).to.have.property('name', 'sut'); | ||
expect(sut.toObj()).to.have.property('guid', sut.guid()); | ||
expect(sut.toObj()).to.have.property('status', sut.status()); | ||
}) | ||
it('Should log listeners', ()=>{ | ||
sut | ||
.on('foo',()=>{}) | ||
.on('bar',()=>{},function namedFunction(){}) | ||
expect(sut.toObj()).to.have.deep.property('listeners.foo'); | ||
expect(sut.toObj()).to.have.deep.property('listeners.bar'); | ||
expect(sut.toObj().listeners.bar).to.contain('function') | ||
expect(sut.toObj().listeners.bar).to.contain('namedFunction') | ||
}) | ||
it('Should log filtered properties', ()=>{ | ||
expect(sut.toObj('name', 'guid')).to.have.property('name', 'sut'); | ||
expect(sut.toObj('name', 'guid')).to.have.property('guid', sut.guid()); | ||
expect(sut.toObj('name', 'guid')).not.to.have.property('status'); | ||
}) | ||
}) | ||
describe('Remote Logger API', ()=>{ | ||
it('Should use remote logger', (done)=>{ | ||
var test = sut.create("test") | ||
flow.logger(log=>{ | ||
if (test.done) return; | ||
test.done = true | ||
console.log(log) | ||
expect(log.flow.guid).to.eql(test.guid()) | ||
done() | ||
},true) | ||
test.parent(null) | ||
}) | ||
it('Should log .create() API', (done)=>{ | ||
var test = sut.create("test") | ||
flow.logger(log=>{ | ||
expect(log.action).to.equal('create') | ||
expect(log.flow.name).to.equal('test') | ||
expect(log.d.name).to.equal('bar') | ||
done() | ||
},true) | ||
test.create('bar') | ||
}) | ||
it('Should log .create() API with data', (done)=>{ | ||
var test = sut.create("test") | ||
flow.logger(log=>{ | ||
expect(log.d.name).to.equal('bar') | ||
expect(log.d.data).to.equal('"data1"') | ||
done() | ||
},true) | ||
test.create('bar','data1') | ||
}) | ||
it('Should log .create() API with multi data', (done)=>{ | ||
var test = sut.create("test") | ||
flow.logger(log=>{ | ||
expect(log.d.name).to.equal('bar') | ||
expect(log.d.data).to.equal('["data1","data2"]') | ||
done() | ||
},true) | ||
test.create('bar','data1', 'data2') | ||
}) | ||
it('Should log .name() API', (done)=>{ | ||
var test = sut.create("test") | ||
flow.logger(log=>{ | ||
expect(log.action).to.equal('name') | ||
expect(log.d).to.equal('"bar"') | ||
expect(log.d0).to.equal('"test"') | ||
done() | ||
},true) | ||
test.name('bar') | ||
}) | ||
it('Should log .data(x) API', (done)=>{ | ||
var test = sut.create("test", "foo") | ||
flow.logger(log=>{ | ||
expect(log.action).to.equal('data') | ||
expect(log.d).to.equal('"bar"') | ||
expect(log.d0).to.equal('"foo"') | ||
done() | ||
},true) | ||
test.data('bar') | ||
}) | ||
it('Should log .data(...args) API', (done)=>{ | ||
var test = sut.create("test", "foo","bar") | ||
flow.logger(log=>{ | ||
expect(log.action).to.equal('data') | ||
expect(log.d).to.equal('["dog","cat"]') | ||
expect(log.d0).to.equal('["foo","bar"]') | ||
flow.logger.reset() | ||
done() | ||
},true) | ||
test.data('dog','cat') | ||
}) | ||
it('Should log unparenting (.parent(null))', (done)=>{ | ||
var test = sut.create("test", "foo") | ||
flow.logger(log=>{ | ||
expect(log.action).to.equal('parent') | ||
expect(log.d).to.equal(undefined) | ||
expect(log.d0.name).to.equal('sut') | ||
flow.logger.reset() | ||
done() | ||
},true) | ||
test.parent(null) | ||
}) | ||
it('Should log reparenting (.parent(node))', (done)=>{ | ||
var test = sut.create("test", "foo") | ||
var test2 = sut.create('test2') | ||
flow.logger(log=>{ | ||
expect(log.action).to.equal('parent') | ||
expect(log.d.name).to.equal('test2') | ||
expect(log.d0.name).to.equal('sut') | ||
flow.logger.reset() | ||
done() | ||
},true) | ||
test.parent(test2) | ||
}) | ||
it('Should log .emit() API', (done)=>{ | ||
var test = sut.create("test") | ||
flow.logger(log=>{ | ||
expect(log.action).to.equal('emit') | ||
expect(log.flow.name).to.equal('sut') | ||
expect(log.d.name).to.equal('test') | ||
flow.logger.reset() | ||
done() | ||
},true) | ||
test.emit() | ||
}) | ||
it('Should log .emit("foo") API', (done)=>{ | ||
var test = sut.create("test") | ||
flow.logger(log=>{ | ||
if (log.action=='create') return; | ||
expect(log.action).to.equal('emit') | ||
expect(log.flow.name).to.equal('test') | ||
expect(log.d.name).to.equal('foo') | ||
flow.logger.reset() | ||
done() | ||
},true) | ||
test.emit('foo') | ||
}) | ||
it('Should log .emitted("foo") API', (done)=>{ | ||
var test = sut.create("test") | ||
.on('foo',()=>{ | ||
flow.logger(log=>{ | ||
let recipient = log.d.recipients[0] | ||
expect(log.action).to.equal('emitted') | ||
expect(log.flow.name).to.equal('test') | ||
expect(log.d.name).to.equal('foo') | ||
expect(recipient.flow.name).to.equal('test') | ||
expect(recipient.route.map(f=>f.flow.name).join()) | ||
.to.equal('foo,test') | ||
flow.logger.reset() | ||
done() | ||
},true) | ||
}) | ||
test.emit('foo') | ||
}) | ||
it('Should log .direction("foo") API', (done)=>{ | ||
var test = sut.create("test") | ||
flow.logger(log=>{ | ||
expect(log.action).to.equal('direction') | ||
expect(log.flow.name).to.equal('test') | ||
expect(log.d).to.equal('"UPSTREAM"') | ||
expect(log.d0).to.equal('"DEFAULT"') | ||
flow.logger.reset() | ||
done() | ||
},true) | ||
test.direction('UPSTREAM') | ||
}) | ||
}) | ||
describe('Remote Log Serialiser', ()=>{ | ||
it('Should serialise number', (done)=>{ | ||
var test = sut.create("test") | ||
flow.logger(log=>{ | ||
if (test.done) return; | ||
test.done = true | ||
expect(log.d).to.eql('55') | ||
done() | ||
},true) | ||
test.data(55) | ||
}) | ||
it('Should serialise String', (done)=>{ | ||
var test = sut.create("test") | ||
flow.logger(log=>{ | ||
if (test.done) return; | ||
test.done = true | ||
expect(log.d).to.eql('"hello"') | ||
done() | ||
},true) | ||
test.data('hello') | ||
}) | ||
it('Should serialise Object', (done)=>{ | ||
var test = sut.create("test") | ||
flow.logger(log=>{ | ||
if (test.done) return; | ||
test.done = true | ||
expect(log.d).to.eql('{"foo":"bar"}') | ||
done() | ||
},true) | ||
test.data({foo:'bar'}) | ||
}) | ||
it('Should serialise recursive Objects', (done)=>{ | ||
var test = sut.create("test") | ||
flow.logger(log=>{ | ||
if (test.done) return; | ||
test.done = true | ||
expect(log.d).to.eql('{"foo":{"o":"*Recursive0"}}') | ||
done() | ||
},true) | ||
let o = {foo:{}} | ||
o.foo.o = o | ||
test.data(o) | ||
}) | ||
it('Should serialise duplicate Objects', (done)=>{ | ||
var test = sut.create("test") | ||
flow.logger(log=>{ | ||
if (test.done) return; | ||
test.done = true | ||
expect(log.d).to.eql('{"foo":{},"bar":"*Recursive1"}') | ||
done() | ||
},true) | ||
let o = {foo:{}} | ||
o.bar = o.foo | ||
test.data(o) | ||
}) | ||
it('Should serialise Array', (done)=>{ | ||
var test = sut.create("test") | ||
flow.logger(log=>{ | ||
if (test.done) return; | ||
test.done = true | ||
expect(log.d).to.eql('[3,"four",5]') | ||
done() | ||
},true) | ||
test.data([3,'four',5]) | ||
}) | ||
it('Should serialise named Function', (done)=>{ | ||
var test = sut.create("test") | ||
flow.logger(log=>{ | ||
if (test.done) return; | ||
test.done = true | ||
expect(log.d).to.eql('"function foo(arg,arg){...}"') | ||
done() | ||
},true) | ||
test.data(function foo(a,b){}) | ||
}) | ||
it('Should serialise Date', (done)=>{ | ||
var test = sut.create("test") | ||
flow.logger(log=>{ | ||
if (test.done) return; | ||
test.done = true | ||
expect(log.d).to.eql('"1970-01-01T00:00:00.000Z"') | ||
done() | ||
},true) | ||
test.data(new Date(0)) | ||
}) | ||
}) | ||
}) |
import flow from 'nflow' | ||
import assert from 'assert' | ||
import {expect} from 'chai' | ||
let noop = ()=>{} | ||
var sut | ||
@@ -43,3 +45,3 @@ | ||
it('should record route to recipients', function(){ | ||
sut.on('test', ()=>{}) | ||
sut.on('test', noop) | ||
var a = sut.create('a') | ||
@@ -53,9 +55,23 @@ var b = sut.create('b') | ||
var recipient = d.emit.recipients[0] | ||
var recipientMap = recipient.route.map(f=>f.name()) | ||
var recipientMap = recipient.route.map(f=>f.flow.name()) | ||
expect(recipient.flow).to.eql(sut) | ||
expect(recipientMap.join()).to.eql(['sut','b','test'].join()) | ||
expect(recipientMap.join()).to.eql('test,b,sut') | ||
}) | ||
it('should not deliver to unreachable recipients', function(){ | ||
sut | ||
var a = sut.create('a') | ||
var b = sut.create('b') | ||
var c = a.create('c').on('test', noop) | ||
var e = b.create('e').on('test', noop) | ||
var d = b.emit.upstream('test') | ||
var recipients = d.emit.recipients | ||
expect(recipients.length).to.equal(0) | ||
}) | ||
}) | ||
describe('route.none() API', function(){ | ||
describe('route.current() API', function(){ | ||
it('should return event and current node', function(){ | ||
@@ -68,3 +84,3 @@ var f = sut | ||
var route = f.emit.route.NONE(f) | ||
var route = f.emit.route.CURRENT(f) | ||
var map = route.map(f=>f.flow.name()) | ||
@@ -85,3 +101,3 @@ expect(map).to.eql(['d','c']) | ||
var route = f.emit.route.NONE(f) | ||
var route = f.emit.route.CURRENT(f) | ||
var map = route.map(f=>f.flow.name()) | ||
@@ -92,13 +108,12 @@ expect(map).to.eql(['d','c']) | ||
it('should record route to recipients', function(){ | ||
sut.on('test', ()=>{}) | ||
sut.on('test', noop) | ||
var a = sut.create('a') | ||
.on('test', ()=>{}) | ||
var d = a.emit.none('test') | ||
.on('test', noop) | ||
var d = a.emit.current('test') | ||
var recipient = d.emit.recipients[0] | ||
var recipientMap = recipient.route.map(f=>f.name()) | ||
var recipientMap = recipient.route.map(f=>f.flow.name()) | ||
expect(recipient.flow).to.eql(a) | ||
expect(recipientMap.join()).to.eql(['a', 'test'].join()) | ||
expect(recipientMap.join()).to.eql('test,a') | ||
}) | ||
}) | ||
@@ -144,5 +159,5 @@ | ||
var c = a.create('c') | ||
.on('test', ()=>{}) | ||
.on('test', noop) | ||
var e = b.create('e') | ||
.on('test', ()=>{}) | ||
.on('test', noop) | ||
var d = sut.emit.downstream('test') | ||
@@ -152,8 +167,8 @@ | ||
var eTest = d.emit.recipients[1] | ||
var cMap = cTest.route.map(f=>f.name()) | ||
var eMap = eTest.route.map(f=>f.name()) | ||
var cMap = cTest.route.map(f=>f.flow.name()) | ||
var eMap = eTest.route.map(f=>f.flow.name()) | ||
expect(cTest.flow).to.eql(c) | ||
expect(eTest.flow).to.eql(e) | ||
expect(cMap.join()).to.eql(['c','a','sut','test'].join()) | ||
expect(eMap.join()).to.eql(['e','b','sut','test'].join()) | ||
expect(cMap.join()).to.eql('test,sut,a,c') | ||
expect(eMap.join()).to.eql('test,sut,b,e') | ||
}) | ||
@@ -183,57 +198,54 @@ }) | ||
}) | ||
it('should record route to recipients', function(){ | ||
it('should record upstream route to recipients', function(){ | ||
var a = sut.create('a') | ||
var b = sut.create('b') | ||
var c = a.create('c') | ||
.on('test', ()=>{}) | ||
var e = b.create('e') | ||
.on('test', ()=>{}) | ||
var d = b.emit('test') | ||
var b = a.create('b').on('test', noop) | ||
var c = b.create('c') | ||
var d = c.create('d') | ||
var cTest = d.emit.recipients[0] | ||
var eTest = d.emit.recipients[1] | ||
var cMap = cTest.route.map(f=>f.name()) | ||
var eMap = eTest.route.map(f=>f.name()) | ||
expect(cTest.flow).to.eql(c) | ||
expect(eTest.flow).to.eql(e) | ||
expect(cMap.join()).to.eql(['c','a','sut','b','test'].join()) | ||
expect(eMap.join()).to.eql(['e','b','sut','b','test'].join()) | ||
var test = d.emit('test') | ||
var testRecipients = test.emit.recipients[0] | ||
var map = testRecipients.route.map(f=>f.flow.name()) | ||
expect(testRecipients.flow).to.eql(b) | ||
expect(map.join()).to.eql('test,d,c,b') | ||
}) | ||
describe('foo', ()=>{ | ||
it('should traverse events', function(){ | ||
sut.on('test', ()=>{}) | ||
it('should record route to recipients', function(){ | ||
var a = sut.create('a') | ||
.on('test', ()=>{ }) | ||
var test = a | ||
.emit('b') | ||
.emit('c') | ||
.emit('test') | ||
var route = test.emit.route.DEFAULT(test) | ||
var map = route.map(f=>f.flow.name()) | ||
console.log(map) | ||
expect(map.join()).to.eql('test,c,b,a,sut') | ||
}) | ||
it('should record route to upstream recipients', function(){ | ||
var b = a.create('b') | ||
var c0 = b.create('c0').on('test', noop) | ||
var c = b.create('c') | ||
var d = c.create('d') | ||
var a = sut.create('a') | ||
.on('test', ()=>{}) | ||
var test = a | ||
.emit('b') | ||
.emit('c') | ||
.emit('test') | ||
console.log(test.emit.recipients) | ||
var recipient = test.emit.recipients[0] | ||
var recipientMap = recipient.route.map(f=>f.name()) | ||
expect(recipient.flow).to.eql(a) | ||
expect(recipientMap.join()).to.eql('a,b,c,test') | ||
var test = d.emit('test') | ||
var testRecipients = test.emit.recipients[0] | ||
var map = testRecipients.route.map(f=>f.flow.name()) | ||
expect(testRecipients.flow).to.eql(c0) | ||
expect(map.join()).to.eql('test,d,c,b,a,sut,a,b,c0') | ||
}) | ||
it('should record route to detached recipients', function(){ | ||
var a = sut.create('a').on('test', noop) | ||
var b = a.create('b').emit() | ||
var c0 = b.create('c0').on('test', noop) | ||
var c = b.create('c') | ||
var d = c.create('d') | ||
var test = d.emit('test') | ||
var testRecipients0 = test.emit.recipients[0] | ||
var testRecipients1 = test.emit.recipients[1] | ||
var map0 = testRecipients0.route.map(f=>f.flow.name()) | ||
var map1 = testRecipients1.route.map(f=>f.flow.name()) | ||
expect(testRecipients0.flow.name()).to.eql('c0') | ||
expect(testRecipients1.flow.name()).to.eql('a') | ||
expect(map0.join()).to.eql('test,d,c,b,c0') | ||
expect(map1.join()).to.eql('test,d,c,b,a') | ||
}) | ||
}) | ||
}) |
@@ -0,1 +1,2 @@ | ||
import './spec/propagation.js' | ||
import './spec/cancellation.js' | ||
@@ -2,0 +3,0 @@ import './spec/connection.js' |
@@ -1,2 +0,3 @@ | ||
var package = require('./package.json') | ||
var webpack = require('webpack') | ||
var path = require('path'); | ||
@@ -32,2 +33,7 @@ var hostname = 'localhost' | ||
}, | ||
plugins:[ | ||
new webpack.DefinePlugin({ | ||
VERSION: JSON.stringify(package.version) | ||
}) | ||
], | ||
stats: { | ||
@@ -34,0 +40,0 @@ colors: true, |
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
2578640
51
25739
22