@develia/commons 0.4.22 → 0.4.24
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/dist/cjs/collections/cache-dictionary.js +2 -6
- package/dist/cjs/collections/cache-dictionary.js.map +1 -1
- package/dist/cjs/debouncer.js +121 -0
- package/dist/cjs/debouncer.js.map +1 -0
- package/dist/cjs/functions.js +0 -86
- package/dist/cjs/functions.js.map +1 -1
- package/dist/cjs/index.js +8 -1
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/keyed-debouncer.js +144 -0
- package/dist/cjs/keyed-debouncer.js.map +1 -0
- package/dist/cjs/result.js +3 -0
- package/dist/cjs/result.js.map +1 -0
- package/dist/cjs/triggers.js +103 -0
- package/dist/cjs/triggers.js.map +1 -0
- package/dist/cjs/utilities.js +27 -4
- package/dist/cjs/utilities.js.map +1 -1
- package/dist/esm/collections/cache-dictionary.js +2 -6
- package/dist/esm/collections/cache-dictionary.js.map +1 -1
- package/dist/esm/debouncer.js +118 -0
- package/dist/esm/debouncer.js.map +1 -0
- package/dist/esm/functions.js +0 -85
- package/dist/esm/functions.js.map +1 -1
- package/dist/esm/index.js +3 -0
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/keyed-debouncer.js +109 -0
- package/dist/esm/keyed-debouncer.js.map +1 -0
- package/dist/esm/result.js +2 -0
- package/dist/esm/result.js.map +1 -0
- package/dist/esm/triggers.js +98 -0
- package/dist/esm/triggers.js.map +1 -0
- package/dist/esm/utilities.js +27 -4
- package/dist/esm/utilities.js.map +1 -1
- package/dist/types/collections/cache-dictionary.d.ts.map +1 -1
- package/dist/types/debouncer.d.ts +60 -0
- package/dist/types/debouncer.d.ts.map +1 -0
- package/dist/types/functions.d.ts +5 -35
- package/dist/types/functions.d.ts.map +1 -1
- package/dist/types/index.d.ts +6 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/keyed-debouncer.d.ts +56 -0
- package/dist/types/keyed-debouncer.d.ts.map +1 -0
- package/dist/types/result.d.ts +11 -0
- package/dist/types/result.d.ts.map +1 -0
- package/dist/types/triggers.d.ts +64 -0
- package/dist/types/triggers.d.ts.map +1 -0
- package/dist/types/utilities.d.ts +8 -3
- package/dist/types/utilities.d.ts.map +1 -1
- package/dist/web/collections/cache-dictionary.js +2 -6
- package/dist/web/collections/cache-dictionary.js.map +1 -1
- package/dist/web/debouncer.js +118 -0
- package/dist/web/debouncer.js.map +1 -0
- package/dist/web/functions.js +0 -85
- package/dist/web/functions.js.map +1 -1
- package/dist/web/index.js +3 -0
- package/dist/web/index.js.map +1 -1
- package/dist/web/keyed-debouncer.js +109 -0
- package/dist/web/keyed-debouncer.js.map +1 -0
- package/dist/web/result.js +2 -0
- package/dist/web/result.js.map +1 -0
- package/dist/web/triggers.js +99 -0
- package/dist/web/triggers.js.map +1 -0
- package/dist/web/utilities.js +27 -4
- package/dist/web/utilities.js.map +1 -1
- package/package.json +3 -4
- package/src/collections/cache-dictionary.ts +2 -6
- package/src/debouncer.ts +135 -0
- package/src/functions.ts +5 -114
- package/src/index.ts +6 -0
- package/src/keyed-debouncer.ts +121 -0
- package/src/result.ts +6 -0
- package/src/triggers.ts +126 -0
- package/src/utilities.ts +30 -4
- package/dist/cjs/package.json +0 -3
|
@@ -41,9 +41,7 @@ class CacheDictionary {
|
|
|
41
41
|
delete this.expiration[key];
|
|
42
42
|
}
|
|
43
43
|
else {
|
|
44
|
-
|
|
45
|
-
expiration.setSeconds(expiration.getSeconds() + duration);
|
|
46
|
-
this.expiration[key] = expiration;
|
|
44
|
+
this.expiration[key] = this.calculateExpiration(duration);
|
|
47
45
|
}
|
|
48
46
|
}
|
|
49
47
|
/**
|
|
@@ -97,9 +95,7 @@ class CacheDictionary {
|
|
|
97
95
|
if (duration === null) {
|
|
98
96
|
return undefined;
|
|
99
97
|
}
|
|
100
|
-
|
|
101
|
-
expiration.setSeconds(expiration.getSeconds() + duration);
|
|
102
|
-
return expiration;
|
|
98
|
+
return new Date(Date.now() + duration * 1000);
|
|
103
99
|
}
|
|
104
100
|
}
|
|
105
101
|
exports.default = CacheDictionary;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cache-dictionary.js","sourceRoot":"","sources":["../../../src/collections/cache-dictionary.ts"],"names":[],"mappings":";;AAAA;;;GAGG;AACH,MAAqB,eAAe;IAMhC;;;OAGG;IACH,YAAY,WAAwC,IAAI,EAAE,kBAAiC,IAAI;QAC3F,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACzB,IAAI,CAAC,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QACjC,IAAI,CAAC,eAAe,GAAG,eAAe,CAAC;QACvC,IAAI,CAAC,UAAU,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IAC1C,CAAC;IAED;;;;OAIG;IACI,aAAa,CAAC,GAAW;QAC5B,OAAO,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;IAChC,CAAC;IAED;;;;OAIG;IACI,aAAa,CAAC,GAAW,EAAE,UAA4B;QAC1D,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,GAAG,UAAU,CAAC;IACtC,CAAC;IAED;;;;OAIG;IACI,WAAW,CAAC,GAAW,EAAE,QAAuB;QACnD,IAAI,QAAQ,KAAK,IAAI,EAAE,CAAC;YACpB,OAAO,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;QAChC,CAAC;aAAM,CAAC;YACJ,
|
|
1
|
+
{"version":3,"file":"cache-dictionary.js","sourceRoot":"","sources":["../../../src/collections/cache-dictionary.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * A dictionary-like structure with caching and expiration capabilities.\n * @template T - The type of the values stored in the cache.\n */\nexport default class CacheDictionary<T> {\n private readonly fallback: ((key: string) => T) | null;\n private readonly cache: { [key: string]: T };\n private readonly defaultDuration: number | null;\n private readonly expiration: { [key: string]: Date | undefined };\n\n /**\n * @param {((key: string) => T) | null} fallback - Optional function to call when a key is not found.\n * @param {number | null} defaultDuration - Default duration in seconds for cache items.\n */\n constructor(fallback: ((key: string) => T) | null = null, defaultDuration: number | null = null) {\n this.fallback = fallback;\n this.cache = Object.create(null);\n this.defaultDuration = defaultDuration;\n this.expiration = Object.create(null);\n }\n\n /**\n * Gets the expiration date for a specific key.\n * @param {string} key - The key.\n * @returns {Date | undefined} The expiration date or undefined.\n */\n public getExpiration(key: string): Date | undefined {\n return this.expiration[key];\n }\n\n /**\n * Sets a specific expiration date for a key.\n * @param {string} key - The key.\n * @param {Date | undefined} expiration - The expiration date.\n */\n public setExpiration(key: string, expiration: Date | undefined): void {\n this.expiration[key] = expiration;\n }\n\n /**\n * Sets a duration in seconds for a key's expiration.\n * @param {string} key - The key.\n * @param {number | null} duration - Duration in seconds. If null, expiration is removed.\n */\n public setDuration(key: string, duration: number | null): void {\n if (duration === null) {\n delete this.expiration[key];\n } else {\n this.expiration[key] = this.calculateExpiration(duration);\n }\n }\n\n /**\n * Gets a value from the cache. If not found and a fallback exists, it uses the fallback.\n * If the item is expired, it's removed and null is returned.\n * @param {string} key - The key to retrieve.\n * @returns {T | null} The value or null if not found/expired.\n */\n public get(key: string): T | null {\n if (!Object.prototype.hasOwnProperty.call(this.cache, key)) {\n if (this.fallback) {\n this.cache[key] = this.fallback(key);\n this.expiration[key] = this.calculateExpiration(this.defaultDuration);\n } else {\n return null;\n }\n }\n\n if (this.isExpired(key)) {\n this.remove(key);\n return null;\n }\n\n return this.cache[key];\n }\n\n /**\n * Sets a value in the cache with an optional duration.\n * @param {string} key - The key.\n * @param {T} value - The value to store.\n * @param {number | null} duration - Duration in seconds.\n */\n public set(key: string, value: T, duration: number | null = null): void {\n this.cache[key] = value;\n this.expiration[key] = this.calculateExpiration(duration);\n }\n\n /**\n * Removes an item from the cache.\n * @param {string} key - The key to remove.\n */\n public remove(key: string): void {\n delete this.cache[key];\n delete this.expiration[key];\n }\n\n private isExpired(key: string): boolean {\n const expiration = this.expiration[key];\n if (expiration instanceof Date) {\n return expiration < new Date();\n }\n return false;\n }\n\n private calculateExpiration(duration: number | null): Date | undefined {\n if (duration === null) {\n return undefined;\n }\n\n return new Date(Date.now() + duration * 1000);\n }\n}"]}
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
|
|
3
|
+
if (kind === "m") throw new TypeError("Private method is not writable");
|
|
4
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
|
|
5
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
|
|
6
|
+
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
|
|
7
|
+
};
|
|
8
|
+
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
|
|
9
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
|
|
10
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
11
|
+
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
12
|
+
};
|
|
13
|
+
var _Debouncer_instances, _Debouncer_controller, _Debouncer_delayMs, _Debouncer_onSchedule, _Debouncer_onStart, _Debouncer_onSuccess, _Debouncer_onCancel, _Debouncer_onError, _Debouncer_onIdle, _Debouncer_run, _Debouncer_becomeIdle;
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.assertValidDelay = assertValidDelay;
|
|
16
|
+
const utilities_js_1 = require("./utilities.js");
|
|
17
|
+
const functions_js_1 = require("./functions.js");
|
|
18
|
+
/**
|
|
19
|
+
* Keeps at most one live task.
|
|
20
|
+
* Scheduling a new task cancels the previous one, whether it was still
|
|
21
|
+
* waiting or already running.
|
|
22
|
+
*
|
|
23
|
+
* @example
|
|
24
|
+
* ```ts
|
|
25
|
+
* const debouncer = new Debouncer({delayMs: 1500});
|
|
26
|
+
*
|
|
27
|
+
* debouncer.schedule(async (signal) => {
|
|
28
|
+
* const reply = await callAI(messages, {signal});
|
|
29
|
+
* if (signal.aborted) return;
|
|
30
|
+
* await sendReply(reply);
|
|
31
|
+
* });
|
|
32
|
+
* ```
|
|
33
|
+
*/
|
|
34
|
+
class Debouncer {
|
|
35
|
+
constructor(options) {
|
|
36
|
+
_Debouncer_instances.add(this);
|
|
37
|
+
_Debouncer_controller.set(this, void 0);
|
|
38
|
+
_Debouncer_delayMs.set(this, void 0);
|
|
39
|
+
_Debouncer_onSchedule.set(this, void 0);
|
|
40
|
+
_Debouncer_onStart.set(this, void 0);
|
|
41
|
+
_Debouncer_onSuccess.set(this, void 0);
|
|
42
|
+
_Debouncer_onCancel.set(this, void 0);
|
|
43
|
+
_Debouncer_onError.set(this, void 0);
|
|
44
|
+
_Debouncer_onIdle.set(this, void 0);
|
|
45
|
+
assertValidDelay(options.delayMs);
|
|
46
|
+
__classPrivateFieldSet(this, _Debouncer_delayMs, options.delayMs, "f");
|
|
47
|
+
__classPrivateFieldSet(this, _Debouncer_onSchedule, options.onSchedule ?? functions_js_1.noop, "f");
|
|
48
|
+
__classPrivateFieldSet(this, _Debouncer_onStart, options.onStart ?? functions_js_1.noop, "f");
|
|
49
|
+
__classPrivateFieldSet(this, _Debouncer_onSuccess, options.onSuccess ?? functions_js_1.noop, "f");
|
|
50
|
+
__classPrivateFieldSet(this, _Debouncer_onCancel, options.onCancel ?? functions_js_1.noop, "f");
|
|
51
|
+
__classPrivateFieldSet(this, _Debouncer_onError, options.onError ?? console.error, "f");
|
|
52
|
+
__classPrivateFieldSet(this, _Debouncer_onIdle, options.onIdle ?? functions_js_1.noop, "f");
|
|
53
|
+
}
|
|
54
|
+
/** Whether a task is waiting or running. */
|
|
55
|
+
get isPending() {
|
|
56
|
+
return __classPrivateFieldGet(this, _Debouncer_controller, "f") !== undefined;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Schedule `task`, cancelling any previous task.
|
|
60
|
+
*
|
|
61
|
+
* @param task - The task to run once the delay elapses.
|
|
62
|
+
* @param delayMs - Wait for this task only. Defaults to the configured `delayMs`.
|
|
63
|
+
*/
|
|
64
|
+
schedule(task, delayMs = __classPrivateFieldGet(this, _Debouncer_delayMs, "f")) {
|
|
65
|
+
assertValidDelay(delayMs);
|
|
66
|
+
if (__classPrivateFieldGet(this, _Debouncer_controller, "f") !== undefined) {
|
|
67
|
+
__classPrivateFieldGet(this, _Debouncer_controller, "f").abort();
|
|
68
|
+
__classPrivateFieldGet(this, _Debouncer_onCancel, "f").call(this);
|
|
69
|
+
}
|
|
70
|
+
const controller = new AbortController();
|
|
71
|
+
__classPrivateFieldSet(this, _Debouncer_controller, controller, "f");
|
|
72
|
+
__classPrivateFieldGet(this, _Debouncer_onSchedule, "f").call(this);
|
|
73
|
+
void __classPrivateFieldGet(this, _Debouncer_instances, "m", _Debouncer_run).call(this, task, delayMs, controller);
|
|
74
|
+
}
|
|
75
|
+
/** Cancel the current task, if any. */
|
|
76
|
+
cancel() {
|
|
77
|
+
if (__classPrivateFieldGet(this, _Debouncer_controller, "f") === undefined) {
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
__classPrivateFieldGet(this, _Debouncer_controller, "f").abort();
|
|
81
|
+
__classPrivateFieldGet(this, _Debouncer_onCancel, "f").call(this);
|
|
82
|
+
__classPrivateFieldGet(this, _Debouncer_instances, "m", _Debouncer_becomeIdle).call(this);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
_Debouncer_controller = new WeakMap(), _Debouncer_delayMs = new WeakMap(), _Debouncer_onSchedule = new WeakMap(), _Debouncer_onStart = new WeakMap(), _Debouncer_onSuccess = new WeakMap(), _Debouncer_onCancel = new WeakMap(), _Debouncer_onError = new WeakMap(), _Debouncer_onIdle = new WeakMap(), _Debouncer_instances = new WeakSet(), _Debouncer_run = async function _Debouncer_run(task, delayMs, controller) {
|
|
86
|
+
const signal = controller.signal;
|
|
87
|
+
try {
|
|
88
|
+
await (0, utilities_js_1.delay)(delayMs, signal);
|
|
89
|
+
__classPrivateFieldGet(this, _Debouncer_onStart, "f").call(this);
|
|
90
|
+
await task(signal);
|
|
91
|
+
if (!signal.aborted) {
|
|
92
|
+
__classPrivateFieldGet(this, _Debouncer_onSuccess, "f").call(this);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
catch (error) {
|
|
96
|
+
if (!signal.aborted) {
|
|
97
|
+
__classPrivateFieldGet(this, _Debouncer_onError, "f").call(this, error);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
finally {
|
|
101
|
+
// A replaced or cancelled task must not touch the current state.
|
|
102
|
+
if (__classPrivateFieldGet(this, _Debouncer_controller, "f") === controller) {
|
|
103
|
+
__classPrivateFieldGet(this, _Debouncer_instances, "m", _Debouncer_becomeIdle).call(this);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}, _Debouncer_becomeIdle = function _Debouncer_becomeIdle() {
|
|
107
|
+
__classPrivateFieldSet(this, _Debouncer_controller, undefined, "f");
|
|
108
|
+
__classPrivateFieldGet(this, _Debouncer_onIdle, "f").call(this);
|
|
109
|
+
};
|
|
110
|
+
exports.default = Debouncer;
|
|
111
|
+
/**
|
|
112
|
+
* Throw a `RangeError` unless `delayMs` is a finite number >= 0.
|
|
113
|
+
*
|
|
114
|
+
* @internal Shared with `KeyedDebouncer`; not part of the public API.
|
|
115
|
+
*/
|
|
116
|
+
function assertValidDelay(delayMs) {
|
|
117
|
+
if (!Number.isFinite(delayMs) || delayMs < 0) {
|
|
118
|
+
throw new RangeError(`delayMs must be a number >= 0 (received: ${delayMs})`);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
//# sourceMappingURL=debouncer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"debouncer.js","sourceRoot":"","sources":["../../src/debouncer.ts"],"names":[],"mappings":"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","sourcesContent":["import {delay} from \"./utilities.js\";\nimport {noop} from \"./functions.js\";\n\n/**\n * Cancellable task. It must honour `signal`: pass it to fetch/SDKs and check\n * `signal.aborted` before producing irreversible side effects.\n */\nexport type DebouncedTask = (signal: AbortSignal) => Promise<void>;\n\n/** Options accepted by {@link Debouncer}. */\nexport interface DebouncerOptions {\n /** Default wait, in milliseconds, before a task is executed. */\n delayMs: number;\n /** Called every time a task is scheduled, after any previous task has been cancelled. */\n onSchedule?: () => void;\n /** Called when the wait elapses and the task is about to run. */\n onStart?: () => void;\n /** Called when a task completes without throwing and without being cancelled. */\n onSuccess?: () => void;\n /** Called when a live task is cancelled, either by {@link Debouncer.cancel} or by being replaced. */\n onCancel?: () => void;\n /** Receives task errors. Cancellations never reach this callback. Defaults to `console.error`. */\n onError?: (error: unknown) => void;\n /** Called every time the debouncer goes from busy to idle. */\n onIdle?: () => void;\n}\n\n/**\n * Keeps at most one live task.\n * Scheduling a new task cancels the previous one, whether it was still\n * waiting or already running.\n *\n * @example\n * ```ts\n * const debouncer = new Debouncer({delayMs: 1500});\n *\n * debouncer.schedule(async (signal) => {\n * const reply = await callAI(messages, {signal});\n * if (signal.aborted) return;\n * await sendReply(reply);\n * });\n * ```\n */\nexport default class Debouncer {\n #controller: AbortController | undefined;\n readonly #delayMs: number;\n readonly #onSchedule: () => void;\n readonly #onStart: () => void;\n readonly #onSuccess: () => void;\n readonly #onCancel: () => void;\n readonly #onError: (error: unknown) => void;\n readonly #onIdle: () => void;\n\n constructor(options: DebouncerOptions) {\n assertValidDelay(options.delayMs);\n this.#delayMs = options.delayMs;\n this.#onSchedule = options.onSchedule ?? noop;\n this.#onStart = options.onStart ?? noop;\n this.#onSuccess = options.onSuccess ?? noop;\n this.#onCancel = options.onCancel ?? noop;\n this.#onError = options.onError ?? console.error;\n this.#onIdle = options.onIdle ?? noop;\n }\n\n /** Whether a task is waiting or running. */\n get isPending(): boolean {\n return this.#controller !== undefined;\n }\n\n /**\n * Schedule `task`, cancelling any previous task.\n *\n * @param task - The task to run once the delay elapses.\n * @param delayMs - Wait for this task only. Defaults to the configured `delayMs`.\n */\n schedule(task: DebouncedTask, delayMs: number = this.#delayMs): void {\n assertValidDelay(delayMs);\n if (this.#controller !== undefined) {\n this.#controller.abort();\n this.#onCancel();\n }\n\n const controller = new AbortController();\n this.#controller = controller;\n this.#onSchedule();\n void this.#run(task, delayMs, controller);\n }\n\n /** Cancel the current task, if any. */\n cancel(): void {\n if (this.#controller === undefined) {\n return;\n }\n this.#controller.abort();\n this.#onCancel();\n this.#becomeIdle();\n }\n\n async #run(task: DebouncedTask, delayMs: number, controller: AbortController): Promise<void> {\n const signal = controller.signal;\n try {\n await delay(delayMs, signal);\n this.#onStart();\n await task(signal);\n if (!signal.aborted) {\n this.#onSuccess();\n }\n } catch (error) {\n if (!signal.aborted) {\n this.#onError(error);\n }\n } finally {\n // A replaced or cancelled task must not touch the current state.\n if (this.#controller === controller) {\n this.#becomeIdle();\n }\n }\n }\n\n #becomeIdle(): void {\n this.#controller = undefined;\n this.#onIdle();\n }\n}\n\n/**\n * Throw a `RangeError` unless `delayMs` is a finite number >= 0.\n *\n * @internal Shared with `KeyedDebouncer`; not part of the public API.\n */\nexport function assertValidDelay(delayMs: number): void {\n if (!Number.isFinite(delayMs) || delayMs < 0) {\n throw new RangeError(`delayMs must be a number >= 0 (received: ${delayMs})`);\n }\n}\n"]}
|
package/dist/cjs/functions.js
CHANGED
|
@@ -5,7 +5,6 @@ exports.constant = constant;
|
|
|
5
5
|
exports.noop = noop;
|
|
6
6
|
exports.once = once;
|
|
7
7
|
exports.memoize = memoize;
|
|
8
|
-
exports.debounce = debounce;
|
|
9
8
|
exports.throttle = throttle;
|
|
10
9
|
exports.partial = partial;
|
|
11
10
|
exports.pipe = pipe;
|
|
@@ -125,91 +124,6 @@ function memoize(fn, resolver, cache = new Map()) {
|
|
|
125
124
|
memoized.has = (...args) => cache.has(resolveKey(...args));
|
|
126
125
|
return memoized;
|
|
127
126
|
}
|
|
128
|
-
/**
|
|
129
|
-
* Delay a function until no calls have been made for the configured wait time.
|
|
130
|
-
* The latest arguments and this-context are used for the trailing execution.
|
|
131
|
-
*
|
|
132
|
-
* @example
|
|
133
|
-
* ```ts
|
|
134
|
-
* const search = debounce((query: string) => {
|
|
135
|
-
* console.log(query);
|
|
136
|
-
* }, 300);
|
|
137
|
-
*
|
|
138
|
-
* search("com");
|
|
139
|
-
* search("commons"); // only this value is printed after 300 ms
|
|
140
|
-
* ```
|
|
141
|
-
*
|
|
142
|
-
* @example
|
|
143
|
-
* ```ts
|
|
144
|
-
* const track = debounce(sendAnalytics, 1000, {leading: true, trailing: false});
|
|
145
|
-
*
|
|
146
|
-
* track("open"); // executed immediately
|
|
147
|
-
* track.cancel(); // cancel the pending debounce window
|
|
148
|
-
* ```
|
|
149
|
-
*/
|
|
150
|
-
function debounce(fn, wait, options = {}) {
|
|
151
|
-
const delay = normalizeDelay(wait);
|
|
152
|
-
const leading = options.leading ?? false;
|
|
153
|
-
const trailing = options.trailing ?? true;
|
|
154
|
-
let timer;
|
|
155
|
-
let lastArgs;
|
|
156
|
-
let lastThis;
|
|
157
|
-
let result;
|
|
158
|
-
const invoke = () => {
|
|
159
|
-
const args = lastArgs;
|
|
160
|
-
const context = lastThis;
|
|
161
|
-
lastArgs = undefined;
|
|
162
|
-
lastThis = undefined;
|
|
163
|
-
result = fn.apply(context, args);
|
|
164
|
-
return result;
|
|
165
|
-
};
|
|
166
|
-
const expire = () => {
|
|
167
|
-
timer = undefined;
|
|
168
|
-
if (trailing && lastArgs) {
|
|
169
|
-
invoke();
|
|
170
|
-
}
|
|
171
|
-
else {
|
|
172
|
-
lastArgs = undefined;
|
|
173
|
-
lastThis = undefined;
|
|
174
|
-
}
|
|
175
|
-
};
|
|
176
|
-
const start = () => {
|
|
177
|
-
timer = setTimeout(expire, delay);
|
|
178
|
-
};
|
|
179
|
-
const debounced = function (...args) {
|
|
180
|
-
const invokeLeading = leading && timer === undefined;
|
|
181
|
-
lastArgs = args;
|
|
182
|
-
lastThis = this;
|
|
183
|
-
if (timer !== undefined) {
|
|
184
|
-
clearTimeout(timer);
|
|
185
|
-
}
|
|
186
|
-
start();
|
|
187
|
-
if (invokeLeading) {
|
|
188
|
-
return invoke();
|
|
189
|
-
}
|
|
190
|
-
return result;
|
|
191
|
-
};
|
|
192
|
-
debounced.cancel = () => {
|
|
193
|
-
if (timer !== undefined) {
|
|
194
|
-
clearTimeout(timer);
|
|
195
|
-
}
|
|
196
|
-
timer = undefined;
|
|
197
|
-
lastArgs = undefined;
|
|
198
|
-
lastThis = undefined;
|
|
199
|
-
};
|
|
200
|
-
debounced.flush = () => {
|
|
201
|
-
if (timer !== undefined) {
|
|
202
|
-
clearTimeout(timer);
|
|
203
|
-
timer = undefined;
|
|
204
|
-
if (lastArgs && trailing) {
|
|
205
|
-
return invoke();
|
|
206
|
-
}
|
|
207
|
-
}
|
|
208
|
-
return result;
|
|
209
|
-
};
|
|
210
|
-
debounced.pending = () => timer !== undefined;
|
|
211
|
-
return debounced;
|
|
212
|
-
}
|
|
213
127
|
/**
|
|
214
128
|
* Limit how often a function can run during a time window.
|
|
215
129
|
* Calls made while the function is throttled can optionally be replayed once at the end with the latest arguments.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"functions.js","sourceRoot":"","sources":["../../src/functions.ts"],"names":[],"mappings":"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","sourcesContent":["type AnyFunction = (this: any, ...args: any[]) => any;\ntype TimerHandle = ReturnType<typeof setTimeout>;\n\n/** Options that control when a debounced function is executed. */\nexport interface DebounceOptions {\n /** Execute on the first call in a debounce window. Defaults to false. */\n leading?: boolean;\n /** Execute after the debounce window using the latest arguments. Defaults to true. */\n trailing?: boolean;\n}\n\n/** Options that control when a throttled function is executed. */\nexport interface ThrottleOptions {\n /** Execute immediately on the first call in a throttle window. Defaults to true. */\n leading?: boolean;\n /** Execute once more at the end of the throttle window using the latest arguments. Defaults to true. */\n trailing?: boolean;\n}\n\n/**\n * A delayed function returned by {@link debounce} or {@link throttle}.\n *\n * @example\n * ```ts\n * const saveLater = debounce(save, 250);\n * saveLater();\n *\n * if (saveLater.pending()) {\n * saveLater.flush();\n * }\n * ```\n */\nexport type DeferredFunction<F extends AnyFunction> = ((\n this: ThisParameterType<F>,\n ...args: Parameters<F>\n) => ReturnType<F> | undefined) & {\n /** Cancel the scheduled call and forget the latest arguments. */\n cancel(): void;\n /** Execute the scheduled trailing call immediately, when one exists. */\n flush(): ReturnType<F> | undefined;\n /** Return true while a trailing call is scheduled. */\n pending(): boolean;\n};\n\n/**\n * A memoized function with helpers for inspecting and invalidating its cache.\n *\n * @example\n * ```ts\n * const getUser = memoize((id: string) => fetchUser(id));\n *\n * getUser(\"42\");\n * getUser.has(\"42\"); // true\n * getUser.delete(\"42\");\n * ```\n */\nexport type MemoizedFunction<F extends AnyFunction, K> = ((\n this: ThisParameterType<F>,\n ...args: Parameters<F>\n) => ReturnType<F>) & {\n /** The backing cache used by the memoized function. */\n readonly cache: Map<K, ReturnType<F>>;\n /** Remove every cached value. */\n clear(): void;\n /** Remove the cached value for the key resolved from the provided arguments. */\n delete(...args: Parameters<F>): boolean;\n /** Return true when a cached value exists for the key resolved from the provided arguments. */\n has(...args: Parameters<F>): boolean;\n};\n\ntype Unary<T, R> = (arg: T) => R;\n\n/**\n * Return the received value unchanged.\n * Useful as a default mapper, placeholder callback, or neutral transform in a pipeline.\n *\n * @example\n * ```ts\n * identity(5); // 5\n *\n * const value = {name: \"commons\"};\n * identity(value) === value; // true\n * ```\n */\nexport function identity<T>(value: T): T {\n return value;\n}\n\n/**\n * Create a function that always returns the same value.\n *\n * @example\n * ```ts\n * const getAnswer = constant(42);\n *\n * getAnswer(); // 42\n * getAnswer(); // 42\n * ```\n */\nexport function constant<T>(value: T): () => T {\n return () => value;\n}\n\n/**\n * Do nothing and return undefined.\n * Useful as a safe default callback.\n *\n * @example\n * ```ts\n * const onComplete = options.onComplete ?? noop;\n * onComplete();\n * ```\n */\nexport function noop(): void {\n // Intentionally empty.\n}\n\n/**\n * Create a function that can be executed only once.\n * Later calls return the result from the first execution without calling the original function again.\n *\n * @example\n * ```ts\n * const initialize = once(() => ({connected: true}));\n *\n * const first = initialize();\n * const second = initialize();\n * first === second; // true\n * ```\n */\nexport function once<F extends AnyFunction>(fn: F): F {\n let called = false;\n let result: ReturnType<F>;\n\n return function (this: ThisParameterType<F>, ...args: Parameters<F>): ReturnType<F> {\n if (!called) {\n called = true;\n result = fn.apply(this, args);\n }\n return result;\n } as F;\n}\n\n/**\n * Cache the result of a function and reuse it for calls with the same resolved key.\n * By default, the first argument is used as the cache key.\n *\n * @example\n * ```ts\n * const double = memoize((value: number) => value * 2);\n *\n * double(4); // 8, computed\n * double(4); // 8, read from cache\n * double.has(4); // true\n * ```\n *\n * @example\n * ```ts\n * const sum = memoize(\n * (left: number, right: number) => left + right,\n * (left, right) => `${left}:${right}`,\n * );\n *\n * sum(2, 3); // 5\n * sum.delete(2, 3); // true\n * sum.clear();\n * ```\n */\nexport function memoize<F extends AnyFunction, K = Parameters<F>[0]>(\n fn: F,\n resolver?: (...args: Parameters<F>) => K,\n cache: Map<K, ReturnType<F>> = new Map<K, ReturnType<F>>()\n): MemoizedFunction<F, K> {\n const resolveKey = (...args: Parameters<F>): K => {\n if (resolver) return resolver(...args);\n return args[0] as K;\n };\n\n const memoized = function (this: ThisParameterType<F>, ...args: Parameters<F>): ReturnType<F> {\n const key = resolveKey(...args);\n if (cache.has(key)) {\n return cache.get(key)!;\n }\n\n const value = fn.apply(this, args);\n cache.set(key, value);\n return value;\n } as MemoizedFunction<F, K>;\n\n Object.defineProperty(memoized, \"cache\", {\n value: cache,\n enumerable: false,\n });\n\n memoized.clear = () => cache.clear();\n memoized.delete = (...args: Parameters<F>) => cache.delete(resolveKey(...args));\n memoized.has = (...args: Parameters<F>) => cache.has(resolveKey(...args));\n\n return memoized;\n}\n\n/**\n * Delay a function until no calls have been made for the configured wait time.\n * The latest arguments and this-context are used for the trailing execution.\n *\n * @example\n * ```ts\n * const search = debounce((query: string) => {\n * console.log(query);\n * }, 300);\n *\n * search(\"com\");\n * search(\"commons\"); // only this value is printed after 300 ms\n * ```\n *\n * @example\n * ```ts\n * const track = debounce(sendAnalytics, 1000, {leading: true, trailing: false});\n *\n * track(\"open\"); // executed immediately\n * track.cancel(); // cancel the pending debounce window\n * ```\n */\nexport function debounce<F extends AnyFunction>(\n fn: F,\n wait: number,\n options: DebounceOptions = {}\n): DeferredFunction<F> {\n const delay = normalizeDelay(wait);\n const leading = options.leading ?? false;\n const trailing = options.trailing ?? true;\n\n let timer: TimerHandle | undefined;\n let lastArgs: Parameters<F> | undefined;\n let lastThis: ThisParameterType<F> | undefined;\n let result: ReturnType<F> | undefined;\n\n const invoke = (): ReturnType<F> => {\n const args = lastArgs!;\n const context = lastThis!;\n lastArgs = undefined;\n lastThis = undefined;\n result = fn.apply(context, args);\n return result as ReturnType<F>;\n };\n\n const expire = (): void => {\n timer = undefined;\n if (trailing && lastArgs) {\n invoke();\n } else {\n lastArgs = undefined;\n lastThis = undefined;\n }\n };\n\n const start = (): void => {\n timer = setTimeout(expire, delay);\n };\n\n const debounced = function (this: ThisParameterType<F>, ...args: Parameters<F>): ReturnType<F> | undefined {\n const invokeLeading = leading && timer === undefined;\n lastArgs = args;\n lastThis = this;\n\n if (timer !== undefined) {\n clearTimeout(timer);\n }\n start();\n\n if (invokeLeading) {\n return invoke();\n }\n\n return result;\n } as DeferredFunction<F>;\n\n debounced.cancel = (): void => {\n if (timer !== undefined) {\n clearTimeout(timer);\n }\n timer = undefined;\n lastArgs = undefined;\n lastThis = undefined;\n };\n\n debounced.flush = (): ReturnType<F> | undefined => {\n if (timer !== undefined) {\n clearTimeout(timer);\n timer = undefined;\n if (lastArgs && trailing) {\n return invoke();\n }\n }\n return result;\n };\n\n debounced.pending = (): boolean => timer !== undefined;\n\n return debounced;\n}\n\n/**\n * Limit how often a function can run during a time window.\n * Calls made while the function is throttled can optionally be replayed once at the end with the latest arguments.\n *\n * @example\n * ```ts\n * const onScroll = throttle(() => {\n * console.log(window.scrollY);\n * }, 100);\n *\n * window.addEventListener(\"scroll\", onScroll);\n * ```\n *\n * @example\n * ```ts\n * const refresh = throttle(loadData, 500, {leading: false});\n *\n * refresh(); // scheduled instead of executed immediately\n * refresh.flush(); // execute the scheduled call now\n * ```\n */\nexport function throttle<F extends AnyFunction>(\n fn: F,\n wait: number,\n options: ThrottleOptions = {}\n): DeferredFunction<F> {\n const delay = normalizeDelay(wait);\n const leading = options.leading ?? true;\n const trailing = options.trailing ?? true;\n\n let timer: TimerHandle | undefined;\n let lastArgs: Parameters<F> | undefined;\n let lastThis: ThisParameterType<F> | undefined;\n let lastInvokeTime = 0;\n let hasInvoked = false;\n let result: ReturnType<F> | undefined;\n\n const invoke = (time: number): ReturnType<F> => {\n const args = lastArgs!;\n const context = lastThis!;\n lastArgs = undefined;\n lastThis = undefined;\n hasInvoked = true;\n lastInvokeTime = time;\n result = fn.apply(context, args);\n return result as ReturnType<F>;\n };\n\n const expire = (): void => {\n timer = undefined;\n if (trailing && lastArgs) {\n invoke(Date.now());\n } else {\n lastArgs = undefined;\n lastThis = undefined;\n }\n };\n\n const throttled = function (this: ThisParameterType<F>, ...args: Parameters<F>): ReturnType<F> | undefined {\n const now = Date.now();\n lastArgs = args;\n lastThis = this;\n\n if (!hasInvoked) {\n if (leading) {\n return invoke(now);\n }\n hasInvoked = true;\n lastInvokeTime = now;\n }\n\n const remaining = delay - (now - lastInvokeTime);\n if (remaining <= 0 || remaining > delay) {\n if (timer !== undefined) {\n clearTimeout(timer);\n timer = undefined;\n }\n return invoke(now);\n }\n\n if (timer === undefined && trailing) {\n timer = setTimeout(expire, remaining);\n }\n\n return result;\n } as DeferredFunction<F>;\n\n throttled.cancel = (): void => {\n if (timer !== undefined) {\n clearTimeout(timer);\n }\n timer = undefined;\n lastArgs = undefined;\n lastThis = undefined;\n lastInvokeTime = 0;\n hasInvoked = false;\n };\n\n throttled.flush = (): ReturnType<F> | undefined => {\n if (timer !== undefined) {\n clearTimeout(timer);\n timer = undefined;\n if (lastArgs && trailing) {\n return invoke(Date.now());\n }\n }\n return result;\n };\n\n throttled.pending = (): boolean => timer !== undefined;\n\n return throttled;\n}\n\n/**\n * Create a function with one or more arguments already provided.\n * Later arguments are appended after the preset arguments.\n *\n * @example\n * ```ts\n * const sum = (a: number, b: number, c: number) => a + b + c;\n * const addFive = partial(sum, 2, 3);\n *\n * addFive(4); // 9\n * ```\n */\nexport function partial<F extends AnyFunction>(\n fn: F,\n ...presetArgs: unknown[]\n): (...laterArgs: unknown[]) => ReturnType<F> {\n return function (this: ThisParameterType<F>, ...laterArgs: unknown[]): ReturnType<F> {\n return fn.apply(this, [...presetArgs, ...laterArgs] as Parameters<F>);\n };\n}\n\n/**\n * Compose unary functions from left to right.\n * The first function receives the original arguments, and each next function receives the previous result.\n *\n * @example\n * ```ts\n * const transform = pipe(\n * (value: number) => value + 1,\n * (value: number) => value * 2,\n * );\n *\n * transform(2); // 6\n * ```\n */\nexport function pipe<A, B>(ab: Unary<A, B>): Unary<A, B>;\nexport function pipe<A, B, C>(ab: Unary<A, B>, bc: Unary<B, C>): Unary<A, C>;\nexport function pipe<A, B, C, D>(ab: Unary<A, B>, bc: Unary<B, C>, cd: Unary<C, D>): Unary<A, D>;\nexport function pipe<A, B, C, D, E>(ab: Unary<A, B>, bc: Unary<B, C>, cd: Unary<C, D>, de: Unary<D, E>): Unary<A, E>;\nexport function pipe(...fns: AnyFunction[]): AnyFunction {\n return createFlow(fns);\n}\n\n/**\n * Compose unary functions from right to left.\n * The rightmost function receives the original arguments, and each function to its left receives the previous result.\n *\n * @example\n * ```ts\n * const transform = compose(\n * (value: number) => value + 1,\n * (value: number) => value * 2,\n * );\n *\n * transform(2); // 5\n * ```\n */\nexport function compose<A, B>(ab: Unary<A, B>): Unary<A, B>;\nexport function compose<A, B, C>(bc: Unary<B, C>, ab: Unary<A, B>): Unary<A, C>;\nexport function compose<A, B, C, D>(cd: Unary<C, D>, bc: Unary<B, C>, ab: Unary<A, B>): Unary<A, D>;\nexport function compose<A, B, C, D, E>(de: Unary<D, E>, cd: Unary<C, D>, bc: Unary<B, C>, ab: Unary<A, B>): Unary<A, E>;\nexport function compose(...fns: AnyFunction[]): AnyFunction {\n return createFlow(fns.slice().reverse());\n}\n\nfunction createFlow(fns: AnyFunction[]): AnyFunction {\n if (fns.length === 0) return identity;\n\n return function (this: any, ...args: any[]): unknown {\n let result = fns[0].apply(this, args);\n for (let i = 1; i < fns.length; i++) {\n result = fns[i].call(this, result);\n }\n return result;\n };\n}\n\nfunction normalizeDelay(wait: number): number {\n return Number.isFinite(wait) ? Math.max(0, wait) : 0;\n}"]}
|
|
1
|
+
{"version":3,"file":"functions.js","sourceRoot":"","sources":["../../src/functions.ts"],"names":[],"mappings":"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","sourcesContent":["type AnyFunction = (this: any, ...args: any[]) => any;\ntype TimerHandle = ReturnType<typeof setTimeout>;\n\n/** Options that control when a throttled function is executed. */\nexport interface ThrottleOptions {\n /** Execute immediately on the first call in a throttle window. Defaults to true. */\n leading?: boolean;\n /** Execute once more at the end of the throttle window using the latest arguments. Defaults to true. */\n trailing?: boolean;\n}\n\n/**\n * A delayed function returned by {@link throttle}.\n *\n * @example\n * ```ts\n * const refresh = throttle(loadData, 250);\n * refresh();\n *\n * if (refresh.pending()) {\n * refresh.flush();\n * }\n * ```\n */\nexport type DeferredFunction<F extends AnyFunction> = ((\n this: ThisParameterType<F>,\n ...args: Parameters<F>\n) => ReturnType<F> | undefined) & {\n /** Cancel the scheduled call and forget the latest arguments. */\n cancel(): void;\n /** Execute the scheduled trailing call immediately, when one exists. */\n flush(): ReturnType<F> | undefined;\n /** Return true while a trailing call is scheduled. */\n pending(): boolean;\n};\n\n/**\n * A memoized function with helpers for inspecting and invalidating its cache.\n *\n * @example\n * ```ts\n * const getUser = memoize((id: string) => fetchUser(id));\n *\n * getUser(\"42\");\n * getUser.has(\"42\"); // true\n * getUser.delete(\"42\");\n * ```\n */\nexport type MemoizedFunction<F extends AnyFunction, K> = ((\n this: ThisParameterType<F>,\n ...args: Parameters<F>\n) => ReturnType<F>) & {\n /** The backing cache used by the memoized function. */\n readonly cache: Map<K, ReturnType<F>>;\n /** Remove every cached value. */\n clear(): void;\n /** Remove the cached value for the key resolved from the provided arguments. */\n delete(...args: Parameters<F>): boolean;\n /** Return true when a cached value exists for the key resolved from the provided arguments. */\n has(...args: Parameters<F>): boolean;\n};\n\ntype Unary<T, R> = (arg: T) => R;\n\n/**\n * Return the received value unchanged.\n * Useful as a default mapper, placeholder callback, or neutral transform in a pipeline.\n *\n * @example\n * ```ts\n * identity(5); // 5\n *\n * const value = {name: \"commons\"};\n * identity(value) === value; // true\n * ```\n */\nexport function identity<T>(value: T): T {\n return value;\n}\n\n/**\n * Create a function that always returns the same value.\n *\n * @example\n * ```ts\n * const getAnswer = constant(42);\n *\n * getAnswer(); // 42\n * getAnswer(); // 42\n * ```\n */\nexport function constant<T>(value: T): () => T {\n return () => value;\n}\n\n/**\n * Do nothing and return undefined.\n * Useful as a safe default callback.\n *\n * @example\n * ```ts\n * const onComplete = options.onComplete ?? noop;\n * onComplete();\n * ```\n */\nexport function noop(): void {\n // Intentionally empty.\n}\n\n/**\n * Create a function that can be executed only once.\n * Later calls return the result from the first execution without calling the original function again.\n *\n * @example\n * ```ts\n * const initialize = once(() => ({connected: true}));\n *\n * const first = initialize();\n * const second = initialize();\n * first === second; // true\n * ```\n */\nexport function once<F extends AnyFunction>(fn: F): F {\n let called = false;\n let result: ReturnType<F>;\n\n return function (this: ThisParameterType<F>, ...args: Parameters<F>): ReturnType<F> {\n if (!called) {\n called = true;\n result = fn.apply(this, args);\n }\n return result;\n } as F;\n}\n\n/**\n * Cache the result of a function and reuse it for calls with the same resolved key.\n * By default, the first argument is used as the cache key.\n *\n * @example\n * ```ts\n * const double = memoize((value: number) => value * 2);\n *\n * double(4); // 8, computed\n * double(4); // 8, read from cache\n * double.has(4); // true\n * ```\n *\n * @example\n * ```ts\n * const sum = memoize(\n * (left: number, right: number) => left + right,\n * (left, right) => `${left}:${right}`,\n * );\n *\n * sum(2, 3); // 5\n * sum.delete(2, 3); // true\n * sum.clear();\n * ```\n */\nexport function memoize<F extends AnyFunction, K = Parameters<F>[0]>(\n fn: F,\n resolver?: (...args: Parameters<F>) => K,\n cache: Map<K, ReturnType<F>> = new Map<K, ReturnType<F>>()\n): MemoizedFunction<F, K> {\n const resolveKey = (...args: Parameters<F>): K => {\n if (resolver) return resolver(...args);\n return args[0] as K;\n };\n\n const memoized = function (this: ThisParameterType<F>, ...args: Parameters<F>): ReturnType<F> {\n const key = resolveKey(...args);\n if (cache.has(key)) {\n return cache.get(key)!;\n }\n\n const value = fn.apply(this, args);\n cache.set(key, value);\n return value;\n } as MemoizedFunction<F, K>;\n\n Object.defineProperty(memoized, \"cache\", {\n value: cache,\n enumerable: false,\n });\n\n memoized.clear = () => cache.clear();\n memoized.delete = (...args: Parameters<F>) => cache.delete(resolveKey(...args));\n memoized.has = (...args: Parameters<F>) => cache.has(resolveKey(...args));\n\n return memoized;\n}\n\n/**\n * Limit how often a function can run during a time window.\n * Calls made while the function is throttled can optionally be replayed once at the end with the latest arguments.\n *\n * @example\n * ```ts\n * const onScroll = throttle(() => {\n * console.log(window.scrollY);\n * }, 100);\n *\n * window.addEventListener(\"scroll\", onScroll);\n * ```\n *\n * @example\n * ```ts\n * const refresh = throttle(loadData, 500, {leading: false});\n *\n * refresh(); // scheduled instead of executed immediately\n * refresh.flush(); // execute the scheduled call now\n * ```\n */\nexport function throttle<F extends AnyFunction>(\n fn: F,\n wait: number,\n options: ThrottleOptions = {}\n): DeferredFunction<F> {\n const delay = normalizeDelay(wait);\n const leading = options.leading ?? true;\n const trailing = options.trailing ?? true;\n\n let timer: TimerHandle | undefined;\n let lastArgs: Parameters<F> | undefined;\n let lastThis: ThisParameterType<F> | undefined;\n let lastInvokeTime = 0;\n let hasInvoked = false;\n let result: ReturnType<F> | undefined;\n\n const invoke = (time: number): ReturnType<F> => {\n const args = lastArgs!;\n const context = lastThis!;\n lastArgs = undefined;\n lastThis = undefined;\n hasInvoked = true;\n lastInvokeTime = time;\n result = fn.apply(context, args);\n return result as ReturnType<F>;\n };\n\n const expire = (): void => {\n timer = undefined;\n if (trailing && lastArgs) {\n invoke(Date.now());\n } else {\n lastArgs = undefined;\n lastThis = undefined;\n }\n };\n\n const throttled = function (this: ThisParameterType<F>, ...args: Parameters<F>): ReturnType<F> | undefined {\n const now = Date.now();\n lastArgs = args;\n lastThis = this;\n\n if (!hasInvoked) {\n if (leading) {\n return invoke(now);\n }\n hasInvoked = true;\n lastInvokeTime = now;\n }\n\n const remaining = delay - (now - lastInvokeTime);\n if (remaining <= 0 || remaining > delay) {\n if (timer !== undefined) {\n clearTimeout(timer);\n timer = undefined;\n }\n return invoke(now);\n }\n\n if (timer === undefined && trailing) {\n timer = setTimeout(expire, remaining);\n }\n\n return result;\n } as DeferredFunction<F>;\n\n throttled.cancel = (): void => {\n if (timer !== undefined) {\n clearTimeout(timer);\n }\n timer = undefined;\n lastArgs = undefined;\n lastThis = undefined;\n lastInvokeTime = 0;\n hasInvoked = false;\n };\n\n throttled.flush = (): ReturnType<F> | undefined => {\n if (timer !== undefined) {\n clearTimeout(timer);\n timer = undefined;\n if (lastArgs && trailing) {\n return invoke(Date.now());\n }\n }\n return result;\n };\n\n throttled.pending = (): boolean => timer !== undefined;\n\n return throttled;\n}\n\n/**\n * Create a function with one or more arguments already provided.\n * Later arguments are appended after the preset arguments.\n *\n * @example\n * ```ts\n * const sum = (a: number, b: number, c: number) => a + b + c;\n * const addFive = partial(sum, 2, 3);\n *\n * addFive(4); // 9\n * ```\n */\nexport function partial<F extends AnyFunction>(\n fn: F,\n ...presetArgs: unknown[]\n): (...laterArgs: unknown[]) => ReturnType<F> {\n return function (this: ThisParameterType<F>, ...laterArgs: unknown[]): ReturnType<F> {\n return fn.apply(this, [...presetArgs, ...laterArgs] as Parameters<F>);\n };\n}\n\n/**\n * Compose unary functions from left to right.\n * The first function receives the original arguments, and each next function receives the previous result.\n *\n * @example\n * ```ts\n * const transform = pipe(\n * (value: number) => value + 1,\n * (value: number) => value * 2,\n * );\n *\n * transform(2); // 6\n * ```\n */\nexport function pipe<A, B>(ab: Unary<A, B>): Unary<A, B>;\nexport function pipe<A, B, C>(ab: Unary<A, B>, bc: Unary<B, C>): Unary<A, C>;\nexport function pipe<A, B, C, D>(ab: Unary<A, B>, bc: Unary<B, C>, cd: Unary<C, D>): Unary<A, D>;\nexport function pipe<A, B, C, D, E>(ab: Unary<A, B>, bc: Unary<B, C>, cd: Unary<C, D>, de: Unary<D, E>): Unary<A, E>;\nexport function pipe(...fns: AnyFunction[]): AnyFunction {\n return createFlow(fns);\n}\n\n/**\n * Compose unary functions from right to left.\n * The rightmost function receives the original arguments, and each function to its left receives the previous result.\n *\n * @example\n * ```ts\n * const transform = compose(\n * (value: number) => value + 1,\n * (value: number) => value * 2,\n * );\n *\n * transform(2); // 5\n * ```\n */\nexport function compose<A, B>(ab: Unary<A, B>): Unary<A, B>;\nexport function compose<A, B, C>(bc: Unary<B, C>, ab: Unary<A, B>): Unary<A, C>;\nexport function compose<A, B, C, D>(cd: Unary<C, D>, bc: Unary<B, C>, ab: Unary<A, B>): Unary<A, D>;\nexport function compose<A, B, C, D, E>(de: Unary<D, E>, cd: Unary<C, D>, bc: Unary<B, C>, ab: Unary<A, B>): Unary<A, E>;\nexport function compose(...fns: AnyFunction[]): AnyFunction {\n return createFlow(fns.slice().reverse());\n}\n\nfunction createFlow(fns: AnyFunction[]): AnyFunction {\n if (fns.length === 0) return identity;\n\n return function (this: any, ...args: any[]): unknown {\n let result = fns[0].apply(this, args);\n for (let i = 1; i < fns.length; i++) {\n result = fns[i].call(this, result);\n }\n return result;\n };\n}\n\nfunction normalizeDelay(wait: number): number {\n return Number.isFinite(wait) ? Math.max(0, wait) : 0;\n}"]}
|
package/dist/cjs/index.js
CHANGED
|
@@ -18,7 +18,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
18
18
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
19
19
|
};
|
|
20
20
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
21
|
-
exports.formToObject = exports.submitForm = exports.ajaxSubmission = exports.ajaxSubmit = exports.CleanURLSearchParams = exports.draft = exports.Range = exports.Event = exports.EventBus = exports.from = exports.Lazy = exports.AsyncPoolExecutor = exports.Stopwatch = exports.TimeSpan = exports.Timer = exports.Order = exports.KeyValuePair = exports.CancellablePromise = exports.TypeCode = exports.Type = void 0;
|
|
21
|
+
exports.formToObject = exports.submitForm = exports.ajaxSubmission = exports.ajaxSubmit = exports.CleanURLSearchParams = exports.draft = exports.Range = exports.Event = exports.EventBus = exports.from = exports.Lazy = exports.KeyedDebouncer = exports.Debouncer = exports.AsyncPoolExecutor = exports.CountTrigger = exports.TimeTrigger = exports.Stopwatch = exports.TimeSpan = exports.Timer = exports.Order = exports.KeyValuePair = exports.CancellablePromise = exports.TypeCode = exports.Type = void 0;
|
|
22
22
|
// ─── Types ───────────────────────────────────────────
|
|
23
23
|
__exportStar(require("./types.js"), exports);
|
|
24
24
|
var type_js_1 = require("./type.js");
|
|
@@ -45,8 +45,15 @@ var timespan_js_1 = require("./timespan.js");
|
|
|
45
45
|
Object.defineProperty(exports, "TimeSpan", { enumerable: true, get: function () { return __importDefault(timespan_js_1).default; } });
|
|
46
46
|
var stopwatch_js_1 = require("./stopwatch.js");
|
|
47
47
|
Object.defineProperty(exports, "Stopwatch", { enumerable: true, get: function () { return __importDefault(stopwatch_js_1).default; } });
|
|
48
|
+
var triggers_js_1 = require("./triggers.js");
|
|
49
|
+
Object.defineProperty(exports, "TimeTrigger", { enumerable: true, get: function () { return triggers_js_1.TimeTrigger; } });
|
|
50
|
+
Object.defineProperty(exports, "CountTrigger", { enumerable: true, get: function () { return triggers_js_1.CountTrigger; } });
|
|
48
51
|
var async_pool_executor_js_1 = require("./async-pool-executor.js");
|
|
49
52
|
Object.defineProperty(exports, "AsyncPoolExecutor", { enumerable: true, get: function () { return __importDefault(async_pool_executor_js_1).default; } });
|
|
53
|
+
var debouncer_js_1 = require("./debouncer.js");
|
|
54
|
+
Object.defineProperty(exports, "Debouncer", { enumerable: true, get: function () { return __importDefault(debouncer_js_1).default; } });
|
|
55
|
+
var keyed_debouncer_js_1 = require("./keyed-debouncer.js");
|
|
56
|
+
Object.defineProperty(exports, "KeyedDebouncer", { enumerable: true, get: function () { return __importDefault(keyed_debouncer_js_1).default; } });
|
|
50
57
|
// ─── Patterns ────────────────────────────────────────
|
|
51
58
|
var lazy_js_1 = require("./lazy.js");
|
|
52
59
|
Object.defineProperty(exports, "Lazy", { enumerable: true, get: function () { return __importDefault(lazy_js_1).default; } });
|
package/dist/cjs/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";AAAA,eAAe;;;;;;;;;;;;;;;;;;;;AAEf,wDAAwD;AACxD,6CAA2B;AAC3B,qCAA0C;AAAlC,gHAAA,OAAO,OAAQ;AACvB,+CAAmD;AAA3C,yHAAA,OAAO,OAAY;AAE3B,wDAAwD;AACxD,iDAA+B;AAC/B,iDAA+B;AAC/B,8CAA4B;AAC5B,4CAA0B;AAC1B,6CAA2B;AAC3B,mEAAuE;AAA/D,6IAAA,OAAO,OAAsB;AAErC,uDAAuD;AACvD,yDAA4D;AAApD,kIAAA,OAAO,OAAgB;AAC/B,uCAA4C;AAApC,kHAAA,OAAO,OAAS;AAExB,uDAAuD;AACvD,uCAA4C;AAApC,kHAAA,OAAO,OAAS;AACxB,6CAAkD;AAA1C,wHAAA,OAAO,OAAY;AAC3B,+CAAoD;AAA5C,0HAAA,OAAO,OAAa;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";AAAA,eAAe;;;;;;;;;;;;;;;;;;;;AAEf,wDAAwD;AACxD,6CAA2B;AAC3B,qCAA0C;AAAlC,gHAAA,OAAO,OAAQ;AACvB,+CAAmD;AAA3C,yHAAA,OAAO,OAAY;AAE3B,wDAAwD;AACxD,iDAA+B;AAC/B,iDAA+B;AAC/B,8CAA4B;AAC5B,4CAA0B;AAC1B,6CAA2B;AAC3B,mEAAuE;AAA/D,6IAAA,OAAO,OAAsB;AAErC,uDAAuD;AACvD,yDAA4D;AAApD,kIAAA,OAAO,OAAgB;AAC/B,uCAA4C;AAApC,kHAAA,OAAO,OAAS;AAExB,uDAAuD;AACvD,uCAA4C;AAApC,kHAAA,OAAO,OAAS;AACxB,6CAAkD;AAA1C,wHAAA,OAAO,OAAY;AAC3B,+CAAoD;AAA5C,0HAAA,OAAO,OAAa;AAE5B,6CAAwD;AAAhD,0GAAA,WAAW,OAAA;AAAE,2GAAA,YAAY,OAAA;AACjC,mEAAsE;AAA9D,4IAAA,OAAO,OAAqB;AACpC,+CAAoD;AAA5C,0HAAA,OAAO,OAAa;AAE5B,2DAA+D;AAAvD,qIAAA,OAAO,OAAkB;AAGjC,wDAAwD;AACxD,qCAA0C;AAAlC,gHAAA,OAAO,OAAQ;AACvB,iDAAsD;AAA9C,gHAAA,OAAO,OAAQ;AACvB,+CAA+C;AAAvC,wGAAA,QAAQ,OAAA;AAAE,qGAAA,KAAK,OAAA;AACvB,uCAA4C;AAApC,kHAAA,OAAO,OAAS;AAExB,qDAAqD;AACrD,uCAA4C;AAApC,kHAAA,OAAO,OAAS;AAExB,wDAAwD;AACxD,2EAA6E;AAArE,mJAAA,OAAO,OAAwB;AACvC,mBAAmB;AACnB,+CAAwF;AAAhF,sGAAA,UAAU,OAAA;AAAE,0GAAA,cAAc,OAAA;AAAE,sGAAA,UAAU,OAAA;AAAE,wGAAA,YAAY,OAAA;AAI5D,wDAAwD;AACxD,mBAAmB;AACnB,6CAA2B;AAC3B,mBAAmB;AACnB,yDAAuC","sourcesContent":["// src/index.ts\n\n// ─── Types ───────────────────────────────────────────\nexport * from './types.js';\nexport {default as Type} from './type.js';\nexport {default as TypeCode} from './type-code.js';\n\n// ─── Utilities ───────────────────────────────────────\nexport * from './utilities.js';\nexport * from './functions.js';\nexport * from './string.js';\nexport * from './math.js';\nexport * from './parse.js';\nexport {default as CancellablePromise} from \"./cancellable-promise.js\";\n\n// ─── Data Structures ────────────────────────────────\nexport {default as KeyValuePair} from './key-value-pair.js';\nexport {default as Order} from './order.js';\n\n// ─── Async & Timing ─────────────────────────────────\nexport {default as Timer} from './timer.js';\nexport {default as TimeSpan} from './timespan.js';\nexport {default as Stopwatch} from './stopwatch.js';\nexport type {Result} from './result.js';\nexport {TimeTrigger, CountTrigger} from './triggers.js';\nexport {default as AsyncPoolExecutor} from './async-pool-executor.js';\nexport {default as Debouncer} from './debouncer.js';\nexport type {DebouncedTask, DebouncerOptions} from './debouncer.js';\nexport {default as KeyedDebouncer} from './keyed-debouncer.js';\nexport type {KeyedDebouncerOptions} from './keyed-debouncer.js';\n\n// ─── Patterns ────────────────────────────────────────\nexport {default as Lazy} from './lazy.js';\nexport {default as from} from './collections/from.js';\nexport {EventBus, Event} from './event-bus.js';\nexport {default as Range} from './range.js';\n\n// ─── Draft ────────────────────────────────────────\nexport {default as draft} from './draft.js';\n\n// ─── Web ─────────────────────────────────────────────\nexport {default as CleanURLSearchParams} from './clean-url-search-params.js';\n/** @deprecated */\nexport {ajaxSubmit, ajaxSubmission, submitForm, formToObject} from './browser/index.js';\n\n\n\n// ─── Deprecated ──────────────────────────────────────\n/** @deprecated */\nexport * from './array.js';\n/** @deprecated */\nexport * from './collections/index.js';"]}
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
|
|
36
|
+
if (kind === "m") throw new TypeError("Private method is not writable");
|
|
37
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
|
|
38
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
|
|
39
|
+
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
|
|
40
|
+
};
|
|
41
|
+
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
|
|
42
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
|
|
43
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
44
|
+
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
45
|
+
};
|
|
46
|
+
var _KeyedDebouncer_instances, _KeyedDebouncer_debouncers, _KeyedDebouncer_delayMs, _KeyedDebouncer_onSchedule, _KeyedDebouncer_onStart, _KeyedDebouncer_onSuccess, _KeyedDebouncer_onCancel, _KeyedDebouncer_onError, _KeyedDebouncer_onIdle, _KeyedDebouncer_create;
|
|
47
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
48
|
+
const debouncer_js_1 = __importStar(require("./debouncer.js"));
|
|
49
|
+
const functions_js_1 = require("./functions.js");
|
|
50
|
+
/**
|
|
51
|
+
* An independent {@link Debouncer} per key.
|
|
52
|
+
* Debouncers only exist for keys with pending work: each one is created when
|
|
53
|
+
* its first task is scheduled and removed as soon as it becomes idle.
|
|
54
|
+
*
|
|
55
|
+
* @example
|
|
56
|
+
* ```ts
|
|
57
|
+
* const debouncer = new KeyedDebouncer<string>({delayMs: 1500});
|
|
58
|
+
*
|
|
59
|
+
* debouncer.schedule(chatId, async (signal) => {
|
|
60
|
+
* const pending = await store.getPending(chatId);
|
|
61
|
+
* const reply = await callAI(pending, {signal});
|
|
62
|
+
* if (signal.aborted) return;
|
|
63
|
+
* await sendReply(chatId, reply);
|
|
64
|
+
* });
|
|
65
|
+
* ```
|
|
66
|
+
*/
|
|
67
|
+
class KeyedDebouncer {
|
|
68
|
+
constructor(options) {
|
|
69
|
+
_KeyedDebouncer_instances.add(this);
|
|
70
|
+
_KeyedDebouncer_debouncers.set(this, new Map());
|
|
71
|
+
_KeyedDebouncer_delayMs.set(this, void 0);
|
|
72
|
+
_KeyedDebouncer_onSchedule.set(this, void 0);
|
|
73
|
+
_KeyedDebouncer_onStart.set(this, void 0);
|
|
74
|
+
_KeyedDebouncer_onSuccess.set(this, void 0);
|
|
75
|
+
_KeyedDebouncer_onCancel.set(this, void 0);
|
|
76
|
+
_KeyedDebouncer_onError.set(this, void 0);
|
|
77
|
+
_KeyedDebouncer_onIdle.set(this, void 0);
|
|
78
|
+
(0, debouncer_js_1.assertValidDelay)(options.delayMs);
|
|
79
|
+
__classPrivateFieldSet(this, _KeyedDebouncer_delayMs, options.delayMs, "f");
|
|
80
|
+
__classPrivateFieldSet(this, _KeyedDebouncer_onSchedule, options.onSchedule ?? functions_js_1.noop, "f");
|
|
81
|
+
__classPrivateFieldSet(this, _KeyedDebouncer_onStart, options.onStart ?? functions_js_1.noop, "f");
|
|
82
|
+
__classPrivateFieldSet(this, _KeyedDebouncer_onSuccess, options.onSuccess ?? functions_js_1.noop, "f");
|
|
83
|
+
__classPrivateFieldSet(this, _KeyedDebouncer_onCancel, options.onCancel ?? functions_js_1.noop, "f");
|
|
84
|
+
__classPrivateFieldSet(this, _KeyedDebouncer_onError, options.onError ?? console.error, "f");
|
|
85
|
+
__classPrivateFieldSet(this, _KeyedDebouncer_onIdle, options.onIdle ?? functions_js_1.noop, "f");
|
|
86
|
+
}
|
|
87
|
+
/** Number of keys with a task waiting or running. */
|
|
88
|
+
get size() {
|
|
89
|
+
return __classPrivateFieldGet(this, _KeyedDebouncer_debouncers, "f").size;
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Schedule `task` for `key`, cancelling any previous task of that key.
|
|
93
|
+
*
|
|
94
|
+
* @param key - The key whose task is replaced.
|
|
95
|
+
* @param task - The task to run once the delay elapses.
|
|
96
|
+
* @param delayMs - Wait for this task only. Defaults to the configured `delayMs`.
|
|
97
|
+
*/
|
|
98
|
+
schedule(key, task, delayMs) {
|
|
99
|
+
const existing = __classPrivateFieldGet(this, _KeyedDebouncer_debouncers, "f").get(key);
|
|
100
|
+
if (existing !== undefined) {
|
|
101
|
+
existing.schedule(task, delayMs);
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
// Validate first so an invalid delay never registers the key.
|
|
105
|
+
(0, debouncer_js_1.assertValidDelay)(delayMs ?? __classPrivateFieldGet(this, _KeyedDebouncer_delayMs, "f"));
|
|
106
|
+
const debouncer = __classPrivateFieldGet(this, _KeyedDebouncer_instances, "m", _KeyedDebouncer_create).call(this, key);
|
|
107
|
+
__classPrivateFieldGet(this, _KeyedDebouncer_debouncers, "f").set(key, debouncer);
|
|
108
|
+
debouncer.schedule(task, delayMs);
|
|
109
|
+
}
|
|
110
|
+
/** Cancel the task of `key`, if any. */
|
|
111
|
+
cancel(key) {
|
|
112
|
+
__classPrivateFieldGet(this, _KeyedDebouncer_debouncers, "f").get(key)?.cancel();
|
|
113
|
+
}
|
|
114
|
+
/** Cancel every task. Useful when shutting the process down. */
|
|
115
|
+
cancelAll() {
|
|
116
|
+
// Copy first: cancelling removes the debouncer from the map.
|
|
117
|
+
for (const debouncer of [...__classPrivateFieldGet(this, _KeyedDebouncer_debouncers, "f").values()]) {
|
|
118
|
+
debouncer.cancel();
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
/** Whether a task is waiting or running for `key`. */
|
|
122
|
+
isPending(key) {
|
|
123
|
+
return __classPrivateFieldGet(this, _KeyedDebouncer_debouncers, "f").has(key);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
_KeyedDebouncer_debouncers = new WeakMap(), _KeyedDebouncer_delayMs = new WeakMap(), _KeyedDebouncer_onSchedule = new WeakMap(), _KeyedDebouncer_onStart = new WeakMap(), _KeyedDebouncer_onSuccess = new WeakMap(), _KeyedDebouncer_onCancel = new WeakMap(), _KeyedDebouncer_onError = new WeakMap(), _KeyedDebouncer_onIdle = new WeakMap(), _KeyedDebouncer_instances = new WeakSet(), _KeyedDebouncer_create = function _KeyedDebouncer_create(key) {
|
|
127
|
+
const debouncer = new debouncer_js_1.default({
|
|
128
|
+
delayMs: __classPrivateFieldGet(this, _KeyedDebouncer_delayMs, "f"),
|
|
129
|
+
onSchedule: () => __classPrivateFieldGet(this, _KeyedDebouncer_onSchedule, "f").call(this, key),
|
|
130
|
+
onStart: () => __classPrivateFieldGet(this, _KeyedDebouncer_onStart, "f").call(this, key),
|
|
131
|
+
onSuccess: () => __classPrivateFieldGet(this, _KeyedDebouncer_onSuccess, "f").call(this, key),
|
|
132
|
+
onCancel: () => __classPrivateFieldGet(this, _KeyedDebouncer_onCancel, "f").call(this, key),
|
|
133
|
+
onError: (error) => __classPrivateFieldGet(this, _KeyedDebouncer_onError, "f").call(this, error, key),
|
|
134
|
+
onIdle: () => {
|
|
135
|
+
if (__classPrivateFieldGet(this, _KeyedDebouncer_debouncers, "f").get(key) === debouncer) {
|
|
136
|
+
__classPrivateFieldGet(this, _KeyedDebouncer_debouncers, "f").delete(key);
|
|
137
|
+
__classPrivateFieldGet(this, _KeyedDebouncer_onIdle, "f").call(this, key);
|
|
138
|
+
}
|
|
139
|
+
},
|
|
140
|
+
});
|
|
141
|
+
return debouncer;
|
|
142
|
+
};
|
|
143
|
+
exports.default = KeyedDebouncer;
|
|
144
|
+
//# sourceMappingURL=keyed-debouncer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"keyed-debouncer.js","sourceRoot":"","sources":["../../src/keyed-debouncer.ts"],"names":[],"mappings":"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","sourcesContent":["import Debouncer, {assertValidDelay, type DebouncedTask} from \"./debouncer.js\";\nimport {noop} from \"./functions.js\";\n\n/** Options accepted by {@link KeyedDebouncer}. Every callback receives the affected key. */\nexport interface KeyedDebouncerOptions<K> {\n /** Default wait, in milliseconds, before a task is executed. */\n delayMs: number;\n /** Called every time a task is scheduled for `key`, after any previous task of that key has been cancelled. */\n onSchedule?: (key: K) => void;\n /** Called when the wait elapses and the task of `key` is about to run. */\n onStart?: (key: K) => void;\n /** Called when the task of `key` completes without throwing and without being cancelled. */\n onSuccess?: (key: K) => void;\n /** Called when a live task of `key` is cancelled, either explicitly or by being replaced. */\n onCancel?: (key: K) => void;\n /** Receives task errors. Cancellations never reach this callback. Defaults to `console.error`. */\n onError?: (error: unknown, key: K) => void;\n /** Called when `key` has no more pending work, after it has been removed from the debouncer. */\n onIdle?: (key: K) => void;\n}\n\n/**\n * An independent {@link Debouncer} per key.\n * Debouncers only exist for keys with pending work: each one is created when\n * its first task is scheduled and removed as soon as it becomes idle.\n *\n * @example\n * ```ts\n * const debouncer = new KeyedDebouncer<string>({delayMs: 1500});\n *\n * debouncer.schedule(chatId, async (signal) => {\n * const pending = await store.getPending(chatId);\n * const reply = await callAI(pending, {signal});\n * if (signal.aborted) return;\n * await sendReply(chatId, reply);\n * });\n * ```\n */\nexport default class KeyedDebouncer<K = string> {\n readonly #debouncers = new Map<K, Debouncer>();\n readonly #delayMs: number;\n readonly #onSchedule: (key: K) => void;\n readonly #onStart: (key: K) => void;\n readonly #onSuccess: (key: K) => void;\n readonly #onCancel: (key: K) => void;\n readonly #onError: (error: unknown, key: K) => void;\n readonly #onIdle: (key: K) => void;\n\n constructor(options: KeyedDebouncerOptions<K>) {\n assertValidDelay(options.delayMs);\n this.#delayMs = options.delayMs;\n this.#onSchedule = options.onSchedule ?? noop;\n this.#onStart = options.onStart ?? noop;\n this.#onSuccess = options.onSuccess ?? noop;\n this.#onCancel = options.onCancel ?? noop;\n this.#onError = options.onError ?? console.error;\n this.#onIdle = options.onIdle ?? noop;\n }\n\n /** Number of keys with a task waiting or running. */\n get size(): number {\n return this.#debouncers.size;\n }\n\n /**\n * Schedule `task` for `key`, cancelling any previous task of that key.\n *\n * @param key - The key whose task is replaced.\n * @param task - The task to run once the delay elapses.\n * @param delayMs - Wait for this task only. Defaults to the configured `delayMs`.\n */\n schedule(key: K, task: DebouncedTask, delayMs?: number): void {\n const existing = this.#debouncers.get(key);\n if (existing !== undefined) {\n existing.schedule(task, delayMs);\n return;\n }\n\n // Validate first so an invalid delay never registers the key.\n assertValidDelay(delayMs ?? this.#delayMs);\n const debouncer = this.#create(key);\n this.#debouncers.set(key, debouncer);\n debouncer.schedule(task, delayMs);\n }\n\n /** Cancel the task of `key`, if any. */\n cancel(key: K): void {\n this.#debouncers.get(key)?.cancel();\n }\n\n /** Cancel every task. Useful when shutting the process down. */\n cancelAll(): void {\n // Copy first: cancelling removes the debouncer from the map.\n for (const debouncer of [...this.#debouncers.values()]) {\n debouncer.cancel();\n }\n }\n\n /** Whether a task is waiting or running for `key`. */\n isPending(key: K): boolean {\n return this.#debouncers.has(key);\n }\n\n #create(key: K): Debouncer {\n const debouncer: Debouncer = new Debouncer({\n delayMs: this.#delayMs,\n onSchedule: () => this.#onSchedule(key),\n onStart: () => this.#onStart(key),\n onSuccess: () => this.#onSuccess(key),\n onCancel: () => this.#onCancel(key),\n onError: (error) => this.#onError(error, key),\n onIdle: () => {\n if (this.#debouncers.get(key) === debouncer) {\n this.#debouncers.delete(key);\n this.#onIdle(key);\n }\n },\n });\n return debouncer;\n }\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"result.js","sourceRoot":"","sources":["../../src/result.ts"],"names":[],"mappings":"","sourcesContent":["/**\n * Represents success and failure outputs narrowed by `success`.\n */\nexport type Result<TSuccessOutput, TFailureOutput = undefined> =\n | {readonly success: true; readonly output: TSuccessOutput}\n | {readonly success: false; readonly output?: TFailureOutput};\n"]}
|