@cognite/underscore 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (60) hide show
  1. package/README.md +40 -0
  2. package/dist/arrays.d.ts +41 -0
  3. package/dist/arrays.js +23 -0
  4. package/dist/assert.d.ts +8 -0
  5. package/dist/assert.js +6 -0
  6. package/dist/brand.d.ts +42 -0
  7. package/dist/chunk-and-process-in-parallel.d.ts +112 -0
  8. package/dist/chunk-and-process-in-parallel.js +30 -0
  9. package/dist/chunk-array.d.ts +27 -0
  10. package/dist/chunk-array.js +7 -0
  11. package/dist/class.d.ts +12 -0
  12. package/dist/class.js +6 -0
  13. package/dist/exhaustive-guard.d.ts +17 -0
  14. package/dist/exhaustive-guard.js +6 -0
  15. package/dist/exponential-backoff-with-jitter.d.ts +15 -0
  16. package/dist/exponential-backoff-with-jitter.js +8 -0
  17. package/dist/generate-unique-name.d.ts +19 -0
  18. package/dist/generate-unique-name.js +11 -0
  19. package/dist/get-numbers-between.d.ts +17 -0
  20. package/dist/get-numbers-between.js +6 -0
  21. package/dist/humanize-value.d.ts +5 -0
  22. package/dist/humanize-value.js +16 -0
  23. package/dist/index.d.ts +23 -0
  24. package/dist/index.js +23 -0
  25. package/dist/is-function.d.ts +7 -0
  26. package/dist/is-function.js +6 -0
  27. package/dist/is-primitive.d.ts +9 -0
  28. package/dist/is-primitive.js +7 -0
  29. package/dist/is-valid-url.d.ts +16 -0
  30. package/dist/is-valid-url.js +17 -0
  31. package/dist/iterators.d.ts +9 -0
  32. package/dist/iterators.js +7 -0
  33. package/dist/math.d.ts +14 -0
  34. package/dist/math.js +9 -0
  35. package/dist/random.d.ts +32 -0
  36. package/dist/random.js +22 -0
  37. package/dist/react/use-debounce.d.ts +23 -0
  38. package/dist/react/use-debounce.js +15 -0
  39. package/dist/react/use-derived-promise.d.ts +34 -0
  40. package/dist/react/use-derived-promise.js +34 -0
  41. package/dist/react/use-stable-sync-external-store.d.ts +27 -0
  42. package/dist/react/use-stable-sync-external-store.js +12 -0
  43. package/dist/react.d.ts +3 -0
  44. package/dist/react.js +4 -0
  45. package/dist/repeat.d.ts +7 -0
  46. package/dist/repeat.js +6 -0
  47. package/dist/retry-async.d.ts +92 -0
  48. package/dist/retry-async.js +18 -0
  49. package/dist/sleep.d.ts +7 -0
  50. package/dist/sleep.js +6 -0
  51. package/dist/string.d.ts +41 -0
  52. package/dist/string.js +12 -0
  53. package/dist/structMap/index.d.ts +3 -0
  54. package/dist/structMap/stableStringify.d.ts +23 -0
  55. package/dist/structMap/stableStringify.js +24 -0
  56. package/dist/structMap/structMap.d.ts +110 -0
  57. package/dist/structMap/structMap.js +29 -0
  58. package/dist/structMap/testUtils.d.ts +17 -0
  59. package/dist/structMap/types.d.ts +7 -0
  60. package/package.json +45 -0
package/README.md ADDED
@@ -0,0 +1,40 @@
1
+ # Lodashy
2
+
3
+ > [!WARNING]
4
+ > This package is developed and published for Cognite's internal use. It is made publicly available on npm as a
5
+ > side effect of our internal tooling, but no support, stability, or continued availability is guaranteed for
6
+ > external users. Cognite makes no warranty regarding this package and accepts no liability for any security
7
+ > vulnerabilities, defects, or issues arising from its use, by internal or external consumers.
8
+
9
+ A collection of useful plain Typescript utility functions.
10
+
11
+ ## Functions
12
+
13
+ See the collection of functions [here](./docs/modules.md).
14
+
15
+ ## Importing
16
+
17
+ The library has two modules. Non-React functions is imported the following way:
18
+ ```ts
19
+ import { someFunction } from '@cognite/underscore';
20
+ ```
21
+
22
+ But React functions are imported the following way:
23
+ ```ts
24
+ import { someFunction } from '@cognite/underscore/react';
25
+ ```
26
+
27
+ ## Example
28
+
29
+ ```ts
30
+ import { getNumbersBetween } from '@cognite/underscore';
31
+
32
+ const numbers = getNumbersBetween(1, 5);
33
+ for (const num of numbers) {
34
+ console.log(num); // 1, 2, 3, 4
35
+ }
36
+ ```
37
+
38
+ ## Update documentation
39
+
40
+ To update the documentation, please run `pnpm nx docs underscore`.
@@ -0,0 +1,41 @@
1
+ /**
2
+ * Inserts an element at a specific index in an array.
3
+ *
4
+ * @template T - The type of elements in the array.
5
+ * @param {T[]} array - The array.
6
+ * @param {number} index - The index at which to insert the element.
7
+ * @param {T} item - The element to insert.
8
+ */
9
+ export declare function insertAt<T>(array: T[], index: number, item: T): void;
10
+ /**
11
+ * Removes an element from an array, but only removed the first occurrence.
12
+ *
13
+ * @template T - The type of elements in the array.
14
+ * @param {T[]} array - The array.
15
+ * @param {T} item - The element to remove.
16
+ */
17
+ export declare function remove<T>(array: T[], item: T): void;
18
+ /**
19
+ * Removes an element by the index from an array.
20
+ *
21
+ * @template T - The type of elements in the array.
22
+ * @param {T[]} array - The array.
23
+ * @param {number} index - The index of the element to remove.
24
+ */
25
+ export declare function removeAt<T>(array: T[], index: number): void;
26
+ /**
27
+ * Swaps two elements in an array at index `i` and `j`.
28
+ *
29
+ * @template T - The type of elements in the array.
30
+ * @param {T[]} array - The array.
31
+ * @param {number} i - The index of the first element.
32
+ * @param {number} j - The index of the second element.
33
+ */
34
+ export declare function swap<T>(array: T[], i: number, j: number): void;
35
+ /**
36
+ * Shuffles the elements of the given array using the Fisher-Yates algorithm.
37
+ *
38
+ * @template T - The type of elements in the array.
39
+ * @param {T[]} array - The array.
40
+ */
41
+ export declare function shuffle<T>(array: T[]): void;
package/dist/arrays.js ADDED
@@ -0,0 +1,23 @@
1
+ import { randomInteger as e } from "./random.js";
2
+ //#region libs/shared/underscore/src/arrays.ts
3
+ function t(e, t, n) {
4
+ e.splice(t, 0, n);
5
+ }
6
+ function n(e, t) {
7
+ let n = e.indexOf(t);
8
+ n !== -1 && r(e, n);
9
+ }
10
+ function r(e, t) {
11
+ e.splice(t, 1);
12
+ }
13
+ function i(e, t, n) {
14
+ [e[t], e[n]] = [e[n], e[t]];
15
+ }
16
+ function a(t) {
17
+ for (let n = t.length - 1; n >= 0; n--) {
18
+ let r = e(0, n + 1);
19
+ i(t, n, r);
20
+ }
21
+ }
22
+ //#endregion
23
+ export { t as insertAt, n as remove, r as removeAt, a as shuffle, i as swap };
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Whatever gets passed into the condition parameter must be true if the assert returns. That means that for the rest of the scope, that condition must be truthy from the perspective of the type checker.
3
+ * Adapted from {@link https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-7.html#assertion-functions}
4
+ *
5
+ * @param condition - A condition which is guaranteed to be true for the rest of the calling scope after this function returns.
6
+ * @param msg - The message which should be included in the error given that the condition fails.
7
+ */
8
+ export declare function assert(condition: unknown, msg?: string): asserts condition;
package/dist/assert.js ADDED
@@ -0,0 +1,6 @@
1
+ //#region libs/shared/underscore/src/assert.ts
2
+ function e(e, t) {
3
+ if (!e) throw Error(t);
4
+ }
5
+ //#endregion
6
+ export { e as assert };
@@ -0,0 +1,42 @@
1
+ declare const brand: unique symbol;
2
+ /**
3
+ * Adds a compile-time-only "brand" to a base type, producing a nominal type.
4
+ * TypeScript's structural typing normally treats any two types with the same shape as
5
+ * interchangeable, so a `UserId` and an `OrderId` that are both `string` can be passed to each
6
+ * other's functions by mistake.
7
+ * `Brand` closes that hole by attaching a unique, unused property to the type, so values of
8
+ * different brands are no longer assignable to one another even though they share a base type.
9
+ * The branded property does not exist at runtime — it is erased during compilation and only
10
+ * affects type checking.
11
+ *
12
+ * Declare a custom branded type by aliasing `Brand` with a base type and a unique name:
13
+ * ```ts
14
+ * type UserId = Brand<string, 'UserId'>;
15
+ * type OrderId = Brand<string, 'OrderId'>;
16
+ * ```
17
+ *
18
+ * Because there is no runtime representation, values must be converted into a branded type with
19
+ * a type assertion, typically inside a small constructor function that documents and centralizes
20
+ * the conversion:
21
+ * ```ts
22
+ * function toUserId(id: string): UserId {
23
+ * return id as UserId;
24
+ * }
25
+ * ```
26
+ *
27
+ * Once created, a branded value can still be used wherever the base type is expected...
28
+ * ```ts
29
+ * function logId(id: string) {}
30
+ * logId(toUserId('abc')); // OK, UserId is a string
31
+ * ```
32
+ * ...but the reverse requires an explicit conversion, and brands are not interchangeable:
33
+ * ```ts
34
+ * function getUser(id: UserId) {}
35
+ * getUser('abc'); // Error, plain string is not a UserId
36
+ * getUser(toOrderId('abc')); // Error, OrderId is not a UserId
37
+ * ```
38
+ */
39
+ export type Brand<Base, Name extends string> = Base & {
40
+ readonly [brand]: Name;
41
+ };
42
+ export {};
@@ -0,0 +1,112 @@
1
+ /**
2
+ * Options for {@link chunkAndProcessInParallel}.
3
+ */
4
+ export interface ChunkAndProcessOptions {
5
+ /**
6
+ * Maximum number of chunks to process in parallel.
7
+ * @default 10
8
+ */
9
+ numWorkers?: number;
10
+ }
11
+ /**
12
+ * Error thrown when {@link chunkAndProcessInParallel} fails partway through processing.
13
+ *
14
+ * This error provides detailed information about which items were successfully processed,
15
+ * which items failed, and which items were never attempted.
16
+ *
17
+ * @template T - The type of input elements.
18
+ */
19
+ export declare class PartialExecutionError<T, U> extends Error {
20
+ /**
21
+ * The underlying error that caused the failure.
22
+ */
23
+ readonly reason: Error;
24
+ /**
25
+ * Input items from chunks that were successfully processed before the error occurred.
26
+ */
27
+ readonly succeeded: T[];
28
+ /**
29
+ * Results from the chunks that were successfully processed before the error occurred.
30
+ */
31
+ readonly succeededResults: U[];
32
+ /**
33
+ * Input items from the chunk that failed and caused the error.
34
+ */
35
+ readonly failed: T[];
36
+ /**
37
+ * Input items from chunks that were never processed due to the error.
38
+ * This includes both chunks that were never started and chunks that were
39
+ * in-progress when the error occurred.
40
+ */
41
+ readonly unprocessed: T[];
42
+ constructor(reason: Error, succeeded: T[], succeededResults: U[], failed: T[], unprocessed: T[]);
43
+ }
44
+ /**
45
+ * Splits an array into chunks and processes each chunk in parallel using a callback function.
46
+ *
47
+ * This function is useful for batch processing large datasets where you want to:
48
+ * - Limit the number of items processed at once (e.g., API limits)
49
+ * - Process multiple chunks simultaneously for better performance
50
+ * - Control the degree of parallelism to avoid overwhelming resources
51
+ *
52
+ * The function maintains a saturated queue up to `numWorkers` concurrent operations.
53
+ * When one chunk completes, the next chunk starts immediately, ensuring optimal throughput.
54
+ *
55
+ * All chunks are processed with controlled parallelism, and the results are flattened into
56
+ * a single array. If any chunk fails, the entire operation fails.
57
+ * The order of the result is maintained regardless of the completion order of the
58
+ * chunks, but not that there is no requirement that the callback must return one
59
+ * result per input element (i.e. the number of result elements might differ from the
60
+ * number of input elements).
61
+ *
62
+ * @template T - The type of elements in the input array.
63
+ * @template U - The type of elements in the output array.
64
+ * @param workItems - The array of items to process.
65
+ * @param chunkSize - The maximum size of each chunk. Must be a positive integer.
66
+ * @param performWorkCallback - An async function that processes a chunk and returns results.
67
+ * @param options - Optional configuration for parallelism control.
68
+ * @returns A promise that resolves to a flattened array of all results.
69
+ * @throws {Error} If `chunkSize` is not a positive integer or `numWorkers` is not a positive integer.
70
+ * @throws {PartialExecutionError} If `performWorkCallback` throws an error for any chunk, providing details about succeeded, failed, and unprocessed items.
71
+ *
72
+ * @example
73
+ * ```ts
74
+ * // Batch retrieve assets from CDF with controlled parallelism
75
+ * const assetIds = [1, 2, 3, ..., 10000];
76
+ * const assets = await chunkAndProcessInParallel(
77
+ * assetIds,
78
+ * 1000, // Retrieve 1000 assets per request
79
+ * async (chunk) => {
80
+ * const response = await client.assets.retrieve(
81
+ * chunk.map(id => ({ id }))
82
+ * );
83
+ * return response;
84
+ * },
85
+ * { numWorkers: 5 } // Process at most 5 chunks concurrently
86
+ * );
87
+ * // Result: All assets from all chunks combined
88
+ * ```
89
+ *
90
+ * @example
91
+ * ```ts
92
+ * // Handle partial execution errors
93
+ * try {
94
+ * const results = await chunkAndProcessInParallel(
95
+ * largeDataset,
96
+ * 100,
97
+ * async (chunk) => processChunk(chunk),
98
+ * { numWorkers: 3 }
99
+ * );
100
+ * } catch (error) {
101
+ * if (error instanceof PartialExecutionError) {
102
+ * console.log(`Successfully processed ${error.succeeded.length} items`);
103
+ * console.log(`Failed to process ${error.failed.length} items`);
104
+ * console.log(`Did not attempt ${error.unprocessed.length} items`);
105
+ * console.error('Failure reason:', error.reason);
106
+ * // Optionally retry only the failed and unprocessed items
107
+ * }
108
+ * throw error;
109
+ * }
110
+ * ```
111
+ */
112
+ export declare function chunkAndProcessInParallel<T, U>(workItems: T[], chunkSize: number, performWorkCallback: (workItemsChunk: T[]) => Promise<U[]>, options?: ChunkAndProcessOptions): Promise<U[]>;
@@ -0,0 +1,30 @@
1
+ import { chunkArray as e } from "./chunk-array.js";
2
+ //#region libs/shared/underscore/src/chunk-and-process-in-parallel.ts
3
+ var t = class extends Error {
4
+ constructor(e, t, n, r, i) {
5
+ super(`${e.message} (succeeded: ${t.length}, failed: ${r.length}, unprocessed: ${i.length})`), this.name = "PartialExecutionError", this.reason = e, this.succeeded = t, this.succeededResults = n, this.failed = r, this.unprocessed = i, this.message = `Processing failed for ${r.length} items: ${e.message}`;
6
+ }
7
+ };
8
+ async function n(n, r, i, a) {
9
+ let o = a?.numWorkers ?? 10;
10
+ if (o <= 0 || !Number.isInteger(o)) throw Error("numWorkers must be a positive integer");
11
+ let s = Array.from(e(n, r));
12
+ if (s.length === 0) return [];
13
+ let c = Array(s.length), l = 0, u = !1, d = /* @__PURE__ */ new Set(), f = async () => {
14
+ for (; !u && l < s.length;) {
15
+ let e = l++;
16
+ try {
17
+ let t = await i(s[e]);
18
+ c[e] = t, d.add(e);
19
+ } catch (n) {
20
+ u = !0;
21
+ let r = [], i = [], a = [];
22
+ for (let t = 0; t < s.length; t++) d.has(t) ? (r.push(...s[t]), i.push(...c[t])) : t !== e && a.push(...s[t]);
23
+ throw new t(n instanceof Error ? n : Error(String(n)), r, i, s[e], a);
24
+ }
25
+ }
26
+ }, p = Array.from({ length: Math.min(o, s.length) }, () => f());
27
+ return await Promise.all(p), c.flat();
28
+ }
29
+ //#endregion
30
+ export { t as PartialExecutionError, n as chunkAndProcessInParallel };
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Splits an array into smaller chunks of a specified size using a generator. If the
3
+ * array length is not evenly divisible by `chunkSize`, the final chunk will contain
4
+ * the remaining elements.
5
+ *
6
+ * @template T - The type of elements in the array.
7
+ * @param array - The array to split into chunks.
8
+ * @param chunkSize - The maximum size of each chunk. Must be a positive integer.
9
+ * @returns A generator that yields arrays of size `chunkSize` (or smaller for the last chunk).
10
+ * @throws {Error} If `chunkSize` is not a positive integer.
11
+ *
12
+ * @example
13
+ * ```ts
14
+ * // Basic usage
15
+ * const chunks = Array.from(chunkArray([1, 2, 3, 4, 5], 2));
16
+ * // Result: [[1, 2], [3, 4], [5]]
17
+ * ```
18
+ *
19
+ * @example
20
+ * ```ts
21
+ * // Process chunks lazily using for...of
22
+ * for (const chunk of chunkArray([1, 2, 3, 4, 5, 6], 3)) {
23
+ * console.log(chunk); // Logs: [1, 2, 3], then [4, 5, 6]
24
+ * }
25
+ * ```
26
+ */
27
+ export declare function chunkArray<T>(array: T[], chunkSize: number): Generator<T[], void, unknown>;
@@ -0,0 +1,7 @@
1
+ //#region libs/shared/underscore/src/chunk-array.ts
2
+ function* e(e, t) {
3
+ if (t <= 0 || !Number.isInteger(t)) throw Error(`chunkSize must be an integer greater than 0, but got ${t}`);
4
+ for (let n = 0; n < e.length; n += t) yield e.slice(n, n + t);
5
+ }
6
+ //#endregion
7
+ export { e as chunkArray };
@@ -0,0 +1,12 @@
1
+ export type Class<T> = Function & {
2
+ prototype: T;
3
+ };
4
+ /**
5
+ * Returns true if the value is an instance of the given class type.
6
+ *
7
+ * @template T - The type of the class instance.
8
+ * @param value - The value to check
9
+ * @param classType - The class type to expect.
10
+ * @returns True if the value is an instance of the given class type.
11
+ */
12
+ export declare function isInstanceOf<T>(value: unknown, classType: Class<T>): value is T;
package/dist/class.js ADDED
@@ -0,0 +1,6 @@
1
+ //#region libs/shared/underscore/src/class.ts
2
+ function e(e, t) {
3
+ return e instanceof t;
4
+ }
5
+ //#endregion
6
+ export { e as isInstanceOf };
@@ -0,0 +1,17 @@
1
+ /**
2
+ * This will cause a type error if the switch statement is not exhaustive.
3
+ *
4
+ * @example
5
+ * ```ts
6
+ * type Value = 'a' | 'b';
7
+ * const value: Value = 'a';
8
+ * switch (value) {
9
+ * case 'a':
10
+ * return 'A';
11
+ * default:
12
+ * // This will cause a type error as we are missing the case for 'b'
13
+ * return exhaustiveGuard(value);
14
+ * }
15
+ * ```
16
+ */
17
+ export declare function exhaustiveGuard(_value: never): never;
@@ -0,0 +1,6 @@
1
+ //#region libs/shared/underscore/src/exhaustive-guard.ts
2
+ function e(e) {
3
+ throw Error(`ERROR! Reached forbidden guard function with unexpected value: ${JSON.stringify(e)}`);
4
+ }
5
+ //#endregion
6
+ export { e as exhaustiveGuard };
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Calculates the delay in milliseconds for the next retry attempt. Uses "exponential backoff with
3
+ * full jitter" algorithm.
4
+ *
5
+ * `floor(random() * min(2 ** attempt * baseDelayInMs, maxDelayInMs))`
6
+ *
7
+ * @see https://aws.amazon.com/blogs/architecture/exponential-backoff-and-jitter/
8
+ *
9
+ * @param attempt - The current attempt (1-based).
10
+ * @param baseDelayInMs - The base delay in milliseconds. Default is 250ms.
11
+ * @param maxDelayInMs - The maximum delay in milliseconds. Default is 15,000ms (15 seconds).
12
+ * @param randomCallback - A callback function that returns a random number between 0 (inclusive) and 1 (exclusive). Default is Math.random. Provided for testing/mocking purposes.
13
+ * @returns The delay in milliseconds for the next retry attempt.
14
+ */
15
+ export declare function exponentialBackoffWithJitter(attempt: number, baseDelayInMs?: number, maxDelayInMs?: number, randomCallback?: typeof Math.random): number;
@@ -0,0 +1,8 @@
1
+ //#region libs/shared/underscore/src/exponential-backoff-with-jitter.ts
2
+ function e(e, t = 250, n = 15e3, r = Math.random) {
3
+ if (e < 1) throw Error("`attempt` must be 1 or greater");
4
+ let i = 2 ** e * t, a = Math.min(i, n);
5
+ return Math.floor(r() * a);
6
+ }
7
+ //#endregion
8
+ export { e as exponentialBackoffWithJitter };
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Generates a unique name based on a prefix and existing names.
3
+ * If no existing names match the prefix, returns the prefix as-is.
4
+ * Otherwise, appends the next available number to the prefix.
5
+ *
6
+ * @param existingNames - Array of existing names to check against
7
+ * @param prefix - The prefix to use for the unique name
8
+ * @returns A unique name that doesn't conflict with existing names
9
+ *
10
+ * @example
11
+ * ```typescript
12
+ * generateUniqueName(['Untitled evaluation', 'Untitled evaluation 1'], 'Untitled evaluation')
13
+ * // Returns: 'Untitled evaluation 2'
14
+ *
15
+ * generateUniqueName(['Other name'], 'Untitled evaluation')
16
+ * // Returns: 'Untitled evaluation'
17
+ * ```
18
+ */
19
+ export declare function generateUniqueName(existingNames: string[], prefix: string): string;
@@ -0,0 +1,11 @@
1
+ //#region libs/shared/underscore/src/generate-unique-name.ts
2
+ function e(e, t) {
3
+ let n = e.filter((e) => e.startsWith(t));
4
+ return n.length === 0 ? t : `${t} ${n.reduce((e, n) => {
5
+ if (n === t) return Math.max(e, 0);
6
+ let r = t.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"), i = n.match(RegExp(`^${r} (\\d+)(?:.*)?$`));
7
+ return i || (i = n.match(RegExp(`^${r}[^\\w]*(\\d+)(?:.*)?$`)), i) ? Math.max(e, parseInt(i[1], 10)) : Math.max(e, 0);
8
+ }, 0) + 1}`;
9
+ }
10
+ //#endregion
11
+ export { e as generateUniqueName };
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Generates a sequence of numbers between the specified range.
3
+ *
4
+ * @param minInclusive - The starting number of the sequence (inclusive).
5
+ * @param maxExclusive - The ending number of the sequence (exclusive).
6
+ * @param step - The step value to increment by (default is 1).
7
+ * @returns A generator that yields numbers between the specified range.
8
+ *
9
+ * @example
10
+ * ```ts
11
+ * const numbers = getNumbersBetween(1, 5);
12
+ * for (const num of numbers) {
13
+ * console.log(num); // 1, 2, 3, 4
14
+ * }
15
+ * ```
16
+ */
17
+ export declare function getNumbersBetween(minInclusive: number, maxExclusive: number, step?: number): Generator<number>;
@@ -0,0 +1,6 @@
1
+ //#region libs/shared/underscore/src/get-numbers-between.ts
2
+ function* e(e, t, n = 1) {
3
+ for (let r = e; r < t; r += n) yield r;
4
+ }
5
+ //#endregion
6
+ export { e as getNumbersBetween };
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Turns nested objects and arrays into a flat, human-readable string for UI display.
3
+ * Null, undefined, NaN, and empty collections render as `'-'`.
4
+ */
5
+ export declare function humanizeValue(value: unknown): string;
@@ -0,0 +1,16 @@
1
+ import { isArray as e, isNaN as t, isObject as n } from "lodash-es";
2
+ //#region libs/shared/underscore/src/humanize-value.ts
3
+ function r(i) {
4
+ if (i == null || t(i) || e(i) && i.length === 0 || n(i) && Object.keys(i).length === 0) return "-";
5
+ let a = "", o = (t) => {
6
+ e(t) ? t.forEach((e) => {
7
+ o(e);
8
+ }) : n(t) ? Object.entries(t).forEach(([e, t]) => {
9
+ let n = r(t);
10
+ a += `${e}: ${n} `;
11
+ }) : a += `${String(t)} `;
12
+ };
13
+ return o(i), a.trim();
14
+ }
15
+ //#endregion
16
+ export { r as humanizeValue };
@@ -0,0 +1,23 @@
1
+ export { insertAt, remove, removeAt, swap, shuffle } from './arrays';
2
+ export { assert } from './assert';
3
+ export type { Brand } from './brand';
4
+ export { chunkAndProcessInParallel } from './chunk-and-process-in-parallel';
5
+ export { chunkArray } from './chunk-array';
6
+ export { isInstanceOf, type Class } from './class';
7
+ export { exhaustiveGuard } from './exhaustive-guard';
8
+ export { exponentialBackoffWithJitter } from './exponential-backoff-with-jitter';
9
+ export { generateUniqueName } from './generate-unique-name';
10
+ export { getNumbersBetween } from './get-numbers-between';
11
+ export { humanizeValue } from './humanize-value';
12
+ export { isFunction } from './is-function';
13
+ export { isPrimitive } from './is-primitive';
14
+ export { isValidUrl } from './is-valid-url';
15
+ export { every } from './iterators';
16
+ export { isEven, isOdd } from './math';
17
+ export { randomString, randomInteger, randomFloat, randomElement, } from './random';
18
+ export { repeat } from './repeat';
19
+ export { retryAsync } from './retry-async';
20
+ export { sleep } from './sleep';
21
+ export { capitalizeFirstLetter, kebabToPascalCase, toKebabCase, } from './string';
22
+ export type { KeySerializer } from './structMap';
23
+ export { stableStringify, StructMap } from './structMap';
package/dist/index.js ADDED
@@ -0,0 +1,23 @@
1
+ import { repeat as e } from "./repeat.js";
2
+ import { randomElement as t, randomFloat as n, randomInteger as r, randomString as i } from "./random.js";
3
+ import { insertAt as a, remove as o, removeAt as s, shuffle as c, swap as l } from "./arrays.js";
4
+ import { assert as u } from "./assert.js";
5
+ import { chunkArray as d } from "./chunk-array.js";
6
+ import { chunkAndProcessInParallel as f } from "./chunk-and-process-in-parallel.js";
7
+ import { isInstanceOf as p } from "./class.js";
8
+ import { exhaustiveGuard as m } from "./exhaustive-guard.js";
9
+ import { exponentialBackoffWithJitter as h } from "./exponential-backoff-with-jitter.js";
10
+ import { generateUniqueName as g } from "./generate-unique-name.js";
11
+ import { getNumbersBetween as _ } from "./get-numbers-between.js";
12
+ import { humanizeValue as v } from "./humanize-value.js";
13
+ import { isFunction as y } from "./is-function.js";
14
+ import { isPrimitive as b } from "./is-primitive.js";
15
+ import { isValidUrl as x } from "./is-valid-url.js";
16
+ import { every as S } from "./iterators.js";
17
+ import { isEven as C, isOdd as w } from "./math.js";
18
+ import { sleep as T } from "./sleep.js";
19
+ import { retryAsync as E } from "./retry-async.js";
20
+ import { capitalizeFirstLetter as D, kebabToPascalCase as O, toKebabCase as k } from "./string.js";
21
+ import { stableStringify as A } from "./structMap/stableStringify.js";
22
+ import { StructMap as j } from "./structMap/structMap.js";
23
+ export { j as StructMap, u as assert, D as capitalizeFirstLetter, f as chunkAndProcessInParallel, d as chunkArray, S as every, m as exhaustiveGuard, h as exponentialBackoffWithJitter, g as generateUniqueName, _ as getNumbersBetween, v as humanizeValue, a as insertAt, C as isEven, y as isFunction, p as isInstanceOf, w as isOdd, b as isPrimitive, x as isValidUrl, O as kebabToPascalCase, t as randomElement, n as randomFloat, r as randomInteger, i as randomString, o as remove, s as removeAt, e as repeat, E as retryAsync, c as shuffle, T as sleep, A as stableStringify, l as swap, k as toKebabCase };
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Checks if the given value is a function.
3
+ *
4
+ * @param maybeFunction - The value to check.
5
+ * @returns True if the value is a function, otherwise false.
6
+ */
7
+ export declare function isFunction(maybeFunction: unknown): maybeFunction is Function;
@@ -0,0 +1,6 @@
1
+ //#region libs/shared/underscore/src/is-function.ts
2
+ function e(e) {
3
+ return typeof e == "function";
4
+ }
5
+ //#endregion
6
+ export { e as isFunction };
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Checks if the given value is a primitive.
3
+ * Primitives include: string, number, boolean, null, undefined, symbol, and bigint.
4
+ * {@link https://developer.mozilla.org/en-US/docs/Glossary/Primitive}
5
+ *
6
+ * @param value - The value to check.
7
+ * @returns Returns true if the value is a primitive, false otherwise.
8
+ */
9
+ export declare function isPrimitive(value: unknown): boolean;
@@ -0,0 +1,7 @@
1
+ //#region libs/shared/underscore/src/is-primitive.ts
2
+ function e(e) {
3
+ let t = typeof e;
4
+ return e === null || t === "string" || t === "number" || t === "boolean" || t === "undefined" || t === "symbol" || t === "bigint";
5
+ }
6
+ //#endregion
7
+ export { e as isPrimitive };
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Inspired by: https://github.com/segmentio/is-url
3
+ */
4
+ /**
5
+ * Checks if a value is a valid URL.
6
+ *
7
+ * A valid URL must:
8
+ * - Be a string.
9
+ * - Start with "http://" or "https://".
10
+ * - Contain a valid domain name.
11
+ * - Not contain spaces in the host part.
12
+ *
13
+ * @param {unknown} value - The value to be checked.
14
+ * @returns {value is string} - Returns `true` if the value is a valid URL, otherwise `false`.
15
+ */
16
+ export declare function isValidUrl(value: unknown): value is string;
@@ -0,0 +1,17 @@
1
+ //#region libs/shared/underscore/src/is-valid-url.ts
2
+ var e = /^(https?):\/\/(\S+)$/, t = /^[^\s\\.]+\.\S{2,}$/;
3
+ function n(n) {
4
+ if (typeof n != "string") return !1;
5
+ let r = n.match(e);
6
+ if (!r) return !1;
7
+ let i = r[2];
8
+ if (!i || !t.test(i)) return !1;
9
+ try {
10
+ let e = new URL(n);
11
+ return e.protocol === "http:" || e.protocol === "https:";
12
+ } catch {
13
+ return !1;
14
+ }
15
+ }
16
+ //#endregion
17
+ export { n as isValidUrl };
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Tests whether all elements in the iterable pass the test implemented by the provided predicate function.
3
+ *
4
+ * @template T - The type of elements in the iterable.
5
+ * @param {Iterable<T>} iterable - The iterable to be tested.
6
+ * @param {(value: T) => boolean} predicate - A function that tests each element of the iterable.
7
+ * @returns {boolean} - Returns `true` if all elements pass the test, otherwise `false`.
8
+ */
9
+ export declare function every<T>(iterable: Iterable<T>, predicate: (value: T) => boolean): boolean;
@@ -0,0 +1,7 @@
1
+ //#region libs/shared/underscore/src/iterators.ts
2
+ function e(e, t) {
3
+ for (let n of e) if (!t(n)) return !1;
4
+ return !0;
5
+ }
6
+ //#endregion
7
+ export { e as every };