@cognite/underscore 1.0.1 → 1.48535.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.
Files changed (95) hide show
  1. package/README.md +2 -0
  2. package/dist/arrays.d.ts +31 -31
  3. package/dist/arrays.js +53 -18
  4. package/dist/arrays.js.map +1 -0
  5. package/dist/assert.d.ts +6 -6
  6. package/dist/assert.js +12 -5
  7. package/dist/assert.js.map +1 -0
  8. package/dist/brand.d.ts +41 -38
  9. package/dist/brand.js +39 -0
  10. package/dist/brand.js.map +1 -0
  11. package/dist/chunk-and-process-in-parallel.d.ts +112 -106
  12. package/dist/chunk-and-process-in-parallel.js +138 -29
  13. package/dist/chunk-and-process-in-parallel.js.map +1 -0
  14. package/dist/chunk-array.d.ts +25 -25
  15. package/dist/chunk-array.js +34 -6
  16. package/dist/chunk-array.js.map +1 -0
  17. package/dist/class.d.ts +8 -8
  18. package/dist/class.js +11 -5
  19. package/dist/class.js.map +1 -0
  20. package/dist/exhaustive-guard.d.ts +15 -15
  21. package/dist/exhaustive-guard.js +19 -5
  22. package/dist/exhaustive-guard.js.map +1 -0
  23. package/dist/exponential-backoff-with-jitter.d.ts +13 -13
  24. package/dist/exponential-backoff-with-jitter.js +23 -7
  25. package/dist/exponential-backoff-with-jitter.js.map +1 -0
  26. package/dist/generate-unique-name.d.ts +17 -17
  27. package/dist/generate-unique-name.js +46 -10
  28. package/dist/generate-unique-name.js.map +1 -0
  29. package/dist/get-numbers-between.d.ts +15 -15
  30. package/dist/get-numbers-between.js +21 -5
  31. package/dist/get-numbers-between.js.map +1 -0
  32. package/dist/humanize-value.d.ts +3 -3
  33. package/dist/humanize-value.js +33 -15
  34. package/dist/humanize-value.js.map +1 -0
  35. package/dist/index.d.ts +23 -23
  36. package/dist/index.js +23 -23
  37. package/dist/index.js.map +1 -0
  38. package/dist/is-function.d.ts +5 -5
  39. package/dist/is-function.js +9 -5
  40. package/dist/is-function.js.map +1 -0
  41. package/dist/is-primitive.d.ts +7 -7
  42. package/dist/is-primitive.js +16 -6
  43. package/dist/is-primitive.js.map +1 -0
  44. package/dist/is-valid-url.d.ts +11 -14
  45. package/dist/is-valid-url.js +39 -16
  46. package/dist/is-valid-url.js.map +1 -0
  47. package/dist/iterators.d.ts +7 -7
  48. package/dist/iterators.js +16 -6
  49. package/dist/iterators.js.map +1 -0
  50. package/dist/math.d.ts +10 -10
  51. package/dist/math.js +16 -7
  52. package/dist/math.js.map +1 -0
  53. package/dist/random.d.ts +24 -24
  54. package/dist/random.js +52 -18
  55. package/dist/random.js.map +1 -0
  56. package/dist/react/use-debounce.d.ts +21 -21
  57. package/dist/react/use-debounce.js +39 -14
  58. package/dist/react/use-debounce.js.map +1 -0
  59. package/dist/react/use-derived-promise.d.ts +28 -29
  60. package/dist/react/use-derived-promise.js +70 -33
  61. package/dist/react/use-derived-promise.js.map +1 -0
  62. package/dist/react/use-stable-sync-external-store.d.ts +25 -25
  63. package/dist/react/use-stable-sync-external-store.js +52 -11
  64. package/dist/react/use-stable-sync-external-store.js.map +1 -0
  65. package/dist/react.d.ts +3 -3
  66. package/dist/react.js +5 -4
  67. package/dist/react.js.map +1 -0
  68. package/dist/repeat.d.ts +5 -5
  69. package/dist/repeat.js +11 -5
  70. package/dist/repeat.js.map +1 -0
  71. package/dist/retry-async.d.ts +87 -87
  72. package/dist/retry-async.js +88 -17
  73. package/dist/retry-async.js.map +1 -0
  74. package/dist/sleep.d.ts +5 -5
  75. package/dist/sleep.js +9 -5
  76. package/dist/sleep.js.map +1 -0
  77. package/dist/string.d.ts +35 -35
  78. package/dist/string.js +48 -9
  79. package/dist/string.js.map +1 -0
  80. package/dist/structMap/index.d.ts +3 -3
  81. package/dist/structMap/index.js +4 -0
  82. package/dist/structMap/index.js.map +1 -0
  83. package/dist/structMap/stableStringify.d.ts +21 -21
  84. package/dist/structMap/stableStringify.js +69 -22
  85. package/dist/structMap/stableStringify.js.map +1 -0
  86. package/dist/structMap/structMap.d.ts +111 -108
  87. package/dist/structMap/structMap.js +131 -28
  88. package/dist/structMap/structMap.js.map +1 -0
  89. package/dist/structMap/testUtils.d.ts +8 -8
  90. package/dist/structMap/testUtils.js +26 -0
  91. package/dist/structMap/testUtils.js.map +1 -0
  92. package/dist/structMap/types.d.ts +4 -4
  93. package/dist/structMap/types.js +5 -0
  94. package/dist/structMap/types.js.map +1 -0
  95. package/package.json +7 -4
package/dist/random.js CHANGED
@@ -1,22 +1,56 @@
1
- import { repeat as e } from "./repeat.js";
2
- //#region libs/shared/underscore/src/random.ts
3
- function t(t) {
4
- if (t < 1) throw Error("Length must be greater than 0");
5
- let r = [..."ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"], i = "";
6
- return e(() => {
7
- i += n(r);
8
- }, t), i;
1
+ import { repeat } from "./repeat.js";
2
+ /**
3
+ * Generates a random string of the specified length using alphanumeric characters.
4
+ *
5
+ * @param {number} length - The length of the random string to generate. Must be greater than 0.
6
+ * @returns {string} A random string of the specified length.
7
+ * @throws {Error} If the length is less than 1.
8
+ */ export function randomString(length) {
9
+ if (length < 1) {
10
+ throw new Error('Length must be greater than 0');
11
+ }
12
+ const validCharacters = [
13
+ ...'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'
14
+ ];
15
+ let result = '';
16
+ repeat(()=>{
17
+ result += randomElement(validCharacters);
18
+ }, length);
19
+ return result;
9
20
  }
10
- function n(e) {
11
- return e[r(0, e.length)];
21
+ /**
22
+ * Returns a random element from the given array.
23
+ *
24
+ * @template T - The type of elements in the array.
25
+ * @param {T[]} array - The array from which to select a random element.
26
+ * @returns {T} A random element from the array.
27
+ */ export function randomElement(array) {
28
+ const index = randomInteger(0, array.length);
29
+ return array[index];
12
30
  }
13
- function r(e, t) {
14
- if (e >= t) throw Error("The `minInclusive` value must be less than the `maxExclusive` value.");
15
- return Math.floor(Math.random() * (t - e)) + e;
31
+ /**
32
+ * Returns a random integer between minInclusive and maxExclusive.
33
+ *
34
+ * @param minInclusive
35
+ * @param maxExclusive
36
+ * @returns
37
+ */ export function randomInteger(minInclusive, maxExclusive) {
38
+ if (minInclusive >= maxExclusive) {
39
+ throw new Error('The `minInclusive` value must be less than the `maxExclusive` value.');
40
+ }
41
+ return Math.floor(Math.random() * (maxExclusive - minInclusive)) + minInclusive;
16
42
  }
17
- function i(e, t) {
18
- if (e >= t) throw Error("The `minInclusive` value must be less than the `maxExclusive` value.");
19
- return Math.random() * (t - e) + e;
43
+ /**
44
+ * Generates a random float within the given range [min, max).
45
+ *
46
+ * @param {number} minInclusive - The minimum value (inclusive).
47
+ * @param {number} maxExclusive - The maximum value (exclusive).
48
+ * @returns {number} A random float within the range [min, max).
49
+ */ export function randomFloat(minInclusive, maxExclusive) {
50
+ if (minInclusive >= maxExclusive) {
51
+ throw new Error('The `minInclusive` value must be less than the `maxExclusive` value.');
52
+ }
53
+ return Math.random() * (maxExclusive - minInclusive) + minInclusive;
20
54
  }
21
- //#endregion
22
- export { n as randomElement, i as randomFloat, r as randomInteger, t as randomString };
55
+
56
+ //# sourceMappingURL=random.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/random.ts"],"sourcesContent":["import { repeat } from './repeat';\n\n/**\n * Generates a random string of the specified length using alphanumeric characters.\n *\n * @param {number} length - The length of the random string to generate. Must be greater than 0.\n * @returns {string} A random string of the specified length.\n * @throws {Error} If the length is less than 1.\n */\nexport function randomString(length: number): string {\n if (length < 1) {\n throw new Error('Length must be greater than 0');\n }\n const validCharacters = [\n ...'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789',\n ];\n let result = '';\n repeat(() => {\n result += randomElement(validCharacters);\n }, length);\n return result;\n}\n\n/**\n * Returns a random element from the given array.\n *\n * @template T - The type of elements in the array.\n * @param {T[]} array - The array from which to select a random element.\n * @returns {T} A random element from the array.\n */\nexport function randomElement<T>(array: readonly T[]): T {\n const index = randomInteger(0, array.length);\n return array[index];\n}\n\n/**\n * Returns a random integer between minInclusive and maxExclusive.\n *\n * @param minInclusive\n * @param maxExclusive\n * @returns\n */\nexport function randomInteger(\n minInclusive: number,\n maxExclusive: number\n): number {\n if (minInclusive >= maxExclusive) {\n throw new Error(\n 'The `minInclusive` value must be less than the `maxExclusive` value.'\n );\n }\n return (\n Math.floor(Math.random() * (maxExclusive - minInclusive)) + minInclusive\n );\n}\n\n/**\n * Generates a random float within the given range [min, max).\n *\n * @param {number} minInclusive - The minimum value (inclusive).\n * @param {number} maxExclusive - The maximum value (exclusive).\n * @returns {number} A random float within the range [min, max).\n */\nexport function randomFloat(\n minInclusive: number,\n maxExclusive: number\n): number {\n if (minInclusive >= maxExclusive) {\n throw new Error(\n 'The `minInclusive` value must be less than the `maxExclusive` value.'\n );\n }\n return Math.random() * (maxExclusive - minInclusive) + minInclusive;\n}\n"],"names":["repeat","randomString","length","Error","validCharacters","result","randomElement","array","index","randomInteger","minInclusive","maxExclusive","Math","floor","random","randomFloat"],"mappings":"AAAA,SAASA,MAAM,QAAQ,cAAW;AAElC;;;;;;CAMC,GACD,OAAO,SAASC,aAAaC,MAAc;IACzC,IAAIA,SAAS,GAAG;QACd,MAAM,IAAIC,MAAM;IAClB;IACA,MAAMC,kBAAkB;WACnB;KACJ;IACD,IAAIC,SAAS;IACbL,OAAO;QACLK,UAAUC,cAAcF;IAC1B,GAAGF;IACH,OAAOG;AACT;AAEA;;;;;;CAMC,GACD,OAAO,SAASC,cAAiBC,KAAmB;IAClD,MAAMC,QAAQC,cAAc,GAAGF,MAAML,MAAM;IAC3C,OAAOK,KAAK,CAACC,MAAM;AACrB;AAEA;;;;;;CAMC,GACD,OAAO,SAASC,cACdC,YAAoB,EACpBC,YAAoB;IAEpB,IAAID,gBAAgBC,cAAc;QAChC,MAAM,IAAIR,MACR;IAEJ;IACA,OACES,KAAKC,KAAK,CAACD,KAAKE,MAAM,KAAMH,CAAAA,eAAeD,YAAW,KAAMA;AAEhE;AAEA;;;;;;CAMC,GACD,OAAO,SAASK,YACdL,YAAoB,EACpBC,YAAoB;IAEpB,IAAID,gBAAgBC,cAAc;QAChC,MAAM,IAAIR,MACR;IAEJ;IACA,OAAOS,KAAKE,MAAM,KAAMH,CAAAA,eAAeD,YAAW,IAAKA;AACzD"}
@@ -1,23 +1,23 @@
1
1
  /**
2
- * Hook that debounces a value by a specified delay.
3
- *
4
- * The returned value will only update after the specified delay has passed
5
- * since the last change to the input value. This is useful for reducing
6
- * the frequency of expensive operations triggered by rapidly changing values.
7
- *
8
- * @param value - The value to debounce
9
- * @param delayInMs - The delay in milliseconds
10
- * @returns The debounced value
11
- *
12
- * @example
13
- * ```tsx
14
- * const [searchTerm, setSearchTerm] = useState('');
15
- * const debouncedSearchTerm = useDebounce(searchTerm, 300);
16
- *
17
- * // API call only triggers when user stops typing for 300ms
18
- * useEffect(() => {
19
- * searchApi(debouncedSearchTerm);
20
- * }, [debouncedSearchTerm]);
21
- * ```
22
- */
2
+ * Hook that debounces a value by a specified delay.
3
+ *
4
+ * The returned value will only update after the specified delay has passed
5
+ * since the last change to the input value. This is useful for reducing
6
+ * the frequency of expensive operations triggered by rapidly changing values.
7
+ *
8
+ * @param value - The value to debounce
9
+ * @param delayInMs - The delay in milliseconds
10
+ * @returns The debounced value
11
+ *
12
+ * @example
13
+ * ```tsx
14
+ * const [searchTerm, setSearchTerm] = useState('');
15
+ * const debouncedSearchTerm = useDebounce(searchTerm, 300);
16
+ *
17
+ * // API call only triggers when user stops typing for 300ms
18
+ * useEffect(() => {
19
+ * searchApi(debouncedSearchTerm);
20
+ * }, [debouncedSearchTerm]);
21
+ * ```
22
+ */
23
23
  export declare function useDebounce<T>(value: T, delayInMs: number): T;
@@ -1,15 +1,40 @@
1
- import { useEffect as e, useState as t } from "react";
2
- //#region libs/shared/underscore/src/react/use-debounce.ts
3
- function n(n, r) {
4
- let [i, a] = t(n);
5
- return e(() => {
6
- let e = setTimeout(() => {
7
- a(n);
8
- }, r);
9
- return () => {
10
- clearTimeout(e);
11
- };
12
- }, [n, r]), i;
1
+ import { useEffect, useState } from "react";
2
+ /**
3
+ * Hook that debounces a value by a specified delay.
4
+ *
5
+ * The returned value will only update after the specified delay has passed
6
+ * since the last change to the input value. This is useful for reducing
7
+ * the frequency of expensive operations triggered by rapidly changing values.
8
+ *
9
+ * @param value - The value to debounce
10
+ * @param delayInMs - The delay in milliseconds
11
+ * @returns The debounced value
12
+ *
13
+ * @example
14
+ * ```tsx
15
+ * const [searchTerm, setSearchTerm] = useState('');
16
+ * const debouncedSearchTerm = useDebounce(searchTerm, 300);
17
+ *
18
+ * // API call only triggers when user stops typing for 300ms
19
+ * useEffect(() => {
20
+ * searchApi(debouncedSearchTerm);
21
+ * }, [debouncedSearchTerm]);
22
+ * ```
23
+ */ export function useDebounce(value, delayInMs) {
24
+ const [debouncedValue, setDebouncedValue] = useState(value);
25
+ useEffect(()=>{
26
+ const handler = setTimeout(()=>{
27
+ setDebouncedValue(value);
28
+ }, delayInMs);
29
+ // Cancel the timeout if value changes (also on delayInMs change or unmount)
30
+ return ()=>{
31
+ clearTimeout(handler);
32
+ };
33
+ }, [
34
+ value,
35
+ delayInMs
36
+ ]);
37
+ return debouncedValue;
13
38
  }
14
- //#endregion
15
- export { n as useDebounce };
39
+
40
+ //# sourceMappingURL=use-debounce.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/react/use-debounce.ts"],"sourcesContent":["import { useEffect, useState } from 'react';\n\n/**\n * Hook that debounces a value by a specified delay.\n *\n * The returned value will only update after the specified delay has passed\n * since the last change to the input value. This is useful for reducing\n * the frequency of expensive operations triggered by rapidly changing values.\n *\n * @param value - The value to debounce\n * @param delayInMs - The delay in milliseconds\n * @returns The debounced value\n *\n * @example\n * ```tsx\n * const [searchTerm, setSearchTerm] = useState('');\n * const debouncedSearchTerm = useDebounce(searchTerm, 300);\n *\n * // API call only triggers when user stops typing for 300ms\n * useEffect(() => {\n * searchApi(debouncedSearchTerm);\n * }, [debouncedSearchTerm]);\n * ```\n */\nexport function useDebounce<T>(value: T, delayInMs: number): T {\n const [debouncedValue, setDebouncedValue] = useState(value);\n\n useEffect(() => {\n const handler = setTimeout(() => {\n setDebouncedValue(value);\n }, delayInMs);\n\n // Cancel the timeout if value changes (also on delayInMs change or unmount)\n return (): void => {\n clearTimeout(handler);\n };\n }, [value, delayInMs]);\n\n return debouncedValue;\n}\n"],"names":["useEffect","useState","useDebounce","value","delayInMs","debouncedValue","setDebouncedValue","handler","setTimeout","clearTimeout"],"mappings":"AAAA,SAASA,SAAS,EAAEC,QAAQ,QAAQ,QAAQ;AAE5C;;;;;;;;;;;;;;;;;;;;;CAqBC,GACD,OAAO,SAASC,YAAeC,KAAQ,EAAEC,SAAiB;IACxD,MAAM,CAACC,gBAAgBC,kBAAkB,GAAGL,SAASE;IAErDH,UAAU;QACR,MAAMO,UAAUC,WAAW;YACzBF,kBAAkBH;QACpB,GAAGC;QAEH,4EAA4E;QAC5E,OAAO;YACLK,aAAaF;QACf;IACF,GAAG;QAACJ;QAAOC;KAAU;IAErB,OAAOC;AACT"}
@@ -1,34 +1,33 @@
1
- type UseDerivedPromiseResult<T> = {
2
- data: T | undefined;
3
- error: Error | undefined;
4
- isLoading: true;
1
+ export type UseDerivedPromiseResult<T> = {
2
+ data: T | undefined;
3
+ error: Error | undefined;
4
+ isLoading: true;
5
5
  } | {
6
- data: T;
7
- error: undefined;
8
- isLoading: false;
6
+ data: T;
7
+ error: undefined;
8
+ isLoading: false;
9
9
  } | {
10
- data: undefined;
11
- error: Error;
12
- isLoading: false;
10
+ data: undefined;
11
+ error: Error;
12
+ isLoading: false;
13
13
  };
14
14
  /**
15
- * A custom React hook that executes a promise function whenever its dependencies change.
16
- * It manages the loading state, error handling, and the result of the promise.
17
- *
18
- * @param promiseFn - A function that returns a promise.
19
- * @param deps - An array of dependencies that trigger the promise execution when changed.
20
- * @returns An object containing the data, loading state, and error from the promise execution.
21
- *
22
- * @example
23
- * // Usage inside a React component
24
- * const { data: user, error, isLoading } = useDerivedPromise(
25
- * () => getUserFromId(userId),
26
- * [userId]
27
- * );
28
- *
29
- * if (isLoading) return <div>Loading...</div>;
30
- * if (error) return <div>Error: {error.message}</div>;
31
- * return <div>User: {user.name}</div>;
32
- */
15
+ * A custom React hook that executes a promise function whenever its dependencies change.
16
+ * It manages the loading state, error handling, and the result of the promise.
17
+ *
18
+ * @param promiseFn - A function that returns a promise.
19
+ * @param deps - An array of dependencies that trigger the promise execution when changed.
20
+ * @returns An object containing the data, loading state, and error from the promise execution.
21
+ *
22
+ * @example
23
+ * // Usage inside a React component
24
+ * const { data: user, error, isLoading } = useDerivedPromise(
25
+ * () => getUserFromId(userId),
26
+ * [userId]
27
+ * );
28
+ *
29
+ * if (isLoading) return <div>Loading...</div>;
30
+ * if (error) return <div>Error: {error.message}</div>;
31
+ * return <div>User: {user.name}</div>;
32
+ */
33
33
  export declare function useDerivedPromise<T>(promiseFn: () => Promise<T>, deps: React.DependencyList): UseDerivedPromiseResult<T>;
34
- export {};
@@ -1,34 +1,71 @@
1
- import { useEffect as e, useState as t } from "react";
2
- //#region libs/shared/underscore/src/react/use-derived-promise.ts
3
- function n(n, r) {
4
- let [i, a] = t(void 0), [o, s] = t(!0), [c, l] = t(void 0);
5
- return e(() => {
6
- let e = !0;
7
- return s(!0), (async () => {
8
- try {
9
- let t = await n();
10
- e && a(t);
11
- } catch (t) {
12
- e && l(t instanceof Error ? t : Error(String(t)));
13
- } finally {
14
- e && s(!1);
15
- }
16
- })(), () => {
17
- e = !1;
18
- };
19
- }, r), o ? {
20
- data: i,
21
- error: c,
22
- isLoading: !0
23
- } : c ? {
24
- data: void 0,
25
- error: c,
26
- isLoading: !1
27
- } : {
28
- data: i,
29
- error: void 0,
30
- isLoading: !1
31
- };
1
+ /* eslint-disable @eslint-react/hooks-extra/no-direct-set-state-in-use-effect */ import { useEffect, useState } from "react";
2
+ /**
3
+ * A custom React hook that executes a promise function whenever its dependencies change.
4
+ * It manages the loading state, error handling, and the result of the promise.
5
+ *
6
+ * @param promiseFn - A function that returns a promise.
7
+ * @param deps - An array of dependencies that trigger the promise execution when changed.
8
+ * @returns An object containing the data, loading state, and error from the promise execution.
9
+ *
10
+ * @example
11
+ * // Usage inside a React component
12
+ * const { data: user, error, isLoading } = useDerivedPromise(
13
+ * () => getUserFromId(userId),
14
+ * [userId]
15
+ * );
16
+ *
17
+ * if (isLoading) return <div>Loading...</div>;
18
+ * if (error) return <div>Error: {error.message}</div>;
19
+ * return <div>User: {user.name}</div>;
20
+ */ export function useDerivedPromise(promiseFn, deps) {
21
+ const [data, setData] = useState(undefined);
22
+ const [isLoading, setIsLoading] = useState(true);
23
+ const [error, setError] = useState(undefined);
24
+ useEffect(()=>{
25
+ let isActive = true;
26
+ // If a dependency changes, reset loading state
27
+ setIsLoading(true);
28
+ const executePromise = async ()=>{
29
+ try {
30
+ const result = await promiseFn();
31
+ if (isActive) {
32
+ setData(result);
33
+ }
34
+ } catch (err) {
35
+ if (isActive) {
36
+ setError(err instanceof Error ? err : new Error(String(err)));
37
+ }
38
+ } finally{
39
+ if (isActive) {
40
+ setIsLoading(false);
41
+ }
42
+ }
43
+ };
44
+ executePromise();
45
+ return ()=>{
46
+ isActive = false;
47
+ };
48
+ // eslint-disable-next-line react-hooks/exhaustive-deps
49
+ }, deps); // Effect re-runs only when these dependencies change
50
+ if (isLoading) {
51
+ return {
52
+ data,
53
+ error,
54
+ isLoading: true
55
+ };
56
+ }
57
+ if (error) {
58
+ return {
59
+ data: undefined,
60
+ error,
61
+ isLoading: false
62
+ };
63
+ }
64
+ return {
65
+ data: data,
66
+ error: undefined,
67
+ isLoading: false
68
+ };
32
69
  }
33
- //#endregion
34
- export { n as useDerivedPromise };
70
+
71
+ //# sourceMappingURL=use-derived-promise.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/react/use-derived-promise.ts"],"sourcesContent":["/* eslint-disable @eslint-react/hooks-extra/no-direct-set-state-in-use-effect */\nimport { useEffect, useState } from 'react';\n\nexport type UseDerivedPromiseResult<T> =\n // Loading state\n | {\n data: T | undefined;\n error: Error | undefined;\n isLoading: true;\n }\n // Resolved state\n | {\n data: T;\n error: undefined;\n isLoading: false;\n }\n // Rejected state\n | {\n data: undefined;\n error: Error;\n isLoading: false;\n };\n\n/**\n * A custom React hook that executes a promise function whenever its dependencies change.\n * It manages the loading state, error handling, and the result of the promise.\n *\n * @param promiseFn - A function that returns a promise.\n * @param deps - An array of dependencies that trigger the promise execution when changed.\n * @returns An object containing the data, loading state, and error from the promise execution.\n *\n * @example\n * // Usage inside a React component\n * const { data: user, error, isLoading } = useDerivedPromise(\n * () => getUserFromId(userId),\n * [userId]\n * );\n *\n * if (isLoading) return <div>Loading...</div>;\n * if (error) return <div>Error: {error.message}</div>;\n * return <div>User: {user.name}</div>;\n */\nexport function useDerivedPromise<T>(\n promiseFn: () => Promise<T>,\n deps: React.DependencyList\n): UseDerivedPromiseResult<T> {\n const [data, setData] = useState<T | undefined>(undefined);\n const [isLoading, setIsLoading] = useState<boolean>(true);\n const [error, setError] = useState<Error | undefined>(undefined);\n\n useEffect(() => {\n let isActive = true;\n\n // If a dependency changes, reset loading state\n setIsLoading(true);\n\n const executePromise = async (): Promise<void> => {\n try {\n const result = await promiseFn();\n if (isActive) {\n setData(result);\n }\n } catch (err) {\n if (isActive) {\n setError(err instanceof Error ? err : new Error(String(err)));\n }\n } finally {\n if (isActive) {\n setIsLoading(false);\n }\n }\n };\n\n executePromise();\n\n return (): void => {\n isActive = false;\n };\n\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, deps); // Effect re-runs only when these dependencies change\n\n if (isLoading) {\n return { data, error, isLoading: true };\n }\n if (error) {\n return { data: undefined, error, isLoading: false };\n }\n return { data: data as T, error: undefined, isLoading: false };\n}\n"],"names":["useEffect","useState","useDerivedPromise","promiseFn","deps","data","setData","undefined","isLoading","setIsLoading","error","setError","isActive","executePromise","result","err","Error","String"],"mappings":"AAAA,8EAA8E,GAC9E,SAASA,SAAS,EAAEC,QAAQ,QAAQ,QAAQ;AAsB5C;;;;;;;;;;;;;;;;;;CAkBC,GACD,OAAO,SAASC,kBACdC,SAA2B,EAC3BC,IAA0B;IAE1B,MAAM,CAACC,MAAMC,QAAQ,GAAGL,SAAwBM;IAChD,MAAM,CAACC,WAAWC,aAAa,GAAGR,SAAkB;IACpD,MAAM,CAACS,OAAOC,SAAS,GAAGV,SAA4BM;IAEtDP,UAAU;QACR,IAAIY,WAAW;QAEf,+CAA+C;QAC/CH,aAAa;QAEb,MAAMI,iBAAiB;YACrB,IAAI;gBACF,MAAMC,SAAS,MAAMX;gBACrB,IAAIS,UAAU;oBACZN,QAAQQ;gBACV;YACF,EAAE,OAAOC,KAAK;gBACZ,IAAIH,UAAU;oBACZD,SAASI,eAAeC,QAAQD,MAAM,IAAIC,MAAMC,OAAOF;gBACzD;YACF,SAAU;gBACR,IAAIH,UAAU;oBACZH,aAAa;gBACf;YACF;QACF;QAEAI;QAEA,OAAO;YACLD,WAAW;QACb;IAEA,uDAAuD;IACzD,GAAGR,OAAO,qDAAqD;IAE/D,IAAII,WAAW;QACb,OAAO;YAAEH;YAAMK;YAAOF,WAAW;QAAK;IACxC;IACA,IAAIE,OAAO;QACT,OAAO;YAAEL,MAAME;YAAWG;YAAOF,WAAW;QAAM;IACpD;IACA,OAAO;QAAEH,MAAMA;QAAWK,OAAOH;QAAWC,WAAW;IAAM;AAC/D"}
@@ -1,27 +1,27 @@
1
1
  /**
2
- * A wrapper around React's `useSyncExternalStore` that returns a referentially
3
- * stable value from a mutable data source.
4
- *
5
- * This hook uses structural cloning and deep equality checks to keep returning
6
- * the same reference for the same value, making it safe to use with dependency
7
- * arrays in other hooks.
8
- *
9
- * This is performance-sensitive and should be used with small slices of data.
10
- *
11
- * @template T - structurally-cloneable data type from your store
12
- *
13
- * @param subscribe - A function that subscribes to the external store and
14
- * returns an unsubscribe function. Called with a callback that should be
15
- * invoked whenever the store changes. Should be memoized.
16
- * @param getSnapshot - A function that retrieves the current value from the
17
- * external store. Must be a pure function and can be called multiple times
18
- * per render. Must return a structurally-cloneable value. Does not need to be
19
- * memoized.
20
- *
21
- * @returns The current value from the store, with referential stability
22
- * guaranteed when the value content hasn't changed.
23
- *
24
- * @see [React
25
- * useSyncExternalStore](https://react.dev/reference/react/useSyncExternalStore)
26
- */
2
+ * A wrapper around React's `useSyncExternalStore` that returns a referentially
3
+ * stable value from a mutable data source.
4
+ *
5
+ * This hook uses structural cloning and deep equality checks to keep returning
6
+ * the same reference for the same value, making it safe to use with dependency
7
+ * arrays in other hooks.
8
+ *
9
+ * This is performance-sensitive and should be used with small slices of data.
10
+ *
11
+ * @template T - structurally-cloneable data type from your store
12
+ *
13
+ * @param subscribe - A function that subscribes to the external store and
14
+ * returns an unsubscribe function. Called with a callback that should be
15
+ * invoked whenever the store changes. Should be memoized.
16
+ * @param getSnapshot - A function that retrieves the current value from the
17
+ * external store. Must be a pure function and can be called multiple times
18
+ * per render. Must return a structurally-cloneable value. Does not need to be
19
+ * memoized.
20
+ *
21
+ * @returns The current value from the store, with referential stability
22
+ * guaranteed when the value content hasn't changed.
23
+ *
24
+ * @see [React
25
+ * useSyncExternalStore](https://react.dev/reference/react/useSyncExternalStore)
26
+ */
27
27
  export declare function useStableSyncExternalStore<T>(subscribe: (callback: VoidFunction) => VoidFunction, getSnapshot: () => T): T;
@@ -1,12 +1,53 @@
1
- import { isEqual as e } from "lodash-es";
2
- import { useRef as t, useSyncExternalStore as n } from "react";
3
- //#region libs/shared/underscore/src/react/use-stable-sync-external-store.ts
4
- function r(r, i) {
5
- let a = t(null);
6
- return n(r, () => {
7
- let t = i(), n = structuredClone(t), r = a.current;
8
- return r !== null && e(r, n) ? r : (a.current = n, n);
9
- });
1
+ import { useRef, useSyncExternalStore } from "react";
2
+ import { isEqual } from "lodash-es";
3
+ /**
4
+ * A wrapper around React's `useSyncExternalStore` that returns a referentially
5
+ * stable value from a mutable data source.
6
+ *
7
+ * This hook uses structural cloning and deep equality checks to keep returning
8
+ * the same reference for the same value, making it safe to use with dependency
9
+ * arrays in other hooks.
10
+ *
11
+ * This is performance-sensitive and should be used with small slices of data.
12
+ *
13
+ * @template T - structurally-cloneable data type from your store
14
+ *
15
+ * @param subscribe - A function that subscribes to the external store and
16
+ * returns an unsubscribe function. Called with a callback that should be
17
+ * invoked whenever the store changes. Should be memoized.
18
+ * @param getSnapshot - A function that retrieves the current value from the
19
+ * external store. Must be a pure function and can be called multiple times
20
+ * per render. Must return a structurally-cloneable value. Does not need to be
21
+ * memoized.
22
+ *
23
+ * @returns The current value from the store, with referential stability
24
+ * guaranteed when the value content hasn't changed.
25
+ *
26
+ * @see [React
27
+ * useSyncExternalStore](https://react.dev/reference/react/useSyncExternalStore)
28
+ */ export function useStableSyncExternalStore(subscribe, getSnapshot) {
29
+ // Store the previous value to compare against for referential stability
30
+ const prevValueRef = useRef(null);
31
+ // Wrap the snapshot getter to add cloning and deep equality comparison.
32
+ // useSyncExternalStore does not benefit from memoizing this function,
33
+ // performance instead relies on consumers leveraging the returned stable
34
+ // reference in their own memoization.
35
+ const wrappedGetSnapshot = ()=>{
36
+ // Get the raw value from the snapshot function
37
+ const rawValue = getSnapshot();
38
+ // Clone the value to ensure immutability and to compare with previous value
39
+ const clonedValue = structuredClone(rawValue);
40
+ // Check if the value is equal to the previous value
41
+ const prevValue = prevValueRef.current;
42
+ if (prevValue !== null && isEqual(prevValue, clonedValue)) {
43
+ // Return the previous reference to maintain referential identity
44
+ return prevValue;
45
+ }
46
+ // Update the memoized value and return the new one
47
+ prevValueRef.current = clonedValue;
48
+ return clonedValue;
49
+ };
50
+ return useSyncExternalStore(subscribe, wrappedGetSnapshot);
10
51
  }
11
- //#endregion
12
- export { r as useStableSyncExternalStore };
52
+
53
+ //# sourceMappingURL=use-stable-sync-external-store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/react/use-stable-sync-external-store.ts"],"sourcesContent":["import { useRef, useSyncExternalStore } from 'react';\n\nimport { isEqual } from 'lodash-es';\n\n/**\n * A wrapper around React's `useSyncExternalStore` that returns a referentially\n * stable value from a mutable data source.\n *\n * This hook uses structural cloning and deep equality checks to keep returning\n * the same reference for the same value, making it safe to use with dependency\n * arrays in other hooks.\n *\n * This is performance-sensitive and should be used with small slices of data.\n *\n * @template T - structurally-cloneable data type from your store\n *\n * @param subscribe - A function that subscribes to the external store and\n * returns an unsubscribe function. Called with a callback that should be\n * invoked whenever the store changes. Should be memoized.\n * @param getSnapshot - A function that retrieves the current value from the\n * external store. Must be a pure function and can be called multiple times\n * per render. Must return a structurally-cloneable value. Does not need to be\n * memoized.\n *\n * @returns The current value from the store, with referential stability\n * guaranteed when the value content hasn't changed.\n *\n * @see [React\n * useSyncExternalStore](https://react.dev/reference/react/useSyncExternalStore)\n */\nexport function useStableSyncExternalStore<T>(\n subscribe: (callback: VoidFunction) => VoidFunction,\n getSnapshot: () => T\n): T {\n // Store the previous value to compare against for referential stability\n const prevValueRef = useRef<T | null>(null);\n\n // Wrap the snapshot getter to add cloning and deep equality comparison.\n // useSyncExternalStore does not benefit from memoizing this function,\n // performance instead relies on consumers leveraging the returned stable\n // reference in their own memoization.\n const wrappedGetSnapshot = (): T => {\n // Get the raw value from the snapshot function\n const rawValue = getSnapshot();\n\n // Clone the value to ensure immutability and to compare with previous value\n const clonedValue = structuredClone(rawValue);\n\n // Check if the value is equal to the previous value\n const prevValue = prevValueRef.current;\n if (prevValue !== null && isEqual(prevValue, clonedValue)) {\n // Return the previous reference to maintain referential identity\n return prevValue;\n }\n\n // Update the memoized value and return the new one\n prevValueRef.current = clonedValue;\n return clonedValue;\n };\n\n return useSyncExternalStore(subscribe, wrappedGetSnapshot);\n}\n"],"names":["useRef","useSyncExternalStore","isEqual","useStableSyncExternalStore","subscribe","getSnapshot","prevValueRef","wrappedGetSnapshot","rawValue","clonedValue","structuredClone","prevValue","current"],"mappings":"AAAA,SAASA,MAAM,EAAEC,oBAAoB,QAAQ,QAAQ;AAErD,SAASC,OAAO,QAAQ,YAAY;AAEpC;;;;;;;;;;;;;;;;;;;;;;;;;CAyBC,GACD,OAAO,SAASC,2BACdC,SAAmD,EACnDC,WAAoB;IAEpB,wEAAwE;IACxE,MAAMC,eAAeN,OAAiB;IAEtC,wEAAwE;IACxE,sEAAsE;IACtE,yEAAyE;IACzE,sCAAsC;IACtC,MAAMO,qBAAqB;QACzB,+CAA+C;QAC/C,MAAMC,WAAWH;QAEjB,4EAA4E;QAC5E,MAAMI,cAAcC,gBAAgBF;QAEpC,oDAAoD;QACpD,MAAMG,YAAYL,aAAaM,OAAO;QACtC,IAAID,cAAc,QAAQT,QAAQS,WAAWF,cAAc;YACzD,iEAAiE;YACjE,OAAOE;QACT;QAEA,mDAAmD;QACnDL,aAAaM,OAAO,GAAGH;QACvB,OAAOA;IACT;IAEA,OAAOR,qBAAqBG,WAAWG;AACzC"}
package/dist/react.d.ts CHANGED
@@ -1,3 +1,3 @@
1
- export { useDebounce } from './react/use-debounce';
2
- export { useDerivedPromise } from './react/use-derived-promise';
3
- export { useStableSyncExternalStore } from './react/use-stable-sync-external-store';
1
+ export { useDebounce } from "./react/use-debounce";
2
+ export { useDerivedPromise, type UseDerivedPromiseResult } from "./react/use-derived-promise";
3
+ export { useStableSyncExternalStore } from "./react/use-stable-sync-external-store";
package/dist/react.js CHANGED
@@ -1,4 +1,5 @@
1
- import { useDebounce as e } from "./react/use-debounce.js";
2
- import { useDerivedPromise as t } from "./react/use-derived-promise.js";
3
- import { useStableSyncExternalStore as n } from "./react/use-stable-sync-external-store.js";
4
- export { e as useDebounce, t as useDerivedPromise, n as useStableSyncExternalStore };
1
+ export { useDebounce } from "./react/use-debounce.js";
2
+ export { useDerivedPromise } from "./react/use-derived-promise.js";
3
+ export { useStableSyncExternalStore } from "./react/use-stable-sync-external-store.js";
4
+
5
+ //# sourceMappingURL=react.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/react.ts"],"sourcesContent":["export { useDebounce } from './react/use-debounce';\nexport {\n useDerivedPromise,\n type UseDerivedPromiseResult,\n} from './react/use-derived-promise';\nexport { useStableSyncExternalStore } from './react/use-stable-sync-external-store';\n"],"names":["useDebounce","useDerivedPromise","useStableSyncExternalStore"],"mappings":"AAAA,SAASA,WAAW,QAAQ,0BAAuB;AACnD,SACEC,iBAAiB,QAEZ,iCAA8B;AACrC,SAASC,0BAA0B,QAAQ,4CAAyC"}
package/dist/repeat.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  /**
2
- * Repeats the execution of a given function a specified number of times.
3
- *
4
- * @param fn - The function to be executed repeatedly.
5
- * @param times - The number of times to execute the function.
6
- */
2
+ * Repeats the execution of a given function a specified number of times.
3
+ *
4
+ * @param fn - The function to be executed repeatedly.
5
+ * @param times - The number of times to execute the function.
6
+ */
7
7
  export declare function repeat(fn: VoidFunction, times: number): void;
package/dist/repeat.js CHANGED
@@ -1,6 +1,12 @@
1
- //#region libs/shared/underscore/src/repeat.ts
2
- function e(e, t) {
3
- for (let n = 0; n < t; ++n) e();
1
+ /**
2
+ * Repeats the execution of a given function a specified number of times.
3
+ *
4
+ * @param fn - The function to be executed repeatedly.
5
+ * @param times - The number of times to execute the function.
6
+ */ export function repeat(fn, times) {
7
+ for(let i = 0; i < times; ++i){
8
+ fn();
9
+ }
4
10
  }
5
- //#endregion
6
- export { e as repeat };
11
+
12
+ //# sourceMappingURL=repeat.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/repeat.ts"],"sourcesContent":["/**\n * Repeats the execution of a given function a specified number of times.\n *\n * @param fn - The function to be executed repeatedly.\n * @param times - The number of times to execute the function.\n */\nexport function repeat(fn: VoidFunction, times: number): void {\n for (let i = 0; i < times; ++i) {\n fn();\n }\n}\n"],"names":["repeat","fn","times","i"],"mappings":"AAAA;;;;;CAKC,GACD,OAAO,SAASA,OAAOC,EAAgB,EAAEC,KAAa;IACpD,IAAK,IAAIC,IAAI,GAAGA,IAAID,OAAO,EAAEC,EAAG;QAC9BF;IACF;AACF"}