@lionweb/ts-utils 0.7.0-beta.2 → 0.7.0-beta.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +4 -1
- package/dist/{array-helpers.d.ts → arrays.d.ts} +11 -1
- package/dist/arrays.d.ts.map +1 -0
- package/dist/arrays.js +34 -0
- package/dist/arrays.js.map +1 -0
- package/dist/cycles.d.ts.map +1 -1
- package/dist/graphs.d.ts.map +1 -1
- package/dist/index.d.ts +4 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -3
- package/dist/index.js.map +1 -1
- package/dist/json.d.ts +5 -0
- package/dist/json.d.ts.map +1 -0
- package/dist/json.js +9 -0
- package/dist/json.js.map +1 -0
- package/dist/{map-helpers.d.ts → maps.d.ts} +14 -1
- package/dist/maps.d.ts.map +1 -0
- package/dist/{map-helpers.js → maps.js} +19 -1
- package/dist/maps.js.map +1 -0
- package/dist/{nested-map.d.ts → nested-maps.d.ts} +10 -7
- package/dist/nested-maps.d.ts.map +1 -0
- package/dist/{nested-map.js → nested-maps.js} +2 -3
- package/dist/nested-maps.js.map +1 -0
- package/dist/recursion.d.ts.map +1 -1
- package/dist/string-mapping.d.ts.map +1 -1
- package/dist/string-sorting.d.ts.map +1 -1
- package/dist/toposort.d.ts +1 -1
- package/dist/toposort.d.ts.map +1 -1
- package/dist/toposort.js +0 -3
- package/dist/toposort.js.map +1 -1
- package/package.json +27 -27
- package/src/arrays.ts +49 -0
- package/src/cycles.ts +31 -0
- package/src/graphs.ts +36 -0
- package/src/index.ts +10 -0
- package/src/json.ts +8 -0
- package/src/maps.ts +82 -0
- package/src/nested-maps.ts +99 -0
- package/src/recursion.ts +41 -0
- package/src/string-mapping.ts +38 -0
- package/src/string-sorting.ts +29 -0
- package/src/toposort.ts +46 -0
- package/dist/array-helpers.d.ts.map +0 -1
- package/dist/array-helpers.js +0 -19
- package/dist/array-helpers.js.map +0 -1
- package/dist/map-helpers.d.ts.map +0 -1
- package/dist/map-helpers.js.map +0 -1
- package/dist/nested-map.d.ts.map +0 -1
- package/dist/nested-map.js.map +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,5 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
## 0.7.0
|
|
4
4
|
|
|
5
|
-
Initial creation and publication of this package, as an extraction and de-duplication from `@lionweb/core`, `@lionweb/utilities`, `@lionweb/class-core`, and `@lionweb/validation`.
|
|
5
|
+
* Initial creation and publication of this package, as an extraction and de-duplication from `@lionweb/core`, `@lionweb/utilities`, `@lionweb/class-core`, and `@lionweb/validation`.
|
|
6
|
+
* Add 'mapFrom' function that maps an array to a map, using given key and value functions.
|
|
7
|
+
* Introduce explicit types for `nested{1,2,3}Mapper` functions.
|
|
8
|
+
* Package `src/` again (— i.e., don't ignore for NPM packaging.)
|
|
6
9
|
|
|
@@ -15,4 +15,14 @@ export declare const asArray: <T>(thing: AnyNumberOf<T>) => T[];
|
|
|
15
15
|
* @return a view of the given array of items with duplicates removed.
|
|
16
16
|
*/
|
|
17
17
|
export declare const uniquesAmong: <T>(ts: T[]) => T[];
|
|
18
|
-
|
|
18
|
+
/**
|
|
19
|
+
* @return the defined values of given type (parameter) `T` from the given array,
|
|
20
|
+
* leaving out the `null` or `undefined` values.
|
|
21
|
+
*/
|
|
22
|
+
export declare const keepDefineds: <T>(ts: (T | null | undefined)[]) => T[];
|
|
23
|
+
/**
|
|
24
|
+
* @return the last element of the given `ts` array.
|
|
25
|
+
* @throws an {@link Error} if the array is empty, so it doesn't have a last element.
|
|
26
|
+
*/
|
|
27
|
+
export declare const lastOfArray: <T>(ts: T[]) => T;
|
|
28
|
+
//# sourceMappingURL=arrays.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"arrays.d.ts","sourceRoot":"","sources":["../src/arrays.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,MAAM,MAAM,WAAW,CAAC,CAAC,IAAI,SAAS,GAAG,CAAC,GAAG,CAAC,EAAE,CAAA;AAEhD;;;;GAIG;AACH,eAAO,MAAM,OAAO,GAAI,CAAC,EAAE,OAAO,WAAW,CAAC,CAAC,CAAC,KAAG,CAAC,EAQnD,CAAA;AAED;;GAEG;AACH,eAAO,MAAM,YAAY,GAAI,CAAC,EAAE,IAAI,CAAC,EAAE,KAAG,CAAC,EACvB,CAAA;AAGpB;;;GAGG;AACH,eAAO,MAAM,YAAY,GAAI,CAAC,EAAE,IAAI,CAAC,CAAC,GAAG,IAAI,GAAG,SAAS,CAAC,EAAE,KAAG,CAAC,EACN,CAAA;AAG1D;;;GAGG;AACH,eAAO,MAAM,WAAW,GAAI,CAAC,EAAE,IAAI,CAAC,EAAE,KAAG,CAKxC,CAAA"}
|
package/dist/arrays.js
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Turns a {@link AnyNumberOf feature's value} into an array of objects
|
|
3
|
+
* (possibly empty), regardless of the feature's cardinality and how its
|
|
4
|
+
* value happened to be parsed.
|
|
5
|
+
*/
|
|
6
|
+
export const asArray = (thing) => {
|
|
7
|
+
if (thing === undefined) {
|
|
8
|
+
return [];
|
|
9
|
+
}
|
|
10
|
+
if (Array.isArray(thing)) {
|
|
11
|
+
return thing;
|
|
12
|
+
}
|
|
13
|
+
return [thing];
|
|
14
|
+
};
|
|
15
|
+
/**
|
|
16
|
+
* @return a view of the given array of items with duplicates removed.
|
|
17
|
+
*/
|
|
18
|
+
export const uniquesAmong = (ts) => [...new Set(ts)];
|
|
19
|
+
/**
|
|
20
|
+
* @return the defined values of given type (parameter) `T` from the given array,
|
|
21
|
+
* leaving out the `null` or `undefined` values.
|
|
22
|
+
*/
|
|
23
|
+
export const keepDefineds = (ts) => ts.filter((t) => t !== undefined && t !== null);
|
|
24
|
+
/**
|
|
25
|
+
* @return the last element of the given `ts` array.
|
|
26
|
+
* @throws an {@link Error} if the array is empty, so it doesn't have a last element.
|
|
27
|
+
*/
|
|
28
|
+
export const lastOfArray = (ts) => {
|
|
29
|
+
if (ts.length === 0) {
|
|
30
|
+
throw new Error(`empty array doesn't have a last element`);
|
|
31
|
+
}
|
|
32
|
+
return ts[ts.length - 1];
|
|
33
|
+
};
|
|
34
|
+
//# sourceMappingURL=arrays.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"arrays.js","sourceRoot":"","sources":["../src/arrays.ts"],"names":[],"mappings":"AAQA;;;;GAIG;AACH,MAAM,CAAC,MAAM,OAAO,GAAG,CAAI,KAAqB,EAAO,EAAE;IACrD,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QACtB,OAAO,EAAE,CAAA;IACb,CAAC;IACD,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACvB,OAAO,KAAK,CAAA;IAChB,CAAC;IACD,OAAO,CAAC,KAAK,CAAC,CAAA;AAClB,CAAC,CAAA;AAED;;GAEG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,CAAI,EAAO,EAAO,EAAE,CAC5C,CAAC,GAAG,IAAI,GAAG,CAAC,EAAE,CAAC,CAAC,CAAA;AAGpB;;;GAGG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,CAAI,EAA4B,EAAO,EAAE,CACjE,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,SAAS,IAAI,CAAC,KAAK,IAAI,CAAQ,CAAA;AAG1D;;;GAGG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG,CAAI,EAAO,EAAK,EAAE;IACzC,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAClB,MAAM,IAAI,KAAK,CAAC,yCAAyC,CAAC,CAAA;IAC9D,CAAC;IACD,OAAO,EAAE,CAAC,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC,CAAA;AAC5B,CAAC,CAAA"}
|
package/dist/cycles.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cycles.d.ts","sourceRoot":"","sources":["../src/cycles.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,aAAa,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,CAAA;AAG5C;;;;GAIG;AACH,eAAO,MAAM,SAAS,
|
|
1
|
+
{"version":3,"file":"cycles.d.ts","sourceRoot":"","sources":["../src/cycles.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,aAAa,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,CAAA;AAG5C;;;;GAIG;AACH,eAAO,MAAM,SAAS,GAAI,CAAC,EAAE,OAAO,CAAC,EAAE,eAAe,aAAa,CAAC,CAAC,CAAC,KAAG,CAAC,EAMzE,CAAA"}
|
package/dist/graphs.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"graphs.d.ts","sourceRoot":"","sources":["../src/graphs.ts"],"names":[],"mappings":"AAEA;;GAEG;AACH,MAAM,MAAM,YAAY,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,CAAA;AAE9C;;;;;;;GAOG;AACH,eAAO,MAAM,WAAW,
|
|
1
|
+
{"version":3,"file":"graphs.d.ts","sourceRoot":"","sources":["../src/graphs.ts"],"names":[],"mappings":"AAEA;;GAEG;AACH,MAAM,MAAM,YAAY,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,CAAA;AAE9C;;;;;;;GAOG;AACH,eAAO,MAAM,WAAW,GACnB,CAAC,EAAE,CAAC,EAAE,QAAQ,YAAY,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,cAAc,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,KAAG,YAAY,CAAC,CAAC,EAAE,CAAC,CAcjF,CAAA;AAEL;;GAEG;AACH,eAAO,MAAM,UAAU,GAAI,CAAC,EAAE,GAAG,CAAC,QAAQ,CAAA"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
export * from "./
|
|
1
|
+
export * from "./arrays.js";
|
|
2
2
|
export * from "./cycles.js";
|
|
3
3
|
export * from "./graphs.js";
|
|
4
|
-
export * from "./
|
|
5
|
-
export * from "./
|
|
4
|
+
export * from "./json.js";
|
|
5
|
+
export * from "./maps.js";
|
|
6
|
+
export * from "./nested-maps.js";
|
|
6
7
|
export * from "./recursion.js";
|
|
7
8
|
export * from "./string-sorting.js";
|
|
8
9
|
export * from "./string-mapping.js";
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAA;AAC3B,cAAc,aAAa,CAAA;AAC3B,cAAc,aAAa,CAAA;AAC3B,cAAc,WAAW,CAAA;AACzB,cAAc,WAAW,CAAA;AACzB,cAAc,kBAAkB,CAAA;AAChC,cAAc,gBAAgB,CAAA;AAC9B,cAAc,qBAAqB,CAAA;AACnC,cAAc,qBAAqB,CAAA;AACnC,cAAc,eAAe,CAAA"}
|
package/dist/index.js
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
export * from "./
|
|
1
|
+
export * from "./arrays.js";
|
|
2
2
|
export * from "./cycles.js";
|
|
3
3
|
export * from "./graphs.js";
|
|
4
|
-
export * from "./
|
|
5
|
-
export * from "./
|
|
4
|
+
export * from "./json.js";
|
|
5
|
+
export * from "./maps.js";
|
|
6
|
+
export * from "./nested-maps.js";
|
|
6
7
|
export * from "./recursion.js";
|
|
7
8
|
export * from "./string-sorting.js";
|
|
8
9
|
export * from "./string-mapping.js";
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAA;AAC3B,cAAc,aAAa,CAAA;AAC3B,cAAc,aAAa,CAAA;AAC3B,cAAc,WAAW,CAAA;AACzB,cAAc,WAAW,CAAA;AACzB,cAAc,kBAAkB,CAAA;AAChC,cAAc,gBAAgB,CAAA;AAC9B,cAAc,qBAAqB,CAAA;AACnC,cAAc,qBAAqB,CAAA;AACnC,cAAc,eAAe,CAAA"}
|
package/dist/json.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"json.d.ts","sourceRoot":"","sources":["../src/json.ts"],"names":[],"mappings":"AAAA,8CAA8C;AAC9C,eAAO,MAAM,kBAAkB,GAAI,KAAK,OAAO,KAAG,MAEjD,CAAA;AACD,4CAA4C;AAC5C,eAAO,MAAM,mBAAmB,GAAK,KAAK,OAAO,KAAG,MAEnD,CAAA"}
|
package/dist/json.js
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/** Normalized JSON with 4 spaces as indent */
|
|
2
|
+
export const asPrettyJsonString = (obj) => {
|
|
3
|
+
return JSON.stringify(obj, null, 4);
|
|
4
|
+
};
|
|
5
|
+
/** Minimal JSON with no spaces as indent */
|
|
6
|
+
export const asMinimalJsonString = (obj) => {
|
|
7
|
+
return JSON.stringify(obj, null, 0);
|
|
8
|
+
};
|
|
9
|
+
//# sourceMappingURL=json.js.map
|
package/dist/json.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"json.js","sourceRoot":"","sources":["../src/json.ts"],"names":[],"mappings":"AAAA,8CAA8C;AAC9C,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,GAAY,EAAU,EAAE;IACvD,OAAO,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;AACxC,CAAC,CAAA;AACD,4CAA4C;AAC5C,MAAM,CAAC,MAAM,mBAAmB,GAAI,CAAC,GAAY,EAAU,EAAE;IACzD,OAAO,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;AACxC,CAAC,CAAA"}
|
|
@@ -22,4 +22,17 @@ export declare const duplicatesAmong: <T>(ts: T[], keyFunc: (t: T) => string) =>
|
|
|
22
22
|
* Maps the values of a map/record according to the given mapping function.
|
|
23
23
|
*/
|
|
24
24
|
export declare const mapValues: <V, W>(map: Record<string, V>, valFunc: (v: V) => W) => Record<string, W>;
|
|
25
|
-
|
|
25
|
+
/**
|
|
26
|
+
* Gets the value under the given key from the given map,
|
|
27
|
+
* creating that value when that key wasn't present yet.
|
|
28
|
+
* This allows for convenient “chaining” of map-lookups,
|
|
29
|
+
* e.g. to build up nested maps.
|
|
30
|
+
*/
|
|
31
|
+
export declare const lazyMapGet: <T>(map: {
|
|
32
|
+
[key: string]: T;
|
|
33
|
+
}, key: string, createThunk: () => T) => T;
|
|
34
|
+
/**
|
|
35
|
+
* @return a map with each key-value pair the result of mapping an item in the given list using the given key and value functions.
|
|
36
|
+
*/
|
|
37
|
+
export declare const mapFrom: <T, V>(ts: T[], keyFunc: (t: T) => string, valueFunc: (t: T) => V) => Record<string, V>;
|
|
38
|
+
//# sourceMappingURL=maps.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"maps.d.ts","sourceRoot":"","sources":["../src/maps.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,eAAO,MAAM,OAAO,GAAI,CAAC,SAAS;IAAE,EAAE,EAAE,MAAM,CAAA;CAAE,EAAE,IAAI,CAAC,EAAE,KAAG;IAAE,CAAC,EAAE,EAAE,MAAM,GAAG,CAAC,CAAA;CAO5E,CAAA;AAGD;;GAEG;AACH,eAAO,MAAM,OAAO,GAAI,CAAC,EAAE,IAAI,CAAC,EAAE,EAAE,SAAS,CAAC,CAAC,EAAE,CAAC,KAAK,MAAM,KAAG,MAAM,CAAC,MAAM,EAAE,CAAC,EAAE,CAYjF,CAAA;AAGD;;GAEG;AACH,eAAO,MAAM,YAAY,GAAI,CAAC,EAAE,KAAK,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,EAAE,WAAW,CAAC,CAAC,EAAE,CAAC,KAAK,OAAO,KAAG,MAAM,CAAC,MAAM,EAAE,CAAC,CAIlG,CAAA;AAGL;;GAEG;AACH,eAAO,MAAM,eAAe,GAAI,CAAC,EAAE,IAAI,CAAC,EAAE,EAAE,SAAS,CAAC,CAAC,EAAE,CAAC,KAAK,MAAM,KAAG,MAAM,CAAC,MAAM,EAAE,CAAC,EAAE,CAC7B,CAAA;AAG7D;;GAEG;AACH,eAAO,MAAM,SAAS,GAAI,CAAC,EAAE,CAAC,EAAE,KAAK,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,KAAG,MAAM,CAAC,MAAM,EAAE,CAAC,CAI1F,CAAA;AAGL;;;;;GAKG;AACH,eAAO,MAAM,UAAU,GAAI,CAAC,EAAE,KAAK;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,CAAC,CAAA;CAAE,EAAE,KAAK,MAAM,EAAE,aAAa,MAAM,CAAC,KAAG,CAO5F,CAAA;AAGD;;GAEG;AACH,eAAO,MAAM,OAAO,GAAI,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,EAAE,EAAE,SAAS,CAAC,CAAC,EAAE,CAAC,KAAK,MAAM,EAAE,WAAW,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,KAAG,MAAM,CAAC,MAAM,EAAE,CAAC,CAGtG,CAAA"}
|
|
@@ -39,4 +39,22 @@ export const duplicatesAmong = (ts, keyFunc) => filterValues(groupBy(ts, keyFunc
|
|
|
39
39
|
*/
|
|
40
40
|
export const mapValues = (map, valFunc) => Object.fromEntries(Object.entries(map)
|
|
41
41
|
.map(([key, value]) => [key, valFunc(value)]));
|
|
42
|
-
|
|
42
|
+
/**
|
|
43
|
+
* Gets the value under the given key from the given map,
|
|
44
|
+
* creating that value when that key wasn't present yet.
|
|
45
|
+
* This allows for convenient “chaining” of map-lookups,
|
|
46
|
+
* e.g. to build up nested maps.
|
|
47
|
+
*/
|
|
48
|
+
export const lazyMapGet = (map, key, createThunk) => {
|
|
49
|
+
if (key in map) {
|
|
50
|
+
return map[key];
|
|
51
|
+
}
|
|
52
|
+
const value = createThunk();
|
|
53
|
+
map[key] = value;
|
|
54
|
+
return value;
|
|
55
|
+
};
|
|
56
|
+
/**
|
|
57
|
+
* @return a map with each key-value pair the result of mapping an item in the given list using the given key and value functions.
|
|
58
|
+
*/
|
|
59
|
+
export const mapFrom = (ts, keyFunc, valueFunc) => Object.fromEntries(ts.map((t) => [keyFunc(t), valueFunc(t)]));
|
|
60
|
+
//# sourceMappingURL=maps.js.map
|
package/dist/maps.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"maps.js","sourceRoot":"","sources":["../src/maps.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,CAAC,MAAM,OAAO,GAAG,CAA2B,EAAO,EAAuB,EAAE;IAC9E,MAAM,GAAG,GAAwB,EAAE,CAAA;IACnC,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE;QACb,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAA;IACjB,CAAC,CAAC,CAAA;IACF,OAAO,GAAG,CAAA;IACV,6EAA6E;AACjF,CAAC,CAAA;AAGD;;GAEG;AACH,MAAM,CAAC,MAAM,OAAO,GAAG,CAAI,EAAO,EAAE,OAAyB,EAAuB,EAAE;IAClF,MAAM,GAAG,GAAwB,EAAE,CAAA;IACnC,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE;QACb,MAAM,GAAG,GAAG,OAAO,CAAC,CAAC,CAAC,CAAA;QACtB,IAAI,IAAI,GAAG,GAAG,CAAC,GAAG,CAAC,CAAA;QACnB,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;YACrB,IAAI,GAAG,EAAE,CAAA;YACT,GAAG,CAAC,GAAG,CAAC,GAAG,IAAI,CAAA;QACnB,CAAC;QACD,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IAChB,CAAC,CAAC,CAAA;IACF,OAAO,GAAG,CAAA;AACd,CAAC,CAAA;AAGD;;GAEG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,CAAI,GAAsB,EAAE,SAA4B,EAAqB,EAAE,CACvG,MAAM,CAAC,WAAW,CACd,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC;KACd,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAChD,CAAA;AAGL;;GAEG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,CAAI,EAAO,EAAE,OAAyB,EAAuB,EAAE,CAC1F,YAAY,CAAC,OAAO,CAAC,EAAE,EAAE,OAAO,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC,CAAA;AAG7D;;GAEG;AACH,MAAM,CAAC,MAAM,SAAS,GAAG,CAAO,GAAsB,EAAE,OAAoB,EAAqB,EAAE,CAC/F,MAAM,CAAC,WAAW,CACd,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC;KACd,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CACpD,CAAA;AAGL;;;;;GAKG;AACH,MAAM,CAAC,MAAM,UAAU,GAAG,CAAI,GAAyB,EAAE,GAAW,EAAE,WAAoB,EAAK,EAAE;IAC7F,IAAI,GAAG,IAAI,GAAG,EAAE,CAAC;QACb,OAAO,GAAG,CAAC,GAAG,CAAC,CAAA;IACnB,CAAC;IACD,MAAM,KAAK,GAAG,WAAW,EAAE,CAAA;IAC3B,GAAG,CAAC,GAAG,CAAC,GAAG,KAAK,CAAA;IAChB,OAAO,KAAK,CAAA;AAChB,CAAC,CAAA;AAGD;;GAEG;AACH,MAAM,CAAC,MAAM,OAAO,GAAG,CAAO,EAAO,EAAE,OAAyB,EAAE,SAAsB,EAAqB,EAAE,CAC3G,MAAM,CAAC,WAAW,CACd,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAC5C,CAAA"}
|
|
@@ -1,27 +1,30 @@
|
|
|
1
1
|
export type Nested1Map<T> = Record<string, T>;
|
|
2
2
|
export type Nested2Map<T> = Record<string, Record<string, T>>;
|
|
3
3
|
export type Nested3Map<T> = Record<string, Record<string, Record<string, T>>>;
|
|
4
|
-
export
|
|
5
|
-
export declare const
|
|
6
|
-
export
|
|
4
|
+
export type Nested1Mapper<T, R> = (nested1Map: Nested1Map<T>) => Nested1Map<R>;
|
|
5
|
+
export declare const mapValuesMapper: <T, R>(valueMapFunc: (t: T) => R) => Nested1Mapper<T, R>;
|
|
6
|
+
export type Nested2Mapper<T, R> = (nested2Map: Nested2Map<T>) => Nested2Map<R>;
|
|
7
|
+
export declare const nested2Mapper: <T, R>(valueMapFunc: (t: T) => R) => Nested2Mapper<T, R>;
|
|
8
|
+
export type Nested3Mapper<T, R> = (nested3Map: Nested3Map<T>) => Nested3Map<R>;
|
|
9
|
+
export declare const nested3Mapper: <T, R>(valueMapFunc: (t: T) => R) => Nested3Mapper<T, R>;
|
|
7
10
|
/**
|
|
8
11
|
* Return a function that groups an array of things using a group function as a
|
|
9
12
|
* map : string (group key) → array of grouped things.
|
|
10
13
|
*/
|
|
11
|
-
export declare const grouper: <T>(key1Func: (t: T) => string) => (ts: T[]) => Nested1Map<T[]
|
|
14
|
+
export declare const grouper: <T>(key1Func: (t: T) => string) => ((ts: T[]) => Nested1Map<T[]>);
|
|
12
15
|
/**
|
|
13
16
|
* Return a function that groups an array of things using two group functions as a nested map
|
|
14
17
|
* map : string (group key 1) →
|
|
15
18
|
* map : string (group key 2) → array of grouped things.
|
|
16
19
|
*/
|
|
17
|
-
export declare const nested2Grouper: <T>(key1Func: (t: T) => string, key2Func: (t: T) => string) => (ts: T[]) => Nested2Map<T[]
|
|
20
|
+
export declare const nested2Grouper: <T>(key1Func: (t: T) => string, key2Func: (t: T) => string) => ((ts: T[]) => Nested2Map<T[]>);
|
|
18
21
|
/**
|
|
19
22
|
* Return a function that groups an array of things using two group functions as a nested map
|
|
20
23
|
* map : string (group key 1) →
|
|
21
24
|
* map : string (group key 2) →
|
|
22
25
|
* map : string (group key 3) → array of grouped things.
|
|
23
26
|
*/
|
|
24
|
-
export declare const nested3Grouper: <T>(key1Func: (t: T) => string, key2Func: (t: T) => string, key3Func: (t: T) => string) => (ts: T[]) => Nested3Map<T[]
|
|
27
|
+
export declare const nested3Grouper: <T>(key1Func: (t: T) => string, key2Func: (t: T) => string, key3Func: (t: T) => string) => ((ts: T[]) => Nested3Map<T[]>);
|
|
25
28
|
/**
|
|
26
29
|
* Flat-maps over the values of a
|
|
27
30
|
* map : string (group key) → values
|
|
@@ -43,4 +46,4 @@ export declare const nestedFlatMap2: <T, R>(nested2Map: Nested2Map<T>, map2Func:
|
|
|
43
46
|
* using the map function, which is also provided with the keys.
|
|
44
47
|
*/
|
|
45
48
|
export declare const nestedFlatMap3: <T, R>(nested3Map: Nested3Map<T>, map3Func: (t: T, key1: string, key2: string, key3: string) => R) => R[];
|
|
46
|
-
//# sourceMappingURL=nested-
|
|
49
|
+
//# sourceMappingURL=nested-maps.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"nested-maps.d.ts","sourceRoot":"","sources":["../src/nested-maps.ts"],"names":[],"mappings":"AAGA,MAAM,MAAM,UAAU,CAAC,CAAC,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,CAAA;AAC7C,MAAM,MAAM,UAAU,CAAC,CAAC,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAA;AAC7D,MAAM,MAAM,UAAU,CAAC,CAAC,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,CAAA;AAE7E,MAAM,MAAM,aAAa,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC,CAAC,KAAK,UAAU,CAAC,CAAC,CAAC,CAAA;AAC9E,eAAO,MAAM,eAAe,GACvB,CAAC,EAAE,CAAC,EAAE,cAAc,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,KAAG,aAAa,CAAC,CAAC,EAAE,CAAC,CAEwC,CAAA;AAGjG,MAAM,MAAM,aAAa,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC,CAAC,KAAK,UAAU,CAAC,CAAC,CAAC,CAAA;AAC9E,eAAO,MAAM,aAAa,GAAI,CAAC,EAAE,CAAC,EAAE,cAAc,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,KAAG,aAAa,CAAC,CAAC,EAAE,CAAC,CAChC,CAAA;AAElD,MAAM,MAAM,aAAa,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC,CAAC,KAAK,UAAU,CAAC,CAAC,CAAC,CAAA;AAC9E,eAAO,MAAM,aAAa,GAAI,CAAC,EAAE,CAAC,EAAE,cAAc,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,KAAG,aAAa,CAAC,CAAC,EAAE,CAAC,CAClC,CAAA;AAEhD;;;GAGG;AACH,eAAO,MAAM,OAAO,GACf,CAAC,EAAE,UAAU,CAAC,CAAC,EAAE,CAAC,KAAK,MAAM,KAAG,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,KAAK,UAAU,CAAC,CAAC,EAAE,CAAC,CAEjC,CAAA;AAEjC;;;;GAIG;AACH,eAAO,MAAM,cAAc,GACtB,CAAC,EAAE,UAAU,CAAC,CAAC,EAAE,CAAC,KAAK,MAAM,EAAE,UAAU,CAAC,CAAC,EAAE,CAAC,KAAK,MAAM,KAAG,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,KAAK,UAAU,CAAC,CAAC,EAAE,CAAC,CAEzB,CAAA;AAGrE;;;;;GAKG;AACH,eAAO,MAAM,cAAc,GACtB,CAAC,EAAE,UAAU,CAAC,CAAC,EAAE,CAAC,KAAK,MAAM,EAAE,UAAU,CAAC,CAAC,EAAE,CAAC,KAAK,MAAM,EAAE,UAAU,CAAC,CAAC,EAAE,CAAC,KAAK,MAAM,KAAG,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,KAAK,UAAU,CAAC,CAAC,EAAE,CAAC,CAEpC,CAAA;AAEtF;;;;GAIG;AACH,eAAO,MAAM,aAAa,GAAI,CAAC,EAAE,CAAC,EAAE,KAAK,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,KAAK,CAAC,KAAG,CAAC,EAMzF,CAAA;AAET;;;;;GAKG;AACH,eAAO,MAAM,cAAc,GAAI,CAAC,EAAE,CAAC,EAAE,YAAY,UAAU,CAAC,CAAC,CAAC,EAAE,UAAU,CAAC,CAAC,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,CAAC,KAAG,CAAC,EAQ5G,CAAA;AAET;;;;;;GAMG;AACH,eAAO,MAAM,cAAc,GAAI,CAAC,EAAE,CAAC,EAAE,YAAY,UAAU,CAAC,CAAC,CAAC,EAAE,UAAU,CAAC,CAAC,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,CAAC,KAAG,CAAC,EAQ1H,CAAA"}
|
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import { groupBy } from "./
|
|
1
|
+
import { groupBy } from "./maps.js";
|
|
2
2
|
export const mapValuesMapper = (valueMapFunc) => (map) => Object.fromEntries(Object.entries(map).map(([key, value]) => [key, valueMapFunc(value)]));
|
|
3
|
-
// === mapValues(map, valueFunc)
|
|
4
3
|
export const nested2Mapper = (valueMapFunc) => mapValuesMapper(mapValuesMapper(valueMapFunc));
|
|
5
4
|
export const nested3Mapper = (valueMapFunc) => mapValuesMapper(nested2Mapper(valueMapFunc));
|
|
6
5
|
/**
|
|
@@ -49,4 +48,4 @@ export const nestedFlatMap2 = (nested2Map, map2Func) => Object
|
|
|
49
48
|
export const nestedFlatMap3 = (nested3Map, map3Func) => Object
|
|
50
49
|
.entries(nested3Map)
|
|
51
50
|
.flatMap(([key1, nestedMap2]) => nestedFlatMap2(nestedMap2, (t, key2, key3) => map3Func(t, key1, key2, key3)));
|
|
52
|
-
//# sourceMappingURL=nested-
|
|
51
|
+
//# sourceMappingURL=nested-maps.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"nested-maps.js","sourceRoot":"","sources":["../src/nested-maps.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAQnC,MAAM,CAAC,MAAM,eAAe,GACxB,CAAO,YAAyB,EAAuB,EAAE,CACzD,CAAC,GAAsB,EAAqB,EAAE,CAC1C,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,EAAE,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAA;AAIjG,MAAM,CAAC,MAAM,aAAa,GAAG,CAAO,YAAyB,EAAuB,EAAE,CAClF,eAAe,CAAC,eAAe,CAAC,YAAY,CAAC,CAAC,CAAA;AAGlD,MAAM,CAAC,MAAM,aAAa,GAAG,CAAO,YAAyB,EAAuB,EAAE,CAClF,eAAe,CAAC,aAAa,CAAC,YAAY,CAAC,CAAC,CAAA;AAEhD;;;GAGG;AACH,MAAM,CAAC,MAAM,OAAO,GAChB,CAAI,QAA0B,EAAkC,EAAE,CAC9D,CAAC,EAAO,EAAE,EAAE,CACR,OAAO,CAAC,EAAE,EAAE,QAAQ,CAAC,CAAA;AAEjC;;;;GAIG;AACH,MAAM,CAAC,MAAM,cAAc,GACvB,CAAI,QAA0B,EAAE,QAA0B,EAAkC,EAAE,CAC1F,CAAC,EAAO,EAAE,EAAE,CACR,eAAe,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,CAAC,CAAA;AACrE,4EAA4E;AAE5E;;;;;GAKG;AACH,MAAM,CAAC,MAAM,cAAc,GACvB,CAAI,QAA0B,EAAE,QAA0B,EAAE,QAA0B,EAAkC,EAAE,CACtH,CAAC,EAAO,EAAE,EAAE,CACR,eAAe,CAAC,cAAc,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,CAAC,CAAA;AAEtF;;;;GAIG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,CAAO,GAAsB,EAAE,OAAkC,EAAO,EAAE,CACnG,MAAM;KACD,OAAO,CAAC,GAAG,CAAC;KACZ,GAAG,CACA,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,EAAE,EAAE,CACV,OAAO,CAAC,CAAC,EAAE,IAAI,CAAC,CACvB,CAAA;AAET;;;;;GAKG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,CAAO,UAAyB,EAAE,QAAiD,EAAO,EAAE,CACtH,MAAM;KACD,OAAO,CAAC,UAAU,CAAC;KACnB,OAAO,CACJ,CAAC,CAAC,IAAI,EAAE,UAAU,CAAC,EAAE,EAAE,CACnB,aAAa,CAAC,UAAU,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,EAAE,CAClC,QAAQ,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,CAC1B,CACR,CAAA;AAET;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,CAAO,UAAyB,EAAE,QAA+D,EAAO,EAAE,CACpI,MAAM;KACD,OAAO,CAAC,UAAU,CAAC;KACnB,OAAO,CACJ,CAAC,CAAC,IAAI,EAAE,UAAU,CAAC,EAAE,EAAE,CACnB,cAAc,CAAC,UAAU,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,CACzC,QAAQ,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,CAChC,CACR,CAAA"}
|
package/dist/recursion.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"recursion.d.ts","sourceRoot":"","sources":["../src/recursion.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,KAAK,UAAU,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,CAAA;AAErC;;;GAGG;AACH,QAAA,MAAM,0BAA0B,
|
|
1
|
+
{"version":3,"file":"recursion.d.ts","sourceRoot":"","sources":["../src/recursion.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,KAAK,UAAU,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,CAAA;AAErC;;;GAGG;AACH,QAAA,MAAM,0BAA0B,GAAI,CAAC,EAAE,CAAC,EACpC,QAAQ,UAAU,CAAC,CAAC,EAAE,CAAC,CAAC,EACxB,cAAc,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,KAC5B,UAAU,CAAC,CAAC,EAAE,CAAC,CAcb,CAAA;AAGL,QAAA,MAAM,iBAAiB,GAAI,CAAC,EAAE,GAAG,CAAC,QAAQ,CAAA;AAG1C,YAAY,EACR,UAAU,EACb,CAAA;AAED,OAAO,EACH,0BAA0B,EAC1B,iBAAiB,EACpB,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"string-mapping.d.ts","sourceRoot":"","sources":["../src/string-mapping.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,MAAM,aAAa,GAAG,CAAC,GAAG,OAAO,EAAE,MAAM,EAAE,KAAK,MAAM,CAAA;AAE5D;;GAEG;AACH,MAAM,MAAM,YAAY,GAAG,CAAC,GAAG,EAAE,MAAM,KAAK,MAAM,CAAA;AAGlD;;GAEG;AACH,eAAO,MAAM,YAAY,
|
|
1
|
+
{"version":3,"file":"string-mapping.d.ts","sourceRoot":"","sources":["../src/string-mapping.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,MAAM,aAAa,GAAG,CAAC,GAAG,OAAO,EAAE,MAAM,EAAE,KAAK,MAAM,CAAA;AAE5D;;GAEG;AACH,MAAM,MAAM,YAAY,GAAG,CAAC,GAAG,EAAE,MAAM,KAAK,MAAM,CAAA;AAGlD;;GAEG;AACH,eAAO,MAAM,YAAY,GAAI,WAAW,MAAM,KAAG,aACN,CAAA;AAE3C;;;GAGG;AACH,eAAO,MAAM,MAAM,EAAE,aAC0B,CAAA;AAE/C;;;;GAIG;AACH,eAAO,MAAM,KAAK,GAAI,eAAe,aAAa,EAAE,GAAG,eAAe,YAAY,EAAE,KAAG,aAOlF,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"string-sorting.d.ts","sourceRoot":"","sources":["../src/string-sorting.ts"],"names":[],"mappings":"AAAA;;GAEG;AAWH,eAAO,MAAM,eAAe,
|
|
1
|
+
{"version":3,"file":"string-sorting.d.ts","sourceRoot":"","sources":["../src/string-sorting.ts"],"names":[],"mappings":"AAAA;;GAEG;AAWH,eAAO,MAAM,eAAe,GAAI,CAAC,EAAE,IAAI,CAAC,EAAE,EAAE,SAAS,CAAC,CAAC,EAAE,CAAC,KAAK,MAAM,QAC5B,CAAA;AAGzC,MAAM,MAAM,YAAY,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,MAAM,EAAE,CAAA;AAQ1D,eAAO,MAAM,aAAa,cAAkC,CAAA;AAE5D,eAAO,MAAM,wBAAwB,cAAgD,CAAA"}
|
package/dist/toposort.d.ts
CHANGED
|
@@ -2,5 +2,5 @@
|
|
|
2
2
|
* Computes the topological order of the transitive closure of the graph with the given vertices and edges given by the edge function,
|
|
3
3
|
* or returns {@code false} if there's a cycle.
|
|
4
4
|
*/
|
|
5
|
-
export declare const dependencyOrderOf: <T>(vertices: T[], edgesOf: (vertex: T) => T[]) =>
|
|
5
|
+
export declare const dependencyOrderOf: <T>(vertices: T[], edgesOf: (vertex: T) => T[]) => T[] | false;
|
|
6
6
|
//# sourceMappingURL=toposort.d.ts.map
|
package/dist/toposort.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"toposort.d.ts","sourceRoot":"","sources":["../src/toposort.ts"],"names":[],"mappings":"AAiBA;;;GAGG;AACH,eAAO,MAAM,iBAAiB,
|
|
1
|
+
{"version":3,"file":"toposort.d.ts","sourceRoot":"","sources":["../src/toposort.ts"],"names":[],"mappings":"AAiBA;;;GAGG;AACH,eAAO,MAAM,iBAAiB,GAAI,CAAC,EAAE,UAAU,CAAC,EAAE,EAAE,SAAS,CAAC,MAAM,EAAE,CAAC,KAAK,CAAC,EAAE,KAAG,CAAC,EAAE,GAAG,KAuBvF,CAAA"}
|
package/dist/toposort.js
CHANGED
|
@@ -30,9 +30,6 @@ export const dependencyOrderOf = (vertices, edgesOf) => {
|
|
|
30
30
|
const extendedChain = [...chain, current];
|
|
31
31
|
const hasCycle = edgesOf(current).some((edge) => visit(edge, extendedChain));
|
|
32
32
|
ordered.push(current);
|
|
33
|
-
if (hasCycle) {
|
|
34
|
-
console.dir(ordered);
|
|
35
|
-
}
|
|
36
33
|
return hasCycle;
|
|
37
34
|
};
|
|
38
35
|
const hasCycle = vertices.some((vertex) => visit(vertex, []));
|
package/dist/toposort.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"toposort.js","sourceRoot":"","sources":["../src/toposort.ts"],"names":[],"mappings":"AAAA,wDAAwD;AACxD,EAAE;AACF,iEAAiE;AACjE,mEAAmE;AACnE,0CAA0C;AAC1C,EAAE;AACF,iDAAiD;AACjD,EAAE;AACF,sEAAsE;AACtE,oEAAoE;AACpE,2EAA2E;AAC3E,sEAAsE;AACtE,iCAAiC;AACjC,EAAE;AACF,sEAAsE;AACtE,sCAAsC;AAEtC;;;GAGG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAI,QAAa,EAAE,OAA2B,EAAe,EAAE;IAC5F,MAAM,OAAO,GAAQ,EAAE,CAAA;IAEvB,MAAM,KAAK,GAAG,CAAC,OAAU,EAAE,KAAU,EAAE,EAAE;QACrC,IAAI,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC;YAChC,OAAO,KAAK,CAAA;QAChB,CAAC;QACD,IAAI,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC;YAC9B,OAAO,IAAI,CAAA;QACf,CAAC;QACD,MAAM,aAAa,GAAG,CAAE,GAAG,KAAK,EAAE,OAAO,CAAE,CAAA;QAC3C,MAAM,QAAQ,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC,IAAI,CAClC,CAAC,IAAI,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,EAAE,aAAa,CAAC,CACvC,CAAA;QACD,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;QACrB,
|
|
1
|
+
{"version":3,"file":"toposort.js","sourceRoot":"","sources":["../src/toposort.ts"],"names":[],"mappings":"AAAA,wDAAwD;AACxD,EAAE;AACF,iEAAiE;AACjE,mEAAmE;AACnE,0CAA0C;AAC1C,EAAE;AACF,iDAAiD;AACjD,EAAE;AACF,sEAAsE;AACtE,oEAAoE;AACpE,2EAA2E;AAC3E,sEAAsE;AACtE,iCAAiC;AACjC,EAAE;AACF,sEAAsE;AACtE,sCAAsC;AAEtC;;;GAGG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAI,QAAa,EAAE,OAA2B,EAAe,EAAE;IAC5F,MAAM,OAAO,GAAQ,EAAE,CAAA;IAEvB,MAAM,KAAK,GAAG,CAAC,OAAU,EAAE,KAAU,EAAE,EAAE;QACrC,IAAI,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC;YAChC,OAAO,KAAK,CAAA;QAChB,CAAC;QACD,IAAI,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC;YAC9B,OAAO,IAAI,CAAA;QACf,CAAC;QACD,MAAM,aAAa,GAAG,CAAE,GAAG,KAAK,EAAE,OAAO,CAAE,CAAA;QAC3C,MAAM,QAAQ,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC,IAAI,CAClC,CAAC,IAAI,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,EAAE,aAAa,CAAC,CACvC,CAAA;QACD,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;QACrB,OAAO,QAAQ,CAAA;IACnB,CAAC,CAAA;IAED,MAAM,QAAQ,GAAG,QAAQ,CAAC,IAAI,CAC1B,CAAC,MAAM,EAAE,EAAE,CAAC,KAAK,CAAC,MAAM,EAAE,EAAE,CAAC,CAChC,CAAA;IAED,OAAO,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,CAAA;AACrC,CAAC,CAAA"}
|
package/package.json
CHANGED
|
@@ -1,29 +1,29 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
2
|
+
"name": "@lionweb/ts-utils",
|
|
3
|
+
"version": "0.7.0-beta.21",
|
|
4
|
+
"description": "Utilities for LionWeb JSON",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"types": "dist/index.d.ts",
|
|
7
|
+
"typings": "dist/index.d.ts",
|
|
8
|
+
"type": "module",
|
|
9
|
+
"license": "Apache-2.0",
|
|
10
|
+
"repository": {
|
|
11
|
+
"type": "git",
|
|
12
|
+
"url": "git+https://github.com/LionWeb-io/lionweb-typescript.git"
|
|
13
|
+
},
|
|
14
|
+
"bugs": {
|
|
15
|
+
"url": "https://github.com/LionWeb-io/lionweb-typescript/issues"
|
|
16
|
+
},
|
|
17
|
+
"scripts": {
|
|
18
|
+
"clean": "npx rimraf dist node_modules -g lionweb-ts-utils-*.tgz",
|
|
19
|
+
"build": "tsc",
|
|
20
|
+
"lint": "eslint src",
|
|
21
|
+
"prep:pre-release": "npm run clean && npm install && npm run build",
|
|
22
|
+
"prerelease-alpha": "npm run prep:pre-release",
|
|
23
|
+
"release-alpha": "npm publish --tag alpha",
|
|
24
|
+
"prerelease-beta": "npm run prep:pre-release",
|
|
25
|
+
"release-beta": "npm publish --tag beta",
|
|
26
|
+
"prerelease": "npm run prep:pre-release",
|
|
27
|
+
"release": "npm publish"
|
|
28
|
+
}
|
|
29
29
|
}
|
package/src/arrays.ts
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Feature's values are often persisted as either `undefined`, a single object, or an array of objects,
|
|
3
|
+
* regardless of the actual cardinality of that feature.
|
|
4
|
+
* This is e.g. the case when parsing an Ecore XML metamodel file.
|
|
5
|
+
* This type definition captures that phenomenon.
|
|
6
|
+
*/
|
|
7
|
+
export type AnyNumberOf<T> = undefined | T | T[]
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Turns a {@link AnyNumberOf feature's value} into an array of objects
|
|
11
|
+
* (possibly empty), regardless of the feature's cardinality and how its
|
|
12
|
+
* value happened to be parsed.
|
|
13
|
+
*/
|
|
14
|
+
export const asArray = <T>(thing: AnyNumberOf<T>): T[] => {
|
|
15
|
+
if (thing === undefined) {
|
|
16
|
+
return []
|
|
17
|
+
}
|
|
18
|
+
if (Array.isArray(thing)) {
|
|
19
|
+
return thing
|
|
20
|
+
}
|
|
21
|
+
return [thing]
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* @return a view of the given array of items with duplicates removed.
|
|
26
|
+
*/
|
|
27
|
+
export const uniquesAmong = <T>(ts: T[]): T[] =>
|
|
28
|
+
[...new Set(ts)]
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* @return the defined values of given type (parameter) `T` from the given array,
|
|
33
|
+
* leaving out the `null` or `undefined` values.
|
|
34
|
+
*/
|
|
35
|
+
export const keepDefineds = <T>(ts: (T | null | undefined)[]): T[] =>
|
|
36
|
+
ts.filter((t) => t !== undefined && t !== null) as T[]
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* @return the last element of the given `ts` array.
|
|
41
|
+
* @throws an {@link Error} if the array is empty, so it doesn't have a last element.
|
|
42
|
+
*/
|
|
43
|
+
export const lastOfArray = <T>(ts: T[]): T => {
|
|
44
|
+
if (ts.length === 0) {
|
|
45
|
+
throw new Error(`empty array doesn't have a last element`)
|
|
46
|
+
}
|
|
47
|
+
return ts[ts.length - 1]
|
|
48
|
+
}
|
|
49
|
+
|
package/src/cycles.ts
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
export type NextsFunction<T> = (t: T) => T[]
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Compute whether there's a cycle of dependencies, starting with `thing` and computing "nexts" with the given `nextsFunction`.
|
|
6
|
+
* @return An array with a cycle of "things", starting at the given `thing`.
|
|
7
|
+
* An array of length 0 means: the given `thing` is not part of any cycle.
|
|
8
|
+
*/
|
|
9
|
+
export const cycleWith = <T>(thing: T, nextsFunction: NextsFunction<T>): T[] => {
|
|
10
|
+
|
|
11
|
+
const result = visit<T>(thing, [], nextsFunction)
|
|
12
|
+
return result.length > 0 && result[result.length - 1] === thing
|
|
13
|
+
? result
|
|
14
|
+
: []
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
const visit = <T>(current: T, chain: T[], nextsFunction: NextsFunction<T>): T[] => {
|
|
18
|
+
if (chain.indexOf(current) > -1) {
|
|
19
|
+
// Add current to end, so we know what sub-array constitutes the actual cycle:
|
|
20
|
+
return [ ...chain, current ]
|
|
21
|
+
}
|
|
22
|
+
const extendedChain = [ ...chain, current ]
|
|
23
|
+
for (const dependency of nextsFunction(current)) {
|
|
24
|
+
const recursion = visit(dependency, extendedChain, nextsFunction)
|
|
25
|
+
if (recursion.length > 0) {
|
|
26
|
+
return recursion
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
return []
|
|
30
|
+
}
|
|
31
|
+
|
package/src/graphs.ts
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
// NB This is an almost identical copy of packages/core/utils/recursion.ts
|
|
2
|
+
// Copied to avoid package dependencies
|
|
3
|
+
/**
|
|
4
|
+
* Type def. of a generic "flatMap" function.
|
|
5
|
+
*/
|
|
6
|
+
export type ResultMapper<T, R> = (t: T) => R[]
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Returns a function that performs a "flatMap" on a graph that's specified as a start vertex. and a function that computes (outgoing) edges.
|
|
10
|
+
* The "flatMap" is performed depth-first, and doesn't loop on cycles.
|
|
11
|
+
*
|
|
12
|
+
* @param mapper The function that calculates the result values
|
|
13
|
+
* @param nextVertices The function that calculates the next edges to visit.
|
|
14
|
+
* @returns A function that takes a starting vertex and recursively calculates the result values for each vertex visited.
|
|
15
|
+
*/
|
|
16
|
+
export const visitAndMap =
|
|
17
|
+
<T, R>(mapper: ResultMapper<T, R>, nextVertices: (t: T) => T[]): ResultMapper<T, R> =>
|
|
18
|
+
(startVertex: T): R[] => {
|
|
19
|
+
const visited: T[] = []
|
|
20
|
+
const results: R[] = []
|
|
21
|
+
const recurse = (t: T) => {
|
|
22
|
+
if (visited.indexOf(t) > -1) {
|
|
23
|
+
return
|
|
24
|
+
}
|
|
25
|
+
visited.push(t)
|
|
26
|
+
results.push(...mapper(t))
|
|
27
|
+
nextVertices(t).forEach(recurse)
|
|
28
|
+
}
|
|
29
|
+
recurse(startVertex)
|
|
30
|
+
return results
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* A mapper function that returns the node itself as result
|
|
35
|
+
*/
|
|
36
|
+
export const selfMapper = <T>(t: T) => [t]
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export * from "./arrays.js"
|
|
2
|
+
export * from "./cycles.js"
|
|
3
|
+
export * from "./graphs.js"
|
|
4
|
+
export * from "./json.js"
|
|
5
|
+
export * from "./maps.js"
|
|
6
|
+
export * from "./nested-maps.js"
|
|
7
|
+
export * from "./recursion.js"
|
|
8
|
+
export * from "./string-sorting.js"
|
|
9
|
+
export * from "./string-mapping.js"
|
|
10
|
+
export * from "./toposort.js"
|
package/src/json.ts
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/** Normalized JSON with 4 spaces as indent */
|
|
2
|
+
export const asPrettyJsonString = (obj: unknown): string => {
|
|
3
|
+
return JSON.stringify(obj, null, 4);
|
|
4
|
+
}
|
|
5
|
+
/** Minimal JSON with no spaces as indent */
|
|
6
|
+
export const asMinimalJsonString = (obj: unknown): string => {
|
|
7
|
+
return JSON.stringify(obj, null, 0);
|
|
8
|
+
}
|
package/src/maps.ts
ADDED
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Computes a map id -> thing with id.
|
|
3
|
+
*/
|
|
4
|
+
export const byIdMap = <T extends { id: string }>(ts: T[]): { [id: string]: T } => {
|
|
5
|
+
const map: { [id: string]: T } = {}
|
|
6
|
+
ts.forEach((t) => {
|
|
7
|
+
map[t.id] = t
|
|
8
|
+
})
|
|
9
|
+
return map
|
|
10
|
+
// TODO -> Object.fromEntries(...) but what happens then with duplicate IDs?
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Groups a list of items according to a computed key.
|
|
16
|
+
*/
|
|
17
|
+
export const groupBy = <T>(ts: T[], keyFunc: (t: T) => string): Record<string, T[]> => {
|
|
18
|
+
const map: Record<string, T[]> = {}
|
|
19
|
+
ts.forEach((t) => {
|
|
20
|
+
const key = keyFunc(t)
|
|
21
|
+
let list = map[key]
|
|
22
|
+
if (list === undefined) {
|
|
23
|
+
list = []
|
|
24
|
+
map[key] = list
|
|
25
|
+
}
|
|
26
|
+
list.push(t)
|
|
27
|
+
})
|
|
28
|
+
return map
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Filters the values of a map/record according the given predicate.
|
|
34
|
+
*/
|
|
35
|
+
export const filterValues = <V>(map: Record<string, V>, predicate: (v: V) => boolean): Record<string, V> =>
|
|
36
|
+
Object.fromEntries(
|
|
37
|
+
Object.entries(map)
|
|
38
|
+
.filter(([_, value]) => predicate(value))
|
|
39
|
+
)
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Computes the given items whose computed keys are duplicates, as a map key → items.
|
|
44
|
+
*/
|
|
45
|
+
export const duplicatesAmong = <T>(ts: T[], keyFunc: (t: T) => string): Record<string, T[]> =>
|
|
46
|
+
filterValues(groupBy(ts, keyFunc), (ts) => ts.length > 1)
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Maps the values of a map/record according to the given mapping function.
|
|
51
|
+
*/
|
|
52
|
+
export const mapValues = <V, W>(map: Record<string, V>, valFunc: (v: V) => W): Record<string, W> =>
|
|
53
|
+
Object.fromEntries(
|
|
54
|
+
Object.entries(map)
|
|
55
|
+
.map(([key, value]) => [key, valFunc(value)])
|
|
56
|
+
)
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Gets the value under the given key from the given map,
|
|
61
|
+
* creating that value when that key wasn't present yet.
|
|
62
|
+
* This allows for convenient “chaining” of map-lookups,
|
|
63
|
+
* e.g. to build up nested maps.
|
|
64
|
+
*/
|
|
65
|
+
export const lazyMapGet = <T>(map: { [key: string]: T }, key: string, createThunk: () => T): T => {
|
|
66
|
+
if (key in map) {
|
|
67
|
+
return map[key]
|
|
68
|
+
}
|
|
69
|
+
const value = createThunk()
|
|
70
|
+
map[key] = value
|
|
71
|
+
return value
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* @return a map with each key-value pair the result of mapping an item in the given list using the given key and value functions.
|
|
77
|
+
*/
|
|
78
|
+
export const mapFrom = <T, V>(ts: T[], keyFunc: (t: T) => string, valueFunc: (t: T) => V): Record<string, V> =>
|
|
79
|
+
Object.fromEntries(
|
|
80
|
+
ts.map((t) => [keyFunc(t), valueFunc(t)])
|
|
81
|
+
)
|
|
82
|
+
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import { groupBy } from "./maps.js"
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
export type Nested1Map<T> = Record<string, T> // (for conceptual continuity)
|
|
5
|
+
export type Nested2Map<T> = Record<string, Record<string, T>>
|
|
6
|
+
export type Nested3Map<T> = Record<string, Record<string, Record<string, T>>>
|
|
7
|
+
|
|
8
|
+
export type Nested1Mapper<T, R> = (nested1Map: Nested1Map<T>) => Nested1Map<R>
|
|
9
|
+
export const mapValuesMapper =
|
|
10
|
+
<T, R>(valueMapFunc: (t: T) => R): Nested1Mapper<T, R> =>
|
|
11
|
+
(map: Record<string, T>): Record<string, R> =>
|
|
12
|
+
Object.fromEntries(Object.entries(map).map(([key, value]) => [key, valueMapFunc(value)]))
|
|
13
|
+
// === mapValues(map, valueFunc)
|
|
14
|
+
|
|
15
|
+
export type Nested2Mapper<T, R> = (nested2Map: Nested2Map<T>) => Nested2Map<R>
|
|
16
|
+
export const nested2Mapper = <T, R>(valueMapFunc: (t: T) => R): Nested2Mapper<T, R> =>
|
|
17
|
+
mapValuesMapper(mapValuesMapper(valueMapFunc))
|
|
18
|
+
|
|
19
|
+
export type Nested3Mapper<T, R> = (nested3Map: Nested3Map<T>) => Nested3Map<R>
|
|
20
|
+
export const nested3Mapper = <T, R>(valueMapFunc: (t: T) => R): Nested3Mapper<T, R> =>
|
|
21
|
+
mapValuesMapper(nested2Mapper(valueMapFunc))
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Return a function that groups an array of things using a group function as a
|
|
25
|
+
* map : string (group key) → array of grouped things.
|
|
26
|
+
*/
|
|
27
|
+
export const grouper =
|
|
28
|
+
<T>(key1Func: (t: T) => string): ((ts: T[]) => Nested1Map<T[]>) =>
|
|
29
|
+
(ts: T[]) =>
|
|
30
|
+
groupBy(ts, key1Func)
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Return a function that groups an array of things using two group functions as a nested map
|
|
34
|
+
* map : string (group key 1) →
|
|
35
|
+
* map : string (group key 2) → array of grouped things.
|
|
36
|
+
*/
|
|
37
|
+
export const nested2Grouper =
|
|
38
|
+
<T>(key1Func: (t: T) => string, key2Func: (t: T) => string): ((ts: T[]) => Nested2Map<T[]>) =>
|
|
39
|
+
(ts: T[]) =>
|
|
40
|
+
mapValuesMapper(grouper(key2Func))(grouper(key1Func)(ts))
|
|
41
|
+
// === mapValuesMapper((vs) => groupBy(vs, key2Func))(groupBy(ts, key1Func))
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Return a function that groups an array of things using two group functions as a nested map
|
|
45
|
+
* map : string (group key 1) →
|
|
46
|
+
* map : string (group key 2) →
|
|
47
|
+
* map : string (group key 3) → array of grouped things.
|
|
48
|
+
*/
|
|
49
|
+
export const nested3Grouper =
|
|
50
|
+
<T>(key1Func: (t: T) => string, key2Func: (t: T) => string, key3Func: (t: T) => string): ((ts: T[]) => Nested3Map<T[]>) =>
|
|
51
|
+
(ts: T[]) =>
|
|
52
|
+
mapValuesMapper(nested2Grouper(key2Func, key3Func))(grouper(key1Func)(ts))
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Flat-maps over the values of a
|
|
56
|
+
* map : string (group key) → values
|
|
57
|
+
* using the map function, which is also provided with the keys.
|
|
58
|
+
*/
|
|
59
|
+
export const flatMapValues = <T, R>(map: Record<string, T>, mapFunc: (t: T, key1: string) => R): R[] =>
|
|
60
|
+
Object
|
|
61
|
+
.entries(map)
|
|
62
|
+
.map(
|
|
63
|
+
([key1, t]) =>
|
|
64
|
+
mapFunc(t, key1)
|
|
65
|
+
)
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Flat-maps over the values of a nested map
|
|
69
|
+
* map : string (group key 1) →
|
|
70
|
+
* map: string (group key 2) → values
|
|
71
|
+
* using the map function, which is also provided with the keys.
|
|
72
|
+
*/
|
|
73
|
+
export const nestedFlatMap2 = <T, R>(nested2Map: Nested2Map<T>, map2Func: (t: T, key1: string, key2: string) => R): R[] =>
|
|
74
|
+
Object
|
|
75
|
+
.entries(nested2Map)
|
|
76
|
+
.flatMap(
|
|
77
|
+
([key1, nestedMap1]) =>
|
|
78
|
+
flatMapValues(nestedMap1, (t, key2) =>
|
|
79
|
+
map2Func(t, key1, key2)
|
|
80
|
+
)
|
|
81
|
+
)
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Flat-maps over the values of a nested map
|
|
85
|
+
* map : string (group key 1) →
|
|
86
|
+
* map: string (group key 2) →
|
|
87
|
+
* map: string (group key 3) → values
|
|
88
|
+
* using the map function, which is also provided with the keys.
|
|
89
|
+
*/
|
|
90
|
+
export const nestedFlatMap3 = <T, R>(nested3Map: Nested3Map<T>, map3Func: (t: T, key1: string, key2: string, key3: string) => R): R[] =>
|
|
91
|
+
Object
|
|
92
|
+
.entries(nested3Map)
|
|
93
|
+
.flatMap(
|
|
94
|
+
([key1, nestedMap2]) =>
|
|
95
|
+
nestedFlatMap2(nestedMap2, (t, key2, key3) =>
|
|
96
|
+
map3Func(t, key1, key2, key3)
|
|
97
|
+
)
|
|
98
|
+
)
|
|
99
|
+
|
package/src/recursion.ts
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Type def. of a generic "flatMap" function.
|
|
3
|
+
*/
|
|
4
|
+
type FlatMapper<T, R> = (t: T) => R[]
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Performs a "flatMap" on a graph that's specified as a start vertex and a function that computes (outgoing) edges.
|
|
8
|
+
* The "flatMap" is performed depth-first, and doesn't loop on cycles.
|
|
9
|
+
*/
|
|
10
|
+
const flatMapNonCyclingFollowing = <T, R>(
|
|
11
|
+
mapper: FlatMapper<T, R>,
|
|
12
|
+
nextVertices: (t: T) => T[]
|
|
13
|
+
): FlatMapper<T, R> =>
|
|
14
|
+
(startVertex: T): R[] => {
|
|
15
|
+
const visited: T[] = []
|
|
16
|
+
const rs: R[] = []
|
|
17
|
+
const recurse = (t: T) => {
|
|
18
|
+
if (visited.indexOf(t) > -1) {
|
|
19
|
+
return
|
|
20
|
+
}
|
|
21
|
+
visited.push(t)
|
|
22
|
+
rs.push(...mapper(t))
|
|
23
|
+
nextVertices(t).forEach(recurse)
|
|
24
|
+
}
|
|
25
|
+
recurse(startVertex)
|
|
26
|
+
return rs
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
const trivialFlatMapper = <T>(t: T) => [t]
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
export type {
|
|
34
|
+
FlatMapper
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export {
|
|
38
|
+
flatMapNonCyclingFollowing,
|
|
39
|
+
trivialFlatMapper
|
|
40
|
+
}
|
|
41
|
+
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A type for functions that map any number of strings (as a variadic argument) to a single string.
|
|
3
|
+
*/
|
|
4
|
+
export type StringsMapper = (...strings: string[]) => string
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* A type for functions that map strings to strings.
|
|
8
|
+
*/
|
|
9
|
+
export type StringMapper = (str: string) => string
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* @return a {@link StringsMapper function} that concatenates the strings passed into it, using the given separator string.
|
|
14
|
+
*/
|
|
15
|
+
export const concatenator = (separator: string): StringsMapper =>
|
|
16
|
+
(...strings) => strings.join(separator)
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* @return a {@link StringsMapper function} that picks the last string of the strings passed into it.
|
|
20
|
+
* (This means that there must always be at least one string passed in.)
|
|
21
|
+
*/
|
|
22
|
+
export const lastOf: StringsMapper =
|
|
23
|
+
(...strings) => strings[strings.length - 1]
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* @return a {@link StringsMapper function} that chains the given {@link StringsMapper functions} (at least 1),
|
|
27
|
+
* in thar order.
|
|
28
|
+
* (This is straightforward functional composition.)
|
|
29
|
+
*/
|
|
30
|
+
export const chain = (stringsMapper: StringsMapper, ...stringMappers: StringMapper[]): StringsMapper =>
|
|
31
|
+
(...strings: string[]) => {
|
|
32
|
+
let result = stringsMapper(...strings)
|
|
33
|
+
stringMappers.forEach((mapper) => {
|
|
34
|
+
result = mapper(result)
|
|
35
|
+
})
|
|
36
|
+
return result
|
|
37
|
+
}
|
|
38
|
+
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Various functional utilities for sorting things.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
type Comparer<T> = (l: T, r: T) => number
|
|
7
|
+
|
|
8
|
+
const stringCompare: Comparer<string> = (l, r): number =>
|
|
9
|
+
l === r ? 0 : (l > r ? 1 : -1)
|
|
10
|
+
|
|
11
|
+
const stringyCompare = <T>(keyFunc: (t: T) => string): Comparer<T> =>
|
|
12
|
+
(l: T, r: T) => stringCompare(keyFunc(l), keyFunc(r))
|
|
13
|
+
|
|
14
|
+
export const sortByStringKey = <T>(ts: T[], keyFunc: (t: T) => string) =>
|
|
15
|
+
[...ts].sort(stringyCompare(keyFunc))
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
export type StringSorter = (strings: string[]) => string[]
|
|
19
|
+
|
|
20
|
+
const sortedStringsWith = (strMap: (str: string) => string): StringSorter =>
|
|
21
|
+
(strings) => {
|
|
22
|
+
strings.sort((l, r) => strMap(l).localeCompare(strMap(r)))
|
|
23
|
+
return strings
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export const sortedStrings = sortedStringsWith((str) => str)
|
|
27
|
+
|
|
28
|
+
export const sortedStringsByUppercase = sortedStringsWith((str) => str.toUpperCase())
|
|
29
|
+
|
package/src/toposort.ts
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
// Copyright 2025 TRUMPF Laser SE and other contributors
|
|
2
|
+
//
|
|
3
|
+
// Licensed under the Apache License, Version 2.0 (the "License")
|
|
4
|
+
// you may not use this file except in compliance with the License.
|
|
5
|
+
// You may obtain a copy of the License at
|
|
6
|
+
//
|
|
7
|
+
// http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
//
|
|
9
|
+
// Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
// See the License for the specific language governing permissions and
|
|
13
|
+
// limitations under the License.
|
|
14
|
+
//
|
|
15
|
+
// SPDX-FileCopyrightText: 2025 TRUMPF Laser SE and other contributors
|
|
16
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Computes the topological order of the transitive closure of the graph with the given vertices and edges given by the edge function,
|
|
20
|
+
* or returns {@code false} if there's a cycle.
|
|
21
|
+
*/
|
|
22
|
+
export const dependencyOrderOf = <T>(vertices: T[], edgesOf: (vertex: T) => T[]): T[] | false => {
|
|
23
|
+
const ordered: T[] = []
|
|
24
|
+
|
|
25
|
+
const visit = (current: T, chain: T[]) => {
|
|
26
|
+
if (ordered.indexOf(current) > -1) {
|
|
27
|
+
return false
|
|
28
|
+
}
|
|
29
|
+
if (chain.indexOf(current) > -1) {
|
|
30
|
+
return true
|
|
31
|
+
}
|
|
32
|
+
const extendedChain = [ ...chain, current ]
|
|
33
|
+
const hasCycle = edgesOf(current).some(
|
|
34
|
+
(edge) => visit(edge, extendedChain)
|
|
35
|
+
)
|
|
36
|
+
ordered.push(current)
|
|
37
|
+
return hasCycle
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const hasCycle = vertices.some(
|
|
41
|
+
(vertex) => visit(vertex, [])
|
|
42
|
+
)
|
|
43
|
+
|
|
44
|
+
return hasCycle ? false : ordered
|
|
45
|
+
}
|
|
46
|
+
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"array-helpers.d.ts","sourceRoot":"","sources":["../src/array-helpers.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,MAAM,MAAM,WAAW,CAAC,CAAC,IAAI,SAAS,GAAG,CAAC,GAAG,CAAC,EAAE,CAAA;AAEhD;;;;GAIG;AACH,eAAO,MAAM,OAAO,mCAQnB,CAAA;AAED;;GAEG;AACH,eAAO,MAAM,YAAY,qBACL,CAAA"}
|
package/dist/array-helpers.js
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Turns a {@link AnyNumberOf feature's value} into an array of objects
|
|
3
|
-
* (possibly empty), regardless of the feature's cardinality and how its
|
|
4
|
-
* value happened to be parsed.
|
|
5
|
-
*/
|
|
6
|
-
export const asArray = (thing) => {
|
|
7
|
-
if (thing === undefined) {
|
|
8
|
-
return [];
|
|
9
|
-
}
|
|
10
|
-
if (Array.isArray(thing)) {
|
|
11
|
-
return thing;
|
|
12
|
-
}
|
|
13
|
-
return [thing];
|
|
14
|
-
};
|
|
15
|
-
/**
|
|
16
|
-
* @return a view of the given array of items with duplicates removed.
|
|
17
|
-
*/
|
|
18
|
-
export const uniquesAmong = (ts) => [...new Set(ts)];
|
|
19
|
-
//# sourceMappingURL=array-helpers.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"array-helpers.js","sourceRoot":"","sources":["../src/array-helpers.ts"],"names":[],"mappings":"AAQA;;;;GAIG;AACH,MAAM,CAAC,MAAM,OAAO,GAAG,CAAI,KAAqB,EAAO,EAAE;IACrD,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QACtB,OAAO,EAAE,CAAA;IACb,CAAC;IACD,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACvB,OAAO,KAAK,CAAA;IAChB,CAAC;IACD,OAAO,CAAC,KAAK,CAAC,CAAA;AAClB,CAAC,CAAA;AAED;;GAEG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,CAAI,EAAO,EAAO,EAAE,CAC5C,CAAC,GAAG,IAAI,GAAG,CAAC,EAAE,CAAC,CAAC,CAAA"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"map-helpers.d.ts","sourceRoot":"","sources":["../src/map-helpers.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,eAAO,MAAM,OAAO;QAAoB,MAAM;;;CAO7C,CAAA;AAGD;;GAEG;AACH,eAAO,MAAM,OAAO,kCAAmC,MAAM,wBAY5D,CAAA;AAGD;;GAEG;AACH,eAAO,MAAM,YAAY,mDAAoD,OAAO,sBAI/E,CAAA;AAGL;;GAEG;AACH,eAAO,MAAM,eAAe,kCAAmC,MAAM,wBACR,CAAA;AAG7D;;GAEG;AACH,eAAO,MAAM,SAAS,2EAIjB,CAAA"}
|
package/dist/map-helpers.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"map-helpers.js","sourceRoot":"","sources":["../src/map-helpers.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,CAAC,MAAM,OAAO,GAAG,CAA2B,EAAO,EAAuB,EAAE;IAC9E,MAAM,GAAG,GAAwB,EAAE,CAAA;IACnC,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE;QACb,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAA;IACjB,CAAC,CAAC,CAAA;IACF,OAAO,GAAG,CAAA;IACV,6EAA6E;AACjF,CAAC,CAAA;AAGD;;GAEG;AACH,MAAM,CAAC,MAAM,OAAO,GAAG,CAAI,EAAO,EAAE,OAAyB,EAAuB,EAAE;IAClF,MAAM,GAAG,GAAwB,EAAE,CAAA;IACnC,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE;QACb,MAAM,GAAG,GAAG,OAAO,CAAC,CAAC,CAAC,CAAA;QACtB,IAAI,IAAI,GAAG,GAAG,CAAC,GAAG,CAAC,CAAA;QACnB,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;YACrB,IAAI,GAAG,EAAE,CAAA;YACT,GAAG,CAAC,GAAG,CAAC,GAAG,IAAI,CAAA;QACnB,CAAC;QACD,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IAChB,CAAC,CAAC,CAAA;IACF,OAAO,GAAG,CAAA;AACd,CAAC,CAAA;AAGD;;GAEG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,CAAI,GAAsB,EAAE,SAA4B,EAAqB,EAAE,CACvG,MAAM,CAAC,WAAW,CACd,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC;KACd,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAChD,CAAA;AAGL;;GAEG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,CAAI,EAAO,EAAE,OAAyB,EAAuB,EAAE,CAC1F,YAAY,CAAC,OAAO,CAAC,EAAE,EAAE,OAAO,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC,CAAA;AAG7D;;GAEG;AACH,MAAM,CAAC,MAAM,SAAS,GAAG,CAAO,GAAsB,EAAE,OAAoB,EAAqB,EAAE,CAC/F,MAAM,CAAC,WAAW,CACd,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC;KACd,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CACpD,CAAA"}
|
package/dist/nested-map.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"nested-map.d.ts","sourceRoot":"","sources":["../src/nested-map.ts"],"names":[],"mappings":"AAGA,MAAM,MAAM,UAAU,CAAC,CAAC,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,CAAA;AAC7C,MAAM,MAAM,UAAU,CAAC,CAAC,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAA;AAC7D,MAAM,MAAM,UAAU,CAAC,CAAC,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,CAAA;AAE7E,eAAO,MAAM,eAAe,oFAGqE,CAAA;AAGjG,eAAO,MAAM,aAAa,oHAAsF,CAAA;AAEhH,eAAO,MAAM,aAAa,oJAAoF,CAAA;AAE9G;;;GAGG;AACH,eAAO,MAAM,OAAO,0BACQ,MAAM,iCAED,CAAA;AAEjC;;;;GAIG;AACH,eAAO,MAAM,cAAc,0BACC,MAAM,sBAAsB,MAAM,iCAEO,CAAA;AAGrE;;;;;GAKG;AACH,eAAO,MAAM,cAAc,0BACC,MAAM,sBAAsB,MAAM,sBAAsB,MAAM,iCAEJ,CAAA;AAEtF;;;;GAIG;AACH,eAAO,MAAM,aAAa,uDAAwD,MAAM,cAM/E,CAAA;AAET;;;;;GAKG;AACH,eAAO,MAAM,cAAc,2DAA4D,MAAM,QAAQ,MAAM,cAQlG,CAAA;AAET;;;;;;GAMG;AACH,eAAO,MAAM,cAAc,2DAA4D,MAAM,QAAQ,MAAM,QAAQ,MAAM,cAQhH,CAAA"}
|
package/dist/nested-map.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"nested-map.js","sourceRoot":"","sources":["../src/nested-map.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAA;AAO1C,MAAM,CAAC,MAAM,eAAe,GACxB,CAAO,YAAyB,EAAE,EAAE,CACpC,CAAC,GAAsB,EAAqB,EAAE,CAC1C,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,EAAE,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAA;AACjG,gCAAgC;AAEhC,MAAM,CAAC,MAAM,aAAa,GAAG,CAAO,YAAyB,EAAE,EAAE,CAAC,eAAe,CAAC,eAAe,CAAC,YAAY,CAAC,CAAC,CAAA;AAEhH,MAAM,CAAC,MAAM,aAAa,GAAG,CAAO,YAAyB,EAAE,EAAE,CAAC,eAAe,CAAC,aAAa,CAAC,YAAY,CAAC,CAAC,CAAA;AAE9G;;;GAGG;AACH,MAAM,CAAC,MAAM,OAAO,GAChB,CAAI,QAA0B,EAAkC,EAAE,CAC9D,CAAC,EAAO,EAAE,EAAE,CACR,OAAO,CAAC,EAAE,EAAE,QAAQ,CAAC,CAAA;AAEjC;;;;GAIG;AACH,MAAM,CAAC,MAAM,cAAc,GACvB,CAAI,QAA0B,EAAE,QAA0B,EAAkC,EAAE,CAC1F,CAAC,EAAO,EAAE,EAAE,CACR,eAAe,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,CAAC,CAAA;AACrE,4EAA4E;AAE5E;;;;;GAKG;AACH,MAAM,CAAC,MAAM,cAAc,GACvB,CAAI,QAA0B,EAAE,QAA0B,EAAE,QAA0B,EAAkC,EAAE,CACtH,CAAC,EAAO,EAAE,EAAE,CACR,eAAe,CAAC,cAAc,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,CAAC,CAAA;AAEtF;;;;GAIG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,CAAO,GAAsB,EAAE,OAAkC,EAAO,EAAE,CACnG,MAAM;KACD,OAAO,CAAC,GAAG,CAAC;KACZ,GAAG,CACA,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,EAAE,EAAE,CACV,OAAO,CAAC,CAAC,EAAE,IAAI,CAAC,CACvB,CAAA;AAET;;;;;GAKG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,CAAO,UAAyB,EAAE,QAAiD,EAAO,EAAE,CACtH,MAAM;KACD,OAAO,CAAC,UAAU,CAAC;KACnB,OAAO,CACJ,CAAC,CAAC,IAAI,EAAE,UAAU,CAAC,EAAE,EAAE,CACnB,aAAa,CAAC,UAAU,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,EAAE,CAClC,QAAQ,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,CAC1B,CACR,CAAA;AAET;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,CAAO,UAAyB,EAAE,QAA+D,EAAO,EAAE,CACpI,MAAM;KACD,OAAO,CAAC,UAAU,CAAC;KACnB,OAAO,CACJ,CAAC,CAAC,IAAI,EAAE,UAAU,CAAC,EAAE,EAAE,CACnB,cAAc,CAAC,UAAU,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,CACzC,QAAQ,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,CAChC,CACR,CAAA"}
|