UNPKG

reflux-core

Version:

A simple library for uni-directional dataflow application architecture inspired by ReactJS Flux

127 lines (113 loc) 4.36 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.staticJoinCreator = staticJoinCreator; exports.instanceJoinCreator = instanceJoinCreator; var _createStore = require("./createStore"); var _utils = require("./utils"); var _ = _interopRequireWildcard(_utils); function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } } /** * Internal module used to create static and instance join methods */ var slice = Array.prototype.slice, strategyMethodNames = { strict: "joinStrict", first: "joinLeading", last: "joinTrailing", all: "joinConcat" }; /** * Used in `index.js` to create the static join methods * @param {String} strategy Which strategy to use when tracking listenable trigger arguments * @returns {Function} A static function which returns a store with a join listen on the given listenables using the given strategy */ function staticJoinCreator(strategy) { return function () /* listenables... */{ var listenables = slice.call(arguments); return (0, _createStore.createStore)({ init: function init() { this[strategyMethodNames[strategy]].apply(this, listenables.concat("triggerAsync")); } }); }; } /** * Used in `ListenerMethods.js` to create the instance join methods * @param {String} strategy Which strategy to use when tracking listenable trigger arguments * @returns {Function} An instance method which sets up a join listen on the given listenables using the given strategy */ function instanceJoinCreator(strategy) { return function () /* listenables..., callback*/{ _.throwIf(arguments.length < 2, "Cannot create a join with less than 2 listenables!"); var listenables = slice.call(arguments), callback = listenables.pop(), numberOfListenables = listenables.length, join = { numberOfListenables: numberOfListenables, callback: this[callback] || callback, listener: this, strategy: strategy }, i, cancels = [], subobj; for (i = 0; i < numberOfListenables; i++) { _.throwIf(this.validateListening(listenables[i])); } for (i = 0; i < numberOfListenables; i++) { cancels.push(listenables[i].listen(newListener(i, join), this)); } reset(join); subobj = { listenable: listenables }; subobj.stop = makeStopper(subobj, cancels, this); this.subscriptions = (this.subscriptions || []).concat(subobj); return subobj; }; } // ---- internal join functions ---- function makeStopper(subobj, cancels, context) { return function () { var i, subs = context.subscriptions, index = subs ? subs.indexOf(subobj) : -1; _.throwIf(index === -1, "Tried to remove join already gone from subscriptions list!"); for (i = 0; i < cancels.length; i++) { cancels[i](); } subs.splice(index, 1); }; } function reset(join) { join.listenablesEmitted = new Array(join.numberOfListenables); join.args = new Array(join.numberOfListenables); } function newListener(i, join) { return function () { var callargs = slice.call(arguments); if (join.listenablesEmitted[i]) { switch (join.strategy) { case "strict": throw new Error("Strict join failed because listener triggered twice."); case "last": join.args[i] = callargs;break; case "all": join.args[i].push(callargs); } } else { join.listenablesEmitted[i] = true; join.args[i] = join.strategy === "all" ? [callargs] : callargs; } emitIfAllListenablesEmitted(join); }; } function emitIfAllListenablesEmitted(join) { for (var i = 0; i < join.numberOfListenables; i++) { if (!join.listenablesEmitted[i]) { return; } } join.callback.apply(join.listener, join.args); reset(join); }