@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.
- package/README.md +40 -0
- package/dist/arrays.d.ts +41 -0
- package/dist/arrays.js +23 -0
- package/dist/assert.d.ts +8 -0
- package/dist/assert.js +6 -0
- package/dist/brand.d.ts +42 -0
- package/dist/chunk-and-process-in-parallel.d.ts +112 -0
- package/dist/chunk-and-process-in-parallel.js +30 -0
- package/dist/chunk-array.d.ts +27 -0
- package/dist/chunk-array.js +7 -0
- package/dist/class.d.ts +12 -0
- package/dist/class.js +6 -0
- package/dist/exhaustive-guard.d.ts +17 -0
- package/dist/exhaustive-guard.js +6 -0
- package/dist/exponential-backoff-with-jitter.d.ts +15 -0
- package/dist/exponential-backoff-with-jitter.js +8 -0
- package/dist/generate-unique-name.d.ts +19 -0
- package/dist/generate-unique-name.js +11 -0
- package/dist/get-numbers-between.d.ts +17 -0
- package/dist/get-numbers-between.js +6 -0
- package/dist/humanize-value.d.ts +5 -0
- package/dist/humanize-value.js +16 -0
- package/dist/index.d.ts +23 -0
- package/dist/index.js +23 -0
- package/dist/is-function.d.ts +7 -0
- package/dist/is-function.js +6 -0
- package/dist/is-primitive.d.ts +9 -0
- package/dist/is-primitive.js +7 -0
- package/dist/is-valid-url.d.ts +16 -0
- package/dist/is-valid-url.js +17 -0
- package/dist/iterators.d.ts +9 -0
- package/dist/iterators.js +7 -0
- package/dist/math.d.ts +14 -0
- package/dist/math.js +9 -0
- package/dist/random.d.ts +32 -0
- package/dist/random.js +22 -0
- package/dist/react/use-debounce.d.ts +23 -0
- package/dist/react/use-debounce.js +15 -0
- package/dist/react/use-derived-promise.d.ts +34 -0
- package/dist/react/use-derived-promise.js +34 -0
- package/dist/react/use-stable-sync-external-store.d.ts +27 -0
- package/dist/react/use-stable-sync-external-store.js +12 -0
- package/dist/react.d.ts +3 -0
- package/dist/react.js +4 -0
- package/dist/repeat.d.ts +7 -0
- package/dist/repeat.js +6 -0
- package/dist/retry-async.d.ts +92 -0
- package/dist/retry-async.js +18 -0
- package/dist/sleep.d.ts +7 -0
- package/dist/sleep.js +6 -0
- package/dist/string.d.ts +41 -0
- package/dist/string.js +12 -0
- package/dist/structMap/index.d.ts +3 -0
- package/dist/structMap/stableStringify.d.ts +23 -0
- package/dist/structMap/stableStringify.js +24 -0
- package/dist/structMap/structMap.d.ts +110 -0
- package/dist/structMap/structMap.js +29 -0
- package/dist/structMap/testUtils.d.ts +17 -0
- package/dist/structMap/types.d.ts +7 -0
- 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`.
|
package/dist/arrays.d.ts
ADDED
|
@@ -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 };
|
package/dist/assert.d.ts
ADDED
|
@@ -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
package/dist/brand.d.ts
ADDED
|
@@ -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 };
|
package/dist/class.d.ts
ADDED
|
@@ -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,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,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,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 };
|
package/dist/index.d.ts
ADDED
|
@@ -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,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;
|