(function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : typeof define === 'function' && define.amd ? define(['exports'], factory) : (factory((global.svelte = global.svelte || {}))); }(this, (function (exports) { 'use strict'; function assign(tar, src) { for (var k in src) tar[k] = src[k]; return tar; } function blankObject() { return Object.create(null); } function _differs(a, b) { return a != a ? b == b : a !== b || ((a && typeof a === 'object') || typeof a === 'function'); } function _differsImmutable(a, b) { return a != a ? b == b : a !== b; } function fire(eventName, data) { var handlers = eventName in this._handlers && this._handlers[eventName].slice(); if (!handlers) return; for (var i = 0; i < handlers.length; i += 1) { var handler = handlers[i]; if (!handler.__calling) { try { handler.__calling = true; handler.call(this, data); } finally { handler.__calling = false; } } } } function get() { return this._state; } function on(eventName, handler) { var handlers = this._handlers[eventName] || (this._handlers[eventName] = []); handlers.push(handler); return { cancel: function() { var index = handlers.indexOf(handler); if (~index) handlers.splice(index, 1); } }; } function Store(state, options) { this._handlers = {}; this._dependents = []; this._computed = blankObject(); this._sortedComputedProperties = []; this._state = assign({}, state); this._differs = options && options.immutable ? _differsImmutable : _differs; } assign(Store.prototype, { _add(component, props) { this._dependents.push({ component: component, props: props }); }, _init(props) { const state = {}; for (let i = 0; i < props.length; i += 1) { const prop = props[i]; state['$' + prop] = this._state[prop]; } return state; }, _remove(component) { let i = this._dependents.length; while (i--) { if (this._dependents[i].component === component) { this._dependents.splice(i, 1); return; } } }, _set(newState, changed) { const previous = this._state; this._state = assign(assign({}, previous), newState); for (let i = 0; i < this._sortedComputedProperties.length; i += 1) { this._sortedComputedProperties[i].update(this._state, changed); } this.fire('state', { changed, previous, current: this._state }); this._dependents .filter(dependent => { const componentState = {}; let dirty = false; for (let j = 0; j < dependent.props.length; j += 1) { const prop = dependent.props[j]; if (prop in changed) { componentState['$' + prop] = this._state[prop]; dirty = true; } } if (dirty) { dependent.component._stage(componentState); return true; } }) .forEach(dependent => { dependent.component.set({}); }); this.fire('update', { changed, previous, current: this._state }); }, _sortComputedProperties() { const computed = this._computed; const sorted = this._sortedComputedProperties = []; const visited = blankObject(); let currentKey; function visit(key) { const c = computed[key]; if (c) { c.deps.forEach(dep => { if (dep === currentKey) { throw new Error(`Cyclical dependency detected between ${dep} <-> ${key}`); } visit(dep); }); if (!visited[key]) { visited[key] = true; sorted.push(c); } } } for (const key in this._computed) { visit(currentKey = key); } }, compute(key, deps, fn) { let value; const c = { deps, update: (state, changed, dirty) => { const values = deps.map(dep => { if (dep in changed) dirty = true; return state[dep]; }); if (dirty) { const newValue = fn.apply(null, values); if (this._differs(newValue, value)) { value = newValue; changed[key] = true; state[key] = value; } } } }; this._computed[key] = c; this._sortComputedProperties(); const state = assign({}, this._state); const changed = {}; c.update(state, changed, true); this._set(state, changed); }, fire, get, on, set(newState) { const oldState = this._state; const changed = this._changed = {}; let dirty = false; for (const key in newState) { if (this._computed[key]) throw new Error(`'${key}' is a read-only computed property`); if (this._differs(newState[key], oldState[key])) changed[key] = dirty = true; } if (!dirty) return; this._set(newState, changed); } }); exports.Store = Store; Object.defineProperty(exports, '__esModule', { value: true }); })));