From ed2a19aa67e511cab9f7db0229215adaff134ba5 Mon Sep 17 00:00:00 2001 From: Richard Harris Date: Tue, 4 Jun 2019 22:14:36 -0400 Subject: [PATCH] DRY out --- src/runtime/store/index.ts | 63 ++++++++++++++------------------------ 1 file changed, 23 insertions(+), 40 deletions(-) diff --git a/src/runtime/store/index.ts b/src/runtime/store/index.ts index f03a550c5f..6f14162115 100644 --- a/src/runtime/store/index.ts +++ b/src/runtime/store/index.ts @@ -112,12 +112,12 @@ type StoresValues = T extends Readable ? U : * applying an aggregation function over its input values. * @param {Stores} stores input stores * @param {function(Stores=, function(*)=):*}fn function callback that aggregates the values - * @param {*=}value initial value, when used asynchronously + * @param {*=}initial_value when used asynchronously */ export function derived( stores: S, fn: (values: StoresValues, set?: Subscriber) => T | Unsubscriber | void, - value?: T, + initial_value?: T, ): Readable { const single = !Array.isArray(stores); @@ -127,28 +127,14 @@ export function derived( const auto = fn.length < 2; - const subscribers: Array> = []; - let unsubscribers; - let cleanup = noop; - let running = false; - - function invalidate() { - subscribers.forEach(subscriber => subscriber[1]()); - } - - function set(current_value) { - value = current_value; - if (running) { - invalidate(); - subscribers.forEach(subscriber => subscriber[0](value)); - } - } + const invalidators: Array> = []; - function start() { + const store = readable(initial_value, (set) => { + let inited = false; const values: StoresValues = [] as StoresValues; let pending = 0; - running = false; + let cleanup = noop; const sync = () => { if (pending) { @@ -163,47 +149,44 @@ export function derived( } }; - unsubscribers = stores_array.map((store, i) => store.subscribe( + const unsubscribers = stores_array.map((store, i) => store.subscribe( (value) => { values[i] = value; pending &= ~(1 << i); - if (running) { + if (inited) { sync(); } }, () => { - invalidate(); + run_all(invalidators); pending |= (1 << i); }), ); + inited = true; sync(); - running = true; - } - function stop() { - run_all(unsubscribers); - cleanup(); - } + return function stop() { + run_all(unsubscribers); + cleanup(); + }; + }); return { subscribe(run: Subscriber, invalidate: Invalidater = noop): Unsubscriber { - const subscriber: SubscribeInvalidateTuple = [run, invalidate]; - subscribers.push(subscriber); - if (subscribers.length === 1) start(); - run(value); + invalidators.push(invalidate); + + const unsubscribe = store.subscribe(run, invalidate); return () => { - const index = subscribers.indexOf(subscriber); + const index = invalidators.indexOf(invalidate); if (index !== -1) { - subscribers.splice(index, 1); - } - if (subscribers.length === 0) { - stop(); + invalidators.splice(index, 1); } + unsubscribe(); }; } - }; + } } /** @@ -214,4 +197,4 @@ export function get(store: Readable): T { let value: T | undefined; store.subscribe((_: T) => value = _)(); return value as T; -} +} \ No newline at end of file