@depthbomb/common 1.3.1 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +286 -1
- package/dist/collections.cjs +1 -0
- package/dist/{queue.d.cts → collections.d.cts} +31 -5
- package/dist/{queue.d.mts → collections.d.mts} +31 -5
- package/dist/collections.mjs +1 -0
- package/dist/decorators.cjs +1 -1
- package/dist/decorators.d.cts +1 -1
- package/dist/decorators.d.mts +1 -1
- package/dist/decorators.mjs +1 -1
- package/dist/functional.cjs +1 -0
- package/dist/{fn.d.cts → functional.d.cts} +1 -1
- package/dist/{fn.d.mts → functional.d.mts} +1 -1
- package/dist/guards.cjs +1 -0
- package/dist/guards.d.cts +7 -0
- package/dist/guards.d.mts +7 -0
- package/dist/guards.mjs +1 -0
- package/dist/index.cjs +1 -1
- package/dist/index.d.cts +12 -7
- package/dist/index.d.mts +12 -7
- package/dist/index.mjs +1 -1
- package/dist/lazy.cjs +1 -1
- package/dist/lazy.d.cts +1 -5
- package/dist/lazy.d.mts +1 -5
- package/dist/lazy.mjs +1 -1
- package/dist/number.cjs +1 -0
- package/dist/number.d.cts +8 -0
- package/dist/number.d.mts +8 -0
- package/dist/number.mjs +1 -0
- package/dist/promise.cjs +1 -0
- package/dist/promise.d.cts +48 -0
- package/dist/promise.d.mts +48 -0
- package/dist/promise.mjs +1 -0
- package/dist/random.cjs +1 -0
- package/dist/random.d.cts +11 -0
- package/dist/random.d.mts +11 -0
- package/dist/random.mjs +1 -0
- package/dist/state.cjs +1 -0
- package/dist/state.d.cts +88 -0
- package/dist/state.d.mts +88 -0
- package/dist/state.mjs +1 -0
- package/dist/timing.cjs +1 -0
- package/dist/timing.d.cts +71 -0
- package/dist/timing.d.mts +71 -0
- package/dist/timing.mjs +1 -0
- package/dist/typing.cjs +1 -0
- package/dist/typing.d.cts +26 -0
- package/dist/typing.d.mts +26 -0
- package/dist/typing.mjs +1 -0
- package/dist/url.cjs +1 -0
- package/dist/{urllib.d.cts → url.d.cts} +12 -2
- package/dist/{urllib.d.mts → url.d.mts} +12 -2
- package/dist/url.mjs +1 -0
- package/package.json +103 -81
- package/dist/async.cjs +0 -1
- package/dist/async.d.cts +0 -44
- package/dist/async.d.mts +0 -44
- package/dist/async.mjs +0 -1
- package/dist/fn.cjs +0 -1
- package/dist/queue.cjs +0 -1
- package/dist/queue.mjs +0 -1
- package/dist/types.cjs +0 -1
- package/dist/types.d.cts +0 -9
- package/dist/types.d.mts +0 -9
- package/dist/types.mjs +0 -1
- package/dist/urllib.cjs +0 -1
- package/dist/urllib.mjs +0 -1
- /package/dist/{fn.mjs → functional.mjs} +0 -0
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { Awaitable } from "./typing.cjs";
|
|
2
|
+
|
|
3
|
+
//#region src/promise.d.ts
|
|
4
|
+
interface IConcurrencyOptions {
|
|
5
|
+
concurrency?: number;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Waits for all promises to settle and returns an array of successful results.
|
|
9
|
+
*
|
|
10
|
+
* @param promises An array of promises to wait for
|
|
11
|
+
* @returns A promise that resolves to an array of successful results
|
|
12
|
+
*/
|
|
13
|
+
declare function allSettledSuccessful<T>(promises: Array<Awaitable<T>>): Promise<T[]>;
|
|
14
|
+
interface SettledDetailed<T> {
|
|
15
|
+
results: Array<PromiseSettledResult<T>>;
|
|
16
|
+
fulfilled: T[];
|
|
17
|
+
rejected: unknown[];
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Waits for all values to settle and returns full settled results plus split fulfilled/rejected lists.
|
|
21
|
+
*
|
|
22
|
+
* @param promises Values or promises to settle.
|
|
23
|
+
*/
|
|
24
|
+
declare function allSettledDetailed<T>(promises: Array<Awaitable<T>>): Promise<SettledDetailed<T>>;
|
|
25
|
+
/**
|
|
26
|
+
* Executes an array of asynchronous tasks sequentially.
|
|
27
|
+
*
|
|
28
|
+
* @param tasks An array of functions that return promises
|
|
29
|
+
* @returns A promise that resolves to an array of results from the input tasks
|
|
30
|
+
*/
|
|
31
|
+
declare function sequential<T>(tasks: Array<() => Awaitable<T>>): Promise<T[]>;
|
|
32
|
+
/**
|
|
33
|
+
* Runs asynchronous tasks with a concurrency limit while preserving result order.
|
|
34
|
+
*
|
|
35
|
+
* @param tasks Task functions to execute.
|
|
36
|
+
* @param options Concurrency options.
|
|
37
|
+
*/
|
|
38
|
+
declare function pool<T>(tasks: Array<() => Awaitable<T>>, options?: IConcurrencyOptions): Promise<T[]>;
|
|
39
|
+
/**
|
|
40
|
+
* Maps values using an async mapper with a concurrency limit.
|
|
41
|
+
*
|
|
42
|
+
* @param values Input values.
|
|
43
|
+
* @param mapper Mapping function.
|
|
44
|
+
* @param options Concurrency options.
|
|
45
|
+
*/
|
|
46
|
+
declare function pMap<T, U>(values: Iterable<T>, mapper: (value: T, index: number) => Awaitable<U>, options?: IConcurrencyOptions): Promise<U[]>;
|
|
47
|
+
//#endregion
|
|
48
|
+
export { IConcurrencyOptions, SettledDetailed, allSettledDetailed, allSettledSuccessful, pMap, pool, sequential };
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { Awaitable } from "./typing.mjs";
|
|
2
|
+
|
|
3
|
+
//#region src/promise.d.ts
|
|
4
|
+
interface IConcurrencyOptions {
|
|
5
|
+
concurrency?: number;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Waits for all promises to settle and returns an array of successful results.
|
|
9
|
+
*
|
|
10
|
+
* @param promises An array of promises to wait for
|
|
11
|
+
* @returns A promise that resolves to an array of successful results
|
|
12
|
+
*/
|
|
13
|
+
declare function allSettledSuccessful<T>(promises: Array<Awaitable<T>>): Promise<T[]>;
|
|
14
|
+
interface SettledDetailed<T> {
|
|
15
|
+
results: Array<PromiseSettledResult<T>>;
|
|
16
|
+
fulfilled: T[];
|
|
17
|
+
rejected: unknown[];
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Waits for all values to settle and returns full settled results plus split fulfilled/rejected lists.
|
|
21
|
+
*
|
|
22
|
+
* @param promises Values or promises to settle.
|
|
23
|
+
*/
|
|
24
|
+
declare function allSettledDetailed<T>(promises: Array<Awaitable<T>>): Promise<SettledDetailed<T>>;
|
|
25
|
+
/**
|
|
26
|
+
* Executes an array of asynchronous tasks sequentially.
|
|
27
|
+
*
|
|
28
|
+
* @param tasks An array of functions that return promises
|
|
29
|
+
* @returns A promise that resolves to an array of results from the input tasks
|
|
30
|
+
*/
|
|
31
|
+
declare function sequential<T>(tasks: Array<() => Awaitable<T>>): Promise<T[]>;
|
|
32
|
+
/**
|
|
33
|
+
* Runs asynchronous tasks with a concurrency limit while preserving result order.
|
|
34
|
+
*
|
|
35
|
+
* @param tasks Task functions to execute.
|
|
36
|
+
* @param options Concurrency options.
|
|
37
|
+
*/
|
|
38
|
+
declare function pool<T>(tasks: Array<() => Awaitable<T>>, options?: IConcurrencyOptions): Promise<T[]>;
|
|
39
|
+
/**
|
|
40
|
+
* Maps values using an async mapper with a concurrency limit.
|
|
41
|
+
*
|
|
42
|
+
* @param values Input values.
|
|
43
|
+
* @param mapper Mapping function.
|
|
44
|
+
* @param options Concurrency options.
|
|
45
|
+
*/
|
|
46
|
+
declare function pMap<T, U>(values: Iterable<T>, mapper: (value: T, index: number) => Awaitable<U>, options?: IConcurrencyOptions): Promise<U[]>;
|
|
47
|
+
//#endregion
|
|
48
|
+
export { IConcurrencyOptions, SettledDetailed, allSettledDetailed, allSettledSuccessful, pMap, pool, sequential };
|
package/dist/promise.mjs
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
async function e(e){return(await Promise.allSettled(e)).filter(e=>e.status===`fulfilled`).map(e=>e.value)}async function t(e){let t=await Promise.allSettled(e),n=[],r=[];for(let e of t){if(e.status===`fulfilled`){n.push(e.value);continue}r.push(e.reason)}return{results:t,fulfilled:n,rejected:r}}async function n(e){let t=[];for(let n of e)t.push(await n());return t}function r(e){if(!Number.isInteger(e)||e<1)throw Error(`concurrency must be an integer >= 1`);return e}async function i(e,t={}){if(e.length===0)return[];let n=r(t.concurrency??e.length),i=Array(e.length),a=0;async function o(){for(;;){let t=a++;if(t>=e.length)return;i[t]=await e[t]()}}let s=Math.min(n,e.length),c=Array.from({length:s},()=>o());return await Promise.all(c),i}async function a(e,t,n={}){let r=[],a=0;for(let n of e){let e=a++;r.push(()=>t(n,e))}return i(r,n)}export{t as allSettledDetailed,e as allSettledSuccessful,a as pMap,i as pool,n as sequential};
|
package/dist/random.cjs
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});function e(e,t){if(!Number.isFinite(e)||!Number.isFinite(t))throw Error(`min and max must be finite numbers`);if(e>t)throw Error(`min must be <= max`)}function t(t=0,n=1){return e(t,n),Math.random()*(n-t)+t}function n(n,r){if(!Number.isInteger(n)||!Number.isInteger(r))throw Error(`min and max must be integers`);return e(n,r),Math.floor(t(n,r+1))}function r(e){if(e.length===0)throw Error(`cannot pick from empty array`);return e[n(0,e.length-1)]}function i(e){if(e.length===0)throw Error(`cannot pick from empty weighted items`);let n=0;for(let t of e){if(!Number.isFinite(t.weight)||t.weight<0)throw Error(`weights must be finite numbers >= 0`);n+=t.weight}if(n<=0)throw Error(`total weight must be > 0`);let r=t(0,n);for(let t of e)if(r-=t.weight,r<=0)return t.value;return e[e.length-1].value}exports.pickRandom=r,exports.pickWeighted=i,exports.randomFloat=t,exports.randomInt=n;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
//#region src/random.d.ts
|
|
2
|
+
interface IWeightedItem<T> {
|
|
3
|
+
value: T;
|
|
4
|
+
weight: number;
|
|
5
|
+
}
|
|
6
|
+
declare function randomFloat(min?: number, max?: number): number;
|
|
7
|
+
declare function randomInt(min: number, max: number): number;
|
|
8
|
+
declare function pickRandom<T>(values: readonly T[]): T;
|
|
9
|
+
declare function pickWeighted<T>(items: Array<IWeightedItem<T>>): T;
|
|
10
|
+
//#endregion
|
|
11
|
+
export { IWeightedItem, pickRandom, pickWeighted, randomFloat, randomInt };
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
//#region src/random.d.ts
|
|
2
|
+
interface IWeightedItem<T> {
|
|
3
|
+
value: T;
|
|
4
|
+
weight: number;
|
|
5
|
+
}
|
|
6
|
+
declare function randomFloat(min?: number, max?: number): number;
|
|
7
|
+
declare function randomInt(min: number, max: number): number;
|
|
8
|
+
declare function pickRandom<T>(values: readonly T[]): T;
|
|
9
|
+
declare function pickWeighted<T>(items: Array<IWeightedItem<T>>): T;
|
|
10
|
+
//#endregion
|
|
11
|
+
export { IWeightedItem, pickRandom, pickWeighted, randomFloat, randomInt };
|
package/dist/random.mjs
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
function e(e,t){if(!Number.isFinite(e)||!Number.isFinite(t))throw Error(`min and max must be finite numbers`);if(e>t)throw Error(`min must be <= max`)}function t(t=0,n=1){return e(t,n),Math.random()*(n-t)+t}function n(n,r){if(!Number.isInteger(n)||!Number.isInteger(r))throw Error(`min and max must be integers`);return e(n,r),Math.floor(t(n,r+1))}function r(e){if(e.length===0)throw Error(`cannot pick from empty array`);return e[n(0,e.length-1)]}function i(e){if(e.length===0)throw Error(`cannot pick from empty weighted items`);let n=0;for(let t of e){if(!Number.isFinite(t.weight)||t.weight<0)throw Error(`weights must be finite numbers >= 0`);n+=t.weight}if(n<=0)throw Error(`total weight must be > 0`);let r=t(0,n);for(let t of e)if(r-=t.weight,r<=0)return t.value;return e[e.length-1].value}export{r as pickRandom,i as pickWeighted,t as randomFloat,n as randomInt};
|
package/dist/state.cjs
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});var e=class{value;#e;constructor(e){this.value=e,this.#e=e}set(e){this.value=e}reset(){this.value=this.#e}valueOf(){return this.value}toString(){return String(this.value)}},t=class extends e{constructor(e=!1){super(e)}get isTrue(){return this.value===!0}get isFalse(){return!this.isTrue}set(e){super.set(e)}setTrue(){this.value=!0}setFalse(){this.value=!1}toggle(){this.value=!this.value}};function n(e){let t,n=!1;function r(){return n||=(t=e(),!0),t}function i(){n=!1,t=void 0}return{get:r,reset:i}}function r(e){let t;function n(){return t||=e().catch(e=>{throw t=void 0,e}),t}function r(){t=void 0}return{get:n,reset:r}}exports.Flag=t,exports.ResettableValue=e,exports.resettableLazy=n,exports.resettableLazyAsync=r;
|
package/dist/state.d.cts
ADDED
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
//#region src/state.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* Holds a mutable value and remembers its initial value so it can be restored.
|
|
4
|
+
*
|
|
5
|
+
* @typeParam T Type of the held value.
|
|
6
|
+
*/
|
|
7
|
+
declare class ResettableValue<T> {
|
|
8
|
+
#private;
|
|
9
|
+
/**
|
|
10
|
+
* The current value.
|
|
11
|
+
*/
|
|
12
|
+
value: T;
|
|
13
|
+
/**
|
|
14
|
+
* Create a resettable value.
|
|
15
|
+
*
|
|
16
|
+
* @param value Initial value to store and reset back to.
|
|
17
|
+
*/
|
|
18
|
+
constructor(value: T);
|
|
19
|
+
/**
|
|
20
|
+
* Set the current value.
|
|
21
|
+
*
|
|
22
|
+
* @param value New value to assign.
|
|
23
|
+
*/
|
|
24
|
+
set(value: T): void;
|
|
25
|
+
/**
|
|
26
|
+
* Restore the value back to its initial constructor value.
|
|
27
|
+
*/
|
|
28
|
+
reset(): void;
|
|
29
|
+
/**
|
|
30
|
+
* Return the current value for primitive coercion.
|
|
31
|
+
*
|
|
32
|
+
* @returns The current value.
|
|
33
|
+
*/
|
|
34
|
+
valueOf(): T;
|
|
35
|
+
/**
|
|
36
|
+
* Convert the current value to a string.
|
|
37
|
+
*
|
|
38
|
+
* @returns The string representation of the current value.
|
|
39
|
+
*/
|
|
40
|
+
toString(): string;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* A resettable boolean helper with convenience setters and state checks.
|
|
44
|
+
*/
|
|
45
|
+
declare class Flag extends ResettableValue<boolean> {
|
|
46
|
+
/**
|
|
47
|
+
* Create a new flag.
|
|
48
|
+
*
|
|
49
|
+
* @param value Initial flag value. Defaults to `false`.
|
|
50
|
+
*/
|
|
51
|
+
constructor(value?: boolean);
|
|
52
|
+
/**
|
|
53
|
+
* Whether the flag is currently `true`.
|
|
54
|
+
*/
|
|
55
|
+
get isTrue(): boolean;
|
|
56
|
+
/**
|
|
57
|
+
* Whether the flag is currently `false`.
|
|
58
|
+
*/
|
|
59
|
+
get isFalse(): boolean;
|
|
60
|
+
/**
|
|
61
|
+
* Set the flag value.
|
|
62
|
+
*
|
|
63
|
+
* @param value Value to assign.
|
|
64
|
+
*/
|
|
65
|
+
set(value: boolean): void;
|
|
66
|
+
/**
|
|
67
|
+
* Set the flag to `true`.
|
|
68
|
+
*/
|
|
69
|
+
setTrue(): void;
|
|
70
|
+
/**
|
|
71
|
+
* Set the flag to `false`.
|
|
72
|
+
*/
|
|
73
|
+
setFalse(): void;
|
|
74
|
+
/**
|
|
75
|
+
* Invert the current flag value.
|
|
76
|
+
*/
|
|
77
|
+
toggle(): void;
|
|
78
|
+
}
|
|
79
|
+
declare function resettableLazy<T>(factory: () => T): {
|
|
80
|
+
get: () => T;
|
|
81
|
+
reset: () => void;
|
|
82
|
+
};
|
|
83
|
+
declare function resettableLazyAsync<T>(factory: () => Promise<T>): {
|
|
84
|
+
get: () => Promise<T>;
|
|
85
|
+
reset: () => void;
|
|
86
|
+
};
|
|
87
|
+
//#endregion
|
|
88
|
+
export { Flag, ResettableValue, resettableLazy, resettableLazyAsync };
|
package/dist/state.d.mts
ADDED
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
//#region src/state.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* Holds a mutable value and remembers its initial value so it can be restored.
|
|
4
|
+
*
|
|
5
|
+
* @typeParam T Type of the held value.
|
|
6
|
+
*/
|
|
7
|
+
declare class ResettableValue<T> {
|
|
8
|
+
#private;
|
|
9
|
+
/**
|
|
10
|
+
* The current value.
|
|
11
|
+
*/
|
|
12
|
+
value: T;
|
|
13
|
+
/**
|
|
14
|
+
* Create a resettable value.
|
|
15
|
+
*
|
|
16
|
+
* @param value Initial value to store and reset back to.
|
|
17
|
+
*/
|
|
18
|
+
constructor(value: T);
|
|
19
|
+
/**
|
|
20
|
+
* Set the current value.
|
|
21
|
+
*
|
|
22
|
+
* @param value New value to assign.
|
|
23
|
+
*/
|
|
24
|
+
set(value: T): void;
|
|
25
|
+
/**
|
|
26
|
+
* Restore the value back to its initial constructor value.
|
|
27
|
+
*/
|
|
28
|
+
reset(): void;
|
|
29
|
+
/**
|
|
30
|
+
* Return the current value for primitive coercion.
|
|
31
|
+
*
|
|
32
|
+
* @returns The current value.
|
|
33
|
+
*/
|
|
34
|
+
valueOf(): T;
|
|
35
|
+
/**
|
|
36
|
+
* Convert the current value to a string.
|
|
37
|
+
*
|
|
38
|
+
* @returns The string representation of the current value.
|
|
39
|
+
*/
|
|
40
|
+
toString(): string;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* A resettable boolean helper with convenience setters and state checks.
|
|
44
|
+
*/
|
|
45
|
+
declare class Flag extends ResettableValue<boolean> {
|
|
46
|
+
/**
|
|
47
|
+
* Create a new flag.
|
|
48
|
+
*
|
|
49
|
+
* @param value Initial flag value. Defaults to `false`.
|
|
50
|
+
*/
|
|
51
|
+
constructor(value?: boolean);
|
|
52
|
+
/**
|
|
53
|
+
* Whether the flag is currently `true`.
|
|
54
|
+
*/
|
|
55
|
+
get isTrue(): boolean;
|
|
56
|
+
/**
|
|
57
|
+
* Whether the flag is currently `false`.
|
|
58
|
+
*/
|
|
59
|
+
get isFalse(): boolean;
|
|
60
|
+
/**
|
|
61
|
+
* Set the flag value.
|
|
62
|
+
*
|
|
63
|
+
* @param value Value to assign.
|
|
64
|
+
*/
|
|
65
|
+
set(value: boolean): void;
|
|
66
|
+
/**
|
|
67
|
+
* Set the flag to `true`.
|
|
68
|
+
*/
|
|
69
|
+
setTrue(): void;
|
|
70
|
+
/**
|
|
71
|
+
* Set the flag to `false`.
|
|
72
|
+
*/
|
|
73
|
+
setFalse(): void;
|
|
74
|
+
/**
|
|
75
|
+
* Invert the current flag value.
|
|
76
|
+
*/
|
|
77
|
+
toggle(): void;
|
|
78
|
+
}
|
|
79
|
+
declare function resettableLazy<T>(factory: () => T): {
|
|
80
|
+
get: () => T;
|
|
81
|
+
reset: () => void;
|
|
82
|
+
};
|
|
83
|
+
declare function resettableLazyAsync<T>(factory: () => Promise<T>): {
|
|
84
|
+
get: () => Promise<T>;
|
|
85
|
+
reset: () => void;
|
|
86
|
+
};
|
|
87
|
+
//#endregion
|
|
88
|
+
export { Flag, ResettableValue, resettableLazy, resettableLazyAsync };
|
package/dist/state.mjs
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
var e=class{value;#e;constructor(e){this.value=e,this.#e=e}set(e){this.value=e}reset(){this.value=this.#e}valueOf(){return this.value}toString(){return String(this.value)}},t=class extends e{constructor(e=!1){super(e)}get isTrue(){return this.value===!0}get isFalse(){return!this.isTrue}set(e){super.set(e)}setTrue(){this.value=!0}setFalse(){this.value=!1}toggle(){this.value=!this.value}};function n(e){let t,n=!1;function r(){return n||=(t=e(),!0),t}function i(){n=!1,t=void 0}return{get:r,reset:i}}function r(e){let t;function n(){return t||=e().catch(e=>{throw t=void 0,e}),t}function r(){t=void 0}return{get:n,reset:r}}export{t as Flag,e as ResettableValue,n as resettableLazy,r as resettableLazyAsync};
|
package/dist/timing.cjs
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});let e=function(e){return e[e.None=0]=`None`,e[e.Full=1]=`Full`,e[e.Equal=2]=`Equal`,e}({});function t(e){return new Promise(t=>setTimeout(t,e))}function n(e){return new Promise((t,n)=>setTimeout(n,e))}async function r(e,n=100,r=5e3){let i=Date.now();for(;!await e();){if(Date.now()-i>r)throw Error(`Timeout exceeded`);await t(n)}}async function i(e,t){let n;try{return await Promise.race([e,new Promise((e,r)=>{n=setTimeout(()=>r(Error(`Operation timed out`)),t)})])}finally{n!==void 0&&clearTimeout(n)}}function a(){let e=Error(`Aborted`);return e.name=`AbortError`,e}function o(e){if(e?.aborted)throw a()}async function s(e,t){if(e<=0){o(t);return}await new Promise((n,r)=>{let i=setTimeout(()=>{t&&t.removeEventListener(`abort`,o),n()},e);function o(){clearTimeout(i),t?.removeEventListener(`abort`,o),r(a())}t&&t.addEventListener(`abort`,o,{once:!0})})}function c(e){if(!Number.isFinite(e)||e<0)throw Error(`ms must be a finite number >= 0`);let t=new AbortController,n=setTimeout(()=>t.abort(),e);return t.signal.addEventListener(`abort`,()=>clearTimeout(n),{once:!0}),t.signal}function l(...e){let t=e.filter(e=>e!==void 0),n=new AbortController,r=new Map,i=()=>{if(!n.signal.aborted){n.abort();for(let[e,t]of r)e.removeEventListener(`abort`,t);r.clear()}};for(let e of t){if(e.aborted){i();break}let t=()=>i();r.set(e,t),e.addEventListener(`abort`,t,{once:!0})}return n.signal}async function u(e,t){return o(t),await new Promise((n,r)=>{function i(){t.removeEventListener(`abort`,i),r(a())}t.addEventListener(`abort`,i,{once:!0}),Promise.resolve(e).then(e=>{t.removeEventListener(`abort`,i),n(e)},e=>{t.removeEventListener(`abort`,i),r(e)})})}function d(t,n){return n===e.None?t:n===e.Full?Math.floor(Math.random()*t):Math.floor(t/2+t/2*Math.random())}async function f(t,n={}){let r=n.attempts??3,i=n.baseMs??100,a=n.maxMs??1/0,c=n.jitter??e.None;if(!Number.isInteger(r)||r<1)throw Error(`attempts must be an integer >= 1`);if(i<0||!Number.isFinite(i))throw Error(`baseMs must be a finite number >= 0`);if(a<0||Number.isNaN(a))throw Error(`maxMs must be a number >= 0`);for(let e=1;e<=r;e++){o(n.signal);try{return await t(e)}catch(t){if(e>=r||n.shouldRetry&&!await n.shouldRetry(t,e))throw t;await s(d(Math.min(i*2**(e-1),a),c),n.signal)}}throw Error(`Unreachable`)}exports.RetryJitter=e,exports.abortAfter=c,exports.pollUntil=r,exports.raceSignals=l,exports.rejectionTimeout=n,exports.retry=f,exports.timeout=t,exports.withAbort=u,exports.withTimeout=i;
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { Awaitable } from "./typing.cjs";
|
|
2
|
+
|
|
3
|
+
//#region src/timing.d.ts
|
|
4
|
+
interface IRetryOptions {
|
|
5
|
+
attempts?: number;
|
|
6
|
+
baseMs?: number;
|
|
7
|
+
maxMs?: number;
|
|
8
|
+
jitter?: RetryJitter;
|
|
9
|
+
signal?: AbortSignal;
|
|
10
|
+
shouldRetry?: (error: unknown, attempt: number) => Awaitable<boolean>;
|
|
11
|
+
}
|
|
12
|
+
declare const enum RetryJitter {
|
|
13
|
+
None = 0,
|
|
14
|
+
Full = 1,
|
|
15
|
+
Equal = 2
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Returns a promise after the provided {@link ms} has passed
|
|
19
|
+
* @param ms The number of milliseconds to wait
|
|
20
|
+
*/
|
|
21
|
+
declare function timeout(ms: number): Promise<unknown>;
|
|
22
|
+
/**
|
|
23
|
+
* Rejects a promise after the provided {@link ms} has passed
|
|
24
|
+
* @param ms The number of milliseconds to wait
|
|
25
|
+
*/
|
|
26
|
+
declare function rejectionTimeout(ms: number): Promise<unknown>;
|
|
27
|
+
/**
|
|
28
|
+
* Polls until the provided condition is met, or the timeout is exceeded.
|
|
29
|
+
*
|
|
30
|
+
* @param condition A function that returns a boolean or a promise that resolves to a boolean
|
|
31
|
+
* @param interval The interval in milliseconds to wait between checks
|
|
32
|
+
* @param timeoutMs The maximum time in milliseconds to wait before throwing an error
|
|
33
|
+
*/
|
|
34
|
+
declare function pollUntil(condition: () => Awaitable<boolean>, interval?: number, timeoutMs?: number): Promise<void>;
|
|
35
|
+
/**
|
|
36
|
+
* Wraps a promise with a timeout. If the promise does not resolve within the specified time, an error is thrown.
|
|
37
|
+
*
|
|
38
|
+
* @param promise The promise to wrap with a timeout
|
|
39
|
+
* @param ms The number of milliseconds to wait before timing out
|
|
40
|
+
*
|
|
41
|
+
* @returns The result of the promise if it resolves before the timeout, otherwise throws an error
|
|
42
|
+
*/
|
|
43
|
+
declare function withTimeout<T>(promise: Promise<T>, ms: number): Promise<T>;
|
|
44
|
+
/**
|
|
45
|
+
* Returns an AbortSignal that aborts automatically after the given number of milliseconds.
|
|
46
|
+
*
|
|
47
|
+
* @param ms Delay before automatic abort.
|
|
48
|
+
*/
|
|
49
|
+
declare function abortAfter(ms: number): AbortSignal;
|
|
50
|
+
/**
|
|
51
|
+
* Returns a signal that aborts when any of the input signals aborts.
|
|
52
|
+
*
|
|
53
|
+
* @param signals Input abort signals.
|
|
54
|
+
*/
|
|
55
|
+
declare function raceSignals(...signals: Array<AbortSignal | undefined>): AbortSignal;
|
|
56
|
+
/**
|
|
57
|
+
* Wraps a promise and rejects when the signal aborts before completion.
|
|
58
|
+
*
|
|
59
|
+
* @param promise Promise or value to await.
|
|
60
|
+
* @param signal Abort signal to monitor.
|
|
61
|
+
*/
|
|
62
|
+
declare function withAbort<T>(promise: Awaitable<T>, signal: AbortSignal): Promise<T>;
|
|
63
|
+
/**
|
|
64
|
+
* Retries an operation with exponential backoff.
|
|
65
|
+
*
|
|
66
|
+
* @param fn Operation to run for each attempt.
|
|
67
|
+
* @param options Retry options controlling attempts, backoff, jitter, and cancellation.
|
|
68
|
+
*/
|
|
69
|
+
declare function retry<T>(fn: (attempt: number) => Awaitable<T>, options?: IRetryOptions): Promise<T>;
|
|
70
|
+
//#endregion
|
|
71
|
+
export { IRetryOptions, RetryJitter, abortAfter, pollUntil, raceSignals, rejectionTimeout, retry, timeout, withAbort, withTimeout };
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { Awaitable } from "./typing.mjs";
|
|
2
|
+
|
|
3
|
+
//#region src/timing.d.ts
|
|
4
|
+
interface IRetryOptions {
|
|
5
|
+
attempts?: number;
|
|
6
|
+
baseMs?: number;
|
|
7
|
+
maxMs?: number;
|
|
8
|
+
jitter?: RetryJitter;
|
|
9
|
+
signal?: AbortSignal;
|
|
10
|
+
shouldRetry?: (error: unknown, attempt: number) => Awaitable<boolean>;
|
|
11
|
+
}
|
|
12
|
+
declare const enum RetryJitter {
|
|
13
|
+
None = 0,
|
|
14
|
+
Full = 1,
|
|
15
|
+
Equal = 2
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Returns a promise after the provided {@link ms} has passed
|
|
19
|
+
* @param ms The number of milliseconds to wait
|
|
20
|
+
*/
|
|
21
|
+
declare function timeout(ms: number): Promise<unknown>;
|
|
22
|
+
/**
|
|
23
|
+
* Rejects a promise after the provided {@link ms} has passed
|
|
24
|
+
* @param ms The number of milliseconds to wait
|
|
25
|
+
*/
|
|
26
|
+
declare function rejectionTimeout(ms: number): Promise<unknown>;
|
|
27
|
+
/**
|
|
28
|
+
* Polls until the provided condition is met, or the timeout is exceeded.
|
|
29
|
+
*
|
|
30
|
+
* @param condition A function that returns a boolean or a promise that resolves to a boolean
|
|
31
|
+
* @param interval The interval in milliseconds to wait between checks
|
|
32
|
+
* @param timeoutMs The maximum time in milliseconds to wait before throwing an error
|
|
33
|
+
*/
|
|
34
|
+
declare function pollUntil(condition: () => Awaitable<boolean>, interval?: number, timeoutMs?: number): Promise<void>;
|
|
35
|
+
/**
|
|
36
|
+
* Wraps a promise with a timeout. If the promise does not resolve within the specified time, an error is thrown.
|
|
37
|
+
*
|
|
38
|
+
* @param promise The promise to wrap with a timeout
|
|
39
|
+
* @param ms The number of milliseconds to wait before timing out
|
|
40
|
+
*
|
|
41
|
+
* @returns The result of the promise if it resolves before the timeout, otherwise throws an error
|
|
42
|
+
*/
|
|
43
|
+
declare function withTimeout<T>(promise: Promise<T>, ms: number): Promise<T>;
|
|
44
|
+
/**
|
|
45
|
+
* Returns an AbortSignal that aborts automatically after the given number of milliseconds.
|
|
46
|
+
*
|
|
47
|
+
* @param ms Delay before automatic abort.
|
|
48
|
+
*/
|
|
49
|
+
declare function abortAfter(ms: number): AbortSignal;
|
|
50
|
+
/**
|
|
51
|
+
* Returns a signal that aborts when any of the input signals aborts.
|
|
52
|
+
*
|
|
53
|
+
* @param signals Input abort signals.
|
|
54
|
+
*/
|
|
55
|
+
declare function raceSignals(...signals: Array<AbortSignal | undefined>): AbortSignal;
|
|
56
|
+
/**
|
|
57
|
+
* Wraps a promise and rejects when the signal aborts before completion.
|
|
58
|
+
*
|
|
59
|
+
* @param promise Promise or value to await.
|
|
60
|
+
* @param signal Abort signal to monitor.
|
|
61
|
+
*/
|
|
62
|
+
declare function withAbort<T>(promise: Awaitable<T>, signal: AbortSignal): Promise<T>;
|
|
63
|
+
/**
|
|
64
|
+
* Retries an operation with exponential backoff.
|
|
65
|
+
*
|
|
66
|
+
* @param fn Operation to run for each attempt.
|
|
67
|
+
* @param options Retry options controlling attempts, backoff, jitter, and cancellation.
|
|
68
|
+
*/
|
|
69
|
+
declare function retry<T>(fn: (attempt: number) => Awaitable<T>, options?: IRetryOptions): Promise<T>;
|
|
70
|
+
//#endregion
|
|
71
|
+
export { IRetryOptions, RetryJitter, abortAfter, pollUntil, raceSignals, rejectionTimeout, retry, timeout, withAbort, withTimeout };
|
package/dist/timing.mjs
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
let e=function(e){return e[e.None=0]=`None`,e[e.Full=1]=`Full`,e[e.Equal=2]=`Equal`,e}({});function t(e){return new Promise(t=>setTimeout(t,e))}function n(e){return new Promise((t,n)=>setTimeout(n,e))}async function r(e,n=100,r=5e3){let i=Date.now();for(;!await e();){if(Date.now()-i>r)throw Error(`Timeout exceeded`);await t(n)}}async function i(e,t){let n;try{return await Promise.race([e,new Promise((e,r)=>{n=setTimeout(()=>r(Error(`Operation timed out`)),t)})])}finally{n!==void 0&&clearTimeout(n)}}function a(){let e=Error(`Aborted`);return e.name=`AbortError`,e}function o(e){if(e?.aborted)throw a()}async function s(e,t){if(e<=0){o(t);return}await new Promise((n,r)=>{let i=setTimeout(()=>{t&&t.removeEventListener(`abort`,o),n()},e);function o(){clearTimeout(i),t?.removeEventListener(`abort`,o),r(a())}t&&t.addEventListener(`abort`,o,{once:!0})})}function c(e){if(!Number.isFinite(e)||e<0)throw Error(`ms must be a finite number >= 0`);let t=new AbortController,n=setTimeout(()=>t.abort(),e);return t.signal.addEventListener(`abort`,()=>clearTimeout(n),{once:!0}),t.signal}function l(...e){let t=e.filter(e=>e!==void 0),n=new AbortController,r=new Map,i=()=>{if(!n.signal.aborted){n.abort();for(let[e,t]of r)e.removeEventListener(`abort`,t);r.clear()}};for(let e of t){if(e.aborted){i();break}let t=()=>i();r.set(e,t),e.addEventListener(`abort`,t,{once:!0})}return n.signal}async function u(e,t){return o(t),await new Promise((n,r)=>{function i(){t.removeEventListener(`abort`,i),r(a())}t.addEventListener(`abort`,i,{once:!0}),Promise.resolve(e).then(e=>{t.removeEventListener(`abort`,i),n(e)},e=>{t.removeEventListener(`abort`,i),r(e)})})}function d(t,n){return n===e.None?t:n===e.Full?Math.floor(Math.random()*t):Math.floor(t/2+t/2*Math.random())}async function f(t,n={}){let r=n.attempts??3,i=n.baseMs??100,a=n.maxMs??1/0,c=n.jitter??e.None;if(!Number.isInteger(r)||r<1)throw Error(`attempts must be an integer >= 1`);if(i<0||!Number.isFinite(i))throw Error(`baseMs must be a finite number >= 0`);if(a<0||Number.isNaN(a))throw Error(`maxMs must be a number >= 0`);for(let e=1;e<=r;e++){o(n.signal);try{return await t(e)}catch(t){if(e>=r||n.shouldRetry&&!await n.shouldRetry(t,e))throw t;await s(d(Math.min(i*2**(e-1),a),c),n.signal)}}throw Error(`Unreachable`)}export{e as RetryJitter,c as abortAfter,r as pollUntil,l as raceSignals,n as rejectionTimeout,f as retry,t as timeout,u as withAbort,i as withTimeout};
|
package/dist/typing.cjs
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=e=>e;function t(e){}function n(e){return Object.entries(e)}function r(e){return{ok:!0,value:e}}function i(e){return{ok:!1,error:e}}function a(e){return e.ok}function o(e,t){return e.ok?r(t(e.value)):e}function s(e,t){return e.ok?e:i(t(e.error))}async function c(e,t){try{return r(await e())}catch(e){return i(t?t(e):e)}}exports.assume=t,exports.cast=e,exports.err=i,exports.isOk=a,exports.mapErr=s,exports.mapOk=o,exports.ok=r,exports.tryCatchAsync=c,exports.typedEntries=n;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
//#region src/typing.d.ts
|
|
2
|
+
type Awaitable<T> = PromiseLike<T> | T;
|
|
3
|
+
type Maybe<T> = T | undefined;
|
|
4
|
+
type Nullable<T> = T | null;
|
|
5
|
+
type Result<T, E = unknown> = {
|
|
6
|
+
ok: true;
|
|
7
|
+
value: T;
|
|
8
|
+
} | {
|
|
9
|
+
ok: false;
|
|
10
|
+
error: E;
|
|
11
|
+
};
|
|
12
|
+
declare const cast: <T, U extends T>(value: U) => U;
|
|
13
|
+
declare function assume<T>(value: unknown): asserts value is T;
|
|
14
|
+
declare function typedEntries<T extends object>(obj: T): { [K in keyof T]: [K, T[K]] }[keyof T][];
|
|
15
|
+
declare function ok<T>(value: T): Result<T, never>;
|
|
16
|
+
declare function err<E>(error: E): Result<never, E>;
|
|
17
|
+
declare function isOk<T, E>(result: Result<T, E>): result is {
|
|
18
|
+
ok: true;
|
|
19
|
+
value: T;
|
|
20
|
+
};
|
|
21
|
+
declare function mapOk<T, U, E>(result: Result<T, E>, mapper: (value: T) => U): Result<U, E>;
|
|
22
|
+
declare function mapErr<T, E, F>(result: Result<T, E>, mapper: (error: E) => F): Result<T, F>;
|
|
23
|
+
declare function tryCatchAsync<T>(operation: () => Awaitable<T>): Promise<Result<T, unknown>>;
|
|
24
|
+
declare function tryCatchAsync<T, E>(operation: () => Awaitable<T>, mapError: (error: unknown) => E): Promise<Result<T, E>>;
|
|
25
|
+
//#endregion
|
|
26
|
+
export { Awaitable, Maybe, Nullable, Result, assume, cast, err, isOk, mapErr, mapOk, ok, tryCatchAsync, typedEntries };
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
//#region src/typing.d.ts
|
|
2
|
+
type Awaitable<T> = PromiseLike<T> | T;
|
|
3
|
+
type Maybe<T> = T | undefined;
|
|
4
|
+
type Nullable<T> = T | null;
|
|
5
|
+
type Result<T, E = unknown> = {
|
|
6
|
+
ok: true;
|
|
7
|
+
value: T;
|
|
8
|
+
} | {
|
|
9
|
+
ok: false;
|
|
10
|
+
error: E;
|
|
11
|
+
};
|
|
12
|
+
declare const cast: <T, U extends T>(value: U) => U;
|
|
13
|
+
declare function assume<T>(value: unknown): asserts value is T;
|
|
14
|
+
declare function typedEntries<T extends object>(obj: T): { [K in keyof T]: [K, T[K]] }[keyof T][];
|
|
15
|
+
declare function ok<T>(value: T): Result<T, never>;
|
|
16
|
+
declare function err<E>(error: E): Result<never, E>;
|
|
17
|
+
declare function isOk<T, E>(result: Result<T, E>): result is {
|
|
18
|
+
ok: true;
|
|
19
|
+
value: T;
|
|
20
|
+
};
|
|
21
|
+
declare function mapOk<T, U, E>(result: Result<T, E>, mapper: (value: T) => U): Result<U, E>;
|
|
22
|
+
declare function mapErr<T, E, F>(result: Result<T, E>, mapper: (error: E) => F): Result<T, F>;
|
|
23
|
+
declare function tryCatchAsync<T>(operation: () => Awaitable<T>): Promise<Result<T, unknown>>;
|
|
24
|
+
declare function tryCatchAsync<T, E>(operation: () => Awaitable<T>, mapError: (error: unknown) => E): Promise<Result<T, E>>;
|
|
25
|
+
//#endregion
|
|
26
|
+
export { Awaitable, Maybe, Nullable, Result, assume, cast, err, isOk, mapErr, mapOk, ok, tryCatchAsync, typedEntries };
|
package/dist/typing.mjs
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
const e=e=>e;function t(e){}function n(e){return Object.entries(e)}function r(e){return{ok:!0,value:e}}function i(e){return{ok:!1,error:e}}function a(e){return e.ok}function o(e,t){return e.ok?r(t(e.value)):e}function s(e,t){return e.ok?e:i(t(e.error))}async function c(e,t){try{return r(await e())}catch(e){return i(t?t(e):e)}}export{t as assume,e as cast,i as err,a as isOk,s as mapErr,o as mapOk,r as ok,c as tryCatchAsync,n as typedEntries};
|
package/dist/url.cjs
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});function e(e,...t){let n=``;for(let r=0;r<e.length;r++)n+=e[r],r<t.length&&(n+=encodeURIComponent(String(t[r])));return n}function t(e,n,r){if(r!=null){if(Array.isArray(r)){for(let i of r)t(e,n,i);return}if(typeof r==`object`){try{e.append(n,JSON.stringify(r))}catch{e.append(n,String(r))}return}e.append(n,String(r))}}var n=class e{#e;constructor(t,n){t instanceof e||t instanceof URL?this.#e=new URL(t.toString()):n?this.#e=new URL(t,n.toString()):this.#e=new URL(t)}get protocol(){return this.#e.protocol}get host(){return this.#e.host}get hostname(){return this.#e.hostname}get port(){return this.#e.port}get origin(){return this.#e.origin}get username(){return this.#e.username}get password(){return this.#e.password}get hash(){return this.#e.hash}get search(){return this.#e.search}get searchParams(){return new URLSearchParams(this.#e.search)}get pathname(){return this.#e.pathname}get parts(){return this.#e.pathname.split(`/`).filter(Boolean).map(decodeURIComponent)}get name(){return this.parts.at(-1)??``}get suffix(){let e=this.name,t=e.lastIndexOf(`.`);return t>=0?e.slice(t):``}get stem(){let e=this.name,t=e.lastIndexOf(`.`);return t>=0?e.slice(0,t):e}get parent(){let e=this.parts.slice(0,-1);return this.withPath(e)}joinpath(...e){let t=[...this.parts,...e.map(e=>e.replace(/^\/+|\/+$/g,``))];return this.withPath(t)}div(...e){return this.joinpath(...e)}withPath(t){let n=new URL(this.#e.toString());return n.pathname=`/`+t.map(encodeURIComponent).join(`/`),new e(n)}withQuery(n){let r=new URL(this.#e.toString());for(let[e,i]of Object.entries(n))r.searchParams.delete(e),t(r.searchParams,e,i);return new e(r)}withQueryPatch(e){return this.withQuery(e)}appendQuery(n){let r=new URL(this.#e.toString());for(let[e,i]of Object.entries(n))t(r.searchParams,e,i);return new e(r)}withoutEmptyQuery(){let t=new URL(this.#e.toString()),n=new Set;for(let e of t.searchParams.keys())n.has(e)||(n.add(e),t.searchParams.getAll(e).every(e=>e===``)&&t.searchParams.delete(e));return new e(t)}withoutQuery(...t){let n=new URL(this.#e.toString());for(let e of t)n.searchParams.delete(e);return new e(n)}withHash(t){let n=new URL(this.#e.toString());return n.hash=t.startsWith(`#`)?t:`#${t}`,new e(n)}withoutHash(){let t=new URL(this.#e.toString());return t.hash=``,new e(t)}async fetch(e){return fetch(this.#e,e)}resolve(t){return new e(t,this)}equals(t){return this.toString()===new e(t).toString()}toURL(){return new URL(this.#e.toString())}toString(){return this.#e.toString()}valueOf(){return this.toString()}[Symbol.toPrimitive](){return this.toString()}static from(t,n){return new e(t,n)}static parse(t){return new e(t)}};exports.URLPath=n,exports.url=e;
|
|
@@ -1,7 +1,14 @@
|
|
|
1
|
-
//#region src/
|
|
1
|
+
//#region src/url.d.ts
|
|
2
2
|
type URLLike = string | URL | URLPath;
|
|
3
3
|
type QueryValue = string | number | undefined | null | boolean | Array<QueryValue> | Record<string, any>;
|
|
4
4
|
type QueryObject = Record<string, QueryValue | QueryValue[]>;
|
|
5
|
+
/**
|
|
6
|
+
* Tagged-template helper for encoded URL path segments.
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* const path = url`/users/${userId}/posts/${postId}`;
|
|
10
|
+
*/
|
|
11
|
+
declare function url(strings: TemplateStringsArray, ...values: unknown[]): string;
|
|
5
12
|
declare class URLPath {
|
|
6
13
|
#private;
|
|
7
14
|
constructor(input: URLLike, base?: URLLike);
|
|
@@ -25,6 +32,9 @@ declare class URLPath {
|
|
|
25
32
|
div(...segments: string[]): URLPath;
|
|
26
33
|
private withPath;
|
|
27
34
|
withQuery(params: QueryObject): URLPath;
|
|
35
|
+
withQueryPatch(params: QueryObject): URLPath;
|
|
36
|
+
appendQuery(params: QueryObject): URLPath;
|
|
37
|
+
withoutEmptyQuery(): URLPath;
|
|
28
38
|
withoutQuery(...keys: string[]): URLPath;
|
|
29
39
|
withHash(hash: string): URLPath;
|
|
30
40
|
withoutHash(): URLPath;
|
|
@@ -39,4 +49,4 @@ declare class URLPath {
|
|
|
39
49
|
static parse(input: string): URLPath;
|
|
40
50
|
}
|
|
41
51
|
//#endregion
|
|
42
|
-
export { QueryObject, QueryValue, URLLike, URLPath };
|
|
52
|
+
export { QueryObject, QueryValue, URLLike, URLPath, url };
|
|
@@ -1,7 +1,14 @@
|
|
|
1
|
-
//#region src/
|
|
1
|
+
//#region src/url.d.ts
|
|
2
2
|
type URLLike = string | URL | URLPath;
|
|
3
3
|
type QueryValue = string | number | undefined | null | boolean | Array<QueryValue> | Record<string, any>;
|
|
4
4
|
type QueryObject = Record<string, QueryValue | QueryValue[]>;
|
|
5
|
+
/**
|
|
6
|
+
* Tagged-template helper for encoded URL path segments.
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* const path = url`/users/${userId}/posts/${postId}`;
|
|
10
|
+
*/
|
|
11
|
+
declare function url(strings: TemplateStringsArray, ...values: unknown[]): string;
|
|
5
12
|
declare class URLPath {
|
|
6
13
|
#private;
|
|
7
14
|
constructor(input: URLLike, base?: URLLike);
|
|
@@ -25,6 +32,9 @@ declare class URLPath {
|
|
|
25
32
|
div(...segments: string[]): URLPath;
|
|
26
33
|
private withPath;
|
|
27
34
|
withQuery(params: QueryObject): URLPath;
|
|
35
|
+
withQueryPatch(params: QueryObject): URLPath;
|
|
36
|
+
appendQuery(params: QueryObject): URLPath;
|
|
37
|
+
withoutEmptyQuery(): URLPath;
|
|
28
38
|
withoutQuery(...keys: string[]): URLPath;
|
|
29
39
|
withHash(hash: string): URLPath;
|
|
30
40
|
withoutHash(): URLPath;
|
|
@@ -39,4 +49,4 @@ declare class URLPath {
|
|
|
39
49
|
static parse(input: string): URLPath;
|
|
40
50
|
}
|
|
41
51
|
//#endregion
|
|
42
|
-
export { QueryObject, QueryValue, URLLike, URLPath };
|
|
52
|
+
export { QueryObject, QueryValue, URLLike, URLPath, url };
|
package/dist/url.mjs
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
function e(e,...t){let n=``;for(let r=0;r<e.length;r++)n+=e[r],r<t.length&&(n+=encodeURIComponent(String(t[r])));return n}function t(e,n,r){if(r!=null){if(Array.isArray(r)){for(let i of r)t(e,n,i);return}if(typeof r==`object`){try{e.append(n,JSON.stringify(r))}catch{e.append(n,String(r))}return}e.append(n,String(r))}}var n=class e{#e;constructor(t,n){t instanceof e||t instanceof URL?this.#e=new URL(t.toString()):n?this.#e=new URL(t,n.toString()):this.#e=new URL(t)}get protocol(){return this.#e.protocol}get host(){return this.#e.host}get hostname(){return this.#e.hostname}get port(){return this.#e.port}get origin(){return this.#e.origin}get username(){return this.#e.username}get password(){return this.#e.password}get hash(){return this.#e.hash}get search(){return this.#e.search}get searchParams(){return new URLSearchParams(this.#e.search)}get pathname(){return this.#e.pathname}get parts(){return this.#e.pathname.split(`/`).filter(Boolean).map(decodeURIComponent)}get name(){return this.parts.at(-1)??``}get suffix(){let e=this.name,t=e.lastIndexOf(`.`);return t>=0?e.slice(t):``}get stem(){let e=this.name,t=e.lastIndexOf(`.`);return t>=0?e.slice(0,t):e}get parent(){let e=this.parts.slice(0,-1);return this.withPath(e)}joinpath(...e){let t=[...this.parts,...e.map(e=>e.replace(/^\/+|\/+$/g,``))];return this.withPath(t)}div(...e){return this.joinpath(...e)}withPath(t){let n=new URL(this.#e.toString());return n.pathname=`/`+t.map(encodeURIComponent).join(`/`),new e(n)}withQuery(n){let r=new URL(this.#e.toString());for(let[e,i]of Object.entries(n))r.searchParams.delete(e),t(r.searchParams,e,i);return new e(r)}withQueryPatch(e){return this.withQuery(e)}appendQuery(n){let r=new URL(this.#e.toString());for(let[e,i]of Object.entries(n))t(r.searchParams,e,i);return new e(r)}withoutEmptyQuery(){let t=new URL(this.#e.toString()),n=new Set;for(let e of t.searchParams.keys())n.has(e)||(n.add(e),t.searchParams.getAll(e).every(e=>e===``)&&t.searchParams.delete(e));return new e(t)}withoutQuery(...t){let n=new URL(this.#e.toString());for(let e of t)n.searchParams.delete(e);return new e(n)}withHash(t){let n=new URL(this.#e.toString());return n.hash=t.startsWith(`#`)?t:`#${t}`,new e(n)}withoutHash(){let t=new URL(this.#e.toString());return t.hash=``,new e(t)}async fetch(e){return fetch(this.#e,e)}resolve(t){return new e(t,this)}equals(t){return this.toString()===new e(t).toString()}toURL(){return new URL(this.#e.toString())}toString(){return this.#e.toString()}valueOf(){return this.toString()}[Symbol.toPrimitive](){return this.toString()}static from(t,n){return new e(t,n)}static parse(t){return new e(t)}};export{n as URLPath,e as url};
|