es-toolkit 1.47.1 → 1.48.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/CHANGELOG.md +15 -0
- package/dist/browser.global.js +3 -3
- package/dist/compat/array/difference.js +1 -2
- package/dist/compat/array/difference.mjs +1 -2
- package/dist/compat/array/sortedIndex.js +1 -1
- package/dist/compat/array/sortedIndex.mjs +1 -1
- package/dist/compat/compat.js +1 -1
- package/dist/compat/compat.mjs +1 -1
- package/dist/compat/index.js +1 -1
- package/dist/compat/index.mjs +1 -1
- package/dist/compat/math/parseInt.js +2 -1
- package/dist/compat/math/parseInt.mjs +2 -1
- package/dist/compat/math/random.d.mts +3 -3
- package/dist/compat/math/random.d.ts +3 -3
- package/dist/compat/object/pick.js +6 -5
- package/dist/compat/object/pick.mjs +6 -5
- package/dist/compat/predicate/isMatchWith.js +9 -6
- package/dist/compat/predicate/isMatchWith.mjs +9 -6
- package/dist/compat/predicate/isNaN.js +2 -1
- package/dist/compat/predicate/isNaN.mjs +2 -1
- package/dist/compat/predicate/isNumber.js +4 -1
- package/dist/compat/predicate/isNumber.mjs +4 -1
- package/dist/compat/util/toPath.js +3 -4
- package/dist/compat/util/toPath.mjs +3 -4
- package/dist/function/debounce.d.mts +1 -0
- package/dist/function/debounce.d.ts +1 -0
- package/dist/function/debounce.js +1 -0
- package/dist/function/debounce.mjs +1 -0
- package/dist/object/toMerged.js +2 -1
- package/dist/object/toMerged.mjs +2 -1
- package/dist/promise/timeout.d.mts +25 -2
- package/dist/promise/timeout.d.ts +25 -2
- package/dist/promise/timeout.js +31 -5
- package/dist/promise/timeout.mjs +31 -5
- package/dist/promise/withTimeout.d.mts +19 -1
- package/dist/promise/withTimeout.d.ts +19 -1
- package/dist/promise/withTimeout.js +15 -2
- package/dist/promise/withTimeout.mjs +15 -2
- package/package.json +4 -3
|
@@ -24,14 +24,15 @@ const require_set = require("./set.js");
|
|
|
24
24
|
* // each path can be passed individually as an argument
|
|
25
25
|
* const obj = { a: 1, b: 2, c: 3 };
|
|
26
26
|
* const result = pick(obj, 'a', 'c');
|
|
27
|
+
* // result will be { a: 1, c: 3 }
|
|
27
28
|
*
|
|
28
29
|
* // pick a key over a path
|
|
29
30
|
* const obj = { 'a.b': 1, a: { b: 2 } };
|
|
30
31
|
* const result = pick(obj, 'a.b');
|
|
31
32
|
* // result will be { 'a.b': 1 }
|
|
32
33
|
*/
|
|
33
|
-
function pick(
|
|
34
|
-
if (require_isNil.isNil(
|
|
34
|
+
function pick(object, ...keysArr) {
|
|
35
|
+
if (require_isNil.isNil(object)) return {};
|
|
35
36
|
const result = {};
|
|
36
37
|
for (let i = 0; i < keysArr.length; i++) {
|
|
37
38
|
let keys = keysArr[i];
|
|
@@ -47,9 +48,9 @@ function pick(obj, ...keysArr) {
|
|
|
47
48
|
break;
|
|
48
49
|
}
|
|
49
50
|
for (const key of keys) {
|
|
50
|
-
const value = require_get.get(
|
|
51
|
-
if (value === void 0 && !require_has.has(
|
|
52
|
-
if (typeof key === "string" && Object.hasOwn(
|
|
51
|
+
const value = require_get.get(object, key);
|
|
52
|
+
if (value === void 0 && !require_has.has(object, key)) continue;
|
|
53
|
+
if (typeof key === "string" && Object.hasOwn(object, key)) result[key] = value;
|
|
53
54
|
else require_set.set(result, key, value);
|
|
54
55
|
}
|
|
55
56
|
}
|
|
@@ -24,14 +24,15 @@ import { set } from "./set.mjs";
|
|
|
24
24
|
* // each path can be passed individually as an argument
|
|
25
25
|
* const obj = { a: 1, b: 2, c: 3 };
|
|
26
26
|
* const result = pick(obj, 'a', 'c');
|
|
27
|
+
* // result will be { a: 1, c: 3 }
|
|
27
28
|
*
|
|
28
29
|
* // pick a key over a path
|
|
29
30
|
* const obj = { 'a.b': 1, a: { b: 2 } };
|
|
30
31
|
* const result = pick(obj, 'a.b');
|
|
31
32
|
* // result will be { 'a.b': 1 }
|
|
32
33
|
*/
|
|
33
|
-
function pick(
|
|
34
|
-
if (isNil(
|
|
34
|
+
function pick(object, ...keysArr) {
|
|
35
|
+
if (isNil(object)) return {};
|
|
35
36
|
const result = {};
|
|
36
37
|
for (let i = 0; i < keysArr.length; i++) {
|
|
37
38
|
let keys = keysArr[i];
|
|
@@ -47,9 +48,9 @@ function pick(obj, ...keysArr) {
|
|
|
47
48
|
break;
|
|
48
49
|
}
|
|
49
50
|
for (const key of keys) {
|
|
50
|
-
const value = get(
|
|
51
|
-
if (value === void 0 && !has(
|
|
52
|
-
if (typeof key === "string" && Object.hasOwn(
|
|
51
|
+
const value = get(object, key);
|
|
52
|
+
if (value === void 0 && !has(object, key)) continue;
|
|
53
|
+
if (typeof key === "string" && Object.hasOwn(object, key)) result[key] = value;
|
|
53
54
|
else set(result, key, value);
|
|
54
55
|
}
|
|
55
56
|
}
|
|
@@ -77,20 +77,23 @@ function isMatchWith(target, source, compare) {
|
|
|
77
77
|
return isMatchWithInternal(target, source, function doesMatch(objValue, srcValue, key, object, source, stack) {
|
|
78
78
|
const isEqual = compare(objValue, srcValue, key, object, source, stack);
|
|
79
79
|
if (isEqual !== void 0) return Boolean(isEqual);
|
|
80
|
-
return isMatchWithInternal(objValue, srcValue, doesMatch, stack);
|
|
81
|
-
}, /* @__PURE__ */ new Map());
|
|
80
|
+
return isMatchWithInternal(objValue, srcValue, doesMatch, stack, false);
|
|
81
|
+
}, /* @__PURE__ */ new Map(), true);
|
|
82
82
|
}
|
|
83
|
-
function isMatchWithInternal(target, source, compare, stack) {
|
|
83
|
+
function isMatchWithInternal(target, source, compare, stack, isRoot = false) {
|
|
84
84
|
if (source === target) return true;
|
|
85
85
|
switch (typeof source) {
|
|
86
86
|
case "object": return isObjectMatch(target, source, compare, stack);
|
|
87
87
|
case "function":
|
|
88
|
-
if (Object.keys(source).length > 0) return isMatchWithInternal(target, { ...source }, compare, stack);
|
|
88
|
+
if (Object.keys(source).length > 0) return isMatchWithInternal(target, { ...source }, compare, stack, isRoot);
|
|
89
89
|
return require_isEqualsSameValueZero.isEqualsSameValueZero(target, source);
|
|
90
90
|
default:
|
|
91
91
|
if (!require_isObject.isObject(target)) return require_isEqualsSameValueZero.isEqualsSameValueZero(target, source);
|
|
92
|
-
if (
|
|
93
|
-
|
|
92
|
+
if (isRoot) {
|
|
93
|
+
if (typeof source === "string") return source === "";
|
|
94
|
+
return true;
|
|
95
|
+
}
|
|
96
|
+
return require_isEqualsSameValueZero.isEqualsSameValueZero(target, source);
|
|
94
97
|
}
|
|
95
98
|
}
|
|
96
99
|
function isObjectMatch(target, source, compare, stack) {
|
|
@@ -77,20 +77,23 @@ function isMatchWith(target, source, compare) {
|
|
|
77
77
|
return isMatchWithInternal(target, source, function doesMatch(objValue, srcValue, key, object, source, stack) {
|
|
78
78
|
const isEqual = compare(objValue, srcValue, key, object, source, stack);
|
|
79
79
|
if (isEqual !== void 0) return Boolean(isEqual);
|
|
80
|
-
return isMatchWithInternal(objValue, srcValue, doesMatch, stack);
|
|
81
|
-
}, /* @__PURE__ */ new Map());
|
|
80
|
+
return isMatchWithInternal(objValue, srcValue, doesMatch, stack, false);
|
|
81
|
+
}, /* @__PURE__ */ new Map(), true);
|
|
82
82
|
}
|
|
83
|
-
function isMatchWithInternal(target, source, compare, stack) {
|
|
83
|
+
function isMatchWithInternal(target, source, compare, stack, isRoot = false) {
|
|
84
84
|
if (source === target) return true;
|
|
85
85
|
switch (typeof source) {
|
|
86
86
|
case "object": return isObjectMatch(target, source, compare, stack);
|
|
87
87
|
case "function":
|
|
88
|
-
if (Object.keys(source).length > 0) return isMatchWithInternal(target, { ...source }, compare, stack);
|
|
88
|
+
if (Object.keys(source).length > 0) return isMatchWithInternal(target, { ...source }, compare, stack, isRoot);
|
|
89
89
|
return isEqualsSameValueZero(target, source);
|
|
90
90
|
default:
|
|
91
91
|
if (!isObject(target)) return isEqualsSameValueZero(target, source);
|
|
92
|
-
if (
|
|
93
|
-
|
|
92
|
+
if (isRoot) {
|
|
93
|
+
if (typeof source === "string") return source === "";
|
|
94
|
+
return true;
|
|
95
|
+
}
|
|
96
|
+
return isEqualsSameValueZero(target, source);
|
|
94
97
|
}
|
|
95
98
|
}
|
|
96
99
|
function isObjectMatch(target, source, compare, stack) {
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
const require_isNumber = require("./isNumber.js");
|
|
1
2
|
//#region src/compat/predicate/isNaN.ts
|
|
2
3
|
/**
|
|
3
4
|
* Checks if the value is NaN.
|
|
@@ -12,7 +13,7 @@
|
|
|
12
13
|
* isNaN(undefined); // false
|
|
13
14
|
*/
|
|
14
15
|
function isNaN(value) {
|
|
15
|
-
return Number.isNaN(value);
|
|
16
|
+
return require_isNumber.isNumber(value) && Number.isNaN(Number(value));
|
|
16
17
|
}
|
|
17
18
|
//#endregion
|
|
18
19
|
exports.isNaN = isNaN;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { isNumber } from "./isNumber.mjs";
|
|
1
2
|
//#region src/compat/predicate/isNaN.ts
|
|
2
3
|
/**
|
|
3
4
|
* Checks if the value is NaN.
|
|
@@ -12,7 +13,7 @@
|
|
|
12
13
|
* isNaN(undefined); // false
|
|
13
14
|
*/
|
|
14
15
|
function isNaN(value) {
|
|
15
|
-
return Number.isNaN(value);
|
|
16
|
+
return isNumber(value) && Number.isNaN(Number(value));
|
|
16
17
|
}
|
|
17
18
|
//#endregion
|
|
18
19
|
export { isNaN };
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
const require_getTag = require("../_internal/getTag.js");
|
|
2
|
+
require("../_internal/tags.js");
|
|
3
|
+
const require_isObjectLike = require("./isObjectLike.js");
|
|
1
4
|
//#region src/compat/predicate/isNumber.ts
|
|
2
5
|
/**
|
|
3
6
|
* Checks if a given value is a number.
|
|
@@ -17,7 +20,7 @@
|
|
|
17
20
|
* console.log(isNumber(value3)); // false
|
|
18
21
|
*/
|
|
19
22
|
function isNumber(value) {
|
|
20
|
-
return typeof value === "number" || value
|
|
23
|
+
return typeof value === "number" || require_isObjectLike.isObjectLike(value) && require_getTag.getTag(value) === "[object Number]";
|
|
21
24
|
}
|
|
22
25
|
//#endregion
|
|
23
26
|
exports.isNumber = isNumber;
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
import { getTag } from "../_internal/getTag.mjs";
|
|
2
|
+
import "../_internal/tags.mjs";
|
|
3
|
+
import { isObjectLike } from "./isObjectLike.mjs";
|
|
1
4
|
//#region src/compat/predicate/isNumber.ts
|
|
2
5
|
/**
|
|
3
6
|
* Checks if a given value is a number.
|
|
@@ -17,7 +20,7 @@
|
|
|
17
20
|
* console.log(isNumber(value3)); // false
|
|
18
21
|
*/
|
|
19
22
|
function isNumber(value) {
|
|
20
|
-
return typeof value === "number" || value
|
|
23
|
+
return typeof value === "number" || isObjectLike(value) && getTag(value) === "[object Number]";
|
|
21
24
|
}
|
|
22
25
|
//#endregion
|
|
23
26
|
export { isNumber };
|
|
@@ -29,10 +29,7 @@ function toPath(deepKey) {
|
|
|
29
29
|
let key = "";
|
|
30
30
|
let quoteChar = "";
|
|
31
31
|
let bracket = false;
|
|
32
|
-
if (deepKey.charCodeAt(0) === 46)
|
|
33
|
-
result.push("");
|
|
34
|
-
index++;
|
|
35
|
-
}
|
|
32
|
+
if (deepKey.charCodeAt(0) === 46) result.push("");
|
|
36
33
|
while (index < length) {
|
|
37
34
|
const char = deepKey[index];
|
|
38
35
|
if (quoteChar) if (char === "\\" && index + 1 < length) {
|
|
@@ -57,6 +54,8 @@ function toPath(deepKey) {
|
|
|
57
54
|
result.push(key);
|
|
58
55
|
key = "";
|
|
59
56
|
}
|
|
57
|
+
const next = deepKey[index + 1];
|
|
58
|
+
if (next === void 0 || next === ".") result.push("");
|
|
60
59
|
} else key += char;
|
|
61
60
|
index++;
|
|
62
61
|
}
|
|
@@ -29,10 +29,7 @@ function toPath(deepKey) {
|
|
|
29
29
|
let key = "";
|
|
30
30
|
let quoteChar = "";
|
|
31
31
|
let bracket = false;
|
|
32
|
-
if (deepKey.charCodeAt(0) === 46)
|
|
33
|
-
result.push("");
|
|
34
|
-
index++;
|
|
35
|
-
}
|
|
32
|
+
if (deepKey.charCodeAt(0) === 46) result.push("");
|
|
36
33
|
while (index < length) {
|
|
37
34
|
const char = deepKey[index];
|
|
38
35
|
if (quoteChar) if (char === "\\" && index + 1 < length) {
|
|
@@ -57,6 +54,8 @@ function toPath(deepKey) {
|
|
|
57
54
|
result.push(key);
|
|
58
55
|
key = "";
|
|
59
56
|
}
|
|
57
|
+
const next = deepKey[index + 1];
|
|
58
|
+
if (next === void 0 || next === ".") result.push("");
|
|
60
59
|
} else key += char;
|
|
61
60
|
index++;
|
|
62
61
|
}
|
|
@@ -43,6 +43,7 @@ interface DebouncedFunction<F extends (...args: any[]) => void> {
|
|
|
43
43
|
* @param debounceMs - The number of milliseconds to delay.
|
|
44
44
|
* @param options - The options object
|
|
45
45
|
* @param options.signal - An optional AbortSignal to cancel the debounced function.
|
|
46
|
+
* @param options.edges - An optional array specifying whether the function should be invoked on the leading edge, trailing edge, or both.
|
|
46
47
|
* @returns A new debounced function with a `cancel` method.
|
|
47
48
|
*
|
|
48
49
|
* @example
|
|
@@ -43,6 +43,7 @@ interface DebouncedFunction<F extends (...args: any[]) => void> {
|
|
|
43
43
|
* @param debounceMs - The number of milliseconds to delay.
|
|
44
44
|
* @param options - The options object
|
|
45
45
|
* @param options.signal - An optional AbortSignal to cancel the debounced function.
|
|
46
|
+
* @param options.edges - An optional array specifying whether the function should be invoked on the leading edge, trailing edge, or both.
|
|
46
47
|
* @returns A new debounced function with a `cancel` method.
|
|
47
48
|
*
|
|
48
49
|
* @example
|
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
* @param debounceMs - The number of milliseconds to delay.
|
|
10
10
|
* @param options - The options object
|
|
11
11
|
* @param options.signal - An optional AbortSignal to cancel the debounced function.
|
|
12
|
+
* @param options.edges - An optional array specifying whether the function should be invoked on the leading edge, trailing edge, or both.
|
|
12
13
|
* @returns A new debounced function with a `cancel` method.
|
|
13
14
|
*
|
|
14
15
|
* @example
|
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
* @param debounceMs - The number of milliseconds to delay.
|
|
10
10
|
* @param options - The options object
|
|
11
11
|
* @param options.signal - An optional AbortSignal to cancel the debounced function.
|
|
12
|
+
* @param options.edges - An optional array specifying whether the function should be invoked on the leading edge, trailing edge, or both.
|
|
12
13
|
* @returns A new debounced function with a `cancel` method.
|
|
13
14
|
*
|
|
14
15
|
* @example
|
package/dist/object/toMerged.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
const require_clone = require("./clone.js");
|
|
2
|
+
const require_cloneDeep = require("./cloneDeep.js");
|
|
2
3
|
const require_isPlainObject = require("../predicate/isPlainObject.js");
|
|
3
4
|
const require_mergeWith = require("./mergeWith.js");
|
|
4
5
|
//#region src/object/toMerged.ts
|
|
@@ -45,7 +46,7 @@ const require_mergeWith = require("./mergeWith.js");
|
|
|
45
46
|
* // Output: { a: [1, 2, 3] }
|
|
46
47
|
*/
|
|
47
48
|
function toMerged(target, source) {
|
|
48
|
-
return require_mergeWith.mergeWith(
|
|
49
|
+
return require_mergeWith.mergeWith(require_cloneDeep.cloneDeep(target), source, function mergeRecursively(targetValue, sourceValue) {
|
|
49
50
|
if (Array.isArray(sourceValue)) if (Array.isArray(targetValue)) return require_mergeWith.mergeWith(require_clone.clone(targetValue), sourceValue, mergeRecursively);
|
|
50
51
|
else return require_mergeWith.mergeWith([], sourceValue, mergeRecursively);
|
|
51
52
|
else if (require_isPlainObject.isPlainObject(sourceValue)) if (require_isPlainObject.isPlainObject(targetValue)) return require_mergeWith.mergeWith(require_clone.clone(targetValue), sourceValue, mergeRecursively);
|
package/dist/object/toMerged.mjs
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { clone } from "./clone.mjs";
|
|
2
|
+
import { cloneDeep } from "./cloneDeep.mjs";
|
|
2
3
|
import { isPlainObject } from "../predicate/isPlainObject.mjs";
|
|
3
4
|
import { mergeWith } from "./mergeWith.mjs";
|
|
4
5
|
//#region src/object/toMerged.ts
|
|
@@ -45,7 +46,7 @@ import { mergeWith } from "./mergeWith.mjs";
|
|
|
45
46
|
* // Output: { a: [1, 2, 3] }
|
|
46
47
|
*/
|
|
47
48
|
function toMerged(target, source) {
|
|
48
|
-
return mergeWith(
|
|
49
|
+
return mergeWith(cloneDeep(target), source, function mergeRecursively(targetValue, sourceValue) {
|
|
49
50
|
if (Array.isArray(sourceValue)) if (Array.isArray(targetValue)) return mergeWith(clone(targetValue), sourceValue, mergeRecursively);
|
|
50
51
|
else return mergeWith([], sourceValue, mergeRecursively);
|
|
51
52
|
else if (isPlainObject(sourceValue)) if (isPlainObject(targetValue)) return mergeWith(clone(targetValue), sourceValue, mergeRecursively);
|
|
@@ -1,9 +1,20 @@
|
|
|
1
1
|
//#region src/promise/timeout.d.ts
|
|
2
|
+
interface TimeoutOptions {
|
|
3
|
+
signal?: AbortSignal;
|
|
4
|
+
}
|
|
2
5
|
/**
|
|
3
6
|
* Returns a promise that rejects with a `TimeoutError` after a specified delay.
|
|
4
7
|
*
|
|
8
|
+
* You can pass an `AbortSignal` to cancel the timeout. Unlike most `AbortSignal`-aware
|
|
9
|
+
* APIs, aborting does **not** reject the promise. A `timeout` only exists to lose a
|
|
10
|
+
* `Promise.race`, so cancelling it leaves the promise pending forever, allowing the
|
|
11
|
+
* operation it guards to settle on its own. The underlying timer and abort listener
|
|
12
|
+
* are cleared on abort, so nothing is leaked.
|
|
13
|
+
*
|
|
5
14
|
* @param ms - The delay duration in milliseconds.
|
|
6
|
-
* @
|
|
15
|
+
* @param options - The options object.
|
|
16
|
+
* @param options.signal - An optional AbortSignal to cancel the timeout. When aborted, the returned promise never settles.
|
|
17
|
+
* @returns A promise that rejects with a `TimeoutError` after the specified delay, or never settles if aborted.
|
|
7
18
|
* @throws {TimeoutError} Throws a `TimeoutError` after the specified delay.
|
|
8
19
|
*
|
|
9
20
|
* @example
|
|
@@ -12,7 +23,19 @@
|
|
|
12
23
|
* } catch (error) {
|
|
13
24
|
* console.error(error); // Will log 'The operation was timed out'
|
|
14
25
|
* }
|
|
26
|
+
*
|
|
27
|
+
* @example
|
|
28
|
+
* // Cancelling the timeout lifts the time limit instead of throwing.
|
|
29
|
+
* const controller = new AbortController();
|
|
30
|
+
* setTimeout(() => controller.abort(), 50);
|
|
31
|
+
*
|
|
32
|
+
* const result = await Promise.race([
|
|
33
|
+
* doWork(),
|
|
34
|
+
* timeout(1000, { signal: controller.signal }), // never rejects once aborted
|
|
35
|
+
* ]);
|
|
15
36
|
*/
|
|
16
|
-
declare function timeout(ms: number
|
|
37
|
+
declare function timeout(ms: number, {
|
|
38
|
+
signal
|
|
39
|
+
}?: TimeoutOptions): Promise<never>;
|
|
17
40
|
//#endregion
|
|
18
41
|
export { timeout };
|
|
@@ -1,9 +1,20 @@
|
|
|
1
1
|
//#region src/promise/timeout.d.ts
|
|
2
|
+
interface TimeoutOptions {
|
|
3
|
+
signal?: AbortSignal;
|
|
4
|
+
}
|
|
2
5
|
/**
|
|
3
6
|
* Returns a promise that rejects with a `TimeoutError` after a specified delay.
|
|
4
7
|
*
|
|
8
|
+
* You can pass an `AbortSignal` to cancel the timeout. Unlike most `AbortSignal`-aware
|
|
9
|
+
* APIs, aborting does **not** reject the promise. A `timeout` only exists to lose a
|
|
10
|
+
* `Promise.race`, so cancelling it leaves the promise pending forever, allowing the
|
|
11
|
+
* operation it guards to settle on its own. The underlying timer and abort listener
|
|
12
|
+
* are cleared on abort, so nothing is leaked.
|
|
13
|
+
*
|
|
5
14
|
* @param ms - The delay duration in milliseconds.
|
|
6
|
-
* @
|
|
15
|
+
* @param options - The options object.
|
|
16
|
+
* @param options.signal - An optional AbortSignal to cancel the timeout. When aborted, the returned promise never settles.
|
|
17
|
+
* @returns A promise that rejects with a `TimeoutError` after the specified delay, or never settles if aborted.
|
|
7
18
|
* @throws {TimeoutError} Throws a `TimeoutError` after the specified delay.
|
|
8
19
|
*
|
|
9
20
|
* @example
|
|
@@ -12,7 +23,19 @@
|
|
|
12
23
|
* } catch (error) {
|
|
13
24
|
* console.error(error); // Will log 'The operation was timed out'
|
|
14
25
|
* }
|
|
26
|
+
*
|
|
27
|
+
* @example
|
|
28
|
+
* // Cancelling the timeout lifts the time limit instead of throwing.
|
|
29
|
+
* const controller = new AbortController();
|
|
30
|
+
* setTimeout(() => controller.abort(), 50);
|
|
31
|
+
*
|
|
32
|
+
* const result = await Promise.race([
|
|
33
|
+
* doWork(),
|
|
34
|
+
* timeout(1000, { signal: controller.signal }), // never rejects once aborted
|
|
35
|
+
* ]);
|
|
15
36
|
*/
|
|
16
|
-
declare function timeout(ms: number
|
|
37
|
+
declare function timeout(ms: number, {
|
|
38
|
+
signal
|
|
39
|
+
}?: TimeoutOptions): Promise<never>;
|
|
17
40
|
//#endregion
|
|
18
41
|
export { timeout };
|
package/dist/promise/timeout.js
CHANGED
|
@@ -1,11 +1,18 @@
|
|
|
1
1
|
const require_TimeoutError = require("../error/TimeoutError.js");
|
|
2
|
-
const require_delay = require("./delay.js");
|
|
3
2
|
//#region src/promise/timeout.ts
|
|
4
3
|
/**
|
|
5
4
|
* Returns a promise that rejects with a `TimeoutError` after a specified delay.
|
|
6
5
|
*
|
|
6
|
+
* You can pass an `AbortSignal` to cancel the timeout. Unlike most `AbortSignal`-aware
|
|
7
|
+
* APIs, aborting does **not** reject the promise. A `timeout` only exists to lose a
|
|
8
|
+
* `Promise.race`, so cancelling it leaves the promise pending forever, allowing the
|
|
9
|
+
* operation it guards to settle on its own. The underlying timer and abort listener
|
|
10
|
+
* are cleared on abort, so nothing is leaked.
|
|
11
|
+
*
|
|
7
12
|
* @param ms - The delay duration in milliseconds.
|
|
8
|
-
* @
|
|
13
|
+
* @param options - The options object.
|
|
14
|
+
* @param options.signal - An optional AbortSignal to cancel the timeout. When aborted, the returned promise never settles.
|
|
15
|
+
* @returns A promise that rejects with a `TimeoutError` after the specified delay, or never settles if aborted.
|
|
9
16
|
* @throws {TimeoutError} Throws a `TimeoutError` after the specified delay.
|
|
10
17
|
*
|
|
11
18
|
* @example
|
|
@@ -14,10 +21,29 @@ const require_delay = require("./delay.js");
|
|
|
14
21
|
* } catch (error) {
|
|
15
22
|
* console.error(error); // Will log 'The operation was timed out'
|
|
16
23
|
* }
|
|
24
|
+
*
|
|
25
|
+
* @example
|
|
26
|
+
* // Cancelling the timeout lifts the time limit instead of throwing.
|
|
27
|
+
* const controller = new AbortController();
|
|
28
|
+
* setTimeout(() => controller.abort(), 50);
|
|
29
|
+
*
|
|
30
|
+
* const result = await Promise.race([
|
|
31
|
+
* doWork(),
|
|
32
|
+
* timeout(1000, { signal: controller.signal }), // never rejects once aborted
|
|
33
|
+
* ]);
|
|
17
34
|
*/
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
35
|
+
function timeout(ms, { signal } = {}) {
|
|
36
|
+
return new Promise((_resolve, reject) => {
|
|
37
|
+
const abortHandler = () => {
|
|
38
|
+
clearTimeout(timeoutId);
|
|
39
|
+
};
|
|
40
|
+
if (signal?.aborted) return;
|
|
41
|
+
const timeoutId = setTimeout(() => {
|
|
42
|
+
signal?.removeEventListener("abort", abortHandler);
|
|
43
|
+
reject(new require_TimeoutError.TimeoutError());
|
|
44
|
+
}, ms);
|
|
45
|
+
signal?.addEventListener("abort", abortHandler, { once: true });
|
|
46
|
+
});
|
|
21
47
|
}
|
|
22
48
|
//#endregion
|
|
23
49
|
exports.timeout = timeout;
|
package/dist/promise/timeout.mjs
CHANGED
|
@@ -1,11 +1,18 @@
|
|
|
1
1
|
import { TimeoutError } from "../error/TimeoutError.mjs";
|
|
2
|
-
import { delay } from "./delay.mjs";
|
|
3
2
|
//#region src/promise/timeout.ts
|
|
4
3
|
/**
|
|
5
4
|
* Returns a promise that rejects with a `TimeoutError` after a specified delay.
|
|
6
5
|
*
|
|
6
|
+
* You can pass an `AbortSignal` to cancel the timeout. Unlike most `AbortSignal`-aware
|
|
7
|
+
* APIs, aborting does **not** reject the promise. A `timeout` only exists to lose a
|
|
8
|
+
* `Promise.race`, so cancelling it leaves the promise pending forever, allowing the
|
|
9
|
+
* operation it guards to settle on its own. The underlying timer and abort listener
|
|
10
|
+
* are cleared on abort, so nothing is leaked.
|
|
11
|
+
*
|
|
7
12
|
* @param ms - The delay duration in milliseconds.
|
|
8
|
-
* @
|
|
13
|
+
* @param options - The options object.
|
|
14
|
+
* @param options.signal - An optional AbortSignal to cancel the timeout. When aborted, the returned promise never settles.
|
|
15
|
+
* @returns A promise that rejects with a `TimeoutError` after the specified delay, or never settles if aborted.
|
|
9
16
|
* @throws {TimeoutError} Throws a `TimeoutError` after the specified delay.
|
|
10
17
|
*
|
|
11
18
|
* @example
|
|
@@ -14,10 +21,29 @@ import { delay } from "./delay.mjs";
|
|
|
14
21
|
* } catch (error) {
|
|
15
22
|
* console.error(error); // Will log 'The operation was timed out'
|
|
16
23
|
* }
|
|
24
|
+
*
|
|
25
|
+
* @example
|
|
26
|
+
* // Cancelling the timeout lifts the time limit instead of throwing.
|
|
27
|
+
* const controller = new AbortController();
|
|
28
|
+
* setTimeout(() => controller.abort(), 50);
|
|
29
|
+
*
|
|
30
|
+
* const result = await Promise.race([
|
|
31
|
+
* doWork(),
|
|
32
|
+
* timeout(1000, { signal: controller.signal }), // never rejects once aborted
|
|
33
|
+
* ]);
|
|
17
34
|
*/
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
35
|
+
function timeout(ms, { signal } = {}) {
|
|
36
|
+
return new Promise((_resolve, reject) => {
|
|
37
|
+
const abortHandler = () => {
|
|
38
|
+
clearTimeout(timeoutId);
|
|
39
|
+
};
|
|
40
|
+
if (signal?.aborted) return;
|
|
41
|
+
const timeoutId = setTimeout(() => {
|
|
42
|
+
signal?.removeEventListener("abort", abortHandler);
|
|
43
|
+
reject(new TimeoutError());
|
|
44
|
+
}, ms);
|
|
45
|
+
signal?.addEventListener("abort", abortHandler, { once: true });
|
|
46
|
+
});
|
|
21
47
|
}
|
|
22
48
|
//#endregion
|
|
23
49
|
export { timeout };
|
|
@@ -1,14 +1,23 @@
|
|
|
1
1
|
//#region src/promise/withTimeout.d.ts
|
|
2
|
+
interface WithTimeoutOptions {
|
|
3
|
+
signal?: AbortSignal;
|
|
4
|
+
}
|
|
2
5
|
/**
|
|
3
6
|
* Executes an async function and enforces a timeout.
|
|
4
7
|
*
|
|
5
8
|
* If the promise does not resolve within the specified time,
|
|
6
9
|
* the timeout will trigger and the returned promise will be rejected.
|
|
7
10
|
*
|
|
11
|
+
* You can pass an `AbortSignal` to cancel the timeout. Aborting the signal lifts the
|
|
12
|
+
* time limit: the timeout stops counting and `run`'s promise is awaited without a
|
|
13
|
+
* deadline. It does not reject the returned promise or abort `run` itself — pass the
|
|
14
|
+
* same signal into `run` if you also want to cancel the underlying work.
|
|
8
15
|
*
|
|
9
16
|
* @template T
|
|
10
17
|
* @param run - A function that returns a promise to be executed.
|
|
11
18
|
* @param ms - The timeout duration in milliseconds.
|
|
19
|
+
* @param options - The options object.
|
|
20
|
+
* @param options.signal - An optional AbortSignal to cancel the timeout. When aborted, the time limit is lifted.
|
|
12
21
|
* @returns A promise that resolves with the result of the `run` function or rejects if the timeout is reached.
|
|
13
22
|
*
|
|
14
23
|
* @example
|
|
@@ -23,7 +32,16 @@
|
|
|
23
32
|
* } catch (error) {
|
|
24
33
|
* console.error(error); // Will log 'TimeoutError' if `fetchData` is not resolved within 1 second.
|
|
25
34
|
* }
|
|
35
|
+
*
|
|
36
|
+
* @example
|
|
37
|
+
* // Lift the time limit when the user opts to keep waiting.
|
|
38
|
+
* const controller = new AbortController();
|
|
39
|
+
* keepWaitingButton.onclick = () => controller.abort();
|
|
40
|
+
*
|
|
41
|
+
* const data = await withTimeout(fetchData, 1000, { signal: controller.signal });
|
|
26
42
|
*/
|
|
27
|
-
declare function withTimeout<T>(run: () => Promise<T>, ms: number
|
|
43
|
+
declare function withTimeout<T>(run: () => Promise<T>, ms: number, {
|
|
44
|
+
signal
|
|
45
|
+
}?: WithTimeoutOptions): Promise<T>;
|
|
28
46
|
//#endregion
|
|
29
47
|
export { withTimeout };
|
|
@@ -1,14 +1,23 @@
|
|
|
1
1
|
//#region src/promise/withTimeout.d.ts
|
|
2
|
+
interface WithTimeoutOptions {
|
|
3
|
+
signal?: AbortSignal;
|
|
4
|
+
}
|
|
2
5
|
/**
|
|
3
6
|
* Executes an async function and enforces a timeout.
|
|
4
7
|
*
|
|
5
8
|
* If the promise does not resolve within the specified time,
|
|
6
9
|
* the timeout will trigger and the returned promise will be rejected.
|
|
7
10
|
*
|
|
11
|
+
* You can pass an `AbortSignal` to cancel the timeout. Aborting the signal lifts the
|
|
12
|
+
* time limit: the timeout stops counting and `run`'s promise is awaited without a
|
|
13
|
+
* deadline. It does not reject the returned promise or abort `run` itself — pass the
|
|
14
|
+
* same signal into `run` if you also want to cancel the underlying work.
|
|
8
15
|
*
|
|
9
16
|
* @template T
|
|
10
17
|
* @param run - A function that returns a promise to be executed.
|
|
11
18
|
* @param ms - The timeout duration in milliseconds.
|
|
19
|
+
* @param options - The options object.
|
|
20
|
+
* @param options.signal - An optional AbortSignal to cancel the timeout. When aborted, the time limit is lifted.
|
|
12
21
|
* @returns A promise that resolves with the result of the `run` function or rejects if the timeout is reached.
|
|
13
22
|
*
|
|
14
23
|
* @example
|
|
@@ -23,7 +32,16 @@
|
|
|
23
32
|
* } catch (error) {
|
|
24
33
|
* console.error(error); // Will log 'TimeoutError' if `fetchData` is not resolved within 1 second.
|
|
25
34
|
* }
|
|
35
|
+
*
|
|
36
|
+
* @example
|
|
37
|
+
* // Lift the time limit when the user opts to keep waiting.
|
|
38
|
+
* const controller = new AbortController();
|
|
39
|
+
* keepWaitingButton.onclick = () => controller.abort();
|
|
40
|
+
*
|
|
41
|
+
* const data = await withTimeout(fetchData, 1000, { signal: controller.signal });
|
|
26
42
|
*/
|
|
27
|
-
declare function withTimeout<T>(run: () => Promise<T>, ms: number
|
|
43
|
+
declare function withTimeout<T>(run: () => Promise<T>, ms: number, {
|
|
44
|
+
signal
|
|
45
|
+
}?: WithTimeoutOptions): Promise<T>;
|
|
28
46
|
//#endregion
|
|
29
47
|
export { withTimeout };
|
|
@@ -6,10 +6,16 @@ const require_timeout = require("./timeout.js");
|
|
|
6
6
|
* If the promise does not resolve within the specified time,
|
|
7
7
|
* the timeout will trigger and the returned promise will be rejected.
|
|
8
8
|
*
|
|
9
|
+
* You can pass an `AbortSignal` to cancel the timeout. Aborting the signal lifts the
|
|
10
|
+
* time limit: the timeout stops counting and `run`'s promise is awaited without a
|
|
11
|
+
* deadline. It does not reject the returned promise or abort `run` itself — pass the
|
|
12
|
+
* same signal into `run` if you also want to cancel the underlying work.
|
|
9
13
|
*
|
|
10
14
|
* @template T
|
|
11
15
|
* @param run - A function that returns a promise to be executed.
|
|
12
16
|
* @param ms - The timeout duration in milliseconds.
|
|
17
|
+
* @param options - The options object.
|
|
18
|
+
* @param options.signal - An optional AbortSignal to cancel the timeout. When aborted, the time limit is lifted.
|
|
13
19
|
* @returns A promise that resolves with the result of the `run` function or rejects if the timeout is reached.
|
|
14
20
|
*
|
|
15
21
|
* @example
|
|
@@ -24,9 +30,16 @@ const require_timeout = require("./timeout.js");
|
|
|
24
30
|
* } catch (error) {
|
|
25
31
|
* console.error(error); // Will log 'TimeoutError' if `fetchData` is not resolved within 1 second.
|
|
26
32
|
* }
|
|
33
|
+
*
|
|
34
|
+
* @example
|
|
35
|
+
* // Lift the time limit when the user opts to keep waiting.
|
|
36
|
+
* const controller = new AbortController();
|
|
37
|
+
* keepWaitingButton.onclick = () => controller.abort();
|
|
38
|
+
*
|
|
39
|
+
* const data = await withTimeout(fetchData, 1000, { signal: controller.signal });
|
|
27
40
|
*/
|
|
28
|
-
async function withTimeout(run, ms) {
|
|
29
|
-
return Promise.race([run(), require_timeout.timeout(ms)]);
|
|
41
|
+
async function withTimeout(run, ms, { signal } = {}) {
|
|
42
|
+
return Promise.race([run(), require_timeout.timeout(ms, { signal })]);
|
|
30
43
|
}
|
|
31
44
|
//#endregion
|
|
32
45
|
exports.withTimeout = withTimeout;
|
|
@@ -6,10 +6,16 @@ import { timeout } from "./timeout.mjs";
|
|
|
6
6
|
* If the promise does not resolve within the specified time,
|
|
7
7
|
* the timeout will trigger and the returned promise will be rejected.
|
|
8
8
|
*
|
|
9
|
+
* You can pass an `AbortSignal` to cancel the timeout. Aborting the signal lifts the
|
|
10
|
+
* time limit: the timeout stops counting and `run`'s promise is awaited without a
|
|
11
|
+
* deadline. It does not reject the returned promise or abort `run` itself — pass the
|
|
12
|
+
* same signal into `run` if you also want to cancel the underlying work.
|
|
9
13
|
*
|
|
10
14
|
* @template T
|
|
11
15
|
* @param run - A function that returns a promise to be executed.
|
|
12
16
|
* @param ms - The timeout duration in milliseconds.
|
|
17
|
+
* @param options - The options object.
|
|
18
|
+
* @param options.signal - An optional AbortSignal to cancel the timeout. When aborted, the time limit is lifted.
|
|
13
19
|
* @returns A promise that resolves with the result of the `run` function or rejects if the timeout is reached.
|
|
14
20
|
*
|
|
15
21
|
* @example
|
|
@@ -24,9 +30,16 @@ import { timeout } from "./timeout.mjs";
|
|
|
24
30
|
* } catch (error) {
|
|
25
31
|
* console.error(error); // Will log 'TimeoutError' if `fetchData` is not resolved within 1 second.
|
|
26
32
|
* }
|
|
33
|
+
*
|
|
34
|
+
* @example
|
|
35
|
+
* // Lift the time limit when the user opts to keep waiting.
|
|
36
|
+
* const controller = new AbortController();
|
|
37
|
+
* keepWaitingButton.onclick = () => controller.abort();
|
|
38
|
+
*
|
|
39
|
+
* const data = await withTimeout(fetchData, 1000, { signal: controller.signal });
|
|
27
40
|
*/
|
|
28
|
-
async function withTimeout(run, ms) {
|
|
29
|
-
return Promise.race([run(), timeout(ms)]);
|
|
41
|
+
async function withTimeout(run, ms, { signal } = {}) {
|
|
42
|
+
return Promise.race([run(), timeout(ms, { signal })]);
|
|
30
43
|
}
|
|
31
44
|
//#endregion
|
|
32
45
|
export { withTimeout };
|