@zelgadis87/utils-core 4.0.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 (134) hide show
  1. package/dist/Lazy.d.ts +21 -0
  2. package/dist/LazyAsync.d.ts +23 -0
  3. package/dist/Logger.d.ts +21 -0
  4. package/dist/Optional.d.ts +70 -0
  5. package/dist/async/CancelableDeferred.d.ts +17 -0
  6. package/dist/async/Deferred.d.ts +27 -0
  7. package/dist/async/RateThrottler.d.ts +12 -0
  8. package/dist/async/Semaphore.d.ts +10 -0
  9. package/dist/async/index.d.ts +4 -0
  10. package/dist/index.d.ts +11 -0
  11. package/dist/random/index.d.ts +2 -0
  12. package/dist/random/randomInterval.d.ts +1 -0
  13. package/dist/random/randomPercentage.d.ts +1 -0
  14. package/dist/sorting/ComparisonChain.d.ts +57 -0
  15. package/dist/sorting/Sorter.d.ts +100 -0
  16. package/dist/sorting/index.d.ts +4 -0
  17. package/dist/sorting/types.d.ts +5 -0
  18. package/dist/time/RandomTimeDuration.d.ts +9 -0
  19. package/dist/time/TimeBase.d.ts +38 -0
  20. package/dist/time/TimeDuration.d.ts +81 -0
  21. package/dist/time/TimeFrequency.d.ts +10 -0
  22. package/dist/time/TimeInstant.d.ts +137 -0
  23. package/dist/time/TimeInstantBuilder.d.ts +77 -0
  24. package/dist/time/TimeUnit.d.ts +17 -0
  25. package/dist/time/index.d.ts +6 -0
  26. package/dist/time/types.d.ts +26 -0
  27. package/dist/tsconfig.tsbuildinfo +1 -0
  28. package/dist/types/arrays.d.ts +33 -0
  29. package/dist/types/booleans.d.ts +2 -0
  30. package/dist/types/functions.d.ts +20 -0
  31. package/dist/types/index.d.ts +12 -0
  32. package/dist/types/json.d.ts +6 -0
  33. package/dist/types/nulls.d.ts +8 -0
  34. package/dist/types/numbers.d.ts +31 -0
  35. package/dist/types/promises.d.ts +6 -0
  36. package/dist/types/records.d.ts +14 -0
  37. package/dist/types/strings.d.ts +40 -0
  38. package/dist/upgrade/DataUpgrader.d.ts +22 -0
  39. package/dist/upgrade/errors.d.ts +12 -0
  40. package/dist/upgrade/getTransitionsPath.d.ts +3 -0
  41. package/dist/upgrade/index.d.ts +2 -0
  42. package/dist/upgrade/types.d.ts +31 -0
  43. package/dist/utils/asError.d.ts +1 -0
  44. package/dist/utils/bindThis.d.ts +1 -0
  45. package/dist/utils/constant.d.ts +8 -0
  46. package/dist/utils/entries.d.ts +4 -0
  47. package/dist/utils/groupBy.d.ts +7 -0
  48. package/dist/utils/iff.d.ts +8 -0
  49. package/dist/utils/index.d.ts +22 -0
  50. package/dist/utils/indexBy.d.ts +7 -0
  51. package/dist/utils/jsonCloneDeep.d.ts +2 -0
  52. package/dist/utils/math.d.ts +9 -0
  53. package/dist/utils/noop.d.ts +1 -0
  54. package/dist/utils/omit.d.ts +2 -0
  55. package/dist/utils/pad.d.ts +3 -0
  56. package/dist/utils/pluralize.d.ts +1 -0
  57. package/dist/utils/round.d.ts +8 -0
  58. package/dist/utils/sortBy.d.ts +7 -0
  59. package/dist/utils/throttle.d.ts +3 -0
  60. package/dist/utils/uniq.d.ts +1 -0
  61. package/dist/utils/uniqBy.d.ts +2 -0
  62. package/dist/utils/uniqByKey.d.ts +1 -0
  63. package/dist/utils/upsert.d.ts +0 -0
  64. package/dist/utils/withTryCatch.d.ts +2 -0
  65. package/dist/utils/withTryCatchAsync.d.ts +2 -0
  66. package/dist/utils/wrap.d.ts +1 -0
  67. package/esbuild/index.cjs +2670 -0
  68. package/esbuild/index.mjs +2518 -0
  69. package/package.json +159 -0
  70. package/src/Lazy.ts +77 -0
  71. package/src/LazyAsync.ts +100 -0
  72. package/src/Logger.ts +44 -0
  73. package/src/Optional.ts +172 -0
  74. package/src/async/CancelableDeferred.ts +36 -0
  75. package/src/async/Deferred.ts +84 -0
  76. package/src/async/RateThrottler.ts +46 -0
  77. package/src/async/Semaphore.ts +45 -0
  78. package/src/async/index.ts +6 -0
  79. package/src/index.ts +13 -0
  80. package/src/random/index.ts +3 -0
  81. package/src/random/randomInterval.ts +4 -0
  82. package/src/random/randomPercentage.ts +6 -0
  83. package/src/sorting/ComparisonChain.ts +209 -0
  84. package/src/sorting/Sorter.ts +357 -0
  85. package/src/sorting/index.ts +5 -0
  86. package/src/sorting/types.ts +7 -0
  87. package/src/time/RandomTimeDuration.ts +21 -0
  88. package/src/time/TimeBase.ts +113 -0
  89. package/src/time/TimeDuration.ts +296 -0
  90. package/src/time/TimeFrequency.ts +28 -0
  91. package/src/time/TimeInstant.ts +488 -0
  92. package/src/time/TimeInstantBuilder.ts +126 -0
  93. package/src/time/TimeUnit.ts +43 -0
  94. package/src/time/index.ts +8 -0
  95. package/src/time/types.ts +56 -0
  96. package/src/types/arrays.ts +89 -0
  97. package/src/types/booleans.ts +8 -0
  98. package/src/types/functions.ts +27 -0
  99. package/src/types/index.ts +18 -0
  100. package/src/types/json.ts +5 -0
  101. package/src/types/nulls.ts +33 -0
  102. package/src/types/numbers.ts +80 -0
  103. package/src/types/promises.ts +23 -0
  104. package/src/types/records.ts +21 -0
  105. package/src/types/strings.ts +143 -0
  106. package/src/upgrade/DataUpgrader.ts +100 -0
  107. package/src/upgrade/errors.ts +25 -0
  108. package/src/upgrade/getTransitionsPath.ts +89 -0
  109. package/src/upgrade/index.ts +4 -0
  110. package/src/upgrade/types.ts +36 -0
  111. package/src/utils/asError.ts +12 -0
  112. package/src/utils/bindThis.ts +4 -0
  113. package/src/utils/constant.ts +9 -0
  114. package/src/utils/entries.ts +13 -0
  115. package/src/utils/groupBy.ts +39 -0
  116. package/src/utils/iff.ts +26 -0
  117. package/src/utils/index.ts +24 -0
  118. package/src/utils/indexBy.ts +36 -0
  119. package/src/utils/jsonCloneDeep.ts +31 -0
  120. package/src/utils/math.ts +44 -0
  121. package/src/utils/noop.ts +2 -0
  122. package/src/utils/omit.ts +8 -0
  123. package/src/utils/pad.ts +20 -0
  124. package/src/utils/pluralize.ts +20 -0
  125. package/src/utils/round.ts +24 -0
  126. package/src/utils/sortBy.ts +27 -0
  127. package/src/utils/throttle.ts +10 -0
  128. package/src/utils/uniq.ts +6 -0
  129. package/src/utils/uniqBy.ts +15 -0
  130. package/src/utils/uniqByKey.ts +5 -0
  131. package/src/utils/upsert.ts +2 -0
  132. package/src/utils/withTryCatch.ts +10 -0
  133. package/src/utils/withTryCatchAsync.ts +6 -0
  134. package/src/utils/wrap.ts +4 -0
@@ -0,0 +1,2518 @@
1
+ // src/types/arrays.ts
2
+ function ensureArray(t) {
3
+ return t instanceof Array ? t : [t];
4
+ }
5
+ function ensureReadableArray(t) {
6
+ return t instanceof Array ? t : [t];
7
+ }
8
+ function isArray(t) {
9
+ return t instanceof Array;
10
+ }
11
+ function upsert(arr, item, isEqual) {
12
+ const index = arr.findIndex((a) => isEqual(a, item));
13
+ if (index === -1) {
14
+ return [...arr, item];
15
+ } else {
16
+ return [
17
+ ...arr.slice(0, index),
18
+ item,
19
+ ...arr.slice(index + 1)
20
+ ];
21
+ }
22
+ }
23
+ function range(start, end) {
24
+ if (end < start) throw new Error();
25
+ let length = end - start + 1;
26
+ return new Array(length).fill(1).map((_, i) => start + i);
27
+ }
28
+ function fill(length, value) {
29
+ return new Array(length).fill(value);
30
+ }
31
+ function extendArray(arr, props) {
32
+ return arr.map((t) => ({
33
+ ...t,
34
+ ...props
35
+ }));
36
+ }
37
+ function extendArrayWith(arr, propsFn) {
38
+ return arr.map((t) => ({
39
+ ...t,
40
+ ...propsFn(t)
41
+ }));
42
+ }
43
+ function reverse(arr) {
44
+ return [...arr].reverse();
45
+ }
46
+ function head(arr, defaultValue = null) {
47
+ return arr.length ? arr[0] : defaultValue;
48
+ }
49
+ function last(arr, defaultValue = null) {
50
+ return head(reverse(arr), defaultValue);
51
+ }
52
+ function sortedArray(arr, sortFn) {
53
+ return [...arr].sort(sortFn);
54
+ }
55
+ function includes(arr, item, fromIndex) {
56
+ return arr.includes(item, fromIndex);
57
+ }
58
+ function filterTruthy(arr) {
59
+ return arr.filter((x) => x !== false);
60
+ }
61
+
62
+ // src/types/booleans.ts
63
+ function isTrue(x) {
64
+ return x === true;
65
+ }
66
+ function isFalse(x) {
67
+ return x === false;
68
+ }
69
+
70
+ // src/types/functions.ts
71
+ function isFunction(t) {
72
+ return typeof t === "function";
73
+ }
74
+
75
+ // src/types/nulls.ts
76
+ function ensureDefined(v, name = "value") {
77
+ if (isDefined(v))
78
+ return v;
79
+ throw new Error("Expected " + name + " to be defined, got: " + v);
80
+ }
81
+ function isDefined(x) {
82
+ return x !== null && x !== void 0;
83
+ }
84
+ function isNullOrUndefined(x) {
85
+ return x === null || x === void 0;
86
+ }
87
+ function ifDefined(source, callback) {
88
+ if (isDefined(source))
89
+ callback(source);
90
+ }
91
+ function mapDefined(source, mapper) {
92
+ if (isDefined(source))
93
+ return mapper(source);
94
+ return null;
95
+ }
96
+ function ifNullOrUndefined(source, callback) {
97
+ if (isNullOrUndefined(source))
98
+ callback();
99
+ }
100
+
101
+ // src/types/numbers.ts
102
+ function ensurePositiveNumber(v, name = "value") {
103
+ if (v !== void 0 && v !== null && v > 0)
104
+ return v;
105
+ throw new Error(`Expected ${name} to be positive, got: ${v}`);
106
+ }
107
+ function ensureNonNegativeNumber(v, name = "value") {
108
+ if (v !== void 0 && v !== null && v >= 0)
109
+ return v;
110
+ throw new Error(`Expected ${name} to be non-negative, got: ${v}`);
111
+ }
112
+ function ensureNonPositiveNumber(v, name = "value") {
113
+ if (v !== void 0 && v !== null && v <= 0)
114
+ return v;
115
+ throw new Error(`Expected ${name} to be non-positive, got: ${v}`);
116
+ }
117
+ function ensureNegativeNumber(v, name = "value") {
118
+ if (v !== void 0 && v !== null && v < 0)
119
+ return v;
120
+ throw new Error(`Expected ${name} to be negative, got: ${v}`);
121
+ }
122
+ function incrementBy(n) {
123
+ return (v) => v + n;
124
+ }
125
+ function multiplyBy(n) {
126
+ return (v) => v * n;
127
+ }
128
+ function divideBy(n) {
129
+ return (v) => v / n;
130
+ }
131
+ var increment = incrementBy(1);
132
+ var decrement = incrementBy(-1);
133
+ var decrementBy = (n) => incrementBy(-n);
134
+ function isNumber(v) {
135
+ return typeof v === "number";
136
+ }
137
+ function isPositiveNumber(v) {
138
+ return v > 0;
139
+ }
140
+ function isNegativeNumber(v) {
141
+ return v < 0;
142
+ }
143
+ function isZero(v) {
144
+ return v === 0;
145
+ }
146
+
147
+ // src/types/promises.ts
148
+ function asPromise(promisable) {
149
+ return Promise.resolve(promisable);
150
+ }
151
+ function promiseSequence(...fns) {
152
+ const fn = async function() {
153
+ const results = [];
154
+ for (let i = 0; i < fns.length; i++) {
155
+ results[i] = await fns[i]();
156
+ }
157
+ return results;
158
+ };
159
+ return fn;
160
+ }
161
+ function delayPromise(duration) {
162
+ return (result) => duration.promise().then(() => result);
163
+ }
164
+
165
+ // src/types/records.ts
166
+ function dictToList(obj) {
167
+ return Object.keys(obj).map((key) => obj[key]);
168
+ }
169
+ function pick(o, keys) {
170
+ return keys.reduce((obj, key) => {
171
+ obj[key] = o[key];
172
+ return obj;
173
+ }, {});
174
+ }
175
+
176
+ // src/types/strings.ts
177
+ function hashCode(str) {
178
+ let hash = 0;
179
+ for (let i = 0; i < str.length; ++i)
180
+ hash = Math.imul(31, hash) + str.charCodeAt(i);
181
+ return hash | 0;
182
+ }
183
+ function repeat(char, times) {
184
+ return times > 0 ? range(0, times - 1).map((_) => char).join("") : "";
185
+ }
186
+ function capitalizeWord(word) {
187
+ return word[0].toUpperCase() + word.substring(1).toLowerCase();
188
+ }
189
+ function splitWords(text, regEx = /\s+/) {
190
+ return text.split(regEx).filter((t) => t.length > 0);
191
+ }
192
+ function stringToNumber(s) {
193
+ if (isNullOrUndefined(s))
194
+ return null;
195
+ return Number(s);
196
+ }
197
+ var StringParts = class _StringParts {
198
+ _parts;
199
+ constructor(...parts) {
200
+ this._parts = parts;
201
+ }
202
+ toUpperCase() {
203
+ return new _StringParts(...this.parts.map((part) => part.toUpperCase()));
204
+ }
205
+ toLowerCase() {
206
+ return new _StringParts(...this.parts.map((part) => part.toLowerCase()));
207
+ }
208
+ capitalizeFirst() {
209
+ if (!this.length) return this;
210
+ return new _StringParts(capitalizeWord(this.first), ...this.tail.map((part) => part.toLowerCase()));
211
+ }
212
+ capitalizeEach() {
213
+ return new _StringParts(...this.parts.map((part) => capitalizeWord(part)));
214
+ }
215
+ get parts() {
216
+ return this._parts;
217
+ }
218
+ get tail() {
219
+ const [_first, ...tail] = this.parts;
220
+ return tail;
221
+ }
222
+ get first() {
223
+ return this._parts[0] ?? null;
224
+ }
225
+ get last() {
226
+ return this._parts[this.length - 1] ?? null;
227
+ }
228
+ get length() {
229
+ return this._parts.length;
230
+ }
231
+ trim() {
232
+ return new _StringParts(...this.parts.map((part) => part.trim()));
233
+ }
234
+ toSnakeCase() {
235
+ return this.toLowerCase().join("_");
236
+ }
237
+ toCamelCase() {
238
+ if (!this.length) return "";
239
+ return [this.first.toLowerCase(), ...this.tail.map(capitalizeWord)].join("");
240
+ }
241
+ toKebabCase() {
242
+ return this.toLowerCase().join("-");
243
+ }
244
+ toPascalCase() {
245
+ return this.capitalizeEach().join("");
246
+ }
247
+ toHumanCase() {
248
+ return this.capitalizeFirst().join(" ");
249
+ }
250
+ join(separator) {
251
+ return this.parts.join(separator);
252
+ }
253
+ mergeWith({ parts: otherParts }) {
254
+ return new _StringParts(...this.parts, ...otherParts);
255
+ }
256
+ slice(start, end) {
257
+ return new _StringParts(...this.parts.slice(start, end));
258
+ }
259
+ splice(start, deleteCount, ...items) {
260
+ return new _StringParts(...this.parts.splice(start, deleteCount, ...items));
261
+ }
262
+ push(part) {
263
+ return new _StringParts(...this.parts, part);
264
+ }
265
+ shift(part) {
266
+ return new _StringParts(part, ...this.parts);
267
+ }
268
+ reverse() {
269
+ return new _StringParts(...this.parts.reverse());
270
+ }
271
+ static fromString = (s, separator = /\s+/g) => {
272
+ if (s === null || separator === null)
273
+ throw new Error("Invalid arguments");
274
+ return new _StringParts(...s.split(separator));
275
+ };
276
+ static fromParts = (...parts) => {
277
+ return new _StringParts(...parts);
278
+ };
279
+ };
280
+
281
+ // src/Lazy.ts
282
+ var Lazy = class _Lazy {
283
+ _value = void 0;
284
+ _initialized = false;
285
+ _generator;
286
+ constructor(generator) {
287
+ this._generator = ensureDefined(generator);
288
+ }
289
+ get value() {
290
+ return this._value;
291
+ }
292
+ getOrCreate() {
293
+ if (!this._initialized) {
294
+ this._value = this._generator();
295
+ this._initialized = true;
296
+ }
297
+ return this._value;
298
+ }
299
+ getOrThrow(errorMessage) {
300
+ if (!this._initialized)
301
+ throw new Error(errorMessage);
302
+ return this._value;
303
+ }
304
+ or(t) {
305
+ if (!this._initialized) {
306
+ return t;
307
+ } else {
308
+ return this._value;
309
+ }
310
+ }
311
+ isPresent() {
312
+ return this._initialized;
313
+ }
314
+ isEmpty() {
315
+ return !this._initialized;
316
+ }
317
+ ifPresent(fn) {
318
+ if (this.isPresent()) {
319
+ fn(this._value);
320
+ }
321
+ }
322
+ ifEmpty(fn) {
323
+ if (this.isEmpty()) {
324
+ fn();
325
+ }
326
+ }
327
+ apply(fnPresent, fnEmpty) {
328
+ if (this.isPresent()) {
329
+ fnPresent(this._value);
330
+ } else {
331
+ fnEmpty();
332
+ }
333
+ }
334
+ static of(generator) {
335
+ return new _Lazy(generator);
336
+ }
337
+ };
338
+
339
+ // src/LazyAsync.ts
340
+ var LazyAsync = class _LazyAsync {
341
+ _promise = void 0;
342
+ _pending = false;
343
+ _resolvedValue = void 0;
344
+ _error = void 0;
345
+ _generator;
346
+ constructor(generator) {
347
+ this._generator = ensureDefined(generator);
348
+ }
349
+ getOrCreate() {
350
+ if (this.isEmpty()) {
351
+ this._pending = true;
352
+ this._promise = this._generator();
353
+ this._promise.then((value) => {
354
+ this._pending = false;
355
+ this._resolvedValue = value;
356
+ }, (err) => {
357
+ this._pending = false;
358
+ this._error = err;
359
+ });
360
+ }
361
+ return this._promise;
362
+ }
363
+ isPresent() {
364
+ return this._promise !== void 0;
365
+ }
366
+ isEmpty() {
367
+ return this._promise === void 0;
368
+ }
369
+ isPending() {
370
+ return this.isPresent() && this._pending === true;
371
+ }
372
+ isReady() {
373
+ return this.isPresent() && this._pending === false;
374
+ }
375
+ isResolved() {
376
+ return this.isReady() && this._error === void 0;
377
+ }
378
+ isError() {
379
+ return this.isReady() && this._error !== void 0;
380
+ }
381
+ ifPresent(fn) {
382
+ if (this.isPresent()) {
383
+ fn(this._promise);
384
+ }
385
+ }
386
+ ifEmpty(fn) {
387
+ if (this.isEmpty()) {
388
+ fn();
389
+ }
390
+ }
391
+ ifPending(fn) {
392
+ if (this.isPending()) {
393
+ fn(this._promise);
394
+ }
395
+ }
396
+ ifReady(fn) {
397
+ if (this.isReady()) {
398
+ fn(this._promise);
399
+ }
400
+ }
401
+ ifResolved(fn) {
402
+ if (this.isResolved()) {
403
+ fn(this._resolvedValue);
404
+ }
405
+ }
406
+ ifError(fn) {
407
+ if (this.isError()) {
408
+ fn(this._error);
409
+ }
410
+ }
411
+ getOrThrow(errorMessage) {
412
+ if (!this._promise)
413
+ throw new Error(errorMessage);
414
+ return this._promise;
415
+ }
416
+ static of(generator) {
417
+ return new _LazyAsync(generator);
418
+ }
419
+ };
420
+
421
+ // src/async/Deferred.ts
422
+ var DeferredCanceledError = class extends Error {
423
+ };
424
+ var Deferred = class {
425
+ _pending;
426
+ _internals;
427
+ get pending() {
428
+ return this._pending;
429
+ }
430
+ /** @deprecated: Use resolve, then and catch directly; use asPromise to return a promise type. */
431
+ get promise() {
432
+ return this._internals.promise;
433
+ }
434
+ constructor() {
435
+ this._pending = true;
436
+ this._internals = this.createInternals();
437
+ }
438
+ resolve(val) {
439
+ if (!this._pending) throw new Error("Illegal state exception");
440
+ this._pending = false;
441
+ this._internals.resolve(val);
442
+ }
443
+ reject(reason) {
444
+ if (!this._pending) throw new Error("Illegal state exception");
445
+ this._pending = false;
446
+ this._internals.reject(reason);
447
+ }
448
+ then(onFulfilled, onRejected) {
449
+ return this._internals.promise.then(onFulfilled, onRejected);
450
+ }
451
+ catch(onRejected) {
452
+ return this._internals.promise.catch(onRejected);
453
+ }
454
+ finally(onfinally) {
455
+ return this._internals.promise.finally(onfinally);
456
+ }
457
+ cancel() {
458
+ if (!this._pending) throw new Error("Illegal state exception");
459
+ this._internals.reject(new DeferredCanceledError("Execution aborted by the user"));
460
+ }
461
+ get asPromise() {
462
+ return this;
463
+ }
464
+ get asCancelablePromise() {
465
+ return this;
466
+ }
467
+ createInternals() {
468
+ let resolveSelf, rejectSelf;
469
+ const promise = new Promise((resolve, reject) => {
470
+ resolveSelf = resolve;
471
+ rejectSelf = reject;
472
+ });
473
+ return {
474
+ promise,
475
+ resolve: resolveSelf,
476
+ reject: rejectSelf
477
+ };
478
+ }
479
+ get [Symbol.toStringTag]() {
480
+ return "[object Deferred]";
481
+ }
482
+ };
483
+ var Deferred_default = Deferred;
484
+
485
+ // src/utils/asError.ts
486
+ function asError(e) {
487
+ if (e === void 0 || e === null)
488
+ return new Error("Void message");
489
+ if (e instanceof Error)
490
+ return e;
491
+ if (typeof e === "string")
492
+ return new Error(e);
493
+ if (e instanceof String)
494
+ return new Error(e.toString());
495
+ return new Error(JSON.stringify(e));
496
+ }
497
+
498
+ // src/utils/bindThis.ts
499
+ function bindThis(fn, _this) {
500
+ return fn.bind(_this);
501
+ }
502
+
503
+ // src/utils/constant.ts
504
+ function constant(v) {
505
+ return () => v;
506
+ }
507
+ function identity(t) {
508
+ return t;
509
+ }
510
+ var constantNull = constant(null);
511
+ var constantTrue = constant(true);
512
+ var constantFalse = constant(false);
513
+ var constantZero = constant(0);
514
+ var constantOne = constant(1);
515
+
516
+ // src/utils/entries.ts
517
+ function dictToEntries(obj) {
518
+ return Object.entries(obj);
519
+ }
520
+ function entriesToDict(entries) {
521
+ return Object.fromEntries(entries);
522
+ }
523
+ function mapEntries(dict, mapper) {
524
+ return entriesToDict(dictToEntries(dict).map((entry) => mapper(entry)));
525
+ }
526
+
527
+ // src/utils/groupBy.ts
528
+ function groupByString(arr, field) {
529
+ return groupByStringWith(arr, (t) => t[field]);
530
+ }
531
+ function groupByNumber(arr, field) {
532
+ return groupByNumberWith(arr, (t) => t[field]);
533
+ }
534
+ function groupBySymbol(arr, field) {
535
+ return groupBySymbolWith(arr, (t) => t[field]);
536
+ }
537
+ function groupByStringWith(arr, getter) {
538
+ return doGroupByWith(arr, getter);
539
+ }
540
+ function groupByNumberWith(arr, getter) {
541
+ return doGroupByWith(arr, getter);
542
+ }
543
+ function groupBySymbolWith(arr, getter) {
544
+ return doGroupByWith(arr, getter);
545
+ }
546
+ function doGroupByWith(arr, getter) {
547
+ return arr.reduce((dict, cur) => {
548
+ const key = getter(cur);
549
+ if (key !== null && key !== void 0) {
550
+ const arr2 = dict[key] ?? [];
551
+ arr2.push(cur);
552
+ dict[key] = arr2;
553
+ }
554
+ return dict;
555
+ }, {});
556
+ }
557
+
558
+ // src/utils/iff.ts
559
+ function iff(firstPredicate, valueIfTrue) {
560
+ if (firstPredicate === true || firstPredicate instanceof Function && firstPredicate() === true) {
561
+ const ret = {
562
+ elseIf: () => ret,
563
+ otherwise: () => valueIfTrue
564
+ };
565
+ return ret;
566
+ } else {
567
+ const ret = {
568
+ elseIf: (elseIf, valueIfElseIfTrue) => iff(elseIf, valueIfElseIfTrue),
569
+ otherwise: (valueIfElse) => valueIfElse
570
+ };
571
+ return ret;
572
+ }
573
+ }
574
+
575
+ // src/utils/indexBy.ts
576
+ function indexByString(arr, field) {
577
+ return indexByStringWith(arr, (t) => t[field]);
578
+ }
579
+ function indexByNumber(arr, field) {
580
+ return indexByNumberWith(arr, (t) => t[field]);
581
+ }
582
+ function indexBySymbol(arr, field) {
583
+ return indexBySymbolWith(arr, (t) => t[field]);
584
+ }
585
+ function indexByStringWith(arr, getter) {
586
+ return doIndexByWith(arr, getter);
587
+ }
588
+ function indexByNumberWith(arr, getter) {
589
+ return doIndexByWith(arr, getter);
590
+ }
591
+ function indexBySymbolWith(arr, getter) {
592
+ return doIndexByWith(arr, getter);
593
+ }
594
+ function doIndexByWith(arr, getter) {
595
+ return arr.reduce((dict, cur) => {
596
+ const key = getter(cur);
597
+ if (key !== null && key !== void 0)
598
+ dict[key] = cur;
599
+ return dict;
600
+ }, {});
601
+ }
602
+
603
+ // src/utils/jsonCloneDeep.ts
604
+ function jsonCloneDeep(a) {
605
+ if (null === a || "object" !== typeof a) return a;
606
+ if (a instanceof Date) {
607
+ return new Date(a.getTime());
608
+ } else if (a instanceof Array) {
609
+ const copy = [];
610
+ for (let i = 0, len = a.length; i < len; i++) {
611
+ copy[i] = jsonCloneDeep(a[i]);
612
+ }
613
+ return copy;
614
+ } else if (a instanceof Object) {
615
+ const copy = {};
616
+ for (let attr in a) {
617
+ if (a.hasOwnProperty(attr))
618
+ copy[attr] = jsonCloneDeep(a[attr]);
619
+ }
620
+ return copy;
621
+ }
622
+ throw new Error("Unable to copy obj! Its type isn't supported.");
623
+ }
624
+
625
+ // src/utils/math.ts
626
+ function clamp(n, min2, max2) {
627
+ if (min2 === null || max2 === null || n === null || isNaN(min2) || isNaN(max2) || isNaN(n) || min2 > max2)
628
+ throw new Error();
629
+ if (n > max2) {
630
+ return max2;
631
+ } else if (n < min2) {
632
+ return min2;
633
+ } else {
634
+ return n;
635
+ }
636
+ }
637
+ function average(arr) {
638
+ const f = 1 / arr.length;
639
+ return arr.reduce((tot, cur) => tot + cur * f, 0);
640
+ }
641
+ function sum(arr) {
642
+ return arr.reduce((tot, cur) => tot + cur, 0);
643
+ }
644
+ function sumBy(arr, getter) {
645
+ return sum(arr.map(getter));
646
+ }
647
+ function min(arr) {
648
+ if (arr.length === 0) throw new Error("Cannot calculate value on empty array");
649
+ return arr.reduce((min2, cur) => cur < min2 ? cur : min2);
650
+ }
651
+ function minBy(arr, getter) {
652
+ return min(arr.map(getter));
653
+ }
654
+ function max(arr) {
655
+ if (arr.length === 0) throw new Error("Cannot calculate value on empty array");
656
+ return arr.reduce((max2, cur) => cur > max2 ? cur : max2);
657
+ }
658
+ function maxBy(arr, getter) {
659
+ return max(arr.map(getter));
660
+ }
661
+
662
+ // src/utils/noop.ts
663
+ function noop() {
664
+ }
665
+
666
+ // src/utils/omit.ts
667
+ function omit(o, ...keys) {
668
+ return keys.reduce((obj, key) => {
669
+ delete obj[key];
670
+ return obj;
671
+ }, { ...o });
672
+ }
673
+
674
+ // src/utils/pad.ts
675
+ function pad(str, n, char, where = "left") {
676
+ const length = ensureDefined(str).length;
677
+ if (length >= ensureDefined(n)) return str;
678
+ if (ensureDefined(char).length !== 1)
679
+ throw new Error("Illegal pad character");
680
+ const padding = repeat(char, n - length);
681
+ return (where === "left" ? padding : "") + str + (where === "right" ? padding : "");
682
+ }
683
+
684
+ // src/utils/pluralize.ts
685
+ function pluralize(n, singular, plural) {
686
+ if (!singular || !singular.length)
687
+ throw new Error();
688
+ if (n === 1)
689
+ return singular;
690
+ plural = plural ?? singular + "s";
691
+ const firstUppercase = singular.charAt(0) === singular.charAt(0).toUpperCase();
692
+ if (firstUppercase) {
693
+ const PLURAL = plural.toUpperCase();
694
+ const isAllUppercase = plural === PLURAL;
695
+ plural = isAllUppercase ? PLURAL : plural.charAt(0).toUpperCase() + plural.slice(1).toLowerCase();
696
+ }
697
+ return plural;
698
+ }
699
+
700
+ // src/utils/round.ts
701
+ var roundModes = {
702
+ "toNearest": Math.round,
703
+ "toLower": Math.floor,
704
+ "toUpper": Math.ceil,
705
+ "towardsZero": (n) => n > 0 ? Math.floor(n) : Math.ceil(n),
706
+ "awayFromZero": (n) => n > 0 ? Math.ceil(n) : Math.floor(n)
707
+ };
708
+ function round(n, precision = 0, mode = "toNearest") {
709
+ const base = 10;
710
+ const power = Math.pow(base, precision);
711
+ return roundModes[mode](n * power) / power;
712
+ }
713
+ var roundToNearest = (n, precision = 0) => round(n, precision, "toNearest");
714
+ var roundToLower = (n, precision = 0) => round(n, precision, "toLower");
715
+ var roundToUpper = (n, precision = 0) => round(n, precision, "toUpper");
716
+ var roundTowardsZero = (n, precision = 0) => round(n, precision, "towardsZero");
717
+ var roundAwayFromZero = (n, precision = 0) => round(n, precision, "awayFromZero");
718
+
719
+ // src/utils/sortBy.ts
720
+ function sortBy(keyOrGetter, direction = "ASC", nulls = "LAST") {
721
+ const directionNum = direction === "ASC" ? -1 : 1;
722
+ const nullsNum = nulls === "LAST" ? -1 : 1;
723
+ const sortByNum = (a, b) => {
724
+ if (a === b)
725
+ return -1;
726
+ const aDefined = !(a === null || a === void 0 || isNaN(a));
727
+ const bDefined = !(b === null || b === void 0 || isNaN(b));
728
+ if (!aDefined && !bDefined)
729
+ return -1;
730
+ if (aDefined !== bDefined)
731
+ return nullsNum * (aDefined ? 1 : -1);
732
+ return (a > b ? -1 : 1) * directionNum;
733
+ };
734
+ if (typeof keyOrGetter === "function") {
735
+ return (a, b) => sortByNum(keyOrGetter(a), keyOrGetter(b));
736
+ } else {
737
+ return (a, b) => sortByNum(a[keyOrGetter], b[keyOrGetter]);
738
+ }
739
+ }
740
+
741
+ // src/async/RateThrottler.ts
742
+ var RateThrottler = class {
743
+ constructor(_frequency) {
744
+ this._frequency = _frequency;
745
+ const initialOffset = this.cooldown.divideBy(_frequency.times);
746
+ this._availableSlots = new Array(_frequency.times).fill(0).map((_, i) => TimeInstant.now().addMs(i * initialOffset.ms));
747
+ this._waitingRequests = [];
748
+ }
749
+ _availableSlots;
750
+ _waitingRequests;
751
+ get cooldown() {
752
+ return this._frequency.period;
753
+ }
754
+ async execute(fn) {
755
+ const wrappedFn = async () => {
756
+ const slot = this._availableSlots.shift();
757
+ try {
758
+ return slot.promise().then(() => fn());
759
+ } finally {
760
+ this._availableSlots.push(TimeInstant.now().addDuration(this.cooldown));
761
+ if (this._waitingRequests.length > 0) this._waitingRequests.shift().resolve();
762
+ }
763
+ };
764
+ if (this._availableSlots.length > 0) {
765
+ return wrappedFn();
766
+ } else {
767
+ const waitingRequest = new Deferred_default();
768
+ this._waitingRequests.push(waitingRequest);
769
+ return waitingRequest.then(() => wrappedFn());
770
+ }
771
+ }
772
+ };
773
+
774
+ // src/async/Semaphore.ts
775
+ var Semaphore = class {
776
+ constructor(_availableSlots = 1) {
777
+ this._availableSlots = _availableSlots;
778
+ this._waitingRequests = [];
779
+ }
780
+ _waitingRequests;
781
+ async _awaitSlot() {
782
+ if (this._availableSlots > 0) {
783
+ this._availableSlots -= 1;
784
+ return void 0;
785
+ } else {
786
+ const deferred = new Deferred_default();
787
+ this._waitingRequests.push(deferred);
788
+ return deferred.asPromise;
789
+ }
790
+ }
791
+ _releaseSlot() {
792
+ const waitingSlotToResolve = this._waitingRequests.shift();
793
+ if (waitingSlotToResolve) {
794
+ waitingSlotToResolve.resolve();
795
+ } else {
796
+ this._availableSlots += 1;
797
+ }
798
+ }
799
+ async execute(fn, cooldown = TimeDuration.ZERO) {
800
+ return this._awaitSlot().then(() => fn()).finally(() => {
801
+ void cooldown.promise().then(() => this._releaseSlot());
802
+ });
803
+ }
804
+ };
805
+
806
+ // src/utils/throttle.ts
807
+ function throttle(fn, frequence) {
808
+ const semaphore = new RateThrottler(frequence);
809
+ return (...t) => {
810
+ return semaphore.execute(async () => fn(...t));
811
+ };
812
+ }
813
+
814
+ // src/utils/uniqBy.ts
815
+ function uniqBy(arr, getter) {
816
+ return arr.reduce((dict, cur) => {
817
+ const key = getter(cur);
818
+ if (dict.keys.includes(key)) {
819
+ return dict;
820
+ } else {
821
+ return {
822
+ keys: [...dict.keys, key],
823
+ values: [...dict.values, cur]
824
+ };
825
+ }
826
+ }, { keys: [], values: [] }).values;
827
+ }
828
+
829
+ // src/utils/uniq.ts
830
+ function uniq(arr) {
831
+ return uniqBy(arr, identity);
832
+ }
833
+
834
+ // src/utils/uniqByKey.ts
835
+ function uniqByKey(arr, key) {
836
+ return uniqBy(arr, (item) => item[key]);
837
+ }
838
+
839
+ // src/utils/withTryCatch.ts
840
+ function withTryCatch(fn) {
841
+ try {
842
+ return fn();
843
+ } catch (e) {
844
+ return asError(e);
845
+ }
846
+ }
847
+
848
+ // src/utils/withTryCatchAsync.ts
849
+ async function withTryCatchAsync(fn) {
850
+ return fn().catch((e) => asError(e));
851
+ }
852
+
853
+ // src/utils/wrap.ts
854
+ function wrap(str, delimiter) {
855
+ return delimiter + str + delimiter;
856
+ }
857
+
858
+ // src/time/TimeUnit.ts
859
+ var TimeUnit = class _TimeUnit {
860
+ constructor(multiplier) {
861
+ this.multiplier = multiplier;
862
+ }
863
+ toUnit(value, unit) {
864
+ return value * (this.multiplier / unit.multiplier);
865
+ }
866
+ toMs(value) {
867
+ return this.toUnit(value, _TimeUnit.MILLISECONDS);
868
+ }
869
+ toSeconds(value) {
870
+ return this.toUnit(value, _TimeUnit.SECONDS);
871
+ }
872
+ toMinutes(value) {
873
+ return this.toUnit(value, _TimeUnit.MINUTES);
874
+ }
875
+ toHours(value) {
876
+ return this.toUnit(value, _TimeUnit.HOURS);
877
+ }
878
+ toDays(value) {
879
+ return this.toUnit(value, _TimeUnit.DAYS);
880
+ }
881
+ toWeeks(value) {
882
+ return this.toUnit(value, _TimeUnit.WEEKS);
883
+ }
884
+ static MILLISECONDS = new _TimeUnit(1);
885
+ static SECONDS = new _TimeUnit(1e3 * _TimeUnit.MILLISECONDS.multiplier);
886
+ static MINUTES = new _TimeUnit(60 * _TimeUnit.SECONDS.multiplier);
887
+ static HOURS = new _TimeUnit(60 * _TimeUnit.MINUTES.multiplier);
888
+ static DAYS = new _TimeUnit(24 * _TimeUnit.HOURS.multiplier);
889
+ static WEEKS = new _TimeUnit(7 * _TimeUnit.DAYS.multiplier);
890
+ };
891
+
892
+ // src/time/TimeBase.ts
893
+ var TimeBase = class {
894
+ _ms;
895
+ constructor(value, unit) {
896
+ this._ms = unit.toMs(value);
897
+ }
898
+ get ms() {
899
+ return this._ms / TimeUnit.MILLISECONDS.multiplier;
900
+ }
901
+ get seconds() {
902
+ return this._ms / TimeUnit.SECONDS.multiplier;
903
+ }
904
+ get minutes() {
905
+ return this._ms / TimeUnit.MINUTES.multiplier;
906
+ }
907
+ get hours() {
908
+ return this._ms / TimeUnit.HOURS.multiplier;
909
+ }
910
+ get days() {
911
+ return this._ms / TimeUnit.DAYS.multiplier;
912
+ }
913
+ addMs(milliseconds) {
914
+ return this.addUnits(milliseconds, TimeUnit.MILLISECONDS);
915
+ }
916
+ addSeconds(seconds) {
917
+ return this.addUnits(seconds, TimeUnit.SECONDS);
918
+ }
919
+ addMinutes(minutes) {
920
+ return this.addUnits(minutes, TimeUnit.MINUTES);
921
+ }
922
+ addHours(hours) {
923
+ return this.addUnits(hours, TimeUnit.HOURS);
924
+ }
925
+ addDays(days) {
926
+ return this.addUnits(days, TimeUnit.DAYS);
927
+ }
928
+ removeDays(days) {
929
+ return this.removeUnits(days, TimeUnit.DAYS);
930
+ }
931
+ addUnits(n, unit) {
932
+ return this.create(this._ms + unit.toMs(n), TimeUnit.MILLISECONDS);
933
+ }
934
+ removeMs(milliseconds) {
935
+ return this.addUnits(-milliseconds, TimeUnit.MILLISECONDS);
936
+ }
937
+ removeSeconds(seconds) {
938
+ return this.addUnits(-seconds, TimeUnit.SECONDS);
939
+ }
940
+ removeMinutes(minutes) {
941
+ return this.addUnits(-minutes, TimeUnit.MINUTES);
942
+ }
943
+ removeHours(hours) {
944
+ return this.addUnits(-hours, TimeUnit.HOURS);
945
+ }
946
+ removeUnits(n, unit) {
947
+ return this.addUnits(-n, unit);
948
+ }
949
+ getUnit(unit) {
950
+ return this._ms / unit.multiplier;
951
+ }
952
+ toUnits() {
953
+ return {
954
+ days: Math.floor(this._ms / TimeUnit.DAYS.multiplier),
955
+ hours: Math.floor(this._ms / TimeUnit.HOURS.multiplier % 24),
956
+ minutes: Math.floor(this._ms / TimeUnit.MINUTES.multiplier % 60),
957
+ seconds: Math.floor(this._ms / TimeUnit.SECONDS.multiplier % 60)
958
+ };
959
+ }
960
+ static toMs(units) {
961
+ if (!units)
962
+ throw new Error("Invalid units given");
963
+ let ms = 0;
964
+ ms += units.ms ?? 0 * TimeUnit.MILLISECONDS.multiplier;
965
+ ms += (units.seconds ?? 0) * TimeUnit.SECONDS.multiplier;
966
+ ms += (units.minutes ?? 0) * TimeUnit.MINUTES.multiplier;
967
+ ms += (units.hours ?? 0) * TimeUnit.HOURS.multiplier;
968
+ ms += (units.days ?? 0) * TimeUnit.DAYS.multiplier;
969
+ return ms;
970
+ }
971
+ toJSON() {
972
+ return this._ms;
973
+ }
974
+ };
975
+
976
+ // src/random/randomInterval.ts
977
+ function randomInterval(min2, max2) {
978
+ return Math.floor(Math.random() * (max2 - min2 + 1) + min2);
979
+ }
980
+
981
+ // src/random/randomPercentage.ts
982
+ function randomPercentage(min2, max2) {
983
+ return randomInterval(min2, max2) / 100;
984
+ }
985
+
986
+ // src/time/TimeDuration.ts
987
+ var TimeDuration = class _TimeDuration extends TimeBase {
988
+ constructor(value, unit) {
989
+ super(value, unit);
990
+ if (value < 0)
991
+ throw new Error("Duration cannot be less than 0");
992
+ }
993
+ create(value, unit) {
994
+ return new _TimeDuration(value, unit);
995
+ }
996
+ addDuration(duration) {
997
+ return this.addUnits(duration.ms, TimeUnit.MILLISECONDS);
998
+ }
999
+ removeDuration(duration) {
1000
+ return this.removeUnits(duration.ms, TimeUnit.MILLISECONDS);
1001
+ }
1002
+ removeUnits(n, unit) {
1003
+ const nn = Math.min(n, this.getUnit(unit));
1004
+ return super.removeUnits(nn, unit);
1005
+ }
1006
+ /** @deprecated: Use multiplyBy instead **/
1007
+ multiply(times) {
1008
+ return this.multiplyBy(times);
1009
+ }
1010
+ multiplyBy(times) {
1011
+ ensureNonNegativeNumber(times, "times");
1012
+ return _TimeDuration.ms(this.ms * times);
1013
+ }
1014
+ divideBy(times) {
1015
+ ensurePositiveNumber(times, "times");
1016
+ return _TimeDuration.ms(this.ms / times);
1017
+ }
1018
+ /**
1019
+ * Returns the current duration in a human readable format, prioritizing the most significant unit of time and excluding the rest.
1020
+ * @todo[2023-06] Should allow more customization options
1021
+ * @todo[2023-06] By default should show the secondary unit only when actually needed (eg, 1h 20m & 3h, instead of 1h 20m & 3h 28m)
1022
+ * @todo[2023-06] Should not allow negative durations, as this is a duration and not an instant.
1023
+ * @returns the duration, with only the most significant units displayed as a human readable string, eg: 1d 20h, 10m 30s.
1024
+ */
1025
+ get formatted() {
1026
+ const format = (x, u1, y, u2) => `${x}${u1} ${pad(y.toString(), 2, "0")}${u2}`;
1027
+ const units = this.toUnits();
1028
+ if (units.days >= 1)
1029
+ return format(units.days, "d", units.hours, "h");
1030
+ else if (units.hours >= 1)
1031
+ return format(units.hours, "h", units.minutes, "m");
1032
+ else if (units.minutes >= 1)
1033
+ return format(units.minutes, "m", units.seconds, "s");
1034
+ else if (units.seconds >= 0)
1035
+ return units.seconds.toString() + "s";
1036
+ else if (units.seconds > -60)
1037
+ return "A few moments ago";
1038
+ else
1039
+ return "Some time ago";
1040
+ }
1041
+ /**
1042
+ * @deprecated[2023-06] this method makes no sense, as durations are positive by default.
1043
+ */
1044
+ absolute() {
1045
+ return this.ms < 0 ? new _TimeDuration(-this.ms, TimeUnit.MILLISECONDS) : this;
1046
+ }
1047
+ interval(cb) {
1048
+ return setInterval(cb, this.ms);
1049
+ }
1050
+ timeout(cb) {
1051
+ return setTimeout(cb, this.ms);
1052
+ }
1053
+ promise() {
1054
+ const deferred = new Deferred_default();
1055
+ if (this.isEmpty()) {
1056
+ deferred.resolve();
1057
+ } else {
1058
+ this.timeout(() => deferred.resolve());
1059
+ }
1060
+ return deferred.asCancelablePromise;
1061
+ }
1062
+ delay(cb) {
1063
+ const deferred = this.promise();
1064
+ void deferred.then(() => {
1065
+ cb();
1066
+ }, (_err) => {
1067
+ return;
1068
+ });
1069
+ return { cancel: () => deferred.cancel() };
1070
+ }
1071
+ debounce(fn) {
1072
+ let handle = null;
1073
+ return (t) => {
1074
+ if (handle)
1075
+ clearTimeout(handle);
1076
+ handle = this.timeout(() => {
1077
+ handle = null;
1078
+ fn(t);
1079
+ });
1080
+ };
1081
+ }
1082
+ toDigitalClock() {
1083
+ const units = this.toUnits();
1084
+ return pad(units.hours.toString(), 2, "0") + ":" + pad(units.minutes.toString(), 2, "0") + ":" + pad(units.seconds.toString(), 2, "0");
1085
+ }
1086
+ get asSeconds() {
1087
+ if (this.ms < 0)
1088
+ return "0";
1089
+ if (this.ms < 1e3)
1090
+ return (this.ms / 1e3).toFixed(1);
1091
+ return Math.floor(this.seconds).toString();
1092
+ }
1093
+ fromNow() {
1094
+ return TimeInstant_default.now().addDuration(this);
1095
+ }
1096
+ differenceFrom(other) {
1097
+ return new _TimeDuration(Math.abs(this.ms - other.ms), TimeUnit.MILLISECONDS);
1098
+ }
1099
+ /** @deprecated: Use fromNow instead **/
1100
+ addCurrentTime() {
1101
+ return this.fromNow();
1102
+ }
1103
+ isGreaterThan(other) {
1104
+ return this.ms > other.ms;
1105
+ }
1106
+ isLessThan(other) {
1107
+ return this.ms < other.ms;
1108
+ }
1109
+ compareTo(other) {
1110
+ if (this.ms === other.ms) {
1111
+ return 0;
1112
+ } else if (this.isLessThan(other)) {
1113
+ return -1;
1114
+ } else {
1115
+ return 1;
1116
+ }
1117
+ }
1118
+ atLeast(other) {
1119
+ if (!this.isLessThan(other)) {
1120
+ return this;
1121
+ } else {
1122
+ return other;
1123
+ }
1124
+ }
1125
+ atMost(other) {
1126
+ if (!this.isGreaterThan(other)) {
1127
+ return this;
1128
+ } else {
1129
+ return other;
1130
+ }
1131
+ }
1132
+ isEmpty() {
1133
+ return this.ms <= 0;
1134
+ }
1135
+ isNotEmpty() {
1136
+ return this.ms > 0;
1137
+ }
1138
+ /**
1139
+ * This method is used to provide a better DX when inspecting a TimeInstant object in DevTools.
1140
+ */
1141
+ get _duration() {
1142
+ return this.formatted;
1143
+ }
1144
+ toString() {
1145
+ return `${this.constructor.name}[${this.formatted}]`;
1146
+ }
1147
+ static parseHumanTime(humanTime) {
1148
+ const match = humanTime.trim().match(/^(?:([0-9]+)d|)\s*(?:([0-9]+)h|)\s*(?:([0-9]+)m|)\s*(?:([0-9]+)s|)$/);
1149
+ if (match) {
1150
+ const [_, days, hours, minutes, seconds] = match;
1151
+ return new _TimeDuration(TimeBase.toMs({ days: Number(days ?? 0), hours: Number(hours ?? 0), minutes: Number(minutes ?? 0), seconds: Number(seconds ?? 0) }), TimeUnit.MILLISECONDS);
1152
+ }
1153
+ throw new Error("Failed to parse time: " + humanTime);
1154
+ }
1155
+ static compare(a, b) {
1156
+ return a.compareTo(b);
1157
+ }
1158
+ static ms = durationConstructor(TimeUnit.MILLISECONDS);
1159
+ static seconds = durationConstructor(TimeUnit.SECONDS);
1160
+ static minutes = durationConstructor(TimeUnit.MINUTES);
1161
+ static hours = durationConstructor(TimeUnit.HOURS);
1162
+ static days = durationConstructor(TimeUnit.DAYS);
1163
+ static shamefulUnref = (ms) => {
1164
+ if (ms instanceof _TimeDuration) {
1165
+ return ms.ms;
1166
+ }
1167
+ return ms;
1168
+ };
1169
+ static shamefulRef = (ms) => {
1170
+ if (ms instanceof _TimeDuration) {
1171
+ return ms;
1172
+ }
1173
+ if (ms < 0) {
1174
+ ms = 0;
1175
+ }
1176
+ return _TimeDuration.ms(ms);
1177
+ };
1178
+ static unref = (ms) => {
1179
+ return _TimeDuration.shamefulUnref(ms);
1180
+ };
1181
+ static ref = (ms) => {
1182
+ return _TimeDuration.shamefulRef(ms);
1183
+ };
1184
+ static fromMs(ms) {
1185
+ return new _TimeDuration(ms, TimeUnit.MILLISECONDS);
1186
+ }
1187
+ static distanceFromNow(instant) {
1188
+ return _TimeDuration.distance(TimeInstant_default.now(), instant);
1189
+ }
1190
+ static distance(instant1, instant2) {
1191
+ return instant1.distanceFrom(instant2);
1192
+ }
1193
+ static greatest(duration1, duration2) {
1194
+ return duration1.isGreaterThan(duration2) ? duration1 : duration2;
1195
+ }
1196
+ static lowest(duration1, duration2) {
1197
+ return duration1.isLessThan(duration2) ? duration1 : duration2;
1198
+ }
1199
+ static ZERO = new _TimeDuration(0, TimeUnit.MILLISECONDS);
1200
+ static fromJSON(ms) {
1201
+ return _TimeDuration.ms(ms);
1202
+ }
1203
+ };
1204
+ function durationConstructor(unit) {
1205
+ return (a, b) => {
1206
+ const aMs = unit.toMs(a);
1207
+ const bMs = b ? unit.toMs(b) : aMs;
1208
+ return TimeDuration.fromMs(randomInterval(aMs, bMs));
1209
+ };
1210
+ }
1211
+ function isAllowedTimeDuration(t) {
1212
+ return typeof t === "number" && t > 0 || t instanceof TimeDuration;
1213
+ }
1214
+ var TimeDuration_default = TimeDuration;
1215
+
1216
+ // src/time/TimeInstantBuilder.ts
1217
+ var isRelativeNumber = (x) => x !== void 0 && x.length > 0 && (x[0] === "+" || x[0] === "-");
1218
+ var defaultTimeInstantCreationParameters = {
1219
+ year: { relative: 0, relativeTo: "now" },
1220
+ month: { relative: 0, relativeTo: "now" },
1221
+ date: { relative: 0, relativeTo: "now" },
1222
+ hours: { relative: 0, relativeTo: "now" },
1223
+ minutes: { relative: 0, relativeTo: "now" },
1224
+ seconds: { relative: 0, relativeTo: "now" },
1225
+ milliseconds: { relative: 0, relativeTo: "now" }
1226
+ };
1227
+ var timeInstantCreationRelativeAliases = {
1228
+ current: 0,
1229
+ last: -1,
1230
+ next: 1
1231
+ };
1232
+ var monthNames = {
1233
+ january: 1,
1234
+ february: 2,
1235
+ march: 3,
1236
+ april: 4,
1237
+ may: 5,
1238
+ june: 6,
1239
+ july: 7,
1240
+ august: 8,
1241
+ september: 9,
1242
+ october: 10,
1243
+ november: 11,
1244
+ december: 12
1245
+ };
1246
+ var timeInstantResolveValue = (getFromDate2, referenceDate, x) => {
1247
+ if (x === void 0) {
1248
+ return getFromDate2(referenceDate);
1249
+ } else if (typeof x === "number") {
1250
+ return x;
1251
+ } else if (typeof x === "string") {
1252
+ if (isRelativeNumber(x)) {
1253
+ return getFromDate2(referenceDate) + parseInt(x);
1254
+ } else if (x in timeInstantCreationRelativeAliases) {
1255
+ return getFromDate2(referenceDate) + timeInstantCreationRelativeAliases[x];
1256
+ } else if (x in monthNames) {
1257
+ return monthNames[x];
1258
+ } else {
1259
+ throw new Error("Uparseable string detected: " + x);
1260
+ }
1261
+ } else if ("relative" in x) {
1262
+ const { relative, relativeTo } = x;
1263
+ if (relativeTo === void 0 || relativeTo === "now") {
1264
+ return getFromDate2(referenceDate) + relative;
1265
+ } else {
1266
+ return getFromDate2(relativeTo.asDateUTC()) + relative;
1267
+ }
1268
+ } else if ("absolute" in x) {
1269
+ return x.absolute;
1270
+ } else {
1271
+ throw new Error("Uparseable value detected: " + x);
1272
+ }
1273
+ };
1274
+ var getFromDate = {
1275
+ year: (d) => d.getFullYear(),
1276
+ month: (d) => d.getMonth(),
1277
+ date: (d) => d.getDate(),
1278
+ hours: (d) => d.getHours(),
1279
+ minutes: (d) => d.getMinutes(),
1280
+ seconds: (d) => d.getSeconds(),
1281
+ milliseconds: (d) => d.getMilliseconds()
1282
+ };
1283
+ var toReferenceDate = (x) => {
1284
+ ensureDefined(x);
1285
+ if (isTimeInstant(x)) return x.asDateUTC();
1286
+ return x;
1287
+ };
1288
+ function createTimeInstantFromParameters(aParameters, aReferenceDate = TimeInstant.now()) {
1289
+ const { year, month, date, hours, minutes, seconds, milliseconds } = { ...defaultTimeInstantCreationParameters, ...aParameters };
1290
+ const referenceDate = toReferenceDate(aReferenceDate);
1291
+ const timestamp2 = Date.UTC(
1292
+ timeInstantResolveValue(getFromDate.year, referenceDate, year),
1293
+ timeInstantResolveValue(getFromDate.month, referenceDate, month),
1294
+ timeInstantResolveValue(getFromDate.date, referenceDate, date),
1295
+ timeInstantResolveValue(getFromDate.hours, referenceDate, hours),
1296
+ timeInstantResolveValue(getFromDate.minutes, referenceDate, minutes),
1297
+ timeInstantResolveValue(getFromDate.seconds, referenceDate, seconds),
1298
+ timeInstantResolveValue(getFromDate.milliseconds, referenceDate, milliseconds)
1299
+ );
1300
+ if (isNaN(timestamp2))
1301
+ throw new Error(`Unparseable date: ${JSON.stringify(aParameters)} }`);
1302
+ return TimeInstant.fromUnixTimestamp(timestamp2);
1303
+ }
1304
+ function timeInstantBuilder() {
1305
+ let referenceDate = TimeInstant.now().asDateUTC();
1306
+ const value = { ...defaultTimeInstantCreationParameters };
1307
+ const ret = {
1308
+ year: (x) => {
1309
+ value.year = x;
1310
+ return ret;
1311
+ },
1312
+ month: (x) => {
1313
+ value.month = x;
1314
+ return ret;
1315
+ },
1316
+ date: (x) => {
1317
+ value.date = x;
1318
+ return ret;
1319
+ },
1320
+ hours: (x) => {
1321
+ value.hours = x;
1322
+ return ret;
1323
+ },
1324
+ minutes: (x) => {
1325
+ value.minutes = x;
1326
+ return ret;
1327
+ },
1328
+ seconds: (x) => {
1329
+ value.seconds = x;
1330
+ return ret;
1331
+ },
1332
+ milliseconds: (x) => {
1333
+ value.milliseconds = x;
1334
+ return ret;
1335
+ },
1336
+ values: (x) => {
1337
+ Object.keys(value).forEach((key) => value[key] = x[key] ?? value[key]);
1338
+ return ret;
1339
+ },
1340
+ relativeTo: (x) => {
1341
+ referenceDate = toReferenceDate(x);
1342
+ return ret;
1343
+ },
1344
+ build: () => createTimeInstantFromParameters(value, referenceDate)
1345
+ };
1346
+ return ret;
1347
+ }
1348
+
1349
+ // src/time/TimeInstant.ts
1350
+ var TimeInstant = class _TimeInstant extends TimeBase {
1351
+ constructor(number, unit) {
1352
+ super(number, unit);
1353
+ }
1354
+ create(value, unit) {
1355
+ return new _TimeInstant(value, unit);
1356
+ }
1357
+ addDuration(duration) {
1358
+ return _TimeInstant.fromUnixTimestamp(this.ms + duration.ms);
1359
+ }
1360
+ removeDuration(duration) {
1361
+ return _TimeInstant.fromUnixTimestamp(this.ms - duration.ms);
1362
+ }
1363
+ distanceFrom(instant) {
1364
+ return TimeDuration_default.fromMs(Math.abs(this.ms - instant.ms));
1365
+ }
1366
+ distanceFromNow() {
1367
+ return TimeDuration_default.fromMs(Math.abs(this.ms - Date.now()));
1368
+ }
1369
+ distanceFromStartOfDay() {
1370
+ return this.distanceFrom(this.atStartOfDay());
1371
+ }
1372
+ atStartOfDay() {
1373
+ return this.atTime({ hours: 0, minutes: 0, seconds: 0, milliseconds: 0 });
1374
+ }
1375
+ distanceFromEndOfDay() {
1376
+ return this.distanceFrom(this.atEndOfDay());
1377
+ }
1378
+ atEndOfDay() {
1379
+ return this.atTime({ hours: 23, minutes: 59, seconds: 59, milliseconds: 999 });
1380
+ }
1381
+ /** @deprecated[2024-10-24]: Use #promise() instead. */
1382
+ timeout(cb) {
1383
+ if (!this.isInTheFuture) {
1384
+ throw new Error("Instant is in the past");
1385
+ } else {
1386
+ return this.distanceFromNow().timeout(() => cb());
1387
+ }
1388
+ }
1389
+ promise() {
1390
+ const deferred = new Deferred_default();
1391
+ if (!this.isInTheFuture) {
1392
+ deferred.resolve();
1393
+ } else {
1394
+ this.distanceFromNow().timeout(() => deferred.resolve());
1395
+ }
1396
+ return deferred.asCancelablePromise;
1397
+ }
1398
+ delay(cb) {
1399
+ const deferred = this.promise();
1400
+ void deferred.then(() => {
1401
+ cb();
1402
+ }, (_err) => {
1403
+ return;
1404
+ });
1405
+ return { cancel: () => deferred.cancel() };
1406
+ }
1407
+ isToday() {
1408
+ return Math.floor(this.days) === Math.floor(_TimeInstant.now().days);
1409
+ }
1410
+ asTimeString() {
1411
+ const date = this.asDate();
1412
+ return `${this.doGetTwoDigitsHours(date)}:${this.doGetTwoDigitsMinutes(date)}:${this.doGetTwoDigitsSeconds(date)}`;
1413
+ }
1414
+ asDateString() {
1415
+ const date = this.asDate();
1416
+ return `${this.doGetTwoDigitsDays(date)}/${this.doGetTwoDigitsMonths(date)}/${this.doGetFourDigitsYears(date)}`;
1417
+ }
1418
+ asIso8601() {
1419
+ const dash = "-", colon = ".", doublecolon = ":", T = "T", date = this.asDate();
1420
+ return this.doGetFourDigitsYears(date) + dash + this.doGetTwoDigitsMonths(date) + dash + this.doGetTwoDigitsDays(date) + T + this.doGetTwoDigitsHours(date) + doublecolon + this.doGetTwoDigitsMinutes(date) + doublecolon + this.doGetTwoDigitsSeconds(date) + colon + this.doGetThreeDigitsMilliseconds(date) + this.doGetFourDigitsTimezoneOffset(date);
1421
+ }
1422
+ asIso8601UTC() {
1423
+ const dash = "-", colon = ".", doublecolon = ":", T = "T", utcDate = this.asDateUTC();
1424
+ return this.doGetFourDigitsYears(utcDate) + dash + this.doGetTwoDigitsMonths(utcDate) + dash + this.doGetTwoDigitsDays(utcDate) + T + this.doGetTwoDigitsHours(utcDate) + doublecolon + this.doGetTwoDigitsMinutes(utcDate) + doublecolon + this.doGetTwoDigitsSeconds(utcDate) + colon + this.doGetThreeDigitsMilliseconds(utcDate) + "Z";
1425
+ }
1426
+ asHumanTimestamp() {
1427
+ const dash = "-", colon = ".", doublecolon = ":", T = "T", date = this.asDate();
1428
+ return this.doGetFourDigitsYears(date) + dash + this.doGetTwoDigitsMonths(date) + dash + this.doGetTwoDigitsDays(date) + T + this.doGetTwoDigitsHours(date) + doublecolon + this.doGetTwoDigitsMinutes(date) + doublecolon + this.doGetTwoDigitsSeconds(date) + colon + this.doGetThreeDigitsMilliseconds(date);
1429
+ }
1430
+ // Please do not use this method internally, as it is not optimized for continued usage.
1431
+ get twoDigitsDays() {
1432
+ return this.doGetTwoDigitsDays(this.asDate());
1433
+ }
1434
+ // Please do not use this method internally, as it is not optimized for continued usage.
1435
+ get twoDigitsMonths() {
1436
+ return this.doGetTwoDigitsMonths(this.asDate());
1437
+ }
1438
+ // Please do not use this method internally, as it is not optimized for continued usage.
1439
+ get fourDigitsYears() {
1440
+ return this.doGetFourDigitsYears(this.asDate());
1441
+ }
1442
+ // Please do not use this method internally, as it is not optimized for continued usage.
1443
+ get twoDigitsHours() {
1444
+ return this.doGetTwoDigitsHours(this.asDate());
1445
+ }
1446
+ // Please do not use this method internally, as it is not optimized for continued usage.
1447
+ get twoDigitsMinutes() {
1448
+ return this.doGetTwoDigitsMinutes(this.asDate());
1449
+ }
1450
+ // Please do not use this method internally, as it is not optimized for continued usage.
1451
+ get twoDigitsSeconds() {
1452
+ return this.doGetTwoDigitsSeconds(this.asDate());
1453
+ }
1454
+ // Please do not use this method internally, as it is not optimized for continued usage.
1455
+ get threeDigitsMilliseconds() {
1456
+ return this.doGetThreeDigitsMilliseconds(this.asDate());
1457
+ }
1458
+ // Please do not use this method internally, as it is not optimized for continued usage.
1459
+ get twoDigitsDaysUTC() {
1460
+ return this.doGetTwoDigitsDays(this.asDateUTC());
1461
+ }
1462
+ // Please do not use this method internally, as it is not optimized for continued usage.
1463
+ get twoDigitsMonthsUTC() {
1464
+ return this.doGetTwoDigitsMonths(this.asDateUTC());
1465
+ }
1466
+ // Please do not use this method internally, as it is not optimized for continued usage.
1467
+ get fourDigitsYearsUTC() {
1468
+ return this.doGetFourDigitsYears(this.asDateUTC());
1469
+ }
1470
+ // Please do not use this method internally, as it is not optimized for continued usage.
1471
+ get twoDigitsHoursUTC() {
1472
+ return this.doGetTwoDigitsHours(this.asDateUTC());
1473
+ }
1474
+ // Please do not use this method internally, as it is not optimized for continued usage.
1475
+ get twoDigitsMinutesUTC() {
1476
+ return this.doGetTwoDigitsMinutes(this.asDateUTC());
1477
+ }
1478
+ // Please do not use this method internally, as it is not optimized for continued usage.
1479
+ get twoDigitsSecondsUTC() {
1480
+ return this.doGetTwoDigitsSeconds(this.asDateUTC());
1481
+ }
1482
+ // Please do not use this method internally, as it is not optimized for continued usage.
1483
+ get threeDigitsMillisecondsUTC() {
1484
+ return this.doGetThreeDigitsMilliseconds(this.asDateUTC());
1485
+ }
1486
+ // Please do not use this method internally, as it is not optimized for continued usage.
1487
+ get fourDigitsTimezoneOffset() {
1488
+ const offset = this.asDate().getTimezoneOffset();
1489
+ return (offset >= 0 ? "+" : "-") + pad(Math.floor(Math.abs(offset) / 60).toString(), 2, "0") + pad((Math.abs(offset) % 60).toString(), 2, "0");
1490
+ }
1491
+ doGetTwoDigitsDays(date) {
1492
+ return pad(date.getDate().toString(), 2, "0");
1493
+ }
1494
+ doGetTwoDigitsMonths(date) {
1495
+ return pad((date.getMonth() + 1).toString(), 2, "0");
1496
+ }
1497
+ doGetFourDigitsYears(date) {
1498
+ return pad(date.getFullYear().toString(), 4, "0");
1499
+ }
1500
+ doGetTwoDigitsHours(date) {
1501
+ return pad(date.getHours().toString(), 2, "0");
1502
+ }
1503
+ doGetTwoDigitsMinutes(date) {
1504
+ return pad(date.getMinutes().toString(), 2, "0");
1505
+ }
1506
+ doGetTwoDigitsSeconds(date) {
1507
+ return pad(date.getSeconds().toString(), 2, "0");
1508
+ }
1509
+ doGetThreeDigitsMilliseconds(date) {
1510
+ return pad(date.getMilliseconds().toString(), 3, "0");
1511
+ }
1512
+ doGetFourDigitsTimezoneOffset(date) {
1513
+ const offset = date.getTimezoneOffset();
1514
+ return (offset >= 0 ? "+" : "-") + pad(Math.floor(Math.abs(offset) / 60).toString(), 2, "0") + pad((Math.abs(offset) % 60).toString(), 2, "0");
1515
+ }
1516
+ asUnixTimestamp() {
1517
+ return this.ms;
1518
+ }
1519
+ asDate() {
1520
+ return new Date(this.ms);
1521
+ }
1522
+ asDateUTC() {
1523
+ return new Date(this.ms + (/* @__PURE__ */ new Date()).getTimezoneOffset() * 60 * 1e3);
1524
+ }
1525
+ get isInThePast() {
1526
+ return this.ms < Date.now();
1527
+ }
1528
+ get isInTheFuture() {
1529
+ return this.ms > Date.now();
1530
+ }
1531
+ isAfter(other) {
1532
+ return this.ms > other.ms;
1533
+ }
1534
+ isBefore(other) {
1535
+ return this.ms < other.ms;
1536
+ }
1537
+ compareTo(other) {
1538
+ if (this.ms === other.ms) {
1539
+ return 0;
1540
+ } else if (this.isBefore(other)) {
1541
+ return -1;
1542
+ } else {
1543
+ return 1;
1544
+ }
1545
+ }
1546
+ /**
1547
+ * @deprecated[04/07/2023]: Use distanceFromNow instead
1548
+ */
1549
+ fromNow() {
1550
+ return TimeDuration_default.ms(this.ms - Date.now());
1551
+ }
1552
+ /**
1553
+ * @deprecated[04/07/2023]: Use distanceFrom instead
1554
+ */
1555
+ from(instant) {
1556
+ return TimeDuration_default.ms(this.ms - instant.ms);
1557
+ }
1558
+ /**
1559
+ * @deprecated[04/07/2023]: Use distanceFromUnixTimestamp instead
1560
+ */
1561
+ fromTimestamp(timestamp2) {
1562
+ return TimeDuration_default.ms(this.ms - timestamp2);
1563
+ }
1564
+ distanceFromUnixTimestamp(timestamp2) {
1565
+ return TimeDuration_default.ms(this.ms - timestamp2);
1566
+ }
1567
+ atTime(parameters) {
1568
+ return _TimeInstant.fromParameters(parameters, this);
1569
+ }
1570
+ atDate(parameters) {
1571
+ return _TimeInstant.fromParameters(parameters, this);
1572
+ }
1573
+ at(parameters) {
1574
+ return _TimeInstant.fromParameters(parameters, this);
1575
+ }
1576
+ isBetween(start, end) {
1577
+ return this.ms >= start.ms && this.ms <= end.ms;
1578
+ }
1579
+ static fromDate(date) {
1580
+ return this.fromUnixTimestamp(date.getTime());
1581
+ }
1582
+ static fromUnixTimestamp(unixTimestamp) {
1583
+ return new _TimeInstant(unixTimestamp, TimeUnit.MILLISECONDS);
1584
+ }
1585
+ static fromUnixSeconds(unixSeconds) {
1586
+ return new _TimeInstant(unixSeconds, TimeUnit.SECONDS);
1587
+ }
1588
+ static fromParameters(parameters, referenceDate) {
1589
+ return createTimeInstantFromParameters(parameters, referenceDate);
1590
+ }
1591
+ static greatest(instant1, instant2) {
1592
+ return instant1.isAfter(instant2) ? instant1 : instant2;
1593
+ }
1594
+ static lowest(instant1, instant2) {
1595
+ return instant1.isBefore(instant2) ? instant1 : instant2;
1596
+ }
1597
+ static builder() {
1598
+ return timeInstantBuilder();
1599
+ }
1600
+ /**
1601
+ * @deprecated[19/07/2023] Use {@link fromParameters} instead.
1602
+ */
1603
+ static fromUnits({ date, month, year, hours, minutes, seconds }) {
1604
+ const dt = Date.UTC(year, month - 1, date, hours ?? 0, minutes ?? 0, seconds ?? 0);
1605
+ if (isNaN(dt))
1606
+ throw new Error(`Unparseable date: ${date}, ${month}, ${year}, ${hours ?? "-"}, ${minutes ?? "-"}, ${seconds ?? "-"}`);
1607
+ return _TimeInstant.fromUnixTimestamp(dt);
1608
+ }
1609
+ static fromIso8601(str) {
1610
+ return _TimeInstant.fromUnixTimestamp(new Date(str).getTime());
1611
+ }
1612
+ static now() {
1613
+ return _TimeInstant.fromUnixTimestamp(Date.now());
1614
+ }
1615
+ static get currentTimeStamp() {
1616
+ return Date.now();
1617
+ }
1618
+ static compare(a, b) {
1619
+ return a.compareTo(b);
1620
+ }
1621
+ roundedToStartOf(unit) {
1622
+ return _TimeInstant.fromUnixTimestamp(this.ms - this.ms % unit.multiplier);
1623
+ }
1624
+ roundedToEndOf(unit) {
1625
+ return _TimeInstant.fromUnixTimestamp(this.ms - this.ms % unit.multiplier + unit.toMs(1) - 1);
1626
+ }
1627
+ roundedToNext(unit, factor = 1) {
1628
+ const unitMs = unit.toMs(factor);
1629
+ const timestamp2 = Math.ceil(this.ms / unitMs) * unitMs;
1630
+ return _TimeInstant.fromUnixTimestamp(timestamp2);
1631
+ }
1632
+ roundedToPrevious(unit, factor = 1) {
1633
+ const unitMs = unit.toMs(factor);
1634
+ const timestamp2 = Math.floor(this.ms / unitMs) * unitMs;
1635
+ return _TimeInstant.fromUnixTimestamp(timestamp2);
1636
+ }
1637
+ roundedTo(unit, factor = 1) {
1638
+ const unitMs = unit.toMs(factor);
1639
+ const timestamp2 = Math.round(this.ms / unitMs) * unitMs;
1640
+ return _TimeInstant.fromUnixTimestamp(timestamp2);
1641
+ }
1642
+ get dayOfMonth() {
1643
+ return this.asDate().getDate();
1644
+ }
1645
+ get dayOfWeek() {
1646
+ return this.asDate().getDay() + 1;
1647
+ }
1648
+ get month() {
1649
+ return this.asDate().getMonth() + 1;
1650
+ }
1651
+ get year() {
1652
+ return this.asDate().getFullYear();
1653
+ }
1654
+ /**
1655
+ * Returns the week number represented by this instant, according to the ISO 8601 standard.
1656
+ * Please note that the instant and the week number could be of two different years, eg the friday 1st january is actually part of week 52 of the previous year.
1657
+ */
1658
+ get weekNumber() {
1659
+ const date = this.asDate();
1660
+ const oneDay = 1e3 * 60 * 60 * 24;
1661
+ const thursdayOfThisWeek = new Date(date.getFullYear(), date.getMonth(), date.getDate() + 4 - (date.getDay() || 7), 14, 0, 0);
1662
+ const firstOfJanuary = new Date(thursdayOfThisWeek.getFullYear(), 0, 1, 14, 0, 0);
1663
+ const dayOfTheYear = Math.round((thursdayOfThisWeek.getTime() - firstOfJanuary.getTime()) / oneDay);
1664
+ const weekNumber = Math.floor(dayOfTheYear / 7) + 1;
1665
+ return { weekNumber, year: thursdayOfThisWeek.getFullYear() };
1666
+ }
1667
+ /**
1668
+ * This method is used to provide a better DX when inspecting a TimeInstant object in DevTools.
1669
+ */
1670
+ get _time() {
1671
+ return this.asHumanTimestamp();
1672
+ }
1673
+ toString() {
1674
+ return `${this.constructor.name}[${this.asHumanTimestamp()}]`;
1675
+ }
1676
+ static ZERO = _TimeInstant.fromUnixTimestamp(0);
1677
+ static fromJSON(ms) {
1678
+ return _TimeInstant.fromUnixTimestamp(ms);
1679
+ }
1680
+ };
1681
+ function isTimeInstant(x) {
1682
+ return x !== null && x !== void 0 && x instanceof TimeInstant;
1683
+ }
1684
+ var TimeInstant_default = TimeInstant;
1685
+
1686
+ // src/Logger.ts
1687
+ var LEVELS = ["log", "debug", "info", "warn", "error"];
1688
+ var timestamp = () => TimeInstant_default.now().asTimeString();
1689
+ var Logger = class {
1690
+ constructor(name, args) {
1691
+ this.name = name;
1692
+ this.console = args?.console ?? globalThis.console;
1693
+ this.enabled = args?.enabled ?? true;
1694
+ this.minLevel = LEVELS.indexOf((args?.minLevel ?? "DEBUG").toLowerCase());
1695
+ }
1696
+ enabled = true;
1697
+ console;
1698
+ minLevel;
1699
+ get log() {
1700
+ return this.logWrap("log");
1701
+ }
1702
+ get debug() {
1703
+ return this.logWrap("debug");
1704
+ }
1705
+ get info() {
1706
+ return this.logWrap("info");
1707
+ }
1708
+ get warn() {
1709
+ return this.logWrap("warn");
1710
+ }
1711
+ get error() {
1712
+ return this.logWrap("error");
1713
+ }
1714
+ logWrap(methodName) {
1715
+ if (!this.console[methodName])
1716
+ throw new Error("Invalid method name: " + methodName);
1717
+ if (!this.enabled || !this.console || LEVELS.indexOf(methodName) < this.minLevel)
1718
+ return noop;
1719
+ return this.console[methodName].bind(this.console, timestamp(), methodName.toUpperCase(), this.name);
1720
+ }
1721
+ };
1722
+
1723
+ // src/Optional.ts
1724
+ var Optional = class _Optional {
1725
+ _present;
1726
+ _value;
1727
+ constructor(t) {
1728
+ const defined = isDefined(t);
1729
+ this._value = defined ? t : void 0;
1730
+ this._present = defined;
1731
+ }
1732
+ get rawValue() {
1733
+ return this._value;
1734
+ }
1735
+ get() {
1736
+ if (this.isEmpty())
1737
+ throw new ErrorGetEmptyOptional();
1738
+ return this.rawValue;
1739
+ }
1740
+ set(t) {
1741
+ if (isNullOrUndefined(t))
1742
+ throw new ErrorSetEmptyOptional();
1743
+ this._value = t;
1744
+ this._present = true;
1745
+ }
1746
+ clear() {
1747
+ this._value = void 0;
1748
+ this._present = false;
1749
+ }
1750
+ isEmpty() {
1751
+ return !this._present;
1752
+ }
1753
+ isPresent() {
1754
+ return this._present;
1755
+ }
1756
+ ifEmpty(callback) {
1757
+ if (this.isEmpty())
1758
+ callback();
1759
+ }
1760
+ ifPresent(callback) {
1761
+ if (this.isPresent())
1762
+ callback(this.rawValue);
1763
+ }
1764
+ apply(callbackIfPresent, callbackIfEmpty) {
1765
+ if (this.isEmpty()) {
1766
+ callbackIfEmpty();
1767
+ } else {
1768
+ callbackIfPresent(this.rawValue);
1769
+ }
1770
+ }
1771
+ orElse(newValue) {
1772
+ if (this.isEmpty())
1773
+ return _Optional.ofNullable(newValue);
1774
+ return this;
1775
+ }
1776
+ orElseGet(produceValue) {
1777
+ if (this.isEmpty()) {
1778
+ const newValue = produceValue();
1779
+ return _Optional.ofNullable(newValue);
1780
+ }
1781
+ return this;
1782
+ }
1783
+ orElseThrow(produceError) {
1784
+ if (this.isEmpty())
1785
+ throw produceError();
1786
+ return this;
1787
+ }
1788
+ mapTo(mapper) {
1789
+ return this.flatMapTo((t) => _Optional.ofNullable(mapper(t)));
1790
+ }
1791
+ flatMapTo(mapper) {
1792
+ if (this.isPresent()) {
1793
+ const newValue = mapper(this.rawValue);
1794
+ return newValue;
1795
+ }
1796
+ return this;
1797
+ }
1798
+ filter(predicate) {
1799
+ if (this.isPresent()) {
1800
+ if (predicate(this.rawValue)) {
1801
+ return this;
1802
+ } else {
1803
+ return _Optional.empty();
1804
+ }
1805
+ } else {
1806
+ return this;
1807
+ }
1808
+ }
1809
+ static empty() {
1810
+ return new _Optional(void 0);
1811
+ }
1812
+ static of(t) {
1813
+ if (isNullOrUndefined(t))
1814
+ throw new ErrorCannotInstantiatePresentOptionalWithEmptyValue();
1815
+ return new _Optional(t);
1816
+ }
1817
+ static ofNullable(t) {
1818
+ return new _Optional(t);
1819
+ }
1820
+ };
1821
+ var ErrorGetEmptyOptional = class extends Error {
1822
+ constructor() {
1823
+ super("Cannot retrieve a value from an EmptyOptional.");
1824
+ }
1825
+ };
1826
+ var ErrorSetEmptyOptional = class extends Error {
1827
+ constructor() {
1828
+ super("Cannot set a null or undefined value.");
1829
+ }
1830
+ };
1831
+ var ErrorCannotInstantiatePresentOptionalWithEmptyValue = class extends Error {
1832
+ constructor() {
1833
+ super("Cannot initialize a PresentOptional with a null or undefined value.");
1834
+ }
1835
+ };
1836
+
1837
+ // src/sorting/ComparisonChain.ts
1838
+ var defaultCompareValueOptions = {
1839
+ nullsFirst: false,
1840
+ direction: "ASC"
1841
+ };
1842
+ function looseOptionsToStrict(x) {
1843
+ return { ...defaultCompareValueOptions, ...typeof x === "string" ? { direction: x } : x };
1844
+ }
1845
+ function compareValues(a, b, options) {
1846
+ if (a === b)
1847
+ return 0;
1848
+ const nullA = a === null || a === void 0;
1849
+ const nullB = b === null || b === void 0;
1850
+ if (nullA && nullB)
1851
+ return 0;
1852
+ if (nullA !== nullB)
1853
+ return nullA === options.nullsFirst ? -1 : 1;
1854
+ return a < b ? -1 : 1;
1855
+ }
1856
+ function compareFunction(fn, options) {
1857
+ return (a, b) => applyDirection(compareValues(fn(a), fn(b), options), options.direction);
1858
+ }
1859
+ function applyDirection(res, direction) {
1860
+ return res * (direction === "ASC" ? 1 : -1);
1861
+ }
1862
+ function compareUsingGetter(getter, options) {
1863
+ return compareFunction(getter, looseOptionsToStrict(options));
1864
+ }
1865
+ function compareUsingField(field, options) {
1866
+ return compareFunction((t) => t[field], looseOptionsToStrict(options));
1867
+ }
1868
+ function compareUsingNaturalOrder(options) {
1869
+ return compareFunction(identity, looseOptionsToStrict(options));
1870
+ }
1871
+ function compareStrings(options) {
1872
+ return compareFunction((t) => options?.ignoreCase === true ? t.toLowerCase() : t, looseOptionsToStrict(options));
1873
+ }
1874
+ function compareBooleans(options) {
1875
+ const opts = { ...defaultCompareValueOptions, ...options };
1876
+ const fn = (a, b) => {
1877
+ if (a === b)
1878
+ return 0;
1879
+ if (isNullOrUndefined(a)) return opts.nullsFirst ? -1 : 1;
1880
+ if (isNullOrUndefined(b)) return opts.nullsFirst ? 1 : -1;
1881
+ return a === true && opts.truesFirst || a === false && !opts.truesFirst ? -1 : 1;
1882
+ };
1883
+ return (a, b) => applyDirection(fn(a, b), opts.direction);
1884
+ }
1885
+ function compareUsingFunction(fn) {
1886
+ return fn;
1887
+ }
1888
+ function compareUsingSet(arr) {
1889
+ const fn = (a, b) => {
1890
+ if (a === b)
1891
+ return 0;
1892
+ const aIncluded = isDefined(a) && arr.includes(a);
1893
+ const bIncluded = isDefined(b) && arr.includes(b);
1894
+ if (aIncluded === bIncluded) {
1895
+ return 0;
1896
+ } else {
1897
+ return aIncluded ? -1 : 1;
1898
+ }
1899
+ };
1900
+ return fn;
1901
+ }
1902
+ function compareUsingArray(arr) {
1903
+ const fn = (a, b) => {
1904
+ if (a === b)
1905
+ return 0;
1906
+ const aIncluded = isDefined(a) && arr.includes(a);
1907
+ const bIncluded = isDefined(b) && arr.includes(b);
1908
+ if (!aIncluded && !bIncluded) {
1909
+ return 0;
1910
+ } else if (aIncluded && bIncluded) {
1911
+ return arr.indexOf(a) < arr.indexOf(b) ? -1 : 1;
1912
+ } else {
1913
+ return aIncluded ? -1 : 1;
1914
+ }
1915
+ };
1916
+ return fn;
1917
+ }
1918
+ function reverse2(fn) {
1919
+ return (a, b) => fn(a, b) * -1;
1920
+ }
1921
+ var ComparisonChain = class _ComparisonChain {
1922
+ constructor(_fns, _reversed = false) {
1923
+ this._fns = _fns;
1924
+ this._reversed = _reversed;
1925
+ }
1926
+ compare = (a, b) => {
1927
+ return this.doCompare(a, b) * (this._reversed ? -1 : 1);
1928
+ };
1929
+ sort = (arr) => {
1930
+ return [...arr].sort(this.compare);
1931
+ };
1932
+ then(getFn) {
1933
+ const cmp = getFn(createCompare());
1934
+ return this.thenBy(cmp);
1935
+ }
1936
+ thenBy(cmp) {
1937
+ return new _ComparisonChain([...this._fns, getComparisonFunction(cmp)]);
1938
+ }
1939
+ thenChain(transform, getFn) {
1940
+ const cmp = getFn(createCompare());
1941
+ return this.thenChainBy(transform, cmp);
1942
+ }
1943
+ thenChainBy(transform, cmp) {
1944
+ return new _ComparisonChain([...this._fns, applyTransformationBeforeComparison(transform, getComparisonFunction(cmp))]);
1945
+ }
1946
+ reversed() {
1947
+ return new _ComparisonChain([...this._fns], !this._reversed);
1948
+ }
1949
+ doCompare(a, b) {
1950
+ return this._fns.reduce((ret, fn) => {
1951
+ return ret !== 0 ? ret : fn(a, b);
1952
+ }, 0);
1953
+ }
1954
+ static create() {
1955
+ return {
1956
+ using: (getFn) => {
1957
+ return new _ComparisonChain([]).then(getFn);
1958
+ },
1959
+ usingTransformation: (transform, getFn) => {
1960
+ return new _ComparisonChain([]).thenChain(transform, getFn);
1961
+ }
1962
+ };
1963
+ }
1964
+ static createWith(getFn) {
1965
+ return this.create().using(getFn);
1966
+ }
1967
+ static createWithTransformation(transform, getFn) {
1968
+ return this.create().usingTransformation(transform, getFn);
1969
+ }
1970
+ };
1971
+ var ComparisonChain_default = ComparisonChain;
1972
+ function createCompare() {
1973
+ return {
1974
+ compareUsingGetter,
1975
+ compareUsingField,
1976
+ compareUsingStrings: compareStrings,
1977
+ compareUsingStringsIgnoringCase: (options) => compareStrings({ ...looseOptionsToStrict(options), ignoreCase: true }),
1978
+ compareUsingBooleans: compareBooleans,
1979
+ compareUsingNumbers: compareUsingNaturalOrder,
1980
+ compareUsingDates: compareUsingNaturalOrder,
1981
+ compareUsingFunction,
1982
+ placeFirst: (arr) => compareUsingSet(arr),
1983
+ placeFirstInOrder: (arr) => compareUsingArray(arr),
1984
+ placeLast: (arr) => reverse2(compareUsingSet(arr)),
1985
+ placeLastInOrder: (arr) => reverse2(compareUsingArray([...arr].reverse()))
1986
+ };
1987
+ }
1988
+ function applyTransformationBeforeComparison(transform, fn) {
1989
+ return (a, b) => fn(transform(a), transform(b));
1990
+ }
1991
+ function getComparisonFunction(arg) {
1992
+ return arg instanceof ComparisonChain ? arg.compare : arg;
1993
+ }
1994
+
1995
+ // src/sorting/Sorter.ts
1996
+ var defaultCompareValuesOptions = {
1997
+ nullsFirst: false
1998
+ };
1999
+ var defaultCompareFunctionOptions = {
2000
+ ...defaultCompareValuesOptions,
2001
+ direction: "ASC"
2002
+ };
2003
+ var naturalOrderComparison = (a, b) => a < b ? -1 : 1;
2004
+ function compareValues2(a, b, cmp, { nullsFirst }) {
2005
+ if (a === b)
2006
+ return 0;
2007
+ const nullA = isNullOrUndefined(a);
2008
+ const nullB = isNullOrUndefined(b);
2009
+ if (nullA && nullB)
2010
+ return 0;
2011
+ if (nullA !== nullB)
2012
+ return nullA === nullsFirst ? -1 : 1;
2013
+ return cmp(a, b);
2014
+ }
2015
+ function compareFunction2(fn, cmp, { nullsFirst, direction }) {
2016
+ return (a, b) => applyDirection2(compareValues2(fn(a), fn(b), cmp, { nullsFirst }), direction);
2017
+ }
2018
+ function applyDirection2(res, direction) {
2019
+ return res * (direction === "ASC" ? 1 : -1);
2020
+ }
2021
+ function combine(f, g) {
2022
+ return (t) => g(f(t));
2023
+ }
2024
+ function reverse3(fn) {
2025
+ return (a, b) => fn(a, b) * -1;
2026
+ }
2027
+ var chain = (fns, cmpFn) => {
2028
+ return doCreateWithFunctions([...fns, cmpFn]);
2029
+ };
2030
+ var transformAndChain = (fns, transform, cmpFn) => {
2031
+ const fn = (a, b) => cmpFn(transform(a), transform(b));
2032
+ return chain(fns, fn);
2033
+ };
2034
+ var compareStrings2 = (fns, transform, options = {}) => {
2035
+ const { nullsFirst, direction, ignoreCase } = { ...defaultStringComparisonOptions, ...options };
2036
+ if (ignoreCase)
2037
+ transform = combine(transform, (t) => t.toLowerCase());
2038
+ return chain(fns, compareFunction2(transform, naturalOrderComparison, { nullsFirst, direction }));
2039
+ };
2040
+ var compareNumbers = (fns, transform, options = {}) => {
2041
+ const { nullsFirst, direction } = { ...defaultNumberComparisonOptions, ...options };
2042
+ return chain(fns, compareFunction2(transform, naturalOrderComparison, { nullsFirst, direction }));
2043
+ };
2044
+ var compareDates = (fns, transform, options = {}) => {
2045
+ const { nullsFirst, direction } = { ...defaultDateComparisonOptions, ...options };
2046
+ return chain(fns, compareFunction2(transform, naturalOrderComparison, { nullsFirst, direction }));
2047
+ };
2048
+ var compareBooleans2 = (fns, transform, options) => {
2049
+ const { nullsFirst, truesFirst } = { ...defaultBooleanComparisonOptions, ...options };
2050
+ return chain(fns, compareFunction2(transform, naturalOrderComparison, { nullsFirst, direction: truesFirst ? "DESC" : "ASC" }));
2051
+ };
2052
+ var prioritizeSet = (fns, transform, set, reversed = false) => {
2053
+ return compareBooleans2(fns, (t) => {
2054
+ const r = transform(t);
2055
+ return isDefined(r) && set.includes(r);
2056
+ }, { truesFirst: !reversed, nullsFirst: false });
2057
+ };
2058
+ var prioritizeArray = (fns, transform, arr, reversed = false) => {
2059
+ return compareNumbers(fns, (t) => {
2060
+ const r = transform(t);
2061
+ if (!isDefined(r)) return Number.MAX_VALUE;
2062
+ const indexOf = arr.indexOf(r);
2063
+ return indexOf === -1 ? Number.MAX_VALUE : indexOf;
2064
+ }, { direction: reversed ? "DESC" : "ASC", nullsFirst: false });
2065
+ };
2066
+ var next = (fns, transform) => {
2067
+ const using = (transformToX) => {
2068
+ return next(fns, combine(transform, transformToX));
2069
+ };
2070
+ const retAsChainable = {
2071
+ chain(chain2) {
2072
+ return transformAndChain(fns, transform, chain2.compare);
2073
+ }
2074
+ };
2075
+ const retAsUsing = {
2076
+ using
2077
+ };
2078
+ const retAsPrioritizable = {
2079
+ prioritizing(arr, _options = {}) {
2080
+ return prioritizeArray(fns, transform, arr);
2081
+ },
2082
+ deprioritizing(arr, _options = {}) {
2083
+ return prioritizeArray(fns, transform, arr, true);
2084
+ },
2085
+ prioritizingWithEqualWeight(arr, _options = {}) {
2086
+ return prioritizeSet(fns, transform, arr);
2087
+ },
2088
+ deprioritizingWithEqualWeight(arr, _options = {}) {
2089
+ return prioritizeSet(fns, transform, arr, true);
2090
+ }
2091
+ };
2092
+ const retForRecords = {
2093
+ ...retAsUsing,
2094
+ usingStrings: (field) => using((t) => t[field]),
2095
+ usingNumbers: (field) => using((t) => t[field]),
2096
+ usingBooleans: (field) => using((t) => t[field]),
2097
+ usingDates: (field) => using((t) => t[field])
2098
+ };
2099
+ const retForNumbers = {
2100
+ ...retAsUsing,
2101
+ inAscendingOrder(opts = {}) {
2102
+ return compareNumbers(fns, transform, { direction: "ASC", ...opts });
2103
+ },
2104
+ inDescendingOrder(opts = {}) {
2105
+ return compareNumbers(fns, transform, { direction: "DESC", ...opts });
2106
+ }
2107
+ };
2108
+ const retForStrings = {
2109
+ ...retAsUsing,
2110
+ inLexographicalOrder(opts = {}) {
2111
+ return compareStrings2(fns, transform, { direction: "ASC", ignoreCase: false, ...opts });
2112
+ },
2113
+ inLexographicalOrderIgnoringCase(opts = {}) {
2114
+ return compareStrings2(fns, transform, { direction: "ASC", ignoreCase: true, ...opts });
2115
+ },
2116
+ inReverseLexographicalOrder(opts = {}) {
2117
+ return compareStrings2(fns, transform, { direction: "DESC", ignoreCase: false, ...opts });
2118
+ },
2119
+ inReverseLexographicalOrderIgnoringCase(opts = {}) {
2120
+ return compareStrings2(fns, transform, { direction: "DESC", ignoreCase: true, ...opts });
2121
+ }
2122
+ };
2123
+ const retForBooleans = {
2124
+ ...retAsUsing,
2125
+ truesFirst(opts = {}) {
2126
+ return compareBooleans2(fns, transform, { truesFirst: true, ...opts });
2127
+ },
2128
+ falsesFirst(opts = {}) {
2129
+ return compareBooleans2(fns, transform, { truesFirst: false, ...opts });
2130
+ }
2131
+ };
2132
+ const retForDates = {
2133
+ ...retAsUsing,
2134
+ mostAncientFirst(opts = {}) {
2135
+ return compareDates(fns, transform, { direction: "ASC", ...opts });
2136
+ },
2137
+ mostRecentFirst(opts = {}) {
2138
+ return compareDates(fns, transform, { direction: "DESC", ...opts });
2139
+ }
2140
+ };
2141
+ return {
2142
+ ...retAsPrioritizable,
2143
+ ...retAsChainable,
2144
+ ...retForRecords,
2145
+ ...retForNumbers,
2146
+ ...retForStrings,
2147
+ ...retForBooleans,
2148
+ ...retForDates
2149
+ };
2150
+ };
2151
+ var createComparisonFunction = (fns) => {
2152
+ return (a, b) => {
2153
+ let cmp = 0, i = 0;
2154
+ while (i < fns.length && cmp === 0) {
2155
+ cmp = fns[i++](a, b);
2156
+ }
2157
+ return cmp;
2158
+ };
2159
+ };
2160
+ var compare = (fns, a, b) => {
2161
+ return createComparisonFunction(fns)(a, b);
2162
+ };
2163
+ var sort = (fns, arr) => {
2164
+ const comparisonFn = createComparisonFunction(fns);
2165
+ return [...arr].sort(comparisonFn);
2166
+ };
2167
+ var top = (fns, arr, n) => {
2168
+ return sort(fns, arr).slice(0, Math.max(0, n));
2169
+ };
2170
+ var bottom = (fns, arr, n) => {
2171
+ return sort(fns, arr).slice(-Math.max(0, n)).reverse();
2172
+ };
2173
+ var first = (fns, arr) => {
2174
+ return arr.length ? top(fns, arr, 1)[0] : null;
2175
+ };
2176
+ var last2 = (fns, arr) => {
2177
+ return arr.length ? bottom(fns, arr, 1)[0] : null;
2178
+ };
2179
+ function doCreateEmpty() {
2180
+ return next([], (x) => x);
2181
+ }
2182
+ function doCreateWithFunctions(fns) {
2183
+ return {
2184
+ get then() {
2185
+ return next(fns, identity);
2186
+ },
2187
+ reversed() {
2188
+ return doCreateWithFunctions([...fns.map(reverse3)]);
2189
+ },
2190
+ compare: (a, b) => {
2191
+ return compare(fns, a, b);
2192
+ },
2193
+ sort: (arr) => {
2194
+ return sort(fns, arr);
2195
+ },
2196
+ top: (arr, n) => {
2197
+ return top(fns, arr, n);
2198
+ },
2199
+ bottom: (arr, n) => {
2200
+ return bottom(fns, arr, n);
2201
+ },
2202
+ first: (arr) => {
2203
+ return first(fns, arr);
2204
+ },
2205
+ last: (arr) => {
2206
+ return last2(fns, arr);
2207
+ }
2208
+ };
2209
+ }
2210
+ var defaultStringComparisonOptions = { ...defaultCompareFunctionOptions, ignoreCase: false };
2211
+ var defaultNumberComparisonOptions = { ...defaultCompareFunctionOptions };
2212
+ var defaultDateComparisonOptions = { ...defaultCompareFunctionOptions };
2213
+ var defaultBooleanComparisonOptions = { ...defaultCompareValuesOptions };
2214
+ function createSorterFor() {
2215
+ return doCreateEmpty();
2216
+ }
2217
+ var Sorter = {
2218
+ createFor: () => doCreateEmpty(),
2219
+ sort: (arr, builder) => builder(doCreateEmpty()).sort(arr),
2220
+ top: (arr, n, builder) => builder(doCreateEmpty()).top(arr, n),
2221
+ bottom: (arr, n, builder) => builder(doCreateEmpty()).bottom(arr, n),
2222
+ first: (arr, builder) => builder(doCreateEmpty()).first(arr),
2223
+ last: (arr, builder) => builder(doCreateEmpty()).last(arr)
2224
+ };
2225
+ var Sorting = Sorter;
2226
+
2227
+ // src/time/RandomTimeDuration.ts
2228
+ function randomize(unit) {
2229
+ return (a, b) => {
2230
+ return TimeDuration_default.fromMs(randomInterval(unit.toMs(a), unit.toMs(b)));
2231
+ };
2232
+ }
2233
+ var RandomTimeDuration = class {
2234
+ constructor() {
2235
+ }
2236
+ static ms = randomize(TimeUnit.MILLISECONDS);
2237
+ static seconds = randomize(TimeUnit.SECONDS);
2238
+ static minutes = randomize(TimeUnit.MINUTES);
2239
+ static hours = randomize(TimeUnit.HOURS);
2240
+ static days = randomize(TimeUnit.DAYS);
2241
+ };
2242
+
2243
+ // src/time/TimeFrequency.ts
2244
+ var TimeFrequency = class _TimeFrequency {
2245
+ constructor(times, period) {
2246
+ this.times = times;
2247
+ this.period = period;
2248
+ if (isNaN(times) || times <= 0)
2249
+ throw new Error();
2250
+ if (period.isEmpty())
2251
+ throw new Error();
2252
+ }
2253
+ get frequency() {
2254
+ return this.period.divideBy(this.times);
2255
+ }
2256
+ static onceEvery(period) {
2257
+ return new _TimeFrequency(1, period);
2258
+ }
2259
+ static twiceEvery(period) {
2260
+ return new _TimeFrequency(2, period);
2261
+ }
2262
+ };
2263
+
2264
+ // src/upgrade/errors.ts
2265
+ var UnavailableUpgradeError = class extends Error {
2266
+ constructor(data, from, to) {
2267
+ super(`No transition found to upgrade data from version ${from} to version ${to}.`);
2268
+ this.data = data;
2269
+ this.from = from;
2270
+ this.to = to;
2271
+ }
2272
+ };
2273
+ var EmptyUpgradeError = class extends Error {
2274
+ constructor(data, from, to) {
2275
+ super(`Transition from version ${from} to version ${to} resulted in empty data`);
2276
+ this.data = data;
2277
+ this.from = from;
2278
+ this.to = to;
2279
+ }
2280
+ };
2281
+
2282
+ // src/upgrade/getTransitionsPath.ts
2283
+ var DEBUG_ENABLED = false;
2284
+ function getTransitionsPath(matrix, from, to) {
2285
+ return internalGetTransitionsPath(matrix, from, to, 0, DEBUG_ENABLED);
2286
+ }
2287
+ function internalGetTransitionsPath(matrix, from, to, depth, debug) {
2288
+ debugLog(debug, depth, from, to, "Search started.");
2289
+ const transitionsTo = matrix[to];
2290
+ if (!transitionsTo) {
2291
+ debugLog(debug, depth, from, to, "No transitions available to this version");
2292
+ return null;
2293
+ }
2294
+ const exactTransition = transitionsTo[from];
2295
+ if (exactTransition) {
2296
+ debugLog(debug, depth, from, to, "Found exact transition.");
2297
+ return [exactTransition];
2298
+ }
2299
+ const keys = Object.keys(transitionsTo);
2300
+ return keys.reduce((curBestPath, transitionKey) => {
2301
+ const transition = transitionsTo[transitionKey];
2302
+ const path = internalGetTransitionsPath(matrix, from, transition.from, depth + 1, debug);
2303
+ if (path === null) {
2304
+ debugLog(debug, depth + 1, from, transition.from, "No path found.");
2305
+ return curBestPath;
2306
+ } else {
2307
+ if (curBestPath === null || curBestPath.length > path.length + 1) {
2308
+ debugLog(debug, depth + 1, from, transition.from, "New best path found: " + printTransitions(path));
2309
+ return [...path, transition];
2310
+ } else {
2311
+ return curBestPath;
2312
+ }
2313
+ }
2314
+ }, null);
2315
+ }
2316
+ function debugLog(enabled, depth, from, to, message) {
2317
+ if (!enabled)
2318
+ return;
2319
+ console.info(
2320
+ "#".repeat(depth + 1),
2321
+ from + " -> " + to,
2322
+ message
2323
+ );
2324
+ }
2325
+ function printTransitions(transitions) {
2326
+ return transitions.reduce((ret, cur) => {
2327
+ return ret + " -> " + cur.to;
2328
+ }, "" + transitions[0].from);
2329
+ }
2330
+
2331
+ // src/upgrade/DataUpgrader.ts
2332
+ var VERSION_FIELD = "$version";
2333
+ var DataUpgrader = class _DataUpgrader {
2334
+ constructor(latestVersion) {
2335
+ this.latestVersion = latestVersion;
2336
+ }
2337
+ transitions = {};
2338
+ addTransition(from, to, apply) {
2339
+ if (from === void 0 || from < 0)
2340
+ throw new Error(`Invalid argument from, non-negative number expected, got: ${from}`);
2341
+ if (to === void 0 || to <= 0)
2342
+ throw new Error(`Invalid argument to, positive number expected, got: ${to}`);
2343
+ if (to <= from)
2344
+ throw new Error(`Invalid argument to, expected number greater than ${from}, got: ${to}`);
2345
+ if (to > this.latestVersion)
2346
+ throw new Error(`Invalid argument to, expected number lower than ${this.latestVersion}, got: ${to}`);
2347
+ if (this.transitions[to]?.[from])
2348
+ throw new Error(`Invalid transition arguments, duplicated transition found from ${from} to ${to}`);
2349
+ const toMatrix = this.transitions[to] ?? {};
2350
+ toMatrix[from] = { from, to, apply };
2351
+ this.transitions[to] = toMatrix;
2352
+ return this;
2353
+ }
2354
+ async upgrade(data) {
2355
+ if (!data || typeof data !== "object")
2356
+ throw new Error(`Invalid argument data, object expected, got: ${typeof data}.`);
2357
+ if (data.$version === null || data.$version === void 0 || typeof data.$version !== "number")
2358
+ throw new Error(`Invalid argument data, version metadata required, got: ${data.$version}`);
2359
+ if (data.$version > this.latestVersion)
2360
+ throw new Error(`Invalid argument data, version metadata is in the future: ${data.$version}, current: ${this.latestVersion}`);
2361
+ if (this.isLatestVersion(data))
2362
+ return data;
2363
+ const from = data.$version;
2364
+ const to = this.latestVersion;
2365
+ const path = getTransitionsPath(this.transitions, from, to);
2366
+ if (path === null)
2367
+ throw new UnavailableUpgradeError(data, from, to);
2368
+ let current = jsonCloneDeep(data);
2369
+ for (const transition of path) {
2370
+ const next2 = await transition.apply(current);
2371
+ if (next2 === null || next2 === void 0)
2372
+ throw new EmptyUpgradeError(current, from, to);
2373
+ current = next2;
2374
+ }
2375
+ return current;
2376
+ }
2377
+ isLatestVersion(data) {
2378
+ return data.$version === this.latestVersion;
2379
+ }
2380
+ static create(latest) {
2381
+ return new _DataUpgrader(latest);
2382
+ }
2383
+ static Errors = {
2384
+ EmptyUpgrade: EmptyUpgradeError,
2385
+ UnavailableUpgrade: UnavailableUpgradeError
2386
+ };
2387
+ };
2388
+ function isUpgradable(obj) {
2389
+ return isDefined(obj) && typeof obj === "object" && VERSION_FIELD in obj && isNumber(obj.$version) && isPositiveNumber(obj.$version);
2390
+ }
2391
+ export {
2392
+ ComparisonChain_default as ComparisonChain,
2393
+ DataUpgrader,
2394
+ Deferred,
2395
+ DeferredCanceledError,
2396
+ ErrorCannotInstantiatePresentOptionalWithEmptyValue,
2397
+ ErrorGetEmptyOptional,
2398
+ ErrorSetEmptyOptional,
2399
+ Lazy,
2400
+ LazyAsync,
2401
+ Logger,
2402
+ Optional,
2403
+ RandomTimeDuration,
2404
+ RateThrottler,
2405
+ Semaphore,
2406
+ Sorter,
2407
+ Sorting,
2408
+ StringParts,
2409
+ TimeDuration,
2410
+ TimeFrequency,
2411
+ TimeInstant,
2412
+ TimeUnit,
2413
+ asError,
2414
+ asPromise,
2415
+ average,
2416
+ bindThis,
2417
+ capitalizeWord,
2418
+ clamp,
2419
+ constant,
2420
+ constantFalse,
2421
+ constantNull,
2422
+ constantOne,
2423
+ constantTrue,
2424
+ constantZero,
2425
+ createSorterFor,
2426
+ decrement,
2427
+ decrementBy,
2428
+ delayPromise,
2429
+ dictToEntries,
2430
+ dictToList,
2431
+ divideBy,
2432
+ ensureArray,
2433
+ ensureDefined,
2434
+ ensureNegativeNumber,
2435
+ ensureNonNegativeNumber,
2436
+ ensureNonPositiveNumber,
2437
+ ensurePositiveNumber,
2438
+ ensureReadableArray,
2439
+ entriesToDict,
2440
+ extendArray,
2441
+ extendArrayWith,
2442
+ fill,
2443
+ filterTruthy,
2444
+ groupByNumber,
2445
+ groupByNumberWith,
2446
+ groupByString,
2447
+ groupByStringWith,
2448
+ groupBySymbol,
2449
+ groupBySymbolWith,
2450
+ hashCode,
2451
+ head,
2452
+ identity,
2453
+ ifDefined,
2454
+ ifNullOrUndefined,
2455
+ iff,
2456
+ includes,
2457
+ increment,
2458
+ incrementBy,
2459
+ indexByNumber,
2460
+ indexByNumberWith,
2461
+ indexByString,
2462
+ indexByStringWith,
2463
+ indexBySymbol,
2464
+ indexBySymbolWith,
2465
+ isAllowedTimeDuration,
2466
+ isArray,
2467
+ isDefined,
2468
+ isFalse,
2469
+ isFunction,
2470
+ isNegativeNumber,
2471
+ isNullOrUndefined,
2472
+ isNumber,
2473
+ isPositiveNumber,
2474
+ isTimeInstant,
2475
+ isTrue,
2476
+ isUpgradable,
2477
+ isZero,
2478
+ jsonCloneDeep,
2479
+ last,
2480
+ mapDefined,
2481
+ mapEntries,
2482
+ max,
2483
+ maxBy,
2484
+ min,
2485
+ minBy,
2486
+ multiplyBy,
2487
+ noop,
2488
+ omit,
2489
+ pad,
2490
+ pick,
2491
+ pluralize,
2492
+ promiseSequence,
2493
+ randomInterval,
2494
+ randomPercentage,
2495
+ range,
2496
+ repeat,
2497
+ reverse,
2498
+ round,
2499
+ roundAwayFromZero,
2500
+ roundToLower,
2501
+ roundToNearest,
2502
+ roundToUpper,
2503
+ roundTowardsZero,
2504
+ sortBy,
2505
+ sortedArray,
2506
+ splitWords,
2507
+ stringToNumber,
2508
+ sum,
2509
+ sumBy,
2510
+ throttle,
2511
+ uniq,
2512
+ uniqBy,
2513
+ uniqByKey,
2514
+ upsert,
2515
+ withTryCatch,
2516
+ withTryCatchAsync,
2517
+ wrap
2518
+ };