qznt 1.0.22 → 1.0.32
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 +28 -6
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.mts +22 -10
- package/dist/index.d.ts +22 -10
- package/dist/index.js +28 -6
- package/dist/index.js.map +1 -1
- package/dist/metafile-cjs.json +1 -1
- package/dist/metafile-esm.json +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -72,9 +72,20 @@ function chance(percent2 = 0.5, seed) {
|
|
|
72
72
|
const random = seed !== void 0 ? prng(seed) : Math.random;
|
|
73
73
|
return random() < percent2;
|
|
74
74
|
}
|
|
75
|
-
function choice(array,
|
|
75
|
+
function choice(array, options = {}) {
|
|
76
|
+
const { seed, not, maxRerolls = 10 } = options;
|
|
76
77
|
const random = seed !== void 0 ? prng(seed) : Math.random;
|
|
77
|
-
|
|
78
|
+
const rnd2 = () => array[Math.floor(random() * array.length)];
|
|
79
|
+
let result = rnd2();
|
|
80
|
+
if (seed === void 0 && array.length > 1 && not !== void 0) {
|
|
81
|
+
let rerolls = 0;
|
|
82
|
+
const shouldReroll = () => typeof not === "function" ? not(result) : result === not;
|
|
83
|
+
while (shouldReroll() && rerolls < maxRerolls) {
|
|
84
|
+
result = rnd2();
|
|
85
|
+
rerolls++;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
return result;
|
|
78
89
|
}
|
|
79
90
|
function weighted(array, selector, seed) {
|
|
80
91
|
const random = seed !== void 0 ? prng(seed) : Math.random;
|
|
@@ -86,9 +97,9 @@ function weighted(array, selector, seed) {
|
|
|
86
97
|
cumulativeWeights.push(currentSum);
|
|
87
98
|
}
|
|
88
99
|
const decider = random() * currentSum;
|
|
89
|
-
let index2
|
|
100
|
+
let index2;
|
|
90
101
|
if (array.length < 20) {
|
|
91
|
-
cumulativeWeights.findIndex((w) => w >= decider);
|
|
102
|
+
index2 = cumulativeWeights.findIndex((w) => w >= decider);
|
|
92
103
|
} else {
|
|
93
104
|
let low = 0;
|
|
94
105
|
let high = cumulativeWeights.length - 1;
|
|
@@ -149,9 +160,20 @@ function float(min, max, seed) {
|
|
|
149
160
|
const random = seed !== void 0 ? prng(seed) : Math.random;
|
|
150
161
|
return random() * (max - min) + min;
|
|
151
162
|
}
|
|
152
|
-
function index(array,
|
|
163
|
+
function index(array, options = {}) {
|
|
164
|
+
const { seed, not, maxRerolls = 10 } = options;
|
|
153
165
|
const random = seed !== void 0 ? prng(seed) : Math.random;
|
|
154
|
-
|
|
166
|
+
const rnd2 = () => Math.floor(random() * array.length);
|
|
167
|
+
let result = rnd2();
|
|
168
|
+
if (seed === void 0 && array.length > 1 && not !== void 0) {
|
|
169
|
+
let rerolls = 0;
|
|
170
|
+
const shouldReroll = () => typeof not === "function" ? not(result) : result === not;
|
|
171
|
+
while (shouldReroll() && rerolls < maxRerolls) {
|
|
172
|
+
result = rnd2();
|
|
173
|
+
rerolls++;
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
return result;
|
|
155
177
|
}
|
|
156
178
|
function int(min, max, seed) {
|
|
157
179
|
const random = seed !== void 0 ? prng(seed) : Math.random;
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/arr.ts","../src/rnd.ts","../src/async.ts","../src/fn.ts","../src/date.ts","../src/format.ts","../src/fs.ts","../src/is.ts","../src/math.ts","../src/obj.ts","../src/str.ts","../src/timing.ts","../src/to.ts","../src/Pipe.ts","../src/Storage.ts","../src/Cache.ts","../src/Loop.ts"],"sourcesContent":["import * as arrayUtils from \"./arr\";\nimport * as asyncUtils from \"./async\";\nimport * as functionUtils from \"./fn\";\nimport * as dateUtils from \"./date\";\nimport * as formatUtils from \"./format\";\nimport * as fileUtils from \"./fs\";\nimport * as isUtils from \"./is\";\nimport * as mathUtils from \"./math\";\nimport * as objectUtils from \"./obj\";\nimport * as randomUtils from \"./rnd\";\nimport * as stringUtils from \"./str\";\nimport * as timingUtils from \"./timing\";\nimport * as toUtils from \"./to\";\nimport { Pipe } from \"./Pipe\";\nimport { Storage } from \"./Storage\";\nimport { Cache } from \"./Cache\";\nimport { Loop } from \"./Loop\";\n\nconst qznt = {\n ...arrayUtils,\n ...asyncUtils,\n ...functionUtils,\n ...dateUtils,\n ...formatUtils,\n ...fileUtils,\n ...isUtils,\n ...mathUtils,\n ...objectUtils,\n ...timingUtils,\n ...randomUtils,\n ...stringUtils,\n ...toUtils,\n Pipe,\n Storage,\n Cache,\n Loop\n};\n\nexport const $ = qznt;\nexport default qznt;\n\nexport * from \"./arr\";\nexport * from \"./async\";\nexport * from \"./fn\";\nexport * from \"./date\";\nexport * from \"./format\";\nexport * from \"./fs\";\nexport * from \"./is\";\nexport * from \"./math\";\nexport * from \"./obj\";\nexport * from \"./rnd\";\nexport * from \"./str\";\nexport * from \"./timing\";\nexport * from \"./to\";\nexport * from \"./types\";\nexport { Pipe } from \"./Pipe\";\nexport { Storage } from \"./Storage\";\nexport { Cache } from \"./Cache\";\nexport { Loop } from \"./Loop\";\n","import { rnd } from \"./rnd\";\n\nexport type SequentialMapContext<T, U> = {\n index: number;\n lastElement: U | undefined;\n newArray: ReadonlyArray<U>;\n originalArray: ReadonlyArray<T>;\n};\n\n/**\n * Splits an array into sub-arrays (chunks) of a maximum size.\n * @param array Array to process.\n * @param size The maximum size of each chunk.\n */\nfunction chunk<T>(array: ReadonlyArray<T>, size: number): T[][] {\n if (size <= 0) throw new Error(\"chunk: Size must be a positive integer.\");\n\n const result: T[][] = [];\n const len = array.length;\n\n for (let i = 0; i < len; i += size) {\n result.push(array.slice(i, i + size));\n }\n\n return result;\n}\n\n/**\n * Groups adjacent elements of an array together based on a predicate.\n * @param array Array to process.\n * @param predicate A function that returns true if two adjacent elements belong in the same chunk.\n * @example\n * // Group consecutive identical numbers\n * chunkBy([1, 1, 2, 3, 3, 3], (a, b) => a === b);\n * // [[1, 1], [2], [3, 3, 3]]\n */\nfunction chunkAdj<T>(array: ReadonlyArray<T>, predicate: (prev: T, curr: T) => boolean): T[][] {\n if (array.length === 0) return [];\n\n const results: T[][] = [];\n const len = array.length;\n let currentChunk: T[] = [array[0]!];\n\n for (let i = 1; i < len; i++) {\n const prev = array[i - 1]!;\n const curr = array[i]!;\n\n if (predicate(prev, curr)) {\n currentChunk.push(curr);\n } else {\n results.push(currentChunk);\n currentChunk = [curr];\n }\n }\n\n results.push(currentChunk);\n return results;\n}\n\n/**\n * Groups elements by a key.\n * @param array Array to process.\n * @param iteratee Function to determine the key to group by.\n * @param maxChunkSize Optionally chunk groups and flatten them (useful for pagination).\n */\nfunction cluster<T>(array: ReadonlyArray<T>, iteratee: (item: T) => string | number, maxChunkSize?: number): T[][] {\n const groups = new Map<string | number, T[]>();\n\n for (const item of array) {\n const key = iteratee(item);\n const collection = groups.get(key);\n if (!collection) {\n groups.set(key, [item]);\n } else {\n collection.push(item);\n }\n }\n\n const result: T[][] = [];\n\n for (const group of groups.values()) {\n if (maxChunkSize && maxChunkSize > 0) {\n // If chunking is enabled, split this specific group\n for (let i = 0; i < group.length; i += maxChunkSize) {\n result.push(group.slice(i, i + maxChunkSize));\n }\n } else {\n // Otherwise, just push the whole group as one chunk\n result.push(group);\n }\n }\n\n return result;\n}\n\n/**\n * Removes unwanted values from an array.\n * @param array Array to process.\n * @param mode 'nullable' (default) removes null/undefined. 'falsy' removes null, undefined, 0, \"\", false, and NaN.\n */\nfunction compact<T>(array: ReadonlyArray<T>, mode?: \"nullable\"): NonNullable<T>[];\nfunction compact<T>(array: ReadonlyArray<T>, mode: \"falsy\"): Exclude<T, null | undefined | false | 0 | \"\">[];\nfunction compact<T>(array: ReadonlyArray<T>, mode: \"nullable\" | \"falsy\" = \"nullable\"): any[] {\n if (mode === \"falsy\") {\n // Boolean constructor handles all falsy values\n return array.filter(Boolean);\n }\n\n // Only removes null and undefined\n return array.filter(item => item !== null && item !== undefined);\n}\n\n/**\n * Forces a given item to be an array.\n * @param item The item to force into an array.\n */\nfunction forceArray<T>(item: T): T[] {\n return Array.isArray(item) ? item : [item];\n}\n\n/**\n * Searches a sorted array for a value using the binary search method.\n * Returns the index if found, or the bitwise complement (~index) of the\n * position where the value should be inserted to keep it sorted.\n * @param array The array to process.\n * @param target The value to search for.\n * @param comparator Optional comparator function.\n */\nfunction search<T>(\n array: T[],\n target: T,\n comparator: (a: T, b: T) => number = (a, b) => (a > b ? 1 : a < b ? -1 : 0)\n): number {\n let low = 0;\n let high = array.length - 1;\n\n while (low <= high) {\n const mid = (low + high) >>> 1;\n const comp = comparator(array[mid]!, target);\n\n if (comp < 0) low = mid + 1;\n else if (comp > 0) high = mid - 1;\n else return mid;\n }\n\n return ~low;\n}\n\n/**\n * Maps over an array with access to the previously mapped elements.\n * @param array Array to process.\n * @param callback Function to map over the array.\n */\nfunction seqMap<T, U>(array: ReadonlyArray<T>, callback: (item: T, context: SequentialMapContext<T, U>) => U): U[] {\n const len = array.length;\n const result: U[] = new Array(len);\n\n for (let i = 0; i < len; i++) {\n result[i] = callback(array[i]!, {\n index: i,\n lastElement: i > 0 ? result[i - 1] : undefined,\n // NOTE: This is a reference to the array currently being built\n newArray: result,\n originalArray: array\n });\n }\n\n return result;\n}\n\n/**\n * Shuffles an array using the Fisher-Yates algorithm.\n * @param array The array to shuffle.\n * @param seed Optional seed for RNG.\n */\nfunction shuffle<T>(array: ReadonlyArray<T>, seed?: number): T[] {\n const random = seed !== undefined ? rnd.prng(seed) : Math.random;\n const result = [...array];\n\n for (let i = result.length - 1; i > 0; i--) {\n const j = Math.floor(random() * (i + 1));\n const temp = result[i]!;\n result[i] = result[j]!;\n result[j] = temp;\n }\n\n return result;\n}\n\n/**\n * Sorts an array by a single property in order.\n * @param order 'asc' for ascending (default) or 'desc' for descending.\n * @param array Array to process.\n * @param selector Function to determine the key to sort by.\n */\nfunction sortBy<T>(array: ReadonlyArray<T>, selector: (item: T) => any, order?: \"asc\" | \"desc\"): T[];\n/**\n * Sorts an array by one or more properties in order.\n * @param order 'asc' for ascending (default) or 'desc' for descending.\n * @param array Array to process.\n * @param selectors Functions to determine the keys to sort by.\n */\nfunction sortBy<T>(array: ReadonlyArray<T>, selectors: (item: T) => any[], order?: \"asc\" | \"desc\"): T[];\nfunction sortBy<T>(\n array: ReadonlyArray<T>,\n selectorOrSelectors: (item: T) => any | ((item: T) => any)[],\n order: \"asc\" | \"desc\" = \"asc\"\n): T[] {\n const selectors = Array.isArray(selectorOrSelectors) ? selectorOrSelectors : [selectorOrSelectors];\n\n if (array.length === 0 || selectors.length === 0) {\n return [...array];\n }\n\n const modifier = order === \"desc\" ? -1 : 1;\n const memos = array.map(item => ({ item, keys: selectors.map(s => s(item)) }));\n\n memos.sort((a, b) => {\n for (let i = 0; i < selectors.length; i++) {\n const valA = a.keys[i];\n const valB = b.keys[i];\n\n if (valA === valB) continue;\n\n // Nullish values are pushed to the end regardless of order\n if (valA == null) return 1;\n if (valB == null) return -1;\n\n if (valA < valB) return -1 * modifier;\n if (valA > valB) return 1 * modifier;\n }\n return 0;\n });\n\n return memos.map(m => m.item);\n}\n\n/**\n * Returns an array of unique elements from the given array.\n * Uniqueness is determined by the given key function.\n * @param array Array to process.\n * @param key Function to determine the keys to filter by\n */\nfunction unique<T>(array: T[], key: (item: T) => any): T[] {\n return Array.from(new Map(array.map(item => [key(item), item])).values());\n}\n\nexport const arr = {\n chunk,\n chunkAdj,\n cluster,\n compact,\n forceArray,\n search,\n seqMap,\n shuffle,\n sortBy,\n unique\n};\n","export type AlphaCasing = \"lower\" | \"upper\" | \"mixed\";\n\nexport interface RndStrOptions {\n casing?: AlphaCasing;\n seed?: number;\n customChars?: string;\n exclude?: string | string[];\n}\n\nconst LOWER = \"abcdefghijklmnopqrstuvwxyz\";\nconst UPPER = \"ABCDEFGHIJKLMNOPQRSTUVWXYZ\";\nconst NUM = \"0123456789\";\n\n/**\n * Returns true based on a percentage probability.\n * @param percent A value between 0 and 1. [default: 0.5]\n * @param seed Optional seed for RNG.\n */\nfunction chance(percent: number = 0.5, seed?: number): boolean {\n if (percent <= 0) return false;\n if (percent >= 1) return true;\n const random = seed !== undefined ? prng(seed) : Math.random;\n return random() < percent;\n}\n\n/**\n * Returns a random item from the given array.\n * @param array Array of items to choose from.\n * @param seed Optional seed for RNG.\n */\nfunction choice<T>(array: T[], seed?: number): T {\n const random = seed !== undefined ? prng(seed) : Math.random;\n return array[Math.floor(random() * array.length)]!;\n}\n\n/**\n * Returns a random item from the given array based on their corresponding weights.\n * @param array Array of items to choose from.\n * @param selector Function that selects the item's weight.\n * @param seed Optional seed for RNG.\n */\nfunction weighted<T>(array: T[], selector: (item: T) => number, seed?: number): T {\n const random = seed !== undefined ? prng(seed) : Math.random;\n\n const cumulativeWeights: number[] = [];\n let currentSum = 0;\n\n // Calculate cumulative weights\n for (const item of array) {\n const weight = selector(item);\n currentSum += weight;\n cumulativeWeights.push(currentSum);\n }\n\n const decider = random() * currentSum;\n\n let index = cumulativeWeights.findIndex(w => w >= decider);\n\n // Linear search | O(n)\n if (array.length < 20) {\n cumulativeWeights.findIndex(w => w >= decider);\n }\n // Binary Search | O(log n)\n else {\n let low = 0;\n let high = cumulativeWeights.length - 1;\n\n while (low < high) {\n const mid = (low + high) >>> 1;\n if (decider > cumulativeWeights[mid]!) {\n low = mid + 1;\n } else {\n high = mid;\n }\n }\n index = low;\n }\n\n return array[index]!;\n}\n\n/**\n * Returns an object with a single method, `pick`, which returns a random item from the given array in O(1) time.\n * The probability of each item being picked is determined by the corresponding weight in the `weights` array.\n * @param items Array of items to choose from.\n * @param selector Function that selects the item's weight.\n * @param seed Optional seed for RNG.\n */\nfunction sampler<T>(items: T[], selector: (item: T) => number, seed?: number) {\n const callRandom = seed ? prng(seed) : undefined;\n const len = items.length;\n\n const prob = new Array(len);\n const alias = new Array(len);\n\n const weights = items.map(selector);\n const totalWeight = weights.reduce((a, b) => a + b, 0);\n const scaledWeights = weights.map(w => (w * len) / totalWeight);\n\n const small: number[] = [];\n const large: number[] = [];\n\n scaledWeights.forEach((w, i) => (w < 1 ? small : large).push(i));\n\n while (small.length && large.length) {\n const s = small.pop()!;\n const l = large.pop()!;\n prob[s] = scaledWeights[s];\n alias[s] = l;\n scaledWeights[l] = scaledWeights[l]! + scaledWeights[s]! - 1;\n (scaledWeights[l] < 1 ? small : large).push(l);\n }\n\n while (large.length) prob[large.pop()!] = 1;\n while (small.length) prob[small.pop()!] = 1;\n\n return {\n /**\n * Returns a random item from the given array in O(1) time.\n * @param seed Optional seed for RNG.\n */\n pick: (seed?: number) => {\n const random = seed !== undefined ? prng(seed) : callRandom || Math.random;\n const i = Math.floor(random() * len);\n return random() < prob[i] ? items[i] : items[alias[i]];\n }\n };\n}\n\n/**\n * Creates a deterministic pseudo-random number generator (PRNG) using the Mulberry32 algorithm.\n * @param seed An integer seed value.\n * @example\n * const rng = prng(123);\n * const val1 = rng(); // Always the same for seed 123\n */\nfunction prng(seed: number): () => number {\n return () => {\n let t = (seed += 0x6d2b79f5);\n t = Math.imul(t ^ (t >>> 15), t | 1);\n t ^= t + Math.imul(t ^ (t >>> 7), t | 61);\n return ((t ^ (t >>> 14)) >>> 0) / 4294967296;\n };\n}\n\n/**\n * Generates a random float between the given minimum and maximum values.\n * @param min The minimum value (inclusive) for the random float.\n * @param max The maximum value (inclusive) for the random float.\n * @param seed Optional seed for RNG.\n */\nfunction float(min: number, max: number, seed?: number): number {\n const random = seed !== undefined ? prng(seed) : Math.random;\n return random() * (max - min) + min;\n}\n\n/**\n * Returns a random index from the given array.\n * @param array The array to generate an index for.\n * @param seed Optional seed for RNG.\n */\nfunction index(array: any[], seed?: number): number {\n const random = seed !== undefined ? prng(seed) : Math.random;\n return Math.floor(random() * array.length);\n}\n\n/**\n * Generates a random integer between the given minimum and maximum values.\n * @param min The minimum value (inclusive) for the random integer.\n * @param max The maximum value (inclusive) for the random integer.\n * @param seed Optional seed for RNG.\n */\nfunction int(min: number, max: number, seed?: number): number {\n const random = seed !== undefined ? prng(seed) : Math.random;\n return Math.floor(random() * (max - min + 1)) + min;\n}\n\n/**\n * Generates a random string of the given length using the specified character pool.\n * @param len The length of the random string.\n * @param mode The character pool to use. Can be \"number\", \"alpha\", \"alphanumeric\", or \"custom\".\n * @param options Options for the rndStr function.\n */\nfunction str(len: number, mode: \"number\" | \"alpha\" | \"alphanumeric\" | \"custom\", options: RndStrOptions = {}) {\n const { casing = \"lower\", seed, customChars = \"\", exclude = \"\" } = options;\n const random = seed !== undefined ? prng(seed) : Math.random;\n\n const alphaPool = { lower: LOWER, upper: UPPER, mixed: LOWER + UPPER }[casing];\n let pool = { number: NUM, alpha: alphaPool, alphanumeric: alphaPool + NUM, custom: customChars }[mode];\n\n if (exclude.length > 0) {\n const excludeSet = new Set(Array.isArray(exclude) ? exclude : exclude.split(\"\"));\n pool = pool\n .split(\"\")\n .filter(char => !excludeSet.has(char))\n .join(\"\");\n }\n\n // Safety check\n if (pool.length === 0) throw new Error(\"rndStr: Character pool is empty after exclusions.\");\n\n const result = new Array(len);\n const poolLen = pool.length;\n\n for (let i = 0; i < len; i++) {\n result[i] = pool[Math.floor(random() * poolLen)];\n }\n\n return result.join(\"\");\n}\n\nexport const rnd = {\n chance,\n choice,\n weighted,\n sampler,\n prng,\n float,\n index,\n int,\n str\n};\n","/**\n * Retries an async function with exponential backoff.\n * @param fn The async function to attempt.\n * @param retries Maximum number of retry attempts. [default: 3]\n * @param delay Initial delay in milliseconds. [default: 500ms]\n */\nasync function retry<T>(fn: () => Promise<T>, retries: number = 3, delay: number = 500): Promise<T> {\n try {\n return await fn();\n } catch (error) {\n if (retries <= 0) throw error;\n const jitter = Math.random() * 200;\n return await new Promise(resolve => setTimeout(resolve, delay + jitter));\n }\n}\n\n/**\n * Returns a promise that resolves after the given number of milliseconds.\n * @param ms The time to wait in milliseconds.\n */\nfunction wait(ms: number): Promise<boolean> {\n return new Promise(resolve =>\n setTimeout(() => {\n resolve(true);\n }, ms)\n );\n}\n\nexport const async = {\n retry,\n wait\n};\n","export interface MemoizedFunction<T extends (...args: any[]) => any> {\n (...args: Parameters<T>): ReturnType<T>;\n /** Clears the cache. */\n clear: () => void;\n}\n\n/**\n * Memoizes a function by caching its results based on the input arguments.\n * A resolver function can be provided to customize the key generation.\n * If no resolver is provided, the key will be generated by JSON stringify-ing the input arguments.\n * @param fn The function to memoize.\n * @param resolver An optional resolver function to customize the key generation.\n * @example\n * // 1. Basic usage\n * const heavyCalc = memoize((n: number) => {\n * console.log('Calculating...');\n * return n * 2;\n * });\n * heavyCalc(5); // Logs 'Calculating...' and returns 10\n * heavyCalc(5); // Returns 10 immediately from cache\n * @example\n * // 2. Using maxAge (TTL)\n * const getStockPrice = memoize(fetchPrice, { maxAge: 60000 }); // 1 minute cache\n * @example\n * // 3. Using a custom resolver\n * const getUser = memoize(\n * (user, theme) => render(user, theme),\n * { resolver: (user) => user.id } // Only cache based on ID, ignore theme\n * );\n * @example\n * // 4. Manual cache clearing\n * heavyCalc.clear();\n */\nfunction memoize<T extends (...args: any[]) => any>(\n fn: T,\n options: {\n /** Function to generate a cache key from the input arguments. */\n resolver?: (...args: Parameters<T>) => string;\n /** The time to wait in milliseconds before expiring a cache entry. */\n maxAge?: number;\n } = {}\n): MemoizedFunction<T> {\n const cache = new Map<string, { value: any; timestamp: number }>();\n const { resolver, maxAge } = options;\n\n const memoized = function (this: any, ...args: Parameters<T>) {\n const key = resolver ? resolver(...args) : JSON.stringify(args);\n const now = Date.now();\n const entry = cache.get(key);\n\n // Check if we have a valid (unexpired) entry\n if (entry) {\n if (!maxAge || now - entry.timestamp < maxAge) {\n return entry.value;\n }\n // Delete it since it's expired\n cache.delete(key);\n }\n\n const result = fn.apply(this, args);\n cache.set(key, { value: result, timestamp: now });\n return result;\n } as MemoizedFunction<T>;\n\n memoized.clear = () => cache.clear();\n\n return memoized;\n}\n\nexport const fn = {\n memoize\n};\n","export interface DateOptions {\n /** The reference timestamp to calculate from. Defaults to Date.now() */\n since?: number | Date;\n /** If true, returns null if the target time is in the past. */\n nullIfPast?: boolean;\n /** If true, omits the \" ago\" suffix for past dates. */\n ignorePast?: boolean;\n}\n\nexport interface ParseOptions {\n /** Return value in seconds instead of milliseconds. */\n unit?: \"ms\" | \"s\";\n /** If true, returns the absolute Unix timestamp (Date.now() + result). */\n fromNow?: boolean;\n}\n\nconst MS_MAP: Record<string, number> = {\n ms: 1,\n s: 1000,\n m: 60000,\n h: 3600000,\n d: 86400000,\n w: 604800000,\n mth: 2419200000,\n y: 31536000000\n};\n\n/**\n * Duration formatter.\n *\n * Available styles:\n * - Digital (00:00)\n * - HMS\n * - YMDHMS.\n * @param target The target time to calculate from.\n * @param style The output style to use.\n * @param options Formatting options.\n */\nfunction duration(\n target: number | Date,\n style: \"digital\" | \"hms\" | \"ymdhms\" = \"hms\",\n options: DateOptions = {}\n): string | null {\n const targetMs = target instanceof Date ? target.getTime() : Number(target);\n const sinceMs = options.since instanceof Date ? options.since.getTime() : Number(options.since) || Date.now();\n const diff = Math.abs(targetMs - sinceMs);\n\n if (diff === 0) return style === \"digital\" ? \"00:00\" : \"now\";\n\n const s = Math.floor(diff / 1000) % 60;\n const m = Math.floor(diff / 60000) % 60;\n const h = Math.floor(diff / 3600000) % 24;\n const d = Math.floor(diff / 86400000);\n\n if (style === \"digital\") {\n const parts = [m, s].map(v => String(v).padStart(2, \"0\"));\n if (h > 0 || d > 0) parts.unshift(String(h).padStart(2, \"0\"));\n if (d > 0) parts.unshift(String(d)); // Days don't necessarily need padding\n return parts.join(\":\");\n }\n\n const result: string[] = [];\n const push = (val: number, label: string) => {\n if (val > 0) result.push(`${val} ${label}${val === 1 ? \"\" : \"s\"}`);\n };\n\n if (style === \"ymdhms\") push(d, \"day\");\n push(h, \"hour\");\n push(m, \"minute\");\n push(s, \"second\");\n\n if (result.length === 0) return \"0 seconds\";\n if (result.length === 1) return result[0]!;\n\n const last = result.pop();\n return `${result.join(\", \")} and ${last}`;\n}\n\n/**\n * Formats a date or timestamp into a human-readable relative string (e.g., \"3 days ago\").\n * @param date - The Date object or timestamp to compare.\n * @param locale - The BCP 47 language tag.\n */\nfunction eta(date: Date | number, locale?: Intl.LocalesArgument): string {\n const rtf = new Intl.RelativeTimeFormat(locale, { numeric: \"auto\" });\n const elapsed = (typeof date === \"number\" ? date : date.getTime()) - Date.now();\n\n // Division factors for different units\n const units: { unit: Intl.RelativeTimeFormatUnit; ms: number }[] = [\n { unit: \"year\", ms: 31536000000 },\n { unit: \"month\", ms: 2628000000 },\n { unit: \"day\", ms: 86400000 },\n { unit: \"hour\", ms: 3600000 },\n { unit: \"minute\", ms: 60000 },\n { unit: \"second\", ms: 1000 }\n ];\n\n // Find the largest unit that fits the elapsed time\n for (const { unit, ms } of units) {\n if (Math.abs(elapsed) >= ms || unit === \"second\") {\n return rtf.format(Math.round(elapsed / ms), unit);\n }\n }\n\n return \"\";\n}\n\n/**\n * Parses shorthand strings (1h 30m) into milliseconds or seconds.\n */\nfunction parse(str: string | number, options: ParseOptions = {}): number {\n if (typeof str === \"number\") return str;\n\n const matches = str.matchAll(/(-?\\d+)([a-z]+)/gi);\n let totalMs = 0;\n let found = false;\n\n for (const [_, value, unit] of matches) {\n if (!value || !unit) continue;\n const factor = MS_MAP[unit.toLowerCase()];\n if (factor) {\n totalMs += parseInt(value) * factor;\n found = true;\n }\n }\n\n if (!found) throw new Error(`parse: Invalid time format: \"${str}\"`);\n\n const result = options.unit === \"s\" ? totalMs / 1000 : totalMs;\n return options.fromNow ? Date.now() + result : result;\n}\n\nexport const date = {\n duration,\n eta,\n parse\n};\n","/**\n * Formats a number as a currency string using international standards.\n * @param num - The number to process.\n * @param options - Formatting options.\n * @example\n * currency(1234.5); // \"$1,234.50\"\n * currency(1234.5, 'EUR', 'de-DE'); // \"1.234,50 €\"\n * currency(500, 'JPY'); // \"¥500\" (Yen has no decimals)\n */\nfunction currency(\n num: number,\n options: {\n /** The ISO currency code (e.g., 'USD', 'EUR', 'GBP'). */\n currency?: string;\n /** The BCP 47 language tag. */\n locale?: Intl.LocalesArgument;\n } = {}\n): string {\n return new Intl.NumberFormat(options.locale, {\n style: \"currency\",\n currency: options.currency\n }).format(num);\n}\n\n/**\n * Formats a number with thousands separators and optional decimal precision.\n * @param num - The number to process.\n * @param options - Formatting options.\n * @example\n * num(1000000); // \"1,000,000\" (en-US default)\n * num(1000, { locale: 'de-DE' }); // \"1.000\"\n * num(1234.567, { precision: 2 }); // \"1,234.57\"\n */\nfunction number(\n num: number,\n options: {\n /** The BCP 47 language tag. */\n locale?: Intl.LocalesArgument;\n precision?: number;\n } = {}\n): string {\n return new Intl.NumberFormat(options.locale, {\n minimumFractionDigits: options.precision,\n maximumFractionDigits: options.precision\n }).format(num);\n}\n\nfunction memory(\n bytes: number,\n decimals: number = 1,\n units: string[] = [\"B\", \"KB\", \"MB\", \"GB\", \"TB\", \"PB\", \"EB\", \"ZB\", \"YB\"]\n): string {\n // Handle 0 or negative numbers immediately\n if (bytes <= 0) return `0 ${units[0]}`;\n\n // Calculate the magnitude index (0 for B, 1 for KB, etc.)\n const i = Math.min(Math.floor(Math.log(bytes) / Math.log(1024)), units.length - 1);\n const val = bytes / Math.pow(1024, i);\n return `${val.toFixed(i === 0 ? 0 : decimals)} ${units[i]}`;\n}\n\n/**\n * Formats a number to an ordinal (e.g., 1st, 2nd, 3rd).\n * @param num The number to process.\n * @param locale The BCP 47 language tag.\n */\nfunction ordinal(num: number | string, locale?: Intl.LocalesArgument): string {\n const _num = Number(num);\n if (isNaN(_num)) throw new TypeError(\"Invalid input\");\n\n const pr = new Intl.PluralRules(locale, { type: \"ordinal\" });\n const rule = pr.select(_num);\n\n const suffixes: Record<string, string> = {\n one: \"st\",\n two: \"nd\",\n few: \"rd\",\n other: \"th\"\n };\n\n const suffix = suffixes[rule] || \"th\";\n return _num.toLocaleString(locale) + suffix;\n}\n\n/**\n * Formats a number into a compact, human-readable string (e.g., 1.2k, 1M).\n * @param num - The number to process.\n * @param locale - The BCP 47 language tag.\n */\nfunction compactNumber(num: number, locale?: Intl.LocalesArgument): string {\n return new Intl.NumberFormat(locale, {\n notation: \"compact\",\n compactDisplay: \"short\",\n maximumFractionDigits: 1\n }).format(num);\n}\n\nexport const format = {\n currency,\n number,\n memory,\n ordinal,\n compactNumber\n};\n","import _fs from \"node:fs\";\nimport { join } from \"node:path\";\n\nexport interface ReadDirOptions {\n /** Whether to scan subdirectories. [default: true] */\n recursive?: boolean;\n}\n\n/**\n * Recursively (or shallowly) scans a directory and returns an array of relative file paths.\n * @param path The path to the directory.\n * @param options Options for the readDir function.\n */\nfunction readDir(path: string, options: ReadDirOptions = {}): string[] {\n const { recursive = true } = options;\n\n if (!_fs.existsSync(path)) return [];\n\n // Shallow read\n if (!recursive) {\n return _fs.readdirSync(path).filter(fn => {\n return _fs.statSync(join(path, fn)).isFile();\n });\n }\n\n // Recursive walk\n const walk = (dir: string, base: string = \"\"): string[] => {\n const results: string[] = [];\n\n // Using withFileTypes is much faster as it returns Dirent objects\n const entries = _fs.readdirSync(dir, { withFileTypes: true });\n\n for (const entry of entries) {\n const relativePath = base ? join(base, entry.name) : entry.name;\n const fullPath = join(dir, entry.name);\n\n if (entry.isDirectory()) {\n results.push(...walk(fullPath, relativePath));\n } else if (entry.isFile()) {\n results.push(relativePath);\n }\n }\n\n return results;\n };\n\n return walk(path);\n}\n\nexport const fs = {\n readDir\n};\n","/**\n * Checks if a value is defined (not null or undefined).\n */\nfunction defined<T>(val: T | undefined | null): val is T {\n return val !== undefined && val !== null;\n}\n\n/**\n * Checks if a value is an empty object, array, or string.\n */\nfunction empty(val: unknown): boolean {\n if (!defined(val)) return true;\n if (string(val) || Array.isArray(val)) return val.length === 0;\n if (object(val)) return Object.keys(val).length === 0;\n return false;\n}\n\n/**\n * Checks if a number is within a specified range.\n * @param num The number to check.\n * @param min The minimum or maximum value of the range.\n * @param max The maximum value of the range (optional).\n */\nfunction inRange(num: number, max: number): boolean;\nfunction inRange(num: number, min: number, max: number): boolean;\nfunction inRange(num: number, a: number, b?: number): boolean {\n // If b is undefined, we are clamping [0, a]\n // If b is defined, we are clamping [a, b]\n let min = b !== undefined ? a : 0;\n let max = b !== undefined ? b : a;\n\n // Handles a swapped min/max\n if (min > max) [min, max] = [max, min];\n return num >= min && num <= max;\n}\n\n/**\n * Checks if a value is a plain object (not an array, null, or function).\n */\nfunction object(val: unknown): val is Record<string, any> {\n return val !== null && typeof val === \"object\" && !Array.isArray(val);\n}\n\n/**\n * Checks if an array is sorted.\n */\nfunction sorted<T>(arr: T[], comparator?: (a: T, b: T) => number): boolean {\n for (let i = 0; i < arr.length - 1; i++) {\n const comp = comparator ? comparator(arr[i]!, arr[i + 1]!) : arr[i]! > arr[i + 1]! ? 1 : -1;\n if (comp > 0) return false;\n }\n return true;\n}\n\n/**\n * Checks if a value is a string.\n */\nfunction string(val: unknown): val is string {\n return typeof val === \"string\";\n}\n\n/**\n * Checks if a date is today.\n */\nfunction today(date: number | Date): boolean {\n const d = date instanceof Date ? date : new Date(date);\n const today = new Date();\n return d.getDate() === today.getDate() && d.getMonth() === today.getMonth() && d.getFullYear() === today.getFullYear();\n}\n\nexport const is = {\n defined,\n empty,\n inRange,\n object,\n sorted,\n string,\n today\n};\n","/**\n * Clamps a number within a specified range.\n * @param num The number to check.\n * @param min The minimum or maximum value of the range.\n * @param max The maximum value of the range (optional).\n */\nfunction clamp(num: number, max: number): number;\nfunction clamp(num: number, min: number, max: number): number;\nfunction clamp(num: number, a: number, b?: number): number {\n // If b is undefined, we are clamping [0, a]\n // If b is defined, we are clamping [a, b]\n let min = b !== undefined ? a : 0;\n let max = b !== undefined ? b : a;\n\n // Handles a swapped min/max\n if (min > max) [min, max] = [max, min];\n return Math.max(min, Math.min(num, max));\n}\n\n/**\n * Calculates the interpolation factor (0-1) of a value between two points.\n * @param start - The starting value (0%).\n * @param end - The ending value (100%).\n * @param value - The value to interpolate.\n * @example\n * invLerp(0, 100, 50); // 0.5\n */\nfunction invLerp(start: number, end: number, value: number): number {\n if (start === end) return 0;\n return (value - start) / (end - start);\n}\n\n/**\n * Linearly interpolates between two values.\n * @param start - The starting value (0%).\n * @param end - The ending value (100%).\n * @param t - The interpolation factor (0 to 1).\n * @example\n * lerp(0, 100, 0.5); // 50\n * lerp(10, 20, 0.2); // 12\n */\nfunction lerp(start: number, end: number, t: number): number {\n return start + (end - start) * t;\n}\n\n/**\n * Converts seconds to milliseconds and rounds it to the nearest integer.\n * @param num The number of seconds to convert.\n */\nfunction ms(num: number): number {\n return Math.floor(num * 1000);\n}\n\n/**\n * Calculates the percentage value between two numbers.\n * @param a The numerator.\n * @param b The denominator.\n * @param round Whether to round the result to the nearest integer.\n * @example\n * percent(50, 100) --> 50 // 50%\n * percent(30, 40) --> 75 // 75%\n */\nfunction percent(a: number, b: number, round: boolean = true): number {\n const result = (a / b) * 100;\n return round ? Math.floor(result) : result;\n}\n\n/**\n * Maps a value from one range to another.\n * @param value - The value to map.\n * @param inMin - The minimum value of the input range.\n * @param inMax - The maximum value of the input range.\n * @param outMin - The minimum value of the output range.\n * @param outMax - The maximum value of the output range.\n * @example\n * // Convert mouse X position (0-1920) to a volume level (0-1)\n * const volume = remap(mouseX, 0, 1920, 0, 1);\n */\nfunction remap(value: number, inMin: number, inMax: number, outMin: number, outMax: number): number {\n const t = invLerp(inMin, inMax, value);\n return lerp(outMin, outMax, t);\n}\n\n/**\n * Converts milliseconds to seconds and rounds it to the nearest integer.\n * @param num The number of milliseconds to convert.\n */\nfunction secs(num: number): number {\n return Math.floor(num / 1000);\n}\n\n/**\n * Returns the sum of an array of numbers. Negative values subtract from the total.\n * @param array The array to sum.\n * @param selector Function that selects the item's weight.\n * @param ignoreNaN If true, NaN values will not throw an error.\n */\nfunction sum<T>(array: T[], selector?: (item: T) => number): number {\n const _array = selector ? array.map(selector) : array;\n if (!_array.every(v => typeof v === \"number\")) {\n throw new TypeError(`sum: Array must only contain numbers.`);\n }\n\n return _array.reduce((a, b) => {\n return (isNaN(b) ? 0 : b) < 0 ? a - -b : a + (b || 0);\n }, 0);\n}\n\nexport const math = {\n clamp,\n invLerp,\n lerp,\n ms,\n percent,\n remap,\n secs,\n sum\n};\n","/**\n * Retrieves a nested property.\n * @param obj The object to process.\n * @param path The path to retrieve (e.g., 'data.users[0].id').\n * @param defaultValue The default value to return if the property does not exist.\n */\nfunction get<T = any>(obj: Record<string, any>, path: string, defaultValue?: T): T {\n if (!obj) throw new Error(\"get: Target object is null or undefined\");\n\n // Normalize and split\n const parts = path.replace(/\\[(\\d+)\\]/g, \".$1\").split(\".\");\n let current: any = obj;\n const trace: string[] = [];\n\n for (const part of parts) {\n trace.push(part);\n\n // Check if the link in the chain exists\n if (current === null || typeof current !== \"object\" || !(part in current)) {\n // Return the default value, if provided\n if (arguments.length === 3) return defaultValue as T;\n\n // Else, throw a debug error with the trace path\n const reach = trace.join(\".\");\n throw new Error(`get: Path broken at \"${reach}\". ` + `Property \"${part}\" is missing on ${typeof current}.`);\n }\n\n current = current[part];\n }\n\n // Handle the case where the final value found is undefined\n if (current === undefined && arguments.length === 3) {\n return defaultValue as T;\n }\n\n return current as T;\n}\n\n/**\n * Checks if a nested path exists within an object.\n * @param obj The object to process.\n * @param path The path string (e.g., 'data.users[0].id').\n */\nfunction has(obj: Record<string, any>, path: string): boolean {\n if (!obj || !path) return false;\n\n const parts = path.replace(/\\[(\\d+)\\]/g, \".$1\").split(\".\");\n let current: any = obj;\n\n for (let i = 0; i < parts.length; i++) {\n const part = parts[i]!;\n\n // If the current level isn't an object, the path can't continue\n if (current === null || typeof current !== \"object\") {\n return false;\n }\n\n // Check if the property exists at this level\n if (!(part in current)) {\n return false;\n }\n\n current = current[part];\n }\n\n return true;\n}\n\n/**\n * Sets a nested property value. Creates missing objects/arrays along the path.\n * @param obj The object to process.\n * @param path The path to set (e.g., 'data.users[0].id').\n * @param value The value to inject.\n */\nfunction set(obj: Record<string, any>, path: string, value: any): void {\n const parts = path.replace(/\\[(\\d+)\\]/g, \".$1\").split(\".\");\n let current: any = obj;\n\n for (let i = 0; i < parts.length; i++) {\n const part = parts[i]!;\n const isLast = i === parts.length - 1;\n\n if (isLast) {\n current[part] = value;\n return;\n }\n\n // If the next part is a number, we should create an array, otherwise an object\n const nextPartIsNumber = !isNaN(Number(parts[i + 1]));\n\n if (!(part in current) || current[part] === null || typeof current[part] !== \"object\") {\n current[part] = nextPartIsNumber ? [] : {};\n }\n\n current = current[part];\n }\n}\n\n/**\n * Deep merges multiple objects.\n * @param target - The base object to merge into.\n * @param sources - One or more objects to merge.\n */\nfunction merge<T, S1>(target: T, s1: S1): T & S1;\nfunction merge<T, S1, S2>(target: T, s1: S1, s2: S2): T & S1 & S2;\nfunction merge<T, S1, S2, S3>(target: T, s1: S1, s2: S2, s3: S3): T & S1 & S2 & S3;\nfunction merge(target: any, ...sources: any[]): any;\nfunction merge(target: any, ...sources: any[]) {\n // Loop through every source object provided\n for (const source of sources) {\n if (!source) continue;\n\n Object.keys(source).forEach(key => {\n const targetValue = target[key];\n const sourceValue = source[key];\n\n if (Array.isArray(targetValue) && Array.isArray(sourceValue)) {\n // Concat arrays\n (target as any)[key] = targetValue.concat(sourceValue);\n } else if (\n targetValue &&\n typeof targetValue === \"object\" &&\n sourceValue &&\n typeof sourceValue === \"object\" &&\n !Array.isArray(sourceValue)\n ) {\n // If both are objects, recurse\n merge(targetValue, sourceValue);\n } else {\n // Else, just set the value\n (target as any)[key] = sourceValue;\n }\n });\n }\n\n return target;\n}\n\n/**\n * Creates an object composed of the picked object properties.\n * @param obj The object to process.\n * @param keys The keys to pick from the object.\n */\nfunction pick<T extends object, K extends keyof T>(obj: T, keys: K[]): Pick<T, K> {\n const result = {} as Pick<T, K>;\n for (const key of keys) {\n if (key in obj) {\n result[key] = obj[key];\n }\n }\n return result;\n}\n\n/**\n * Creates an object composed of the omitted object properties.\n * @param obj The object to process.\n * @param keys The keys to omit from the object.\n */\nfunction omit<T extends object, K extends keyof T>(obj: T, keys: K[]): Omit<T, K> {\n const result = { ...obj };\n for (const key of keys) {\n delete result[key];\n }\n return result;\n}\n\nexport const obj = {\n get,\n has,\n set,\n merge,\n pick,\n omit\n};\n","/**\n * Escapes regex characters in the given string.\n * @param str - The string to process.\n */\nfunction escapeRegex(str: string): string {\n return str.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n}\n\n/**\n * Retrieves a substring following a specific flag.\n * @param str The string to process.\n * @param flag A string or regex to look for.\n */\nfunction getFlag(str: string, flag: string | RegExp, length?: number): string | null {\n // NOTE: Using \\b ensures we don't match \"flag\" inside \"flagpole\"\n const regex = flag instanceof RegExp ? flag : new RegExp(`${escapeRegex(flag)}\\\\b`, \"g\");\n\n const match = regex.exec(str);\n if (!match) return null;\n\n const startIndex = match.index + match[0].length;\n let result = str.slice(startIndex).trimStart();\n\n // If length is provided, limit by word count\n if (length !== undefined) {\n return result.split(/\\s+/).slice(0, length).join(\" \");\n }\n\n return result || null;\n}\n\n/**\n * Checks if a string contains a specific flag.\n * @param str The string to process.\n * @param flag A string or regex to look for.\n */\nfunction hasFlag(str: string, flag: string | RegExp): boolean {\n if (flag instanceof RegExp) return flag.test(str);\n\n // NOTE: Using \\b ensures we don't match \"flag\" inside \"flagpole\"\n const pattern = new RegExp(`${escapeRegex(flag)}\\\\b`);\n return pattern.test(str);\n}\n\n/**\n * Formats a string to Title Case, optionally keeping acronyms and skipping minor words (the, and, of, etc.).\n * @param str The string to process.\n * @param smart If true, will keep acronyms and skip minor words. [default: true]\n */\nfunction toTitleCase(str: string, smart = true): string {\n const minorWords = /^(a|an|and|as|at|but|by|en|for|if|in|of|on|or|the|to|v\\.?|via)$/i;\n\n return str.replace(/\\w\\S*/g, (txt, index) => {\n // Always capitalize the first word, otherwise check if it's a minor word\n if (smart && index !== 0 && minorWords.test(txt)) {\n return txt.toLowerCase();\n }\n\n // If it's already uppercase (more than 1 letter), assume it's an acronym\n if (smart && txt.length > 1 && txt === txt.toUpperCase()) {\n return txt;\n }\n\n return txt.charAt(0).toUpperCase() + txt.substring(1).toLowerCase();\n });\n}\n\nexport const str = {\n escapeRegex,\n getFlag,\n hasFlag,\n toTitleCase\n};\n","export interface DebouncedFunction<T extends (...args: any[]) => any> {\n (...args: Parameters<T>): void;\n /** Cancels the debounced function. */\n cancel: () => void;\n}\n\n/**\n * Only executes after 'wait' ms have passed since the last call.\n * @param fn The function to debounce.\n * @param wait The time to wait in milliseconds.\n * @param options Options for the debounce function.\n * @example\n * const search = debounce((str) => console.log(\"Searching:\", str), 500);\n * // Even if called rapidly, it only logs once 500ms after the last call.\n * search('a');\n * search('ab');\n * search('abc'); // Only 'abc' will be logged.\n * // Cancel a pending execution\n * search.cancel();\n */\nfunction debounce<T extends (...args: any[]) => any>(\n fn: T,\n wait: number,\n options: {\n /** Calls the function immediately on the leading edge. */\n immediate?: boolean;\n } = {}\n): DebouncedFunction<T> {\n let timeoutId: ReturnType<typeof setTimeout> | undefined;\n const leading = options.immediate ?? false;\n\n const debounced = function (this: any, ...args: Parameters<T>) {\n const callNow = leading && !timeoutId;\n if (timeoutId) clearTimeout(timeoutId);\n\n timeoutId = setTimeout(() => {\n timeoutId = undefined;\n // If we aren't in leading mode, fire the function at the end\n if (!leading) fn.apply(this, args);\n }, wait);\n\n // If leading is true and no timer was active, fire immediately\n if (callNow) fn.apply(this, args);\n } as DebouncedFunction<T>;\n\n debounced.cancel = () => {\n if (timeoutId) {\n clearTimeout(timeoutId);\n timeoutId = undefined;\n }\n };\n\n return debounced;\n}\n\n/**\n * Executes at most once every 'limit' ms.\n * @param fn The function to throttle.\n * @param limit The time to wait in milliseconds.\n * @example\n * const handleScroll = throttle(() => console.log('Scroll position:', window.scrollY), 200);\n * // Even if the browser fires 100 scroll events per second,\n * // this function will only execute once every 200ms.\n * window.addEventListener('scroll', handleScroll);\n */\nfunction throttle<T extends (...args: any[]) => any>(fn: T, limit: number): (...args: Parameters<T>) => void {\n let inThrottle = false;\n\n return function (this: any, ...args: Parameters<T>) {\n if (!inThrottle) {\n fn.apply(this, args);\n inThrottle = true;\n setTimeout(() => (inThrottle = false), limit);\n }\n };\n}\n\nexport const timing = {\n debounce,\n throttle\n};\n","export type ToRecordContext<T, V> = {\n index: number;\n lastValue: V | undefined;\n newRecord: Readonly<Record<string | number, V>>;\n originalArray: ReadonlyArray<T>;\n};\n\n/**\n * Transforms an array into a object record with access to the object as it's being built.\n * @param array Array to process.\n * @param callback Function to map over the array.\n */\nfunction record<T, V>(\n array: ReadonlyArray<T>,\n callback: (item: T, context: ToRecordContext<T, V>) => { key: string | number; value: V }\n): Record<string | number, V> {\n const result: Record<string | number, V> = {};\n let lastValue: V | undefined = undefined;\n\n for (let i = 0; i < array.length; i++) {\n const { key, value } = callback(array[i]!, {\n index: i,\n lastValue,\n // NOTE: This is a reference to the object currently being built\n newRecord: result,\n originalArray: array\n });\n\n result[key] = value;\n lastValue = value;\n }\n\n return result;\n}\n\nexport const to = {\n record\n};\n","/**\n * Pipes a value through a series of functions.\n * Each function takes the output of the previous one.\n */\nexport function Pipe<A>(value: A): A;\nexport function Pipe<A, B>(value: A, fn1: (arg: A) => B): B;\nexport function Pipe<A, B, C>(value: A, fn1: (arg: A) => B, fn2: (arg: B) => C): C;\nexport function Pipe<A, B, C, D>(value: A, fn1: (arg: A) => B, fn2: (arg: B) => C, fn3: (arg: C) => D): D;\n// prettier-ignore\nexport function Pipe<A, B, C, D, E>(value: A, fn1: (arg: A) => B, fn2: (arg: B) => C, fn3: (arg: C) => D, fn4: (arg: D) => E): E;\n// prettier-ignore\nexport function Pipe<A, B, C, D, E, F>(value: A, fn1: (arg: A) => B, fn2: (arg: B) => C, fn3: (arg: C) => D, fn4: (arg: D) => E, fn5: (arg: E) => F): F;\n// prettier-ignore\nexport function Pipe<A, B, C, D, E, F, G>(value: A, fn1: (arg: A) => B, fn2: (arg: B) => C, fn3: (arg: C) => D, fn4: (arg: D) => E, fn5: (arg: E) => F, fn6: (arg: F) => G): G;\n// prettier-ignore\nexport function Pipe<A, B, C, D, E, F, G, H>(value: A, fn1: (arg: A) => B, fn2: (arg: B) => C, fn3: (arg: C) => D, fn4: (arg: D) => E, fn5: (arg: E) => F, fn6: (arg: F) => G, fn7: (arg: G) => H): H;\n// prettier-ignore\nexport function Pipe<A, B, C, D, E, F, G, H, I>(value: A, fn1: (arg: A) => B, fn2: (arg: B) => C, fn3: (arg: C) => D, fn4: (arg: D) => E, fn5: (arg: E) => F, fn6: (arg: F) => G, fn7: (arg: G) => H, fn8: (arg: H) => I): I;\n// prettier-ignore\nexport function Pipe<A, B, C, D, E, F, G, H, I, J>(value: A, fn1: (arg: A) => B, fn2: (arg: B) => C, fn3: (arg: C) => D, fn4: (arg: D) => E, fn5: (arg: E) => F, fn6: (arg: F) => G, fn7: (arg: G) => H, fn8: (arg: H) => I, fn9: (arg: I) => J): J;\n// prettier-ignore\nexport function Pipe<A, B, C, D, E, F, G, H, I, J, K>(value: A, fn1: (arg: A) => B, fn2: (arg: B) => C, fn3: (arg: C) => D, fn4: (arg: D) => E, fn5: (arg: E) => F, fn6: (arg: F) => G, fn7: (arg: G) => H, fn8: (arg: H) => I, fn9: (arg: I) => J, fn10: (arg: J) => K): K;\n\nexport function Pipe(value: any, ...fns: Function[]): any {\n return fns.reduce((acc, fn) => fn(acc), value);\n}\n","import fs from \"node:fs\";\nimport path from \"node:path\";\n\ntype StorePayload<T> = {\n value: T;\n expiry: number | null;\n};\n\nexport class Storage {\n private isNode = typeof window === \"undefined\";\n private filePath: string | null = null;\n private memoryCache = new Map<string, string>();\n\n private loadFromFile() {\n if (this.filePath && fs.existsSync(this.filePath)) {\n try {\n const data = JSON.parse(fs.readFileSync(this.filePath, \"utf-8\"));\n Object.entries(data).forEach(([k, v]) => this.memoryCache.set(k, JSON.stringify(v)));\n } catch (err) {\n console.error(`Store: Failed to load file '${this.filePath}'`, err);\n }\n }\n }\n\n private persist() {\n if (this.isNode && this.filePath) {\n const out: Record<string, any> = {};\n this.memoryCache.forEach((v, k) => (out[k] = JSON.parse(v)));\n fs.writeFileSync(this.filePath, JSON.stringify(out, null, 2));\n }\n }\n\n /**\n * A lightweight, high-performant persistent storage system.\n * Uses JSON files in Node.js, localStorage in the browser.\n * @param fileName Only used in Node.js to create a persistent .json file.\n * @param directory The directory for the file. Defaults to current working directory.\n */\n constructor(fileName?: string, directory: string = process.cwd()) {\n if (this.isNode && fileName) {\n this.filePath = path.join(directory, fileName.endsWith(\".json\") ? fileName : `${fileName}.json`);\n this.loadFromFile();\n }\n }\n\n has(key: string): boolean {\n if (!this.isNode && window.localStorage) {\n return localStorage.getItem(key) !== null;\n }\n return this.memoryCache.has(key);\n }\n\n get<T>(key: string): T | null {\n let raw: string | null = null;\n\n if (!this.isNode && window.localStorage) {\n raw = localStorage.getItem(key);\n } else {\n raw = this.memoryCache.get(key) || null;\n }\n\n if (!raw) return null;\n\n const payload: StorePayload<T> = JSON.parse(raw);\n if (payload.expiry && Date.now() > payload.expiry) {\n this.remove(key);\n this.persist();\n return null;\n }\n return payload.value;\n }\n\n set<T>(key: string, value: T, ttl?: number): void {\n const payload: StorePayload<T> = {\n value,\n expiry: ttl ? Date.now() + ttl : null\n };\n const serialized = JSON.stringify(payload);\n\n if (!this.isNode && window.localStorage) {\n localStorage.setItem(key, serialized);\n } else {\n this.memoryCache.set(key, serialized);\n this.persist();\n }\n }\n\n remove(key: string): void {\n if (!this.isNode && window.localStorage) {\n localStorage.removeItem(key);\n } else {\n this.memoryCache.delete(key);\n this.persist();\n }\n }\n\n clear(): void {\n if (!this.isNode && window.localStorage) {\n localStorage.clear();\n } else {\n this.memoryCache.clear();\n this.persist();\n }\n }\n}\n","export class Cache<T> {\n private cache = new Map<string | number, { value: T; expiresAt: number | null }>();\n private interval: any;\n\n /**\n * A lightweight, high-performant in-memory cache.\n * Uses Map for O(1) lookups and an optional cleanup interval.\n * @param cleanupMs The interval in milliseconds to run the cleanup function. [default: 60000 (1 minute)]\n */\n constructor(cleanupMs: number = 60_000) {\n // Only run cleanup if the interval is positive\n if (cleanupMs > 0) {\n this.interval = setInterval(() => this.cleanup(), cleanupMs);\n // In Node.js, allow the process to exit even if this interval is running\n if (this.interval.unref) this.interval.unref();\n }\n }\n\n set(key: string | number, value: T, ttlMs?: number): void {\n this.cache.set(key, {\n value,\n expiresAt: ttlMs ? Date.now() + ttlMs : null\n });\n }\n\n get(key: string | number): T | null {\n const data = this.cache.get(key);\n if (!data) return null;\n\n if (data.expiresAt && Date.now() > data.expiresAt) {\n // Passive cleanup\n this.cache.delete(key);\n return null;\n }\n return data.value;\n }\n\n private cleanup(): void {\n if (this.cache.size === 0) return;\n\n const now = Date.now();\n let keysProcessed = 0;\n const maxKeysToScan = 20; // Limit per cycle to avoid CPU spikes\n\n // Iterate through the map\n for (const [key, data] of this.cache) {\n if (data.expiresAt && now > data.expiresAt) {\n this.cache.delete(key);\n }\n\n keysProcessed++;\n if (keysProcessed >= maxKeysToScan) break;\n }\n }\n\n clear(): void {\n this.cache.clear();\n }\n}\n","import EventEmitter from \"node:events\";\nimport { TypedEmitter } from \"./types\";\n\nexport type LoopState = \"running\" | \"paused\" | \"stopped\";\n\nexport interface LoopEvents<T> {\n start: [];\n tick: [result: T];\n pause: [{ remaining: number }];\n resume: [];\n stop: [];\n error: [error: any];\n}\n\nconst TypedEmitterBase = EventEmitter as { new <T>(): TypedEmitter<LoopEvents<T>> };\n\nexport class Loop<T = any> extends TypedEmitterBase<T> {\n private _state: LoopState = \"stopped\";\n private timeoutId: any = null;\n private delay: number;\n private fn: (loop: Loop<T>) => Promise<T> | T;\n\n private startTime: number = 0;\n private remaining: number = 0;\n\n private async run() {\n const currentState: LoopState = this._state;\n\n if (currentState === \"stopped\" || currentState === \"paused\") return;\n\n try {\n const result = await this.fn(this);\n this.emit(\"tick\", result);\n } catch (err) {\n this.emit(\"error\", err);\n }\n\n // Re-check state after the async function finishes\n if (this._state === \"running\") {\n this.startTime = Date.now();\n this.remaining = 0;\n this.clearTimer();\n this.timeoutId = setTimeout(() => this.run(), this.delay);\n }\n }\n\n private clearTimer() {\n if (this.timeoutId) {\n clearTimeout(this.timeoutId);\n this.timeoutId = null;\n }\n }\n\n /**\n * Creates an interval. If the function is async, it will wait for it to complete before scheduling the next run.\n * @param fn The function to run.\n * @param delay The delay between runs in milliseconds.\n * @param immediate Whether to start the loop immediately. [default: true]\n */\n constructor(fn: (loop: Loop<T>) => Promise<T> | T, delay: number, immediate = true) {\n super();\n this.fn = fn;\n this.delay = delay;\n if (immediate) this.start();\n }\n\n get state(): LoopState {\n return this._state;\n }\n\n /** Starts the loop. */\n start() {\n if (this._state !== \"stopped\") return;\n this._state = \"running\";\n this.emit(\"start\");\n this.run();\n }\n\n /** Resumes a paused loop. */\n resume() {\n if (this._state !== \"paused\") return;\n this._state = \"running\";\n this.emit(\"resume\");\n if (this.remaining <= 0) {\n this.run();\n } else {\n this.timeoutId = setTimeout(() => this.run(), this.remaining);\n }\n }\n\n /** Stops the loop. */\n stop() {\n const wasRunning = this._state !== \"stopped\";\n this._state = \"stopped\";\n this.remaining = 0;\n this.clearTimer();\n if (wasRunning) this.emit(\"stop\");\n }\n\n /** Pauses the execution. */\n pause() {\n if (this._state !== \"running\") return;\n this._state = \"paused\";\n const elapsed = Date.now() - this.startTime;\n this.remaining = Math.max(0, this.delay - elapsed);\n this.emit(\"pause\", { remaining: this.remaining });\n this.clearTimer();\n }\n\n /**\n * Sets the delay between runs\n * @param ms The new delay in milliseconds.\n */\n setDelay(ms: number) {\n this.delay = ms;\n }\n\n /** Manually trigger the function once without affecting the loop. */\n async execute() {\n await this.fn(this);\n }\n}\n"],"mappings":"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","names":["str","percent","index","seed","fn","ms","fn","date","ms","str","path","_fs","fn","arr","date","today","obj","path","str","str","index","fn","wait","fn","import_node_fs","import_node_path","fs","path","EventEmitter","fn","ms"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/arr.ts","../src/rnd.ts","../src/async.ts","../src/fn.ts","../src/date.ts","../src/format.ts","../src/fs.ts","../src/is.ts","../src/math.ts","../src/obj.ts","../src/str.ts","../src/timing.ts","../src/to.ts","../src/Pipe.ts","../src/Storage.ts","../src/Cache.ts","../src/Loop.ts"],"sourcesContent":["import * as arrayUtils from \"./arr\";\nimport * as asyncUtils from \"./async\";\nimport * as functionUtils from \"./fn\";\nimport * as dateUtils from \"./date\";\nimport * as formatUtils from \"./format\";\nimport * as fileUtils from \"./fs\";\nimport * as isUtils from \"./is\";\nimport * as mathUtils from \"./math\";\nimport * as objectUtils from \"./obj\";\nimport * as randomUtils from \"./rnd\";\nimport * as stringUtils from \"./str\";\nimport * as timingUtils from \"./timing\";\nimport * as toUtils from \"./to\";\nimport { Pipe } from \"./Pipe\";\nimport { Storage } from \"./Storage\";\nimport { Cache } from \"./Cache\";\nimport { Loop } from \"./Loop\";\n\nconst qznt = {\n ...arrayUtils,\n ...asyncUtils,\n ...functionUtils,\n ...dateUtils,\n ...formatUtils,\n ...fileUtils,\n ...isUtils,\n ...mathUtils,\n ...objectUtils,\n ...timingUtils,\n ...randomUtils,\n ...stringUtils,\n ...toUtils,\n Pipe,\n Storage,\n Cache,\n Loop\n};\n\nexport const $ = qznt;\nexport default qznt;\n\nexport * from \"./arr\";\nexport * from \"./async\";\nexport * from \"./fn\";\nexport * from \"./date\";\nexport * from \"./format\";\nexport * from \"./fs\";\nexport * from \"./is\";\nexport * from \"./math\";\nexport * from \"./obj\";\nexport * from \"./rnd\";\nexport * from \"./str\";\nexport * from \"./timing\";\nexport * from \"./to\";\nexport * from \"./types\";\nexport { Pipe } from \"./Pipe\";\nexport { Storage } from \"./Storage\";\nexport { Cache } from \"./Cache\";\nexport { Loop } from \"./Loop\";\n","import { rnd } from \"./rnd\";\n\nexport type SequentialMapContext<T, U> = {\n index: number;\n lastElement: U | undefined;\n newArray: ReadonlyArray<U>;\n originalArray: ReadonlyArray<T>;\n};\n\n/**\n * Splits an array into sub-arrays (chunks) of a maximum size.\n * @param array Array to process.\n * @param size The maximum size of each chunk.\n */\nfunction chunk<T>(array: ReadonlyArray<T>, size: number): T[][] {\n if (size <= 0) throw new Error(\"chunk: Size must be a positive integer.\");\n\n const result: T[][] = [];\n const len = array.length;\n\n for (let i = 0; i < len; i += size) {\n result.push(array.slice(i, i + size));\n }\n\n return result;\n}\n\n/**\n * Groups adjacent elements of an array together based on a predicate.\n * @param array Array to process.\n * @param predicate A function that returns true if two adjacent elements belong in the same chunk.\n * @example\n * // Group consecutive identical numbers\n * chunkBy([1, 1, 2, 3, 3, 3], (a, b) => a === b);\n * // [[1, 1], [2], [3, 3, 3]]\n */\nfunction chunkAdj<T>(array: ReadonlyArray<T>, predicate: (prev: T, curr: T) => boolean): T[][] {\n if (array.length === 0) return [];\n\n const results: T[][] = [];\n const len = array.length;\n let currentChunk: T[] = [array[0]!];\n\n for (let i = 1; i < len; i++) {\n const prev = array[i - 1]!;\n const curr = array[i]!;\n\n if (predicate(prev, curr)) {\n currentChunk.push(curr);\n } else {\n results.push(currentChunk);\n currentChunk = [curr];\n }\n }\n\n results.push(currentChunk);\n return results;\n}\n\n/**\n * Groups elements by a key.\n * @param array Array to process.\n * @param iteratee Function to determine the key to group by.\n * @param maxChunkSize Optionally chunk groups and flatten them (useful for pagination).\n */\nfunction cluster<T>(array: ReadonlyArray<T>, iteratee: (item: T) => string | number, maxChunkSize?: number): T[][] {\n const groups = new Map<string | number, T[]>();\n\n for (const item of array) {\n const key = iteratee(item);\n const collection = groups.get(key);\n if (!collection) {\n groups.set(key, [item]);\n } else {\n collection.push(item);\n }\n }\n\n const result: T[][] = [];\n\n for (const group of groups.values()) {\n if (maxChunkSize && maxChunkSize > 0) {\n // If chunking is enabled, split this specific group\n for (let i = 0; i < group.length; i += maxChunkSize) {\n result.push(group.slice(i, i + maxChunkSize));\n }\n } else {\n // Otherwise, just push the whole group as one chunk\n result.push(group);\n }\n }\n\n return result;\n}\n\n/**\n * Removes unwanted values from an array.\n * @param array Array to process.\n * @param mode 'nullable' (default) removes null/undefined. 'falsy' removes null, undefined, 0, \"\", false, and NaN.\n */\nfunction compact<T>(array: ReadonlyArray<T>, mode?: \"nullable\"): NonNullable<T>[];\nfunction compact<T>(array: ReadonlyArray<T>, mode: \"falsy\"): Exclude<T, null | undefined | false | 0 | \"\">[];\nfunction compact<T>(array: ReadonlyArray<T>, mode: \"nullable\" | \"falsy\" = \"nullable\"): any[] {\n if (mode === \"falsy\") {\n // Boolean constructor handles all falsy values\n return array.filter(Boolean);\n }\n\n // Only removes null and undefined\n return array.filter(item => item !== null && item !== undefined);\n}\n\n/**\n * Forces a given item to be an array.\n * @param item The item to force into an array.\n */\nfunction forceArray<T>(item: T): T[] {\n return Array.isArray(item) ? item : [item];\n}\n\n/**\n * Searches a sorted array for a value using the binary search method.\n * Returns the index if found, or the bitwise complement (~index) of the\n * position where the value should be inserted to keep it sorted.\n * @param array The array to process.\n * @param target The value to search for.\n * @param comparator Optional comparator function.\n */\nfunction search<T>(\n array: T[],\n target: T,\n comparator: (a: T, b: T) => number = (a, b) => (a > b ? 1 : a < b ? -1 : 0)\n): number {\n let low = 0;\n let high = array.length - 1;\n\n while (low <= high) {\n const mid = (low + high) >>> 1;\n const comp = comparator(array[mid]!, target);\n\n if (comp < 0) low = mid + 1;\n else if (comp > 0) high = mid - 1;\n else return mid;\n }\n\n return ~low;\n}\n\n/**\n * Maps over an array with access to the previously mapped elements.\n * @param array Array to process.\n * @param callback Function to map over the array.\n */\nfunction seqMap<T, U>(array: ReadonlyArray<T>, callback: (item: T, context: SequentialMapContext<T, U>) => U): U[] {\n const len = array.length;\n const result: U[] = new Array(len);\n\n for (let i = 0; i < len; i++) {\n result[i] = callback(array[i]!, {\n index: i,\n lastElement: i > 0 ? result[i - 1] : undefined,\n // NOTE: This is a reference to the array currently being built\n newArray: result,\n originalArray: array\n });\n }\n\n return result;\n}\n\n/**\n * Shuffles an array using the Fisher-Yates algorithm.\n * @param array The array to shuffle.\n * @param seed Optional seed for RNG.\n */\nfunction shuffle<T>(array: ReadonlyArray<T>, seed?: number): T[] {\n const random = seed !== undefined ? rnd.prng(seed) : Math.random;\n const result = [...array];\n\n for (let i = result.length - 1; i > 0; i--) {\n const j = Math.floor(random() * (i + 1));\n const temp = result[i]!;\n result[i] = result[j]!;\n result[j] = temp;\n }\n\n return result;\n}\n\n/**\n * Sorts an array by a single property in order.\n * @param order 'asc' for ascending (default) or 'desc' for descending.\n * @param array Array to process.\n * @param selector Function to determine the key to sort by.\n */\nfunction sortBy<T>(array: ReadonlyArray<T>, selector: (item: T) => any, order?: \"asc\" | \"desc\"): T[];\n/**\n * Sorts an array by one or more properties in order.\n * @param order 'asc' for ascending (default) or 'desc' for descending.\n * @param array Array to process.\n * @param selectors Functions to determine the keys to sort by.\n */\nfunction sortBy<T>(array: ReadonlyArray<T>, selectors: (item: T) => any[], order?: \"asc\" | \"desc\"): T[];\nfunction sortBy<T>(\n array: ReadonlyArray<T>,\n selectorOrSelectors: (item: T) => any | ((item: T) => any)[],\n order: \"asc\" | \"desc\" = \"asc\"\n): T[] {\n const selectors = Array.isArray(selectorOrSelectors) ? selectorOrSelectors : [selectorOrSelectors];\n\n if (array.length === 0 || selectors.length === 0) {\n return [...array];\n }\n\n const modifier = order === \"desc\" ? -1 : 1;\n const memos = array.map(item => ({ item, keys: selectors.map(s => s(item)) }));\n\n memos.sort((a, b) => {\n for (let i = 0; i < selectors.length; i++) {\n const valA = a.keys[i];\n const valB = b.keys[i];\n\n if (valA === valB) continue;\n\n // Nullish values are pushed to the end regardless of order\n if (valA == null) return 1;\n if (valB == null) return -1;\n\n if (valA < valB) return -1 * modifier;\n if (valA > valB) return 1 * modifier;\n }\n return 0;\n });\n\n return memos.map(m => m.item);\n}\n\n/**\n * Returns an array of unique elements from the given array.\n * Uniqueness is determined by the given key function.\n * @param array Array to process.\n * @param key Function to determine the keys to filter by\n */\nfunction unique<T>(array: T[], key: (item: T) => any): T[] {\n return Array.from(new Map(array.map(item => [key(item), item])).values());\n}\n\nexport const arr = {\n chunk,\n chunkAdj,\n cluster,\n compact,\n forceArray,\n search,\n seqMap,\n shuffle,\n sortBy,\n unique\n};\n","export type AlphaCasing = \"lower\" | \"upper\" | \"mixed\";\n\nexport interface RndArrayOptions<T> {\n /** Optional seed for RNG. */\n seed?: number;\n /** Reroll if the result is equal to this value. */\n not?: ((item: T) => boolean) | T;\n /** Maximum number of times to reroll if `not` is specified. [default: 10] */\n maxRerolls?: number;\n}\n\nexport interface RndStrOptions {\n /** Optional seed for RNG. */\n seed?: number;\n /** Character casing mode. */\n casing?: AlphaCasing;\n /** Custom character pool. */\n customChars?: string;\n /** Characters to exclude from the pool. */\n exclude?: string | string[];\n}\n\nconst LOWER = \"abcdefghijklmnopqrstuvwxyz\";\nconst UPPER = \"ABCDEFGHIJKLMNOPQRSTUVWXYZ\";\nconst NUM = \"0123456789\";\n\n/**\n * Returns true based on a percentage probability.\n * @param percent A value between 0 and 1. [default: 0.5]\n * @param seed Optional seed for RNG.\n */\nfunction chance(percent: number = 0.5, seed?: number): boolean {\n if (percent <= 0) return false;\n if (percent >= 1) return true;\n const random = seed !== undefined ? prng(seed) : Math.random;\n return random() < percent;\n}\n\n/**\n * Returns a random item from the given array.\n * @param array Array of items to choose from.\n * @param options Options for the choice function.\n */\nfunction choice<T>(array: T[], options: RndArrayOptions<T> = {}): T {\n const { seed, not, maxRerolls = 10 } = options;\n const random = seed !== undefined ? prng(seed) : Math.random;\n const rnd = () => array[Math.floor(random() * array.length)]!;\n\n let result: T = rnd();\n\n // NOTE: Ignores rerolling if seed is set and result is equal to `not`\n // to prevent infinite loops\n if (seed === undefined && array.length > 1 && not !== undefined) {\n let rerolls = 0;\n\n const shouldReroll = () => (typeof not === \"function\" ? (not as (item: T) => boolean)(result) : result === not);\n while (shouldReroll() && rerolls < maxRerolls) {\n result = rnd();\n rerolls++;\n }\n }\n\n return result;\n}\n\n/**\n * Returns a random item from the given array based on their corresponding weights.\n * @param array Array of items to choose from.\n * @param selector Function that selects the item's weight.\n * @param seed Optional seed for RNG.\n */\nfunction weighted<T>(array: T[], selector: (item: T) => number, seed?: number): T {\n const random = seed !== undefined ? prng(seed) : Math.random;\n\n const cumulativeWeights: number[] = [];\n let currentSum = 0;\n\n // Calculate cumulative weights\n for (const item of array) {\n const weight = selector(item);\n currentSum += weight;\n cumulativeWeights.push(currentSum);\n }\n\n const decider = random() * currentSum;\n\n let index: number;\n\n // Linear search | O(n)\n if (array.length < 20) {\n index = cumulativeWeights.findIndex(w => w >= decider);\n }\n // Binary Search | O(log n)\n else {\n let low = 0;\n let high = cumulativeWeights.length - 1;\n\n while (low < high) {\n const mid = (low + high) >>> 1;\n if (decider > cumulativeWeights[mid]!) {\n low = mid + 1;\n } else {\n high = mid;\n }\n }\n index = low;\n }\n\n return array[index]!;\n}\n\n/**\n * Returns an object with a single method, `pick`, which returns a random item from the given array in O(1) time.\n * The probability of each item being picked is determined by the corresponding weight in the `weights` array.\n * @param items Array of items to choose from.\n * @param selector Function that selects the item's weight.\n * @param seed Optional seed for RNG.\n */\nfunction sampler<T>(items: T[], selector: (item: T) => number, seed?: number) {\n const callRandom = seed ? prng(seed) : undefined;\n const len = items.length;\n\n const prob = new Array(len);\n const alias = new Array(len);\n\n const weights = items.map(selector);\n const totalWeight = weights.reduce((a, b) => a + b, 0);\n const scaledWeights = weights.map(w => (w * len) / totalWeight);\n\n const small: number[] = [];\n const large: number[] = [];\n\n scaledWeights.forEach((w, i) => (w < 1 ? small : large).push(i));\n\n while (small.length && large.length) {\n const s = small.pop()!;\n const l = large.pop()!;\n prob[s] = scaledWeights[s];\n alias[s] = l;\n scaledWeights[l] = scaledWeights[l]! + scaledWeights[s]! - 1;\n (scaledWeights[l] < 1 ? small : large).push(l);\n }\n\n while (large.length) prob[large.pop()!] = 1;\n while (small.length) prob[small.pop()!] = 1;\n\n return {\n /**\n * Returns a random item from the given array in O(1) time.\n * @param seed Optional seed for RNG.\n */\n pick: (seed?: number) => {\n const random = seed !== undefined ? prng(seed) : callRandom || Math.random;\n const i = Math.floor(random() * len);\n return random() < prob[i] ? items[i] : items[alias[i]];\n }\n };\n}\n\n/**\n * Creates a deterministic pseudo-random number generator (PRNG) using the Mulberry32 algorithm.\n * @param seed An integer seed value.\n * @example\n * const rng = prng(123);\n * const val1 = rng(); // Always the same for seed 123\n */\nfunction prng(seed: number): () => number {\n return () => {\n let t = (seed += 0x6d2b79f5);\n t = Math.imul(t ^ (t >>> 15), t | 1);\n t ^= t + Math.imul(t ^ (t >>> 7), t | 61);\n return ((t ^ (t >>> 14)) >>> 0) / 4294967296;\n };\n}\n\n/**\n * Generates a random float between the given minimum and maximum values.\n * @param min The minimum value (inclusive) for the random float.\n * @param max The maximum value (inclusive) for the random float.\n * @param seed Optional seed for RNG.\n */\nfunction float(min: number, max: number, seed?: number): number {\n const random = seed !== undefined ? prng(seed) : Math.random;\n return random() * (max - min) + min;\n}\n\n/**\n * Returns a random index from the given array.\n * @param array The array to generate an index for.\n * @param options Options for the index function.\n */\nfunction index<T>(array: T[], options: RndArrayOptions<number> = {}): number {\n const { seed, not, maxRerolls = 10 } = options;\n const random = seed !== undefined ? prng(seed) : Math.random;\n const rnd = () => Math.floor(random() * array.length);\n\n let result: number = rnd();\n\n // NOTE: Ignores rerolling if seed is set and result is equal to `not`\n // to prevent infinite loops\n if (seed === undefined && array.length > 1 && not !== undefined) {\n let rerolls = 0;\n\n const shouldReroll = () => (typeof not === \"function\" ? (not as (item: number) => boolean)(result) : result === not);\n while (shouldReroll() && rerolls < maxRerolls) {\n result = rnd();\n rerolls++;\n }\n }\n\n return result;\n}\n\n/**\n * Generates a random integer between the given minimum and maximum values.\n * @param min The minimum value (inclusive) for the random integer.\n * @param max The maximum value (inclusive) for the random integer.\n * @param seed Optional seed for RNG.\n */\nfunction int(min: number, max: number, seed?: number): number {\n const random = seed !== undefined ? prng(seed) : Math.random;\n return Math.floor(random() * (max - min + 1)) + min;\n}\n\n/**\n * Generates a random string of the given length using the specified character pool.\n * @param len The length of the random string.\n * @param mode The character pool to use. Can be \"number\", \"alpha\", \"alphanumeric\", or \"custom\".\n * @param options Options for the rndStr function.\n */\nfunction str(len: number, mode: \"number\" | \"alpha\" | \"alphanumeric\" | \"custom\", options: RndStrOptions = {}) {\n const { casing = \"lower\", seed, customChars = \"\", exclude = \"\" } = options;\n const random = seed !== undefined ? prng(seed) : Math.random;\n\n const alphaPool = { lower: LOWER, upper: UPPER, mixed: LOWER + UPPER }[casing];\n let pool = { number: NUM, alpha: alphaPool, alphanumeric: alphaPool + NUM, custom: customChars }[mode];\n\n if (exclude.length > 0) {\n const excludeSet = new Set(Array.isArray(exclude) ? exclude : exclude.split(\"\"));\n pool = pool\n .split(\"\")\n .filter(char => !excludeSet.has(char))\n .join(\"\");\n }\n\n // Safety check\n if (pool.length === 0) throw new Error(\"rndStr: Character pool is empty after exclusions.\");\n\n const result = new Array(len);\n const poolLen = pool.length;\n\n for (let i = 0; i < len; i++) {\n result[i] = pool[Math.floor(random() * poolLen)];\n }\n\n return result.join(\"\");\n}\n\nexport const rnd = {\n chance,\n choice,\n weighted,\n sampler,\n prng,\n float,\n index,\n int,\n str\n};\n","/**\n * Retries an async function with exponential backoff.\n * @param fn The async function to attempt.\n * @param retries Maximum number of retry attempts. [default: 3]\n * @param delay Initial delay in milliseconds. [default: 500ms]\n */\nasync function retry<T>(fn: () => Promise<T>, retries: number = 3, delay: number = 500): Promise<T> {\n try {\n return await fn();\n } catch (error) {\n if (retries <= 0) throw error;\n const jitter = Math.random() * 200;\n return await new Promise(resolve => setTimeout(resolve, delay + jitter));\n }\n}\n\n/**\n * Returns a promise that resolves after the given number of milliseconds.\n * @param ms The time to wait in milliseconds.\n */\nfunction wait(ms: number): Promise<boolean> {\n return new Promise(resolve =>\n setTimeout(() => {\n resolve(true);\n }, ms)\n );\n}\n\nexport const async = {\n retry,\n wait\n};\n","export interface MemoizedFunction<T extends (...args: any[]) => any> {\n (...args: Parameters<T>): ReturnType<T>;\n /** Clears the cache. */\n clear: () => void;\n}\n\n/**\n * Memoizes a function by caching its results based on the input arguments.\n * A resolver function can be provided to customize the key generation.\n * If no resolver is provided, the key will be generated by JSON stringify-ing the input arguments.\n * @param fn The function to memoize.\n * @param resolver An optional resolver function to customize the key generation.\n * @example\n * // 1. Basic usage\n * const heavyCalc = memoize((n: number) => {\n * console.log('Calculating...');\n * return n * 2;\n * });\n * heavyCalc(5); // Logs 'Calculating...' and returns 10\n * heavyCalc(5); // Returns 10 immediately from cache\n * @example\n * // 2. Using maxAge (TTL)\n * const getStockPrice = memoize(fetchPrice, { maxAge: 60000 }); // 1 minute cache\n * @example\n * // 3. Using a custom resolver\n * const getUser = memoize(\n * (user, theme) => render(user, theme),\n * { resolver: (user) => user.id } // Only cache based on ID, ignore theme\n * );\n * @example\n * // 4. Manual cache clearing\n * heavyCalc.clear();\n */\nfunction memoize<T extends (...args: any[]) => any>(\n fn: T,\n options: {\n /** Function to generate a cache key from the input arguments. */\n resolver?: (...args: Parameters<T>) => string;\n /** The time to wait in milliseconds before expiring a cache entry. */\n maxAge?: number;\n } = {}\n): MemoizedFunction<T> {\n const cache = new Map<string, { value: any; timestamp: number }>();\n const { resolver, maxAge } = options;\n\n const memoized = function (this: any, ...args: Parameters<T>) {\n const key = resolver ? resolver(...args) : JSON.stringify(args);\n const now = Date.now();\n const entry = cache.get(key);\n\n // Check if we have a valid (unexpired) entry\n if (entry) {\n if (!maxAge || now - entry.timestamp < maxAge) {\n return entry.value;\n }\n // Delete it since it's expired\n cache.delete(key);\n }\n\n const result = fn.apply(this, args);\n cache.set(key, { value: result, timestamp: now });\n return result;\n } as MemoizedFunction<T>;\n\n memoized.clear = () => cache.clear();\n\n return memoized;\n}\n\nexport const fn = {\n memoize\n};\n","export interface DateOptions {\n /** The reference timestamp to calculate from. Defaults to Date.now() */\n since?: number | Date;\n /** If true, returns null if the target time is in the past. */\n nullIfPast?: boolean;\n /** If true, omits the \" ago\" suffix for past dates. */\n ignorePast?: boolean;\n}\n\nexport interface ParseOptions {\n /** Return value in seconds instead of milliseconds. */\n unit?: \"ms\" | \"s\";\n /** If true, returns the absolute Unix timestamp (Date.now() + result). */\n fromNow?: boolean;\n}\n\nconst MS_MAP: Record<string, number> = {\n ms: 1,\n s: 1000,\n m: 60000,\n h: 3600000,\n d: 86400000,\n w: 604800000,\n mth: 2419200000,\n y: 31536000000\n};\n\n/**\n * Duration formatter.\n *\n * Available styles:\n * - Digital (00:00)\n * - HMS\n * - YMDHMS.\n * @param target The target time to calculate from.\n * @param style The output style to use.\n * @param options Formatting options.\n */\nfunction duration(\n target: number | Date,\n style: \"digital\" | \"hms\" | \"ymdhms\" = \"hms\",\n options: DateOptions = {}\n): string | null {\n const targetMs = target instanceof Date ? target.getTime() : Number(target);\n const sinceMs = options.since instanceof Date ? options.since.getTime() : Number(options.since) || Date.now();\n const diff = Math.abs(targetMs - sinceMs);\n\n if (diff === 0) return style === \"digital\" ? \"00:00\" : \"now\";\n\n const s = Math.floor(diff / 1000) % 60;\n const m = Math.floor(diff / 60000) % 60;\n const h = Math.floor(diff / 3600000) % 24;\n const d = Math.floor(diff / 86400000);\n\n if (style === \"digital\") {\n const parts = [m, s].map(v => String(v).padStart(2, \"0\"));\n if (h > 0 || d > 0) parts.unshift(String(h).padStart(2, \"0\"));\n if (d > 0) parts.unshift(String(d)); // Days don't necessarily need padding\n return parts.join(\":\");\n }\n\n const result: string[] = [];\n const push = (val: number, label: string) => {\n if (val > 0) result.push(`${val} ${label}${val === 1 ? \"\" : \"s\"}`);\n };\n\n if (style === \"ymdhms\") push(d, \"day\");\n push(h, \"hour\");\n push(m, \"minute\");\n push(s, \"second\");\n\n if (result.length === 0) return \"0 seconds\";\n if (result.length === 1) return result[0]!;\n\n const last = result.pop();\n return `${result.join(\", \")} and ${last}`;\n}\n\n/**\n * Formats a date or timestamp into a human-readable relative string (e.g., \"3 days ago\").\n * @param date - The Date object or timestamp to compare.\n * @param locale - The BCP 47 language tag.\n */\nfunction eta(date: Date | number, locale?: Intl.LocalesArgument): string {\n const rtf = new Intl.RelativeTimeFormat(locale, { numeric: \"auto\" });\n const elapsed = (typeof date === \"number\" ? date : date.getTime()) - Date.now();\n\n // Division factors for different units\n const units: { unit: Intl.RelativeTimeFormatUnit; ms: number }[] = [\n { unit: \"year\", ms: 31536000000 },\n { unit: \"month\", ms: 2628000000 },\n { unit: \"day\", ms: 86400000 },\n { unit: \"hour\", ms: 3600000 },\n { unit: \"minute\", ms: 60000 },\n { unit: \"second\", ms: 1000 }\n ];\n\n // Find the largest unit that fits the elapsed time\n for (const { unit, ms } of units) {\n if (Math.abs(elapsed) >= ms || unit === \"second\") {\n return rtf.format(Math.round(elapsed / ms), unit);\n }\n }\n\n return \"\";\n}\n\n/**\n * Parses shorthand strings (1h 30m) into milliseconds or seconds.\n */\nfunction parse(str: string | number, options: ParseOptions = {}): number {\n if (typeof str === \"number\") return str;\n\n const matches = str.matchAll(/(-?\\d+)([a-z]+)/gi);\n let totalMs = 0;\n let found = false;\n\n for (const [_, value, unit] of matches) {\n if (!value || !unit) continue;\n const factor = MS_MAP[unit.toLowerCase()];\n if (factor) {\n totalMs += parseInt(value) * factor;\n found = true;\n }\n }\n\n if (!found) throw new Error(`parse: Invalid time format: \"${str}\"`);\n\n const result = options.unit === \"s\" ? totalMs / 1000 : totalMs;\n return options.fromNow ? Date.now() + result : result;\n}\n\nexport const date = {\n duration,\n eta,\n parse\n};\n","/**\n * Formats a number as a currency string using international standards.\n * @param num - The number to process.\n * @param options - Formatting options.\n * @example\n * currency(1234.5); // \"$1,234.50\"\n * currency(1234.5, 'EUR', 'de-DE'); // \"1.234,50 €\"\n * currency(500, 'JPY'); // \"¥500\" (Yen has no decimals)\n */\nfunction currency(\n num: number,\n options: {\n /** The ISO currency code (e.g., 'USD', 'EUR', 'GBP'). */\n currency?: string;\n /** The BCP 47 language tag. */\n locale?: Intl.LocalesArgument;\n } = {}\n): string {\n return new Intl.NumberFormat(options.locale, {\n style: \"currency\",\n currency: options.currency\n }).format(num);\n}\n\n/**\n * Formats a number with thousands separators and optional decimal precision.\n * @param num - The number to process.\n * @param options - Formatting options.\n * @example\n * num(1000000); // \"1,000,000\" (en-US default)\n * num(1000, { locale: 'de-DE' }); // \"1.000\"\n * num(1234.567, { precision: 2 }); // \"1,234.57\"\n */\nfunction number(\n num: number,\n options: {\n /** The BCP 47 language tag. */\n locale?: Intl.LocalesArgument;\n precision?: number;\n } = {}\n): string {\n return new Intl.NumberFormat(options.locale, {\n minimumFractionDigits: options.precision,\n maximumFractionDigits: options.precision\n }).format(num);\n}\n\nfunction memory(\n bytes: number,\n decimals: number = 1,\n units: string[] = [\"B\", \"KB\", \"MB\", \"GB\", \"TB\", \"PB\", \"EB\", \"ZB\", \"YB\"]\n): string {\n // Handle 0 or negative numbers immediately\n if (bytes <= 0) return `0 ${units[0]}`;\n\n // Calculate the magnitude index (0 for B, 1 for KB, etc.)\n const i = Math.min(Math.floor(Math.log(bytes) / Math.log(1024)), units.length - 1);\n const val = bytes / Math.pow(1024, i);\n return `${val.toFixed(i === 0 ? 0 : decimals)} ${units[i]}`;\n}\n\n/**\n * Formats a number to an ordinal (e.g., 1st, 2nd, 3rd).\n * @param num The number to process.\n * @param locale The BCP 47 language tag.\n */\nfunction ordinal(num: number | string, locale?: Intl.LocalesArgument): string {\n const _num = Number(num);\n if (isNaN(_num)) throw new TypeError(\"Invalid input\");\n\n const pr = new Intl.PluralRules(locale, { type: \"ordinal\" });\n const rule = pr.select(_num);\n\n const suffixes: Record<string, string> = {\n one: \"st\",\n two: \"nd\",\n few: \"rd\",\n other: \"th\"\n };\n\n const suffix = suffixes[rule] || \"th\";\n return _num.toLocaleString(locale) + suffix;\n}\n\n/**\n * Formats a number into a compact, human-readable string (e.g., 1.2k, 1M).\n * @param num - The number to process.\n * @param locale - The BCP 47 language tag.\n */\nfunction compactNumber(num: number, locale?: Intl.LocalesArgument): string {\n return new Intl.NumberFormat(locale, {\n notation: \"compact\",\n compactDisplay: \"short\",\n maximumFractionDigits: 1\n }).format(num);\n}\n\nexport const format = {\n currency,\n number,\n memory,\n ordinal,\n compactNumber\n};\n","import _fs from \"node:fs\";\nimport { join } from \"node:path\";\n\nexport interface ReadDirOptions {\n /** Whether to scan subdirectories. [default: true] */\n recursive?: boolean;\n}\n\n/**\n * Recursively (or shallowly) scans a directory and returns an array of relative file paths.\n * @param path The path to the directory.\n * @param options Options for the readDir function.\n */\nfunction readDir(path: string, options: ReadDirOptions = {}): string[] {\n const { recursive = true } = options;\n\n if (!_fs.existsSync(path)) return [];\n\n // Shallow read\n if (!recursive) {\n return _fs.readdirSync(path).filter(fn => {\n return _fs.statSync(join(path, fn)).isFile();\n });\n }\n\n // Recursive walk\n const walk = (dir: string, base: string = \"\"): string[] => {\n const results: string[] = [];\n\n // Using withFileTypes is much faster as it returns Dirent objects\n const entries = _fs.readdirSync(dir, { withFileTypes: true });\n\n for (const entry of entries) {\n const relativePath = base ? join(base, entry.name) : entry.name;\n const fullPath = join(dir, entry.name);\n\n if (entry.isDirectory()) {\n results.push(...walk(fullPath, relativePath));\n } else if (entry.isFile()) {\n results.push(relativePath);\n }\n }\n\n return results;\n };\n\n return walk(path);\n}\n\nexport const fs = {\n readDir\n};\n","/**\n * Checks if a value is defined (not null or undefined).\n */\nfunction defined<T>(val: T | undefined | null): val is T {\n return val !== undefined && val !== null;\n}\n\n/**\n * Checks if a value is an empty object, array, or string.\n */\nfunction empty(val: unknown): boolean {\n if (!defined(val)) return true;\n if (string(val) || Array.isArray(val)) return val.length === 0;\n if (object(val)) return Object.keys(val).length === 0;\n return false;\n}\n\n/**\n * Checks if a number is within a specified range.\n * @param num The number to check.\n * @param min The minimum or maximum value of the range.\n * @param max The maximum value of the range (optional).\n */\nfunction inRange(num: number, max: number): boolean;\nfunction inRange(num: number, min: number, max: number): boolean;\nfunction inRange(num: number, a: number, b?: number): boolean {\n // If b is undefined, we are clamping [0, a]\n // If b is defined, we are clamping [a, b]\n let min = b !== undefined ? a : 0;\n let max = b !== undefined ? b : a;\n\n // Handles a swapped min/max\n if (min > max) [min, max] = [max, min];\n return num >= min && num <= max;\n}\n\n/**\n * Checks if a value is a plain object (not an array, null, or function).\n */\nfunction object(val: unknown): val is Record<string, any> {\n return val !== null && typeof val === \"object\" && !Array.isArray(val);\n}\n\n/**\n * Checks if an array is sorted.\n */\nfunction sorted<T>(arr: T[], comparator?: (a: T, b: T) => number): boolean {\n for (let i = 0; i < arr.length - 1; i++) {\n const comp = comparator ? comparator(arr[i]!, arr[i + 1]!) : arr[i]! > arr[i + 1]! ? 1 : -1;\n if (comp > 0) return false;\n }\n return true;\n}\n\n/**\n * Checks if a value is a string.\n */\nfunction string(val: unknown): val is string {\n return typeof val === \"string\";\n}\n\n/**\n * Checks if a date is today.\n */\nfunction today(date: number | Date): boolean {\n const d = date instanceof Date ? date : new Date(date);\n const today = new Date();\n return d.getDate() === today.getDate() && d.getMonth() === today.getMonth() && d.getFullYear() === today.getFullYear();\n}\n\nexport const is = {\n defined,\n empty,\n inRange,\n object,\n sorted,\n string,\n today\n};\n","/**\n * Clamps a number within a specified range.\n * @param num The number to check.\n * @param min The minimum or maximum value of the range.\n * @param max The maximum value of the range (optional).\n */\nfunction clamp(num: number, max: number): number;\nfunction clamp(num: number, min: number, max: number): number;\nfunction clamp(num: number, a: number, b?: number): number {\n // If b is undefined, we are clamping [0, a]\n // If b is defined, we are clamping [a, b]\n let min = b !== undefined ? a : 0;\n let max = b !== undefined ? b : a;\n\n // Handles a swapped min/max\n if (min > max) [min, max] = [max, min];\n return Math.max(min, Math.min(num, max));\n}\n\n/**\n * Calculates the interpolation factor (0-1) of a value between two points.\n * @param start - The starting value (0%).\n * @param end - The ending value (100%).\n * @param value - The value to interpolate.\n * @example\n * invLerp(0, 100, 50); // 0.5\n */\nfunction invLerp(start: number, end: number, value: number): number {\n if (start === end) return 0;\n return (value - start) / (end - start);\n}\n\n/**\n * Linearly interpolates between two values.\n * @param start - The starting value (0%).\n * @param end - The ending value (100%).\n * @param t - The interpolation factor (0 to 1).\n * @example\n * lerp(0, 100, 0.5); // 50\n * lerp(10, 20, 0.2); // 12\n */\nfunction lerp(start: number, end: number, t: number): number {\n return start + (end - start) * t;\n}\n\n/**\n * Converts seconds to milliseconds and rounds it to the nearest integer.\n * @param num The number of seconds to convert.\n */\nfunction ms(num: number): number {\n return Math.floor(num * 1000);\n}\n\n/**\n * Calculates the percentage value between two numbers.\n * @param a The numerator.\n * @param b The denominator.\n * @param round Whether to round the result to the nearest integer.\n * @example\n * percent(50, 100) --> 50 // 50%\n * percent(30, 40) --> 75 // 75%\n */\nfunction percent(a: number, b: number, round: boolean = true): number {\n const result = (a / b) * 100;\n return round ? Math.floor(result) : result;\n}\n\n/**\n * Maps a value from one range to another.\n * @param value - The value to map.\n * @param inMin - The minimum value of the input range.\n * @param inMax - The maximum value of the input range.\n * @param outMin - The minimum value of the output range.\n * @param outMax - The maximum value of the output range.\n * @example\n * // Convert mouse X position (0-1920) to a volume level (0-1)\n * const volume = remap(mouseX, 0, 1920, 0, 1);\n */\nfunction remap(value: number, inMin: number, inMax: number, outMin: number, outMax: number): number {\n const t = invLerp(inMin, inMax, value);\n return lerp(outMin, outMax, t);\n}\n\n/**\n * Converts milliseconds to seconds and rounds it to the nearest integer.\n * @param num The number of milliseconds to convert.\n */\nfunction secs(num: number): number {\n return Math.floor(num / 1000);\n}\n\n/**\n * Returns the sum of an array of numbers. Negative values subtract from the total.\n * @param array The array to sum.\n * @param selector Function that selects the item's weight.\n * @param ignoreNaN If true, NaN values will not throw an error.\n */\nfunction sum<T>(array: T[], selector?: (item: T) => number): number {\n const _array = selector ? array.map(selector) : array;\n if (!_array.every(v => typeof v === \"number\")) {\n throw new TypeError(`sum: Array must only contain numbers.`);\n }\n\n return _array.reduce((a, b) => {\n return (isNaN(b) ? 0 : b) < 0 ? a - -b : a + (b || 0);\n }, 0);\n}\n\nexport const math = {\n clamp,\n invLerp,\n lerp,\n ms,\n percent,\n remap,\n secs,\n sum\n};\n","/**\n * Retrieves a nested property.\n * @param obj The object to process.\n * @param path The path to retrieve (e.g., 'data.users[0].id').\n * @param defaultValue The default value to return if the property does not exist.\n */\nfunction get<T = any>(obj: Record<string, any>, path: string, defaultValue?: T): T {\n if (!obj) throw new Error(\"get: Target object is null or undefined\");\n\n // Normalize and split\n const parts = path.replace(/\\[(\\d+)\\]/g, \".$1\").split(\".\");\n let current: any = obj;\n const trace: string[] = [];\n\n for (const part of parts) {\n trace.push(part);\n\n // Check if the link in the chain exists\n if (current === null || typeof current !== \"object\" || !(part in current)) {\n // Return the default value, if provided\n if (arguments.length === 3) return defaultValue as T;\n\n // Else, throw a debug error with the trace path\n const reach = trace.join(\".\");\n throw new Error(`get: Path broken at \"${reach}\". ` + `Property \"${part}\" is missing on ${typeof current}.`);\n }\n\n current = current[part];\n }\n\n // Handle the case where the final value found is undefined\n if (current === undefined && arguments.length === 3) {\n return defaultValue as T;\n }\n\n return current as T;\n}\n\n/**\n * Checks if a nested path exists within an object.\n * @param obj The object to process.\n * @param path The path string (e.g., 'data.users[0].id').\n */\nfunction has(obj: Record<string, any>, path: string): boolean {\n if (!obj || !path) return false;\n\n const parts = path.replace(/\\[(\\d+)\\]/g, \".$1\").split(\".\");\n let current: any = obj;\n\n for (let i = 0; i < parts.length; i++) {\n const part = parts[i]!;\n\n // If the current level isn't an object, the path can't continue\n if (current === null || typeof current !== \"object\") {\n return false;\n }\n\n // Check if the property exists at this level\n if (!(part in current)) {\n return false;\n }\n\n current = current[part];\n }\n\n return true;\n}\n\n/**\n * Sets a nested property value. Creates missing objects/arrays along the path.\n * @param obj The object to process.\n * @param path The path to set (e.g., 'data.users[0].id').\n * @param value The value to inject.\n */\nfunction set(obj: Record<string, any>, path: string, value: any): void {\n const parts = path.replace(/\\[(\\d+)\\]/g, \".$1\").split(\".\");\n let current: any = obj;\n\n for (let i = 0; i < parts.length; i++) {\n const part = parts[i]!;\n const isLast = i === parts.length - 1;\n\n if (isLast) {\n current[part] = value;\n return;\n }\n\n // If the next part is a number, we should create an array, otherwise an object\n const nextPartIsNumber = !isNaN(Number(parts[i + 1]));\n\n if (!(part in current) || current[part] === null || typeof current[part] !== \"object\") {\n current[part] = nextPartIsNumber ? [] : {};\n }\n\n current = current[part];\n }\n}\n\n/**\n * Deep merges multiple objects.\n * @param target - The base object to merge into.\n * @param sources - One or more objects to merge.\n */\nfunction merge<T, S1>(target: T, s1: S1): T & S1;\nfunction merge<T, S1, S2>(target: T, s1: S1, s2: S2): T & S1 & S2;\nfunction merge<T, S1, S2, S3>(target: T, s1: S1, s2: S2, s3: S3): T & S1 & S2 & S3;\nfunction merge(target: any, ...sources: any[]): any;\nfunction merge(target: any, ...sources: any[]) {\n // Loop through every source object provided\n for (const source of sources) {\n if (!source) continue;\n\n Object.keys(source).forEach(key => {\n const targetValue = target[key];\n const sourceValue = source[key];\n\n if (Array.isArray(targetValue) && Array.isArray(sourceValue)) {\n // Concat arrays\n (target as any)[key] = targetValue.concat(sourceValue);\n } else if (\n targetValue &&\n typeof targetValue === \"object\" &&\n sourceValue &&\n typeof sourceValue === \"object\" &&\n !Array.isArray(sourceValue)\n ) {\n // If both are objects, recurse\n merge(targetValue, sourceValue);\n } else {\n // Else, just set the value\n (target as any)[key] = sourceValue;\n }\n });\n }\n\n return target;\n}\n\n/**\n * Creates an object composed of the picked object properties.\n * @param obj The object to process.\n * @param keys The keys to pick from the object.\n */\nfunction pick<T extends object, K extends keyof T>(obj: T, keys: K[]): Pick<T, K> {\n const result = {} as Pick<T, K>;\n for (const key of keys) {\n if (key in obj) {\n result[key] = obj[key];\n }\n }\n return result;\n}\n\n/**\n * Creates an object composed of the omitted object properties.\n * @param obj The object to process.\n * @param keys The keys to omit from the object.\n */\nfunction omit<T extends object, K extends keyof T>(obj: T, keys: K[]): Omit<T, K> {\n const result = { ...obj };\n for (const key of keys) {\n delete result[key];\n }\n return result;\n}\n\nexport const obj = {\n get,\n has,\n set,\n merge,\n pick,\n omit\n};\n","/**\n * Escapes regex characters in the given string.\n * @param str - The string to process.\n */\nfunction escapeRegex(str: string): string {\n return str.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n}\n\n/**\n * Retrieves a substring following a specific flag.\n * @param str The string to process.\n * @param flag A string or regex to look for.\n */\nfunction getFlag(str: string, flag: string | RegExp, length?: number): string | null {\n // NOTE: Using \\b ensures we don't match \"flag\" inside \"flagpole\"\n const regex = flag instanceof RegExp ? flag : new RegExp(`${escapeRegex(flag)}\\\\b`, \"g\");\n\n const match = regex.exec(str);\n if (!match) return null;\n\n const startIndex = match.index + match[0].length;\n let result = str.slice(startIndex).trimStart();\n\n // If length is provided, limit by word count\n if (length !== undefined) {\n return result.split(/\\s+/).slice(0, length).join(\" \");\n }\n\n return result || null;\n}\n\n/**\n * Checks if a string contains a specific flag.\n * @param str The string to process.\n * @param flag A string or regex to look for.\n */\nfunction hasFlag(str: string, flag: string | RegExp): boolean {\n if (flag instanceof RegExp) return flag.test(str);\n\n // NOTE: Using \\b ensures we don't match \"flag\" inside \"flagpole\"\n const pattern = new RegExp(`${escapeRegex(flag)}\\\\b`);\n return pattern.test(str);\n}\n\n/**\n * Formats a string to Title Case, optionally keeping acronyms and skipping minor words (the, and, of, etc.).\n * @param str The string to process.\n * @param smart If true, will keep acronyms and skip minor words. [default: true]\n */\nfunction toTitleCase(str: string, smart = true): string {\n const minorWords = /^(a|an|and|as|at|but|by|en|for|if|in|of|on|or|the|to|v\\.?|via)$/i;\n\n return str.replace(/\\w\\S*/g, (txt, index) => {\n // Always capitalize the first word, otherwise check if it's a minor word\n if (smart && index !== 0 && minorWords.test(txt)) {\n return txt.toLowerCase();\n }\n\n // If it's already uppercase (more than 1 letter), assume it's an acronym\n if (smart && txt.length > 1 && txt === txt.toUpperCase()) {\n return txt;\n }\n\n return txt.charAt(0).toUpperCase() + txt.substring(1).toLowerCase();\n });\n}\n\nexport const str = {\n escapeRegex,\n getFlag,\n hasFlag,\n toTitleCase\n};\n","export interface DebouncedFunction<T extends (...args: any[]) => any> {\n (...args: Parameters<T>): void;\n /** Cancels the debounced function. */\n cancel: () => void;\n}\n\n/**\n * Only executes after 'wait' ms have passed since the last call.\n * @param fn The function to debounce.\n * @param wait The time to wait in milliseconds.\n * @param options Options for the debounce function.\n * @example\n * const search = debounce((str) => console.log(\"Searching:\", str), 500);\n * // Even if called rapidly, it only logs once 500ms after the last call.\n * search('a');\n * search('ab');\n * search('abc'); // Only 'abc' will be logged.\n * // Cancel a pending execution\n * search.cancel();\n */\nfunction debounce<T extends (...args: any[]) => any>(\n fn: T,\n wait: number,\n options: {\n /** Calls the function immediately on the leading edge. */\n immediate?: boolean;\n } = {}\n): DebouncedFunction<T> {\n let timeoutId: ReturnType<typeof setTimeout> | undefined;\n const leading = options.immediate ?? false;\n\n const debounced = function (this: any, ...args: Parameters<T>) {\n const callNow = leading && !timeoutId;\n if (timeoutId) clearTimeout(timeoutId);\n\n timeoutId = setTimeout(() => {\n timeoutId = undefined;\n // If we aren't in leading mode, fire the function at the end\n if (!leading) fn.apply(this, args);\n }, wait);\n\n // If leading is true and no timer was active, fire immediately\n if (callNow) fn.apply(this, args);\n } as DebouncedFunction<T>;\n\n debounced.cancel = () => {\n if (timeoutId) {\n clearTimeout(timeoutId);\n timeoutId = undefined;\n }\n };\n\n return debounced;\n}\n\n/**\n * Executes at most once every 'limit' ms.\n * @param fn The function to throttle.\n * @param limit The time to wait in milliseconds.\n * @example\n * const handleScroll = throttle(() => console.log('Scroll position:', window.scrollY), 200);\n * // Even if the browser fires 100 scroll events per second,\n * // this function will only execute once every 200ms.\n * window.addEventListener('scroll', handleScroll);\n */\nfunction throttle<T extends (...args: any[]) => any>(fn: T, limit: number): (...args: Parameters<T>) => void {\n let inThrottle = false;\n\n return function (this: any, ...args: Parameters<T>) {\n if (!inThrottle) {\n fn.apply(this, args);\n inThrottle = true;\n setTimeout(() => (inThrottle = false), limit);\n }\n };\n}\n\nexport const timing = {\n debounce,\n throttle\n};\n","export type ToRecordContext<T, V> = {\n index: number;\n lastValue: V | undefined;\n newRecord: Readonly<Record<string | number, V>>;\n originalArray: ReadonlyArray<T>;\n};\n\n/**\n * Transforms an array into a object record with access to the object as it's being built.\n * @param array Array to process.\n * @param callback Function to map over the array.\n */\nfunction record<T, V>(\n array: ReadonlyArray<T>,\n callback: (item: T, context: ToRecordContext<T, V>) => { key: string | number; value: V }\n): Record<string | number, V> {\n const result: Record<string | number, V> = {};\n let lastValue: V | undefined = undefined;\n\n for (let i = 0; i < array.length; i++) {\n const { key, value } = callback(array[i]!, {\n index: i,\n lastValue,\n // NOTE: This is a reference to the object currently being built\n newRecord: result,\n originalArray: array\n });\n\n result[key] = value;\n lastValue = value;\n }\n\n return result;\n}\n\nexport const to = {\n record\n};\n","/**\n * Pipes a value through a series of functions.\n * Each function takes the output of the previous one.\n */\nexport function Pipe<A>(value: A): A;\nexport function Pipe<A, B>(value: A, fn1: (arg: A) => B): B;\nexport function Pipe<A, B, C>(value: A, fn1: (arg: A) => B, fn2: (arg: B) => C): C;\nexport function Pipe<A, B, C, D>(value: A, fn1: (arg: A) => B, fn2: (arg: B) => C, fn3: (arg: C) => D): D;\n// prettier-ignore\nexport function Pipe<A, B, C, D, E>(value: A, fn1: (arg: A) => B, fn2: (arg: B) => C, fn3: (arg: C) => D, fn4: (arg: D) => E): E;\n// prettier-ignore\nexport function Pipe<A, B, C, D, E, F>(value: A, fn1: (arg: A) => B, fn2: (arg: B) => C, fn3: (arg: C) => D, fn4: (arg: D) => E, fn5: (arg: E) => F): F;\n// prettier-ignore\nexport function Pipe<A, B, C, D, E, F, G>(value: A, fn1: (arg: A) => B, fn2: (arg: B) => C, fn3: (arg: C) => D, fn4: (arg: D) => E, fn5: (arg: E) => F, fn6: (arg: F) => G): G;\n// prettier-ignore\nexport function Pipe<A, B, C, D, E, F, G, H>(value: A, fn1: (arg: A) => B, fn2: (arg: B) => C, fn3: (arg: C) => D, fn4: (arg: D) => E, fn5: (arg: E) => F, fn6: (arg: F) => G, fn7: (arg: G) => H): H;\n// prettier-ignore\nexport function Pipe<A, B, C, D, E, F, G, H, I>(value: A, fn1: (arg: A) => B, fn2: (arg: B) => C, fn3: (arg: C) => D, fn4: (arg: D) => E, fn5: (arg: E) => F, fn6: (arg: F) => G, fn7: (arg: G) => H, fn8: (arg: H) => I): I;\n// prettier-ignore\nexport function Pipe<A, B, C, D, E, F, G, H, I, J>(value: A, fn1: (arg: A) => B, fn2: (arg: B) => C, fn3: (arg: C) => D, fn4: (arg: D) => E, fn5: (arg: E) => F, fn6: (arg: F) => G, fn7: (arg: G) => H, fn8: (arg: H) => I, fn9: (arg: I) => J): J;\n// prettier-ignore\nexport function Pipe<A, B, C, D, E, F, G, H, I, J, K>(value: A, fn1: (arg: A) => B, fn2: (arg: B) => C, fn3: (arg: C) => D, fn4: (arg: D) => E, fn5: (arg: E) => F, fn6: (arg: F) => G, fn7: (arg: G) => H, fn8: (arg: H) => I, fn9: (arg: I) => J, fn10: (arg: J) => K): K;\n\nexport function Pipe(value: any, ...fns: Function[]): any {\n return fns.reduce((acc, fn) => fn(acc), value);\n}\n","import fs from \"node:fs\";\nimport path from \"node:path\";\n\ntype StorePayload<T> = {\n value: T;\n expiry: number | null;\n};\n\nexport class Storage {\n private isNode = typeof window === \"undefined\";\n private filePath: string | null = null;\n private memoryCache = new Map<string, string>();\n\n private loadFromFile() {\n if (this.filePath && fs.existsSync(this.filePath)) {\n try {\n const data = JSON.parse(fs.readFileSync(this.filePath, \"utf-8\"));\n Object.entries(data).forEach(([k, v]) => this.memoryCache.set(k, JSON.stringify(v)));\n } catch (err) {\n console.error(`Store: Failed to load file '${this.filePath}'`, err);\n }\n }\n }\n\n private persist() {\n if (this.isNode && this.filePath) {\n const out: Record<string, any> = {};\n this.memoryCache.forEach((v, k) => (out[k] = JSON.parse(v)));\n fs.writeFileSync(this.filePath, JSON.stringify(out, null, 2));\n }\n }\n\n /**\n * A lightweight, high-performant persistent storage system.\n * Uses JSON files in Node.js, localStorage in the browser.\n * @param fileName Only used in Node.js to create a persistent .json file.\n * @param directory The directory for the file. Defaults to current working directory.\n */\n constructor(fileName?: string, directory: string = process.cwd()) {\n if (this.isNode && fileName) {\n this.filePath = path.join(directory, fileName.endsWith(\".json\") ? fileName : `${fileName}.json`);\n this.loadFromFile();\n }\n }\n\n has(key: string): boolean {\n if (!this.isNode && window.localStorage) {\n return localStorage.getItem(key) !== null;\n }\n return this.memoryCache.has(key);\n }\n\n get<T>(key: string): T | null {\n let raw: string | null = null;\n\n if (!this.isNode && window.localStorage) {\n raw = localStorage.getItem(key);\n } else {\n raw = this.memoryCache.get(key) || null;\n }\n\n if (!raw) return null;\n\n const payload: StorePayload<T> = JSON.parse(raw);\n if (payload.expiry && Date.now() > payload.expiry) {\n this.remove(key);\n this.persist();\n return null;\n }\n return payload.value;\n }\n\n set<T>(key: string, value: T, ttl?: number): void {\n const payload: StorePayload<T> = {\n value,\n expiry: ttl ? Date.now() + ttl : null\n };\n const serialized = JSON.stringify(payload);\n\n if (!this.isNode && window.localStorage) {\n localStorage.setItem(key, serialized);\n } else {\n this.memoryCache.set(key, serialized);\n this.persist();\n }\n }\n\n remove(key: string): void {\n if (!this.isNode && window.localStorage) {\n localStorage.removeItem(key);\n } else {\n this.memoryCache.delete(key);\n this.persist();\n }\n }\n\n clear(): void {\n if (!this.isNode && window.localStorage) {\n localStorage.clear();\n } else {\n this.memoryCache.clear();\n this.persist();\n }\n }\n}\n","export class Cache<T> {\n private cache = new Map<string | number, { value: T; expiresAt: number | null }>();\n private interval: any;\n\n /**\n * A lightweight, high-performant in-memory cache.\n * Uses Map for O(1) lookups and an optional cleanup interval.\n * @param cleanupMs The interval in milliseconds to run the cleanup function. [default: 60000 (1 minute)]\n */\n constructor(cleanupMs: number = 60_000) {\n // Only run cleanup if the interval is positive\n if (cleanupMs > 0) {\n this.interval = setInterval(() => this.cleanup(), cleanupMs);\n // In Node.js, allow the process to exit even if this interval is running\n if (this.interval.unref) this.interval.unref();\n }\n }\n\n set(key: string | number, value: T, ttlMs?: number): void {\n this.cache.set(key, {\n value,\n expiresAt: ttlMs ? Date.now() + ttlMs : null\n });\n }\n\n get(key: string | number): T | null {\n const data = this.cache.get(key);\n if (!data) return null;\n\n if (data.expiresAt && Date.now() > data.expiresAt) {\n // Passive cleanup\n this.cache.delete(key);\n return null;\n }\n return data.value;\n }\n\n private cleanup(): void {\n if (this.cache.size === 0) return;\n\n const now = Date.now();\n let keysProcessed = 0;\n const maxKeysToScan = 20; // Limit per cycle to avoid CPU spikes\n\n // Iterate through the map\n for (const [key, data] of this.cache) {\n if (data.expiresAt && now > data.expiresAt) {\n this.cache.delete(key);\n }\n\n keysProcessed++;\n if (keysProcessed >= maxKeysToScan) break;\n }\n }\n\n clear(): void {\n this.cache.clear();\n }\n}\n","import EventEmitter from \"node:events\";\nimport { TypedEmitter } from \"./types\";\n\nexport type LoopState = \"running\" | \"paused\" | \"stopped\";\n\nexport interface LoopEvents<T> {\n start: [];\n tick: [result: T];\n pause: [{ remaining: number }];\n resume: [];\n stop: [];\n error: [error: any];\n}\n\nconst TypedEmitterBase = EventEmitter as { new <T>(): TypedEmitter<LoopEvents<T>> };\n\nexport class Loop<T = any> extends TypedEmitterBase<T> {\n private _state: LoopState = \"stopped\";\n private timeoutId: any = null;\n private delay: number;\n private fn: (loop: Loop<T>) => Promise<T> | T;\n\n private startTime: number = 0;\n private remaining: number = 0;\n\n private async run() {\n const currentState: LoopState = this._state;\n\n if (currentState === \"stopped\" || currentState === \"paused\") return;\n\n try {\n const result = await this.fn(this);\n this.emit(\"tick\", result);\n } catch (err) {\n this.emit(\"error\", err);\n }\n\n // Re-check state after the async function finishes\n if (this._state === \"running\") {\n this.startTime = Date.now();\n this.remaining = 0;\n this.clearTimer();\n this.timeoutId = setTimeout(() => this.run(), this.delay);\n }\n }\n\n private clearTimer() {\n if (this.timeoutId) {\n clearTimeout(this.timeoutId);\n this.timeoutId = null;\n }\n }\n\n /**\n * Creates an interval. If the function is async, it will wait for it to complete before scheduling the next run.\n * @param fn The function to run.\n * @param delay The delay between runs in milliseconds.\n * @param immediate Whether to start the loop immediately. [default: true]\n */\n constructor(fn: (loop: Loop<T>) => Promise<T> | T, delay: number, immediate = true) {\n super();\n this.fn = fn;\n this.delay = delay;\n if (immediate) this.start();\n }\n\n get state(): LoopState {\n return this._state;\n }\n\n /** Starts the loop. */\n start() {\n if (this._state !== \"stopped\") return;\n this._state = \"running\";\n this.emit(\"start\");\n this.run();\n }\n\n /** Resumes a paused loop. */\n resume() {\n if (this._state !== \"paused\") return;\n this._state = \"running\";\n this.emit(\"resume\");\n if (this.remaining <= 0) {\n this.run();\n } else {\n this.timeoutId = setTimeout(() => this.run(), this.remaining);\n }\n }\n\n /** Stops the loop. */\n stop() {\n const wasRunning = this._state !== \"stopped\";\n this._state = \"stopped\";\n this.remaining = 0;\n this.clearTimer();\n if (wasRunning) this.emit(\"stop\");\n }\n\n /** Pauses the execution. */\n pause() {\n if (this._state !== \"running\") return;\n this._state = \"paused\";\n const elapsed = Date.now() - this.startTime;\n this.remaining = Math.max(0, this.delay - elapsed);\n this.emit(\"pause\", { remaining: this.remaining });\n this.clearTimer();\n }\n\n /**\n * Sets the delay between runs\n * @param ms The new delay in milliseconds.\n */\n setDelay(ms: number) {\n this.delay = ms;\n }\n\n /** Manually trigger the function once without affecting the loop. */\n async execute() {\n await this.fn(this);\n }\n}\n"],"mappings":"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","names":["str","percent","rnd","index","seed","fn","ms","fn","date","ms","str","path","_fs","fn","arr","date","today","obj","path","str","str","index","fn","wait","fn","import_node_fs","import_node_path","fs","path","EventEmitter","fn","ms"]}
|
package/dist/index.d.mts
CHANGED
|
@@ -193,10 +193,22 @@ declare const fs: {
|
|
|
193
193
|
};
|
|
194
194
|
|
|
195
195
|
type AlphaCasing = "lower" | "upper" | "mixed";
|
|
196
|
+
interface RndArrayOptions<T> {
|
|
197
|
+
/** Optional seed for RNG. */
|
|
198
|
+
seed?: number;
|
|
199
|
+
/** Reroll if the result is equal to this value. */
|
|
200
|
+
not?: ((item: T) => boolean) | T;
|
|
201
|
+
/** Maximum number of times to reroll if `not` is specified. [default: 10] */
|
|
202
|
+
maxRerolls?: number;
|
|
203
|
+
}
|
|
196
204
|
interface RndStrOptions {
|
|
197
|
-
|
|
205
|
+
/** Optional seed for RNG. */
|
|
198
206
|
seed?: number;
|
|
207
|
+
/** Character casing mode. */
|
|
208
|
+
casing?: AlphaCasing;
|
|
209
|
+
/** Custom character pool. */
|
|
199
210
|
customChars?: string;
|
|
211
|
+
/** Characters to exclude from the pool. */
|
|
200
212
|
exclude?: string | string[];
|
|
201
213
|
}
|
|
202
214
|
/**
|
|
@@ -208,9 +220,9 @@ declare function chance(percent?: number, seed?: number): boolean;
|
|
|
208
220
|
/**
|
|
209
221
|
* Returns a random item from the given array.
|
|
210
222
|
* @param array Array of items to choose from.
|
|
211
|
-
* @param
|
|
223
|
+
* @param options Options for the choice function.
|
|
212
224
|
*/
|
|
213
|
-
declare function choice<T>(array: T[],
|
|
225
|
+
declare function choice<T>(array: T[], options?: RndArrayOptions<T>): T;
|
|
214
226
|
/**
|
|
215
227
|
* Returns a random item from the given array based on their corresponding weights.
|
|
216
228
|
* @param array Array of items to choose from.
|
|
@@ -250,9 +262,9 @@ declare function float(min: number, max: number, seed?: number): number;
|
|
|
250
262
|
/**
|
|
251
263
|
* Returns a random index from the given array.
|
|
252
264
|
* @param array The array to generate an index for.
|
|
253
|
-
* @param
|
|
265
|
+
* @param options Options for the index function.
|
|
254
266
|
*/
|
|
255
|
-
declare function index(array:
|
|
267
|
+
declare function index<T>(array: T[], options?: RndArrayOptions<number>): number;
|
|
256
268
|
/**
|
|
257
269
|
* Generates a random integer between the given minimum and maximum values.
|
|
258
270
|
* @param min The minimum value (inclusive) for the random integer.
|
|
@@ -732,14 +744,14 @@ declare const qznt: {
|
|
|
732
744
|
};
|
|
733
745
|
rnd: {
|
|
734
746
|
chance: (percent?: number, seed?: number) => boolean;
|
|
735
|
-
choice: <T>(array: T[],
|
|
747
|
+
choice: <T>(array: T[], options?: RndArrayOptions<T>) => T;
|
|
736
748
|
weighted: <T>(array: T[], selector: (item: T) => number, seed?: number) => T;
|
|
737
749
|
sampler: <T>(items: T[], selector: (item: T) => number, seed?: number) => {
|
|
738
750
|
pick: (seed?: number) => T | undefined;
|
|
739
751
|
};
|
|
740
752
|
prng: (seed: number) => () => number;
|
|
741
753
|
float: (min: number, max: number, seed?: number) => number;
|
|
742
|
-
index: (array:
|
|
754
|
+
index: <T>(array: T[], options?: RndArrayOptions<number>) => number;
|
|
743
755
|
int: (min: number, max: number, seed?: number) => number;
|
|
744
756
|
str: (len: number, mode: "number" | "alpha" | "alphanumeric" | "custom", options?: RndStrOptions) => string;
|
|
745
757
|
};
|
|
@@ -856,14 +868,14 @@ declare const $: {
|
|
|
856
868
|
};
|
|
857
869
|
rnd: {
|
|
858
870
|
chance: (percent?: number, seed?: number) => boolean;
|
|
859
|
-
choice: <T>(array: T[],
|
|
871
|
+
choice: <T>(array: T[], options?: RndArrayOptions<T>) => T;
|
|
860
872
|
weighted: <T>(array: T[], selector: (item: T) => number, seed?: number) => T;
|
|
861
873
|
sampler: <T>(items: T[], selector: (item: T) => number, seed?: number) => {
|
|
862
874
|
pick: (seed?: number) => T | undefined;
|
|
863
875
|
};
|
|
864
876
|
prng: (seed: number) => () => number;
|
|
865
877
|
float: (min: number, max: number, seed?: number) => number;
|
|
866
|
-
index: (array:
|
|
878
|
+
index: <T>(array: T[], options?: RndArrayOptions<number>) => number;
|
|
867
879
|
int: (min: number, max: number, seed?: number) => number;
|
|
868
880
|
str: (len: number, mode: "number" | "alpha" | "alphanumeric" | "custom", options?: RndStrOptions) => string;
|
|
869
881
|
};
|
|
@@ -962,4 +974,4 @@ declare const $: {
|
|
|
962
974
|
};
|
|
963
975
|
};
|
|
964
976
|
|
|
965
|
-
export { $, type AlphaCasing, type AnyFunc, Cache, type DateOptions, type DebouncedFunction, type DeepPartial, Loop, type MemoizedFunction, type ParseOptions, Pipe, type ReadDirOptions, type RndStrOptions, type SequentialMapContext, Storage, type ToRecordContext, type TypedEmitter, arr, async, date, qznt as default, fn, format, fs, is, math, obj, rnd, str, timing, to };
|
|
977
|
+
export { $, type AlphaCasing, type AnyFunc, Cache, type DateOptions, type DebouncedFunction, type DeepPartial, Loop, type MemoizedFunction, type ParseOptions, Pipe, type ReadDirOptions, type RndArrayOptions, type RndStrOptions, type SequentialMapContext, Storage, type ToRecordContext, type TypedEmitter, arr, async, date, qznt as default, fn, format, fs, is, math, obj, rnd, str, timing, to };
|