From 691944e9f8aad5a140296670f5afc38a262a8ee4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=94=D0=B0=D0=BC=D1=98=D0=B0=D0=BD=20=D0=93=D0=B5=D0=BE?= =?UTF-8?q?=D1=80=D0=B3=D0=B8=D0=B5=D0=B2=D1=81=D0=BA=D0=B8?= Date: Tue, 28 Dec 2021 02:24:35 +0100 Subject: [PATCH] store subscribers shouldn't get the initial undefined value before this, an empty, uninitialized store would emit an `undefined` value, even before any value is set. this is quite unexpected and not the same behaviour as rxjs (for example). you can still explicitly create a store with undefined with `writeable(undefined)` or `readable(undefined)` Previously: ``` > var store = require('./store'); > var w = store.writable(); > w.subscribe(v=>console.log('v:', v)); v: undefined ``` After this commit: ``` > var store = require('./store'); > var w = store.writable(); > w.subscribe(v=>console.log('v:', v)); > w.set('test'); v: test ``` --- src/runtime/store/index.ts | 5 ++++- test/store/index.ts | 22 ++++++++++++++++++---- 2 files changed, 22 insertions(+), 5 deletions(-) diff --git a/src/runtime/store/index.ts b/src/runtime/store/index.ts index e947fa0740..f92f83d2d3 100644 --- a/src/runtime/store/index.ts +++ b/src/runtime/store/index.ts @@ -65,8 +65,11 @@ export function writable(value?: T, start: StartStopNotifier = noop): Writ let stop: Unsubscriber; const subscribers: Set> = new Set(); + let runOnSubscribe = value !== undefined; + function set(new_value: T): void { if (safe_not_equal(value, new_value)) { + runOnSubscribe = true; value = new_value; if (stop) { // store is ready const run_queue = !subscriber_queue.length; @@ -94,7 +97,7 @@ export function writable(value?: T, start: StartStopNotifier = noop): Writ if (subscribers.size === 1) { stop = start(set) || noop; } - run(value); + if (runOnSubscribe) run(value); return () => { subscribers.delete(subscriber); diff --git a/test/store/index.ts b/test/store/index.ts index b6fc5940e1..76e38fe610 100644 --- a/test/store/index.ts +++ b/test/store/index.ts @@ -22,7 +22,7 @@ describe('store', () => { assert.deepEqual(values, [0, 1, 2]); }); - it('creates an undefined writable store', () => { + it('creates an empty writable store', () => { const store = writable(); const values = []; @@ -32,9 +32,23 @@ describe('store', () => { unsubscribe(); - assert.deepEqual(values, [undefined]); + assert.deepEqual(values, []); }); + it('creates a null writable store', () => { + const store = writable(null); + const values = []; + + const unsubscribe = store.subscribe(value => { + values.push(value); + }); + + unsubscribe(); + + assert.deepEqual(values, [null]); + }); + + it('calls provided subscribe handler', () => { let called = 0; @@ -128,7 +142,7 @@ describe('store', () => { assert.deepEqual(values, [0, 1, 2]); }); - it('creates an undefined readable store', () => { + it('creates an empty readable store', () => { const store = readable(); const values = []; @@ -138,7 +152,7 @@ describe('store', () => { unsubscribe(); - assert.deepEqual(values, [undefined]); + assert.deepEqual(values, []); }); it('creates a readable store without updater', () => {