qznt 1.0.37 → 2.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.
package/dist/index.js CHANGED
@@ -1,47 +1,251 @@
1
- var __defProp = Object.defineProperty;
2
- var __export = (target, all) => {
3
- for (var name in all)
4
- __defProp(target, name, { get: all[name], enumerable: true });
1
+ // src/Cache.ts
2
+ var Cache = class {
3
+ cache = /* @__PURE__ */ new Map();
4
+ interval;
5
+ /**
6
+ * A lightweight, high-performant in-memory cache.
7
+ * Uses Map for O(1) lookups and an optional cleanup interval.
8
+ * @param cleanupMs The interval in milliseconds to run the cleanup function. [default: 60000 (1 minute)]
9
+ */
10
+ constructor(cleanupMs = 6e4) {
11
+ if (cleanupMs > 0) {
12
+ this.interval = setInterval(() => this.cleanup(), cleanupMs);
13
+ if (this.interval.unref) this.interval.unref();
14
+ }
15
+ }
16
+ set(key, value, ttlMs) {
17
+ this.cache.set(key, {
18
+ value,
19
+ expiresAt: ttlMs ? Date.now() + ttlMs : null
20
+ });
21
+ }
22
+ get(key) {
23
+ const data = this.cache.get(key);
24
+ if (!data) return null;
25
+ if (data.expiresAt && Date.now() > data.expiresAt) {
26
+ this.cache.delete(key);
27
+ return null;
28
+ }
29
+ return data.value;
30
+ }
31
+ cleanup() {
32
+ if (this.cache.size === 0) return;
33
+ const now = Date.now();
34
+ let keysProcessed = 0;
35
+ const maxKeysToScan = 20;
36
+ for (const [key, data] of this.cache) {
37
+ if (data.expiresAt && now > data.expiresAt) {
38
+ this.cache.delete(key);
39
+ }
40
+ keysProcessed++;
41
+ if (keysProcessed >= maxKeysToScan) break;
42
+ }
43
+ }
44
+ clear() {
45
+ this.cache.clear();
46
+ }
5
47
  };
6
48
 
7
- // src/arr.ts
8
- var arr_exports = {};
9
- __export(arr_exports, {
10
- chunk: () => chunk,
11
- chunkAdj: () => chunkAdj,
12
- cluster: () => cluster,
13
- compact: () => compact,
14
- forceArray: () => forceArray,
15
- search: () => search,
16
- seqMap: () => seqMap,
17
- shuffle: () => shuffle,
18
- sortBy: () => sortBy,
19
- unique: () => unique
20
- });
49
+ // src/Loop.ts
50
+ import EventEmitter from "events";
51
+ var TypedEmitterBase = EventEmitter;
52
+ var Loop = class extends TypedEmitterBase {
53
+ _state = "stopped";
54
+ timeoutId = null;
55
+ delay;
56
+ fn;
57
+ startTime = 0;
58
+ remaining = 0;
59
+ async run() {
60
+ const currentState = this._state;
61
+ if (currentState === "stopped" || currentState === "paused") return;
62
+ try {
63
+ const result = await this.fn(this);
64
+ this.emit("tick", result);
65
+ } catch (err) {
66
+ this.emit("error", err);
67
+ }
68
+ if (this._state === "running") {
69
+ this.startTime = Date.now();
70
+ this.remaining = 0;
71
+ this.clearTimer();
72
+ this.timeoutId = setTimeout(() => this.run(), this.delay);
73
+ }
74
+ }
75
+ clearTimer() {
76
+ if (this.timeoutId) {
77
+ clearTimeout(this.timeoutId);
78
+ this.timeoutId = null;
79
+ }
80
+ }
81
+ /**
82
+ * Creates an interval. If the function is async, it will wait for it to complete before scheduling the next run.
83
+ * @param fn The function to run.
84
+ * @param delay The delay between runs in milliseconds.
85
+ * @param immediate Whether to start the loop immediately. [default: true]
86
+ */
87
+ constructor(fn, delay, immediate = true) {
88
+ super();
89
+ this.fn = fn;
90
+ this.delay = delay;
91
+ if (immediate) this.start();
92
+ }
93
+ get state() {
94
+ return this._state;
95
+ }
96
+ /** Starts the loop. */
97
+ start() {
98
+ if (this._state !== "stopped") return;
99
+ this._state = "running";
100
+ this.emit("start");
101
+ this.run();
102
+ }
103
+ /** Resumes a paused loop. */
104
+ resume() {
105
+ if (this._state !== "paused") return;
106
+ this._state = "running";
107
+ this.emit("resume");
108
+ if (this.remaining <= 0) {
109
+ this.run();
110
+ } else {
111
+ this.timeoutId = setTimeout(() => this.run(), this.remaining);
112
+ }
113
+ }
114
+ /** Stops the loop. */
115
+ stop() {
116
+ const wasRunning = this._state !== "stopped";
117
+ this._state = "stopped";
118
+ this.remaining = 0;
119
+ this.clearTimer();
120
+ if (wasRunning) this.emit("stop");
121
+ }
122
+ /** Pauses the execution. */
123
+ pause() {
124
+ if (this._state !== "running") return;
125
+ this._state = "paused";
126
+ const elapsed = Date.now() - this.startTime;
127
+ this.remaining = Math.max(0, this.delay - elapsed);
128
+ this.emit("pause", { remaining: this.remaining });
129
+ this.clearTimer();
130
+ }
131
+ /**
132
+ * Sets the delay between runs
133
+ * @param ms The new delay in milliseconds.
134
+ */
135
+ setDelay(ms) {
136
+ this.delay = ms;
137
+ }
138
+ /** Manually trigger the function once without affecting the loop. */
139
+ async execute() {
140
+ await this.fn(this);
141
+ }
142
+ };
143
+
144
+ // src/Pipe.ts
145
+ function Pipe(value, ...fns) {
146
+ return fns.reduce((acc, fn) => fn(acc), value);
147
+ }
148
+
149
+ // src/Storage.ts
150
+ import fs from "fs";
151
+ import path from "path";
152
+ var Storage = class {
153
+ isNode = typeof window === "undefined";
154
+ filePath = null;
155
+ memoryCache = /* @__PURE__ */ new Map();
156
+ loadFromFile() {
157
+ if (this.filePath && fs.existsSync(this.filePath)) {
158
+ try {
159
+ const data = JSON.parse(fs.readFileSync(this.filePath, "utf-8"));
160
+ Object.entries(data).forEach(([k, v]) => this.memoryCache.set(k, JSON.stringify(v)));
161
+ } catch (err) {
162
+ console.error(`Store: Failed to load file '${this.filePath}'`, err);
163
+ }
164
+ }
165
+ }
166
+ persist() {
167
+ if (this.isNode && this.filePath) {
168
+ const out = {};
169
+ this.memoryCache.forEach((v, k) => out[k] = JSON.parse(v));
170
+ fs.writeFileSync(this.filePath, JSON.stringify(out, null, 2));
171
+ }
172
+ }
173
+ /**
174
+ * A lightweight, high-performant persistent storage system.
175
+ * Uses JSON files in Node.js, localStorage in the browser
176
+ * @param fileName Only used in Node.js to create a persistent .json file
177
+ * @param directory The directory for the file. Defaults to current working directory
178
+ */
179
+ constructor(fileName, directory = process.cwd()) {
180
+ if (this.isNode && fileName) {
181
+ this.filePath = path.join(directory, fileName.endsWith(".json") ? fileName : `${fileName}.json`);
182
+ this.loadFromFile();
183
+ }
184
+ }
185
+ has(key) {
186
+ if (!this.isNode && window.localStorage) {
187
+ return localStorage.getItem(key) !== null;
188
+ }
189
+ return this.memoryCache.has(key);
190
+ }
191
+ get(key) {
192
+ let raw = null;
193
+ if (!this.isNode && window.localStorage) {
194
+ raw = localStorage.getItem(key);
195
+ } else {
196
+ raw = this.memoryCache.get(key) || null;
197
+ }
198
+ if (!raw) return null;
199
+ const payload = JSON.parse(raw);
200
+ if (payload.expiry && Date.now() > payload.expiry) {
201
+ this.remove(key);
202
+ this.persist();
203
+ return null;
204
+ }
205
+ return payload.value;
206
+ }
207
+ set(key, value, ttl) {
208
+ const payload = {
209
+ value,
210
+ expiry: ttl ? Date.now() + ttl : null
211
+ };
212
+ const serialized = JSON.stringify(payload);
213
+ if (!this.isNode && window.localStorage) {
214
+ localStorage.setItem(key, serialized);
215
+ } else {
216
+ this.memoryCache.set(key, serialized);
217
+ this.persist();
218
+ }
219
+ }
220
+ remove(key) {
221
+ if (!this.isNode && window.localStorage) {
222
+ localStorage.removeItem(key);
223
+ } else {
224
+ this.memoryCache.delete(key);
225
+ this.persist();
226
+ }
227
+ }
228
+ clear() {
229
+ if (!this.isNode && window.localStorage) {
230
+ localStorage.clear();
231
+ } else {
232
+ this.memoryCache.clear();
233
+ this.persist();
234
+ }
235
+ }
236
+ };
21
237
 
22
- // src/rnd.ts
23
- var rnd_exports = {};
24
- __export(rnd_exports, {
25
- chance: () => chance,
26
- choice: () => choice,
27
- float: () => float,
28
- index: () => index,
29
- int: () => int,
30
- prng: () => prng,
31
- sampler: () => sampler,
32
- str: () => str,
33
- weighted: () => weighted
34
- });
238
+ // src/random.ts
35
239
  var LOWER = "abcdefghijklmnopqrstuvwxyz";
36
240
  var UPPER = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
37
241
  var NUM = "0123456789";
38
- function chance(percent2 = 0.5, seed) {
242
+ function rndChance(percent2 = 0.5, seed) {
39
243
  if (percent2 <= 0) return false;
40
244
  if (percent2 >= 1) return true;
41
245
  const random = seed !== void 0 ? prng(seed) : Math.random;
42
246
  return random() < percent2;
43
247
  }
44
- function choice(array, options = {}) {
248
+ function rndChoice(array, options = {}) {
45
249
  const { seed, not, maxRerolls = 10 } = options;
46
250
  const random = seed !== void 0 ? prng(seed) : Math.random;
47
251
  const rnd = () => array[Math.floor(random() * array.length)];
@@ -56,19 +260,19 @@ function choice(array, options = {}) {
56
260
  }
57
261
  return result;
58
262
  }
59
- function weighted(array, selector, seed) {
263
+ function weightedRnd(array, predicate, seed) {
60
264
  const random = seed !== void 0 ? prng(seed) : Math.random;
61
265
  const cumulativeWeights = [];
62
266
  let currentSum = 0;
63
267
  for (const item of array) {
64
- const weight = selector(item);
268
+ const weight = predicate(item);
65
269
  currentSum += weight;
66
270
  cumulativeWeights.push(currentSum);
67
271
  }
68
272
  const decider = random() * currentSum;
69
- let index2;
273
+ let index;
70
274
  if (array.length < 20) {
71
- index2 = cumulativeWeights.findIndex((w) => w >= decider);
275
+ index = cumulativeWeights.findIndex((w) => w >= decider);
72
276
  } else {
73
277
  let low = 0;
74
278
  let high = cumulativeWeights.length - 1;
@@ -80,16 +284,16 @@ function weighted(array, selector, seed) {
80
284
  high = mid;
81
285
  }
82
286
  }
83
- index2 = low;
287
+ index = low;
84
288
  }
85
- return array[index2];
289
+ return array[index];
86
290
  }
87
- function sampler(items, selector, seed) {
291
+ function createSampler(items, predicate, seed) {
88
292
  const callRandom = seed ? prng(seed) : void 0;
89
293
  const len = items.length;
90
294
  const prob = new Array(len);
91
295
  const alias = new Array(len);
92
- const weights = items.map(selector);
296
+ const weights = items.map(predicate);
93
297
  const totalWeight = weights.reduce((a, b) => a + b, 0);
94
298
  const scaledWeights = weights.map((w) => w * len / totalWeight);
95
299
  const small = [];
@@ -107,8 +311,8 @@ function sampler(items, selector, seed) {
107
311
  while (small.length) prob[small.pop()] = 1;
108
312
  return {
109
313
  /**
110
- * Returns a random item from the given array in O(1) time.
111
- * @param seed Optional seed for RNG.
314
+ * Returns a random item from the given array in O(1) time
315
+ * @param seed Optional seed for RNG
112
316
  */
113
317
  pick: (seed2) => {
114
318
  const random = seed2 !== void 0 ? prng(seed2) : callRandom || Math.random;
@@ -125,11 +329,11 @@ function prng(seed) {
125
329
  return ((t ^ t >>> 14) >>> 0) / 4294967296;
126
330
  };
127
331
  }
128
- function float(min, max, seed) {
332
+ function rndFloat(min, max, seed) {
129
333
  const random = seed !== void 0 ? prng(seed) : Math.random;
130
334
  return random() * (max - min) + min;
131
335
  }
132
- function index(array, options = {}) {
336
+ function rndIndex(array, options = {}) {
133
337
  const { seed, not, maxRerolls = 10 } = options;
134
338
  const random = seed !== void 0 ? prng(seed) : Math.random;
135
339
  const rnd = () => Math.floor(random() * array.length);
@@ -144,11 +348,11 @@ function index(array, options = {}) {
144
348
  }
145
349
  return result;
146
350
  }
147
- function int(min, max, seed) {
351
+ function rndInt(min, max, seed) {
148
352
  const random = seed !== void 0 ? prng(seed) : Math.random;
149
353
  return Math.floor(random() * (max - min + 1)) + min;
150
354
  }
151
- function str(len, mode, options = {}) {
355
+ function rndString(len, mode, options = {}) {
152
356
  const { casing = "lower", seed, customChars = "", exclude = "" } = options;
153
357
  const random = seed !== void 0 ? prng(seed) : Math.random;
154
358
  const alphaPool = { lower: LOWER, upper: UPPER, mixed: LOWER + UPPER }[casing];
@@ -217,7 +421,7 @@ function cluster(array, iteratee, maxChunkSize) {
217
421
  }
218
422
  return result;
219
423
  }
220
- function compact(array, mode = "nullable") {
424
+ function compactArray(array, mode = "nullable") {
221
425
  if (mode === "falsy") {
222
426
  return array.filter(Boolean);
223
427
  }
@@ -226,7 +430,7 @@ function compact(array, mode = "nullable") {
226
430
  function forceArray(item) {
227
431
  return Array.isArray(item) ? item : [item];
228
432
  }
229
- function search(array, target, comparator = (a, b) => a > b ? 1 : a < b ? -1 : 0) {
433
+ function searchSorted(array, target, comparator = (a, b) => a > b ? 1 : a < b ? -1 : 0) {
230
434
  let low = 0;
231
435
  let high = array.length - 1;
232
436
  while (low <= high) {
@@ -289,13 +493,8 @@ function unique(array, key) {
289
493
  }
290
494
 
291
495
  // src/async.ts
292
- var async_exports = {};
293
- __export(async_exports, {
294
- retry: () => retry,
295
- wait: () => wait
296
- });
297
- async function retry(fn, options = {}) {
298
- const { retries = 3, delay = 500, timeout, signal } = options;
496
+ async function retryPromise(fn, options = {}) {
497
+ const { attempts = 3, delay = 500, timeout, signal } = options;
299
498
  if (signal?.aborted) throw new Error("Operation aborted");
300
499
  const executeWithTimeout = async () => {
301
500
  if (!timeout) return fn(signal);
@@ -314,7 +513,7 @@ async function retry(fn, options = {}) {
314
513
  return await executeWithTimeout();
315
514
  } catch (error) {
316
515
  if (signal?.aborted) throw error;
317
- if (retries <= 0) throw error;
516
+ if (attempts <= 0) throw error;
318
517
  const jitter = Math.random() * 200;
319
518
  const totalDelay = delay + jitter;
320
519
  await new Promise((resolve, reject) => {
@@ -328,51 +527,14 @@ async function retry(fn, options = {}) {
328
527
  { once: true }
329
528
  );
330
529
  });
331
- return retry(fn, { ...options, retries: retries - 1, delay: delay * 2 });
530
+ return retryPromise(fn, { ...options, attempts: attempts - 1, delay: delay * 2 });
332
531
  }
333
532
  }
334
- function wait(ms2) {
335
- return new Promise(
336
- (resolve) => setTimeout(() => {
337
- resolve(true);
338
- }, ms2)
339
- );
340
- }
341
-
342
- // src/fn.ts
343
- var fn_exports = {};
344
- __export(fn_exports, {
345
- memoize: () => memoize
346
- });
347
- function memoize(fn, options = {}) {
348
- const cache = /* @__PURE__ */ new Map();
349
- const { resolver, maxAge } = options;
350
- const memoized = function(...args) {
351
- const key = resolver ? resolver(...args) : JSON.stringify(args);
352
- const now = Date.now();
353
- const entry = cache.get(key);
354
- if (entry) {
355
- if (!maxAge || now - entry.timestamp < maxAge) {
356
- return entry.value;
357
- }
358
- cache.delete(key);
359
- }
360
- const result = fn.apply(this, args);
361
- cache.set(key, { value: result, timestamp: now });
362
- return result;
363
- };
364
- memoized.clear = () => cache.clear();
365
- return memoized;
533
+ function wait(ms) {
534
+ return new Promise((resolve) => setTimeout(() => resolve(true), ms));
366
535
  }
367
536
 
368
537
  // src/date.ts
369
- var date_exports = {};
370
- __export(date_exports, {
371
- duration: () => duration,
372
- eta: () => eta,
373
- getAge: () => getAge,
374
- parse: () => parse
375
- });
376
538
  var MS_MAP = {
377
539
  ms: 1,
378
540
  s: 1e3,
@@ -383,64 +545,18 @@ var MS_MAP = {
383
545
  mth: 24192e5,
384
546
  y: 31536e6
385
547
  };
386
- function duration(target, style = "hms", options = {}) {
387
- const targetMs = target instanceof Date ? target.getTime() : Number(target);
388
- const sinceMs = options.since instanceof Date ? options.since.getTime() : Number(options.since) || Date.now();
389
- const diff = Math.abs(targetMs - sinceMs);
390
- if (diff === 0) return style === "digital" ? "00:00" : "now";
391
- const s = Math.floor(diff / 1e3) % 60;
392
- const m = Math.floor(diff / 6e4) % 60;
393
- const h = Math.floor(diff / 36e5) % 24;
394
- const d = Math.floor(diff / 864e5);
395
- if (style === "digital") {
396
- const parts = [m, s].map((v) => String(v).padStart(2, "0"));
397
- if (h > 0 || d > 0) parts.unshift(String(h).padStart(2, "0"));
398
- if (d > 0) parts.unshift(String(d));
399
- return parts.join(":");
400
- }
401
- const result = [];
402
- const push = (val, label) => {
403
- if (val > 0) result.push(`${val} ${label}${val === 1 ? "" : "s"}`);
404
- };
405
- if (style === "ymdhms") push(d, "day");
406
- push(h, "hour");
407
- push(m, "minute");
408
- push(s, "second");
409
- if (result.length === 0) return "0 seconds";
410
- if (result.length === 1) return result[0];
411
- const last = result.pop();
412
- return `${result.join(", ")} and ${last}`;
413
- }
414
- function eta(date, locale) {
415
- const rtf = new Intl.RelativeTimeFormat(locale, { numeric: "auto" });
416
- const elapsed = (typeof date === "number" ? date : date.getTime()) - Date.now();
417
- const units = [
418
- { unit: "year", ms: 31536e6 },
419
- { unit: "month", ms: 2628e6 },
420
- { unit: "day", ms: 864e5 },
421
- { unit: "hour", ms: 36e5 },
422
- { unit: "minute", ms: 6e4 },
423
- { unit: "second", ms: 1e3 }
424
- ];
425
- for (const { unit, ms: ms2 } of units) {
426
- if (Math.abs(elapsed) >= ms2 || unit === "second") {
427
- return rtf.format(Math.round(elapsed / ms2), unit);
428
- }
429
- }
430
- return "";
431
- }
432
548
  function getAge(birthdate) {
433
- const today2 = /* @__PURE__ */ new Date();
434
- let age = today2.getFullYear() - birthdate.getFullYear();
435
- const monthDiff = today2.getMonth() - birthdate.getMonth();
436
- if (monthDiff < 0 || monthDiff === 0 && today2.getDate() < birthdate.getDate()) {
549
+ const today = /* @__PURE__ */ new Date();
550
+ let age = today.getFullYear() - birthdate.getFullYear();
551
+ const monthDiff = today.getMonth() - birthdate.getMonth();
552
+ if (monthDiff < 0 || monthDiff === 0 && today.getDate() < birthdate.getDate()) {
437
553
  age--;
438
554
  }
439
555
  return age;
440
556
  }
441
- function parse(str2, options = {}) {
442
- if (typeof str2 === "number") return str2;
443
- const matches = str2.matchAll(/(-?\d+)([a-z]+)/gi);
557
+ function parseTime(str, options = {}) {
558
+ if (typeof str === "number") return str;
559
+ const matches = str.matchAll(/(-?\d+)([a-z]+)/gi);
444
560
  let totalMs = 0;
445
561
  let found = false;
446
562
  for (const [_, value, unit] of matches) {
@@ -451,39 +567,85 @@ function parse(str2, options = {}) {
451
567
  found = true;
452
568
  }
453
569
  }
454
- if (!found) throw new Error(`parse: Invalid time format: "${str2}"`);
570
+ if (!found) throw new Error(`parse: Invalid time format: "${str}"`);
455
571
  const result = options.unit === "s" ? totalMs / 1e3 : totalMs;
456
572
  return options.fromNow ? Date.now() + result : result;
457
573
  }
458
574
 
575
+ // src/exec.ts
576
+ function debounce(fn, wait2, options = {}) {
577
+ let timeoutId;
578
+ const leading = options.immediate ?? false;
579
+ const debounced = function(...args) {
580
+ const callNow = leading && !timeoutId;
581
+ if (timeoutId) clearTimeout(timeoutId);
582
+ timeoutId = setTimeout(() => {
583
+ timeoutId = void 0;
584
+ if (!leading) fn.apply(this, args);
585
+ }, wait2);
586
+ if (callNow) fn.apply(this, args);
587
+ };
588
+ debounced.cancel = () => {
589
+ if (timeoutId) {
590
+ clearTimeout(timeoutId);
591
+ timeoutId = void 0;
592
+ }
593
+ };
594
+ return debounced;
595
+ }
596
+ function throttle(fn, limit) {
597
+ let inThrottle = false;
598
+ return function(...args) {
599
+ if (!inThrottle) {
600
+ fn.apply(this, args);
601
+ inThrottle = true;
602
+ setTimeout(() => inThrottle = false, limit);
603
+ }
604
+ };
605
+ }
606
+
607
+ // src/fn.ts
608
+ function memoize(fn, options = {}) {
609
+ const cache = /* @__PURE__ */ new Map();
610
+ const { resolver, maxAge } = options;
611
+ const memoized = function(...args) {
612
+ const key = resolver ? resolver(...args) : JSON.stringify(args);
613
+ const now = Date.now();
614
+ const entry = cache.get(key);
615
+ if (entry) {
616
+ if (!maxAge || now - entry.timestamp < maxAge) {
617
+ return entry.value;
618
+ }
619
+ cache.delete(key);
620
+ }
621
+ const result = fn.apply(this, args);
622
+ cache.set(key, { value: result, timestamp: now });
623
+ return result;
624
+ };
625
+ memoized.clear = () => cache.clear();
626
+ return memoized;
627
+ }
628
+
459
629
  // src/format.ts
460
- var format_exports = {};
461
- __export(format_exports, {
462
- compactNumber: () => compactNumber,
463
- currency: () => currency,
464
- memory: () => memory,
465
- number: () => number,
466
- ordinal: () => ordinal
467
- });
468
- function currency(num, options = {}) {
630
+ function formatCurrency(num, options = {}) {
469
631
  return new Intl.NumberFormat(options.locale, {
470
632
  style: "currency",
471
633
  currency: options.currency
472
634
  }).format(num);
473
635
  }
474
- function number(num, options = {}) {
636
+ function formatNumber(num, options = {}) {
475
637
  return new Intl.NumberFormat(options.locale, {
476
638
  minimumFractionDigits: options.precision,
477
639
  maximumFractionDigits: options.precision
478
640
  }).format(num);
479
641
  }
480
- function memory(bytes, decimals = 1, units = ["B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"]) {
642
+ function formatMemory(bytes, decimals = 1, units = ["B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"]) {
481
643
  if (bytes <= 0) return `0 ${units[0]}`;
482
644
  const i = Math.min(Math.floor(Math.log(bytes) / Math.log(1024)), units.length - 1);
483
645
  const val = bytes / Math.pow(1024, i);
484
646
  return `${val.toFixed(i === 0 ? 0 : decimals)} ${units[i]}`;
485
647
  }
486
- function ordinal(num, locale) {
648
+ function formatOrdinal(num, locale) {
487
649
  const _num = Number(num);
488
650
  if (isNaN(_num)) throw new TypeError("Invalid input");
489
651
  const pr = new Intl.PluralRules(locale, { type: "ordinal" });
@@ -497,19 +659,61 @@ function ordinal(num, locale) {
497
659
  const suffix = suffixes[rule] || "th";
498
660
  return _num.toLocaleString(locale) + suffix;
499
661
  }
500
- function compactNumber(num, locale) {
662
+ function FormatNumberCompact(num, locale) {
501
663
  return new Intl.NumberFormat(locale, {
502
664
  notation: "compact",
503
665
  compactDisplay: "short",
504
666
  maximumFractionDigits: 1
505
667
  }).format(num);
506
668
  }
669
+ function formatDuration(target, style = "hms", options = {}) {
670
+ const targetMs = target instanceof Date ? target.getTime() : Number(target);
671
+ const sinceMs = options.since instanceof Date ? options.since.getTime() : Number(options.since) || Date.now();
672
+ const diff = Math.abs(targetMs - sinceMs);
673
+ if (diff === 0) return style === "digital" ? "00:00" : "now";
674
+ const s = Math.floor(diff / 1e3) % 60;
675
+ const m = Math.floor(diff / 6e4) % 60;
676
+ const h = Math.floor(diff / 36e5) % 24;
677
+ const d = Math.floor(diff / 864e5);
678
+ if (style === "digital") {
679
+ const parts = [m, s].map((v) => String(v).padStart(2, "0"));
680
+ if (h > 0 || d > 0) parts.unshift(String(h).padStart(2, "0"));
681
+ if (d > 0) parts.unshift(String(d));
682
+ return parts.join(":");
683
+ }
684
+ const result = [];
685
+ const push = (val, label) => {
686
+ if (val > 0) result.push(`${val} ${label}${val === 1 ? "" : "s"}`);
687
+ };
688
+ if (style === "ymdhms") push(d, "day");
689
+ push(h, "hour");
690
+ push(m, "minute");
691
+ push(s, "second");
692
+ if (result.length === 0) return "0 seconds";
693
+ if (result.length === 1) return result[0];
694
+ const last = result.pop();
695
+ return `${result.join(", ")} and ${last}`;
696
+ }
697
+ function formatETA(date, locale) {
698
+ const rtf = new Intl.RelativeTimeFormat(locale, { numeric: "auto" });
699
+ const elapsed = (typeof date === "number" ? date : date.getTime()) - Date.now();
700
+ const units = [
701
+ { unit: "year", ms: 31536e6 },
702
+ { unit: "month", ms: 2628e6 },
703
+ { unit: "day", ms: 864e5 },
704
+ { unit: "hour", ms: 36e5 },
705
+ { unit: "minute", ms: 6e4 },
706
+ { unit: "second", ms: 1e3 }
707
+ ];
708
+ for (const { unit, ms } of units) {
709
+ if (Math.abs(elapsed) >= ms || unit === "second") {
710
+ return rtf.format(Math.round(elapsed / ms), unit);
711
+ }
712
+ }
713
+ return "";
714
+ }
507
715
 
508
716
  // src/fs.ts
509
- var fs_exports = {};
510
- __export(fs_exports, {
511
- readDir: () => readDir
512
- });
513
717
  import _fs from "fs";
514
718
  import { join } from "path";
515
719
  function readDir(path2, options = {}) {
@@ -538,77 +742,58 @@ function readDir(path2, options = {}) {
538
742
  }
539
743
 
540
744
  // src/is.ts
541
- var is_exports = {};
542
- __export(is_exports, {
543
- defined: () => defined,
544
- empty: () => empty,
545
- inRange: () => inRange,
546
- object: () => object,
547
- sorted: () => sorted,
548
- string: () => string,
549
- today: () => today
550
- });
551
- function defined(val) {
745
+ function isDefined(val) {
552
746
  return val !== void 0 && val !== null;
553
747
  }
554
- function empty(val) {
555
- if (!defined(val)) return true;
556
- if (string(val) || Array.isArray(val)) return val.length === 0;
557
- if (object(val)) return Object.keys(val).length === 0;
748
+ function isEmpty(val) {
749
+ if (!isDefined(val)) return true;
750
+ if (isString(val) || Array.isArray(val)) return val.length === 0;
751
+ if (isObject(val)) return Object.keys(val).length === 0;
558
752
  return false;
559
753
  }
560
- function inRange(num, a, b) {
754
+ function isObject(val) {
755
+ return val !== null && typeof val === "object" && !Array.isArray(val);
756
+ }
757
+ function isString(val) {
758
+ return typeof val === "string";
759
+ }
760
+ function isInRange(num, a, b) {
561
761
  let min = b !== void 0 ? a : 0;
562
762
  let max = b !== void 0 ? b : a;
563
763
  if (min > max) [min, max] = [max, min];
564
764
  return num >= min && num <= max;
565
765
  }
566
- function object(val) {
567
- return val !== null && typeof val === "object" && !Array.isArray(val);
568
- }
569
- function sorted(arr, comparator) {
766
+ function isSortedArray(arr, comparator) {
570
767
  for (let i = 0; i < arr.length - 1; i++) {
571
768
  const comp = comparator ? comparator(arr[i], arr[i + 1]) : arr[i] > arr[i + 1] ? 1 : -1;
572
769
  if (comp > 0) return false;
573
770
  }
574
771
  return true;
575
772
  }
576
- function string(val) {
577
- return typeof val === "string";
578
- }
579
- function today(date) {
773
+ function isToday(date) {
580
774
  const d = date instanceof Date ? date : new Date(date);
581
- const today2 = /* @__PURE__ */ new Date();
582
- return d.getDate() === today2.getDate() && d.getMonth() === today2.getMonth() && d.getFullYear() === today2.getFullYear();
775
+ const today = /* @__PURE__ */ new Date();
776
+ return d.getDate() === today.getDate() && d.getMonth() === today.getMonth() && d.getFullYear() === today.getFullYear();
583
777
  }
584
778
 
585
779
  // src/math.ts
586
- var math_exports = {};
587
- __export(math_exports, {
588
- clamp: () => clamp,
589
- invLerp: () => invLerp,
590
- lerp: () => lerp,
591
- ms: () => ms,
592
- percent: () => percent,
593
- remap: () => remap,
594
- secs: () => secs,
595
- sum: () => sum,
596
- wrap: () => wrap
597
- });
598
- function clamp(num, a, b) {
780
+ function clampNumber(num, a, b) {
599
781
  let min = b !== void 0 ? a : 0;
600
782
  let max = b !== void 0 ? b : a;
601
783
  if (min > max) [min, max] = [max, min];
602
784
  return Math.max(min, Math.min(num, max));
603
785
  }
604
- function invLerp(start, end, value) {
786
+ function lerp(start, end, t) {
787
+ return start + (end - start) * t;
788
+ }
789
+ function inverseLerp(start, end, value) {
605
790
  if (start === end) return 0;
606
791
  return (value - start) / (end - start);
607
792
  }
608
- function lerp(start, end, t) {
609
- return start + (end - start) * t;
793
+ function msToSecs(num) {
794
+ return Math.floor(num / 1e3);
610
795
  }
611
- function ms(num) {
796
+ function secsToMs(num) {
612
797
  return Math.floor(num * 1e3);
613
798
  }
614
799
  function percent(a, b, round = true) {
@@ -616,36 +801,19 @@ function percent(a, b, round = true) {
616
801
  return round ? Math.floor(result) : result;
617
802
  }
618
803
  function remap(value, inMin, inMax, outMin, outMax) {
619
- const t = invLerp(inMin, inMax, value);
804
+ const t = inverseLerp(inMin, inMax, value);
620
805
  return lerp(outMin, outMax, t);
621
806
  }
622
- function secs(num) {
623
- return Math.floor(num / 1e3);
624
- }
625
807
  function sum(array, selector) {
626
808
  const _array = selector ? array.map(selector) : array;
627
- if (!_array.every((v) => typeof v === "number")) {
628
- throw new TypeError(`sum: Array must only contain numbers.`);
629
- }
630
- return _array.reduce((a, b) => {
631
- return (isNaN(b) ? 0 : b) < 0 ? a - -b : a + (b || 0);
632
- }, 0);
809
+ return _array.reduce((a, b) => b < 0 ? a - -b : a + (b || 0), 0);
633
810
  }
634
811
  function wrap(num, max) {
635
812
  return (num % max + max) % max;
636
813
  }
637
814
 
638
815
  // src/obj.ts
639
- var obj_exports = {};
640
- __export(obj_exports, {
641
- get: () => get,
642
- has: () => has,
643
- merge: () => merge,
644
- omit: () => omit,
645
- pick: () => pick,
646
- set: () => set
647
- });
648
- function get(obj, path2, defaultValue) {
816
+ function getProp(obj, path2, defaultValue) {
649
817
  if (!obj) throw new Error("get: Target object is null or undefined");
650
818
  const parts = path2.replace(/\[(\d+)\]/g, ".$1").split(".");
651
819
  let current = obj;
@@ -664,7 +832,7 @@ function get(obj, path2, defaultValue) {
664
832
  }
665
833
  return current;
666
834
  }
667
- function has(obj, path2) {
835
+ function hasProp(obj, path2) {
668
836
  if (!obj || !path2) return false;
669
837
  const parts = path2.replace(/\[(\d+)\]/g, ".$1").split(".");
670
838
  let current = obj;
@@ -680,7 +848,7 @@ function has(obj, path2) {
680
848
  }
681
849
  return true;
682
850
  }
683
- function set(obj, path2, value) {
851
+ function setProp(obj, path2, value) {
684
852
  const parts = path2.replace(/\[(\d+)\]/g, ".$1").split(".");
685
853
  let current = obj;
686
854
  for (let i = 0; i < parts.length; i++) {
@@ -732,36 +900,32 @@ function omit(obj, keys) {
732
900
  }
733
901
 
734
902
  // src/str.ts
735
- var str_exports = {};
736
- __export(str_exports, {
737
- escapeRegex: () => escapeRegex,
738
- getFlag: () => getFlag,
739
- hasFlag: () => hasFlag,
740
- toTitleCase: () => toTitleCase
741
- });
742
- function escapeRegex(str2) {
743
- return str2.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
903
+ function escapeRegex(str) {
904
+ return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
744
905
  }
745
- function getFlag(str2, flag, length) {
906
+ function getFlag(str, flag, length) {
746
907
  const regex = flag instanceof RegExp ? flag : new RegExp(`${escapeRegex(flag)}\\b`, "g");
747
- const match = regex.exec(str2);
908
+ const match = regex.exec(str);
748
909
  if (!match) return null;
749
910
  const startIndex = match.index + match[0].length;
750
- let result = str2.slice(startIndex).trimStart();
911
+ let result = str.slice(startIndex).trimStart();
751
912
  if (length !== void 0) {
752
913
  return result.split(/\s+/).slice(0, length).join(" ");
753
914
  }
754
915
  return result || null;
755
916
  }
756
- function hasFlag(str2, flag) {
757
- if (flag instanceof RegExp) return flag.test(str2);
917
+ function hasFlag(str, flag) {
918
+ if (flag instanceof RegExp) return flag.test(str);
758
919
  const pattern = new RegExp(`${escapeRegex(flag)}\\b`);
759
- return pattern.test(str2);
920
+ return pattern.test(str);
921
+ }
922
+ function pluralize(count, singular, plural = `${singular}s`) {
923
+ return count === 1 ? singular : plural;
760
924
  }
761
- function toTitleCase(str2, smart = true) {
925
+ function toTitleCase(str, smart = true) {
762
926
  const minorWords = /^(a|an|and|as|at|but|by|en|for|if|in|of|on|or|the|to|v\.?|via)$/i;
763
- return str2.replace(/\w\S*/g, (txt, index2) => {
764
- if (smart && index2 !== 0 && minorWords.test(txt)) {
927
+ return str.replace(/\w\S*/g, (txt, index) => {
928
+ if (smart && index !== 0 && minorWords.test(txt)) {
765
929
  return txt.toLowerCase();
766
930
  }
767
931
  if (smart && txt.length > 1 && txt === txt.toUpperCase()) {
@@ -770,391 +934,70 @@ function toTitleCase(str2, smart = true) {
770
934
  return txt.charAt(0).toUpperCase() + txt.substring(1).toLowerCase();
771
935
  });
772
936
  }
773
-
774
- // src/timing.ts
775
- var timing_exports = {};
776
- __export(timing_exports, {
777
- debounce: () => debounce,
778
- throttle: () => throttle
779
- });
780
- function debounce(fn, wait2, options = {}) {
781
- let timeoutId;
782
- const leading = options.immediate ?? false;
783
- const debounced = function(...args) {
784
- const callNow = leading && !timeoutId;
785
- if (timeoutId) clearTimeout(timeoutId);
786
- timeoutId = setTimeout(() => {
787
- timeoutId = void 0;
788
- if (!leading) fn.apply(this, args);
789
- }, wait2);
790
- if (callNow) fn.apply(this, args);
791
- };
792
- debounced.cancel = () => {
793
- if (timeoutId) {
794
- clearTimeout(timeoutId);
795
- timeoutId = void 0;
796
- }
797
- };
798
- return debounced;
799
- }
800
- function throttle(fn, limit) {
801
- let inThrottle = false;
802
- return function(...args) {
803
- if (!inThrottle) {
804
- fn.apply(this, args);
805
- inThrottle = true;
806
- setTimeout(() => inThrottle = false, limit);
807
- }
808
- };
809
- }
810
-
811
- // src/to.ts
812
- var to_exports = {};
813
- __export(to_exports, {
814
- record: () => record
815
- });
816
- function record(array, callback) {
817
- const result = {};
818
- let lastValue = void 0;
819
- for (let i = 0; i < array.length; i++) {
820
- const { key, value } = callback(array[i], {
821
- index: i,
822
- lastValue,
823
- // NOTE: This is a reference to the object currently being built
824
- newRecord: result,
825
- originalArray: array
826
- });
827
- result[key] = value;
828
- lastValue = value;
829
- }
830
- return result;
831
- }
832
-
833
- // src/Pipe.ts
834
- function Pipe(value, ...fns) {
835
- return fns.reduce((acc, fn) => fn(acc), value);
836
- }
837
-
838
- // src/Storage.ts
839
- import fs from "fs";
840
- import path from "path";
841
- var Storage = class {
842
- isNode = typeof window === "undefined";
843
- filePath = null;
844
- memoryCache = /* @__PURE__ */ new Map();
845
- loadFromFile() {
846
- if (this.filePath && fs.existsSync(this.filePath)) {
847
- try {
848
- const data = JSON.parse(fs.readFileSync(this.filePath, "utf-8"));
849
- Object.entries(data).forEach(([k, v]) => this.memoryCache.set(k, JSON.stringify(v)));
850
- } catch (err) {
851
- console.error(`Store: Failed to load file '${this.filePath}'`, err);
852
- }
853
- }
854
- }
855
- persist() {
856
- if (this.isNode && this.filePath) {
857
- const out = {};
858
- this.memoryCache.forEach((v, k) => out[k] = JSON.parse(v));
859
- fs.writeFileSync(this.filePath, JSON.stringify(out, null, 2));
860
- }
861
- }
862
- /**
863
- * A lightweight, high-performant persistent storage system.
864
- * Uses JSON files in Node.js, localStorage in the browser.
865
- * @param fileName Only used in Node.js to create a persistent .json file.
866
- * @param directory The directory for the file. Defaults to current working directory.
867
- */
868
- constructor(fileName, directory = process.cwd()) {
869
- if (this.isNode && fileName) {
870
- this.filePath = path.join(directory, fileName.endsWith(".json") ? fileName : `${fileName}.json`);
871
- this.loadFromFile();
872
- }
873
- }
874
- has(key) {
875
- if (!this.isNode && window.localStorage) {
876
- return localStorage.getItem(key) !== null;
877
- }
878
- return this.memoryCache.has(key);
879
- }
880
- get(key) {
881
- let raw = null;
882
- if (!this.isNode && window.localStorage) {
883
- raw = localStorage.getItem(key);
884
- } else {
885
- raw = this.memoryCache.get(key) || null;
886
- }
887
- if (!raw) return null;
888
- const payload = JSON.parse(raw);
889
- if (payload.expiry && Date.now() > payload.expiry) {
890
- this.remove(key);
891
- this.persist();
892
- return null;
893
- }
894
- return payload.value;
895
- }
896
- set(key, value, ttl) {
897
- const payload = {
898
- value,
899
- expiry: ttl ? Date.now() + ttl : null
900
- };
901
- const serialized = JSON.stringify(payload);
902
- if (!this.isNode && window.localStorage) {
903
- localStorage.setItem(key, serialized);
904
- } else {
905
- this.memoryCache.set(key, serialized);
906
- this.persist();
907
- }
908
- }
909
- remove(key) {
910
- if (!this.isNode && window.localStorage) {
911
- localStorage.removeItem(key);
912
- } else {
913
- this.memoryCache.delete(key);
914
- this.persist();
915
- }
916
- }
917
- clear() {
918
- if (!this.isNode && window.localStorage) {
919
- localStorage.clear();
920
- } else {
921
- this.memoryCache.clear();
922
- this.persist();
923
- }
924
- }
925
- };
926
-
927
- // src/Cache.ts
928
- var Cache = class {
929
- cache = /* @__PURE__ */ new Map();
930
- interval;
931
- /**
932
- * A lightweight, high-performant in-memory cache.
933
- * Uses Map for O(1) lookups and an optional cleanup interval.
934
- * @param cleanupMs The interval in milliseconds to run the cleanup function. [default: 60000 (1 minute)]
935
- */
936
- constructor(cleanupMs = 6e4) {
937
- if (cleanupMs > 0) {
938
- this.interval = setInterval(() => this.cleanup(), cleanupMs);
939
- if (this.interval.unref) this.interval.unref();
940
- }
941
- }
942
- set(key, value, ttlMs) {
943
- this.cache.set(key, {
944
- value,
945
- expiresAt: ttlMs ? Date.now() + ttlMs : null
946
- });
947
- }
948
- get(key) {
949
- const data = this.cache.get(key);
950
- if (!data) return null;
951
- if (data.expiresAt && Date.now() > data.expiresAt) {
952
- this.cache.delete(key);
953
- return null;
954
- }
955
- return data.value;
956
- }
957
- cleanup() {
958
- if (this.cache.size === 0) return;
959
- const now = Date.now();
960
- let keysProcessed = 0;
961
- const maxKeysToScan = 20;
962
- for (const [key, data] of this.cache) {
963
- if (data.expiresAt && now > data.expiresAt) {
964
- this.cache.delete(key);
965
- }
966
- keysProcessed++;
967
- if (keysProcessed >= maxKeysToScan) break;
968
- }
969
- }
970
- clear() {
971
- this.cache.clear();
972
- }
973
- };
974
-
975
- // src/Loop.ts
976
- import EventEmitter from "events";
977
- var TypedEmitterBase = EventEmitter;
978
- var Loop = class extends TypedEmitterBase {
979
- _state = "stopped";
980
- timeoutId = null;
981
- delay;
982
- fn;
983
- startTime = 0;
984
- remaining = 0;
985
- async run() {
986
- const currentState = this._state;
987
- if (currentState === "stopped" || currentState === "paused") return;
988
- try {
989
- const result = await this.fn(this);
990
- this.emit("tick", result);
991
- } catch (err) {
992
- this.emit("error", err);
993
- }
994
- if (this._state === "running") {
995
- this.startTime = Date.now();
996
- this.remaining = 0;
997
- this.clearTimer();
998
- this.timeoutId = setTimeout(() => this.run(), this.delay);
999
- }
1000
- }
1001
- clearTimer() {
1002
- if (this.timeoutId) {
1003
- clearTimeout(this.timeoutId);
1004
- this.timeoutId = null;
1005
- }
1006
- }
1007
- /**
1008
- * Creates an interval. If the function is async, it will wait for it to complete before scheduling the next run.
1009
- * @param fn The function to run.
1010
- * @param delay The delay between runs in milliseconds.
1011
- * @param immediate Whether to start the loop immediately. [default: true]
1012
- */
1013
- constructor(fn, delay, immediate = true) {
1014
- super();
1015
- this.fn = fn;
1016
- this.delay = delay;
1017
- if (immediate) this.start();
1018
- }
1019
- get state() {
1020
- return this._state;
1021
- }
1022
- /** Starts the loop. */
1023
- start() {
1024
- if (this._state !== "stopped") return;
1025
- this._state = "running";
1026
- this.emit("start");
1027
- this.run();
1028
- }
1029
- /** Resumes a paused loop. */
1030
- resume() {
1031
- if (this._state !== "paused") return;
1032
- this._state = "running";
1033
- this.emit("resume");
1034
- if (this.remaining <= 0) {
1035
- this.run();
1036
- } else {
1037
- this.timeoutId = setTimeout(() => this.run(), this.remaining);
1038
- }
1039
- }
1040
- /** Stops the loop. */
1041
- stop() {
1042
- const wasRunning = this._state !== "stopped";
1043
- this._state = "stopped";
1044
- this.remaining = 0;
1045
- this.clearTimer();
1046
- if (wasRunning) this.emit("stop");
1047
- }
1048
- /** Pauses the execution. */
1049
- pause() {
1050
- if (this._state !== "running") return;
1051
- this._state = "paused";
1052
- const elapsed = Date.now() - this.startTime;
1053
- this.remaining = Math.max(0, this.delay - elapsed);
1054
- this.emit("pause", { remaining: this.remaining });
1055
- this.clearTimer();
1056
- }
1057
- /**
1058
- * Sets the delay between runs
1059
- * @param ms The new delay in milliseconds.
1060
- */
1061
- setDelay(ms2) {
1062
- this.delay = ms2;
1063
- }
1064
- /** Manually trigger the function once without affecting the loop. */
1065
- async execute() {
1066
- await this.fn(this);
1067
- }
1068
- };
1069
-
1070
- // src/index.ts
1071
- var qznt = {
1072
- arr: arr_exports,
1073
- async: async_exports,
1074
- fn: fn_exports,
1075
- date: date_exports,
1076
- format: format_exports,
1077
- fs: fs_exports,
1078
- is: is_exports,
1079
- math: math_exports,
1080
- obj: obj_exports,
1081
- timing: timing_exports,
1082
- rnd: rnd_exports,
1083
- str: str_exports,
1084
- to: to_exports,
1085
- Pipe,
1086
- Storage,
1087
- Cache,
1088
- Loop
1089
- };
1090
- var $ = qznt;
1091
- var index_default = qznt;
1092
937
  export {
1093
- $,
1094
938
  Cache,
939
+ FormatNumberCompact,
1095
940
  Loop,
1096
941
  Pipe,
1097
942
  Storage,
1098
- chance,
1099
- choice,
1100
943
  chunk,
1101
944
  chunkAdj,
1102
- clamp,
945
+ clampNumber,
1103
946
  cluster,
1104
- compact,
1105
- compactNumber,
1106
- currency,
947
+ compactArray,
948
+ createSampler,
1107
949
  debounce,
1108
- index_default as default,
1109
- defined,
1110
- duration,
1111
- empty,
1112
950
  escapeRegex,
1113
- eta,
1114
- float,
1115
951
  forceArray,
1116
- get,
952
+ formatCurrency,
953
+ formatDuration,
954
+ formatETA,
955
+ formatMemory,
956
+ formatNumber,
957
+ formatOrdinal,
1117
958
  getAge,
1118
959
  getFlag,
1119
- has,
960
+ getProp,
1120
961
  hasFlag,
1121
- inRange,
1122
- index,
1123
- int,
1124
- invLerp,
962
+ hasProp,
963
+ inverseLerp,
964
+ isDefined,
965
+ isEmpty,
966
+ isInRange,
967
+ isObject,
968
+ isSortedArray,
969
+ isString,
970
+ isToday,
1125
971
  lerp,
1126
972
  memoize,
1127
- memory,
1128
973
  merge,
1129
- ms,
1130
- number,
1131
- object,
974
+ msToSecs,
1132
975
  omit,
1133
- ordinal,
1134
- parse,
976
+ parseTime,
1135
977
  percent,
1136
978
  pick,
979
+ pluralize,
1137
980
  prng,
1138
981
  readDir,
1139
- record,
1140
982
  remap,
1141
- retry,
1142
- sampler,
1143
- search,
1144
- secs,
983
+ retryPromise,
984
+ rndChance,
985
+ rndChoice,
986
+ rndFloat,
987
+ rndIndex,
988
+ rndInt,
989
+ rndString,
990
+ searchSorted,
991
+ secsToMs,
1145
992
  seqMap,
1146
- set,
993
+ setProp,
1147
994
  shuffle,
1148
995
  sortBy,
1149
- sorted,
1150
- str,
1151
- string,
1152
996
  sum,
1153
997
  throttle,
1154
998
  toTitleCase,
1155
- today,
1156
999
  unique,
1157
1000
  wait,
1158
- weighted,
1001
+ weightedRnd,
1159
1002
  wrap
1160
1003
  };