@thi.ng/arrays 2.3.10 → 2.4.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/CHANGELOG.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Change Log
2
2
 
3
- - **Last updated**: 2022-10-03T16:07:55Z
3
+ - **Last updated**: 2022-10-31T23:01:45Z
4
4
  - **Generator**: [thi.ng/monopub](https://thi.ng/monopub)
5
5
 
6
6
  All notable changes to this project will be documented in this file.
@@ -9,6 +9,15 @@ See [Conventional Commits](https://conventionalcommits.org/) for commit guidelin
9
9
  **Note:** Unlisted _patch_ versions only involve non-code or otherwise excluded changes
10
10
  and/or version bumps of transitive dependencies.
11
11
 
12
+ ## [2.4.0](https://github.com/thi-ng/umbrella/tree/@thi.ng/arrays@2.4.0) (2022-10-31)
13
+
14
+ #### 🚀 Features
15
+
16
+ - add topoSort() ([f7f2e20](https://github.com/thi-ng/umbrella/commit/f7f2e20))
17
+ - add topoSort() as lightweight alt for [@thi.ng/dgraph](https://github.com/thi-ng/umbrella/tree/main/packages/dgraph)
18
+ - add tests
19
+ - update readme
20
+
12
21
  ## [2.3.0](https://github.com/thi-ng/umbrella/tree/@thi.ng/arrays@2.3.0) (2022-07-08)
13
22
 
14
23
  #### 🚀 Features
package/README.md CHANGED
@@ -51,7 +51,7 @@ node --experimental-repl-await
51
51
  > const arrays = await import("@thi.ng/arrays");
52
52
  ```
53
53
 
54
- Package sizes (gzipped, pre-treeshake): ESM: 2.51 KB
54
+ Package sizes (gzipped, pre-treeshake): ESM: 2.64 KB
55
55
 
56
56
  ## Dependencies
57
57
 
@@ -90,6 +90,7 @@ Package sizes (gzipped, pre-treeshake): ESM: 2.51 KB
90
90
  - [startsWith()](https://github.com/thi-ng/umbrella/tree/develop/packages/arrays/src/starts-with.ts)
91
91
  - [swap()](https://github.com/thi-ng/umbrella/tree/develop/packages/arrays/src/swap.ts)
92
92
  - [swizzle()](https://github.com/thi-ng/umbrella/tree/develop/packages/arrays/src/swizzle.ts)
93
+ - [topoSort()](https://github.com/thi-ng/umbrella/tree/develop/packages/arrays/src/topo-sort.ts)
93
94
 
94
95
  ### Binary search result predicates
95
96
 
package/index.d.ts CHANGED
@@ -21,4 +21,5 @@ export * from "./sort-cached.js";
21
21
  export * from "./starts-with.js";
22
22
  export * from "./swap.js";
23
23
  export * from "./swizzle.js";
24
+ export * from "./topo-sort.js";
24
25
  //# sourceMappingURL=index.d.ts.map
package/index.js CHANGED
@@ -21,3 +21,4 @@ export * from "./sort-cached.js";
21
21
  export * from "./starts-with.js";
22
22
  export * from "./swap.js";
23
23
  export * from "./swizzle.js";
24
+ export * from "./topo-sort.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@thi.ng/arrays",
3
- "version": "2.3.10",
3
+ "version": "2.4.0",
4
4
  "description": "Array / Arraylike utilities",
5
5
  "type": "module",
6
6
  "module": "./index.js",
@@ -34,29 +34,33 @@
34
34
  "test": "testament test"
35
35
  },
36
36
  "dependencies": {
37
- "@thi.ng/api": "^8.4.3",
38
- "@thi.ng/checks": "^3.3.1",
39
- "@thi.ng/compare": "^2.1.13",
40
- "@thi.ng/equiv": "^2.1.11",
41
- "@thi.ng/errors": "^2.2.2",
42
- "@thi.ng/random": "^3.3.12"
37
+ "@thi.ng/api": "^8.4.4",
38
+ "@thi.ng/checks": "^3.3.2",
39
+ "@thi.ng/compare": "^2.1.14",
40
+ "@thi.ng/equiv": "^2.1.12",
41
+ "@thi.ng/errors": "^2.2.3",
42
+ "@thi.ng/random": "^3.3.13"
43
43
  },
44
44
  "devDependencies": {
45
- "@microsoft/api-extractor": "^7.31.1",
46
- "@thi.ng/testament": "^0.3.3",
45
+ "@microsoft/api-extractor": "^7.33.5",
46
+ "@thi.ng/testament": "^0.3.4",
47
47
  "rimraf": "^3.0.2",
48
48
  "tools": "^0.0.1",
49
- "typedoc": "^0.22.17",
50
- "typescript": "^4.8.3"
49
+ "typedoc": "^0.23.18",
50
+ "typescript": "^4.8.4"
51
51
  },
52
52
  "keywords": [
53
53
  "aos",
54
54
  "array",
55
55
  "binary",
56
+ "distance",
56
57
  "fuzzy",
58
+ "levenshtein",
57
59
  "search",
58
60
  "shuffle",
61
+ "sort",
59
62
  "swizzle",
63
+ "topology",
60
64
  "typescript"
61
65
  ],
62
66
  "publishConfig": {
@@ -141,10 +145,13 @@
141
145
  },
142
146
  "./swizzle": {
143
147
  "default": "./swizzle.js"
148
+ },
149
+ "./topo-sort": {
150
+ "default": "./topo-sort.js"
144
151
  }
145
152
  },
146
153
  "thi.ng": {
147
154
  "year": 2018
148
155
  },
149
- "gitHead": "cc61bc0a890288bea00b8df81ffd73bc4851ffd3\n"
156
+ "gitHead": "7eff3051eb395f460421727b8cf5ef79f09faaa9\n"
150
157
  }
package/topo-sort.d.ts ADDED
@@ -0,0 +1,36 @@
1
+ import type { Fn, Nullable, IObjectOf } from "@thi.ng/api";
2
+ /**
3
+ * Takes an object describing a DAG of nodes of type T with keys being node IDs.
4
+ * Also takes a function which will be applied to each node and either returns
5
+ * an array of node IDs the given node depends on or null if the node has no
6
+ * dependencies. Traverses all nodes in the graph (object) and returns an array
7
+ * of node IDs in topological dependency order.
8
+ *
9
+ * @remarks
10
+ * An error will be thrown if the graph contains cycles. In this case, the full
11
+ * cycle will be part of the error message (see second example below).
12
+ *
13
+ * @example
14
+ * ```ts
15
+ * const graph = {
16
+ * a: { deps: ["c", "b"] },
17
+ * b: {},
18
+ * c: { deps: ["d"] },
19
+ * d: { deps: ["b"] }
20
+ * };
21
+ * topoSort(graph, (node) => node.deps);
22
+ * // [ "b", "d", "c", "a" ]
23
+ *
24
+ * // An error will be thrown if the graph contains cycles...
25
+ * graph.d.deps.push("a");
26
+ *
27
+ * topoSort(graph, (node) => node.deps);
28
+ * // Uncaught Error: illegal state: dependency cycle: a -> c -> d -> a
29
+ * ```
30
+ *
31
+ * @param nodes
32
+ * @param deps
33
+ * @returns
34
+ */
35
+ export declare const topoSort: <T>(nodes: IObjectOf<T>, deps: Fn<T, Nullable<string[]>>) => string[];
36
+ //# sourceMappingURL=topo-sort.d.ts.map
package/topo-sort.js ADDED
@@ -0,0 +1,54 @@
1
+ import { illegalState } from "@thi.ng/errors";
2
+ /**
3
+ * Takes an object describing a DAG of nodes of type T with keys being node IDs.
4
+ * Also takes a function which will be applied to each node and either returns
5
+ * an array of node IDs the given node depends on or null if the node has no
6
+ * dependencies. Traverses all nodes in the graph (object) and returns an array
7
+ * of node IDs in topological dependency order.
8
+ *
9
+ * @remarks
10
+ * An error will be thrown if the graph contains cycles. In this case, the full
11
+ * cycle will be part of the error message (see second example below).
12
+ *
13
+ * @example
14
+ * ```ts
15
+ * const graph = {
16
+ * a: { deps: ["c", "b"] },
17
+ * b: {},
18
+ * c: { deps: ["d"] },
19
+ * d: { deps: ["b"] }
20
+ * };
21
+ * topoSort(graph, (node) => node.deps);
22
+ * // [ "b", "d", "c", "a" ]
23
+ *
24
+ * // An error will be thrown if the graph contains cycles...
25
+ * graph.d.deps.push("a");
26
+ *
27
+ * topoSort(graph, (node) => node.deps);
28
+ * // Uncaught Error: illegal state: dependency cycle: a -> c -> d -> a
29
+ * ```
30
+ *
31
+ * @param nodes
32
+ * @param deps
33
+ * @returns
34
+ */
35
+ export const topoSort = (nodes, deps) => {
36
+ const cycles = {};
37
+ const topology = [];
38
+ const sort = (id, path) => {
39
+ if (cycles[id])
40
+ illegalState(`dependency cycle: ${path.join(" -> ")}`);
41
+ cycles[id] = true;
42
+ const nodeDeps = deps(nodes[id]);
43
+ if (nodeDeps) {
44
+ for (let d of nodeDeps)
45
+ sort(d, [...path, d]);
46
+ }
47
+ cycles[id] = false;
48
+ if (!topology.includes(id))
49
+ topology.push(id);
50
+ };
51
+ for (let id in nodes)
52
+ sort(id, [id]);
53
+ return topology;
54
+ };