@eggjs/tegg-common-util 4.0.2-beta.19 → 4.0.2-beta.20

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/dist/Graph.d.ts CHANGED
@@ -37,8 +37,17 @@ declare class Graph<T extends GraphNodeObj, M extends EdgeMeta = EdgeMeta> {
37
37
  addVertex(node: GraphNode<T, M>): boolean;
38
38
  addEdge(from: GraphNode<T, M>, to: GraphNode<T, M>, meta?: M): boolean;
39
39
  findToNode(id: string, meta: M): GraphNode<T, M> | undefined;
40
+ /**
41
+ * @deprecated Use loopPath() instead. This method is kept for compatibility.
42
+ */
40
43
  appendVertexToPath(node: GraphNode<T, M>, accessPath: GraphPath<T, M>, meta?: M): boolean;
44
+ private buildLoopPath;
45
+ private findLoopPath;
41
46
  loopPath(): GraphPath<T, M> | undefined;
47
+ private accessNodeWithSet;
48
+ /**
49
+ * @deprecated Prefer sort(), which uses Set-based traversal directly.
50
+ */
42
51
  accessNode(node: GraphNode<T, M>, nodes: Array<GraphNode<T, M>>, accessed: boolean[], res: Array<GraphNode<T, M>>): void;
43
52
  sort(): Array<GraphNode<T, M>>;
44
53
  }
package/dist/Graph.js CHANGED
@@ -82,37 +82,74 @@ var Graph = class {
82
82
  if (!node) return void 0;
83
83
  for (const { node: toNode, meta: edgeMeta } of node.toNodeMap.values()) if (edgeMeta && meta.equal(edgeMeta)) return toNode;
84
84
  }
85
+ /**
86
+ * @deprecated Use loopPath() instead. This method is kept for compatibility.
87
+ */
85
88
  appendVertexToPath(node, accessPath, meta) {
86
89
  if (!accessPath.pushVertex(node, meta)) return false;
87
90
  for (const toNode of node.toNodeMap.values()) if (!this.appendVertexToPath(toNode.node, accessPath, toNode.meta)) return false;
88
91
  accessPath.popVertex();
89
92
  return true;
90
93
  }
91
- loopPath() {
94
+ buildLoopPath(stack, node, meta) {
92
95
  const accessPath = new GraphPath();
96
+ for (const pathNode of stack) accessPath.pushVertex(pathNode.node, pathNode.meta);
97
+ accessPath.pushVertex(node, meta);
98
+ return accessPath;
99
+ }
100
+ findLoopPath(node, visiting, visited, stack, meta) {
101
+ if (visited.has(node.id)) return;
102
+ if (visiting.has(node.id)) return this.buildLoopPath(stack, node, meta);
103
+ visiting.add(node.id);
104
+ stack.push({
105
+ node,
106
+ meta
107
+ });
108
+ for (const toNode of node.toNodeMap.values()) {
109
+ const loopPath = this.findLoopPath(toNode.node, visiting, visited, stack, toNode.meta);
110
+ if (loopPath) return loopPath;
111
+ }
112
+ stack.pop();
113
+ visiting.delete(node.id);
114
+ visited.add(node.id);
115
+ }
116
+ loopPath() {
117
+ const visiting = /* @__PURE__ */ new Set();
118
+ const visited = /* @__PURE__ */ new Set();
119
+ const stack = [];
93
120
  const nodes = Array.from(this.nodes.values());
94
- for (const node of nodes) if (!this.appendVertexToPath(node, accessPath)) return accessPath;
121
+ for (const node of nodes) {
122
+ const loopPath = this.findLoopPath(node, visiting, visited, stack);
123
+ if (loopPath) return loopPath;
124
+ }
95
125
  }
96
- accessNode(node, nodes, accessed, res) {
97
- if (accessed[nodes.indexOf(node)]) return;
98
- if (!node.toNodeMap.size) {
99
- accessed[nodes.indexOf(node)] = true;
100
- res.push(node);
101
- return;
126
+ accessNodeWithSet(node, accessed, visiting, res) {
127
+ if (accessed.has(node)) return;
128
+ if (visiting.has(node)) throw new Error("graph has recursive deps: " + node);
129
+ visiting.add(node);
130
+ try {
131
+ for (const toNode of node.toNodeMap.values()) this.accessNodeWithSet(toNode.node, accessed, visiting, res);
132
+ } finally {
133
+ visiting.delete(node);
102
134
  }
103
- for (const toNode of node.toNodeMap.values()) this.accessNode(toNode.node, nodes, accessed, res);
104
- accessed[nodes.indexOf(node)] = true;
135
+ accessed.add(node);
105
136
  res.push(node);
106
137
  }
138
+ /**
139
+ * @deprecated Prefer sort(), which uses Set-based traversal directly.
140
+ */
141
+ accessNode(node, nodes, accessed, res) {
142
+ const accessedSet = /* @__PURE__ */ new Set();
143
+ for (let i = 0; i < nodes.length; ++i) if (accessed[i]) accessedSet.add(nodes[i]);
144
+ this.accessNodeWithSet(node, accessedSet, /* @__PURE__ */ new Set(), res);
145
+ for (let i = 0; i < nodes.length; ++i) accessed[i] = accessedSet.has(nodes[i]);
146
+ }
107
147
  sort() {
108
148
  const res = [];
109
149
  const nodes = Array.from(this.nodes.values());
110
- const accessed = [];
111
- for (let i = 0; i < nodes.length; ++i) accessed.push(false);
112
- for (let i = 0; i < nodes.length; ++i) {
113
- const node = nodes[i];
114
- this.accessNode(node, nodes, accessed, res);
115
- }
150
+ const accessed = /* @__PURE__ */ new Set();
151
+ const visiting = /* @__PURE__ */ new Set();
152
+ for (const node of nodes) this.accessNodeWithSet(node, accessed, visiting, res);
116
153
  return res;
117
154
  }
118
155
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@eggjs/tegg-common-util",
3
- "version": "4.0.2-beta.19",
3
+ "version": "4.0.2-beta.20",
4
4
  "description": "common util for tegg",
5
5
  "keywords": [
6
6
  "collection",
@@ -41,8 +41,8 @@
41
41
  "typecheck": "tsgo --noEmit"
42
42
  },
43
43
  "dependencies": {
44
- "@eggjs/tegg-types": "4.0.2-beta.19",
45
- "@eggjs/utils": "5.0.2-beta.19",
44
+ "@eggjs/tegg-types": "4.0.2-beta.20",
45
+ "@eggjs/utils": "5.0.2-beta.20",
46
46
  "extend2": "^4.0.0",
47
47
  "globby": "^11.0.2",
48
48
  "js-yaml": "^4.1.1",