Skip to content

Commit 0cdc934

Browse files
refactor: added when method to stores
1 parent 2d2c798 commit 0cdc934

File tree

3 files changed

+46
-11
lines changed

3 files changed

+46
-11
lines changed

src/utils/specs/store.spec.js

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -147,10 +147,28 @@ test("can unsub self", () => {
147147
let received = null;
148148
const myStore = writable("initial");
149149
myStore.subscribe((val, unsub) => {
150-
received = val
151-
unsub()
152-
})
150+
received = val;
151+
unsub();
152+
});
153153
myStore.set("foo");
154154
myStore.set("bar");
155-
assert.equal(received, 'foo');
155+
assert.equal(received, "foo");
156+
});
157+
158+
test("when", async () => {
159+
let events = [];
160+
const myStore = writable("initial");
161+
162+
const promise = myStore.when("resolve-me").then((r) => events.push(r));
163+
assert.equal(myStore["_listeners"].length, 1);
164+
assert.deepEqual(events, []);
165+
166+
myStore.set("foobar");
167+
assert.deepEqual(events, []);
168+
assert.equal(myStore["_listeners"].length, 1);
169+
170+
myStore.set("resolve-me");
171+
await promise;
172+
assert.deepEqual(events, ["resolve-me"]);
173+
assert.equal(myStore["_listeners"].length, 0);
156174
});

src/utils/store.js

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -34,25 +34,26 @@ const storeOptions = {
3434
* @returns {Writable<T>}
3535
*/
3636
const writable = (initialValue, options) => {
37-
let _value = initialValue;
37+
let _storeValue = initialValue;
3838
const listeners = [];
3939
const _options = { ...storeOptions, ...options };
4040

4141
const store = {
42-
get: () => _value,
42+
_listeners: listeners,
43+
get: () => _storeValue,
4344
/** @param {T} value */
4445
set: (value) => {
45-
if (!_options.lazy || value !== _value) {
46-
_value = value;
46+
if (!_options.lazy || value !== _storeValue) {
47+
_storeValue = value;
4748

4849
for (const listener of [...listeners]) {
4950
const index = listeners.indexOf(listener);
5051
const unsub = () => listeners.splice(index, 1);
51-
listener(_value, unsub);
52+
listener(_storeValue, unsub);
5253
}
5354
}
5455
},
55-
update: (callback) => store.set(callback(_value)),
56+
update: (callback) => store.set(callback(_storeValue)),
5657
subscribe: (listener) => {
5758
if (!listeners.length) _options.onFirstSub(store);
5859
_options.onSub(store);
@@ -72,6 +73,21 @@ const writable = (initialValue, options) => {
7273
listener(value);
7374
});
7475
},
76+
when: (expected, strict) =>
77+
new Promise((resolve) => {
78+
const matchesExpected = (value) => value === expected || (!strict && value == expected);
79+
if (matchesExpected(_storeValue)) {
80+
console.log("resolved");
81+
resolve(_storeValue);
82+
} else {
83+
const unsub = store.subscribe((newValue) => {
84+
if (matchesExpected(newValue)) {
85+
unsub();
86+
resolve(newValue);
87+
}
88+
});
89+
}
90+
}),
7591
};
7692
return store;
7793
};

types/store.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
* @prop {function(function(T):T):void} update Update the store value
1212
* @prop {function((payload: T, unsub: Unsubscribe)=>void):Unsubscribe} subscribe Subscribe to the store value
1313
* @prop {function(function(T):void):void} next Subscribe to the store value for a single update
14+
* @prop {(expected: T, strict?: boolean)=>Promise<T>} when Returns a promise which resolves when the store value matches the expected value
1415
*/
1516

1617
/**
@@ -39,4 +40,4 @@
3940
/**
4041
* @template T
4142
* @typedef {{ [K in keyof T]: T[K] extends Readable<infer U> ? U : never }} StoreValues
42-
*/
43+
*/

0 commit comments

Comments
 (0)