@stryke/helpers 0.9.35 → 0.9.36
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 +8 -0
- package/dist/arg-identity.cjs +17 -1
- package/dist/arg-identity.mjs +16 -1
- package/dist/arg-identity.mjs.map +1 -1
- package/dist/convert/src/to-string-key.cjs +15 -1
- package/dist/convert/src/to-string-key.mjs +14 -1
- package/dist/convert/src/to-string-key.mjs.map +1 -1
- package/dist/debounce.cjs +62 -1
- package/dist/debounce.mjs +61 -1
- package/dist/debounce.mjs.map +1 -1
- package/dist/deep-clone.cjs +113 -1
- package/dist/deep-clone.mjs +113 -1
- package/dist/deep-clone.mjs.map +1 -1
- package/dist/deep-merge.cjs +60 -1
- package/dist/deep-merge.mjs +60 -1
- package/dist/deep-merge.mjs.map +1 -1
- package/dist/delay.cjs +90 -1
- package/dist/delay.mjs +89 -1
- package/dist/delay.mjs.map +1 -1
- package/dist/errors.cjs +24 -1
- package/dist/errors.mjs +22 -1
- package/dist/errors.mjs.map +1 -1
- package/dist/filter-empty.cjs +7 -1
- package/dist/filter-empty.mjs +7 -1
- package/dist/filter-empty.mjs.map +1 -1
- package/dist/flatten-object.cjs +48 -1
- package/dist/flatten-object.mjs +48 -1
- package/dist/flatten-object.mjs.map +1 -1
- package/dist/get-field.cjs +54 -1
- package/dist/get-field.mjs +54 -1
- package/dist/get-field.mjs.map +1 -1
- package/dist/get-ordered-by.cjs +54 -1
- package/dist/get-ordered-by.mjs +53 -1
- package/dist/get-ordered-by.mjs.map +1 -1
- package/dist/get-unique.cjs +37 -1
- package/dist/get-unique.mjs +35 -1
- package/dist/get-unique.mjs.map +1 -1
- package/dist/identity.cjs +21 -1
- package/dist/identity.mjs +20 -1
- package/dist/identity.mjs.map +1 -1
- package/dist/index.cjs +71 -1
- package/dist/index.mjs +33 -1
- package/dist/is-equal.cjs +87 -1
- package/dist/is-equal.mjs +87 -1
- package/dist/is-equal.mjs.map +1 -1
- package/dist/lru-cache.cjs +190 -1
- package/dist/lru-cache.mjs +189 -1
- package/dist/lru-cache.mjs.map +1 -1
- package/dist/match-sorter.cjs +264 -1
- package/dist/match-sorter.mjs +262 -1
- package/dist/match-sorter.mjs.map +1 -1
- package/dist/memoize.cjs +20 -1
- package/dist/memoize.mjs +19 -1
- package/dist/memoize.mjs.map +1 -1
- package/dist/mutex.cjs +80 -1
- package/dist/mutex.mjs +80 -1
- package/dist/mutex.mjs.map +1 -1
- package/dist/noop.cjs +24 -1
- package/dist/noop.mjs +22 -1
- package/dist/noop.mjs.map +1 -1
- package/dist/omit.cjs +30 -1
- package/dist/omit.mjs +29 -1
- package/dist/omit.mjs.map +1 -1
- package/dist/once.cjs +27 -1
- package/dist/once.mjs +25 -1
- package/dist/once.mjs.map +1 -1
- package/dist/pick.cjs +30 -1
- package/dist/pick.mjs +29 -1
- package/dist/pick.mjs.map +1 -1
- package/dist/remove-accents.cjs +416 -1
- package/dist/remove-accents.mjs +414 -1
- package/dist/remove-accents.mjs.map +1 -1
- package/dist/remove-empty-items.cjs +12 -1
- package/dist/remove-empty-items.mjs +11 -1
- package/dist/remove-empty-items.mjs.map +1 -1
- package/dist/semaphore.cjs +105 -1
- package/dist/semaphore.mjs +104 -1
- package/dist/semaphore.mjs.map +1 -1
- package/dist/set-field.cjs +30 -1
- package/dist/set-field.mjs +30 -1
- package/dist/set-field.mjs.map +1 -1
- package/dist/throttle.cjs +43 -1
- package/dist/throttle.mjs +42 -1
- package/dist/throttle.mjs.map +1 -1
- package/dist/timeout.cjs +18 -1
- package/dist/timeout.mjs +18 -1
- package/dist/timeout.mjs.map +1 -1
- package/dist/to-deep-key.cjs +54 -1
- package/dist/to-deep-key.mjs +53 -1
- package/dist/to-deep-key.mjs.map +1 -1
- package/dist/to-path.cjs +43 -1
- package/dist/to-path.mjs +42 -1
- package/dist/to-path.mjs.map +1 -1
- package/dist/type-checks/src/get-object-tag.cjs +15 -1
- package/dist/type-checks/src/get-object-tag.mjs +14 -1
- package/dist/type-checks/src/get-object-tag.mjs.map +1 -1
- package/dist/type-checks/src/is-deep-key.cjs +28 -1
- package/dist/type-checks/src/is-deep-key.mjs +27 -1
- package/dist/type-checks/src/is-deep-key.mjs.map +1 -1
- package/dist/type-checks/src/is-empty.cjs +20 -1
- package/dist/type-checks/src/is-empty.mjs +20 -1
- package/dist/type-checks/src/is-empty.mjs.map +1 -1
- package/dist/type-checks/src/is-function.cjs +25 -1
- package/dist/type-checks/src/is-function.mjs +25 -1
- package/dist/type-checks/src/is-function.mjs.map +1 -1
- package/dist/type-checks/src/is-mergeable-object.cjs +14 -1
- package/dist/type-checks/src/is-mergeable-object.mjs +14 -1
- package/dist/type-checks/src/is-mergeable-object.mjs.map +1 -1
- package/dist/type-checks/src/is-non-null-object.cjs +16 -1
- package/dist/type-checks/src/is-non-null-object.mjs +16 -1
- package/dist/type-checks/src/is-non-null-object.mjs.map +1 -1
- package/dist/type-checks/src/is-null.cjs +12 -1
- package/dist/type-checks/src/is-null.mjs +11 -1
- package/dist/type-checks/src/is-null.mjs.map +1 -1
- package/dist/type-checks/src/is-number.cjs +18 -1
- package/dist/type-checks/src/is-number.mjs +17 -1
- package/dist/type-checks/src/is-number.mjs.map +1 -1
- package/dist/type-checks/src/is-object-index.cjs +19 -1
- package/dist/type-checks/src/is-object-index.mjs +18 -1
- package/dist/type-checks/src/is-object-index.mjs.map +1 -1
- package/dist/type-checks/src/is-object.cjs +19 -1
- package/dist/type-checks/src/is-object.mjs +19 -1
- package/dist/type-checks/src/is-object.mjs.map +1 -1
- package/dist/type-checks/src/is-plain-object.cjs +63 -1
- package/dist/type-checks/src/is-plain-object.mjs +63 -1
- package/dist/type-checks/src/is-plain-object.mjs.map +1 -1
- package/dist/type-checks/src/is-primitive.cjs +12 -1
- package/dist/type-checks/src/is-primitive.mjs +11 -1
- package/dist/type-checks/src/is-primitive.mjs.map +1 -1
- package/dist/type-checks/src/is-react-element.cjs +8 -1
- package/dist/type-checks/src/is-react-element.mjs +7 -1
- package/dist/type-checks/src/is-react-element.mjs.map +1 -1
- package/dist/type-checks/src/is-set-string.cjs +20 -1
- package/dist/type-checks/src/is-set-string.mjs +20 -1
- package/dist/type-checks/src/is-set-string.mjs.map +1 -1
- package/dist/type-checks/src/is-set.cjs +19 -1
- package/dist/type-checks/src/is-set.mjs +19 -1
- package/dist/type-checks/src/is-set.mjs.map +1 -1
- package/dist/type-checks/src/is-string.cjs +12 -1
- package/dist/type-checks/src/is-string.mjs +11 -1
- package/dist/type-checks/src/is-string.mjs.map +1 -1
- package/dist/type-checks/src/is-typed-array.cjs +8 -1
- package/dist/type-checks/src/is-typed-array.mjs +7 -1
- package/dist/type-checks/src/is-typed-array.mjs.map +1 -1
- package/dist/type-checks/src/is-undefined.cjs +8 -1
- package/dist/type-checks/src/is-undefined.mjs +7 -1
- package/dist/type-checks/src/is-undefined.mjs.map +1 -1
- package/dist/type-checks/src/property-exists.cjs +30 -1
- package/dist/type-checks/src/property-exists.mjs +30 -1
- package/dist/type-checks/src/property-exists.mjs.map +1 -1
- package/dist/unflatten-object.cjs +38 -1
- package/dist/unflatten-object.mjs +38 -1
- package/dist/unflatten-object.mjs.map +1 -1
- package/dist/union.cjs +28 -1
- package/dist/union.mjs +28 -1
- package/dist/union.mjs.map +1 -1
- package/dist/with-timeout.cjs +28 -1
- package/dist/with-timeout.mjs +28 -1
- package/dist/with-timeout.mjs.map +1 -1
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
# Changelog for Stryke - Helpers
|
|
4
4
|
|
|
5
|
+
## [0.9.35](https://github.com/storm-software/stryke/releases/tag/helpers%400.9.35) (01/16/2026)
|
|
6
|
+
|
|
7
|
+
### Updated Dependencies
|
|
8
|
+
|
|
9
|
+
- Updated **type-checks** to **v0.5.18**
|
|
10
|
+
- Updated **convert** to **v0.6.33**
|
|
11
|
+
- Updated **types** to **v0.10.32**
|
|
12
|
+
|
|
5
13
|
## [0.9.34](https://github.com/storm-software/stryke/releases/tag/helpers%400.9.34) (01/15/2026)
|
|
6
14
|
|
|
7
15
|
### Updated Dependencies
|
package/dist/arg-identity.cjs
CHANGED
|
@@ -1 +1,17 @@
|
|
|
1
|
-
|
|
1
|
+
|
|
2
|
+
//#region src/arg-identity.ts
|
|
3
|
+
/**
|
|
4
|
+
* This method returns the first argument provided to it.
|
|
5
|
+
*
|
|
6
|
+
* @remarks
|
|
7
|
+
* For more info, please see {@link https://lodash.com/docs/4.17.15#identity | the original Lodash documentation}.
|
|
8
|
+
*
|
|
9
|
+
* @param value - The value to return.
|
|
10
|
+
* @returns The value provided.
|
|
11
|
+
*/
|
|
12
|
+
function argIdentity(value) {
|
|
13
|
+
return value;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
//#endregion
|
|
17
|
+
exports.argIdentity = argIdentity;
|
package/dist/arg-identity.mjs
CHANGED
|
@@ -1,2 +1,17 @@
|
|
|
1
|
-
|
|
1
|
+
//#region src/arg-identity.ts
|
|
2
|
+
/**
|
|
3
|
+
* This method returns the first argument provided to it.
|
|
4
|
+
*
|
|
5
|
+
* @remarks
|
|
6
|
+
* For more info, please see {@link https://lodash.com/docs/4.17.15#identity | the original Lodash documentation}.
|
|
7
|
+
*
|
|
8
|
+
* @param value - The value to return.
|
|
9
|
+
* @returns The value provided.
|
|
10
|
+
*/
|
|
11
|
+
function argIdentity(value) {
|
|
12
|
+
return value;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
//#endregion
|
|
16
|
+
export { argIdentity };
|
|
2
17
|
//# sourceMappingURL=arg-identity.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"arg-identity.mjs","names":[],"sources":["../src/arg-identity.ts"],"sourcesContent":["/* -------------------------------------------------------------------\n\n ⚡ Storm Software - Stryke\n\n This code was released as part of the Stryke project. Stryke\n is maintained by Storm Software under the Apache-2.0 License, and is\n free for commercial and private use. For more information, please visit\n our licensing page.\n\n Website: https://stormsoftware.com\n Repository: https://github.com/storm-software/stryke\n Documentation: https://stormsoftware.com/projects/stryke/docs\n Contact: https://stormsoftware.com/contact\n License: https://stormsoftware.com/projects/stryke/license\n\n ------------------------------------------------------------------- */\n\n/**\n * This method returns the first argument provided to it.\n *\n * @remarks\n * For more info, please see {@link https://lodash.com/docs/4.17.15#identity | the original Lodash documentation}.\n *\n * @param value - The value to return.\n * @returns The value provided.\n */\nexport function argIdentity(value: any) {\n return value;\n}\n"],"mappings":"AA0BA,SAAgB,
|
|
1
|
+
{"version":3,"file":"arg-identity.mjs","names":[],"sources":["../src/arg-identity.ts"],"sourcesContent":["/* -------------------------------------------------------------------\n\n ⚡ Storm Software - Stryke\n\n This code was released as part of the Stryke project. Stryke\n is maintained by Storm Software under the Apache-2.0 License, and is\n free for commercial and private use. For more information, please visit\n our licensing page.\n\n Website: https://stormsoftware.com\n Repository: https://github.com/storm-software/stryke\n Documentation: https://stormsoftware.com/projects/stryke/docs\n Contact: https://stormsoftware.com/contact\n License: https://stormsoftware.com/projects/stryke/license\n\n ------------------------------------------------------------------- */\n\n/**\n * This method returns the first argument provided to it.\n *\n * @remarks\n * For more info, please see {@link https://lodash.com/docs/4.17.15#identity | the original Lodash documentation}.\n *\n * @param value - The value to return.\n * @returns The value provided.\n */\nexport function argIdentity(value: any) {\n return value;\n}\n"],"mappings":";;;;;;;;;;AA0BA,SAAgB,YAAY,OAAY;AACtC,QAAO"}
|
|
@@ -1 +1,15 @@
|
|
|
1
|
-
|
|
1
|
+
|
|
2
|
+
//#region ../convert/src/to-string-key.ts
|
|
3
|
+
/**
|
|
4
|
+
* Converts `value` to a string key if it's not a string or symbol.
|
|
5
|
+
*
|
|
6
|
+
* @param value - The value to inspect.
|
|
7
|
+
* @returns Returns the key.
|
|
8
|
+
*/
|
|
9
|
+
function toStringKey(value) {
|
|
10
|
+
if (Object.is(value, -0)) return "-0";
|
|
11
|
+
return value.toString();
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
//#endregion
|
|
15
|
+
exports.toStringKey = toStringKey;
|
|
@@ -1,2 +1,15 @@
|
|
|
1
|
-
|
|
1
|
+
//#region ../convert/src/to-string-key.ts
|
|
2
|
+
/**
|
|
3
|
+
* Converts `value` to a string key if it's not a string or symbol.
|
|
4
|
+
*
|
|
5
|
+
* @param value - The value to inspect.
|
|
6
|
+
* @returns Returns the key.
|
|
7
|
+
*/
|
|
8
|
+
function toStringKey(value) {
|
|
9
|
+
if (Object.is(value, -0)) return "-0";
|
|
10
|
+
return value.toString();
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
//#endregion
|
|
14
|
+
export { toStringKey };
|
|
2
15
|
//# sourceMappingURL=to-string-key.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"to-string-key.mjs","names":[],"sources":["../../../../convert/src/to-string-key.ts"],"sourcesContent":["/* -------------------------------------------------------------------\n\n ⚡ Storm Software - Stryke\n\n This code was released as part of the Stryke project. Stryke\n is maintained by Storm Software under the Apache-2.0 license, and is\n free for commercial and private use. For more information, please visit\n our licensing page at https://stormsoftware.com/licenses/projects/stryke.\n\n Website: https://stormsoftware.com\n Repository: https://github.com/storm-software/stryke\n Documentation: https://docs.stormsoftware.com/projects/stryke\n Contact: https://stormsoftware.com/contact\n\n SPDX-License-Identifier: Apache-2.0\n\n ------------------------------------------------------------------- */\n\n/**\n * Converts `value` to a string key if it's not a string or symbol.\n *\n * @param value - The value to inspect.\n * @returns Returns the key.\n */\nexport function toStringKey(value: number): string | symbol {\n if (Object.is(value, -0)) {\n return \"-0\";\n }\n\n return value.toString();\n}\n"],"mappings":"AAwBA,SAAgB,
|
|
1
|
+
{"version":3,"file":"to-string-key.mjs","names":[],"sources":["../../../../convert/src/to-string-key.ts"],"sourcesContent":["/* -------------------------------------------------------------------\n\n ⚡ Storm Software - Stryke\n\n This code was released as part of the Stryke project. Stryke\n is maintained by Storm Software under the Apache-2.0 license, and is\n free for commercial and private use. For more information, please visit\n our licensing page at https://stormsoftware.com/licenses/projects/stryke.\n\n Website: https://stormsoftware.com\n Repository: https://github.com/storm-software/stryke\n Documentation: https://docs.stormsoftware.com/projects/stryke\n Contact: https://stormsoftware.com/contact\n\n SPDX-License-Identifier: Apache-2.0\n\n ------------------------------------------------------------------- */\n\n/**\n * Converts `value` to a string key if it's not a string or symbol.\n *\n * @param value - The value to inspect.\n * @returns Returns the key.\n */\nexport function toStringKey(value: number): string | symbol {\n if (Object.is(value, -0)) {\n return \"-0\";\n }\n\n return value.toString();\n}\n"],"mappings":";;;;;;;AAwBA,SAAgB,YAAY,OAAgC;AAC1D,KAAI,OAAO,GAAG,OAAO,GAAG,CACtB,QAAO;AAGT,QAAO,MAAM,UAAU"}
|
package/dist/debounce.cjs
CHANGED
|
@@ -1 +1,62 @@
|
|
|
1
|
-
|
|
1
|
+
|
|
2
|
+
//#region src/debounce.ts
|
|
3
|
+
/**
|
|
4
|
+
* Creates a debounced function that delays invoking the provided function until after `debounceMs` milliseconds
|
|
5
|
+
* have elapsed since the last time the debounced function was invoked. The debounced function also has a `cancel`
|
|
6
|
+
* method to cancel any pending execution.
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* ```typescript
|
|
10
|
+
* const debouncedFunction = debounce(() => {
|
|
11
|
+
* console.log('Function executed');
|
|
12
|
+
* }, 1000);
|
|
13
|
+
*
|
|
14
|
+
* // Will log 'Function executed' after 1 second if not called again in that time
|
|
15
|
+
* debouncedFunction();
|
|
16
|
+
*
|
|
17
|
+
* // Will not log anything as the previous call is canceled
|
|
18
|
+
* debouncedFunction.cancel();
|
|
19
|
+
*
|
|
20
|
+
* // With AbortSignal
|
|
21
|
+
* const controller = new AbortController();
|
|
22
|
+
* const signal = controller.signal;
|
|
23
|
+
* const debouncedWithSignal = debounce(() => {
|
|
24
|
+
* console.log('Function executed');
|
|
25
|
+
* }, 1000, { signal });
|
|
26
|
+
*
|
|
27
|
+
* debouncedWithSignal();
|
|
28
|
+
*
|
|
29
|
+
* // Will cancel the debounced function call
|
|
30
|
+
* controller.abort();
|
|
31
|
+
* ```
|
|
32
|
+
*
|
|
33
|
+
* @param func - The function to debounce.
|
|
34
|
+
* @param debounceMs - The number of milliseconds to delay.
|
|
35
|
+
* @param options - The options object.
|
|
36
|
+
* @returns A new debounced function with a `cancel` method.
|
|
37
|
+
*/
|
|
38
|
+
function debounce(func, debounceMs, { signal } = {}) {
|
|
39
|
+
let timeoutId = null;
|
|
40
|
+
const debounced = ((...args) => {
|
|
41
|
+
if (timeoutId !== null) clearTimeout(timeoutId);
|
|
42
|
+
if (signal?.aborted) return;
|
|
43
|
+
timeoutId = setTimeout(() => {
|
|
44
|
+
func(...args);
|
|
45
|
+
timeoutId = null;
|
|
46
|
+
}, debounceMs);
|
|
47
|
+
});
|
|
48
|
+
const onAbort = () => {
|
|
49
|
+
debounced.cancel();
|
|
50
|
+
};
|
|
51
|
+
debounced.cancel = () => {
|
|
52
|
+
if (timeoutId !== null) {
|
|
53
|
+
clearTimeout(timeoutId);
|
|
54
|
+
timeoutId = null;
|
|
55
|
+
}
|
|
56
|
+
};
|
|
57
|
+
signal?.addEventListener("abort", onAbort, { once: true });
|
|
58
|
+
return debounced;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
//#endregion
|
|
62
|
+
exports.debounce = debounce;
|
package/dist/debounce.mjs
CHANGED
|
@@ -1,2 +1,62 @@
|
|
|
1
|
-
|
|
1
|
+
//#region src/debounce.ts
|
|
2
|
+
/**
|
|
3
|
+
* Creates a debounced function that delays invoking the provided function until after `debounceMs` milliseconds
|
|
4
|
+
* have elapsed since the last time the debounced function was invoked. The debounced function also has a `cancel`
|
|
5
|
+
* method to cancel any pending execution.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```typescript
|
|
9
|
+
* const debouncedFunction = debounce(() => {
|
|
10
|
+
* console.log('Function executed');
|
|
11
|
+
* }, 1000);
|
|
12
|
+
*
|
|
13
|
+
* // Will log 'Function executed' after 1 second if not called again in that time
|
|
14
|
+
* debouncedFunction();
|
|
15
|
+
*
|
|
16
|
+
* // Will not log anything as the previous call is canceled
|
|
17
|
+
* debouncedFunction.cancel();
|
|
18
|
+
*
|
|
19
|
+
* // With AbortSignal
|
|
20
|
+
* const controller = new AbortController();
|
|
21
|
+
* const signal = controller.signal;
|
|
22
|
+
* const debouncedWithSignal = debounce(() => {
|
|
23
|
+
* console.log('Function executed');
|
|
24
|
+
* }, 1000, { signal });
|
|
25
|
+
*
|
|
26
|
+
* debouncedWithSignal();
|
|
27
|
+
*
|
|
28
|
+
* // Will cancel the debounced function call
|
|
29
|
+
* controller.abort();
|
|
30
|
+
* ```
|
|
31
|
+
*
|
|
32
|
+
* @param func - The function to debounce.
|
|
33
|
+
* @param debounceMs - The number of milliseconds to delay.
|
|
34
|
+
* @param options - The options object.
|
|
35
|
+
* @returns A new debounced function with a `cancel` method.
|
|
36
|
+
*/
|
|
37
|
+
function debounce(func, debounceMs, { signal } = {}) {
|
|
38
|
+
let timeoutId = null;
|
|
39
|
+
const debounced = ((...args) => {
|
|
40
|
+
if (timeoutId !== null) clearTimeout(timeoutId);
|
|
41
|
+
if (signal?.aborted) return;
|
|
42
|
+
timeoutId = setTimeout(() => {
|
|
43
|
+
func(...args);
|
|
44
|
+
timeoutId = null;
|
|
45
|
+
}, debounceMs);
|
|
46
|
+
});
|
|
47
|
+
const onAbort = () => {
|
|
48
|
+
debounced.cancel();
|
|
49
|
+
};
|
|
50
|
+
debounced.cancel = () => {
|
|
51
|
+
if (timeoutId !== null) {
|
|
52
|
+
clearTimeout(timeoutId);
|
|
53
|
+
timeoutId = null;
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
signal?.addEventListener("abort", onAbort, { once: true });
|
|
57
|
+
return debounced;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
//#endregion
|
|
61
|
+
export { debounce };
|
|
2
62
|
//# sourceMappingURL=debounce.mjs.map
|
package/dist/debounce.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"debounce.mjs","names":["timeoutId: ReturnType<typeof setTimeout> | null"],"sources":["../src/debounce.ts"],"sourcesContent":["/* -------------------------------------------------------------------\n\n ⚡ Storm Software - Stryke\n\n This code was released as part of the Stryke project. Stryke\n is maintained by Storm Software under the Apache-2.0 License, and is\n free for commercial and private use. For more information, please visit\n our licensing page.\n\n Website: https://stormsoftware.com\n Repository: https://github.com/storm-software/stryke\n Documentation: https://stormsoftware.com/projects/stryke/docs\n Contact: https://stormsoftware.com/contact\n License: https://stormsoftware.com/projects/stryke/license\n\n ------------------------------------------------------------------- */\n\nexport interface DebounceOptions {\n signal?: AbortSignal;\n}\n\n/**\n * Creates a debounced function that delays invoking the provided function until after `debounceMs` milliseconds\n * have elapsed since the last time the debounced function was invoked. The debounced function also has a `cancel`\n * method to cancel any pending execution.\n *\n * @example\n * ```typescript\n * const debouncedFunction = debounce(() => {\n * console.log('Function executed');\n * }, 1000);\n *\n * // Will log 'Function executed' after 1 second if not called again in that time\n * debouncedFunction();\n *\n * // Will not log anything as the previous call is canceled\n * debouncedFunction.cancel();\n *\n * // With AbortSignal\n * const controller = new AbortController();\n * const signal = controller.signal;\n * const debouncedWithSignal = debounce(() => {\n * console.log('Function executed');\n * }, 1000, { signal });\n *\n * debouncedWithSignal();\n *\n * // Will cancel the debounced function call\n * controller.abort();\n * ```\n *\n * @param func - The function to debounce.\n * @param debounceMs - The number of milliseconds to delay.\n * @param options - The options object.\n * @returns A new debounced function with a `cancel` method.\n */\nexport function debounce<F extends (...args: any[]) => void>(\n func: F,\n debounceMs: number,\n { signal }: DebounceOptions = {}\n): F & { cancel: () => void } {\n let timeoutId: ReturnType<typeof setTimeout> | null = null;\n\n const debounced = ((...args: Parameters<F>) => {\n if (timeoutId !== null) {\n clearTimeout(timeoutId);\n }\n\n if (signal?.aborted) {\n return;\n }\n\n timeoutId = setTimeout(() => {\n func(...args);\n timeoutId = null;\n }, debounceMs);\n }) as F & { cancel: () => void };\n\n const onAbort = () => {\n debounced.cancel();\n };\n\n debounced.cancel = () => {\n if (timeoutId !== null) {\n clearTimeout(timeoutId);\n timeoutId = null;\n }\n };\n\n signal?.addEventListener(\"abort\", onAbort, { once: true });\n\n return debounced;\n}\n"],"mappings":"AAwDA,SAAgB,
|
|
1
|
+
{"version":3,"file":"debounce.mjs","names":["timeoutId: ReturnType<typeof setTimeout> | null"],"sources":["../src/debounce.ts"],"sourcesContent":["/* -------------------------------------------------------------------\n\n ⚡ Storm Software - Stryke\n\n This code was released as part of the Stryke project. Stryke\n is maintained by Storm Software under the Apache-2.0 License, and is\n free for commercial and private use. For more information, please visit\n our licensing page.\n\n Website: https://stormsoftware.com\n Repository: https://github.com/storm-software/stryke\n Documentation: https://stormsoftware.com/projects/stryke/docs\n Contact: https://stormsoftware.com/contact\n License: https://stormsoftware.com/projects/stryke/license\n\n ------------------------------------------------------------------- */\n\nexport interface DebounceOptions {\n signal?: AbortSignal;\n}\n\n/**\n * Creates a debounced function that delays invoking the provided function until after `debounceMs` milliseconds\n * have elapsed since the last time the debounced function was invoked. The debounced function also has a `cancel`\n * method to cancel any pending execution.\n *\n * @example\n * ```typescript\n * const debouncedFunction = debounce(() => {\n * console.log('Function executed');\n * }, 1000);\n *\n * // Will log 'Function executed' after 1 second if not called again in that time\n * debouncedFunction();\n *\n * // Will not log anything as the previous call is canceled\n * debouncedFunction.cancel();\n *\n * // With AbortSignal\n * const controller = new AbortController();\n * const signal = controller.signal;\n * const debouncedWithSignal = debounce(() => {\n * console.log('Function executed');\n * }, 1000, { signal });\n *\n * debouncedWithSignal();\n *\n * // Will cancel the debounced function call\n * controller.abort();\n * ```\n *\n * @param func - The function to debounce.\n * @param debounceMs - The number of milliseconds to delay.\n * @param options - The options object.\n * @returns A new debounced function with a `cancel` method.\n */\nexport function debounce<F extends (...args: any[]) => void>(\n func: F,\n debounceMs: number,\n { signal }: DebounceOptions = {}\n): F & { cancel: () => void } {\n let timeoutId: ReturnType<typeof setTimeout> | null = null;\n\n const debounced = ((...args: Parameters<F>) => {\n if (timeoutId !== null) {\n clearTimeout(timeoutId);\n }\n\n if (signal?.aborted) {\n return;\n }\n\n timeoutId = setTimeout(() => {\n func(...args);\n timeoutId = null;\n }, debounceMs);\n }) as F & { cancel: () => void };\n\n const onAbort = () => {\n debounced.cancel();\n };\n\n debounced.cancel = () => {\n if (timeoutId !== null) {\n clearTimeout(timeoutId);\n timeoutId = null;\n }\n };\n\n signal?.addEventListener(\"abort\", onAbort, { once: true });\n\n return debounced;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAwDA,SAAgB,SACd,MACA,YACA,EAAE,WAA4B,EAAE,EACJ;CAC5B,IAAIA,YAAkD;CAEtD,MAAM,cAAc,GAAG,SAAwB;AAC7C,MAAI,cAAc,KAChB,cAAa,UAAU;AAGzB,MAAI,QAAQ,QACV;AAGF,cAAY,iBAAiB;AAC3B,QAAK,GAAG,KAAK;AACb,eAAY;KACX,WAAW;;CAGhB,MAAM,gBAAgB;AACpB,YAAU,QAAQ;;AAGpB,WAAU,eAAe;AACvB,MAAI,cAAc,MAAM;AACtB,gBAAa,UAAU;AACvB,eAAY;;;AAIhB,SAAQ,iBAAiB,SAAS,SAAS,EAAE,MAAM,MAAM,CAAC;AAE1D,QAAO"}
|
package/dist/deep-clone.cjs
CHANGED
|
@@ -1 +1,113 @@
|
|
|
1
|
-
const
|
|
1
|
+
const require_is_primitive = require('./type-checks/src/is-primitive.cjs');
|
|
2
|
+
const require_is_typed_array = require('./type-checks/src/is-typed-array.cjs');
|
|
3
|
+
|
|
4
|
+
//#region src/deep-clone.ts
|
|
5
|
+
/**
|
|
6
|
+
* Creates a deep clone of the given object.
|
|
7
|
+
*
|
|
8
|
+
* @remarks
|
|
9
|
+
* This function creates a deep clone of the given object, including nested objects and arrays. The resulting output will be of type `Resolved<T>`, which is a type that resolves to the most specific type possible for the given input type `T`. **If you are just looking for a way to copy an object deeply, use {@link deepCopy} instead.**
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```typescript
|
|
13
|
+
* // Clone a primitive values
|
|
14
|
+
* const num = 29;
|
|
15
|
+
* const clonedNum = clone(num);
|
|
16
|
+
* console.log(clonedNum); // 29
|
|
17
|
+
* console.log(clonedNum === num) ; // true
|
|
18
|
+
*
|
|
19
|
+
* // Clone an array
|
|
20
|
+
* const arr = [1, 2, 3];
|
|
21
|
+
* const clonedArr = clone(arr);
|
|
22
|
+
* console.log(clonedArr); // [1, 2, 3]
|
|
23
|
+
* console.log(clonedArr === arr); // false
|
|
24
|
+
*
|
|
25
|
+
* // Clone an array with nested objects
|
|
26
|
+
* const arr = [1, { a: 1 }, [1, 2, 3]];
|
|
27
|
+
* const clonedArr = clone(arr);
|
|
28
|
+
* arr[1].a = 2;
|
|
29
|
+
* console.log(arr); // [2, { a: 2 }, [1, 2, 3]]
|
|
30
|
+
* console.log(clonedArr); // [1, { a: 1 }, [1, 2, 3]]
|
|
31
|
+
* console.log(clonedArr === arr); // false
|
|
32
|
+
*
|
|
33
|
+
* // Clone an object
|
|
34
|
+
* const obj = { a: 1, b: 'es-toolkit', c: [1, 2, 3] };
|
|
35
|
+
* const clonedObj = clone(obj);
|
|
36
|
+
* console.log(clonedObj); // { a: 1, b: 'es-toolkit', c: [1, 2, 3] }
|
|
37
|
+
* console.log(clonedObj === obj); // false
|
|
38
|
+
*
|
|
39
|
+
*
|
|
40
|
+
* // Clone an object with nested objects
|
|
41
|
+
* const obj = { a: 1, b: { c: 1 } };
|
|
42
|
+
* const clonedObj = clone(obj);
|
|
43
|
+
* obj.b.c = 2;
|
|
44
|
+
* console.log(obj); // { a: 1, b: { c: 2 } }
|
|
45
|
+
* console.log(clonedObj); // { a: 1, b: { c: 1 } }
|
|
46
|
+
* console.log(clonedObj === obj); // false
|
|
47
|
+
* ```
|
|
48
|
+
*
|
|
49
|
+
* @param obj - The object to clone.
|
|
50
|
+
* @returns A deep clone of the given object.
|
|
51
|
+
*/
|
|
52
|
+
function deepClone(obj) {
|
|
53
|
+
if (require_is_primitive.isPrimitive(obj)) return obj;
|
|
54
|
+
if (Array.isArray(obj)) return obj.map((item) => deepClone(item));
|
|
55
|
+
if (obj instanceof Date) return new Date(obj.getTime());
|
|
56
|
+
if (obj instanceof RegExp) return new RegExp(obj.source, obj.flags);
|
|
57
|
+
if (obj instanceof Map) {
|
|
58
|
+
const result = /* @__PURE__ */ new Map();
|
|
59
|
+
for (const [key, value] of obj.entries()) result.set(key, deepClone(value));
|
|
60
|
+
return result;
|
|
61
|
+
}
|
|
62
|
+
if (obj instanceof Set) {
|
|
63
|
+
const result = /* @__PURE__ */ new Set();
|
|
64
|
+
for (const value of obj.values()) result.add(deepClone(value));
|
|
65
|
+
return result;
|
|
66
|
+
}
|
|
67
|
+
if (require_is_typed_array.isTypedArray(obj)) {
|
|
68
|
+
const result = new (Object.getPrototypeOf(obj)).constructor(obj.length);
|
|
69
|
+
for (const [i, element_] of obj.entries()) result[i] = deepClone(element_);
|
|
70
|
+
return result;
|
|
71
|
+
}
|
|
72
|
+
if (obj instanceof ArrayBuffer || typeof SharedArrayBuffer !== "undefined" && obj instanceof SharedArrayBuffer) return [...obj];
|
|
73
|
+
if (obj instanceof DataView) {
|
|
74
|
+
const result = new DataView([...obj.buffer]);
|
|
75
|
+
cloneDeepHelper(obj, result);
|
|
76
|
+
return result;
|
|
77
|
+
}
|
|
78
|
+
if (typeof File !== "undefined" && obj instanceof File) {
|
|
79
|
+
const result = new File([obj], obj.name, { type: obj.type });
|
|
80
|
+
cloneDeepHelper(obj, result);
|
|
81
|
+
return result;
|
|
82
|
+
}
|
|
83
|
+
if (obj instanceof Blob) {
|
|
84
|
+
const result = new Blob([obj], { type: obj.type });
|
|
85
|
+
cloneDeepHelper(obj, result);
|
|
86
|
+
return result;
|
|
87
|
+
}
|
|
88
|
+
if (obj instanceof Error) {
|
|
89
|
+
const result = new obj.constructor();
|
|
90
|
+
result.message = obj.message;
|
|
91
|
+
result.name = obj.name;
|
|
92
|
+
result.stack = obj.stack;
|
|
93
|
+
result.cause = obj.cause;
|
|
94
|
+
cloneDeepHelper(obj, result);
|
|
95
|
+
return result;
|
|
96
|
+
}
|
|
97
|
+
if (typeof obj === "object" && obj !== null) {
|
|
98
|
+
const result = {};
|
|
99
|
+
cloneDeepHelper(obj, result);
|
|
100
|
+
return result;
|
|
101
|
+
}
|
|
102
|
+
return obj;
|
|
103
|
+
}
|
|
104
|
+
function cloneDeepHelper(obj, clonedObj) {
|
|
105
|
+
const keys = Object.keys(obj);
|
|
106
|
+
for (const key of keys) {
|
|
107
|
+
const descriptor = Object.getOwnPropertyDescriptor(obj, key);
|
|
108
|
+
if (descriptor?.writable || descriptor?.set) clonedObj[key] = deepClone(obj[key]);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
//#endregion
|
|
113
|
+
exports.deepClone = deepClone;
|
package/dist/deep-clone.mjs
CHANGED
|
@@ -1,2 +1,114 @@
|
|
|
1
|
-
import{isPrimitive
|
|
1
|
+
import { isPrimitive } from "./type-checks/src/is-primitive.mjs";
|
|
2
|
+
import { isTypedArray } from "./type-checks/src/is-typed-array.mjs";
|
|
3
|
+
|
|
4
|
+
//#region src/deep-clone.ts
|
|
5
|
+
/**
|
|
6
|
+
* Creates a deep clone of the given object.
|
|
7
|
+
*
|
|
8
|
+
* @remarks
|
|
9
|
+
* This function creates a deep clone of the given object, including nested objects and arrays. The resulting output will be of type `Resolved<T>`, which is a type that resolves to the most specific type possible for the given input type `T`. **If you are just looking for a way to copy an object deeply, use {@link deepCopy} instead.**
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```typescript
|
|
13
|
+
* // Clone a primitive values
|
|
14
|
+
* const num = 29;
|
|
15
|
+
* const clonedNum = clone(num);
|
|
16
|
+
* console.log(clonedNum); // 29
|
|
17
|
+
* console.log(clonedNum === num) ; // true
|
|
18
|
+
*
|
|
19
|
+
* // Clone an array
|
|
20
|
+
* const arr = [1, 2, 3];
|
|
21
|
+
* const clonedArr = clone(arr);
|
|
22
|
+
* console.log(clonedArr); // [1, 2, 3]
|
|
23
|
+
* console.log(clonedArr === arr); // false
|
|
24
|
+
*
|
|
25
|
+
* // Clone an array with nested objects
|
|
26
|
+
* const arr = [1, { a: 1 }, [1, 2, 3]];
|
|
27
|
+
* const clonedArr = clone(arr);
|
|
28
|
+
* arr[1].a = 2;
|
|
29
|
+
* console.log(arr); // [2, { a: 2 }, [1, 2, 3]]
|
|
30
|
+
* console.log(clonedArr); // [1, { a: 1 }, [1, 2, 3]]
|
|
31
|
+
* console.log(clonedArr === arr); // false
|
|
32
|
+
*
|
|
33
|
+
* // Clone an object
|
|
34
|
+
* const obj = { a: 1, b: 'es-toolkit', c: [1, 2, 3] };
|
|
35
|
+
* const clonedObj = clone(obj);
|
|
36
|
+
* console.log(clonedObj); // { a: 1, b: 'es-toolkit', c: [1, 2, 3] }
|
|
37
|
+
* console.log(clonedObj === obj); // false
|
|
38
|
+
*
|
|
39
|
+
*
|
|
40
|
+
* // Clone an object with nested objects
|
|
41
|
+
* const obj = { a: 1, b: { c: 1 } };
|
|
42
|
+
* const clonedObj = clone(obj);
|
|
43
|
+
* obj.b.c = 2;
|
|
44
|
+
* console.log(obj); // { a: 1, b: { c: 2 } }
|
|
45
|
+
* console.log(clonedObj); // { a: 1, b: { c: 1 } }
|
|
46
|
+
* console.log(clonedObj === obj); // false
|
|
47
|
+
* ```
|
|
48
|
+
*
|
|
49
|
+
* @param obj - The object to clone.
|
|
50
|
+
* @returns A deep clone of the given object.
|
|
51
|
+
*/
|
|
52
|
+
function deepClone(obj) {
|
|
53
|
+
if (isPrimitive(obj)) return obj;
|
|
54
|
+
if (Array.isArray(obj)) return obj.map((item) => deepClone(item));
|
|
55
|
+
if (obj instanceof Date) return new Date(obj.getTime());
|
|
56
|
+
if (obj instanceof RegExp) return new RegExp(obj.source, obj.flags);
|
|
57
|
+
if (obj instanceof Map) {
|
|
58
|
+
const result = /* @__PURE__ */ new Map();
|
|
59
|
+
for (const [key, value] of obj.entries()) result.set(key, deepClone(value));
|
|
60
|
+
return result;
|
|
61
|
+
}
|
|
62
|
+
if (obj instanceof Set) {
|
|
63
|
+
const result = /* @__PURE__ */ new Set();
|
|
64
|
+
for (const value of obj.values()) result.add(deepClone(value));
|
|
65
|
+
return result;
|
|
66
|
+
}
|
|
67
|
+
if (isTypedArray(obj)) {
|
|
68
|
+
const result = new (Object.getPrototypeOf(obj)).constructor(obj.length);
|
|
69
|
+
for (const [i, element_] of obj.entries()) result[i] = deepClone(element_);
|
|
70
|
+
return result;
|
|
71
|
+
}
|
|
72
|
+
if (obj instanceof ArrayBuffer || typeof SharedArrayBuffer !== "undefined" && obj instanceof SharedArrayBuffer) return [...obj];
|
|
73
|
+
if (obj instanceof DataView) {
|
|
74
|
+
const result = new DataView([...obj.buffer]);
|
|
75
|
+
cloneDeepHelper(obj, result);
|
|
76
|
+
return result;
|
|
77
|
+
}
|
|
78
|
+
if (typeof File !== "undefined" && obj instanceof File) {
|
|
79
|
+
const result = new File([obj], obj.name, { type: obj.type });
|
|
80
|
+
cloneDeepHelper(obj, result);
|
|
81
|
+
return result;
|
|
82
|
+
}
|
|
83
|
+
if (obj instanceof Blob) {
|
|
84
|
+
const result = new Blob([obj], { type: obj.type });
|
|
85
|
+
cloneDeepHelper(obj, result);
|
|
86
|
+
return result;
|
|
87
|
+
}
|
|
88
|
+
if (obj instanceof Error) {
|
|
89
|
+
const result = new obj.constructor();
|
|
90
|
+
result.message = obj.message;
|
|
91
|
+
result.name = obj.name;
|
|
92
|
+
result.stack = obj.stack;
|
|
93
|
+
result.cause = obj.cause;
|
|
94
|
+
cloneDeepHelper(obj, result);
|
|
95
|
+
return result;
|
|
96
|
+
}
|
|
97
|
+
if (typeof obj === "object" && obj !== null) {
|
|
98
|
+
const result = {};
|
|
99
|
+
cloneDeepHelper(obj, result);
|
|
100
|
+
return result;
|
|
101
|
+
}
|
|
102
|
+
return obj;
|
|
103
|
+
}
|
|
104
|
+
function cloneDeepHelper(obj, clonedObj) {
|
|
105
|
+
const keys = Object.keys(obj);
|
|
106
|
+
for (const key of keys) {
|
|
107
|
+
const descriptor = Object.getOwnPropertyDescriptor(obj, key);
|
|
108
|
+
if (descriptor?.writable || descriptor?.set) clonedObj[key] = deepClone(obj[key]);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
//#endregion
|
|
113
|
+
export { deepClone };
|
|
2
114
|
//# sourceMappingURL=deep-clone.mjs.map
|
package/dist/deep-clone.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"deep-clone.mjs","names":[],"sources":["../src/deep-clone.ts"],"sourcesContent":["/* -------------------------------------------------------------------\n\n ⚡ Storm Software - Stryke\n\n This code was released as part of the Stryke project. Stryke\n is maintained by Storm Software under the Apache-2.0 license, and is\n free for commercial and private use. For more information, please visit\n our licensing page at https://stormsoftware.com/licenses/projects/stryke.\n\n Website: https://stormsoftware.com\n Repository: https://github.com/storm-software/stryke\n Documentation: https://docs.stormsoftware.com/projects/stryke\n Contact: https://stormsoftware.com/contact\n\n SPDX-License-Identifier: Apache-2.0\n\n ------------------------------------------------------------------- */\n\nimport { isPrimitive } from \"@stryke/type-checks/is-primitive\";\nimport { isTypedArray } from \"@stryke/type-checks/is-typed-array\";\n\nexport type Resolved<T> =\n Equal<T, ResolvedMain<T>> extends true ? T : ResolvedMain<T>;\n\ntype Equal<X, Y> = X extends Y ? (Y extends X ? true : false) : false;\n\ntype ResolvedMain<T> = T extends [never]\n ? never // (special trick for jsonable | null) type\n : ValueOf<T> extends boolean | number | bigint | string\n ? ValueOf<T>\n : T extends (...args: any[]) => any\n ? never\n : T extends object\n ? ResolvedObject<T>\n : ValueOf<T>;\n\ntype ResolvedObject<T extends object> = T extends (infer U)[]\n ? IsTuple<T> extends true\n ? ResolvedTuple<T>\n : ResolvedMain<U>[]\n : T extends Set<infer U>\n ? Set<ResolvedMain<U>>\n : T extends Map<infer K, infer V>\n ? Map<ResolvedMain<K>, ResolvedMain<V>>\n : T extends WeakSet<any> | WeakMap<any, any>\n ? never\n : T extends\n | Date\n | Uint8Array\n | Uint8ClampedArray\n | Uint16Array\n | Uint32Array\n | BigUint64Array\n | Int8Array\n | Int16Array\n | Int32Array\n | BigInt64Array\n | Float32Array\n | Float64Array\n | ArrayBuffer\n | SharedArrayBuffer\n | DataView\n | Blob\n | File\n ? T\n : {\n [P in keyof T]: ResolvedMain<T[P]>;\n };\n\ntype ResolvedTuple<T extends readonly any[]> = T extends []\n ? []\n : T extends [infer F]\n ? [ResolvedMain<F>]\n : T extends [infer F, ...infer Rest extends readonly any[]]\n ? [ResolvedMain<F>, ...ResolvedTuple<Rest>]\n : T extends [(infer F)?]\n ? [ResolvedMain<F>?]\n : T extends [(infer F)?, ...infer Rest extends readonly any[]]\n ? [ResolvedMain<F>?, ...ResolvedTuple<Rest>]\n : [];\n\ntype IsTuple<T extends readonly any[] | { length: number }> = [T] extends [\n never\n]\n ? false\n : T extends readonly any[]\n ? number extends T[\"length\"]\n ? false\n : true\n : false;\n\ntype ValueOf<Instance> =\n IsValueOf<Instance, boolean> extends true\n ? boolean\n : IsValueOf<Instance, number> extends true\n ? number\n : IsValueOf<Instance, string> extends true\n ? string\n : Instance;\n\ntype IsValueOf<Instance, O extends ValueOfInterface<any>> = Instance extends O\n ? O extends ValueOfInterface<infer Primitive>\n ? Instance extends Primitive\n ? false\n : true // not Primitive, but Object\n : false // cannot be\n : false;\n\ninterface ValueOfInterface<T> {\n valueOf: () => T;\n}\n\n/**\n * Creates a deep clone of the given object.\n *\n * @remarks\n * This function creates a deep clone of the given object, including nested objects and arrays. The resulting output will be of type `Resolved<T>`, which is a type that resolves to the most specific type possible for the given input type `T`. **If you are just looking for a way to copy an object deeply, use {@link deepCopy} instead.**\n *\n * @example\n * ```typescript\n * // Clone a primitive values\n * const num = 29;\n * const clonedNum = clone(num);\n * console.log(clonedNum); // 29\n * console.log(clonedNum === num) ; // true\n *\n * // Clone an array\n * const arr = [1, 2, 3];\n * const clonedArr = clone(arr);\n * console.log(clonedArr); // [1, 2, 3]\n * console.log(clonedArr === arr); // false\n *\n * // Clone an array with nested objects\n * const arr = [1, { a: 1 }, [1, 2, 3]];\n * const clonedArr = clone(arr);\n * arr[1].a = 2;\n * console.log(arr); // [2, { a: 2 }, [1, 2, 3]]\n * console.log(clonedArr); // [1, { a: 1 }, [1, 2, 3]]\n * console.log(clonedArr === arr); // false\n *\n * // Clone an object\n * const obj = { a: 1, b: 'es-toolkit', c: [1, 2, 3] };\n * const clonedObj = clone(obj);\n * console.log(clonedObj); // { a: 1, b: 'es-toolkit', c: [1, 2, 3] }\n * console.log(clonedObj === obj); // false\n *\n *\n * // Clone an object with nested objects\n * const obj = { a: 1, b: { c: 1 } };\n * const clonedObj = clone(obj);\n * obj.b.c = 2;\n * console.log(obj); // { a: 1, b: { c: 2 } }\n * console.log(clonedObj); // { a: 1, b: { c: 1 } }\n * console.log(clonedObj === obj); // false\n * ```\n *\n * @param obj - The object to clone.\n * @returns A deep clone of the given object.\n */\nexport function deepClone<T>(obj: T): Resolved<T> {\n if (isPrimitive(obj)) {\n return obj as Resolved<T>;\n }\n\n if (Array.isArray(obj)) {\n return obj.map(item => deepClone(item)) as Resolved<T>;\n }\n\n if (obj instanceof Date) {\n return new Date(obj.getTime()) as Resolved<T>;\n }\n\n if (obj instanceof RegExp) {\n return new RegExp(obj.source, obj.flags) as Resolved<T>;\n }\n\n if (obj instanceof Map) {\n const result = new Map();\n for (const [key, value] of obj.entries()) {\n result.set(key, deepClone(value));\n }\n return result as Resolved<T>;\n }\n\n if (obj instanceof Set) {\n const result = new Set();\n for (const value of obj.values()) {\n result.add(deepClone(value));\n }\n return result as Resolved<T>;\n }\n\n if (isTypedArray(obj)) {\n // eslint-disable-next-line ts/no-unsafe-call\n const result = new (Object.getPrototypeOf(obj).constructor)(obj.length);\n // eslint-disable-next-line ts/naming-convention\n for (const [i, element_] of obj.entries()) {\n result[i] = deepClone(element_);\n }\n return result as Resolved<T>;\n }\n\n if (\n obj instanceof ArrayBuffer ||\n (typeof SharedArrayBuffer !== \"undefined\" &&\n obj instanceof SharedArrayBuffer)\n ) {\n return [...(obj as any)] as Resolved<T>;\n }\n\n if (obj instanceof DataView) {\n const result = new DataView([...(obj.buffer as any)] as any);\n cloneDeepHelper(obj, result);\n return result as Resolved<T>;\n }\n\n // For legacy NodeJS support\n if (typeof File !== \"undefined\" && obj instanceof File) {\n const result = new File([obj], obj.name, { type: obj.type });\n cloneDeepHelper(obj, result);\n return result as Resolved<T>;\n }\n\n if (obj instanceof Blob) {\n const result = new Blob([obj], { type: obj.type });\n cloneDeepHelper(obj, result);\n return result as Resolved<T>;\n }\n\n if (obj instanceof Error) {\n const result = new (obj.constructor as new () => Error)();\n result.message = obj.message;\n result.name = obj.name;\n result.stack = obj.stack;\n result.cause = obj.cause;\n cloneDeepHelper(obj, result);\n return result as Resolved<T>;\n }\n\n if (typeof obj === \"object\" && obj !== null) {\n const result = {};\n cloneDeepHelper(obj, result);\n return result as Resolved<T>;\n }\n\n return obj as Resolved<T>;\n}\n\nfunction cloneDeepHelper(obj: any, clonedObj: any): void {\n const keys = Object.keys(obj);\n\n for (const key of keys) {\n const descriptor = Object.getOwnPropertyDescriptor(obj, key);\n\n if (descriptor?.writable || descriptor?.set) {\n clonedObj[key] = deepClone(obj[key]);\n }\n }\n}\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"deep-clone.mjs","names":[],"sources":["../src/deep-clone.ts"],"sourcesContent":["/* -------------------------------------------------------------------\n\n ⚡ Storm Software - Stryke\n\n This code was released as part of the Stryke project. Stryke\n is maintained by Storm Software under the Apache-2.0 license, and is\n free for commercial and private use. For more information, please visit\n our licensing page at https://stormsoftware.com/licenses/projects/stryke.\n\n Website: https://stormsoftware.com\n Repository: https://github.com/storm-software/stryke\n Documentation: https://docs.stormsoftware.com/projects/stryke\n Contact: https://stormsoftware.com/contact\n\n SPDX-License-Identifier: Apache-2.0\n\n ------------------------------------------------------------------- */\n\nimport { isPrimitive } from \"@stryke/type-checks/is-primitive\";\nimport { isTypedArray } from \"@stryke/type-checks/is-typed-array\";\n\nexport type Resolved<T> =\n Equal<T, ResolvedMain<T>> extends true ? T : ResolvedMain<T>;\n\ntype Equal<X, Y> = X extends Y ? (Y extends X ? true : false) : false;\n\ntype ResolvedMain<T> = T extends [never]\n ? never // (special trick for jsonable | null) type\n : ValueOf<T> extends boolean | number | bigint | string\n ? ValueOf<T>\n : T extends (...args: any[]) => any\n ? never\n : T extends object\n ? ResolvedObject<T>\n : ValueOf<T>;\n\ntype ResolvedObject<T extends object> = T extends (infer U)[]\n ? IsTuple<T> extends true\n ? ResolvedTuple<T>\n : ResolvedMain<U>[]\n : T extends Set<infer U>\n ? Set<ResolvedMain<U>>\n : T extends Map<infer K, infer V>\n ? Map<ResolvedMain<K>, ResolvedMain<V>>\n : T extends WeakSet<any> | WeakMap<any, any>\n ? never\n : T extends\n | Date\n | Uint8Array\n | Uint8ClampedArray\n | Uint16Array\n | Uint32Array\n | BigUint64Array\n | Int8Array\n | Int16Array\n | Int32Array\n | BigInt64Array\n | Float32Array\n | Float64Array\n | ArrayBuffer\n | SharedArrayBuffer\n | DataView\n | Blob\n | File\n ? T\n : {\n [P in keyof T]: ResolvedMain<T[P]>;\n };\n\ntype ResolvedTuple<T extends readonly any[]> = T extends []\n ? []\n : T extends [infer F]\n ? [ResolvedMain<F>]\n : T extends [infer F, ...infer Rest extends readonly any[]]\n ? [ResolvedMain<F>, ...ResolvedTuple<Rest>]\n : T extends [(infer F)?]\n ? [ResolvedMain<F>?]\n : T extends [(infer F)?, ...infer Rest extends readonly any[]]\n ? [ResolvedMain<F>?, ...ResolvedTuple<Rest>]\n : [];\n\ntype IsTuple<T extends readonly any[] | { length: number }> = [T] extends [\n never\n]\n ? false\n : T extends readonly any[]\n ? number extends T[\"length\"]\n ? false\n : true\n : false;\n\ntype ValueOf<Instance> =\n IsValueOf<Instance, boolean> extends true\n ? boolean\n : IsValueOf<Instance, number> extends true\n ? number\n : IsValueOf<Instance, string> extends true\n ? string\n : Instance;\n\ntype IsValueOf<Instance, O extends ValueOfInterface<any>> = Instance extends O\n ? O extends ValueOfInterface<infer Primitive>\n ? Instance extends Primitive\n ? false\n : true // not Primitive, but Object\n : false // cannot be\n : false;\n\ninterface ValueOfInterface<T> {\n valueOf: () => T;\n}\n\n/**\n * Creates a deep clone of the given object.\n *\n * @remarks\n * This function creates a deep clone of the given object, including nested objects and arrays. The resulting output will be of type `Resolved<T>`, which is a type that resolves to the most specific type possible for the given input type `T`. **If you are just looking for a way to copy an object deeply, use {@link deepCopy} instead.**\n *\n * @example\n * ```typescript\n * // Clone a primitive values\n * const num = 29;\n * const clonedNum = clone(num);\n * console.log(clonedNum); // 29\n * console.log(clonedNum === num) ; // true\n *\n * // Clone an array\n * const arr = [1, 2, 3];\n * const clonedArr = clone(arr);\n * console.log(clonedArr); // [1, 2, 3]\n * console.log(clonedArr === arr); // false\n *\n * // Clone an array with nested objects\n * const arr = [1, { a: 1 }, [1, 2, 3]];\n * const clonedArr = clone(arr);\n * arr[1].a = 2;\n * console.log(arr); // [2, { a: 2 }, [1, 2, 3]]\n * console.log(clonedArr); // [1, { a: 1 }, [1, 2, 3]]\n * console.log(clonedArr === arr); // false\n *\n * // Clone an object\n * const obj = { a: 1, b: 'es-toolkit', c: [1, 2, 3] };\n * const clonedObj = clone(obj);\n * console.log(clonedObj); // { a: 1, b: 'es-toolkit', c: [1, 2, 3] }\n * console.log(clonedObj === obj); // false\n *\n *\n * // Clone an object with nested objects\n * const obj = { a: 1, b: { c: 1 } };\n * const clonedObj = clone(obj);\n * obj.b.c = 2;\n * console.log(obj); // { a: 1, b: { c: 2 } }\n * console.log(clonedObj); // { a: 1, b: { c: 1 } }\n * console.log(clonedObj === obj); // false\n * ```\n *\n * @param obj - The object to clone.\n * @returns A deep clone of the given object.\n */\nexport function deepClone<T>(obj: T): Resolved<T> {\n if (isPrimitive(obj)) {\n return obj as Resolved<T>;\n }\n\n if (Array.isArray(obj)) {\n return obj.map(item => deepClone(item)) as Resolved<T>;\n }\n\n if (obj instanceof Date) {\n return new Date(obj.getTime()) as Resolved<T>;\n }\n\n if (obj instanceof RegExp) {\n return new RegExp(obj.source, obj.flags) as Resolved<T>;\n }\n\n if (obj instanceof Map) {\n const result = new Map();\n for (const [key, value] of obj.entries()) {\n result.set(key, deepClone(value));\n }\n return result as Resolved<T>;\n }\n\n if (obj instanceof Set) {\n const result = new Set();\n for (const value of obj.values()) {\n result.add(deepClone(value));\n }\n return result as Resolved<T>;\n }\n\n if (isTypedArray(obj)) {\n // eslint-disable-next-line ts/no-unsafe-call\n const result = new (Object.getPrototypeOf(obj).constructor)(obj.length);\n // eslint-disable-next-line ts/naming-convention\n for (const [i, element_] of obj.entries()) {\n result[i] = deepClone(element_);\n }\n return result as Resolved<T>;\n }\n\n if (\n obj instanceof ArrayBuffer ||\n (typeof SharedArrayBuffer !== \"undefined\" &&\n obj instanceof SharedArrayBuffer)\n ) {\n return [...(obj as any)] as Resolved<T>;\n }\n\n if (obj instanceof DataView) {\n const result = new DataView([...(obj.buffer as any)] as any);\n cloneDeepHelper(obj, result);\n return result as Resolved<T>;\n }\n\n // For legacy NodeJS support\n if (typeof File !== \"undefined\" && obj instanceof File) {\n const result = new File([obj], obj.name, { type: obj.type });\n cloneDeepHelper(obj, result);\n return result as Resolved<T>;\n }\n\n if (obj instanceof Blob) {\n const result = new Blob([obj], { type: obj.type });\n cloneDeepHelper(obj, result);\n return result as Resolved<T>;\n }\n\n if (obj instanceof Error) {\n const result = new (obj.constructor as new () => Error)();\n result.message = obj.message;\n result.name = obj.name;\n result.stack = obj.stack;\n result.cause = obj.cause;\n cloneDeepHelper(obj, result);\n return result as Resolved<T>;\n }\n\n if (typeof obj === \"object\" && obj !== null) {\n const result = {};\n cloneDeepHelper(obj, result);\n return result as Resolved<T>;\n }\n\n return obj as Resolved<T>;\n}\n\nfunction cloneDeepHelper(obj: any, clonedObj: any): void {\n const keys = Object.keys(obj);\n\n for (const key of keys) {\n const descriptor = Object.getOwnPropertyDescriptor(obj, key);\n\n if (descriptor?.writable || descriptor?.set) {\n clonedObj[key] = deepClone(obj[key]);\n }\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA+JA,SAAgB,UAAa,KAAqB;AAChD,KAAI,YAAY,IAAI,CAClB,QAAO;AAGT,KAAI,MAAM,QAAQ,IAAI,CACpB,QAAO,IAAI,KAAI,SAAQ,UAAU,KAAK,CAAC;AAGzC,KAAI,eAAe,KACjB,QAAO,IAAI,KAAK,IAAI,SAAS,CAAC;AAGhC,KAAI,eAAe,OACjB,QAAO,IAAI,OAAO,IAAI,QAAQ,IAAI,MAAM;AAG1C,KAAI,eAAe,KAAK;EACtB,MAAM,yBAAS,IAAI,KAAK;AACxB,OAAK,MAAM,CAAC,KAAK,UAAU,IAAI,SAAS,CACtC,QAAO,IAAI,KAAK,UAAU,MAAM,CAAC;AAEnC,SAAO;;AAGT,KAAI,eAAe,KAAK;EACtB,MAAM,yBAAS,IAAI,KAAK;AACxB,OAAK,MAAM,SAAS,IAAI,QAAQ,CAC9B,QAAO,IAAI,UAAU,MAAM,CAAC;AAE9B,SAAO;;AAGT,KAAI,aAAa,IAAI,EAAE;EAErB,MAAM,SAAS,KAAK,OAAO,eAAe,IAAI,EAAC,YAAa,IAAI,OAAO;AAEvE,OAAK,MAAM,CAAC,GAAG,aAAa,IAAI,SAAS,CACvC,QAAO,KAAK,UAAU,SAAS;AAEjC,SAAO;;AAGT,KACE,eAAe,eACd,OAAO,sBAAsB,eAC5B,eAAe,kBAEjB,QAAO,CAAC,GAAI,IAAY;AAG1B,KAAI,eAAe,UAAU;EAC3B,MAAM,SAAS,IAAI,SAAS,CAAC,GAAI,IAAI,OAAe,CAAQ;AAC5D,kBAAgB,KAAK,OAAO;AAC5B,SAAO;;AAIT,KAAI,OAAO,SAAS,eAAe,eAAe,MAAM;EACtD,MAAM,SAAS,IAAI,KAAK,CAAC,IAAI,EAAE,IAAI,MAAM,EAAE,MAAM,IAAI,MAAM,CAAC;AAC5D,kBAAgB,KAAK,OAAO;AAC5B,SAAO;;AAGT,KAAI,eAAe,MAAM;EACvB,MAAM,SAAS,IAAI,KAAK,CAAC,IAAI,EAAE,EAAE,MAAM,IAAI,MAAM,CAAC;AAClD,kBAAgB,KAAK,OAAO;AAC5B,SAAO;;AAGT,KAAI,eAAe,OAAO;EACxB,MAAM,SAAS,IAAK,IAAI,aAAiC;AACzD,SAAO,UAAU,IAAI;AACrB,SAAO,OAAO,IAAI;AAClB,SAAO,QAAQ,IAAI;AACnB,SAAO,QAAQ,IAAI;AACnB,kBAAgB,KAAK,OAAO;AAC5B,SAAO;;AAGT,KAAI,OAAO,QAAQ,YAAY,QAAQ,MAAM;EAC3C,MAAM,SAAS,EAAE;AACjB,kBAAgB,KAAK,OAAO;AAC5B,SAAO;;AAGT,QAAO;;AAGT,SAAS,gBAAgB,KAAU,WAAsB;CACvD,MAAM,OAAO,OAAO,KAAK,IAAI;AAE7B,MAAK,MAAM,OAAO,MAAM;EACtB,MAAM,aAAa,OAAO,yBAAyB,KAAK,IAAI;AAE5D,MAAI,YAAY,YAAY,YAAY,IACtC,WAAU,OAAO,UAAU,IAAI,KAAK"}
|
package/dist/deep-merge.cjs
CHANGED
|
@@ -1 +1,60 @@
|
|
|
1
|
-
const
|
|
1
|
+
const require_is_function = require('./type-checks/src/is-function.cjs');
|
|
2
|
+
const require_is_mergeable_object = require('./type-checks/src/is-mergeable-object.cjs');
|
|
3
|
+
const require_property_exists = require('./type-checks/src/property-exists.cjs');
|
|
4
|
+
|
|
5
|
+
//#region src/deep-merge.ts
|
|
6
|
+
const emptyTarget = (val) => {
|
|
7
|
+
return Array.isArray(val) ? [] : {};
|
|
8
|
+
};
|
|
9
|
+
const cloneUnlessOtherwiseSpecified = (value, options) => {
|
|
10
|
+
return options.clone !== false && options.isMergeableObject(value) ? deepMerge(emptyTarget(value), value, options) : value;
|
|
11
|
+
};
|
|
12
|
+
const defaultArrayMerge = (target, source, options) => {
|
|
13
|
+
return [...target, ...source].map((element) => {
|
|
14
|
+
return cloneUnlessOtherwiseSpecified(element, options);
|
|
15
|
+
});
|
|
16
|
+
};
|
|
17
|
+
const getMergeFunction = (key, options) => {
|
|
18
|
+
if (!options.customMerge) return deepMerge;
|
|
19
|
+
const customMerge = options.customMerge(key);
|
|
20
|
+
return require_is_function.isFunction(customMerge) ? customMerge : deepMerge;
|
|
21
|
+
};
|
|
22
|
+
const getKeys = (target) => {
|
|
23
|
+
return [...Object.keys(target), ...Object.getOwnPropertySymbols ? Object.getOwnPropertySymbols(target).filter((symbol) => {
|
|
24
|
+
return Object.propertyIsEnumerable.call(target, symbol);
|
|
25
|
+
}) : []];
|
|
26
|
+
};
|
|
27
|
+
const mergeObject = (target, source, options) => {
|
|
28
|
+
const destination = {};
|
|
29
|
+
if (options.isMergeableObject(target)) for (const key of getKeys(target)) destination[key] = cloneUnlessOtherwiseSpecified(target[key], options);
|
|
30
|
+
for (const key of getKeys(source)) destination[key] = require_property_exists.propertyUnsafe(target, key) && options.isMergeableObject(source[key]) ? getMergeFunction(key, options)(target[key], source[key], options) : cloneUnlessOtherwiseSpecified(source[key], options);
|
|
31
|
+
return destination;
|
|
32
|
+
};
|
|
33
|
+
/**
|
|
34
|
+
* Deep merge two objects
|
|
35
|
+
*
|
|
36
|
+
* @param target - The target object
|
|
37
|
+
* @param source - The source object
|
|
38
|
+
* @param options - The options object
|
|
39
|
+
* @returns The merged object
|
|
40
|
+
*/
|
|
41
|
+
function deepMerge(target, source, options) {
|
|
42
|
+
if (!target || !source) return target || source;
|
|
43
|
+
const opts = options ?? {};
|
|
44
|
+
opts.arrayMerge ??= defaultArrayMerge;
|
|
45
|
+
opts.isMergeableObject ??= require_is_mergeable_object.isMergeableObject;
|
|
46
|
+
opts.cloneUnlessOtherwiseSpecified ??= cloneUnlessOtherwiseSpecified;
|
|
47
|
+
const sourceIsArray = Array.isArray(source);
|
|
48
|
+
if (!(sourceIsArray === Array.isArray(target))) return cloneUnlessOtherwiseSpecified(source, opts);
|
|
49
|
+
if (sourceIsArray) return opts.arrayMerge(target, source, opts);
|
|
50
|
+
return mergeObject(target, source, opts);
|
|
51
|
+
}
|
|
52
|
+
deepMerge.all = function deepMergeAll(array, options) {
|
|
53
|
+
if (!Array.isArray(array)) throw new TypeError("first argument should be an array");
|
|
54
|
+
return array.reduce((prev, next) => {
|
|
55
|
+
return deepMerge(prev, next, options);
|
|
56
|
+
}, {});
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
//#endregion
|
|
60
|
+
exports.deepMerge = deepMerge;
|