seitu
Version:
57 lines (56 loc) • 1.4 kB
JavaScript
import { createReadableSubscription, createSubscription } from "../subscription/index.mjs";
//#region src/core/debounced/index.ts
/**
* Debounces updates from a source. Unsubscribed `get()` reads through;
* subscribed `get()` returns the last emitted value.
*
* @example
* ```ts twoslash
* import { createStore, createDebounced } from 'seitu'
*
* const store = createStore('')
* const debounced = createDebounced(store, 300)
* debounced.subscribe(value => console.log('debounced:', value))
* debounced.flush()
* ```
*/
function createDebounced(source, wait) {
let state = source.get();
let timeoutId;
let active = false;
const cancel = () => {
clearTimeout(timeoutId);
timeoutId = void 0;
};
const { subscribe, notify } = createSubscription({ onFirstSubscribe() {
state = source.get();
active = true;
const unsubscribe = source.subscribe(() => {
clearTimeout(timeoutId);
timeoutId = setTimeout(() => {
timeoutId = void 0;
state = source.get();
notify();
}, wait);
});
return () => {
cancel();
active = false;
unsubscribe();
};
} });
const flush = () => {
if (timeoutId === void 0) return;
cancel();
state = source.get();
notify();
};
const get = () => active ? state : source.get();
return {
...createReadableSubscription(get, subscribe, notify, source.getServer),
cancel,
flush
};
}
//#endregion
export { createDebounced };