@thetally/toolbox 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,129 @@
1
+ interface DebouncedFunction<T extends (...args: any[]) => any> {
2
+ (...args: Parameters<T>): void;
3
+ cancel: () => void;
4
+ flush: () => void;
5
+ }
6
+ declare function debounce<T extends (...args: any[]) => any>(fn: T, delay?: number, options?: {
7
+ immediate?: boolean;
8
+ }): DebouncedFunction<T>;
9
+ declare function throttle<F extends (this: any, ...args: any[]) => void>(fn: F, interval?: number): (this: ThisParameterType<F>, ...args: Parameters<F>) => void;
10
+ declare function deepEqual(a: any, b: any): boolean;
11
+ declare function once<F extends (this: any, ...args: any[]) => any>(fn: F): (this: ThisParameterType<F>, ...args: Parameters<F>) => ReturnType<F>;
12
+ declare function pick<T, K extends readonly (keyof T)[]>(obj: T, keys: K): Pick<T, K[number]>;
13
+ declare function omit<T extends Record<string, any>, K extends readonly (keyof T)[]>(obj: T, keys: K): Omit<T, K[number]>;
14
+ declare function retry<T>(fn: () => Promise<T>, attempts: number, delayMs?: number): Promise<T>;
15
+ declare const noop: () => void;
16
+ declare function tryCatch<T>(fn: () => T): [error: unknown, value?: T];
17
+ declare function tap<T>(fn: (v: T) => void): (v: T) => T;
18
+ declare function range(end: number | {
19
+ start?: number;
20
+ end: number;
21
+ step?: number;
22
+ }): Generator<number>;
23
+ declare function cycle<T>(iterable: Iterable<T>): Generator<T>;
24
+ declare function chunk<T>(arr: T[], size: number): T[][];
25
+ declare function shuffle<T>(arr: T[]): T[];
26
+ declare function sample<T>(arr: T[]): T | undefined;
27
+ declare function rotate<T>(arr: T[], n: number): T[];
28
+
29
+ declare function sleep(ms: number): Promise<void>;
30
+ declare class AsyncQueue {
31
+ private queue;
32
+ run<T>(fn: () => Promise<T>): Promise<T>;
33
+ }
34
+ declare function deferred(): {
35
+ promise: Promise<unknown>;
36
+ resolve: (value: unknown) => void;
37
+ reject: (reason?: any) => void;
38
+ };
39
+ declare function timeoutPromise<T>(promise: Promise<T>, ms: number, error?: Error): Promise<unknown>;
40
+
41
+ type Flat<T> = {
42
+ [K in keyof T]: T[K];
43
+ };
44
+ type DurationBuilderLongBase = {
45
+ toMilliseconds(): number;
46
+ toSeconds(): number;
47
+ toMinutes(): number;
48
+ toHours(): number;
49
+ toDays(): number;
50
+ };
51
+ type DurationBuilderShortBase = {
52
+ toMs(): number;
53
+ toS(): number;
54
+ toM(): number;
55
+ toH(): number;
56
+ toD(): number;
57
+ };
58
+ type LongValues = {
59
+ milliseconds(v: number): DurationBuilderLong;
60
+ seconds(v: number): DurationBuilderLong;
61
+ minutes(v: number): DurationBuilderLong;
62
+ hours(v: number): DurationBuilderLong;
63
+ days(v: number): DurationBuilderLong;
64
+ };
65
+ type DurationBuilderLong = Flat<DurationBuilderLongBase & LongValues>;
66
+ type ShortValues = {
67
+ ms(v: number): DurationBuilderShort;
68
+ s(v: number): DurationBuilderShort;
69
+ m(v: number): DurationBuilderShort;
70
+ h(v: number): DurationBuilderShort;
71
+ d(v: number): DurationBuilderShort;
72
+ };
73
+ type DurationBuilderShort = Flat<DurationBuilderShortBase & ShortValues>;
74
+ declare const days: (v: number) => Flat<DurationBuilderLongBase & LongValues>;
75
+ declare const hours: (v: number) => Flat<DurationBuilderLongBase & LongValues>;
76
+ declare const minutes: (v: number) => Flat<DurationBuilderLongBase & LongValues>;
77
+ declare const seconds: (v: number) => Flat<DurationBuilderLongBase & LongValues>;
78
+ declare const milliseconds: (v: number) => Flat<DurationBuilderLongBase & LongValues>;
79
+ declare const d: (v: number) => Flat<DurationBuilderShortBase & ShortValues>;
80
+ declare const h: (v: number) => Flat<DurationBuilderShortBase & ShortValues>;
81
+ declare const m: (v: number) => Flat<DurationBuilderShortBase & ShortValues>;
82
+ declare const s: (v: number) => Flat<DurationBuilderShortBase & ShortValues>;
83
+ declare const ms: (v: number) => Flat<DurationBuilderShortBase & ShortValues>;
84
+
85
+ declare function bigIntPower(one: bigint, two: bigint): bigint;
86
+ declare function convertBase(value: string, sourceBase: number, outBase: number, chars?: string): string;
87
+ declare namespace convertBase {
88
+ var defaultChars: string;
89
+ var MAX_BASE: number;
90
+ }
91
+ declare function clamp(number: number, min: number, max: number): number;
92
+ declare function randInt(min: number, max: number, inclusive?: boolean): number;
93
+ declare function chance(probability: number): boolean;
94
+ declare function roundTo(n: number, decimals: number): number;
95
+ declare function lerp(a: number, b: number, t: number): number;
96
+ declare function inRange(n: number, min: number, max: number): boolean;
97
+
98
+ declare class TimedMap<K, V> {
99
+ private defaultTtlMs?;
100
+ private map;
101
+ private timers;
102
+ constructor(defaultTtlMs?: number | undefined);
103
+ set(key: K, value: V, ttlMs?: number | undefined): void;
104
+ has(key: K): boolean;
105
+ clear(): void;
106
+ get(key: K): V | undefined;
107
+ delete(key: K): boolean;
108
+ get size(): number;
109
+ }
110
+
111
+ type ValueOf<T> = T[keyof T];
112
+ type Entries<T> = {
113
+ [K in keyof T]: [K, T[K]];
114
+ }[keyof T][];
115
+ type Mutable<T> = {
116
+ -readonly [K in keyof T]: T[K];
117
+ };
118
+ type DeepPartial<T> = {
119
+ [K in keyof T]?: T[K] extends object ? DeepPartial<T[K]> : T[K];
120
+ };
121
+ type DeepRequired<T> = {
122
+ [K in keyof T]-?: T[K] extends object ? DeepRequired<T[K]> : T[K];
123
+ };
124
+ type Nullable<T> = T | null | undefined;
125
+ type NonNullable<T> = T extends null | undefined ? never : T;
126
+ type TupleOf<T, N extends number, R extends T[] = []> = R["length"] extends N ? R : TupleOf<T, N, [T, ...R]>;
127
+ type Merge<A, B> = Omit<A, keyof B> & B;
128
+
129
+ export { AsyncQueue, type DebouncedFunction, type DeepPartial, type DeepRequired, type Entries, type Merge, type Mutable, type NonNullable, type Nullable, TimedMap, type TupleOf, type ValueOf, bigIntPower, chance, chunk, clamp, convertBase, cycle, d, days, debounce, deepEqual, deferred, h, hours, inRange, lerp, m, milliseconds, minutes, ms, noop, omit, once, pick, randInt, range, retry, rotate, roundTo, s, sample, seconds, shuffle, sleep, tap, throttle, timeoutPromise, tryCatch };
@@ -0,0 +1,129 @@
1
+ interface DebouncedFunction<T extends (...args: any[]) => any> {
2
+ (...args: Parameters<T>): void;
3
+ cancel: () => void;
4
+ flush: () => void;
5
+ }
6
+ declare function debounce<T extends (...args: any[]) => any>(fn: T, delay?: number, options?: {
7
+ immediate?: boolean;
8
+ }): DebouncedFunction<T>;
9
+ declare function throttle<F extends (this: any, ...args: any[]) => void>(fn: F, interval?: number): (this: ThisParameterType<F>, ...args: Parameters<F>) => void;
10
+ declare function deepEqual(a: any, b: any): boolean;
11
+ declare function once<F extends (this: any, ...args: any[]) => any>(fn: F): (this: ThisParameterType<F>, ...args: Parameters<F>) => ReturnType<F>;
12
+ declare function pick<T, K extends readonly (keyof T)[]>(obj: T, keys: K): Pick<T, K[number]>;
13
+ declare function omit<T extends Record<string, any>, K extends readonly (keyof T)[]>(obj: T, keys: K): Omit<T, K[number]>;
14
+ declare function retry<T>(fn: () => Promise<T>, attempts: number, delayMs?: number): Promise<T>;
15
+ declare const noop: () => void;
16
+ declare function tryCatch<T>(fn: () => T): [error: unknown, value?: T];
17
+ declare function tap<T>(fn: (v: T) => void): (v: T) => T;
18
+ declare function range(end: number | {
19
+ start?: number;
20
+ end: number;
21
+ step?: number;
22
+ }): Generator<number>;
23
+ declare function cycle<T>(iterable: Iterable<T>): Generator<T>;
24
+ declare function chunk<T>(arr: T[], size: number): T[][];
25
+ declare function shuffle<T>(arr: T[]): T[];
26
+ declare function sample<T>(arr: T[]): T | undefined;
27
+ declare function rotate<T>(arr: T[], n: number): T[];
28
+
29
+ declare function sleep(ms: number): Promise<void>;
30
+ declare class AsyncQueue {
31
+ private queue;
32
+ run<T>(fn: () => Promise<T>): Promise<T>;
33
+ }
34
+ declare function deferred(): {
35
+ promise: Promise<unknown>;
36
+ resolve: (value: unknown) => void;
37
+ reject: (reason?: any) => void;
38
+ };
39
+ declare function timeoutPromise<T>(promise: Promise<T>, ms: number, error?: Error): Promise<unknown>;
40
+
41
+ type Flat<T> = {
42
+ [K in keyof T]: T[K];
43
+ };
44
+ type DurationBuilderLongBase = {
45
+ toMilliseconds(): number;
46
+ toSeconds(): number;
47
+ toMinutes(): number;
48
+ toHours(): number;
49
+ toDays(): number;
50
+ };
51
+ type DurationBuilderShortBase = {
52
+ toMs(): number;
53
+ toS(): number;
54
+ toM(): number;
55
+ toH(): number;
56
+ toD(): number;
57
+ };
58
+ type LongValues = {
59
+ milliseconds(v: number): DurationBuilderLong;
60
+ seconds(v: number): DurationBuilderLong;
61
+ minutes(v: number): DurationBuilderLong;
62
+ hours(v: number): DurationBuilderLong;
63
+ days(v: number): DurationBuilderLong;
64
+ };
65
+ type DurationBuilderLong = Flat<DurationBuilderLongBase & LongValues>;
66
+ type ShortValues = {
67
+ ms(v: number): DurationBuilderShort;
68
+ s(v: number): DurationBuilderShort;
69
+ m(v: number): DurationBuilderShort;
70
+ h(v: number): DurationBuilderShort;
71
+ d(v: number): DurationBuilderShort;
72
+ };
73
+ type DurationBuilderShort = Flat<DurationBuilderShortBase & ShortValues>;
74
+ declare const days: (v: number) => Flat<DurationBuilderLongBase & LongValues>;
75
+ declare const hours: (v: number) => Flat<DurationBuilderLongBase & LongValues>;
76
+ declare const minutes: (v: number) => Flat<DurationBuilderLongBase & LongValues>;
77
+ declare const seconds: (v: number) => Flat<DurationBuilderLongBase & LongValues>;
78
+ declare const milliseconds: (v: number) => Flat<DurationBuilderLongBase & LongValues>;
79
+ declare const d: (v: number) => Flat<DurationBuilderShortBase & ShortValues>;
80
+ declare const h: (v: number) => Flat<DurationBuilderShortBase & ShortValues>;
81
+ declare const m: (v: number) => Flat<DurationBuilderShortBase & ShortValues>;
82
+ declare const s: (v: number) => Flat<DurationBuilderShortBase & ShortValues>;
83
+ declare const ms: (v: number) => Flat<DurationBuilderShortBase & ShortValues>;
84
+
85
+ declare function bigIntPower(one: bigint, two: bigint): bigint;
86
+ declare function convertBase(value: string, sourceBase: number, outBase: number, chars?: string): string;
87
+ declare namespace convertBase {
88
+ var defaultChars: string;
89
+ var MAX_BASE: number;
90
+ }
91
+ declare function clamp(number: number, min: number, max: number): number;
92
+ declare function randInt(min: number, max: number, inclusive?: boolean): number;
93
+ declare function chance(probability: number): boolean;
94
+ declare function roundTo(n: number, decimals: number): number;
95
+ declare function lerp(a: number, b: number, t: number): number;
96
+ declare function inRange(n: number, min: number, max: number): boolean;
97
+
98
+ declare class TimedMap<K, V> {
99
+ private defaultTtlMs?;
100
+ private map;
101
+ private timers;
102
+ constructor(defaultTtlMs?: number | undefined);
103
+ set(key: K, value: V, ttlMs?: number | undefined): void;
104
+ has(key: K): boolean;
105
+ clear(): void;
106
+ get(key: K): V | undefined;
107
+ delete(key: K): boolean;
108
+ get size(): number;
109
+ }
110
+
111
+ type ValueOf<T> = T[keyof T];
112
+ type Entries<T> = {
113
+ [K in keyof T]: [K, T[K]];
114
+ }[keyof T][];
115
+ type Mutable<T> = {
116
+ -readonly [K in keyof T]: T[K];
117
+ };
118
+ type DeepPartial<T> = {
119
+ [K in keyof T]?: T[K] extends object ? DeepPartial<T[K]> : T[K];
120
+ };
121
+ type DeepRequired<T> = {
122
+ [K in keyof T]-?: T[K] extends object ? DeepRequired<T[K]> : T[K];
123
+ };
124
+ type Nullable<T> = T | null | undefined;
125
+ type NonNullable<T> = T extends null | undefined ? never : T;
126
+ type TupleOf<T, N extends number, R extends T[] = []> = R["length"] extends N ? R : TupleOf<T, N, [T, ...R]>;
127
+ type Merge<A, B> = Omit<A, keyof B> & B;
128
+
129
+ export { AsyncQueue, type DebouncedFunction, type DeepPartial, type DeepRequired, type Entries, type Merge, type Mutable, type NonNullable, type Nullable, TimedMap, type TupleOf, type ValueOf, bigIntPower, chance, chunk, clamp, convertBase, cycle, d, days, debounce, deepEqual, deferred, h, hours, inRange, lerp, m, milliseconds, minutes, ms, noop, omit, once, pick, randInt, range, retry, rotate, roundTo, s, sample, seconds, shuffle, sleep, tap, throttle, timeoutPromise, tryCatch };
package/dist/index.js ADDED
@@ -0,0 +1,461 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/index.ts
21
+ var index_exports = {};
22
+ __export(index_exports, {
23
+ AsyncQueue: () => AsyncQueue,
24
+ TimedMap: () => TimedMap,
25
+ bigIntPower: () => bigIntPower,
26
+ chance: () => chance,
27
+ chunk: () => chunk,
28
+ clamp: () => clamp,
29
+ convertBase: () => convertBase,
30
+ cycle: () => cycle,
31
+ d: () => d,
32
+ days: () => days,
33
+ debounce: () => debounce,
34
+ deepEqual: () => deepEqual,
35
+ deferred: () => deferred,
36
+ h: () => h,
37
+ hours: () => hours,
38
+ inRange: () => inRange,
39
+ lerp: () => lerp,
40
+ m: () => m,
41
+ milliseconds: () => milliseconds,
42
+ minutes: () => minutes,
43
+ ms: () => ms,
44
+ noop: () => noop,
45
+ omit: () => omit,
46
+ once: () => once,
47
+ pick: () => pick,
48
+ randInt: () => randInt,
49
+ range: () => range,
50
+ retry: () => retry,
51
+ rotate: () => rotate,
52
+ roundTo: () => roundTo,
53
+ s: () => s,
54
+ sample: () => sample,
55
+ seconds: () => seconds,
56
+ shuffle: () => shuffle,
57
+ sleep: () => sleep,
58
+ tap: () => tap,
59
+ throttle: () => throttle,
60
+ timeoutPromise: () => timeoutPromise,
61
+ tryCatch: () => tryCatch
62
+ });
63
+ module.exports = __toCommonJS(index_exports);
64
+
65
+ // src/promises.ts
66
+ function sleep(ms2) {
67
+ return new Promise((resolve) => {
68
+ setTimeout(resolve, ms2);
69
+ });
70
+ }
71
+ var AsyncQueue = class {
72
+ queue = Promise.resolve();
73
+ run(fn) {
74
+ const res = this.queue.then(fn, fn);
75
+ this.queue = res.then(
76
+ () => {
77
+ },
78
+ () => {
79
+ }
80
+ );
81
+ return res;
82
+ }
83
+ };
84
+ function deferred() {
85
+ let resolve = null;
86
+ let reject = null;
87
+ const promise = new Promise((res, rej) => {
88
+ resolve = res;
89
+ reject = rej;
90
+ });
91
+ return { promise, resolve, reject };
92
+ }
93
+ function timeoutPromise(promise, ms2, error = new Error("Timed out")) {
94
+ return Promise.race([
95
+ promise,
96
+ new Promise((_, reject) => setTimeout(() => reject(error), ms2))
97
+ ]);
98
+ }
99
+
100
+ // src/functions.ts
101
+ function debounce(fn, delay = 300, options = {}) {
102
+ let timeout = null;
103
+ let lastArgs = null;
104
+ let lastThis;
105
+ let result;
106
+ const debounced = function(...args) {
107
+ lastArgs = args;
108
+ lastThis = this;
109
+ const callNow = options.immediate && !timeout;
110
+ if (timeout) clearTimeout(timeout);
111
+ timeout = setTimeout(() => {
112
+ timeout = null;
113
+ if (!options.immediate && lastArgs) {
114
+ result = fn.apply(lastThis, lastArgs);
115
+ lastArgs = null;
116
+ }
117
+ }, delay);
118
+ if (callNow) {
119
+ result = fn.apply(lastThis, lastArgs);
120
+ lastArgs = null;
121
+ }
122
+ return result;
123
+ };
124
+ debounced.cancel = () => {
125
+ if (timeout) clearTimeout(timeout);
126
+ timeout = null;
127
+ lastArgs = null;
128
+ };
129
+ debounced.flush = () => {
130
+ if (timeout) {
131
+ clearTimeout(timeout);
132
+ timeout = null;
133
+ if (lastArgs) {
134
+ fn.apply(lastThis, lastArgs);
135
+ lastArgs = null;
136
+ }
137
+ }
138
+ };
139
+ return debounced;
140
+ }
141
+ function throttle(fn, interval = 300) {
142
+ let last = 0;
143
+ let timeout = null;
144
+ return function(...args) {
145
+ const now = Date.now();
146
+ const remaining = interval - (now - last);
147
+ if (remaining <= 0) {
148
+ last = now;
149
+ fn.apply(this, args);
150
+ } else if (!timeout) {
151
+ timeout = setTimeout(() => {
152
+ last = Date.now();
153
+ timeout = null;
154
+ fn.apply(this, args);
155
+ }, remaining);
156
+ }
157
+ };
158
+ }
159
+ function deepEqual(a, b) {
160
+ if (Object.is(a, b)) return true;
161
+ if (typeof a !== "object" || typeof b !== "object" || !a || !b) return false;
162
+ const keysA = Object.keys(a);
163
+ if (keysA.length !== Object.keys(b).length) return false;
164
+ return keysA.every((k) => deepEqual(a[k], b[k]));
165
+ }
166
+ function once(fn) {
167
+ let called = false;
168
+ let result;
169
+ return function(...args) {
170
+ if (!called) {
171
+ called = true;
172
+ result = fn.apply(this, args);
173
+ }
174
+ return result;
175
+ };
176
+ }
177
+ function pick(obj, keys) {
178
+ return Object.fromEntries(keys.map((k) => [k, obj[k]]));
179
+ }
180
+ function omit(obj, keys) {
181
+ const set = new Set(keys);
182
+ return Object.fromEntries(
183
+ Object.entries(obj).filter(([k]) => !set.has(k))
184
+ );
185
+ }
186
+ async function retry(fn, attempts, delayMs = 0) {
187
+ let lastError;
188
+ for (let i = 0; i < attempts; i++) {
189
+ try {
190
+ return await fn();
191
+ } catch (e) {
192
+ lastError = e;
193
+ if (delayMs) await sleep(delayMs);
194
+ }
195
+ }
196
+ throw lastError;
197
+ }
198
+ var noop = () => {
199
+ };
200
+ function tryCatch(fn) {
201
+ try {
202
+ return [null, fn()];
203
+ } catch (e) {
204
+ return [e];
205
+ }
206
+ }
207
+ function tap(fn) {
208
+ return (v) => {
209
+ fn(v);
210
+ return v;
211
+ };
212
+ }
213
+ function* range(end) {
214
+ let start = 0;
215
+ let step = 1;
216
+ let e = 0;
217
+ if (typeof end === "number") {
218
+ e = end;
219
+ } else {
220
+ start = end.start ?? 0;
221
+ step = end.step ?? 1;
222
+ e = end.end;
223
+ }
224
+ if (step === 0) throw new RangeError("step cannot be 0");
225
+ if (step > 0) {
226
+ for (let i = start; i < e; i += step) yield i;
227
+ } else {
228
+ for (let i = start; i > e; i += step) yield i;
229
+ }
230
+ }
231
+ function* cycle(iterable) {
232
+ const items = [...iterable];
233
+ if (!items.length) return;
234
+ while (true) {
235
+ for (const i of items) yield i;
236
+ }
237
+ }
238
+ function chunk(arr, size) {
239
+ const out = [];
240
+ for (let i = 0; i < arr.length; i += size) out.push(arr.slice(i, i + size));
241
+ return out;
242
+ }
243
+ function shuffle(arr) {
244
+ const a = [...arr];
245
+ for (let i = a.length - 1; i > 0; i--) {
246
+ const j = Math.floor(Math.random() * (i + 1));
247
+ [a[i], a[j]] = [a[j], a[i]];
248
+ }
249
+ return a;
250
+ }
251
+ function sample(arr) {
252
+ if (!arr.length) return void 0;
253
+ return arr[Math.floor(Math.random() * arr.length)];
254
+ }
255
+ function rotate(arr, n) {
256
+ const len = arr.length;
257
+ n = (n % len + len) % len;
258
+ return [...arr.slice(n), ...arr.slice(0, n)];
259
+ }
260
+
261
+ // src/duration.ts
262
+ var msValues = {
263
+ ms: 1,
264
+ s: 1e3,
265
+ m: 1e3 * 60,
266
+ h: 1e3 * 60 * 60,
267
+ d: 1e3 * 60 * 60 * 24
268
+ };
269
+ function durationLong(initialMs = 0) {
270
+ let total = initialMs;
271
+ const add = (v, mult) => {
272
+ total += v * mult;
273
+ return builder;
274
+ };
275
+ const builder = {
276
+ toMilliseconds: () => total,
277
+ toSeconds: () => total / msValues.s,
278
+ toMinutes: () => total / msValues.m,
279
+ toHours: () => total / msValues.h,
280
+ toDays: () => total / msValues.d,
281
+ milliseconds: (v) => add(v, msValues.ms),
282
+ seconds: (v) => add(v, msValues.s),
283
+ minutes: (v) => add(v, msValues.m),
284
+ hours: (v) => add(v, msValues.h),
285
+ days: (v) => add(v, msValues.d)
286
+ };
287
+ return builder;
288
+ }
289
+ function durationShort(initialMs = 0) {
290
+ let total = initialMs;
291
+ const add = (v, mult) => {
292
+ total += v * mult;
293
+ return builder;
294
+ };
295
+ const builder = {
296
+ toMs: () => total,
297
+ toS: () => total / msValues.s,
298
+ toM: () => total / msValues.m,
299
+ toH: () => total / msValues.h,
300
+ toD: () => total / msValues.d,
301
+ ms: (v) => add(v, msValues.ms),
302
+ s: (v) => add(v, msValues.s),
303
+ m: (v) => add(v, msValues.m),
304
+ h: (v) => add(v, msValues.h),
305
+ d: (v) => add(v, msValues.d)
306
+ };
307
+ return builder;
308
+ }
309
+ function cS(unit) {
310
+ return (v) => durationShort()[unit](v);
311
+ }
312
+ function cL(unit) {
313
+ return (v) => durationLong()[unit](v);
314
+ }
315
+ var days = cL("days");
316
+ var hours = cL("hours");
317
+ var minutes = cL("minutes");
318
+ var seconds = cL("seconds");
319
+ var milliseconds = cL("milliseconds");
320
+ var d = cS("d");
321
+ var h = cS("h");
322
+ var m = cS("m");
323
+ var s = cS("s");
324
+ var ms = cS("ms");
325
+
326
+ // src/numbers.ts
327
+ function bigIntPower(one, two) {
328
+ if (two === 0n) return 1n;
329
+ const powerTwo = bigIntPower(one, two / 2n);
330
+ if (two % 2n === 0n) return powerTwo * powerTwo;
331
+ return one * powerTwo * powerTwo;
332
+ }
333
+ function convertBase(value, sourceBase, outBase, chars = convertBase.defaultChars) {
334
+ const range2 = [...chars];
335
+ if (sourceBase < 2 || sourceBase > range2.length)
336
+ throw new RangeError(`sourceBase must be between 2 and ${range2.length}`);
337
+ if (outBase < 2 || outBase > range2.length)
338
+ throw new RangeError(`outBase must be between 2 and ${range2.length}`);
339
+ const outBaseBig = BigInt(outBase);
340
+ let decValue = [...value].toReversed().reduce((carry, digit, loopIndex) => {
341
+ const biggestBaseIndex = range2.indexOf(digit);
342
+ if (biggestBaseIndex === -1 || biggestBaseIndex > sourceBase - 1)
343
+ throw new ReferenceError(
344
+ `Invalid digit ${digit} for base ${sourceBase}.`
345
+ );
346
+ return carry + BigInt(biggestBaseIndex) * bigIntPower(BigInt(sourceBase), BigInt(loopIndex));
347
+ }, 0n);
348
+ let output = "";
349
+ while (decValue > 0) {
350
+ output = `${range2[Number(decValue % outBaseBig)] ?? ""}${output}`;
351
+ decValue = (decValue - decValue % outBaseBig) / outBaseBig;
352
+ }
353
+ return output || "0";
354
+ }
355
+ convertBase.defaultChars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-/=[];',.";
356
+ convertBase.MAX_BASE = convertBase.defaultChars.length;
357
+ function clamp(number, min, max) {
358
+ return Math.max(min, Math.min(max, number));
359
+ }
360
+ function randInt(min, max, inclusive = true) {
361
+ if (min > max) {
362
+ throw new RangeError("RandInt: min cannot be greater than max");
363
+ }
364
+ return Math.floor(Math.random() * (max - min + +inclusive)) + min;
365
+ }
366
+ function chance(probability) {
367
+ return Math.random() < probability;
368
+ }
369
+ function roundTo(n, decimals) {
370
+ const f = 10 ** decimals;
371
+ return Math.round(n * f) / f;
372
+ }
373
+ function lerp(a, b, t) {
374
+ return a + (b - a) * t;
375
+ }
376
+ function inRange(n, min, max) {
377
+ return n >= min && n <= max;
378
+ }
379
+
380
+ // src/timedMap.ts
381
+ var TimedMap = class {
382
+ constructor(defaultTtlMs) {
383
+ this.defaultTtlMs = defaultTtlMs;
384
+ }
385
+ map = /* @__PURE__ */ new Map();
386
+ timers = /* @__PURE__ */ new Map();
387
+ set(key, value, ttlMs = this.defaultTtlMs) {
388
+ this.map.set(key, value);
389
+ const timer = setTimeout(() => {
390
+ this.map.delete(key);
391
+ this.timers.delete(key);
392
+ }, ttlMs);
393
+ this.timers.set(key, timer);
394
+ }
395
+ has(key) {
396
+ return this.map.has(key);
397
+ }
398
+ clear() {
399
+ for (const timer of this.timers.values()) {
400
+ clearTimeout(timer);
401
+ }
402
+ this.timers.clear();
403
+ this.map.clear();
404
+ }
405
+ get(key) {
406
+ return this.map.get(key);
407
+ }
408
+ delete(key) {
409
+ const timer = this.timers.get(key);
410
+ if (timer) clearTimeout(timer);
411
+ this.timers.delete(key);
412
+ return this.map.delete(key);
413
+ }
414
+ get size() {
415
+ return this.map.size;
416
+ }
417
+ };
418
+ // Annotate the CommonJS export names for ESM import in node:
419
+ 0 && (module.exports = {
420
+ AsyncQueue,
421
+ TimedMap,
422
+ bigIntPower,
423
+ chance,
424
+ chunk,
425
+ clamp,
426
+ convertBase,
427
+ cycle,
428
+ d,
429
+ days,
430
+ debounce,
431
+ deepEqual,
432
+ deferred,
433
+ h,
434
+ hours,
435
+ inRange,
436
+ lerp,
437
+ m,
438
+ milliseconds,
439
+ minutes,
440
+ ms,
441
+ noop,
442
+ omit,
443
+ once,
444
+ pick,
445
+ randInt,
446
+ range,
447
+ retry,
448
+ rotate,
449
+ roundTo,
450
+ s,
451
+ sample,
452
+ seconds,
453
+ shuffle,
454
+ sleep,
455
+ tap,
456
+ throttle,
457
+ timeoutPromise,
458
+ tryCatch
459
+ });
460
+ //! days(12).h(5).s(4).toS();
461
+ //! d(12).hours(5).seconds(4).toS();
package/dist/index.mjs ADDED
@@ -0,0 +1,396 @@
1
+ // src/promises.ts
2
+ function sleep(ms2) {
3
+ return new Promise((resolve) => {
4
+ setTimeout(resolve, ms2);
5
+ });
6
+ }
7
+ var AsyncQueue = class {
8
+ queue = Promise.resolve();
9
+ run(fn) {
10
+ const res = this.queue.then(fn, fn);
11
+ this.queue = res.then(
12
+ () => {
13
+ },
14
+ () => {
15
+ }
16
+ );
17
+ return res;
18
+ }
19
+ };
20
+ function deferred() {
21
+ let resolve = null;
22
+ let reject = null;
23
+ const promise = new Promise((res, rej) => {
24
+ resolve = res;
25
+ reject = rej;
26
+ });
27
+ return { promise, resolve, reject };
28
+ }
29
+ function timeoutPromise(promise, ms2, error = new Error("Timed out")) {
30
+ return Promise.race([
31
+ promise,
32
+ new Promise((_, reject) => setTimeout(() => reject(error), ms2))
33
+ ]);
34
+ }
35
+
36
+ // src/functions.ts
37
+ function debounce(fn, delay = 300, options = {}) {
38
+ let timeout = null;
39
+ let lastArgs = null;
40
+ let lastThis;
41
+ let result;
42
+ const debounced = function(...args) {
43
+ lastArgs = args;
44
+ lastThis = this;
45
+ const callNow = options.immediate && !timeout;
46
+ if (timeout) clearTimeout(timeout);
47
+ timeout = setTimeout(() => {
48
+ timeout = null;
49
+ if (!options.immediate && lastArgs) {
50
+ result = fn.apply(lastThis, lastArgs);
51
+ lastArgs = null;
52
+ }
53
+ }, delay);
54
+ if (callNow) {
55
+ result = fn.apply(lastThis, lastArgs);
56
+ lastArgs = null;
57
+ }
58
+ return result;
59
+ };
60
+ debounced.cancel = () => {
61
+ if (timeout) clearTimeout(timeout);
62
+ timeout = null;
63
+ lastArgs = null;
64
+ };
65
+ debounced.flush = () => {
66
+ if (timeout) {
67
+ clearTimeout(timeout);
68
+ timeout = null;
69
+ if (lastArgs) {
70
+ fn.apply(lastThis, lastArgs);
71
+ lastArgs = null;
72
+ }
73
+ }
74
+ };
75
+ return debounced;
76
+ }
77
+ function throttle(fn, interval = 300) {
78
+ let last = 0;
79
+ let timeout = null;
80
+ return function(...args) {
81
+ const now = Date.now();
82
+ const remaining = interval - (now - last);
83
+ if (remaining <= 0) {
84
+ last = now;
85
+ fn.apply(this, args);
86
+ } else if (!timeout) {
87
+ timeout = setTimeout(() => {
88
+ last = Date.now();
89
+ timeout = null;
90
+ fn.apply(this, args);
91
+ }, remaining);
92
+ }
93
+ };
94
+ }
95
+ function deepEqual(a, b) {
96
+ if (Object.is(a, b)) return true;
97
+ if (typeof a !== "object" || typeof b !== "object" || !a || !b) return false;
98
+ const keysA = Object.keys(a);
99
+ if (keysA.length !== Object.keys(b).length) return false;
100
+ return keysA.every((k) => deepEqual(a[k], b[k]));
101
+ }
102
+ function once(fn) {
103
+ let called = false;
104
+ let result;
105
+ return function(...args) {
106
+ if (!called) {
107
+ called = true;
108
+ result = fn.apply(this, args);
109
+ }
110
+ return result;
111
+ };
112
+ }
113
+ function pick(obj, keys) {
114
+ return Object.fromEntries(keys.map((k) => [k, obj[k]]));
115
+ }
116
+ function omit(obj, keys) {
117
+ const set = new Set(keys);
118
+ return Object.fromEntries(
119
+ Object.entries(obj).filter(([k]) => !set.has(k))
120
+ );
121
+ }
122
+ async function retry(fn, attempts, delayMs = 0) {
123
+ let lastError;
124
+ for (let i = 0; i < attempts; i++) {
125
+ try {
126
+ return await fn();
127
+ } catch (e) {
128
+ lastError = e;
129
+ if (delayMs) await sleep(delayMs);
130
+ }
131
+ }
132
+ throw lastError;
133
+ }
134
+ var noop = () => {
135
+ };
136
+ function tryCatch(fn) {
137
+ try {
138
+ return [null, fn()];
139
+ } catch (e) {
140
+ return [e];
141
+ }
142
+ }
143
+ function tap(fn) {
144
+ return (v) => {
145
+ fn(v);
146
+ return v;
147
+ };
148
+ }
149
+ function* range(end) {
150
+ let start = 0;
151
+ let step = 1;
152
+ let e = 0;
153
+ if (typeof end === "number") {
154
+ e = end;
155
+ } else {
156
+ start = end.start ?? 0;
157
+ step = end.step ?? 1;
158
+ e = end.end;
159
+ }
160
+ if (step === 0) throw new RangeError("step cannot be 0");
161
+ if (step > 0) {
162
+ for (let i = start; i < e; i += step) yield i;
163
+ } else {
164
+ for (let i = start; i > e; i += step) yield i;
165
+ }
166
+ }
167
+ function* cycle(iterable) {
168
+ const items = [...iterable];
169
+ if (!items.length) return;
170
+ while (true) {
171
+ for (const i of items) yield i;
172
+ }
173
+ }
174
+ function chunk(arr, size) {
175
+ const out = [];
176
+ for (let i = 0; i < arr.length; i += size) out.push(arr.slice(i, i + size));
177
+ return out;
178
+ }
179
+ function shuffle(arr) {
180
+ const a = [...arr];
181
+ for (let i = a.length - 1; i > 0; i--) {
182
+ const j = Math.floor(Math.random() * (i + 1));
183
+ [a[i], a[j]] = [a[j], a[i]];
184
+ }
185
+ return a;
186
+ }
187
+ function sample(arr) {
188
+ if (!arr.length) return void 0;
189
+ return arr[Math.floor(Math.random() * arr.length)];
190
+ }
191
+ function rotate(arr, n) {
192
+ const len = arr.length;
193
+ n = (n % len + len) % len;
194
+ return [...arr.slice(n), ...arr.slice(0, n)];
195
+ }
196
+
197
+ // src/duration.ts
198
+ var msValues = {
199
+ ms: 1,
200
+ s: 1e3,
201
+ m: 1e3 * 60,
202
+ h: 1e3 * 60 * 60,
203
+ d: 1e3 * 60 * 60 * 24
204
+ };
205
+ function durationLong(initialMs = 0) {
206
+ let total = initialMs;
207
+ const add = (v, mult) => {
208
+ total += v * mult;
209
+ return builder;
210
+ };
211
+ const builder = {
212
+ toMilliseconds: () => total,
213
+ toSeconds: () => total / msValues.s,
214
+ toMinutes: () => total / msValues.m,
215
+ toHours: () => total / msValues.h,
216
+ toDays: () => total / msValues.d,
217
+ milliseconds: (v) => add(v, msValues.ms),
218
+ seconds: (v) => add(v, msValues.s),
219
+ minutes: (v) => add(v, msValues.m),
220
+ hours: (v) => add(v, msValues.h),
221
+ days: (v) => add(v, msValues.d)
222
+ };
223
+ return builder;
224
+ }
225
+ function durationShort(initialMs = 0) {
226
+ let total = initialMs;
227
+ const add = (v, mult) => {
228
+ total += v * mult;
229
+ return builder;
230
+ };
231
+ const builder = {
232
+ toMs: () => total,
233
+ toS: () => total / msValues.s,
234
+ toM: () => total / msValues.m,
235
+ toH: () => total / msValues.h,
236
+ toD: () => total / msValues.d,
237
+ ms: (v) => add(v, msValues.ms),
238
+ s: (v) => add(v, msValues.s),
239
+ m: (v) => add(v, msValues.m),
240
+ h: (v) => add(v, msValues.h),
241
+ d: (v) => add(v, msValues.d)
242
+ };
243
+ return builder;
244
+ }
245
+ function cS(unit) {
246
+ return (v) => durationShort()[unit](v);
247
+ }
248
+ function cL(unit) {
249
+ return (v) => durationLong()[unit](v);
250
+ }
251
+ var days = cL("days");
252
+ var hours = cL("hours");
253
+ var minutes = cL("minutes");
254
+ var seconds = cL("seconds");
255
+ var milliseconds = cL("milliseconds");
256
+ var d = cS("d");
257
+ var h = cS("h");
258
+ var m = cS("m");
259
+ var s = cS("s");
260
+ var ms = cS("ms");
261
+
262
+ // src/numbers.ts
263
+ function bigIntPower(one, two) {
264
+ if (two === 0n) return 1n;
265
+ const powerTwo = bigIntPower(one, two / 2n);
266
+ if (two % 2n === 0n) return powerTwo * powerTwo;
267
+ return one * powerTwo * powerTwo;
268
+ }
269
+ function convertBase(value, sourceBase, outBase, chars = convertBase.defaultChars) {
270
+ const range2 = [...chars];
271
+ if (sourceBase < 2 || sourceBase > range2.length)
272
+ throw new RangeError(`sourceBase must be between 2 and ${range2.length}`);
273
+ if (outBase < 2 || outBase > range2.length)
274
+ throw new RangeError(`outBase must be between 2 and ${range2.length}`);
275
+ const outBaseBig = BigInt(outBase);
276
+ let decValue = [...value].toReversed().reduce((carry, digit, loopIndex) => {
277
+ const biggestBaseIndex = range2.indexOf(digit);
278
+ if (biggestBaseIndex === -1 || biggestBaseIndex > sourceBase - 1)
279
+ throw new ReferenceError(
280
+ `Invalid digit ${digit} for base ${sourceBase}.`
281
+ );
282
+ return carry + BigInt(biggestBaseIndex) * bigIntPower(BigInt(sourceBase), BigInt(loopIndex));
283
+ }, 0n);
284
+ let output = "";
285
+ while (decValue > 0) {
286
+ output = `${range2[Number(decValue % outBaseBig)] ?? ""}${output}`;
287
+ decValue = (decValue - decValue % outBaseBig) / outBaseBig;
288
+ }
289
+ return output || "0";
290
+ }
291
+ convertBase.defaultChars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-/=[];',.";
292
+ convertBase.MAX_BASE = convertBase.defaultChars.length;
293
+ function clamp(number, min, max) {
294
+ return Math.max(min, Math.min(max, number));
295
+ }
296
+ function randInt(min, max, inclusive = true) {
297
+ if (min > max) {
298
+ throw new RangeError("RandInt: min cannot be greater than max");
299
+ }
300
+ return Math.floor(Math.random() * (max - min + +inclusive)) + min;
301
+ }
302
+ function chance(probability) {
303
+ return Math.random() < probability;
304
+ }
305
+ function roundTo(n, decimals) {
306
+ const f = 10 ** decimals;
307
+ return Math.round(n * f) / f;
308
+ }
309
+ function lerp(a, b, t) {
310
+ return a + (b - a) * t;
311
+ }
312
+ function inRange(n, min, max) {
313
+ return n >= min && n <= max;
314
+ }
315
+
316
+ // src/timedMap.ts
317
+ var TimedMap = class {
318
+ constructor(defaultTtlMs) {
319
+ this.defaultTtlMs = defaultTtlMs;
320
+ }
321
+ map = /* @__PURE__ */ new Map();
322
+ timers = /* @__PURE__ */ new Map();
323
+ set(key, value, ttlMs = this.defaultTtlMs) {
324
+ this.map.set(key, value);
325
+ const timer = setTimeout(() => {
326
+ this.map.delete(key);
327
+ this.timers.delete(key);
328
+ }, ttlMs);
329
+ this.timers.set(key, timer);
330
+ }
331
+ has(key) {
332
+ return this.map.has(key);
333
+ }
334
+ clear() {
335
+ for (const timer of this.timers.values()) {
336
+ clearTimeout(timer);
337
+ }
338
+ this.timers.clear();
339
+ this.map.clear();
340
+ }
341
+ get(key) {
342
+ return this.map.get(key);
343
+ }
344
+ delete(key) {
345
+ const timer = this.timers.get(key);
346
+ if (timer) clearTimeout(timer);
347
+ this.timers.delete(key);
348
+ return this.map.delete(key);
349
+ }
350
+ get size() {
351
+ return this.map.size;
352
+ }
353
+ };
354
+ export {
355
+ AsyncQueue,
356
+ TimedMap,
357
+ bigIntPower,
358
+ chance,
359
+ chunk,
360
+ clamp,
361
+ convertBase,
362
+ cycle,
363
+ d,
364
+ days,
365
+ debounce,
366
+ deepEqual,
367
+ deferred,
368
+ h,
369
+ hours,
370
+ inRange,
371
+ lerp,
372
+ m,
373
+ milliseconds,
374
+ minutes,
375
+ ms,
376
+ noop,
377
+ omit,
378
+ once,
379
+ pick,
380
+ randInt,
381
+ range,
382
+ retry,
383
+ rotate,
384
+ roundTo,
385
+ s,
386
+ sample,
387
+ seconds,
388
+ shuffle,
389
+ sleep,
390
+ tap,
391
+ throttle,
392
+ timeoutPromise,
393
+ tryCatch
394
+ };
395
+ //! days(12).h(5).s(4).toS();
396
+ //! d(12).hours(5).seconds(4).toS();
package/package.json ADDED
@@ -0,0 +1,23 @@
1
+ {
2
+ "name": "@thetally/toolbox",
3
+ "version": "1.0.0",
4
+ "description": "Core utils and helpers for nodejs",
5
+ "main": "dist/index.js",
6
+ "types": "dist/index.d.ts",
7
+ "exports": {
8
+ ".": {
9
+ "import": "./dist/index.mjs",
10
+ "require": "./dist/index.js",
11
+ "types": "./dist/index.d.ts"
12
+ }
13
+ },
14
+ "scripts": {
15
+ "build": "tsup src/index.ts --format esm,cjs --dts"
16
+ },
17
+ "files": [
18
+ "dist"
19
+ ],
20
+ "keywords": ["utility", "debounce", "sleep"],
21
+ "author": "",
22
+ "license": "ISC"
23
+ }