UNPKG

seitu

Version:
70 lines (69 loc) • 1.63 kB
import { createReadableSubscription, createSubscription } from "../subscription/index.mjs"; //#region src/core/throttled/index.ts /** * Throttles updates from a source to at most once per `wait` ms (leading, then * trailing). Unsubscribed `get()` reads through; subscribed `get()` returns the * last emitted value. * * @example * ```ts twoslash * import { createStore, createThrottled } from 'seitu' * * const store = createStore('') * const throttled = createThrottled(store, 300) * throttled.subscribe(value => console.log('throttled:', value)) * ``` */ function createThrottled(source, wait) { let state = source.get(); let timeoutId; let hasTrailing = false; let active = false; const cancel = () => { clearTimeout(timeoutId); timeoutId = void 0; hasTrailing = false; }; const { subscribe, notify } = createSubscription({ onFirstSubscribe() { state = source.get(); active = true; const unsubscribe = source.subscribe(() => { if (timeoutId) { hasTrailing = true; return; } state = source.get(); notify(); timeoutId = setTimeout(() => { timeoutId = void 0; if (hasTrailing) { hasTrailing = false; state = source.get(); notify(); } }, wait); }); return () => { cancel(); active = false; unsubscribe(); }; } }); const flush = () => { if (!hasTrailing) { cancel(); return; } cancel(); state = source.get(); notify(); }; const get = () => active ? state : source.get(); return { ...createReadableSubscription(get, subscribe, notify, source.getServer), cancel, flush }; } //#endregion export { createThrottled };