diff --git a/store.mjs b/store.mjs index 10bdad3626..5f005f15d5 100644 --- a/store.mjs +++ b/store.mjs @@ -34,7 +34,8 @@ export function readable(start, value) { }; } -export function writable(value) { +export function writable(value, start = noop) { + let stop; const subscribers = []; function set(newValue) { @@ -51,11 +52,13 @@ export function writable(value) { function subscribe(run, invalidate = noop) { const subscriber = [run, invalidate]; subscribers.push(subscriber); + if (subscribers.length === 1) stop = start() || noop; run(value); return () => { const index = subscribers.indexOf(subscriber); if (index !== -1) subscribers.splice(index, 1); + if (subscribers.length === 0) stop(); }; } diff --git a/test/store/index.js b/test/store/index.js index fb518cf24d..f4f89bf9a8 100644 --- a/test/store/index.js +++ b/test/store/index.js @@ -21,6 +21,27 @@ describe('store', () => { assert.deepEqual(values, [0, 1, 2]); }); + + it('calls provided subscribe handler', () => { + let called = 0; + + const store = writable(0, () => { + called += 1; + return () => called -= 1; + }); + + const unsubscribe1 = store.subscribe(() => {}); + assert.equal(called, 1); + + const unsubscribe2 = store.subscribe(() => {}); + assert.equal(called, 1); + + unsubscribe1(); + assert.equal(called, 1); + + unsubscribe2(); + assert.equal(called, 0); + }); }); describe('readable', () => {