UNPKG

fluxx

Version:

Terse application state management

101 lines (77 loc) 2.81 kB
'use strict'; exports.__esModule = true; exports.GlobalStore = GlobalStore; exports.LocalStore = LocalStore; exports.default = Store; var storeId = 1; var stores = exports.stores = {}; function GlobalStore(optionsOrInitialState, registerHandlers) { return Store(optionsOrInitialState, registerHandlers, true); } function LocalStore(optionsOrInitialState, registerHandlers) { return Store(optionsOrInitialState, registerHandlers); } function Store(optionsOrInitialState, registerHandlers, isGlobal) { var _ref = registerHandlers ? {} : optionsOrInitialState; var handlers = _ref.handlers; var initialState = registerHandlers ? optionsOrInitialState : optionsOrInitialState.state; var onHandlers = {}; var dispatching = false; var callbacks = []; var disposeCb = undefined; var instance = { state: initialState, log: Store.log, onDispose: function onDispose(cb) { disposeCb = cb;return instance; } }; instance.id = storeId++; stores[instance.id] = instance; // on(action, callback) registration style if (registerHandlers) { var on = function on(action, fn) { onHandlers[action] = fn; }; registerHandlers(on); } instance._handleAction = function (action, payloads) { if (dispatching) throw new Error('Cannot dispatch an Action in the middle of another Action\'s dispatch'); // Bail fast if this store isn't interested. var handler = handlers ? handlers[action._id] : onHandlers[action._id]; if (!handler) return; dispatching = true; if (instance.log) { var payload = payloads.length > 1 ? payloads : payloads[0]; console.log('%c' + action._name, 'color: #F51DE3', 'dispatched with payload ', payload); } var previousState = instance.state; try { instance.state = handlers ? handler.apply(null, [instance.state].concat(payloads)) : handler(instance.state, payloads[0]); } finally { if (instance.log) { var storeKind = isGlobal ? 'global' : 'local'; console.log('%cNew ' + storeKind + ' state:', 'color: blue', instance.state); } dispatching = false; } if (previousState !== instance.state) callbacks.forEach(function (callback) { return callback(instance.state); }); }; instance.subscribe = function (callback) { callbacks.push(callback); if (instance.log) console.log('%cInitial state:', 'color: green', initialState); return function unsubscribe() { callbacks = callbacks.filter(function (_callback) { return _callback !== callback; }); // Global stores remain active forever, but not local stores if (!isGlobal && callbacks.length === 0) { delete stores[instance.id]; if (disposeCb) disposeCb(); } }; }; return instance; }