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