@elyukai/utils 0.1.2

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 (67) hide show
  1. package/AUTHORS +1 -0
  2. package/CHANGELOG.md +46 -0
  3. package/LICENSE +373 -0
  4. package/README.md +1 -0
  5. package/dist/array/filters.d.ts +14 -0
  6. package/dist/array/filters.js +24 -0
  7. package/dist/array/generators.d.ts +9 -0
  8. package/dist/array/generators.js +13 -0
  9. package/dist/array/groups.d.ts +24 -0
  10. package/dist/array/groups.js +45 -0
  11. package/dist/array/modify.d.ts +21 -0
  12. package/dist/array/modify.js +57 -0
  13. package/dist/array/nonEmpty.d.ts +23 -0
  14. package/dist/array/nonEmpty.js +15 -0
  15. package/dist/array/reductions.d.ts +39 -0
  16. package/dist/array/reductions.js +58 -0
  17. package/dist/array/sets.d.ts +17 -0
  18. package/dist/array/sets.js +19 -0
  19. package/dist/array.d.ts +4 -0
  20. package/dist/array.js +5 -0
  21. package/dist/async.d.ts +11 -0
  22. package/dist/async.js +11 -0
  23. package/dist/classList.d.ts +5 -0
  24. package/dist/classList.js +17 -0
  25. package/dist/compare.d.ts +44 -0
  26. package/dist/compare.js +73 -0
  27. package/dist/date.d.ts +5 -0
  28. package/dist/date.js +5 -0
  29. package/dist/dictionary/native.d.ts +116 -0
  30. package/dist/dictionary/native.js +142 -0
  31. package/dist/dictionary.d.ts +115 -0
  32. package/dist/dictionary.js +178 -0
  33. package/dist/equality.d.ts +44 -0
  34. package/dist/equality.js +53 -0
  35. package/dist/function.d.ts +48 -0
  36. package/dist/function.js +52 -0
  37. package/dist/lazy.d.ts +16 -0
  38. package/dist/lazy.js +32 -0
  39. package/dist/math.d.ts +47 -0
  40. package/dist/math.js +56 -0
  41. package/dist/maybe.d.ts +51 -0
  42. package/dist/maybe.js +36 -0
  43. package/dist/nullable.d.ts +50 -0
  44. package/dist/nullable.js +35 -0
  45. package/dist/number.d.ts +16 -0
  46. package/dist/number.js +16 -0
  47. package/dist/object.d.ts +40 -0
  48. package/dist/object.js +58 -0
  49. package/dist/ordering.d.ts +30 -0
  50. package/dist/ordering.js +46 -0
  51. package/dist/range.d.ts +37 -0
  52. package/dist/range.js +41 -0
  53. package/dist/regex.d.ts +28 -0
  54. package/dist/regex.js +35 -0
  55. package/dist/result.d.ts +54 -0
  56. package/dist/result.js +45 -0
  57. package/dist/roman.d.ts +4 -0
  58. package/dist/roman.js +47 -0
  59. package/dist/string/number.d.ts +31 -0
  60. package/dist/string/number.js +40 -0
  61. package/dist/string/regex.d.ts +28 -0
  62. package/dist/string/regex.js +38 -0
  63. package/dist/string.d.ts +32 -0
  64. package/dist/string.js +96 -0
  65. package/dist/typeSafety.d.ts +38 -0
  66. package/dist/typeSafety.js +33 -0
  67. package/package.json +46 -0
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Types and functions to check for non-empty arrays.
3
+ */
4
+ /**
5
+ * Checks if the array is empty.
6
+ */
7
+ export const isEmpty = (arr) => arr.length === 0;
8
+ /**
9
+ * Checks if the array is not empty, i.e., contains at least one element.
10
+ */
11
+ export const isNotEmpty = (arr) => !isEmpty(arr);
12
+ /**
13
+ * Returns `undefined` if the array is empty, otherwise the non-empty array.
14
+ */
15
+ export const ensureNonEmpty = (arr) => isNotEmpty(arr) ? arr : undefined;
@@ -0,0 +1,39 @@
1
+ /**
2
+ * Reduces an array, but stops as soon as the predicate returns `true` for an
3
+ * accumulated value (including the initial value) and returns the last
4
+ * accumulated value.
5
+ * @param arr The array to reduce.
6
+ * @param fn The function to apply to each element in the array.
7
+ * @param pred The predicate to apply to the initial value and to every result
8
+ * of a call to `fn`, where if it returns `true`, the reduction stops.
9
+ * @param initial The initial value.
10
+ */
11
+ export declare const reduceWhile: <T, U>(arr: T[], fn: (acc: U, value: T, index: number) => U, pred: (acc: U) => boolean, initial: U) => U;
12
+ /**
13
+ * Returns the sum of all numbers in the given array.
14
+ */
15
+ export declare const sum: (arr: number[]) => number;
16
+ /**
17
+ * Returns the sum of values returned by applying the given function to each
18
+ * element in the array.
19
+ */
20
+ export declare const sumWith: <T>(arr: T[], fn: (value: T, index: number) => number) => number;
21
+ /**
22
+ * Counts the number of elements in an array that satisfy the given predicate.
23
+ */
24
+ export declare const count: <T>(arr: T[], predicate: (value: T, index: number) => boolean) => number;
25
+ /**
26
+ * Counts the number of elements the function returns the same value for and
27
+ * returns the count for all returned values as an object.
28
+ */
29
+ export declare const countBy: <T, K extends string | number | symbol>(arr: T[], fn: (value: T, index: number) => K) => Partial<Record<K, number>>;
30
+ /**
31
+ * Counts the number of elements the function returns the same values for and
32
+ * returns the count for all returned values as an object.
33
+ */
34
+ export declare const countByMany: <T, K extends string | number | symbol>(arr: T[], fn: (value: T, index: number) => K[]) => Partial<Record<K, number>>;
35
+ /**
36
+ * Returns `true` if the array contains at least `minCount` elements that
37
+ * satisfy the given predicate, `false` otherwise.
38
+ */
39
+ export declare const someCount: <T>(arr: T[], predicate: (value: T) => boolean, minCount: number) => boolean;
@@ -0,0 +1,58 @@
1
+ import { unique } from "./filters.js";
2
+ /**
3
+ * Reduces an array, but stops as soon as the predicate returns `true` for an
4
+ * accumulated value (including the initial value) and returns the last
5
+ * accumulated value.
6
+ * @param arr The array to reduce.
7
+ * @param fn The function to apply to each element in the array.
8
+ * @param pred The predicate to apply to the initial value and to every result
9
+ * of a call to `fn`, where if it returns `true`, the reduction stops.
10
+ * @param initial The initial value.
11
+ */
12
+ export const reduceWhile = (arr, fn, pred, initial) => {
13
+ let acc = initial;
14
+ let index = 0;
15
+ while (index < arr.length && !pred(acc)) {
16
+ acc = fn(acc, arr[index], index);
17
+ index++;
18
+ }
19
+ return acc;
20
+ };
21
+ /**
22
+ * Returns the sum of all numbers in the given array.
23
+ */
24
+ export const sum = (arr) => arr.reduce((acc, value) => acc + value, 0);
25
+ /**
26
+ * Returns the sum of values returned by applying the given function to each
27
+ * element in the array.
28
+ */
29
+ export const sumWith = (arr, fn) => arr.reduce((acc, value, index) => acc + fn(value, index), 0);
30
+ /**
31
+ * Counts the number of elements in an array that satisfy the given predicate.
32
+ */
33
+ export const count = (arr, predicate) => sumWith(arr, (value, index) => (predicate(value, index) ? 1 : 0));
34
+ /**
35
+ * Counts the number of elements the function returns the same value for and
36
+ * returns the count for all returned values as an object.
37
+ */
38
+ export const countBy = (arr, fn) => arr.reduce((acc, value, index) => {
39
+ const key = fn(value, index);
40
+ acc[key] = (acc[key] ?? 0) + 1;
41
+ return acc;
42
+ }, {});
43
+ /**
44
+ * Counts the number of elements the function returns the same values for and
45
+ * returns the count for all returned values as an object.
46
+ */
47
+ export const countByMany = (arr, fn) => arr.reduce((acc, value, index) => {
48
+ const keys = fn(value, index);
49
+ unique(keys).forEach((key) => {
50
+ acc[key] = (acc[key] ?? 0) + 1;
51
+ });
52
+ return acc;
53
+ }, {});
54
+ /**
55
+ * Returns `true` if the array contains at least `minCount` elements that
56
+ * satisfy the given predicate, `false` otherwise.
57
+ */
58
+ export const someCount = (arr, predicate, minCount) => reduceWhile(arr, (acc, value) => (predicate(value) ? acc + 1 : acc), (acc) => acc >= minCount, 0) >= minCount;
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Calculates the difference between two arrays, including duplicated values.
3
+ * @param oldArr - The original array.
4
+ * @param newArr - The new array to compare against.
5
+ * @returns An object containing the added and removed elements.
6
+ */
7
+ export declare const difference: <T>(oldArr: T[], newArr: T[]) => ArrayDiffResult<T>;
8
+ export interface ArrayDiffResult<T> {
9
+ /**
10
+ * Elements in `newArr` that are not in `oldArr`.
11
+ */
12
+ added: T[];
13
+ /**
14
+ * Elements in `oldArr` that are not in `newArr`.
15
+ */
16
+ removed: T[];
17
+ }
@@ -0,0 +1,19 @@
1
+ import { removeAt } from "./modify.js";
2
+ /**
3
+ * Calculates the difference between two arrays, including duplicated values.
4
+ * @param oldArr - The original array.
5
+ * @param newArr - The new array to compare against.
6
+ * @returns An object containing the added and removed elements.
7
+ */
8
+ export const difference = (oldArr, newArr) => newArr.reduce((acc, item) => {
9
+ const oldIndex = acc.removed.indexOf(item);
10
+ const newIndex = acc.added.indexOf(item);
11
+ if (oldIndex > -1) {
12
+ return {
13
+ ...acc,
14
+ removed: removeAt(acc.removed, oldIndex),
15
+ added: removeAt(acc.added, newIndex),
16
+ };
17
+ }
18
+ return acc;
19
+ }, { removed: oldArr, added: newArr });
@@ -0,0 +1,4 @@
1
+ /**
2
+ * Returns `true` if the two arrays are equal, `false` otherwise.
3
+ */
4
+ export declare const arrayEqual: <T extends number | boolean | string | symbol | null | undefined>(arr1: T[], arr2: T[]) => boolean;
package/dist/array.js ADDED
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Returns `true` if the two arrays are equal, `false` otherwise.
3
+ */
4
+ export const arrayEqual = (arr1, arr2) => arr1.length === arr2.length &&
5
+ arr1.every((value, index) => value === arr2[index]);
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Returns a promise that resolves after a specified delay in milliseconds.
3
+ * @param delay The delay in milliseconds.
4
+ * @returns A promise that resolves after the specified delay.
5
+ *
6
+ * @example
7
+ * ```ts
8
+ * await wait(1000); // Waits for 1 second
9
+ * ```
10
+ */
11
+ export declare const wait: (delay: number) => Promise<void>;
package/dist/async.js ADDED
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Returns a promise that resolves after a specified delay in milliseconds.
3
+ * @param delay The delay in milliseconds.
4
+ * @returns A promise that resolves after the specified delay.
5
+ *
6
+ * @example
7
+ * ```ts
8
+ * await wait(1000); // Waits for 1 second
9
+ * ```
10
+ */
11
+ export const wait = (delay) => new Promise((resolve) => setTimeout(resolve, delay));
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Returns a string of class names from the given arguments. Filters out
3
+ * nullable values and keys with falsey values.
4
+ */
5
+ export declare const classList: (...cls: (string | null | undefined | Record<string, boolean | undefined>)[]) => string;
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Returns a string of class names from the given arguments. Filters out
3
+ * nullable values and keys with falsey values.
4
+ */
5
+ export const classList = (...cls) => cls
6
+ .flatMap((cl) => {
7
+ if (cl === null || cl === undefined) {
8
+ return [];
9
+ }
10
+ else if (typeof cl === "string") {
11
+ return [cl];
12
+ }
13
+ else {
14
+ return Object.entries(cl).flatMap(([k, v]) => (v === true ? [k] : []));
15
+ }
16
+ })
17
+ .join(" ");
@@ -0,0 +1,44 @@
1
+ /**
2
+ * The type of a compare function that can be used to sort values.
3
+ * @returns A negative number if `a` should be sorted before `b`, a positive
4
+ * number if `a` should be sorted after `b`, or zero if `a` and `b` are equal.
5
+ */
6
+ export type Compare<T> = (a: T, b: T) => number;
7
+ /**
8
+ * Build a compare function for values that are nested inside other values. The
9
+ * nested value is getting extracted by the provided accessor function and then
10
+ * compared using the provided compare function. An optional `reverse` parameter
11
+ * can be used to reverse the sort order.
12
+ */
13
+ export declare const compareAt: <T, U>(accessor: (value: T) => U, compare: (a: U, b: U) => number, reverse?: boolean) => Compare<T>;
14
+ /**
15
+ * Build a compare function that nests multiple compare functions. The functions
16
+ * are applied in order, so the first function is the primary sort key, the
17
+ * second function is the secondary sort key, and so on.
18
+ */
19
+ export declare const reduceCompare: <T>(...compares: Compare<T>[]) => Compare<T>;
20
+ /**
21
+ * Compare function for numbers that sorts them in ascending order.
22
+ */
23
+ export declare const numAsc: Compare<number>;
24
+ /**
25
+ * Higher-order compare function that extends a compare function to also handle
26
+ * `null` and `undefined` values. Nullish values are always sorted first.
27
+ */
28
+ export declare const compareNullish: <T extends NonNullable<unknown>>(compare: Compare<T>) => (a: T | null | undefined, b: T | null | undefined) => number;
29
+ /**
30
+ * A function that compares two values for equality.
31
+ */
32
+ export type Equality<T> = (a: T, b: T) => boolean;
33
+ /**
34
+ * Build an equality function for values that are nested inside other values.
35
+ * The nested value is getting extracted by the provided accessor function and
36
+ * then compared using the provided equality function.
37
+ */
38
+ export declare const equalityAt: <T, U>(accessor: (value: T) => U, equality: Equality<U>) => Equality<T>;
39
+ /**
40
+ * Checks two values for value equality. This is a deep equality check that
41
+ * works for all types, including objects and arrays. For objects, it only
42
+ * compares all enumerable keys, no other properties or the prototype chain.
43
+ */
44
+ export declare const deepEqual: <T>(a: T, b: T) => boolean;
@@ -0,0 +1,73 @@
1
+ import { isNullish } from "./nullable.js";
2
+ /**
3
+ * Build a compare function for values that are nested inside other values. The
4
+ * nested value is getting extracted by the provided accessor function and then
5
+ * compared using the provided compare function. An optional `reverse` parameter
6
+ * can be used to reverse the sort order.
7
+ */
8
+ export const compareAt = (accessor, compare, reverse = false) => (a, b) => {
9
+ const result = compare(accessor(a), accessor(b));
10
+ return reverse ? -result : result;
11
+ };
12
+ /**
13
+ * Build a compare function that nests multiple compare functions. The functions
14
+ * are applied in order, so the first function is the primary sort key, the
15
+ * second function is the secondary sort key, and so on.
16
+ */
17
+ export const reduceCompare = (...compares) => (a, b) => {
18
+ for (const compare of compares) {
19
+ const result = compare(a, b);
20
+ if (result !== 0) {
21
+ return result;
22
+ }
23
+ }
24
+ return 0;
25
+ };
26
+ /**
27
+ * Compare function for numbers that sorts them in ascending order.
28
+ */
29
+ export const numAsc = (a, b) => a - b;
30
+ /**
31
+ * Higher-order compare function that extends a compare function to also handle
32
+ * `null` and `undefined` values. Nullish values are always sorted first.
33
+ */
34
+ export const compareNullish = (compare) => (a, b) => {
35
+ if (isNullish(a) && isNullish(b)) {
36
+ return 0;
37
+ }
38
+ if (isNullish(a)) {
39
+ return -1;
40
+ }
41
+ if (isNullish(b)) {
42
+ return 1;
43
+ }
44
+ return compare(a, b);
45
+ };
46
+ /**
47
+ * Build an equality function for values that are nested inside other values.
48
+ * The nested value is getting extracted by the provided accessor function and
49
+ * then compared using the provided equality function.
50
+ */
51
+ export const equalityAt = (accessor, equality) => (a, b) => equality(accessor(a), accessor(b));
52
+ /**
53
+ * Checks two values for value equality. This is a deep equality check that
54
+ * works for all types, including objects and arrays. For objects, it only
55
+ * compares all enumerable keys, no other properties or the prototype chain.
56
+ */
57
+ export const deepEqual = (a, b) => {
58
+ if (a === b) {
59
+ return true;
60
+ }
61
+ if (typeof a === "object" &&
62
+ typeof b === "object" &&
63
+ a !== null &&
64
+ b !== null) {
65
+ const keys = Object.keys(a);
66
+ if (keys.length !== Object.keys(b).length) {
67
+ return false;
68
+ }
69
+ return keys.every((key) => key in b &&
70
+ deepEqual(a[key], b[key]));
71
+ }
72
+ return false;
73
+ };
package/dist/date.d.ts ADDED
@@ -0,0 +1,5 @@
1
+ import { Compare } from "./compare.js";
2
+ /**
3
+ * A comparator function for {@link Date} objects in ascending order.
4
+ */
5
+ export declare const compareDate: Compare<Date>;
package/dist/date.js ADDED
@@ -0,0 +1,5 @@
1
+ import { Compare } from "./compare.js";
2
+ /**
3
+ * A comparator function for {@link Date} objects in ascending order.
4
+ */
5
+ export const compareDate = (a, b) => a.getTime() - b.getTime();
@@ -0,0 +1,116 @@
1
+ /**
2
+ * Introduces helper functions for a native dictionary, which is an index object.
3
+ */
4
+ import type { AnyNonNullish } from "../nullable.js";
5
+ /**
6
+ * An alias for a native dictionary.
7
+ */
8
+ export type Dictionary<T extends AnyNonNullish | null> = Readonly<Record<string, T>>;
9
+ /**
10
+ * An empty dictionary.
11
+ */
12
+ export declare const empty: Dictionary<never>;
13
+ /**
14
+ * Constructs a dictionary from an array of key-value pairs.
15
+ */
16
+ export declare const fromEntries: <T extends AnyNonNullish | null>(entries: [string, T][]) => Dictionary<T>;
17
+ /**
18
+ * Returns the value associated with the given key, or `undefined` if the key does not exist.
19
+ */
20
+ export declare const get: <T extends AnyNonNullish | null>(dict: Dictionary<T>, key: string) => T | undefined;
21
+ /**
22
+ * Returns the value associated with the given key mapped through the given function, or `undefined` if the key does not exist.
23
+ */
24
+ export declare const getMap: <T extends AnyNonNullish | null, U>(dict: Dictionary<T>, key: string, mapFn: (value: T) => U) => U | undefined;
25
+ /**
26
+ * Checks if the dictionary has the given key.
27
+ */
28
+ export declare const has: <T extends AnyNonNullish | null>(dict: Dictionary<T>, key: string) => boolean;
29
+ /**
30
+ * Sets the given key to the given value.
31
+ *
32
+ * If the key already exists, its value will be overwritten.
33
+ */
34
+ export declare const set: <T extends AnyNonNullish | null>(dict: Dictionary<T>, key: string, value: T) => Dictionary<T>;
35
+ /**
36
+ * Removes the given key from the dictionary.
37
+ *
38
+ * If the key does not exist, the same dictionary instance is returned.
39
+ */
40
+ export declare const remove: <T extends AnyNonNullish | null>(dict: Dictionary<T>, key: string) => Dictionary<T>;
41
+ /**
42
+ * Returns the number of entries in the dictionary.
43
+ */
44
+ export declare const size: (dict: Dictionary<AnyNonNullish | null>) => number;
45
+ /**
46
+ * Returns an array of key-value pairs in the dictionary.
47
+ */
48
+ export declare const entries: <T extends AnyNonNullish | null>(dict: Dictionary<T>) => [string, T][];
49
+ /**
50
+ * Returns an array of values in the dictionary.
51
+ */
52
+ export declare const values: <T extends AnyNonNullish | null>(dict: Dictionary<T>) => T[];
53
+ /**
54
+ * Returns an array of keys in the dictionary.
55
+ */
56
+ export declare const keys: (dict: Dictionary<AnyNonNullish | null>) => string[];
57
+ /**
58
+ * Calls the given function for each key-value pair in the dictionary.
59
+ */
60
+ export declare const forEach: <T extends AnyNonNullish | null>(dict: Dictionary<T>, fn: (value: T, key: string) => void) => void;
61
+ /**
62
+ * Calls the given async function for each key-value pair in the dictionary.
63
+ *
64
+ * The calls are made sequentially.
65
+ */
66
+ export declare const forEachAsync: <T extends AnyNonNullish | null>(dict: Dictionary<T>, fn: (value: T, key: string) => Promise<void>) => Promise<void>;
67
+ /**
68
+ * Create, modify, or remove the value for the given key based on its current value.
69
+ *
70
+ * The value passed to `modifyFn` will be `undefined` if the key does not exist.
71
+ * If the `modifyFn` returns `undefined`, the key will be removed from the dictionary.
72
+ * Otherwise, the key will be set to the new value returned by `modifyFn`.
73
+ */
74
+ export declare const modify: <T extends AnyNonNullish | null>(dict: Dictionary<T>, key: string, modifyFn: (currentValue: T | undefined) => T | undefined) => Dictionary<T>;
75
+ /**
76
+ * Returns the first value that matches the given predicate, or `undefined` if no such value exists.
77
+ */
78
+ export declare const find: {
79
+ /**
80
+ * Returns the first value that matches the given predicate, or `undefined` if no such value exists.
81
+ */
82
+ <T extends AnyNonNullish | null, U extends T>(dict: Dictionary<T>, predicate: (value: T, key: string) => value is U): U | undefined;
83
+ /**
84
+ * Returns the first value that matches the given predicate, or `undefined` if no such value exists.
85
+ */
86
+ <T extends AnyNonNullish | null>(dict: Dictionary<T>, predicate: (value: T, key: string) => boolean): T | undefined;
87
+ };
88
+ /**
89
+ * Returns the first key that matches the given predicate, or `undefined` if no such key exists.
90
+ */
91
+ export declare const findKey: <T extends AnyNonNullish | null>(dict: Dictionary<T>, predicate: (value: T, key: string) => boolean) => string | undefined;
92
+ /**
93
+ * Returns the first key-value pair that matches the given predicate, or `undefined` if no such key-value pair exists.
94
+ */
95
+ export declare const findEntry: {
96
+ /**
97
+ * Returns the first key-value pair that matches the given predicate, or `undefined` if no such key-value pair exists.
98
+ */
99
+ <T extends AnyNonNullish | null, U extends T>(dict: Dictionary<T>, predicate: (value: T, key: string) => value is U): [key: string, value: U] | undefined;
100
+ /**
101
+ * Returns the first key-value pair that matches the given predicate, or `undefined` if no such key-value pair exists.
102
+ */
103
+ <T extends AnyNonNullish | null>(dict: Dictionary<T>, predicate: (value: T, key: string) => boolean): [key: string, value: T] | undefined;
104
+ };
105
+ /**
106
+ * Applies the given mapping function to each key-value pair in the dictionary and returns the first non-`undefined` result, or `undefined` if no such result exists.
107
+ */
108
+ export declare const mapFirst: <T extends AnyNonNullish | null, U>(dict: Dictionary<T>, mapFn: (value: T, key: string) => U | undefined) => U | undefined;
109
+ /**
110
+ * Applies a function to every key-value pair in the dictionary.
111
+ */
112
+ export declare const map: <T extends AnyNonNullish | null, U extends AnyNonNullish | null>(dict: Dictionary<T>, mapFn: (value: T, key: string) => U) => Dictionary<U>;
113
+ /**
114
+ * Calls the specified callback function for all the elements in an array. The return value of the callback function is the accumulated result, and is provided as an argument in the next call to the callback function.
115
+ */
116
+ export declare const reduce: <T extends AnyNonNullish | null, U>(dict: Dictionary<T>, reducer: (acc: U, value: T, key: string) => U, initialValue: U) => U;
@@ -0,0 +1,142 @@
1
+ /**
2
+ * Introduces helper functions for a native dictionary, which is an index object.
3
+ */
4
+ import { omitKeys } from "../object.js";
5
+ /**
6
+ * An empty dictionary.
7
+ */
8
+ export const empty = {};
9
+ /**
10
+ * Constructs a dictionary from an array of key-value pairs.
11
+ */
12
+ export const fromEntries = (entries) => Object.fromEntries(entries);
13
+ /**
14
+ * Returns the value associated with the given key, or `undefined` if the key does not exist.
15
+ */
16
+ export const get = (dict, key) => dict[key];
17
+ /**
18
+ * Returns the value associated with the given key mapped through the given function, or `undefined` if the key does not exist.
19
+ */
20
+ export const getMap = (dict, key, mapFn) => {
21
+ const value = get(dict, key);
22
+ return value === undefined ? undefined : mapFn(value);
23
+ };
24
+ /**
25
+ * Checks if the dictionary has the given key.
26
+ */
27
+ export const has = (dict, key) => Object.prototype.hasOwnProperty.call(dict, key);
28
+ /**
29
+ * Sets the given key to the given value.
30
+ *
31
+ * If the key already exists, its value will be overwritten.
32
+ */
33
+ export const set = (dict, key, value) => ({ ...dict, [key]: value });
34
+ /**
35
+ * Removes the given key from the dictionary.
36
+ *
37
+ * If the key does not exist, the same dictionary instance is returned.
38
+ */
39
+ export const remove = (dict, key) => {
40
+ if (has(dict, key)) {
41
+ return omitKeys(dict, key);
42
+ }
43
+ else {
44
+ return dict;
45
+ }
46
+ };
47
+ /**
48
+ * Returns the number of entries in the dictionary.
49
+ */
50
+ export const size = (dict) => Object.keys(dict).length;
51
+ /**
52
+ * Returns an array of key-value pairs in the dictionary.
53
+ */
54
+ export const entries = (dict) => Object.entries(dict);
55
+ /**
56
+ * Returns an array of values in the dictionary.
57
+ */
58
+ export const values = (dict) => Object.values(dict);
59
+ /**
60
+ * Returns an array of keys in the dictionary.
61
+ */
62
+ export const keys = (dict) => Object.keys(dict);
63
+ /**
64
+ * Calls the given function for each key-value pair in the dictionary.
65
+ */
66
+ export const forEach = (dict, fn) => {
67
+ for (const [key, value] of Object.entries(dict)) {
68
+ fn(value, key);
69
+ }
70
+ };
71
+ /**
72
+ * Calls the given async function for each key-value pair in the dictionary.
73
+ *
74
+ * The calls are made sequentially.
75
+ */
76
+ export const forEachAsync = async (dict, fn) => {
77
+ for (const [key, value] of Object.entries(dict)) {
78
+ await fn(value, key);
79
+ }
80
+ };
81
+ /**
82
+ * Create, modify, or remove the value for the given key based on its current value.
83
+ *
84
+ * The value passed to `modifyFn` will be `undefined` if the key does not exist.
85
+ * If the `modifyFn` returns `undefined`, the key will be removed from the dictionary.
86
+ * Otherwise, the key will be set to the new value returned by `modifyFn`.
87
+ */
88
+ export const modify = (dict, key, modifyFn) => {
89
+ const currentValue = get(dict, key);
90
+ const newValue = modifyFn(currentValue);
91
+ if (newValue === undefined) {
92
+ return remove(dict, key);
93
+ }
94
+ else {
95
+ return set(dict, key, newValue);
96
+ }
97
+ };
98
+ /**
99
+ * Returns the first value that matches the given predicate, or `undefined` if no such value exists.
100
+ */
101
+ export const find = (dict, predicate) => findEntry(dict, predicate)?.[1];
102
+ /**
103
+ * Returns the first key that matches the given predicate, or `undefined` if no such key exists.
104
+ */
105
+ export const findKey = (dict, predicate) => findEntry(dict, predicate)?.[0];
106
+ /**
107
+ * Returns the first key-value pair that matches the given predicate, or `undefined` if no such key-value pair exists.
108
+ */
109
+ export const findEntry = (dict, predicate) => {
110
+ for (const [key, value] of Object.entries(dict)) {
111
+ if (predicate(value, key)) {
112
+ return [key, value];
113
+ }
114
+ }
115
+ return undefined;
116
+ };
117
+ /**
118
+ * Applies the given mapping function to each key-value pair in the dictionary and returns the first non-`undefined` result, or `undefined` if no such result exists.
119
+ */
120
+ export const mapFirst = (dict, mapFn) => {
121
+ for (const [key, value] of Object.entries(dict)) {
122
+ const mapped = mapFn(value, key);
123
+ if (mapped !== undefined) {
124
+ return mapped;
125
+ }
126
+ }
127
+ return undefined;
128
+ };
129
+ /**
130
+ * Applies a function to every key-value pair in the dictionary.
131
+ */
132
+ export const map = (dict, mapFn) => {
133
+ const newRecord = {};
134
+ for (const [key, value] of Object.entries(dict)) {
135
+ newRecord[key] = mapFn(value, key);
136
+ }
137
+ return newRecord;
138
+ };
139
+ /**
140
+ * Calls the specified callback function for all the elements in an array. The return value of the callback function is the accumulated result, and is provided as an argument in the next call to the callback function.
141
+ */
142
+ export const reduce = (dict, reducer, initialValue) => Object.entries(dict).reduce((acc, [key, item]) => reducer(acc, item, key), initialValue);