@develia/commons 0.4.16 → 0.4.18

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 (207) hide show
  1. package/dist/cjs/array.js +22 -2
  2. package/dist/cjs/array.js.map +1 -1
  3. package/dist/cjs/async-pool-executor.js +26 -11
  4. package/dist/cjs/async-pool-executor.js.map +1 -1
  5. package/dist/cjs/browser/form-utilities.js +35 -34
  6. package/dist/cjs/browser/form-utilities.js.map +1 -1
  7. package/dist/cjs/browser/geo-location.js +1 -1
  8. package/dist/cjs/browser/geo-location.js.map +1 -1
  9. package/dist/cjs/browser/native-bridge.js +3 -1
  10. package/dist/cjs/browser/native-bridge.js.map +1 -1
  11. package/dist/cjs/cancellable-promise.js +34 -13
  12. package/dist/cjs/cancellable-promise.js.map +1 -1
  13. package/dist/cjs/clean-url-search-params.js +26 -3
  14. package/dist/cjs/clean-url-search-params.js.map +1 -1
  15. package/dist/cjs/collections/cache-dictionary.js +3 -3
  16. package/dist/cjs/collections/cache-dictionary.js.map +1 -1
  17. package/dist/cjs/collections/default-map.js.map +1 -1
  18. package/dist/cjs/collections/default-weak-map.js.map +1 -1
  19. package/dist/cjs/collections/from.js +3 -3
  20. package/dist/cjs/collections/from.js.map +1 -1
  21. package/dist/cjs/collections/index.js.map +1 -1
  22. package/dist/cjs/draft.js +46 -11
  23. package/dist/cjs/draft.js.map +1 -1
  24. package/dist/cjs/event-bus.js +1 -1
  25. package/dist/cjs/event-bus.js.map +1 -1
  26. package/dist/cjs/functions.js +348 -0
  27. package/dist/cjs/functions.js.map +1 -0
  28. package/dist/cjs/index.js +1 -0
  29. package/dist/cjs/index.js.map +1 -1
  30. package/dist/cjs/key-value-pair.js.map +1 -1
  31. package/dist/cjs/lazy.js.map +1 -1
  32. package/dist/cjs/math.js +3 -0
  33. package/dist/cjs/math.js.map +1 -1
  34. package/dist/cjs/order.js.map +1 -1
  35. package/dist/cjs/parse.js +10 -1
  36. package/dist/cjs/parse.js.map +1 -1
  37. package/dist/cjs/patch.js.map +1 -1
  38. package/dist/cjs/stopwatch.js.map +1 -1
  39. package/dist/cjs/string.js +8 -5
  40. package/dist/cjs/string.js.map +1 -1
  41. package/dist/cjs/timer.js +1 -1
  42. package/dist/cjs/timer.js.map +1 -1
  43. package/dist/cjs/timespan.js +21 -8
  44. package/dist/cjs/timespan.js.map +1 -1
  45. package/dist/cjs/type-code.js.map +1 -1
  46. package/dist/cjs/type.js +20 -19
  47. package/dist/cjs/type.js.map +1 -1
  48. package/dist/cjs/types.js.map +1 -1
  49. package/dist/cjs/utilities.js +175 -39
  50. package/dist/cjs/utilities.js.map +1 -1
  51. package/dist/esm/array.js +21 -2
  52. package/dist/esm/array.js.map +1 -1
  53. package/dist/esm/async-pool-executor.js +26 -11
  54. package/dist/esm/async-pool-executor.js.map +1 -1
  55. package/dist/esm/browser/form-utilities.js +35 -34
  56. package/dist/esm/browser/form-utilities.js.map +1 -1
  57. package/dist/esm/browser/geo-location.js +1 -1
  58. package/dist/esm/browser/geo-location.js.map +1 -1
  59. package/dist/esm/browser/native-bridge.js +3 -1
  60. package/dist/esm/browser/native-bridge.js.map +1 -1
  61. package/dist/esm/cancellable-promise.js +34 -13
  62. package/dist/esm/cancellable-promise.js.map +1 -1
  63. package/dist/esm/clean-url-search-params.js +26 -3
  64. package/dist/esm/clean-url-search-params.js.map +1 -1
  65. package/dist/esm/collections/cache-dictionary.js +3 -3
  66. package/dist/esm/collections/cache-dictionary.js.map +1 -1
  67. package/dist/esm/collections/default-map.js.map +1 -1
  68. package/dist/esm/collections/default-weak-map.js.map +1 -1
  69. package/dist/esm/collections/from.js +3 -3
  70. package/dist/esm/collections/from.js.map +1 -1
  71. package/dist/esm/collections/index.js.map +1 -1
  72. package/dist/esm/draft.js +46 -11
  73. package/dist/esm/draft.js.map +1 -1
  74. package/dist/esm/event-bus.js +1 -1
  75. package/dist/esm/event-bus.js.map +1 -1
  76. package/dist/esm/functions.js +336 -0
  77. package/dist/esm/functions.js.map +1 -0
  78. package/dist/esm/index.js +1 -0
  79. package/dist/esm/index.js.map +1 -1
  80. package/dist/esm/key-value-pair.js.map +1 -1
  81. package/dist/esm/lazy.js.map +1 -1
  82. package/dist/esm/math.js +3 -0
  83. package/dist/esm/math.js.map +1 -1
  84. package/dist/esm/order.js.map +1 -1
  85. package/dist/esm/parse.js +10 -1
  86. package/dist/esm/parse.js.map +1 -1
  87. package/dist/esm/patch.js.map +1 -1
  88. package/dist/esm/stopwatch.js.map +1 -1
  89. package/dist/esm/string.js +8 -5
  90. package/dist/esm/string.js.map +1 -1
  91. package/dist/esm/timer.js +1 -1
  92. package/dist/esm/timer.js.map +1 -1
  93. package/dist/esm/timespan.js +21 -8
  94. package/dist/esm/timespan.js.map +1 -1
  95. package/dist/esm/type-code.js.map +1 -1
  96. package/dist/esm/type.js +20 -19
  97. package/dist/esm/type.js.map +1 -1
  98. package/dist/esm/types.js.map +1 -1
  99. package/dist/esm/utilities.js +174 -39
  100. package/dist/esm/utilities.js.map +1 -1
  101. package/dist/types/array.d.ts +20 -0
  102. package/dist/types/array.d.ts.map +1 -1
  103. package/dist/types/async-pool-executor.d.ts +2 -2
  104. package/dist/types/async-pool-executor.d.ts.map +1 -1
  105. package/dist/types/browser/form-utilities.d.ts.map +1 -1
  106. package/dist/types/browser/native-bridge.d.ts.map +1 -1
  107. package/dist/types/cancellable-promise.d.ts.map +1 -1
  108. package/dist/types/clean-url-search-params.d.ts +3 -1
  109. package/dist/types/clean-url-search-params.d.ts.map +1 -1
  110. package/dist/types/collections/from.d.ts +1 -1
  111. package/dist/types/draft.d.ts.map +1 -1
  112. package/dist/types/functions.d.ts +231 -0
  113. package/dist/types/functions.d.ts.map +1 -0
  114. package/dist/types/index.d.ts +1 -0
  115. package/dist/types/index.d.ts.map +1 -1
  116. package/dist/types/math.d.ts.map +1 -1
  117. package/dist/types/parse.d.ts.map +1 -1
  118. package/dist/types/string.d.ts.map +1 -1
  119. package/dist/types/timer.d.ts +1 -1
  120. package/dist/types/timespan.d.ts.map +1 -1
  121. package/dist/types/type.d.ts +2 -0
  122. package/dist/types/type.d.ts.map +1 -1
  123. package/dist/types/types.d.ts +1 -1
  124. package/dist/types/types.d.ts.map +1 -1
  125. package/dist/types/utilities.d.ts +21 -3
  126. package/dist/types/utilities.d.ts.map +1 -1
  127. package/dist/web/array.js +21 -2
  128. package/dist/web/array.js.map +1 -1
  129. package/dist/web/async-pool-executor.js +26 -11
  130. package/dist/web/async-pool-executor.js.map +1 -1
  131. package/dist/web/browser/form-utilities.js +35 -34
  132. package/dist/web/browser/form-utilities.js.map +1 -1
  133. package/dist/web/browser/geo-location.js +1 -1
  134. package/dist/web/browser/geo-location.js.map +1 -1
  135. package/dist/web/browser/native-bridge.js +3 -1
  136. package/dist/web/browser/native-bridge.js.map +1 -1
  137. package/dist/web/cancellable-promise.js +34 -13
  138. package/dist/web/cancellable-promise.js.map +1 -1
  139. package/dist/web/clean-url-search-params.js +26 -3
  140. package/dist/web/clean-url-search-params.js.map +1 -1
  141. package/dist/web/collections/cache-dictionary.js +3 -3
  142. package/dist/web/collections/cache-dictionary.js.map +1 -1
  143. package/dist/web/collections/default-map.js.map +1 -1
  144. package/dist/web/collections/default-weak-map.js.map +1 -1
  145. package/dist/web/collections/from.js +3 -3
  146. package/dist/web/collections/from.js.map +1 -1
  147. package/dist/web/collections/index.js.map +1 -1
  148. package/dist/web/draft.js +46 -11
  149. package/dist/web/draft.js.map +1 -1
  150. package/dist/web/event-bus.js +1 -1
  151. package/dist/web/event-bus.js.map +1 -1
  152. package/dist/web/functions.js +336 -0
  153. package/dist/web/functions.js.map +1 -0
  154. package/dist/web/index.js +1 -0
  155. package/dist/web/index.js.map +1 -1
  156. package/dist/web/key-value-pair.js.map +1 -1
  157. package/dist/web/lazy.js.map +1 -1
  158. package/dist/web/math.js +3 -0
  159. package/dist/web/math.js.map +1 -1
  160. package/dist/web/order.js.map +1 -1
  161. package/dist/web/parse.js +10 -1
  162. package/dist/web/parse.js.map +1 -1
  163. package/dist/web/patch.js.map +1 -1
  164. package/dist/web/stopwatch.js.map +1 -1
  165. package/dist/web/string.js +8 -5
  166. package/dist/web/string.js.map +1 -1
  167. package/dist/web/timer.js +1 -1
  168. package/dist/web/timer.js.map +1 -1
  169. package/dist/web/timespan.js +21 -8
  170. package/dist/web/timespan.js.map +1 -1
  171. package/dist/web/type-code.js.map +1 -1
  172. package/dist/web/type.js +20 -19
  173. package/dist/web/type.js.map +1 -1
  174. package/dist/web/types.js.map +1 -1
  175. package/dist/web/utilities.js +174 -39
  176. package/dist/web/utilities.js.map +1 -1
  177. package/package.json +66 -60
  178. package/src/array.ts +116 -84
  179. package/src/async-pool-executor.ts +107 -85
  180. package/src/browser/form-utilities.ts +32 -31
  181. package/src/browser/geo-location.ts +113 -113
  182. package/src/browser/native-bridge.ts +118 -116
  183. package/src/cancellable-promise.ts +102 -76
  184. package/src/clean-url-search-params.ts +36 -11
  185. package/src/collections/cache-dictionary.ts +115 -115
  186. package/src/collections/default-map.ts +48 -48
  187. package/src/collections/default-weak-map.ts +51 -51
  188. package/src/collections/from.ts +859 -859
  189. package/src/collections/index.ts +3 -3
  190. package/src/draft.ts +55 -16
  191. package/src/event-bus.ts +83 -83
  192. package/src/functions.ts +496 -0
  193. package/src/index.ts +1 -0
  194. package/src/key-value-pair.ts +24 -24
  195. package/src/lazy.ts +32 -32
  196. package/src/math.ts +33 -30
  197. package/src/order.ts +5 -5
  198. package/src/parse.ts +251 -240
  199. package/src/patch.ts +79 -79
  200. package/src/stopwatch.ts +43 -43
  201. package/src/string.ts +8 -5
  202. package/src/timer.ts +67 -67
  203. package/src/timespan.ts +412 -398
  204. package/src/type-code.ts +15 -15
  205. package/src/type.ts +372 -371
  206. package/src/types.ts +30 -30
  207. package/src/utilities.ts +653 -480
@@ -0,0 +1,336 @@
1
+ /**
2
+ * Return the received value unchanged.
3
+ * Useful as a default mapper, placeholder callback, or neutral transform in a pipeline.
4
+ *
5
+ * @example
6
+ * ```ts
7
+ * identity(5); // 5
8
+ *
9
+ * const value = {name: "commons"};
10
+ * identity(value) === value; // true
11
+ * ```
12
+ */
13
+ export function identity(value) {
14
+ return value;
15
+ }
16
+ /**
17
+ * Create a function that always returns the same value.
18
+ *
19
+ * @example
20
+ * ```ts
21
+ * const getAnswer = constant(42);
22
+ *
23
+ * getAnswer(); // 42
24
+ * getAnswer(); // 42
25
+ * ```
26
+ */
27
+ export function constant(value) {
28
+ return () => value;
29
+ }
30
+ /**
31
+ * Do nothing and return undefined.
32
+ * Useful as a safe default callback.
33
+ *
34
+ * @example
35
+ * ```ts
36
+ * const onComplete = options.onComplete ?? noop;
37
+ * onComplete();
38
+ * ```
39
+ */
40
+ export function noop() {
41
+ // Intentionally empty.
42
+ }
43
+ /**
44
+ * Create a function that can be executed only once.
45
+ * Later calls return the result from the first execution without calling the original function again.
46
+ *
47
+ * @example
48
+ * ```ts
49
+ * const initialize = once(() => ({connected: true}));
50
+ *
51
+ * const first = initialize();
52
+ * const second = initialize();
53
+ * first === second; // true
54
+ * ```
55
+ */
56
+ export function once(fn) {
57
+ let called = false;
58
+ let result;
59
+ return function (...args) {
60
+ if (!called) {
61
+ called = true;
62
+ result = fn.apply(this, args);
63
+ }
64
+ return result;
65
+ };
66
+ }
67
+ /**
68
+ * Cache the result of a function and reuse it for calls with the same resolved key.
69
+ * By default, the first argument is used as the cache key.
70
+ *
71
+ * @example
72
+ * ```ts
73
+ * const double = memoize((value: number) => value * 2);
74
+ *
75
+ * double(4); // 8, computed
76
+ * double(4); // 8, read from cache
77
+ * double.has(4); // true
78
+ * ```
79
+ *
80
+ * @example
81
+ * ```ts
82
+ * const sum = memoize(
83
+ * (left: number, right: number) => left + right,
84
+ * (left, right) => `${left}:${right}`,
85
+ * );
86
+ *
87
+ * sum(2, 3); // 5
88
+ * sum.delete(2, 3); // true
89
+ * sum.clear();
90
+ * ```
91
+ */
92
+ export function memoize(fn, resolver, cache = new Map()) {
93
+ const resolveKey = (...args) => {
94
+ if (resolver)
95
+ return resolver(...args);
96
+ return args[0];
97
+ };
98
+ const memoized = function (...args) {
99
+ const key = resolveKey(...args);
100
+ if (cache.has(key)) {
101
+ return cache.get(key);
102
+ }
103
+ const value = fn.apply(this, args);
104
+ cache.set(key, value);
105
+ return value;
106
+ };
107
+ Object.defineProperty(memoized, "cache", {
108
+ value: cache,
109
+ enumerable: false,
110
+ });
111
+ memoized.clear = () => cache.clear();
112
+ memoized.delete = (...args) => cache.delete(resolveKey(...args));
113
+ memoized.has = (...args) => cache.has(resolveKey(...args));
114
+ return memoized;
115
+ }
116
+ /**
117
+ * Delay a function until no calls have been made for the configured wait time.
118
+ * The latest arguments and this-context are used for the trailing execution.
119
+ *
120
+ * @example
121
+ * ```ts
122
+ * const search = debounce((query: string) => {
123
+ * console.log(query);
124
+ * }, 300);
125
+ *
126
+ * search("com");
127
+ * search("commons"); // only this value is printed after 300 ms
128
+ * ```
129
+ *
130
+ * @example
131
+ * ```ts
132
+ * const track = debounce(sendAnalytics, 1000, {leading: true, trailing: false});
133
+ *
134
+ * track("open"); // executed immediately
135
+ * track.cancel(); // cancel the pending debounce window
136
+ * ```
137
+ */
138
+ export function debounce(fn, wait, options = {}) {
139
+ const delay = normalizeDelay(wait);
140
+ const leading = options.leading ?? false;
141
+ const trailing = options.trailing ?? true;
142
+ let timer;
143
+ let lastArgs;
144
+ let lastThis;
145
+ let result;
146
+ const invoke = () => {
147
+ const args = lastArgs;
148
+ const context = lastThis;
149
+ lastArgs = undefined;
150
+ lastThis = undefined;
151
+ result = fn.apply(context, args);
152
+ return result;
153
+ };
154
+ const expire = () => {
155
+ timer = undefined;
156
+ if (trailing && lastArgs) {
157
+ invoke();
158
+ }
159
+ else {
160
+ lastArgs = undefined;
161
+ lastThis = undefined;
162
+ }
163
+ };
164
+ const start = () => {
165
+ timer = setTimeout(expire, delay);
166
+ };
167
+ const debounced = function (...args) {
168
+ const invokeLeading = leading && timer === undefined;
169
+ lastArgs = args;
170
+ lastThis = this;
171
+ if (timer !== undefined) {
172
+ clearTimeout(timer);
173
+ }
174
+ start();
175
+ if (invokeLeading) {
176
+ return invoke();
177
+ }
178
+ return result;
179
+ };
180
+ debounced.cancel = () => {
181
+ if (timer !== undefined) {
182
+ clearTimeout(timer);
183
+ }
184
+ timer = undefined;
185
+ lastArgs = undefined;
186
+ lastThis = undefined;
187
+ };
188
+ debounced.flush = () => {
189
+ if (timer !== undefined) {
190
+ clearTimeout(timer);
191
+ timer = undefined;
192
+ if (lastArgs && trailing) {
193
+ return invoke();
194
+ }
195
+ }
196
+ return result;
197
+ };
198
+ debounced.pending = () => timer !== undefined;
199
+ return debounced;
200
+ }
201
+ /**
202
+ * Limit how often a function can run during a time window.
203
+ * Calls made while the function is throttled can optionally be replayed once at the end with the latest arguments.
204
+ *
205
+ * @example
206
+ * ```ts
207
+ * const onScroll = throttle(() => {
208
+ * console.log(window.scrollY);
209
+ * }, 100);
210
+ *
211
+ * window.addEventListener("scroll", onScroll);
212
+ * ```
213
+ *
214
+ * @example
215
+ * ```ts
216
+ * const refresh = throttle(loadData, 500, {leading: false});
217
+ *
218
+ * refresh(); // scheduled instead of executed immediately
219
+ * refresh.flush(); // execute the scheduled call now
220
+ * ```
221
+ */
222
+ export function throttle(fn, wait, options = {}) {
223
+ const delay = normalizeDelay(wait);
224
+ const leading = options.leading ?? true;
225
+ const trailing = options.trailing ?? true;
226
+ let timer;
227
+ let lastArgs;
228
+ let lastThis;
229
+ let lastInvokeTime = 0;
230
+ let hasInvoked = false;
231
+ let result;
232
+ const invoke = (time) => {
233
+ const args = lastArgs;
234
+ const context = lastThis;
235
+ lastArgs = undefined;
236
+ lastThis = undefined;
237
+ hasInvoked = true;
238
+ lastInvokeTime = time;
239
+ result = fn.apply(context, args);
240
+ return result;
241
+ };
242
+ const expire = () => {
243
+ timer = undefined;
244
+ if (trailing && lastArgs) {
245
+ invoke(Date.now());
246
+ }
247
+ else {
248
+ lastArgs = undefined;
249
+ lastThis = undefined;
250
+ }
251
+ };
252
+ const throttled = function (...args) {
253
+ const now = Date.now();
254
+ lastArgs = args;
255
+ lastThis = this;
256
+ if (!hasInvoked) {
257
+ if (leading) {
258
+ return invoke(now);
259
+ }
260
+ hasInvoked = true;
261
+ lastInvokeTime = now;
262
+ }
263
+ const remaining = delay - (now - lastInvokeTime);
264
+ if (remaining <= 0 || remaining > delay) {
265
+ if (timer !== undefined) {
266
+ clearTimeout(timer);
267
+ timer = undefined;
268
+ }
269
+ return invoke(now);
270
+ }
271
+ if (timer === undefined && trailing) {
272
+ timer = setTimeout(expire, remaining);
273
+ }
274
+ return result;
275
+ };
276
+ throttled.cancel = () => {
277
+ if (timer !== undefined) {
278
+ clearTimeout(timer);
279
+ }
280
+ timer = undefined;
281
+ lastArgs = undefined;
282
+ lastThis = undefined;
283
+ lastInvokeTime = 0;
284
+ hasInvoked = false;
285
+ };
286
+ throttled.flush = () => {
287
+ if (timer !== undefined) {
288
+ clearTimeout(timer);
289
+ timer = undefined;
290
+ if (lastArgs && trailing) {
291
+ return invoke(Date.now());
292
+ }
293
+ }
294
+ return result;
295
+ };
296
+ throttled.pending = () => timer !== undefined;
297
+ return throttled;
298
+ }
299
+ /**
300
+ * Create a function with one or more arguments already provided.
301
+ * Later arguments are appended after the preset arguments.
302
+ *
303
+ * @example
304
+ * ```ts
305
+ * const sum = (a: number, b: number, c: number) => a + b + c;
306
+ * const addFive = partial(sum, 2, 3);
307
+ *
308
+ * addFive(4); // 9
309
+ * ```
310
+ */
311
+ export function partial(fn, ...presetArgs) {
312
+ return function (...laterArgs) {
313
+ return fn.apply(this, [...presetArgs, ...laterArgs]);
314
+ };
315
+ }
316
+ export function pipe(...fns) {
317
+ return createFlow(fns);
318
+ }
319
+ export function compose(...fns) {
320
+ return createFlow(fns.slice().reverse());
321
+ }
322
+ function createFlow(fns) {
323
+ if (fns.length === 0)
324
+ return identity;
325
+ return function (...args) {
326
+ let result = fns[0].apply(this, args);
327
+ for (let i = 1; i < fns.length; i++) {
328
+ result = fns[i].call(this, result);
329
+ }
330
+ return result;
331
+ };
332
+ }
333
+ function normalizeDelay(wait) {
334
+ return Number.isFinite(wait) ? Math.max(0, wait) : 0;
335
+ }
336
+ //# sourceMappingURL=functions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"functions.js","sourceRoot":"","sources":["../../src/functions.ts"],"names":[],"mappings":"AAwEA;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,QAAQ,CAAI,KAAQ;IAChC,OAAO,KAAK,CAAC;AACjB,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,UAAU,QAAQ,CAAI,KAAQ;IAChC,OAAO,GAAG,EAAE,CAAC,KAAK,CAAC;AACvB,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,IAAI;IAChB,uBAAuB;AAC3B,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,IAAI,CAAwB,EAAK;IAC7C,IAAI,MAAM,GAAG,KAAK,CAAC;IACnB,IAAI,MAAqB,CAAC;IAE1B,OAAO,UAAsC,GAAG,IAAmB;QAC/D,IAAI,CAAC,MAAM,EAAE,CAAC;YACV,MAAM,GAAG,IAAI,CAAC;YACd,MAAM,GAAG,EAAE,CAAC,KAAK,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;QAClC,CAAC;QACD,OAAO,MAAM,CAAC;IAClB,CAAM,CAAC;AACX,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,MAAM,UAAU,OAAO,CACnB,EAAK,EACL,QAAwC,EACxC,QAA+B,IAAI,GAAG,EAAoB;IAE1D,MAAM,UAAU,GAAG,CAAC,GAAG,IAAmB,EAAK,EAAE;QAC7C,IAAI,QAAQ;YAAE,OAAO,QAAQ,CAAC,GAAG,IAAI,CAAC,CAAC;QACvC,OAAO,IAAI,CAAC,CAAC,CAAM,CAAC;IACxB,CAAC,CAAC;IAEF,MAAM,QAAQ,GAAG,UAAsC,GAAG,IAAmB;QACzE,MAAM,GAAG,GAAG,UAAU,CAAC,GAAG,IAAI,CAAC,CAAC;QAChC,IAAI,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;YACjB,OAAO,KAAK,CAAC,GAAG,CAAC,GAAG,CAAE,CAAC;QAC3B,CAAC;QAED,MAAM,KAAK,GAAG,EAAE,CAAC,KAAK,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;QACnC,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;QACtB,OAAO,KAAK,CAAC;IACjB,CAA2B,CAAC;IAE5B,MAAM,CAAC,cAAc,CAAC,QAAQ,EAAE,OAAO,EAAE;QACrC,KAAK,EAAE,KAAK;QACZ,UAAU,EAAE,KAAK;KACpB,CAAC,CAAC;IAEH,QAAQ,CAAC,KAAK,GAAG,GAAG,EAAE,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;IACrC,QAAQ,CAAC,MAAM,GAAG,CAAC,GAAG,IAAmB,EAAE,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,UAAU,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC;IAChF,QAAQ,CAAC,GAAG,GAAG,CAAC,GAAG,IAAmB,EAAE,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,UAAU,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC;IAE1E,OAAO,QAAQ,CAAC;AACpB,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAM,UAAU,QAAQ,CACpB,EAAK,EACL,IAAY,EACZ,UAA2B,EAAE;IAE7B,MAAM,KAAK,GAAG,cAAc,CAAC,IAAI,CAAC,CAAC;IACnC,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,IAAI,KAAK,CAAC;IACzC,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,IAAI,IAAI,CAAC;IAE1C,IAAI,KAA8B,CAAC;IACnC,IAAI,QAAmC,CAAC;IACxC,IAAI,QAA0C,CAAC;IAC/C,IAAI,MAAiC,CAAC;IAEtC,MAAM,MAAM,GAAG,GAAkB,EAAE;QAC/B,MAAM,IAAI,GAAG,QAAS,CAAC;QACvB,MAAM,OAAO,GAAG,QAAS,CAAC;QAC1B,QAAQ,GAAG,SAAS,CAAC;QACrB,QAAQ,GAAG,SAAS,CAAC;QACrB,MAAM,GAAG,EAAE,CAAC,KAAK,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;QACjC,OAAO,MAAuB,CAAC;IACnC,CAAC,CAAC;IAEF,MAAM,MAAM,GAAG,GAAS,EAAE;QACtB,KAAK,GAAG,SAAS,CAAC;QAClB,IAAI,QAAQ,IAAI,QAAQ,EAAE,CAAC;YACvB,MAAM,EAAE,CAAC;QACb,CAAC;aAAM,CAAC;YACJ,QAAQ,GAAG,SAAS,CAAC;YACrB,QAAQ,GAAG,SAAS,CAAC;QACzB,CAAC;IACL,CAAC,CAAC;IAEF,MAAM,KAAK,GAAG,GAAS,EAAE;QACrB,KAAK,GAAG,UAAU,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;IACtC,CAAC,CAAC;IAEF,MAAM,SAAS,GAAG,UAAsC,GAAG,IAAmB;QAC1E,MAAM,aAAa,GAAG,OAAO,IAAI,KAAK,KAAK,SAAS,CAAC;QACrD,QAAQ,GAAG,IAAI,CAAC;QAChB,QAAQ,GAAG,IAAI,CAAC;QAEhB,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YACtB,YAAY,CAAC,KAAK,CAAC,CAAC;QACxB,CAAC;QACD,KAAK,EAAE,CAAC;QAER,IAAI,aAAa,EAAE,CAAC;YAChB,OAAO,MAAM,EAAE,CAAC;QACpB,CAAC;QAED,OAAO,MAAM,CAAC;IAClB,CAAwB,CAAC;IAEzB,SAAS,CAAC,MAAM,GAAG,GAAS,EAAE;QAC1B,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YACtB,YAAY,CAAC,KAAK,CAAC,CAAC;QACxB,CAAC;QACD,KAAK,GAAG,SAAS,CAAC;QAClB,QAAQ,GAAG,SAAS,CAAC;QACrB,QAAQ,GAAG,SAAS,CAAC;IACzB,CAAC,CAAC;IAEF,SAAS,CAAC,KAAK,GAAG,GAA8B,EAAE;QAC9C,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YACtB,YAAY,CAAC,KAAK,CAAC,CAAC;YACpB,KAAK,GAAG,SAAS,CAAC;YAClB,IAAI,QAAQ,IAAI,QAAQ,EAAE,CAAC;gBACvB,OAAO,MAAM,EAAE,CAAC;YACpB,CAAC;QACL,CAAC;QACD,OAAO,MAAM,CAAC;IAClB,CAAC,CAAC;IAEF,SAAS,CAAC,OAAO,GAAG,GAAY,EAAE,CAAC,KAAK,KAAK,SAAS,CAAC;IAEvD,OAAO,SAAS,CAAC;AACrB,CAAC;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,UAAU,QAAQ,CACpB,EAAK,EACL,IAAY,EACZ,UAA2B,EAAE;IAE7B,MAAM,KAAK,GAAG,cAAc,CAAC,IAAI,CAAC,CAAC;IACnC,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,IAAI,IAAI,CAAC;IACxC,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,IAAI,IAAI,CAAC;IAE1C,IAAI,KAA8B,CAAC;IACnC,IAAI,QAAmC,CAAC;IACxC,IAAI,QAA0C,CAAC;IAC/C,IAAI,cAAc,GAAG,CAAC,CAAC;IACvB,IAAI,UAAU,GAAG,KAAK,CAAC;IACvB,IAAI,MAAiC,CAAC;IAEtC,MAAM,MAAM,GAAG,CAAC,IAAY,EAAiB,EAAE;QAC3C,MAAM,IAAI,GAAG,QAAS,CAAC;QACvB,MAAM,OAAO,GAAG,QAAS,CAAC;QAC1B,QAAQ,GAAG,SAAS,CAAC;QACrB,QAAQ,GAAG,SAAS,CAAC;QACrB,UAAU,GAAG,IAAI,CAAC;QAClB,cAAc,GAAG,IAAI,CAAC;QACtB,MAAM,GAAG,EAAE,CAAC,KAAK,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;QACjC,OAAO,MAAuB,CAAC;IACnC,CAAC,CAAC;IAEF,MAAM,MAAM,GAAG,GAAS,EAAE;QACtB,KAAK,GAAG,SAAS,CAAC;QAClB,IAAI,QAAQ,IAAI,QAAQ,EAAE,CAAC;YACvB,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;QACvB,CAAC;aAAM,CAAC;YACJ,QAAQ,GAAG,SAAS,CAAC;YACrB,QAAQ,GAAG,SAAS,CAAC;QACzB,CAAC;IACL,CAAC,CAAC;IAEF,MAAM,SAAS,GAAG,UAAsC,GAAG,IAAmB;QAC1E,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACvB,QAAQ,GAAG,IAAI,CAAC;QAChB,QAAQ,GAAG,IAAI,CAAC;QAEhB,IAAI,CAAC,UAAU,EAAE,CAAC;YACd,IAAI,OAAO,EAAE,CAAC;gBACV,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC;YACvB,CAAC;YACD,UAAU,GAAG,IAAI,CAAC;YAClB,cAAc,GAAG,GAAG,CAAC;QACzB,CAAC;QAED,MAAM,SAAS,GAAG,KAAK,GAAG,CAAC,GAAG,GAAG,cAAc,CAAC,CAAC;QACjD,IAAI,SAAS,IAAI,CAAC,IAAI,SAAS,GAAG,KAAK,EAAE,CAAC;YACtC,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;gBACtB,YAAY,CAAC,KAAK,CAAC,CAAC;gBACpB,KAAK,GAAG,SAAS,CAAC;YACtB,CAAC;YACD,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC;QACvB,CAAC;QAED,IAAI,KAAK,KAAK,SAAS,IAAI,QAAQ,EAAE,CAAC;YAClC,KAAK,GAAG,UAAU,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;QAC1C,CAAC;QAED,OAAO,MAAM,CAAC;IAClB,CAAwB,CAAC;IAEzB,SAAS,CAAC,MAAM,GAAG,GAAS,EAAE;QAC1B,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YACtB,YAAY,CAAC,KAAK,CAAC,CAAC;QACxB,CAAC;QACD,KAAK,GAAG,SAAS,CAAC;QAClB,QAAQ,GAAG,SAAS,CAAC;QACrB,QAAQ,GAAG,SAAS,CAAC;QACrB,cAAc,GAAG,CAAC,CAAC;QACnB,UAAU,GAAG,KAAK,CAAC;IACvB,CAAC,CAAC;IAEF,SAAS,CAAC,KAAK,GAAG,GAA8B,EAAE;QAC9C,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YACtB,YAAY,CAAC,KAAK,CAAC,CAAC;YACpB,KAAK,GAAG,SAAS,CAAC;YAClB,IAAI,QAAQ,IAAI,QAAQ,EAAE,CAAC;gBACvB,OAAO,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;YAC9B,CAAC;QACL,CAAC;QACD,OAAO,MAAM,CAAC;IAClB,CAAC,CAAC;IAEF,SAAS,CAAC,OAAO,GAAG,GAAY,EAAE,CAAC,KAAK,KAAK,SAAS,CAAC;IAEvD,OAAO,SAAS,CAAC;AACrB,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,OAAO,CACnB,EAAK,EACL,GAAG,UAAqB;IAExB,OAAO,UAAsC,GAAG,SAAoB;QAChE,OAAO,EAAE,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,GAAG,UAAU,EAAE,GAAG,SAAS,CAAkB,CAAC,CAAC;IAC1E,CAAC,CAAC;AACN,CAAC;AAoBD,MAAM,UAAU,IAAI,CAAC,GAAG,GAAkB;IACtC,OAAO,UAAU,CAAC,GAAG,CAAC,CAAC;AAC3B,CAAC;AAoBD,MAAM,UAAU,OAAO,CAAC,GAAG,GAAkB;IACzC,OAAO,UAAU,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC,OAAO,EAAE,CAAC,CAAC;AAC7C,CAAC;AAED,SAAS,UAAU,CAAC,GAAkB;IAClC,IAAI,GAAG,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,QAAQ,CAAC;IAEtC,OAAO,UAAqB,GAAG,IAAW;QACtC,IAAI,MAAM,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;QACtC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YAClC,MAAM,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QACvC,CAAC;QACD,OAAO,MAAM,CAAC;IAClB,CAAC,CAAC;AACN,CAAC;AAED,SAAS,cAAc,CAAC,IAAY;IAChC,OAAO,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACzD,CAAC","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}"]}
package/dist/web/index.js CHANGED
@@ -5,6 +5,7 @@ export { default as Type } from './type.js';
5
5
  export { default as TypeCode } from './type-code.js';
6
6
  // ─── Utilities ───────────────────────────────────────
7
7
  export * from './utilities.js';
8
+ export * from './functions.js';
8
9
  export * from './string.js';
9
10
  export * from './math.js';
10
11
  export { default as CancellablePromise } from "./cancellable-promise.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,eAAe;AAEf,wDAAwD;AACxD,cAAc,YAAY,CAAC;AAC3B,OAAO,EAAC,OAAO,IAAI,IAAI,EAAC,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAC,OAAO,IAAI,QAAQ,EAAC,MAAM,gBAAgB,CAAC;AAEnD,wDAAwD;AACxD,cAAc,gBAAgB,CAAC;AAC/B,cAAc,aAAa,CAAC;AAC5B,cAAc,WAAW,CAAC;AAC1B,OAAO,EAAC,OAAO,IAAI,kBAAkB,EAAC,MAAM,0BAA0B,CAAC;AAEvE,uDAAuD;AACvD,OAAO,EAAC,OAAO,IAAI,YAAY,EAAC,MAAM,qBAAqB,CAAC;AAC5D,OAAO,EAAC,OAAO,IAAI,KAAK,EAAC,MAAM,YAAY,CAAC;AAE5C,uDAAuD;AACvD,OAAO,EAAC,OAAO,IAAI,KAAK,EAAC,MAAM,YAAY,CAAC;AAC5C,OAAO,EAAC,OAAO,IAAI,QAAQ,EAAC,MAAM,eAAe,CAAC;AAClD,OAAO,EAAC,OAAO,IAAI,SAAS,EAAC,MAAM,gBAAgB,CAAC;AACpD,OAAO,EAAC,OAAO,IAAI,iBAAiB,EAAC,MAAM,0BAA0B,CAAC;AAEtE,wDAAwD;AACxD,OAAO,EAAC,OAAO,IAAI,IAAI,EAAC,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAC,OAAO,IAAI,IAAI,EAAC,MAAM,uBAAuB,CAAC;AACtD,OAAO,EAAC,QAAQ,EAAE,KAAK,EAAC,MAAM,gBAAgB,CAAC;AAC/C,OAAO,EAAC,OAAO,IAAI,KAAK,EAAC,MAAM,YAAY,CAAC;AAE5C,qDAAqD;AACrD,OAAO,EAAC,OAAO,IAAI,KAAK,EAAC,MAAM,YAAY,CAAC;AAE5C,wDAAwD;AACxD,OAAO,EAAC,OAAO,IAAI,oBAAoB,EAAC,MAAM,8BAA8B,CAAC;AAC7E,mBAAmB;AACnB,OAAO,EAAC,UAAU,EAAE,cAAc,EAAE,UAAU,EAAE,YAAY,EAAC,MAAM,oBAAoB,CAAC;AAIxF,wDAAwD;AACxD,mBAAmB;AACnB,cAAc,YAAY,CAAC;AAC3B,mBAAmB;AACnB,cAAc,wBAAwB,CAAC","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 './string.js';\nexport * from './math.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 {default as AsyncPoolExecutor} from './async-pool-executor.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';"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,eAAe;AAEf,wDAAwD;AACxD,cAAc,YAAY,CAAC;AAC3B,OAAO,EAAC,OAAO,IAAI,IAAI,EAAC,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAC,OAAO,IAAI,QAAQ,EAAC,MAAM,gBAAgB,CAAC;AAEnD,wDAAwD;AACxD,cAAc,gBAAgB,CAAC;AAC/B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,aAAa,CAAC;AAC5B,cAAc,WAAW,CAAC;AAC1B,OAAO,EAAC,OAAO,IAAI,kBAAkB,EAAC,MAAM,0BAA0B,CAAC;AAEvE,uDAAuD;AACvD,OAAO,EAAC,OAAO,IAAI,YAAY,EAAC,MAAM,qBAAqB,CAAC;AAC5D,OAAO,EAAC,OAAO,IAAI,KAAK,EAAC,MAAM,YAAY,CAAC;AAE5C,uDAAuD;AACvD,OAAO,EAAC,OAAO,IAAI,KAAK,EAAC,MAAM,YAAY,CAAC;AAC5C,OAAO,EAAC,OAAO,IAAI,QAAQ,EAAC,MAAM,eAAe,CAAC;AAClD,OAAO,EAAC,OAAO,IAAI,SAAS,EAAC,MAAM,gBAAgB,CAAC;AACpD,OAAO,EAAC,OAAO,IAAI,iBAAiB,EAAC,MAAM,0BAA0B,CAAC;AAEtE,wDAAwD;AACxD,OAAO,EAAC,OAAO,IAAI,IAAI,EAAC,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAC,OAAO,IAAI,IAAI,EAAC,MAAM,uBAAuB,CAAC;AACtD,OAAO,EAAC,QAAQ,EAAE,KAAK,EAAC,MAAM,gBAAgB,CAAC;AAC/C,OAAO,EAAC,OAAO,IAAI,KAAK,EAAC,MAAM,YAAY,CAAC;AAE5C,qDAAqD;AACrD,OAAO,EAAC,OAAO,IAAI,KAAK,EAAC,MAAM,YAAY,CAAC;AAE5C,wDAAwD;AACxD,OAAO,EAAC,OAAO,IAAI,oBAAoB,EAAC,MAAM,8BAA8B,CAAC;AAC7E,mBAAmB;AACnB,OAAO,EAAC,UAAU,EAAE,cAAc,EAAE,UAAU,EAAE,YAAY,EAAC,MAAM,oBAAoB,CAAC;AAIxF,wDAAwD;AACxD,mBAAmB;AACnB,cAAc,YAAY,CAAC;AAC3B,mBAAmB;AACnB,cAAc,wBAAwB,CAAC","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 {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 {default as AsyncPoolExecutor} from './async-pool-executor.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';"]}
@@ -1 +1 @@
1
- {"version":3,"file":"key-value-pair.js","sourceRoot":"","sources":["../../src/key-value-pair.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,MAAM,CAAC,OAAO,OAAO,YAAY;IAC7B,IAAI,KAAK;QACL,OAAO,IAAI,CAAC,MAAM,CAAC;IACvB,CAAC;IAED,IAAI,GAAG;QACH,OAAO,IAAI,CAAC,IAAI,CAAC;IACrB,CAAC;IAKD,YAAY,GAAS,EAAE,KAAa;QAChC,IAAI,CAAC,IAAI,GAAG,GAAG,CAAC;QAChB,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC;IACxB,CAAC;CAGJ","sourcesContent":["/**\r\n * Represents a pair of key and value.\r\n *\r\n * @template TKey The type of the key.\r\n * @template TValue The type of the value.\r\n */\r\nexport default class KeyValuePair<TKey, TValue> {\r\n get value(): TValue {\r\n return this._value;\r\n }\r\n\r\n get key(): TKey {\r\n return this._key;\r\n }\r\n\r\n private readonly _key: TKey;\r\n private readonly _value: TValue;\r\n\r\n constructor(key: TKey, value: TValue) {\r\n this._key = key;\r\n this._value = value;\r\n }\r\n\r\n\r\n}"]}
1
+ {"version":3,"file":"key-value-pair.js","sourceRoot":"","sources":["../../src/key-value-pair.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,MAAM,CAAC,OAAO,OAAO,YAAY;IAC7B,IAAI,KAAK;QACL,OAAO,IAAI,CAAC,MAAM,CAAC;IACvB,CAAC;IAED,IAAI,GAAG;QACH,OAAO,IAAI,CAAC,IAAI,CAAC;IACrB,CAAC;IAKD,YAAY,GAAS,EAAE,KAAa;QAChC,IAAI,CAAC,IAAI,GAAG,GAAG,CAAC;QAChB,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC;IACxB,CAAC;CAGJ","sourcesContent":["/**\n * Represents a pair of key and value.\n *\n * @template TKey The type of the key.\n * @template TValue The type of the value.\n */\nexport default class KeyValuePair<TKey, TValue> {\n get value(): TValue {\n return this._value;\n }\n\n get key(): TKey {\n return this._key;\n }\n\n private readonly _key: TKey;\n private readonly _value: TValue;\n\n constructor(key: TKey, value: TValue) {\n this._key = key;\n this._value = value;\n }\n\n\n}"]}
@@ -1 +1 @@
1
- {"version":3,"file":"lazy.js","sourceRoot":"","sources":["../../src/lazy.ts"],"names":[],"mappings":"AAGA;;;GAGG;AACH,MAAM,CAAC,OAAO,OAAO,IAAI;IAKrB,YAAY,MAAmB;QAJvB,kBAAa,GAAG,KAAK,CAAC;QACtB,WAAM,GAAgB,IAAI,CAAC;QAI/B,IAAI,CAAC,cAAc,GAAG,MAAM,CAAC;IACjC,CAAC;IAED,IAAI,YAAY;QACZ,OAAO,IAAI,CAAC,aAAa,CAAC;IAC9B,CAAC;IAED,IAAW,KAAK;QACZ,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,CAAC;YACtB,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,cAAc,EAAE,CAAC;YACpC,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC;QAC9B,CAAC;QACD,OAAO,IAAI,CAAC,MAAW,CAAC;IAC5B,CAAC;IAED,KAAK;QACD,IAAI,CAAC,aAAa,GAAG,KAAK,CAAC;QAC3B,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;IACvB,CAAC;CACJ","sourcesContent":["import type {Nullable, Supplier} from \"./types.js\";\r\n\r\n\r\n/**\r\n * Represents a lazy value that is created only when it is accessed for the first time.\r\n * @template T The type of the lazy value.\r\n */\r\nexport default class Lazy<T> {\r\n private _valueCreated = false;\r\n private _value: Nullable<T> = null;\r\n private readonly _factoryMethod: Supplier<T>;\r\n\r\n constructor(getter: Supplier<T>) {\r\n this._factoryMethod = getter;\r\n }\r\n\r\n get valueCreated(): boolean {\r\n return this._valueCreated;\r\n }\r\n\r\n public get value(): T {\r\n if (!this._valueCreated) {\r\n this._value = this._factoryMethod();\r\n this._valueCreated = true;\r\n }\r\n return this._value as T;\r\n }\r\n\r\n reset(): void {\r\n this._valueCreated = false;\r\n this._value = null;\r\n }\r\n}"]}
1
+ {"version":3,"file":"lazy.js","sourceRoot":"","sources":["../../src/lazy.ts"],"names":[],"mappings":"AAGA;;;GAGG;AACH,MAAM,CAAC,OAAO,OAAO,IAAI;IAKrB,YAAY,MAAmB;QAJvB,kBAAa,GAAG,KAAK,CAAC;QACtB,WAAM,GAAgB,IAAI,CAAC;QAI/B,IAAI,CAAC,cAAc,GAAG,MAAM,CAAC;IACjC,CAAC;IAED,IAAI,YAAY;QACZ,OAAO,IAAI,CAAC,aAAa,CAAC;IAC9B,CAAC;IAED,IAAW,KAAK;QACZ,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,CAAC;YACtB,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,cAAc,EAAE,CAAC;YACpC,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC;QAC9B,CAAC;QACD,OAAO,IAAI,CAAC,MAAW,CAAC;IAC5B,CAAC;IAED,KAAK;QACD,IAAI,CAAC,aAAa,GAAG,KAAK,CAAC;QAC3B,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;IACvB,CAAC;CACJ","sourcesContent":["import type {Nullable, Supplier} from \"./types.js\";\n\n\n/**\n * Represents a lazy value that is created only when it is accessed for the first time.\n * @template T The type of the lazy value.\n */\nexport default class Lazy<T> {\n private _valueCreated = false;\n private _value: Nullable<T> = null;\n private readonly _factoryMethod: Supplier<T>;\n\n constructor(getter: Supplier<T>) {\n this._factoryMethod = getter;\n }\n\n get valueCreated(): boolean {\n return this._valueCreated;\n }\n\n public get value(): T {\n if (!this._valueCreated) {\n this._value = this._factoryMethod();\n this._valueCreated = true;\n }\n return this._value as T;\n }\n\n reset(): void {\n this._valueCreated = false;\n this._value = null;\n }\n}"]}
package/dist/web/math.js CHANGED
@@ -10,6 +10,9 @@
10
10
  * @return {number} - The interpolated value.
11
11
  */
12
12
  export function lerp(n, inMin, inMax, outMin, outMax) {
13
+ if (inMax === inMin) {
14
+ throw new Error("Input range cannot be zero");
15
+ }
13
16
  return outMin + (outMax - outMin) * ((n - inMin) / (inMax - inMin));
14
17
  }
15
18
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"math.js","sourceRoot":"","sources":["../../src/math.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,MAAM,UAAU,IAAI,CAAC,CAAS,EAAE,KAAa,EAAE,KAAa,EAAE,MAAc,EAAE,MAAc;IACxF,OAAO,MAAM,GAAG,CAAC,MAAM,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,GAAG,CAAC,KAAK,GAAG,KAAK,CAAC,CAAC,CAAA;AACvE,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,KAAK,CAAC,CAAS,EAAE,GAAW,EAAE,GAAW;IACrD,IAAI,CAAC,IAAI,GAAG;QACR,OAAO,GAAG,CAAC;IACf,IAAI,CAAC,IAAI,GAAG;QACR,OAAO,GAAG,CAAC;IACf,OAAO,CAAC,CAAA;AACZ,CAAC","sourcesContent":["/**\r\n * Linearly interpolates a number between two ranges.\r\n *\r\n * @param {number} n - The number to interpolate.\r\n * @param {number} inMin - The minimum value of the input range.\r\n * @param {number} inMax - The maximum value of the input range.\r\n * @param {number} outMin - The minimum value of the output range.\r\n * @param {number} outMax - The maximum value of the output range.\r\n *\r\n * @return {number} - The interpolated value.\r\n */\r\nexport function lerp(n: number, inMin: number, inMax: number, outMin: number, outMax: number): number {\r\n return outMin + (outMax - outMin) * ((n - inMin) / (inMax - inMin))\r\n}\r\n\r\n/**\r\n * Clamps a number between a minimum and maximum value.\r\n *\r\n * @param {number} n - The value to be clamped.\r\n * @param {number} min - The minimum value.\r\n * @param {number} max - The maximum value.\r\n * @return {number} The clamped value.\r\n */\r\nexport function clamp(n: number, min: number, max: number): number {\r\n if (n <= min)\r\n return min;\r\n if (n >= max)\r\n return max;\r\n return n\r\n}\r\n"]}
1
+ {"version":3,"file":"math.js","sourceRoot":"","sources":["../../src/math.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,MAAM,UAAU,IAAI,CAAC,CAAS,EAAE,KAAa,EAAE,KAAa,EAAE,MAAc,EAAE,MAAc;IACxF,IAAI,KAAK,KAAK,KAAK,EAAE,CAAC;QAClB,MAAM,IAAI,KAAK,CAAC,4BAA4B,CAAC,CAAC;IAClD,CAAC;IACD,OAAO,MAAM,GAAG,CAAC,MAAM,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,GAAG,CAAC,KAAK,GAAG,KAAK,CAAC,CAAC,CAAA;AACvE,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,KAAK,CAAC,CAAS,EAAE,GAAW,EAAE,GAAW;IACrD,IAAI,CAAC,IAAI,GAAG;QACR,OAAO,GAAG,CAAC;IACf,IAAI,CAAC,IAAI,GAAG;QACR,OAAO,GAAG,CAAC;IACf,OAAO,CAAC,CAAA;AACZ,CAAC","sourcesContent":["/**\n * Linearly interpolates a number between two ranges.\n *\n * @param {number} n - The number to interpolate.\n * @param {number} inMin - The minimum value of the input range.\n * @param {number} inMax - The maximum value of the input range.\n * @param {number} outMin - The minimum value of the output range.\n * @param {number} outMax - The maximum value of the output range.\n *\n * @return {number} - The interpolated value.\n */\nexport function lerp(n: number, inMin: number, inMax: number, outMin: number, outMax: number): number {\n if (inMax === inMin) {\n throw new Error(\"Input range cannot be zero\");\n }\n return outMin + (outMax - outMin) * ((n - inMin) / (inMax - inMin))\n}\n\n/**\n * Clamps a number between a minimum and maximum value.\n *\n * @param {number} n - The value to be clamped.\n * @param {number} min - The minimum value.\n * @param {number} max - The maximum value.\n * @return {number} The clamped value.\n */\nexport function clamp(n: number, min: number, max: number): number {\n if (n <= min)\n return min;\n if (n >= max)\n return max;\n return n\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"order.js","sourceRoot":"","sources":["../../src/order.ts"],"names":[],"mappings":"AAAA,IAAK,KAGJ;AAHD,WAAK,KAAK;IACN,0BAAiB,CAAA;IACjB,4BAAmB,CAAA;AACvB,CAAC,EAHI,KAAK,KAAL,KAAK,QAGT;AAED,eAAe,KAAK,CAAC","sourcesContent":["enum Order {\r\n Ascending = \"asc\",\r\n Descending = \"desc\"\r\n}\r\n\r\nexport default Order;"]}
1
+ {"version":3,"file":"order.js","sourceRoot":"","sources":["../../src/order.ts"],"names":[],"mappings":"AAAA,IAAK,KAGJ;AAHD,WAAK,KAAK;IACN,0BAAiB,CAAA;IACjB,4BAAmB,CAAA;AACvB,CAAC,EAHI,KAAK,KAAL,KAAK,QAGT;AAED,eAAe,KAAK,CAAC","sourcesContent":["enum Order {\n Ascending = \"asc\",\n Descending = \"desc\"\n}\n\nexport default Order;"]}
package/dist/web/parse.js CHANGED
@@ -6,6 +6,15 @@ function stripThousands(value, separator) {
6
6
  return value;
7
7
  return value.split(separator).join("");
8
8
  }
9
+ function isValidInteger(value, radix) {
10
+ if (!Number.isInteger(radix) || radix < 2 || radix > 36)
11
+ return false;
12
+ const signless = value.replace(/^[+-]/, "");
13
+ if (signless === "")
14
+ return false;
15
+ const digits = "0123456789abcdefghijklmnopqrstuvwxyz".slice(0, radix);
16
+ return [...signless.toLowerCase()].every((char) => digits.includes(char));
17
+ }
9
18
  // ============================================
10
19
  // parseInteger
11
20
  // ============================================
@@ -43,7 +52,7 @@ export function parseInteger(value, options = {}) {
43
52
  const cleaned = stripThousands(value.trim(), thousandsSeparator);
44
53
  if (cleaned === "")
45
54
  return null;
46
- if (radix === 10 && !/^[+-]?\d+$/.test(cleaned))
55
+ if (!isValidInteger(cleaned, radix))
47
56
  return null;
48
57
  const parsed = Number.parseInt(cleaned, radix);
49
58
  return Number.isNaN(parsed) ? null : parsed;
@@ -1 +1 @@
1
- {"version":3,"file":"parse.js","sourceRoot":"","sources":["../../src/parse.ts"],"names":[],"mappings":"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","sourcesContent":["// parse.ts\r\n/**\r\n * Options for {@link parseBoolean}.\r\n */\r\nexport interface ParseBooleanOptions {\r\n /**\r\n * Additional strings to consider as `true`.\r\n * These are matched case-insensitively.\r\n * @example [\"oui\", \"ja\"]\r\n */\r\n extraTruthy?: string[];\r\n\r\n /**\r\n * Additional strings to consider as `false`.\r\n * These are matched case-insensitively.\r\n * @example [\"non\", \"nein\"]\r\n */\r\n extraFalsy?: string[];\r\n}\r\n\r\n/**\r\n * Options for {@link parseInteger}.\r\n */\r\nexport interface ParseIntegerOptions {\r\n /**\r\n * Numeric base for conversion.\r\n * @default 10\r\n */\r\n radix?: number;\r\n\r\n /**\r\n * Thousands separator to strip before parsing.\r\n * @example \".\" for \"1.234.567\" → 1234567\r\n * @example \",\" for \"1,234,567\" → 1234567\r\n */\r\n thousandsSeparator?: string;\r\n}\r\n\r\n/**\r\n * Options for {@link parseDecimal}.\r\n */\r\nexport interface ParseDecimalOptions {\r\n /**\r\n * Character used as decimal point.\r\n * @default \".\"\r\n */\r\n decimalSeparator?: \".\" | \",\";\r\n\r\n /**\r\n * Thousands separator to strip before parsing.\r\n * @example \".\" for \"1.234,56\" (EU format)\r\n * @example \",\" for \"1,234.56\" (US format)\r\n */\r\n thousandsSeparator?: string;\r\n}\r\n\r\n// ============================================\r\n// HELPERS\r\n// ============================================\r\n\r\nfunction stripThousands(value: string, separator?: string): string {\r\n if (!separator) return value;\r\n return value.split(separator).join(\"\");\r\n}\r\n\r\n// ============================================\r\n// parseInteger\r\n// ============================================\r\n\r\n/**\r\n * Safely parses a value into an integer.\r\n * Returns `null` if the value cannot be parsed.\r\n *\r\n * - `null` or `undefined` → `null`\r\n * - `number` → returned as-is (floats are truncated)\r\n * - `string` → parsed with the given options\r\n *\r\n * @param value - The value to parse.\r\n * @param options - Optional parsing configuration.\r\n * @returns The parsed integer, or `null` on failure.\r\n *\r\n * @example\r\n * ```ts\r\n * parseInteger(42) // 42\r\n * parseInteger(3.7) // 3\r\n * parseInteger(null) // null\r\n * parseInteger(undefined) // null\r\n * parseInteger(\"42\") // 42\r\n * parseInteger(\"1.234.567\", { thousandsSeparator: \".\" }) // 1234567\r\n * parseInteger(\"FF\", { radix: 16 }) // 255\r\n * parseInteger(\"abc\") // null\r\n * ```\r\n */\r\nexport function parseInteger(\r\n value: string | number | null | undefined,\r\n options: ParseIntegerOptions = {}\r\n): number | null {\r\n if (value === null || value === undefined) return null;\r\n\r\n if (typeof value === \"number\") {\r\n return Number.isFinite(value) ? Math.trunc(value) : null;\r\n }\r\n\r\n const { radix = 10, thousandsSeparator } = options;\r\n\r\n const cleaned = stripThousands(value.trim(), thousandsSeparator);\r\n\r\n if (cleaned === \"\") return null;\r\n if (radix === 10 && !/^[+-]?\\d+$/.test(cleaned)) return null;\r\n\r\n const parsed = Number.parseInt(cleaned, radix);\r\n\r\n return Number.isNaN(parsed) ? null : parsed;\r\n}\r\n\r\n// ============================================\r\n// parseDecimal\r\n// ============================================\r\n\r\n/**\r\n * Safely parses a value into a floating-point number.\r\n * Returns `null` if the value cannot be parsed.\r\n *\r\n * - `null` or `undefined` → `null`\r\n * - `number` → returned as-is (if finite)\r\n * - `string` → parsed with the given options\r\n *\r\n * Supports custom decimal and thousands separators, making it suitable\r\n * for both US (`1,234.56`) and EU (`1.234,56`) number formats.\r\n *\r\n * @param value - The value to parse.\r\n * @param options - Optional parsing configuration.\r\n * @returns The parsed float, or `null` on failure.\r\n *\r\n * @example\r\n * ```ts\r\n * parseDecimal(3.14) // 3.14\r\n * parseDecimal(null) // null\r\n * parseDecimal(undefined) // null\r\n * parseDecimal(\"3.14\") // 3.14\r\n * parseDecimal(\"3,14\", { decimalSeparator: \",\" }) // 3.14\r\n * parseDecimal(\"1.234,56\", { decimalSeparator: \",\", thousandsSeparator: \".\" }) // 1234.56\r\n * parseDecimal(\"abc\") // null\r\n * ```\r\n */\r\nexport function parseDecimal(\r\n value: string | number | null | undefined,\r\n options: ParseDecimalOptions = {}\r\n): number | null {\r\n if (value === null || value === undefined) return null;\r\n\r\n if (typeof value === \"number\") {\r\n return Number.isFinite(value) ? value : null;\r\n }\r\n\r\n const { decimalSeparator = \".\", thousandsSeparator } = options;\r\n\r\n let cleaned = stripThousands(value.trim(), thousandsSeparator);\r\n\r\n if (cleaned === \"\") return null;\r\n\r\n if (decimalSeparator === \",\") {\r\n const commaCount = (cleaned.match(/,/g) || []).length;\r\n if (commaCount > 1) return null;\r\n cleaned = cleaned.replace(\",\", \".\");\r\n }\r\n\r\n if (!/^[+-]?\\d+(\\.\\d+)?$/.test(cleaned)) return null;\r\n\r\n const parsed = Number.parseFloat(cleaned);\r\n\r\n return Number.isNaN(parsed) || !Number.isFinite(parsed) ? null : parsed;\r\n}\r\n\r\n// ============================================\r\n// parseBoolean\r\n// ============================================\r\n\r\nconst DEFAULT_TRUTHY = [\"true\", \"1\", \"yes\", \"si\", \"sí\", \"on\"];\r\nconst DEFAULT_FALSY = [\"false\", \"0\", \"no\", \"off\"];\r\n\r\n/**\r\n * Safely parses a value into a boolean.\r\n * Returns `null` if the value cannot be interpreted as boolean.\r\n *\r\n * - `null` or `undefined` → `null`\r\n * - `boolean` → returned as-is\r\n * - `number` → `0` is `false`, any other finite number is `true`\r\n * - `string` → matched case-insensitively against known truthy/falsy values\r\n *\r\n * Default truthy: `\"true\"`, `\"1\"`, `\"yes\"`, `\"si\"`, `\"sí\"`, `\"on\"`\r\n * Default falsy: `\"false\"`, `\"0\"`, `\"no\"`, `\"off\"`\r\n *\r\n * @param value - The value to parse.\r\n * @param options - Optional parsing configuration.\r\n * @returns The parsed boolean, or `null` on failure.\r\n *\r\n * @example\r\n * ```ts\r\n * parseBoolean(true) // true\r\n * parseBoolean(false) // false\r\n * parseBoolean(1) // true\r\n * parseBoolean(0) // false\r\n * parseBoolean(null) // null\r\n * parseBoolean(undefined) // null\r\n * parseBoolean(\"yes\") // true\r\n * parseBoolean(\"no\") // false\r\n * parseBoolean(\"sí\") // true\r\n * parseBoolean(\"TRUE\") // true\r\n * parseBoolean(\"oui\") // null\r\n * parseBoolean(\"oui\", { extraTruthy: [\"oui\"] }) // true\r\n * parseBoolean(\"nein\", { extraFalsy: [\"nein\"] }) // false\r\n * parseBoolean(\"whatever\") // null\r\n * ```\r\n */\r\nexport function parseBoolean(\r\n value: string | number | boolean | null | undefined,\r\n options: ParseBooleanOptions = {}\r\n): boolean | null {\r\n if (value === null || value === undefined) return null;\r\n\r\n if (typeof value === \"boolean\") return value;\r\n\r\n if (typeof value === \"number\") {\r\n return Number.isFinite(value) ? value !== 0 : null;\r\n }\r\n\r\n const { extraTruthy = [], extraFalsy = [] } = options;\r\n\r\n const normalized = value.trim().toLowerCase();\r\n\r\n if (normalized === \"\") return null;\r\n\r\n const truthy = [...DEFAULT_TRUTHY, ...extraTruthy.map((s) => s.toLowerCase())];\r\n const falsy = [...DEFAULT_FALSY, ...extraFalsy.map((s) => s.toLowerCase())];\r\n\r\n if (truthy.includes(normalized)) return true;\r\n if (falsy.includes(normalized)) return false;\r\n\r\n return null;\r\n}"]}
1
+ {"version":3,"file":"parse.js","sourceRoot":"","sources":["../../src/parse.ts"],"names":[],"mappings":"AAwDA,+CAA+C;AAC/C,UAAU;AACV,+CAA+C;AAE/C,SAAS,cAAc,CAAC,KAAa,EAAE,SAAkB;IACrD,IAAI,CAAC,SAAS;QAAE,OAAO,KAAK,CAAC;IAC7B,OAAO,KAAK,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;AAC3C,CAAC;AAED,SAAS,cAAc,CAAC,KAAa,EAAE,KAAa;IAChD,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,KAAK,GAAG,CAAC,IAAI,KAAK,GAAG,EAAE;QAAE,OAAO,KAAK,CAAC;IAEtE,MAAM,QAAQ,GAAG,KAAK,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;IAC5C,IAAI,QAAQ,KAAK,EAAE;QAAE,OAAO,KAAK,CAAC;IAElC,MAAM,MAAM,GAAG,sCAAsC,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;IAEtE,OAAO,CAAC,GAAG,QAAQ,CAAC,WAAW,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC;AAC9E,CAAC;AAED,+CAA+C;AAC/C,eAAe;AACf,+CAA+C;AAE/C;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,MAAM,UAAU,YAAY,CACxB,KAAyC,EACzC,UAA+B,EAAE;IAEjC,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,IAAI,CAAC;IAEvD,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC5B,OAAO,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IAC7D,CAAC;IAED,MAAM,EAAE,KAAK,GAAG,EAAE,EAAE,kBAAkB,EAAE,GAAG,OAAO,CAAC;IAEnD,MAAM,OAAO,GAAG,cAAc,CAAC,KAAK,CAAC,IAAI,EAAE,EAAE,kBAAkB,CAAC,CAAC;IAEjE,IAAI,OAAO,KAAK,EAAE;QAAE,OAAO,IAAI,CAAC;IAChC,IAAI,CAAC,cAAc,CAAC,OAAO,EAAE,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IAEjD,MAAM,MAAM,GAAG,MAAM,CAAC,QAAQ,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;IAE/C,OAAO,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC;AAChD,CAAC;AAED,+CAA+C;AAC/C,eAAe;AACf,+CAA+C;AAE/C;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,MAAM,UAAU,YAAY,CACxB,KAAyC,EACzC,UAA+B,EAAE;IAEjC,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,IAAI,CAAC;IAEvD,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC5B,OAAO,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC;IACjD,CAAC;IAED,MAAM,EAAE,gBAAgB,GAAG,GAAG,EAAE,kBAAkB,EAAE,GAAG,OAAO,CAAC;IAE/D,IAAI,OAAO,GAAG,cAAc,CAAC,KAAK,CAAC,IAAI,EAAE,EAAE,kBAAkB,CAAC,CAAC;IAE/D,IAAI,OAAO,KAAK,EAAE;QAAE,OAAO,IAAI,CAAC;IAEhC,IAAI,gBAAgB,KAAK,GAAG,EAAE,CAAC;QAC3B,MAAM,UAAU,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC;QACtD,IAAI,UAAU,GAAG,CAAC;YAAE,OAAO,IAAI,CAAC;QAChC,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;IACxC,CAAC;IAED,IAAI,CAAC,oBAAoB,CAAC,IAAI,CAAC,OAAO,CAAC;QAAE,OAAO,IAAI,CAAC;IAErD,MAAM,MAAM,GAAG,MAAM,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;IAE1C,OAAO,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC;AAC5E,CAAC;AAED,+CAA+C;AAC/C,eAAe;AACf,+CAA+C;AAE/C,MAAM,cAAc,GAAG,CAAC,MAAM,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;AAC9D,MAAM,aAAa,GAAG,CAAC,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC;AAElD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,MAAM,UAAU,YAAY,CACxB,KAAmD,EACnD,UAA+B,EAAE;IAEjC,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,IAAI,CAAC;IAEvD,IAAI,OAAO,KAAK,KAAK,SAAS;QAAE,OAAO,KAAK,CAAC;IAE7C,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC5B,OAAO,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IACvD,CAAC;IAED,MAAM,EAAE,WAAW,GAAG,EAAE,EAAE,UAAU,GAAG,EAAE,EAAE,GAAG,OAAO,CAAC;IAEtD,MAAM,UAAU,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IAE9C,IAAI,UAAU,KAAK,EAAE;QAAE,OAAO,IAAI,CAAC;IAEnC,MAAM,MAAM,GAAG,CAAC,GAAG,cAAc,EAAE,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC;IAC/E,MAAM,KAAK,GAAG,CAAC,GAAG,aAAa,EAAE,GAAG,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC;IAE5E,IAAI,MAAM,CAAC,QAAQ,CAAC,UAAU,CAAC;QAAE,OAAO,IAAI,CAAC;IAC7C,IAAI,KAAK,CAAC,QAAQ,CAAC,UAAU,CAAC;QAAE,OAAO,KAAK,CAAC;IAE7C,OAAO,IAAI,CAAC;AAChB,CAAC","sourcesContent":["// parse.ts\n/**\n * Options for {@link parseBoolean}.\n */\nexport interface ParseBooleanOptions {\n /**\n * Additional strings to consider as `true`.\n * These are matched case-insensitively.\n * @example [\"oui\", \"ja\"]\n */\n extraTruthy?: string[];\n\n /**\n * Additional strings to consider as `false`.\n * These are matched case-insensitively.\n * @example [\"non\", \"nein\"]\n */\n extraFalsy?: string[];\n}\n\n/**\n * Options for {@link parseInteger}.\n */\nexport interface ParseIntegerOptions {\n /**\n * Numeric base for conversion.\n * @default 10\n */\n radix?: number;\n\n /**\n * Thousands separator to strip before parsing.\n * @example \".\" for \"1.234.567\" → 1234567\n * @example \",\" for \"1,234,567\" → 1234567\n */\n thousandsSeparator?: string;\n}\n\n/**\n * Options for {@link parseDecimal}.\n */\nexport interface ParseDecimalOptions {\n /**\n * Character used as decimal point.\n * @default \".\"\n */\n decimalSeparator?: \".\" | \",\";\n\n /**\n * Thousands separator to strip before parsing.\n * @example \".\" for \"1.234,56\" (EU format)\n * @example \",\" for \"1,234.56\" (US format)\n */\n thousandsSeparator?: string;\n}\n\n// ============================================\n// HELPERS\n// ============================================\n\nfunction stripThousands(value: string, separator?: string): string {\n if (!separator) return value;\n return value.split(separator).join(\"\");\n}\n\nfunction isValidInteger(value: string, radix: number): boolean {\n if (!Number.isInteger(radix) || radix < 2 || radix > 36) return false;\n\n const signless = value.replace(/^[+-]/, \"\");\n if (signless === \"\") return false;\n\n const digits = \"0123456789abcdefghijklmnopqrstuvwxyz\".slice(0, radix);\n\n return [...signless.toLowerCase()].every((char) => digits.includes(char));\n}\n\n// ============================================\n// parseInteger\n// ============================================\n\n/**\n * Safely parses a value into an integer.\n * Returns `null` if the value cannot be parsed.\n *\n * - `null` or `undefined` → `null`\n * - `number` → returned as-is (floats are truncated)\n * - `string` → parsed with the given options\n *\n * @param value - The value to parse.\n * @param options - Optional parsing configuration.\n * @returns The parsed integer, or `null` on failure.\n *\n * @example\n * ```ts\n * parseInteger(42) // 42\n * parseInteger(3.7) // 3\n * parseInteger(null) // null\n * parseInteger(undefined) // null\n * parseInteger(\"42\") // 42\n * parseInteger(\"1.234.567\", { thousandsSeparator: \".\" }) // 1234567\n * parseInteger(\"FF\", { radix: 16 }) // 255\n * parseInteger(\"abc\") // null\n * ```\n */\nexport function parseInteger(\n value: string | number | null | undefined,\n options: ParseIntegerOptions = {}\n): number | null {\n if (value === null || value === undefined) return null;\n\n if (typeof value === \"number\") {\n return Number.isFinite(value) ? Math.trunc(value) : null;\n }\n\n const { radix = 10, thousandsSeparator } = options;\n\n const cleaned = stripThousands(value.trim(), thousandsSeparator);\n\n if (cleaned === \"\") return null;\n if (!isValidInteger(cleaned, radix)) return null;\n\n const parsed = Number.parseInt(cleaned, radix);\n\n return Number.isNaN(parsed) ? null : parsed;\n}\n\n// ============================================\n// parseDecimal\n// ============================================\n\n/**\n * Safely parses a value into a floating-point number.\n * Returns `null` if the value cannot be parsed.\n *\n * - `null` or `undefined` → `null`\n * - `number` → returned as-is (if finite)\n * - `string` → parsed with the given options\n *\n * Supports custom decimal and thousands separators, making it suitable\n * for both US (`1,234.56`) and EU (`1.234,56`) number formats.\n *\n * @param value - The value to parse.\n * @param options - Optional parsing configuration.\n * @returns The parsed float, or `null` on failure.\n *\n * @example\n * ```ts\n * parseDecimal(3.14) // 3.14\n * parseDecimal(null) // null\n * parseDecimal(undefined) // null\n * parseDecimal(\"3.14\") // 3.14\n * parseDecimal(\"3,14\", { decimalSeparator: \",\" }) // 3.14\n * parseDecimal(\"1.234,56\", { decimalSeparator: \",\", thousandsSeparator: \".\" }) // 1234.56\n * parseDecimal(\"abc\") // null\n * ```\n */\nexport function parseDecimal(\n value: string | number | null | undefined,\n options: ParseDecimalOptions = {}\n): number | null {\n if (value === null || value === undefined) return null;\n\n if (typeof value === \"number\") {\n return Number.isFinite(value) ? value : null;\n }\n\n const { decimalSeparator = \".\", thousandsSeparator } = options;\n\n let cleaned = stripThousands(value.trim(), thousandsSeparator);\n\n if (cleaned === \"\") return null;\n\n if (decimalSeparator === \",\") {\n const commaCount = (cleaned.match(/,/g) || []).length;\n if (commaCount > 1) return null;\n cleaned = cleaned.replace(\",\", \".\");\n }\n\n if (!/^[+-]?\\d+(\\.\\d+)?$/.test(cleaned)) return null;\n\n const parsed = Number.parseFloat(cleaned);\n\n return Number.isNaN(parsed) || !Number.isFinite(parsed) ? null : parsed;\n}\n\n// ============================================\n// parseBoolean\n// ============================================\n\nconst DEFAULT_TRUTHY = [\"true\", \"1\", \"yes\", \"si\", \"sí\", \"on\"];\nconst DEFAULT_FALSY = [\"false\", \"0\", \"no\", \"off\"];\n\n/**\n * Safely parses a value into a boolean.\n * Returns `null` if the value cannot be interpreted as boolean.\n *\n * - `null` or `undefined` → `null`\n * - `boolean` → returned as-is\n * - `number` → `0` is `false`, any other finite number is `true`\n * - `string` → matched case-insensitively against known truthy/falsy values\n *\n * Default truthy: `\"true\"`, `\"1\"`, `\"yes\"`, `\"si\"`, `\"sí\"`, `\"on\"`\n * Default falsy: `\"false\"`, `\"0\"`, `\"no\"`, `\"off\"`\n *\n * @param value - The value to parse.\n * @param options - Optional parsing configuration.\n * @returns The parsed boolean, or `null` on failure.\n *\n * @example\n * ```ts\n * parseBoolean(true) // true\n * parseBoolean(false) // false\n * parseBoolean(1) // true\n * parseBoolean(0) // false\n * parseBoolean(null) // null\n * parseBoolean(undefined) // null\n * parseBoolean(\"yes\") // true\n * parseBoolean(\"no\") // false\n * parseBoolean(\"sí\") // true\n * parseBoolean(\"TRUE\") // true\n * parseBoolean(\"oui\") // null\n * parseBoolean(\"oui\", { extraTruthy: [\"oui\"] }) // true\n * parseBoolean(\"nein\", { extraFalsy: [\"nein\"] }) // false\n * parseBoolean(\"whatever\") // null\n * ```\n */\nexport function parseBoolean(\n value: string | number | boolean | null | undefined,\n options: ParseBooleanOptions = {}\n): boolean | null {\n if (value === null || value === undefined) return null;\n\n if (typeof value === \"boolean\") return value;\n\n if (typeof value === \"number\") {\n return Number.isFinite(value) ? value !== 0 : null;\n }\n\n const { extraTruthy = [], extraFalsy = [] } = options;\n\n const normalized = value.trim().toLowerCase();\n\n if (normalized === \"\") return null;\n\n const truthy = [...DEFAULT_TRUTHY, ...extraTruthy.map((s) => s.toLowerCase())];\n const falsy = [...DEFAULT_FALSY, ...extraFalsy.map((s) => s.toLowerCase())];\n\n if (truthy.includes(normalized)) return true;\n if (falsy.includes(normalized)) return false;\n\n return null;\n}"]}
@@ -1 +1 @@
1
- {"version":3,"file":"patch.js","sourceRoot":"","sources":["../../src/patch.ts"],"names":[],"mappings":"AAoBA;;;;GAIG;AACH,MAAM,UAAU,KAAK,CACjB,YAAiB,EACjB,GAAmB;IAEnB,MAAM,MAAM,GAAG,OAAO,YAAY,KAAK,UAAU,CAAC,CAAC,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC,CAAC,YAAY,CAAC;IAE1F,MAAM,MAAM,GAAG,IAAI,GAAG,EAA0C,CAAC;IACjE,MAAM,OAAO,GACT,GAAG,YAAY,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,CAAQ,CAAC;IAEzE,KAAK,MAAM,CAAC,GAAG,EAAE,EAAE,CAAC,IAAI,OAAO,EAAE,CAAC;QAC9B,MAAM,IAAI,GAAG,MAAM,CAAC,wBAAwB,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;QAC1D,MAAM,MAAM,GAAG,UAAyB,GAAG,IAAe;YACtD,OAAQ,EAAU,CAAC,IAAI,EAAE,GAAG,IAAI,CAAC,CAAC;QACtC,CAAC,CAAC;QACF,IAAI,CAAC;YACD,MAAM,CAAC,cAAc,CAAC,MAAM,EAAE,GAAG,EAAE;gBAC/B,KAAK,EAAE,MAAM;gBACb,QAAQ,EAAE,IAAI;gBACd,YAAY,EAAE,IAAI;gBAClB,UAAU,EAAE,KAAK;aACpB,CAAC,CAAC;YACH,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,IAAI,IAAI,CAAC,CAAC;QAClC,CAAC;QAAC,MAAM,CAAC,CAAC,aAAa;QACvB,CAAC;IACL,CAAC;IACD,OAAO,MAAM,CAAC;AAClB,CAAC;AAYD;;GAEG;AACH,MAAM,UAAU,OAAO,CAAC,YAAiB,EAAE,OAAoD;IAC3F,MAAM,MAAM,GAAG,OAAO,YAAY,KAAK,UAAU,CAAC,CAAC,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC,CAAC,YAAY,CAAC;IAC1F,KAAK,MAAM,CAAC,GAAG,EAAE,IAAI,CAAC,IAAI,OAAO,EAAE,CAAC;QAChC,IAAI,CAAC;YACD,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC;gBAChB,IAAI,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,CAAC;oBAAE,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC;YAC9E,CAAC;iBAAM,CAAC;gBACJ,MAAM,CAAC,cAAc,CAAC,MAAM,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC;YAC7C,CAAC;QACL,CAAC;QAAC,MAAM,CAAC,CAAC,aAAa;QACvB,CAAC;IACL,CAAC;AACL,CAAC","sourcesContent":["import type {Constructor} from \"./types.js\";\r\n\r\nexport type PureMethod<T extends object, A extends any[] = any[], R = any> =\r\n (obj: T, ...args: A) => R;\r\n\r\nexport type PatchSpec<T extends object> =\r\n | Record<string, PureMethod<T, any[], any>>\r\n | Map<PropertyKey, PureMethod<T, any[], any>>;\r\n\r\n\r\nexport function patch<C extends Constructor<any>>(\r\n targetOrCtor: C,\r\n fns: PatchSpec<InstanceType<C>>\r\n): Map<PropertyKey, PropertyDescriptor | null>;\r\n\r\nexport function patch<T extends object>(\r\n targetOrCtor: T,\r\n fns: PatchSpec<T>\r\n): Map<PropertyKey, PropertyDescriptor | null>;\r\n\r\n/**\r\n * Devuelve un Map donde:\r\n * - clave -> null (método añadido nuevo)\r\n * - clave -> descriptorOriginal (método sustituido)\r\n */\r\nexport function patch(\r\n targetOrCtor: any,\r\n fns: PatchSpec<any>\r\n): Map<PropertyKey, PropertyDescriptor | null> {\r\n const target = typeof targetOrCtor === \"function\" ? targetOrCtor.prototype : targetOrCtor;\r\n\r\n const result = new Map<PropertyKey, PropertyDescriptor | null>();\r\n const entries: Array<[PropertyKey, PureMethod<any>]> =\r\n fns instanceof Map ? [...fns.entries()] : Object.entries(fns) as any;\r\n\r\n for (const [key, fn] of entries) {\r\n const prev = Object.getOwnPropertyDescriptor(target, key);\r\n const method = function (this: unknown, ...args: unknown[]) {\r\n return (fn as any)(this, ...args);\r\n };\r\n try {\r\n Object.defineProperty(target, key, {\r\n value: method,\r\n writable: true,\r\n configurable: true,\r\n enumerable: false,\r\n });\r\n result.set(key, prev ?? null);\r\n } catch { /* ignorar */\r\n }\r\n }\r\n return result;\r\n}\r\n\r\n// Overloads unpatch\r\nexport function unpatch<C extends Constructor<any>>(\r\n targetOrCtor: C,\r\n changes: Map<PropertyKey, PropertyDescriptor | null>\r\n): void;\r\nexport function unpatch<T extends object>(\r\n targetOrCtor: T,\r\n changes: Map<PropertyKey, PropertyDescriptor | null>\r\n): void;\r\n\r\n/**\r\n * Revierte un patch a partir del mapa devuelto por `patch`.\r\n */\r\nexport function unpatch(targetOrCtor: any, changes: Map<PropertyKey, PropertyDescriptor | null>): void {\r\n const target = typeof targetOrCtor === \"function\" ? targetOrCtor.prototype : targetOrCtor;\r\n for (const [key, prev] of changes) {\r\n try {\r\n if (prev === null) {\r\n if (Object.prototype.hasOwnProperty.call(target, key)) delete target[key];\r\n } else {\r\n Object.defineProperty(target, key, prev);\r\n }\r\n } catch { /* ignorar */\r\n }\r\n }\r\n}"]}
1
+ {"version":3,"file":"patch.js","sourceRoot":"","sources":["../../src/patch.ts"],"names":[],"mappings":"AAoBA;;;;GAIG;AACH,MAAM,UAAU,KAAK,CACjB,YAAiB,EACjB,GAAmB;IAEnB,MAAM,MAAM,GAAG,OAAO,YAAY,KAAK,UAAU,CAAC,CAAC,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC,CAAC,YAAY,CAAC;IAE1F,MAAM,MAAM,GAAG,IAAI,GAAG,EAA0C,CAAC;IACjE,MAAM,OAAO,GACT,GAAG,YAAY,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,CAAQ,CAAC;IAEzE,KAAK,MAAM,CAAC,GAAG,EAAE,EAAE,CAAC,IAAI,OAAO,EAAE,CAAC;QAC9B,MAAM,IAAI,GAAG,MAAM,CAAC,wBAAwB,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;QAC1D,MAAM,MAAM,GAAG,UAAyB,GAAG,IAAe;YACtD,OAAQ,EAAU,CAAC,IAAI,EAAE,GAAG,IAAI,CAAC,CAAC;QACtC,CAAC,CAAC;QACF,IAAI,CAAC;YACD,MAAM,CAAC,cAAc,CAAC,MAAM,EAAE,GAAG,EAAE;gBAC/B,KAAK,EAAE,MAAM;gBACb,QAAQ,EAAE,IAAI;gBACd,YAAY,EAAE,IAAI;gBAClB,UAAU,EAAE,KAAK;aACpB,CAAC,CAAC;YACH,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,IAAI,IAAI,CAAC,CAAC;QAClC,CAAC;QAAC,MAAM,CAAC,CAAC,aAAa;QACvB,CAAC;IACL,CAAC;IACD,OAAO,MAAM,CAAC;AAClB,CAAC;AAYD;;GAEG;AACH,MAAM,UAAU,OAAO,CAAC,YAAiB,EAAE,OAAoD;IAC3F,MAAM,MAAM,GAAG,OAAO,YAAY,KAAK,UAAU,CAAC,CAAC,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC,CAAC,YAAY,CAAC;IAC1F,KAAK,MAAM,CAAC,GAAG,EAAE,IAAI,CAAC,IAAI,OAAO,EAAE,CAAC;QAChC,IAAI,CAAC;YACD,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC;gBAChB,IAAI,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,CAAC;oBAAE,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC;YAC9E,CAAC;iBAAM,CAAC;gBACJ,MAAM,CAAC,cAAc,CAAC,MAAM,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC;YAC7C,CAAC;QACL,CAAC;QAAC,MAAM,CAAC,CAAC,aAAa;QACvB,CAAC;IACL,CAAC;AACL,CAAC","sourcesContent":["import type {Constructor} from \"./types.js\";\n\nexport type PureMethod<T extends object, A extends any[] = any[], R = any> =\n (obj: T, ...args: A) => R;\n\nexport type PatchSpec<T extends object> =\n | Record<string, PureMethod<T, any[], any>>\n | Map<PropertyKey, PureMethod<T, any[], any>>;\n\n\nexport function patch<C extends Constructor<any>>(\n targetOrCtor: C,\n fns: PatchSpec<InstanceType<C>>\n): Map<PropertyKey, PropertyDescriptor | null>;\n\nexport function patch<T extends object>(\n targetOrCtor: T,\n fns: PatchSpec<T>\n): Map<PropertyKey, PropertyDescriptor | null>;\n\n/**\n * Devuelve un Map donde:\n * - clave -> null (método añadido nuevo)\n * - clave -> descriptorOriginal (método sustituido)\n */\nexport function patch(\n targetOrCtor: any,\n fns: PatchSpec<any>\n): Map<PropertyKey, PropertyDescriptor | null> {\n const target = typeof targetOrCtor === \"function\" ? targetOrCtor.prototype : targetOrCtor;\n\n const result = new Map<PropertyKey, PropertyDescriptor | null>();\n const entries: Array<[PropertyKey, PureMethod<any>]> =\n fns instanceof Map ? [...fns.entries()] : Object.entries(fns) as any;\n\n for (const [key, fn] of entries) {\n const prev = Object.getOwnPropertyDescriptor(target, key);\n const method = function (this: unknown, ...args: unknown[]) {\n return (fn as any)(this, ...args);\n };\n try {\n Object.defineProperty(target, key, {\n value: method,\n writable: true,\n configurable: true,\n enumerable: false,\n });\n result.set(key, prev ?? null);\n } catch { /* ignorar */\n }\n }\n return result;\n}\n\n// Overloads unpatch\nexport function unpatch<C extends Constructor<any>>(\n targetOrCtor: C,\n changes: Map<PropertyKey, PropertyDescriptor | null>\n): void;\nexport function unpatch<T extends object>(\n targetOrCtor: T,\n changes: Map<PropertyKey, PropertyDescriptor | null>\n): void;\n\n/**\n * Revierte un patch a partir del mapa devuelto por `patch`.\n */\nexport function unpatch(targetOrCtor: any, changes: Map<PropertyKey, PropertyDescriptor | null>): void {\n const target = typeof targetOrCtor === \"function\" ? targetOrCtor.prototype : targetOrCtor;\n for (const [key, prev] of changes) {\n try {\n if (prev === null) {\n if (Object.prototype.hasOwnProperty.call(target, key)) delete target[key];\n } else {\n Object.defineProperty(target, key, prev);\n }\n } catch { /* ignorar */\n }\n }\n}"]}
@@ -1 +1 @@
1
- {"version":3,"file":"stopwatch.js","sourceRoot":"","sources":["../../src/stopwatch.ts"],"names":[],"mappings":"AAAA,OAAO,QAAQ,MAAM,eAAe,CAAC;AAErC,MAAM,CAAC,OAAO,OAAO,SAAS;IAA9B;QACY,cAAS,GAAkB,IAAI,CAAC;QAChC,gBAAW,GAAkB,IAAI,CAAC;IAsC9C,CAAC;IApCG;;;;;;;;;OASG;IAEH,KAAK;QACD,IAAI,CAAC,SAAS,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC;QACnC,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;IAC5B,CAAC;IAED,IAAI;QACA,IAAI,IAAI,CAAC,SAAS,KAAK,IAAI,EAAE,CAAC;YAC1B,IAAI,CAAC,WAAW,GAAG,WAAW,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC;YACtD,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;QAC1B,CAAC;IACL,CAAC;IAED,MAAM;QACF,IAAI,IAAI,CAAC,WAAW,KAAK,IAAI,EAAE,CAAC;YAC5B,IAAI,CAAC,SAAS,GAAG,WAAW,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,WAAW,CAAC;YACtD,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;QAC5B,CAAC;IACL,CAAC;IAED,cAAc;QACV,IAAI,IAAI,CAAC,SAAS,KAAK,IAAI,EAAE,CAAC;YAC1B,OAAO,QAAQ,CAAC,gBAAgB,CAAC,WAAW,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC;QACzE,CAAC;QACD,OAAO,QAAQ,CAAC,gBAAgB,CAAC,IAAI,CAAC,WAAW,IAAI,GAAG,CAAC,CAAC;IAC9D,CAAC;CACJ","sourcesContent":["import TimeSpan from \"./timespan.js\";\r\n\r\nexport default class Stopwatch {\r\n private startTime: number | null = null;\r\n private elapsedTime: number | null = null;\r\n\r\n /*static measure<T>(callback: () => T, measure: { value: TimeSpan | null }): T {\r\n const stopwatch = new Stopwatch();\r\n stopwatch.start();\r\n try {\r\n return callback();\r\n } finally {\r\n stopwatch.stop();\r\n measure.value = stopwatch.getElapsedTime();\r\n }\r\n }*/\r\n\r\n start(): void {\r\n this.startTime = performance.now();\r\n this.elapsedTime = null;\r\n }\r\n\r\n stop(): void {\r\n if (this.startTime !== null) {\r\n this.elapsedTime = performance.now() - this.startTime;\r\n this.startTime = null;\r\n }\r\n }\r\n\r\n resume(): void {\r\n if (this.elapsedTime !== null) {\r\n this.startTime = performance.now() - this.elapsedTime;\r\n this.elapsedTime = null;\r\n }\r\n }\r\n\r\n getElapsedTime(): TimeSpan {\r\n if (this.startTime !== null) {\r\n return TimeSpan.fromMilliseconds(performance.now() - this.startTime);\r\n }\r\n return TimeSpan.fromMilliseconds(this.elapsedTime ?? 0.0);\r\n }\r\n}\r\n"]}
1
+ {"version":3,"file":"stopwatch.js","sourceRoot":"","sources":["../../src/stopwatch.ts"],"names":[],"mappings":"AAAA,OAAO,QAAQ,MAAM,eAAe,CAAC;AAErC,MAAM,CAAC,OAAO,OAAO,SAAS;IAA9B;QACY,cAAS,GAAkB,IAAI,CAAC;QAChC,gBAAW,GAAkB,IAAI,CAAC;IAsC9C,CAAC;IApCG;;;;;;;;;OASG;IAEH,KAAK;QACD,IAAI,CAAC,SAAS,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC;QACnC,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;IAC5B,CAAC;IAED,IAAI;QACA,IAAI,IAAI,CAAC,SAAS,KAAK,IAAI,EAAE,CAAC;YAC1B,IAAI,CAAC,WAAW,GAAG,WAAW,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC;YACtD,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;QAC1B,CAAC;IACL,CAAC;IAED,MAAM;QACF,IAAI,IAAI,CAAC,WAAW,KAAK,IAAI,EAAE,CAAC;YAC5B,IAAI,CAAC,SAAS,GAAG,WAAW,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,WAAW,CAAC;YACtD,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;QAC5B,CAAC;IACL,CAAC;IAED,cAAc;QACV,IAAI,IAAI,CAAC,SAAS,KAAK,IAAI,EAAE,CAAC;YAC1B,OAAO,QAAQ,CAAC,gBAAgB,CAAC,WAAW,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC;QACzE,CAAC;QACD,OAAO,QAAQ,CAAC,gBAAgB,CAAC,IAAI,CAAC,WAAW,IAAI,GAAG,CAAC,CAAC;IAC9D,CAAC;CACJ","sourcesContent":["import TimeSpan from \"./timespan.js\";\n\nexport default class Stopwatch {\n private startTime: number | null = null;\n private elapsedTime: number | null = null;\n\n /*static measure<T>(callback: () => T, measure: { value: TimeSpan | null }): T {\n const stopwatch = new Stopwatch();\n stopwatch.start();\n try {\n return callback();\n } finally {\n stopwatch.stop();\n measure.value = stopwatch.getElapsedTime();\n }\n }*/\n\n start(): void {\n this.startTime = performance.now();\n this.elapsedTime = null;\n }\n\n stop(): void {\n if (this.startTime !== null) {\n this.elapsedTime = performance.now() - this.startTime;\n this.startTime = null;\n }\n }\n\n resume(): void {\n if (this.elapsedTime !== null) {\n this.startTime = performance.now() - this.elapsedTime;\n this.elapsedTime = null;\n }\n }\n\n getElapsedTime(): TimeSpan {\n if (this.startTime !== null) {\n return TimeSpan.fromMilliseconds(performance.now() - this.startTime);\n }\n return TimeSpan.fromMilliseconds(this.elapsedTime ?? 0.0);\n }\n}\n"]}
@@ -31,7 +31,8 @@ export function ensureSuffix(str, suffix) {
31
31
  */
32
32
  export function format(template, ...args) {
33
33
  let regex;
34
- if (args.length === 1 && typeof args[0] === 'object') {
34
+ const hasNamedPlaceholders = /{(?!\d+})[^{}]+}/.test(template);
35
+ if (args.length === 1 && args[0] !== null && typeof args[0] === 'object' && hasNamedPlaceholders) {
35
36
  args = args[0];
36
37
  regex = /{(.+?)}/g;
37
38
  }
@@ -39,7 +40,9 @@ export function format(template, ...args) {
39
40
  regex = /{(\d+?)}/g;
40
41
  }
41
42
  return template.replace(regex, (match, key) => {
42
- return typeof args[key] !== 'undefined' ? args[key] : "";
43
+ return Object.prototype.hasOwnProperty.call(args, key) && typeof args[key] !== 'undefined'
44
+ ? args[key]
45
+ : "";
43
46
  });
44
47
  }
45
48
  /**
@@ -55,11 +58,11 @@ function toWords(str) {
55
58
  return [];
56
59
  return str
57
60
  // Insert a space between a lowercase/digit and an uppercase letter (camelCase -> camel Case)
58
- .replace(/([a-z0-9])([A-Z])/g, '$1 $2')
61
+ .replace(/([\p{Ll}\p{N}])(\p{Lu})/gu, '$1 $2')
59
62
  // Insert a space between consecutive uppercase letters followed by a lowercase letter (XMLParser -> XML Parser)
60
- .replace(/([A-Z]+)([A-Z][a-z])/g, '$1 $2')
63
+ .replace(/(\p{Lu}+)(\p{Lu}\p{Ll})/gu, '$1 $2')
61
64
  // Replace any non-alphanumeric character with a space
62
- .replace(/[^a-zA-Z0-9]+/g, ' ')
65
+ .replace(/[^\p{L}\p{N}]+/gu, ' ')
63
66
  .trim()
64
67
  .toLowerCase()
65
68
  .split(/\s+/)