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