import { run_all, noop, get_store_value, safe_not_equal } from './internal'; export function readable(value, start) { return { subscribe: writable(value, start).subscribe }; } export function writable(value, start = noop) { let stop; const subscribers = []; function set(new_value) { if (safe_not_equal(value, new_value)) { value = new_value; if (!stop) return; // not ready subscribers.forEach(s => s[1]()); subscribers.forEach(s => s[0](value)); } } function update(fn) { set(fn(value)); } function subscribe(run, invalidate = noop) { const subscriber = [run, invalidate]; subscribers.push(subscriber); if (subscribers.length === 1) stop = start(set) || noop; run(value); return () => { const index = subscribers.indexOf(subscriber); if (index !== -1) subscribers.splice(index, 1); if (subscribers.length === 0) stop(); }; } return { set, update, subscribe }; } export function derived(stores, fn, initial_value) { const single = !Array.isArray(stores); if (single) stores = [stores]; const auto = fn.length < 2; let value = {}; return readable(initial_value, set => { let inited = false; const values = []; let pending = 0; const sync = () => { if (pending) return; const result = fn(single ? values[0] : values, set); if (auto && (value !== (value = result))) set(result); }; const unsubscribers = stores.map((store, i) => store.subscribe( value => { values[i] = value; pending &= ~(1 << i); if (inited) sync(); }, () => { pending |= (1 << i); }) ); inited = true; sync(); return function stop() { run_all(unsubscribers); }; }); } export { get_store_value as get };