shelving 1.195.1 → 1.196.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/store/PayloadFetchStore.d.ts +2 -1
- package/store/PayloadFetchStore.js +12 -2
- package/util/async.d.ts +8 -0
- package/util/async.js +15 -0
package/package.json
CHANGED
|
@@ -8,6 +8,7 @@ export type PayloadFetchCallback<P, R> = (payload: P, signal: AbortSignal) => R
|
|
|
8
8
|
* @param payload The initial payload for the store.
|
|
9
9
|
* @param value The initial value for the store, or `NONE` if it does not have one yet.
|
|
10
10
|
* @param callback An optional callback that, if set, will be called with the current payload when the `fetch()` method is invoked to fetch the next value.
|
|
11
|
+
* @param debounce Delay in milliseconds before the fetch is triggered after a payload change. `busy` becomes `true` immediately; the actual fetch waits for the debounce period to expire. If the payload changes again before the delay expires the previous fetch is cancelled and the timer resets.
|
|
11
12
|
*/
|
|
12
13
|
export declare class PayloadFetchStore<P, R> extends FetchStore<R> {
|
|
13
14
|
/**
|
|
@@ -15,6 +16,6 @@ export declare class PayloadFetchStore<P, R> extends FetchStore<R> {
|
|
|
15
16
|
* - New payloads can be set using `this.payload.value`
|
|
16
17
|
*/
|
|
17
18
|
readonly payload: Store<P>;
|
|
18
|
-
constructor(payload: P, value: R | typeof NONE, callback?: PayloadFetchCallback<P, R
|
|
19
|
+
constructor(payload: P, value: R | typeof NONE, callback?: PayloadFetchCallback<P, R>, debounce?: number);
|
|
19
20
|
[Symbol.asyncDispose](): Promise<void>;
|
|
20
21
|
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { awaitAbort, getDelay } from "../util/async.js";
|
|
1
2
|
import { awaitDispose } from "../util/dispose.js";
|
|
2
3
|
import { FetchStore } from "./FetchStore.js";
|
|
3
4
|
import { Store } from "./Store.js";
|
|
@@ -7,6 +8,7 @@ import { Store } from "./Store.js";
|
|
|
7
8
|
* @param payload The initial payload for the store.
|
|
8
9
|
* @param value The initial value for the store, or `NONE` if it does not have one yet.
|
|
9
10
|
* @param callback An optional callback that, if set, will be called with the current payload when the `fetch()` method is invoked to fetch the next value.
|
|
11
|
+
* @param debounce Delay in milliseconds before the fetch is triggered after a payload change. `busy` becomes `true` immediately; the actual fetch waits for the debounce period to expire. If the payload changes again before the delay expires the previous fetch is cancelled and the timer resets.
|
|
10
12
|
*/
|
|
11
13
|
export class PayloadFetchStore extends FetchStore {
|
|
12
14
|
/**
|
|
@@ -15,9 +17,17 @@ export class PayloadFetchStore extends FetchStore {
|
|
|
15
17
|
*/
|
|
16
18
|
payload;
|
|
17
19
|
// Override to save initial payload and callback.
|
|
18
|
-
constructor(payload, value, callback) {
|
|
20
|
+
constructor(payload, value, callback, debounce = 0) {
|
|
19
21
|
const payloadStore = new Store(payload);
|
|
20
|
-
|
|
22
|
+
const fetch = callback &&
|
|
23
|
+
(debounce > 0
|
|
24
|
+
? async (signal) => {
|
|
25
|
+
const snap = payloadStore.value;
|
|
26
|
+
await Promise.race([getDelay(debounce), awaitAbort(signal)]);
|
|
27
|
+
return callback(snap, signal);
|
|
28
|
+
}
|
|
29
|
+
: (signal) => callback(payloadStore.value, signal));
|
|
30
|
+
super(value, fetch);
|
|
21
31
|
this.payload = payloadStore;
|
|
22
32
|
void _iterate(this);
|
|
23
33
|
}
|
package/util/async.d.ts
CHANGED
|
@@ -62,3 +62,11 @@ export type Deferred<T = unknown> = {
|
|
|
62
62
|
export declare function getDeferred<T = void>(): Deferred<T>;
|
|
63
63
|
/** Get a promise that automatically resolves after a delay. */
|
|
64
64
|
export declare function getDelay(ms: number): Promise<void>;
|
|
65
|
+
/**
|
|
66
|
+
* Get a promise that rejects with the signal's reason when an `AbortSignal` fires.
|
|
67
|
+
* - Rejects immediately if the signal is already aborted.
|
|
68
|
+
* - Use with `Promise.race()` to cancel a concurrent operation when a signal fires.
|
|
69
|
+
*
|
|
70
|
+
* @example await Promise.race([getDelay(300), awaitAbort(signal)]);
|
|
71
|
+
*/
|
|
72
|
+
export declare function awaitAbort(signal: AbortSignal): Promise<never>;
|
package/util/async.js
CHANGED
|
@@ -110,3 +110,18 @@ export function getDeferred() {
|
|
|
110
110
|
export function getDelay(ms) {
|
|
111
111
|
return new Promise(resolve => setTimeout(resolve, ms));
|
|
112
112
|
}
|
|
113
|
+
/**
|
|
114
|
+
* Get a promise that rejects with the signal's reason when an `AbortSignal` fires.
|
|
115
|
+
* - Rejects immediately if the signal is already aborted.
|
|
116
|
+
* - Use with `Promise.race()` to cancel a concurrent operation when a signal fires.
|
|
117
|
+
*
|
|
118
|
+
* @example await Promise.race([getDelay(300), awaitAbort(signal)]);
|
|
119
|
+
*/
|
|
120
|
+
export function awaitAbort(signal) {
|
|
121
|
+
return new Promise((_, reject) => {
|
|
122
|
+
if (signal.aborted)
|
|
123
|
+
reject(signal.reason);
|
|
124
|
+
else
|
|
125
|
+
signal.addEventListener("abort", () => reject(signal.reason), { once: true });
|
|
126
|
+
});
|
|
127
|
+
}
|