@ls-stack/utils 3.17.1 → 3.19.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.
Files changed (114) hide show
  1. package/README.md +1 -15
  2. package/docs/README.md +72 -0
  3. package/docs/_media/modules.md +52 -0
  4. package/docs/arrayUtils/-internal-.md +17 -0
  5. package/docs/arrayUtils/README.md +423 -0
  6. package/docs/assertions/-internal-.md +63 -0
  7. package/docs/assertions/README.md +565 -0
  8. package/docs/asyncQueue/-internal-.md +815 -0
  9. package/docs/asyncQueue/README.md +75 -0
  10. package/docs/awaitDebounce.md +66 -0
  11. package/docs/cache/-internal-.md +168 -0
  12. package/docs/cache/README.md +360 -0
  13. package/docs/castValues.md +47 -0
  14. package/docs/concurrentCalls/-internal-.md +416 -0
  15. package/docs/concurrentCalls/README.md +77 -0
  16. package/docs/consoleFmt.md +91 -0
  17. package/docs/conversions.md +27 -0
  18. package/docs/createThrottleController/-internal-.md +73 -0
  19. package/docs/createThrottleController/README.md +31 -0
  20. package/docs/debounce.md +188 -0
  21. package/docs/dedent.md +117 -0
  22. package/docs/deepEqual.md +94 -0
  23. package/docs/enhancedMap.md +358 -0
  24. package/docs/exhaustiveMatch/-internal-.md +39 -0
  25. package/docs/exhaustiveMatch/README.md +146 -0
  26. package/docs/getAutoIncrementId.md +93 -0
  27. package/docs/getCompositeKey.md +39 -0
  28. package/docs/getValueStableKey.md +57 -0
  29. package/docs/hash.md +31 -0
  30. package/docs/interpolate/-internal-.md +61 -0
  31. package/docs/interpolate/README.md +62 -0
  32. package/docs/levenshtein.md +93 -0
  33. package/docs/main.md +21 -0
  34. package/docs/mathUtils.md +137 -0
  35. package/docs/modules.md +52 -0
  36. package/docs/objUtils.md +237 -0
  37. package/docs/parallelAsyncCalls/-internal-.md +347 -0
  38. package/docs/parallelAsyncCalls/README.md +45 -0
  39. package/docs/promiseUtils/-internal-.md +69 -0
  40. package/docs/promiseUtils/README.md +31 -0
  41. package/docs/retryOnError.md +67 -0
  42. package/docs/runShellCmd/-internal-.md +111 -0
  43. package/docs/runShellCmd/README.md +201 -0
  44. package/docs/safeJson.md +51 -0
  45. package/docs/saferTyping.md +228 -0
  46. package/docs/serializeXML.md +100 -0
  47. package/docs/shallowEqual.md +33 -0
  48. package/docs/sleep.md +27 -0
  49. package/docs/stringUtils/-internal-.md +17 -0
  50. package/docs/stringUtils/README.md +166 -0
  51. package/docs/testUtils.md +315 -0
  52. package/docs/throttle/-internal-.md +47 -0
  53. package/docs/throttle/README.md +178 -0
  54. package/docs/time.md +274 -0
  55. package/docs/timers.md +256 -0
  56. package/docs/tsResult/-internal-.md +327 -0
  57. package/docs/tsResult/README.md +696 -0
  58. package/docs/typeGuards.md +399 -0
  59. package/docs/typingFnUtils/-internal-.md +27 -0
  60. package/docs/typingFnUtils/README.md +293 -0
  61. package/docs/typingTestUtils.md +172 -0
  62. package/docs/typingUtils.md +111 -0
  63. package/docs/yamlStringify.md +45 -0
  64. package/lib/arrayUtils.js +3 -3
  65. package/lib/assertions.js +2 -2
  66. package/lib/awaitDebounce.cjs +106 -0
  67. package/lib/awaitDebounce.d.cts +38 -0
  68. package/lib/awaitDebounce.d.ts +38 -0
  69. package/lib/awaitDebounce.js +28 -0
  70. package/lib/cache.js +2 -2
  71. package/lib/{chunk-NH2LCAQS.js → chunk-6FIBVC2P.js} +1 -1
  72. package/lib/{chunk-GKOTKAIV.js → chunk-7CQPOM5I.js} +1 -1
  73. package/lib/{chunk-WS4WEVHU.js → chunk-C2SVCIWE.js} +1 -1
  74. package/lib/{chunk-SSKW673U.js → chunk-JF2MDHOJ.js} +5 -1
  75. package/lib/chunk-NW5H5EW7.js +100 -0
  76. package/lib/{chunk-DMW5Q4T2.js → chunk-SRVMMYSW.js} +1 -1
  77. package/lib/concurrentCalls.js +3 -3
  78. package/lib/createThrottleController.js +3 -3
  79. package/lib/debounce.js +4 -95
  80. package/lib/enhancedMap.js +3 -3
  81. package/lib/getAutoIncrementId.cjs +44 -0
  82. package/lib/getAutoIncrementId.d.cts +44 -0
  83. package/lib/getAutoIncrementId.d.ts +44 -0
  84. package/lib/getAutoIncrementId.js +18 -0
  85. package/lib/getCompositeKey.js +3 -3
  86. package/lib/getValueStableKey.js +3 -3
  87. package/lib/interpolate.js +2 -2
  88. package/lib/parallelAsyncCalls.js +2 -2
  89. package/lib/runShellCmd.d.cts +50 -0
  90. package/lib/runShellCmd.d.ts +50 -0
  91. package/lib/serializeXML.cjs +7 -2
  92. package/lib/serializeXML.d.cts +1 -1
  93. package/lib/serializeXML.d.ts +1 -1
  94. package/lib/serializeXML.js +7 -5
  95. package/lib/testUtils.js +3 -3
  96. package/lib/throttle.cjs +250 -0
  97. package/lib/throttle.d.cts +89 -0
  98. package/lib/throttle.d.ts +89 -0
  99. package/lib/throttle.js +38 -0
  100. package/lib/timers.cjs +93 -0
  101. package/lib/timers.d.cts +110 -0
  102. package/lib/timers.d.ts +110 -0
  103. package/lib/timers.js +65 -0
  104. package/lib/tsResult.js +2 -2
  105. package/lib/typeGuards.cjs +7 -2
  106. package/lib/typeGuards.d.cts +2 -1
  107. package/lib/typeGuards.d.ts +2 -1
  108. package/lib/typeGuards.js +5 -3
  109. package/lib/typingFnUtils.cjs +5 -1
  110. package/lib/typingFnUtils.d.cts +1 -1
  111. package/lib/typingFnUtils.d.ts +1 -1
  112. package/lib/typingFnUtils.js +5 -1
  113. package/lib/yamlStringify.js +5 -5
  114. package/package.json +26 -12
package/lib/testUtils.js CHANGED
@@ -14,11 +14,11 @@ import {
14
14
  import {
15
15
  arrayWithPrevAndIndex,
16
16
  filterAndMap
17
- } from "./chunk-DMW5Q4T2.js";
17
+ } from "./chunk-SRVMMYSW.js";
18
18
  import {
19
19
  isObject
20
- } from "./chunk-WS4WEVHU.js";
21
- import "./chunk-SSKW673U.js";
20
+ } from "./chunk-C2SVCIWE.js";
21
+ import "./chunk-JF2MDHOJ.js";
22
22
 
23
23
  // src/testUtils.ts
24
24
  function createLoggerStore({
@@ -0,0 +1,250 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/throttle.ts
21
+ var throttle_exports = {};
22
+ __export(throttle_exports, {
23
+ createThrottledFunctionFactory: () => createThrottledFunctionFactory,
24
+ throttle: () => throttle
25
+ });
26
+ module.exports = __toCommonJS(throttle_exports);
27
+
28
+ // src/debounce.ts
29
+ function debounce(func, wait, options) {
30
+ let lastArgs;
31
+ let lastThis;
32
+ let maxWait;
33
+ let result;
34
+ let timerId;
35
+ let lastCallTime;
36
+ let lastInvokeTime = 0;
37
+ let leading = false;
38
+ let maxing = false;
39
+ let trailing = true;
40
+ if (options) {
41
+ leading = !!options.leading;
42
+ maxing = "maxWait" in options;
43
+ maxWait = maxing ? Math.max(options.maxWait || 0, wait) : maxWait;
44
+ trailing = "trailing" in options ? !!options.trailing : trailing;
45
+ }
46
+ function invokeFunc(time) {
47
+ const args = lastArgs;
48
+ const thisArg = lastThis;
49
+ lastArgs = lastThis = void 0;
50
+ lastInvokeTime = time;
51
+ result = func.apply(thisArg, args);
52
+ return result;
53
+ }
54
+ function leadingEdge(time) {
55
+ lastInvokeTime = time;
56
+ timerId = setTimeout(timerExpired, wait);
57
+ return leading ? invokeFunc(time) : result;
58
+ }
59
+ function remainingWait(time) {
60
+ const timeSinceLastCall = time - (lastCallTime ?? 0);
61
+ const timeSinceLastInvoke = time - lastInvokeTime;
62
+ const timeWaiting = wait - timeSinceLastCall;
63
+ return maxing ? Math.min(timeWaiting, (maxWait ?? 0) - timeSinceLastInvoke) : timeWaiting;
64
+ }
65
+ function shouldInvoke(time) {
66
+ const timeSinceLastCall = time - (lastCallTime ?? 0);
67
+ const timeSinceLastInvoke = time - lastInvokeTime;
68
+ return lastCallTime === void 0 || timeSinceLastCall >= wait || timeSinceLastCall < 0 || maxing && timeSinceLastInvoke >= (maxWait ?? 0);
69
+ }
70
+ function timerExpired() {
71
+ const time = Date.now();
72
+ if (shouldInvoke(time)) {
73
+ return trailingEdge(time);
74
+ }
75
+ timerId = setTimeout(timerExpired, remainingWait(time));
76
+ }
77
+ function trailingEdge(time) {
78
+ timerId = void 0;
79
+ if (trailing && lastArgs) {
80
+ return invokeFunc(time);
81
+ }
82
+ lastArgs = lastThis = void 0;
83
+ return result;
84
+ }
85
+ function cancel() {
86
+ if (timerId !== void 0) {
87
+ clearTimeout(timerId);
88
+ }
89
+ lastInvokeTime = 0;
90
+ lastArgs = lastCallTime = lastThis = timerId = void 0;
91
+ }
92
+ function flush() {
93
+ return timerId === void 0 ? result : trailingEdge(Date.now());
94
+ }
95
+ function debounced() {
96
+ const time = Date.now();
97
+ const isInvoking = shouldInvoke(time);
98
+ lastArgs = arguments;
99
+ lastThis = this;
100
+ lastCallTime = time;
101
+ if (isInvoking) {
102
+ if (timerId === void 0) {
103
+ return leadingEdge(lastCallTime);
104
+ }
105
+ if (maxing) {
106
+ clearTimeout(timerId);
107
+ timerId = setTimeout(timerExpired, wait);
108
+ return invokeFunc(lastCallTime);
109
+ }
110
+ }
111
+ if (timerId === void 0) {
112
+ timerId = setTimeout(timerExpired, wait);
113
+ }
114
+ return result;
115
+ }
116
+ debounced.cancel = cancel;
117
+ debounced.flush = flush;
118
+ return debounced;
119
+ }
120
+
121
+ // src/typeGuards.ts
122
+ function isFunction(value) {
123
+ return typeof value === "function";
124
+ }
125
+
126
+ // src/assertions.ts
127
+ var isFunction2 = isFunction;
128
+
129
+ // src/enhancedMap.ts
130
+ var enhancedMapReject = Symbol();
131
+ var EnhancedMap = class _EnhancedMap extends Map {
132
+ find(predicate) {
133
+ for (const [key, value] of this) {
134
+ if (predicate(value, key)) {
135
+ return { key, value };
136
+ }
137
+ }
138
+ return void 0;
139
+ }
140
+ setMultiple(...values) {
141
+ if (Array.isArray(values[0])) {
142
+ for (const [key, value] of values) {
143
+ this.set(key, value);
144
+ }
145
+ } else {
146
+ for (const [key, value] of Object.entries(values[0])) {
147
+ this.set(key, value);
148
+ }
149
+ }
150
+ return this;
151
+ }
152
+ getOrThrow(key) {
153
+ const value = this.get(key);
154
+ if (value === void 0) {
155
+ throw new Error(`Key ${key} not found in EnhancedMap`);
156
+ }
157
+ return value;
158
+ }
159
+ getOrInsert(key, fallback) {
160
+ if (!this.has(key)) {
161
+ this.set(key, fallback());
162
+ }
163
+ return this.getOrThrow(key);
164
+ }
165
+ toFilteredValues(predicate) {
166
+ const values = [];
167
+ for (const [key, value] of this) {
168
+ if (predicate(value, key)) {
169
+ values.push(value);
170
+ }
171
+ }
172
+ return values;
173
+ }
174
+ toMap(mapFunction) {
175
+ const values = [];
176
+ for (const [key, value] of this) {
177
+ const result = mapFunction(value, key, enhancedMapReject);
178
+ if (result !== enhancedMapReject) {
179
+ values.push(result);
180
+ }
181
+ }
182
+ return values;
183
+ }
184
+ toObjMap(mapFunction) {
185
+ const values = {};
186
+ for (const [key, value] of this) {
187
+ const result = mapFunction(value, key);
188
+ if (result) {
189
+ values[result[0]] = result[1];
190
+ }
191
+ }
192
+ return values;
193
+ }
194
+ toValues() {
195
+ return [...this.values()];
196
+ }
197
+ toKeys() {
198
+ return [...this.keys()];
199
+ }
200
+ static from(array, mapFunction) {
201
+ const map = new _EnhancedMap();
202
+ if (!array) return map;
203
+ const isFn = isFunction2(mapFunction);
204
+ for (const item of array) {
205
+ if (isFn) {
206
+ const result = mapFunction(item);
207
+ if (result) {
208
+ map.set(result[0], result[1]);
209
+ }
210
+ } else {
211
+ const key = item[mapFunction];
212
+ if (key !== void 0) {
213
+ map.set(key, item);
214
+ }
215
+ }
216
+ }
217
+ return map;
218
+ }
219
+ };
220
+
221
+ // src/throttle.ts
222
+ function throttle(func, wait, options) {
223
+ let leading = true;
224
+ let trailing = true;
225
+ if (options) {
226
+ leading = "leading" in options ? !!options.leading : leading;
227
+ trailing = "trailing" in options ? !!options.trailing : trailing;
228
+ }
229
+ return debounce(func, wait, { leading, maxWait: wait, trailing });
230
+ }
231
+ function createThrottledFunctionFactory(wait, callback, options) {
232
+ const cache = new EnhancedMap();
233
+ return {
234
+ call: (...args) => {
235
+ const key = args.map(
236
+ (arg) => arg === void 0 ? "__UNDEFINED__" : JSON.stringify(arg)
237
+ ).join(",");
238
+ const cachedFunction = cache.getOrInsert(
239
+ key,
240
+ () => throttle(callback, wait, options)
241
+ );
242
+ return cachedFunction(...args);
243
+ }
244
+ };
245
+ }
246
+ // Annotate the CommonJS export names for ESM import in node:
247
+ 0 && (module.exports = {
248
+ createThrottledFunctionFactory,
249
+ throttle
250
+ });
@@ -0,0 +1,89 @@
1
+ import { DebouncedFunc } from './debounce.cjs';
2
+ import { __LEGIT_ANY_FUNCTION__ } from './saferTyping.cjs';
3
+
4
+ interface ThrottleSettings {
5
+ /**
6
+ * Specify invoking on the leading edge of the timeout.
7
+ * @default true
8
+ */
9
+ leading?: boolean;
10
+ /**
11
+ * Specify invoking on the trailing edge of the timeout.
12
+ * @default true
13
+ */
14
+ trailing?: boolean;
15
+ }
16
+ /**
17
+ * Creates a throttled function that only invokes the provided function at most once per every `wait` milliseconds.
18
+ * The throttled function comes with a `cancel` method to cancel delayed invocations and a `flush` method to immediately invoke them.
19
+ *
20
+ * Throttling is useful for rate-limiting events that fire frequently, like scroll or resize handlers.
21
+ * Unlike debouncing, throttling guarantees the function is called at regular intervals.
22
+ *
23
+ * @template T - The type of the function to throttle
24
+ * @param func - The function to throttle
25
+ * @param wait - The number of milliseconds to throttle invocations to
26
+ * @param options - The options object
27
+ * @param options.leading - Specify invoking on the leading edge of the timeout (default: true)
28
+ * @param options.trailing - Specify invoking on the trailing edge of the timeout (default: true)
29
+ * @returns Returns the new throttled function
30
+ *
31
+ * @example
32
+ * ```ts
33
+ * const throttledSave = throttle(saveData, 1000);
34
+ *
35
+ * // Will only call saveData at most once per second
36
+ * throttledSave();
37
+ * throttledSave();
38
+ * throttledSave();
39
+ * ```
40
+ *
41
+ * @example
42
+ * ```ts
43
+ * // Only invoke on trailing edge
44
+ * const throttledHandler = throttle(handleScroll, 100, { leading: false });
45
+ * ```
46
+ */
47
+ declare function throttle<T extends __LEGIT_ANY_FUNCTION__>(func: T, wait: number, options?: ThrottleSettings): DebouncedFunc<T>;
48
+ /**
49
+ * Creates a factory for throttled functions that caches throttled instances based on function arguments.
50
+ * Each unique set of arguments gets its own throttled function instance, allowing for fine-grained
51
+ * throttling control per argument combination.
52
+ *
53
+ * This is useful when you want to throttle calls to the same function but with different parameters
54
+ * independently. For example, throttling API calls per user ID or throttling UI updates per component.
55
+ *
56
+ * @template T - The type of arguments the callback function accepts
57
+ * @template R - The return type of the callback function
58
+ * @param wait - The number of milliseconds to throttle invocations to
59
+ * @param callback - The function to throttle
60
+ * @param options - The throttle options (leading/trailing behavior)
61
+ * @returns An object with a `call` method that accepts the callback arguments
62
+ *
63
+ * @example
64
+ * ```ts
65
+ * const apiThrottle = createThrottledFunctionFactory(
66
+ * 1000,
67
+ * (userId: string, action: string) => callAPI(userId, action)
68
+ * );
69
+ *
70
+ * // Each user gets their own throttled instance
71
+ * apiThrottle.call('user1', 'update'); // Executes immediately
72
+ * apiThrottle.call('user2', 'update'); // Executes immediately (different user)
73
+ * apiThrottle.call('user1', 'update'); // Throttled (same user)
74
+ * ```
75
+ *
76
+ * @example
77
+ * ```ts
78
+ * // Throttle UI updates per component
79
+ * const updateThrottle = createThrottledFunctionFactory(
80
+ * 100,
81
+ * (componentId: string, data: any) => updateComponent(componentId, data)
82
+ * );
83
+ * ```
84
+ */
85
+ declare function createThrottledFunctionFactory<T extends string | number | null | undefined | boolean, R>(wait: number, callback: (...args: T[]) => R, options?: ThrottleSettings): {
86
+ call: (...args: T[]) => R | undefined;
87
+ };
88
+
89
+ export { createThrottledFunctionFactory, throttle };
@@ -0,0 +1,89 @@
1
+ import { DebouncedFunc } from './debounce.js';
2
+ import { __LEGIT_ANY_FUNCTION__ } from './saferTyping.js';
3
+
4
+ interface ThrottleSettings {
5
+ /**
6
+ * Specify invoking on the leading edge of the timeout.
7
+ * @default true
8
+ */
9
+ leading?: boolean;
10
+ /**
11
+ * Specify invoking on the trailing edge of the timeout.
12
+ * @default true
13
+ */
14
+ trailing?: boolean;
15
+ }
16
+ /**
17
+ * Creates a throttled function that only invokes the provided function at most once per every `wait` milliseconds.
18
+ * The throttled function comes with a `cancel` method to cancel delayed invocations and a `flush` method to immediately invoke them.
19
+ *
20
+ * Throttling is useful for rate-limiting events that fire frequently, like scroll or resize handlers.
21
+ * Unlike debouncing, throttling guarantees the function is called at regular intervals.
22
+ *
23
+ * @template T - The type of the function to throttle
24
+ * @param func - The function to throttle
25
+ * @param wait - The number of milliseconds to throttle invocations to
26
+ * @param options - The options object
27
+ * @param options.leading - Specify invoking on the leading edge of the timeout (default: true)
28
+ * @param options.trailing - Specify invoking on the trailing edge of the timeout (default: true)
29
+ * @returns Returns the new throttled function
30
+ *
31
+ * @example
32
+ * ```ts
33
+ * const throttledSave = throttle(saveData, 1000);
34
+ *
35
+ * // Will only call saveData at most once per second
36
+ * throttledSave();
37
+ * throttledSave();
38
+ * throttledSave();
39
+ * ```
40
+ *
41
+ * @example
42
+ * ```ts
43
+ * // Only invoke on trailing edge
44
+ * const throttledHandler = throttle(handleScroll, 100, { leading: false });
45
+ * ```
46
+ */
47
+ declare function throttle<T extends __LEGIT_ANY_FUNCTION__>(func: T, wait: number, options?: ThrottleSettings): DebouncedFunc<T>;
48
+ /**
49
+ * Creates a factory for throttled functions that caches throttled instances based on function arguments.
50
+ * Each unique set of arguments gets its own throttled function instance, allowing for fine-grained
51
+ * throttling control per argument combination.
52
+ *
53
+ * This is useful when you want to throttle calls to the same function but with different parameters
54
+ * independently. For example, throttling API calls per user ID or throttling UI updates per component.
55
+ *
56
+ * @template T - The type of arguments the callback function accepts
57
+ * @template R - The return type of the callback function
58
+ * @param wait - The number of milliseconds to throttle invocations to
59
+ * @param callback - The function to throttle
60
+ * @param options - The throttle options (leading/trailing behavior)
61
+ * @returns An object with a `call` method that accepts the callback arguments
62
+ *
63
+ * @example
64
+ * ```ts
65
+ * const apiThrottle = createThrottledFunctionFactory(
66
+ * 1000,
67
+ * (userId: string, action: string) => callAPI(userId, action)
68
+ * );
69
+ *
70
+ * // Each user gets their own throttled instance
71
+ * apiThrottle.call('user1', 'update'); // Executes immediately
72
+ * apiThrottle.call('user2', 'update'); // Executes immediately (different user)
73
+ * apiThrottle.call('user1', 'update'); // Throttled (same user)
74
+ * ```
75
+ *
76
+ * @example
77
+ * ```ts
78
+ * // Throttle UI updates per component
79
+ * const updateThrottle = createThrottledFunctionFactory(
80
+ * 100,
81
+ * (componentId: string, data: any) => updateComponent(componentId, data)
82
+ * );
83
+ * ```
84
+ */
85
+ declare function createThrottledFunctionFactory<T extends string | number | null | undefined | boolean, R>(wait: number, callback: (...args: T[]) => R, options?: ThrottleSettings): {
86
+ call: (...args: T[]) => R | undefined;
87
+ };
88
+
89
+ export { createThrottledFunctionFactory, throttle };
@@ -0,0 +1,38 @@
1
+ import {
2
+ debounce
3
+ } from "./chunk-NW5H5EW7.js";
4
+ import {
5
+ EnhancedMap
6
+ } from "./chunk-7CQPOM5I.js";
7
+ import "./chunk-C2SVCIWE.js";
8
+ import "./chunk-JF2MDHOJ.js";
9
+
10
+ // src/throttle.ts
11
+ function throttle(func, wait, options) {
12
+ let leading = true;
13
+ let trailing = true;
14
+ if (options) {
15
+ leading = "leading" in options ? !!options.leading : leading;
16
+ trailing = "trailing" in options ? !!options.trailing : trailing;
17
+ }
18
+ return debounce(func, wait, { leading, maxWait: wait, trailing });
19
+ }
20
+ function createThrottledFunctionFactory(wait, callback, options) {
21
+ const cache = new EnhancedMap();
22
+ return {
23
+ call: (...args) => {
24
+ const key = args.map(
25
+ (arg) => arg === void 0 ? "__UNDEFINED__" : JSON.stringify(arg)
26
+ ).join(",");
27
+ const cachedFunction = cache.getOrInsert(
28
+ key,
29
+ () => throttle(callback, wait, options)
30
+ );
31
+ return cachedFunction(...args);
32
+ }
33
+ };
34
+ }
35
+ export {
36
+ createThrottledFunctionFactory,
37
+ throttle
38
+ };
package/lib/timers.cjs ADDED
@@ -0,0 +1,93 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/timers.ts
21
+ var timers_exports = {};
22
+ __export(timers_exports, {
23
+ createDebouncedTimeout: () => createDebouncedTimeout,
24
+ createInterval: () => createInterval,
25
+ createTimeout: () => createTimeout,
26
+ createWaitUntil: () => createWaitUntil
27
+ });
28
+ module.exports = __toCommonJS(timers_exports);
29
+ function createTimeout(ms, callback) {
30
+ const timeoutId = setTimeout(callback, ms);
31
+ let isCleaned = false;
32
+ return () => {
33
+ if (isCleaned) return;
34
+ clearTimeout(timeoutId);
35
+ isCleaned = true;
36
+ };
37
+ }
38
+ function createInterval(ms, callback) {
39
+ const intervalId = setInterval(callback, ms);
40
+ let isCleaned = false;
41
+ return () => {
42
+ if (isCleaned) return;
43
+ clearInterval(intervalId);
44
+ isCleaned = true;
45
+ };
46
+ }
47
+ function createDebouncedTimeout(ms, callback) {
48
+ let cleanupTimer = null;
49
+ return {
50
+ clean: () => {
51
+ cleanupTimer?.();
52
+ },
53
+ call: () => {
54
+ cleanupTimer?.();
55
+ cleanupTimer = createTimeout(ms, () => {
56
+ callback();
57
+ });
58
+ }
59
+ };
60
+ }
61
+ function createWaitUntil({
62
+ condition,
63
+ maxWaitMs,
64
+ callback,
65
+ checkIntervalMs = 20
66
+ }) {
67
+ let cleanCheckTimeout = null;
68
+ let cleanMaxWaitTimeout = null;
69
+ cleanMaxWaitTimeout = createTimeout(maxWaitMs, () => {
70
+ cleanCheckTimeout?.();
71
+ });
72
+ function check() {
73
+ const result = condition();
74
+ if (result) {
75
+ cleanMaxWaitTimeout?.();
76
+ callback(result);
77
+ } else {
78
+ cleanCheckTimeout = createTimeout(checkIntervalMs, check);
79
+ }
80
+ }
81
+ check();
82
+ return () => {
83
+ cleanMaxWaitTimeout();
84
+ cleanCheckTimeout?.();
85
+ };
86
+ }
87
+ // Annotate the CommonJS export names for ESM import in node:
88
+ 0 && (module.exports = {
89
+ createDebouncedTimeout,
90
+ createInterval,
91
+ createTimeout,
92
+ createWaitUntil
93
+ });
@@ -0,0 +1,110 @@
1
+ type CleanupTimer = () => void;
2
+ /**
3
+ * Creates a timeout with automatic cleanup capability.
4
+ *
5
+ * Returns a cleanup function that can be called to cancel the timeout.
6
+ * The cleanup function is idempotent - calling it multiple times is safe.
7
+ *
8
+ * @param ms - The timeout duration in milliseconds
9
+ * @param callback - The function to execute when the timeout completes
10
+ * @returns A cleanup function that cancels the timeout when called
11
+ *
12
+ * @example
13
+ * ```typescript
14
+ * const cleanup = createTimeout(1000, () => {
15
+ * console.log('Timeout completed');
16
+ * });
17
+ *
18
+ * // Cancel the timeout before it completes
19
+ * cleanup();
20
+ * ```
21
+ */
22
+ declare function createTimeout(ms: number, callback: () => void): CleanupTimer;
23
+ /**
24
+ * Creates an interval with automatic cleanup capability.
25
+ *
26
+ * Returns a cleanup function that can be called to cancel the interval.
27
+ * The cleanup function is idempotent - calling it multiple times is safe.
28
+ *
29
+ * @param ms - The interval duration in milliseconds
30
+ * @param callback - The function to execute on each interval tick
31
+ * @returns A cleanup function that cancels the interval when called
32
+ *
33
+ * @example
34
+ * ```typescript
35
+ * const cleanup = createInterval(1000, () => {
36
+ * console.log('Interval tick');
37
+ * });
38
+ *
39
+ * // Stop the interval
40
+ * cleanup();
41
+ * ```
42
+ */
43
+ declare function createInterval(ms: number, callback: () => void): CleanupTimer;
44
+ /**
45
+ * Creates a timeout that prevents concurrent executions.
46
+ *
47
+ * Each call to the `call` function will cancel any previous pending timeout
48
+ * and start a new one. This is useful for debouncing or ensuring only the
49
+ * last call executes after a delay.
50
+ *
51
+ * @param ms - The timeout duration in milliseconds
52
+ * @param callback - The function to execute when the timeout completes
53
+ * @returns An object with `call` to trigger the timeout and `clean` to cancel it
54
+ *
55
+ * @example
56
+ * ```typescript
57
+ * const { call, clean } = createDebouncedTimeout(1000, () => {
58
+ * console.log('Only the last call executes');
59
+ * });
60
+ *
61
+ * call(); // This will be cancelled
62
+ * call(); // This will be cancelled
63
+ * call(); // Only this one will execute after 1000ms
64
+ *
65
+ * // Or cancel all pending timeouts
66
+ * clean();
67
+ * ```
68
+ */
69
+ declare function createDebouncedTimeout(ms: number, callback: () => void): {
70
+ call: () => void;
71
+ clean: CleanupTimer;
72
+ };
73
+ /**
74
+ * Creates a timeout that waits for a condition to become true.
75
+ *
76
+ * Polls the condition function at regular intervals until it returns a truthy value,
77
+ * then calls the callback with that value. If the condition doesn't become true
78
+ * within the maximum wait time, the timeout expires without calling the callback.
79
+ *
80
+ * @template T - The type of value returned by the condition function when true
81
+ * @param options - Configuration options
82
+ * @param options.condition - Function that returns false or a truthy value when the condition is met
83
+ * @param options.maxWaitMs - Maximum time to wait for the condition in milliseconds
84
+ * @param options.callback - Function to call when the condition becomes true
85
+ * @param options.checkIntervalMs - How often to check the condition in milliseconds (default: 20)
86
+ * @returns A cleanup function that cancels the condition timeout
87
+ *
88
+ * @example
89
+ * ```typescript
90
+ * const cleanup = createWaitUntil({
91
+ * condition: () => document.getElementById('myElement'),
92
+ * maxWaitMs: 5000,
93
+ * callback: (element) => {
94
+ * console.log('Element found:', element);
95
+ * },
96
+ * checkIntervalMs: 50
97
+ * });
98
+ *
99
+ * // Cancel the condition check
100
+ * cleanup();
101
+ * ```
102
+ */
103
+ declare function createWaitUntil<T extends NonNullable<unknown>>({ condition, maxWaitMs, callback, checkIntervalMs, }: {
104
+ condition: () => false | T;
105
+ maxWaitMs: number;
106
+ callback: (value: T) => void;
107
+ checkIntervalMs?: number;
108
+ }): CleanupTimer;
109
+
110
+ export { type CleanupTimer, createDebouncedTimeout, createInterval, createTimeout, createWaitUntil };