@rsconcept/domain 1.0.0 → 1.2.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.
Files changed (185) hide show
  1. package/README.md +3 -3
  2. package/dist/analyzer-DlSq3Y3r.d.ts +39 -0
  3. package/dist/arguments-extractor-1acwjQNc.d.ts +38 -0
  4. package/dist/ast-C8sIpKdL.d.ts +51 -0
  5. package/dist/ast-annotations-BiMjkKvz.d.ts +16 -0
  6. package/dist/branded-ZlzIcxzu.d.ts +9 -0
  7. package/dist/calculator-C9W2jkSx.d.ts +39 -0
  8. package/dist/cctext/index.d.ts +2 -1
  9. package/dist/cctext/index.js +2 -42
  10. package/dist/cctext/language-api.d.ts +10 -12
  11. package/dist/cctext/language-api.js +157 -227
  12. package/dist/cctext/language-api.js.map +1 -1
  13. package/dist/cctext/language.d.ts +24 -22
  14. package/dist/cctext/language.js +43 -39
  15. package/dist/cctext/language.js.map +1 -1
  16. package/dist/error-E1LVq_3w.d.ts +87 -0
  17. package/dist/graph/graph.d.ts +2 -62
  18. package/dist/graph/graph.js +339 -382
  19. package/dist/graph/graph.js.map +1 -1
  20. package/dist/graph/index.d.ts +2 -1
  21. package/dist/graph/index.js +2 -384
  22. package/dist/graph-DR8rL2o3.d.ts +64 -0
  23. package/dist/hash-Y8I4c6Al.d.ts +8 -0
  24. package/dist/index-BKZ67WMa.d.ts +1 -0
  25. package/dist/index-BVVgDSdq.d.ts +1 -0
  26. package/dist/index-DmtQKWjk.d.ts +1 -0
  27. package/dist/index-_6s0AX1B.d.ts +1 -0
  28. package/dist/index.d.ts +27 -28
  29. package/dist/index.js +23 -5851
  30. package/dist/lezer-tree-iS7LpLBJ.d.ts +14 -0
  31. package/dist/library/folder-tree.d.ts +22 -20
  32. package/dist/library/folder-tree.js +108 -130
  33. package/dist/library/folder-tree.js.map +1 -1
  34. package/dist/library/index.d.ts +8 -17
  35. package/dist/library/index.js +7 -2800
  36. package/dist/library/library-api.d.ts +3 -1
  37. package/dist/library/library-api.js +9 -8
  38. package/dist/library/library-api.js.map +1 -1
  39. package/dist/library/library.d.ts +2 -56
  40. package/dist/library/library.js +23 -19
  41. package/dist/library/library.js.map +1 -1
  42. package/dist/library/oss-api.d.ts +26 -37
  43. package/dist/library/oss-api.js +258 -1096
  44. package/dist/library/oss-api.js.map +1 -1
  45. package/dist/library/oss-layout-api.d.ts +28 -28
  46. package/dist/library/oss-layout-api.js +239 -316
  47. package/dist/library/oss-layout-api.js.map +1 -1
  48. package/dist/library/oss-layout.d.ts +2 -25
  49. package/dist/library/oss-layout.js +1 -1
  50. package/dist/library/oss.d.ts +87 -89
  51. package/dist/library/oss.js +27 -26
  52. package/dist/library/oss.js.map +1 -1
  53. package/dist/library/rsengine.d.ts +100 -106
  54. package/dist/library/rsengine.js +439 -2599
  55. package/dist/library/rsengine.js.map +1 -1
  56. package/dist/library/rsform-api.d.ts +11 -16
  57. package/dist/library/rsform-api.js +313 -825
  58. package/dist/library/rsform-api.js.map +1 -1
  59. package/dist/library/rsform.d.ts +159 -167
  60. package/dist/library/rsform.js +29 -28
  61. package/dist/library/rsform.js.map +1 -1
  62. package/dist/library/rsmodel-api.d.ts +8 -15
  63. package/dist/library/rsmodel-api.js +172 -813
  64. package/dist/library/rsmodel-api.js.map +1 -1
  65. package/dist/library/rsmodel.d.ts +27 -33
  66. package/dist/library/rsmodel.js +16 -23
  67. package/dist/library/rsmodel.js.map +1 -1
  68. package/dist/library/structure-planner.d.ts +20 -26
  69. package/dist/library/structure-planner.js +106 -474
  70. package/dist/library/structure-planner.js.map +1 -1
  71. package/dist/library-CYun28Xz.d.ts +58 -0
  72. package/dist/oss-layout-3glgAqfn.d.ts +27 -0
  73. package/dist/parser-Bwd8LxJ1.d.ts +7 -0
  74. package/dist/parsing/ast.d.ts +2 -49
  75. package/dist/parsing/ast.js +68 -76
  76. package/dist/parsing/ast.js.map +1 -1
  77. package/dist/parsing/index.d.ts +3 -3
  78. package/dist/parsing/index.js +3 -141
  79. package/dist/parsing/lezer-tree.d.ts +2 -13
  80. package/dist/parsing/lezer-tree.js +50 -43
  81. package/dist/parsing/lezer-tree.js.map +1 -1
  82. package/dist/rslang/api.d.ts +9 -14
  83. package/dist/rslang/api.js +114 -827
  84. package/dist/rslang/api.js.map +1 -1
  85. package/dist/rslang/ast-annotations.d.ts +2 -18
  86. package/dist/rslang/ast-annotations.js +34 -45
  87. package/dist/rslang/ast-annotations.js.map +1 -1
  88. package/dist/rslang/error.d.ts +2 -85
  89. package/dist/rslang/error.js +88 -150
  90. package/dist/rslang/error.js.map +1 -1
  91. package/dist/rslang/eval/calculator.d.ts +2 -43
  92. package/dist/rslang/eval/calculator.js +81 -1636
  93. package/dist/rslang/eval/calculator.js.map +1 -1
  94. package/dist/rslang/eval/evaluation-cache.d.ts +22 -26
  95. package/dist/rslang/eval/evaluation-cache.js +168 -287
  96. package/dist/rslang/eval/evaluation-cache.js.map +1 -1
  97. package/dist/rslang/eval/evaluator.d.ts +59 -63
  98. package/dist/rslang/eval/evaluator.js +602 -1509
  99. package/dist/rslang/eval/evaluator.js.map +1 -1
  100. package/dist/rslang/eval/value-api.d.ts +2 -48
  101. package/dist/rslang/eval/value-api.js +2 -490
  102. package/dist/rslang/eval/value.d.ts +2 -36
  103. package/dist/rslang/eval/value.js +2 -118
  104. package/dist/rslang/index.d.ts +14 -17
  105. package/dist/rslang/index.js +12 -4314
  106. package/dist/rslang/labels.d.ts +6 -6
  107. package/dist/rslang/labels.js +139 -305
  108. package/dist/rslang/labels.js.map +1 -1
  109. package/dist/rslang/parser/expression-generator.d.ts +5 -5
  110. package/dist/rslang/parser/expression-generator.js +248 -446
  111. package/dist/rslang/parser/expression-generator.js.map +1 -1
  112. package/dist/rslang/parser/normalize.d.ts +4 -8
  113. package/dist/rslang/parser/normalize.js +286 -481
  114. package/dist/rslang/parser/normalize.js.map +1 -1
  115. package/dist/rslang/parser/parser.d.ts +2 -5
  116. package/dist/rslang/parser/parser.js +30 -21
  117. package/dist/rslang/parser/parser.js.map +1 -1
  118. package/dist/rslang/parser/parser.terms.d.ts +43 -41
  119. package/dist/rslang/parser/parser.terms.js +44 -83
  120. package/dist/rslang/parser/parser.terms.js.map +1 -1
  121. package/dist/rslang/parser/syntax-errors.d.ts +5 -8
  122. package/dist/rslang/parser/syntax-errors.js +113 -382
  123. package/dist/rslang/parser/syntax-errors.js.map +1 -1
  124. package/dist/rslang/parser/token.d.ts +2 -79
  125. package/dist/rslang/parser/token.js +81 -93
  126. package/dist/rslang/parser/token.js.map +1 -1
  127. package/dist/rslang/semantic/analyzer.d.ts +2 -39
  128. package/dist/rslang/semantic/analyzer.js +186 -2600
  129. package/dist/rslang/semantic/analyzer.js.map +1 -1
  130. package/dist/rslang/semantic/arguments-extractor.d.ts +2 -42
  131. package/dist/rslang/semantic/arguments-extractor.js +202 -361
  132. package/dist/rslang/semantic/arguments-extractor.js.map +1 -1
  133. package/dist/rslang/semantic/type-auditor.d.ts +64 -68
  134. package/dist/rslang/semantic/type-auditor.js +594 -1564
  135. package/dist/rslang/semantic/type-auditor.js.map +1 -1
  136. package/dist/rslang/semantic/typification-api.d.ts +4 -7
  137. package/dist/rslang/semantic/typification-api.js +162 -303
  138. package/dist/rslang/semantic/typification-api.js.map +1 -1
  139. package/dist/rslang/semantic/typification-parser.d.ts +2 -12
  140. package/dist/rslang/semantic/typification-parser.js +165 -219
  141. package/dist/rslang/semantic/typification-parser.js.map +1 -1
  142. package/dist/rslang/semantic/typification.d.ts +2 -119
  143. package/dist/rslang/semantic/typification.js +66 -52
  144. package/dist/rslang/semantic/typification.js.map +1 -1
  145. package/dist/rslang/semantic/value-auditor.d.ts +32 -38
  146. package/dist/rslang/semantic/value-auditor.js +206 -518
  147. package/dist/rslang/semantic/value-auditor.js.map +1 -1
  148. package/dist/rslang/semantic/value-class.d.ts +2 -10
  149. package/dist/rslang/semantic/value-class.js +8 -7
  150. package/dist/rslang/semantic/value-class.js.map +1 -1
  151. package/dist/rslang/typification-graph.d.ts +2 -33
  152. package/dist/rslang/typification-graph.js +94 -306
  153. package/dist/rslang/typification-graph.js.map +1 -1
  154. package/dist/shared/branded.d.ts +2 -7
  155. package/dist/shared/branded.js +1 -1
  156. package/dist/shared/hash.d.ts +2 -6
  157. package/dist/shared/hash.js +13 -13
  158. package/dist/shared/hash.js.map +1 -1
  159. package/dist/shared/index.d.ts +3 -2
  160. package/dist/shared/index.js +2 -18
  161. package/dist/token-DeXAmzwr.d.ts +81 -0
  162. package/dist/typification-Dk-fisgO.d.ts +120 -0
  163. package/dist/typification-graph-6HcZ-rKH.d.ts +30 -0
  164. package/dist/typification-parser-BBVx1RxP.d.ts +13 -0
  165. package/dist/value-B8UtCqaK.js +366 -0
  166. package/dist/value-B8UtCqaK.js.map +1 -0
  167. package/dist/value-CTjX6825.d.ts +33 -0
  168. package/dist/value-api-Bw-SgaYY.d.ts +49 -0
  169. package/dist/value-class-CNI-lqXJ.d.ts +12 -0
  170. package/package.json +8 -8
  171. package/src/library/oss-api.test.ts +76 -0
  172. package/src/library/oss-api.ts +4 -1
  173. package/src/library/rsform-api.test.ts +24 -0
  174. package/src/library/rsform-api.ts +12 -4
  175. package/dist/cctext/index.js.map +0 -1
  176. package/dist/graph/index.js.map +0 -1
  177. package/dist/index.js.map +0 -1
  178. package/dist/library/index.js.map +0 -1
  179. package/dist/library/oss-layout.js.map +0 -1
  180. package/dist/parsing/index.js.map +0 -1
  181. package/dist/rslang/eval/value-api.js.map +0 -1
  182. package/dist/rslang/eval/value.js.map +0 -1
  183. package/dist/rslang/index.js.map +0 -1
  184. package/dist/shared/branded.js.map +0 -1
  185. package/dist/shared/index.js.map +0 -1
@@ -1,385 +1,342 @@
1
- // src/graph/graph.ts
2
- var GraphNode = class _GraphNode {
3
- /** Unique identifier of the node. */
4
- id;
5
- /** List of outgoing nodes. */
6
- outputs;
7
- /** List of incoming nodes. */
8
- inputs;
9
- constructor(id) {
10
- this.id = id;
11
- this.outputs = [];
12
- this.inputs = [];
13
- }
14
- clone() {
15
- const result = new _GraphNode(this.id);
16
- result.outputs = [...this.outputs];
17
- result.inputs = [...this.inputs];
18
- return result;
19
- }
20
- addOutput(node) {
21
- this.outputs.push(node);
22
- }
23
- addInput(node) {
24
- this.inputs.push(node);
25
- }
26
- removeInput(target) {
27
- const index = this.inputs.findIndex((node) => node === target);
28
- return index > -1 ? this.inputs.splice(index, 1)[0] : null;
29
- }
30
- removeOutput(target) {
31
- const index = this.outputs.findIndex((node) => node === target);
32
- return index > -1 ? this.outputs.splice(index, 1)[0] : null;
33
- }
1
+ //#region src/graph/graph.ts
2
+ /**
3
+ * Module: Custom graph data structure.
4
+ */
5
+ /** Represents single node of a {@link Graph}, as implemented by storing outgoing and incoming connections. */
6
+ var GraphNode = class GraphNode {
7
+ /** Unique identifier of the node. */
8
+ id;
9
+ /** List of outgoing nodes. */
10
+ outputs;
11
+ /** List of incoming nodes. */
12
+ inputs;
13
+ constructor(id) {
14
+ this.id = id;
15
+ this.outputs = [];
16
+ this.inputs = [];
17
+ }
18
+ clone() {
19
+ const result = new GraphNode(this.id);
20
+ result.outputs = [...this.outputs];
21
+ result.inputs = [...this.inputs];
22
+ return result;
23
+ }
24
+ addOutput(node) {
25
+ this.outputs.push(node);
26
+ }
27
+ addInput(node) {
28
+ this.inputs.push(node);
29
+ }
30
+ removeInput(target) {
31
+ const index = this.inputs.findIndex((node) => node === target);
32
+ return index > -1 ? this.inputs.splice(index, 1)[0] : null;
33
+ }
34
+ removeOutput(target) {
35
+ const index = this.outputs.findIndex((node) => node === target);
36
+ return index > -1 ? this.outputs.splice(index, 1)[0] : null;
37
+ }
34
38
  };
35
- var Graph = class _Graph {
36
- /** Map of nodes. */
37
- nodes = /* @__PURE__ */ new Map();
38
- constructor(arr) {
39
- if (!arr) {
40
- return;
41
- }
42
- arr.forEach((edge) => {
43
- if (edge.length === 1) {
44
- this.addNode(edge[0]);
45
- } else {
46
- this.addEdge(edge[0], edge[1]);
47
- }
48
- });
49
- }
50
- clone() {
51
- const result = new _Graph();
52
- this.nodes.forEach((node) => result.nodes.set(node.id, node.clone()));
53
- return result;
54
- }
55
- at(target) {
56
- return this.nodes.get(target);
57
- }
58
- addNode(target) {
59
- let node = this.nodes.get(target);
60
- if (!node) {
61
- node = new GraphNode(target);
62
- this.nodes.set(target, node);
63
- }
64
- return node;
65
- }
66
- hasNode(target) {
67
- return !!this.nodes.get(target);
68
- }
69
- removeNode(target) {
70
- this.nodes.forEach((node) => {
71
- node.removeInput(target);
72
- node.removeOutput(target);
73
- });
74
- this.nodes.delete(target);
75
- }
76
- foldNode(target) {
77
- const nodeToRemove = this.nodes.get(target);
78
- if (!nodeToRemove) {
79
- return;
80
- }
81
- nodeToRemove.inputs.forEach((input) => {
82
- nodeToRemove.outputs.forEach((output) => {
83
- this.addEdge(input, output);
84
- });
85
- });
86
- this.removeNode(target);
87
- }
88
- removeIsolated() {
89
- const result = [];
90
- this.nodes.forEach((node) => {
91
- if (node.outputs.length === 0 && node.inputs.length === 0) {
92
- result.push(node);
93
- this.nodes.delete(node.id);
94
- }
95
- });
96
- return result;
97
- }
98
- addEdge(source, destination) {
99
- if (this.hasEdge(source, destination)) {
100
- return;
101
- }
102
- const sourceNode = this.addNode(source);
103
- const destinationNode = this.addNode(destination);
104
- sourceNode.addOutput(destinationNode.id);
105
- destinationNode.addInput(sourceNode.id);
106
- }
107
- removeEdge(source, destination) {
108
- const sourceNode = this.nodes.get(source);
109
- const destinationNode = this.nodes.get(destination);
110
- if (sourceNode && destinationNode) {
111
- sourceNode.removeOutput(destination);
112
- destinationNode.removeInput(source);
113
- }
114
- }
115
- hasEdge(source, destination) {
116
- const sourceNode = this.nodes.get(source);
117
- if (!sourceNode) {
118
- return false;
119
- }
120
- return !!sourceNode.outputs.find((id) => id === destination);
121
- }
122
- isReachable(source, destination) {
123
- return this.expandAllOutputs([source]).includes(destination);
124
- }
125
- rootNodes() {
126
- return [...this.nodes.keys()].filter((id) => !this.nodes.get(id)?.inputs.length);
127
- }
128
- expandOutputs(origin) {
129
- const result = [];
130
- origin.forEach((id) => {
131
- const node = this.nodes.get(id);
132
- if (node) {
133
- node.outputs.forEach((child) => {
134
- if (!origin.includes(child) && !result.includes(child)) {
135
- result.push(child);
136
- }
137
- });
138
- }
139
- });
140
- return result;
141
- }
142
- expandInputs(origin) {
143
- const result = [];
144
- origin.forEach((id) => {
145
- const node = this.nodes.get(id);
146
- if (node) {
147
- node.inputs.forEach((child) => {
148
- if (!origin.includes(child) && !result.includes(child)) {
149
- result.push(child);
150
- }
151
- });
152
- }
153
- });
154
- return result;
155
- }
156
- expandAllOutputs(origin) {
157
- const result = this.expandOutputs(origin);
158
- if (result.length === 0) {
159
- return [];
160
- }
161
- const marked = /* @__PURE__ */ new Map();
162
- origin.forEach((id) => marked.set(id, true));
163
- let position = 0;
164
- while (position < result.length) {
165
- const node = this.nodes.get(result[position]);
166
- if (node && !marked.get(node.id)) {
167
- marked.set(node.id, true);
168
- node.outputs.forEach((child) => {
169
- if (!marked.get(child) && !result.find((id) => id === child)) {
170
- result.push(child);
171
- }
172
- });
173
- }
174
- position += 1;
175
- }
176
- return result;
177
- }
178
- expandAllInputs(origin) {
179
- const result = this.expandInputs(origin);
180
- if (result.length === 0) {
181
- return [];
182
- }
183
- const marked = /* @__PURE__ */ new Map();
184
- origin.forEach((id) => marked.set(id, true));
185
- let position = 0;
186
- while (position < result.length) {
187
- const node = this.nodes.get(result[position]);
188
- if (node && !marked.get(node.id)) {
189
- marked.set(node.id, true);
190
- node.inputs.forEach((child) => {
191
- if (!marked.get(child) && !result.find((id) => id === child)) {
192
- result.push(child);
193
- }
194
- });
195
- }
196
- position += 1;
197
- }
198
- return result;
199
- }
200
- maximizePart(origin) {
201
- const outputs = this.expandAllOutputs(origin);
202
- const result = [...origin];
203
- this.topologicalOrder().filter((id) => outputs.includes(id)).forEach((id) => {
204
- const node = this.nodes.get(id);
205
- if (node?.inputs.every((parent) => result.includes(parent))) {
206
- result.push(id);
207
- }
208
- });
209
- return result;
210
- }
211
- topologicalOrder() {
212
- const result = [];
213
- const marked = /* @__PURE__ */ new Set();
214
- const nodeStack = [];
215
- this.nodes.forEach((node) => {
216
- if (marked.has(node.id)) {
217
- return;
218
- }
219
- nodeStack.push(node.id);
220
- while (nodeStack.length > 0) {
221
- const item = nodeStack[nodeStack.length - 1];
222
- if (marked.has(item)) {
223
- if (!result.find((id) => id === item)) {
224
- result.push(item);
225
- }
226
- nodeStack.pop();
227
- } else {
228
- marked.add(item);
229
- const itemNode = this.nodes.get(item);
230
- if (itemNode && itemNode.outputs.length > 0) {
231
- itemNode.outputs.forEach((child) => {
232
- if (!marked.has(child)) {
233
- nodeStack.push(child);
234
- }
235
- });
236
- }
237
- }
238
- }
239
- });
240
- return result.reverse();
241
- }
242
- /**
243
- * Stably reorders the given node ids so that, for this DAG, no node appears before a transitive
244
- * successor (edges: source dependent; {@link GraphNode.outputs} lists dependents).
245
- */
246
- sortStable(target) {
247
- if (target.length <= 1) {
248
- return [...target];
249
- }
250
- const reachable = this.buildTransitiveClosureForSort();
251
- const testSet = /* @__PURE__ */ new Set();
252
- const result = [];
253
- for (const nodeId of [...target].reverse()) {
254
- const nodeReachable = reachable.get(nodeId) ?? /* @__PURE__ */ new Set();
255
- const needMove = testSet.has(nodeId);
256
- for (const childId of nodeReachable) {
257
- testSet.add(childId);
258
- }
259
- if (!needMove) {
260
- result.push(nodeId);
261
- continue;
262
- }
263
- let inserted = false;
264
- for (let index = 0; index < result.length; index++) {
265
- const parent = result[index];
266
- const parentReachable = reachable.get(parent) ?? /* @__PURE__ */ new Set();
267
- if (nodeReachable.has(parent)) {
268
- if (parentReachable.has(nodeId)) {
269
- result.push(nodeId);
270
- } else {
271
- result.splice(index, 0, nodeId);
272
- }
273
- inserted = true;
274
- break;
275
- }
276
- }
277
- if (!inserted) {
278
- result.push(nodeId);
279
- }
280
- }
281
- result.reverse();
282
- return result;
283
- }
284
- buildTransitiveClosureForSort() {
285
- const closure = /* @__PURE__ */ new Map();
286
- for (const node of this.nodes.values()) {
287
- closure.set(node.id, new Set(node.outputs));
288
- }
289
- const order = this.topologicalOrder();
290
- for (const nodeId of [...order].reverse()) {
291
- const node = this.at(nodeId);
292
- if (!node) {
293
- continue;
294
- }
295
- const nodeClosure = closure.get(nodeId) ?? /* @__PURE__ */ new Set();
296
- for (const parentId of node.inputs) {
297
- const parentClosure = closure.get(parentId) ?? /* @__PURE__ */ new Set();
298
- for (const childId of nodeClosure) {
299
- parentClosure.add(childId);
300
- }
301
- closure.set(parentId, parentClosure);
302
- }
303
- }
304
- return closure;
305
- }
306
- transitiveReduction() {
307
- const order = this.topologicalOrder();
308
- const marked = /* @__PURE__ */ new Map();
309
- order.forEach((nodeID) => {
310
- if (marked.get(nodeID)) {
311
- return;
312
- }
313
- const stack = [];
314
- stack.push({ id: nodeID, parents: [] });
315
- while (stack.length > 0) {
316
- const item = stack.splice(0, 1)[0];
317
- const node = this.nodes.get(item.id);
318
- if (node) {
319
- node.outputs.forEach((child) => {
320
- item.parents.forEach((parent) => this.removeEdge(parent, child));
321
- stack.push({ id: child, parents: [item.id, ...item.parents] });
322
- });
323
- }
324
- marked.set(item.id, true);
325
- }
326
- });
327
- }
328
- /**
329
- * Finds a cycle in the graph.
330
- *
331
- * @returns {NodeID[] | null} The cycle if found, otherwise `null`.
332
- * Uses non-recursive DFS.
333
- */
334
- findCycle() {
335
- const visited = /* @__PURE__ */ new Set();
336
- const nodeStack = /* @__PURE__ */ new Set();
337
- const parents = /* @__PURE__ */ new Map();
338
- for (const nodeId of this.nodes.keys()) {
339
- if (visited.has(nodeId)) {
340
- continue;
341
- }
342
- const callStack = [];
343
- callStack.push({ nodeId, parentId: null });
344
- while (callStack.length > 0) {
345
- const { nodeId: nodeId2, parentId } = callStack[callStack.length - 1];
346
- if (visited.has(nodeId2)) {
347
- nodeStack.delete(nodeId2);
348
- callStack.pop();
349
- continue;
350
- }
351
- visited.add(nodeId2);
352
- nodeStack.add(nodeId2);
353
- if (parentId !== null) {
354
- parents.set(nodeId2, parentId);
355
- }
356
- const currentNode = this.nodes.get(nodeId2);
357
- for (const child of currentNode.outputs) {
358
- if (!visited.has(child)) {
359
- callStack.push({ nodeId: child, parentId: nodeId2 });
360
- continue;
361
- }
362
- if (!nodeStack.has(child)) {
363
- continue;
364
- }
365
- const cycle = [];
366
- let current = nodeId2;
367
- cycle.push(child);
368
- while (current !== child) {
369
- cycle.push(current);
370
- current = parents.get(current);
371
- }
372
- cycle.push(child);
373
- cycle.reverse();
374
- return cycle;
375
- }
376
- }
377
- }
378
- return null;
379
- }
380
- };
381
- export {
382
- Graph,
383
- GraphNode
39
+ /**
40
+ * Represents a Graph.
41
+ *
42
+ * This class is optimized for TermGraph use case and not supposed to be used as generic graph implementation.
43
+ */
44
+ var Graph = class Graph {
45
+ /** Map of nodes. */
46
+ nodes = /* @__PURE__ */ new Map();
47
+ constructor(arr) {
48
+ if (!arr) return;
49
+ arr.forEach((edge) => {
50
+ if (edge.length === 1) this.addNode(edge[0]);
51
+ else this.addEdge(edge[0], edge[1]);
52
+ });
53
+ }
54
+ clone() {
55
+ const result = new Graph();
56
+ this.nodes.forEach((node) => result.nodes.set(node.id, node.clone()));
57
+ return result;
58
+ }
59
+ at(target) {
60
+ return this.nodes.get(target);
61
+ }
62
+ addNode(target) {
63
+ let node = this.nodes.get(target);
64
+ if (!node) {
65
+ node = new GraphNode(target);
66
+ this.nodes.set(target, node);
67
+ }
68
+ return node;
69
+ }
70
+ hasNode(target) {
71
+ return !!this.nodes.get(target);
72
+ }
73
+ removeNode(target) {
74
+ this.nodes.forEach((node) => {
75
+ node.removeInput(target);
76
+ node.removeOutput(target);
77
+ });
78
+ this.nodes.delete(target);
79
+ }
80
+ foldNode(target) {
81
+ const nodeToRemove = this.nodes.get(target);
82
+ if (!nodeToRemove) return;
83
+ nodeToRemove.inputs.forEach((input) => {
84
+ nodeToRemove.outputs.forEach((output) => {
85
+ this.addEdge(input, output);
86
+ });
87
+ });
88
+ this.removeNode(target);
89
+ }
90
+ removeIsolated() {
91
+ const result = [];
92
+ this.nodes.forEach((node) => {
93
+ if (node.outputs.length === 0 && node.inputs.length === 0) {
94
+ result.push(node);
95
+ this.nodes.delete(node.id);
96
+ }
97
+ });
98
+ return result;
99
+ }
100
+ addEdge(source, destination) {
101
+ if (this.hasEdge(source, destination)) return;
102
+ const sourceNode = this.addNode(source);
103
+ const destinationNode = this.addNode(destination);
104
+ sourceNode.addOutput(destinationNode.id);
105
+ destinationNode.addInput(sourceNode.id);
106
+ }
107
+ removeEdge(source, destination) {
108
+ const sourceNode = this.nodes.get(source);
109
+ const destinationNode = this.nodes.get(destination);
110
+ if (sourceNode && destinationNode) {
111
+ sourceNode.removeOutput(destination);
112
+ destinationNode.removeInput(source);
113
+ }
114
+ }
115
+ hasEdge(source, destination) {
116
+ const sourceNode = this.nodes.get(source);
117
+ if (!sourceNode) return false;
118
+ return !!sourceNode.outputs.find((id) => id === destination);
119
+ }
120
+ isReachable(source, destination) {
121
+ return this.expandAllOutputs([source]).includes(destination);
122
+ }
123
+ rootNodes() {
124
+ return [...this.nodes.keys()].filter((id) => !this.nodes.get(id)?.inputs.length);
125
+ }
126
+ expandOutputs(origin) {
127
+ const result = [];
128
+ origin.forEach((id) => {
129
+ const node = this.nodes.get(id);
130
+ if (node) node.outputs.forEach((child) => {
131
+ if (!origin.includes(child) && !result.includes(child)) result.push(child);
132
+ });
133
+ });
134
+ return result;
135
+ }
136
+ expandInputs(origin) {
137
+ const result = [];
138
+ origin.forEach((id) => {
139
+ const node = this.nodes.get(id);
140
+ if (node) node.inputs.forEach((child) => {
141
+ if (!origin.includes(child) && !result.includes(child)) result.push(child);
142
+ });
143
+ });
144
+ return result;
145
+ }
146
+ expandAllOutputs(origin) {
147
+ const result = this.expandOutputs(origin);
148
+ if (result.length === 0) return [];
149
+ const marked = /* @__PURE__ */ new Map();
150
+ origin.forEach((id) => marked.set(id, true));
151
+ let position = 0;
152
+ while (position < result.length) {
153
+ const node = this.nodes.get(result[position]);
154
+ if (node && !marked.get(node.id)) {
155
+ marked.set(node.id, true);
156
+ node.outputs.forEach((child) => {
157
+ if (!marked.get(child) && !result.find((id) => id === child)) result.push(child);
158
+ });
159
+ }
160
+ position += 1;
161
+ }
162
+ return result;
163
+ }
164
+ expandAllInputs(origin) {
165
+ const result = this.expandInputs(origin);
166
+ if (result.length === 0) return [];
167
+ const marked = /* @__PURE__ */ new Map();
168
+ origin.forEach((id) => marked.set(id, true));
169
+ let position = 0;
170
+ while (position < result.length) {
171
+ const node = this.nodes.get(result[position]);
172
+ if (node && !marked.get(node.id)) {
173
+ marked.set(node.id, true);
174
+ node.inputs.forEach((child) => {
175
+ if (!marked.get(child) && !result.find((id) => id === child)) result.push(child);
176
+ });
177
+ }
178
+ position += 1;
179
+ }
180
+ return result;
181
+ }
182
+ maximizePart(origin) {
183
+ const outputs = this.expandAllOutputs(origin);
184
+ const result = [...origin];
185
+ this.topologicalOrder().filter((id) => outputs.includes(id)).forEach((id) => {
186
+ if (this.nodes.get(id)?.inputs.every((parent) => result.includes(parent))) result.push(id);
187
+ });
188
+ return result;
189
+ }
190
+ topologicalOrder() {
191
+ const result = [];
192
+ const marked = /* @__PURE__ */ new Set();
193
+ const nodeStack = [];
194
+ this.nodes.forEach((node) => {
195
+ if (marked.has(node.id)) return;
196
+ nodeStack.push(node.id);
197
+ while (nodeStack.length > 0) {
198
+ const item = nodeStack[nodeStack.length - 1];
199
+ if (marked.has(item)) {
200
+ if (!result.find((id) => id === item)) result.push(item);
201
+ nodeStack.pop();
202
+ } else {
203
+ marked.add(item);
204
+ const itemNode = this.nodes.get(item);
205
+ if (itemNode && itemNode.outputs.length > 0) itemNode.outputs.forEach((child) => {
206
+ if (!marked.has(child)) nodeStack.push(child);
207
+ });
208
+ }
209
+ }
210
+ });
211
+ return result.reverse();
212
+ }
213
+ /**
214
+ * Stably reorders the given node ids so that, for this DAG, no node appears before a transitive
215
+ * successor (edges: source → dependent; {@link GraphNode.outputs} lists dependents).
216
+ */
217
+ sortStable(target) {
218
+ if (target.length <= 1) return [...target];
219
+ const reachable = this.buildTransitiveClosureForSort();
220
+ const testSet = /* @__PURE__ */ new Set();
221
+ const result = [];
222
+ for (const nodeId of [...target].reverse()) {
223
+ const nodeReachable = reachable.get(nodeId) ?? /* @__PURE__ */ new Set();
224
+ const needMove = testSet.has(nodeId);
225
+ for (const childId of nodeReachable) testSet.add(childId);
226
+ if (!needMove) {
227
+ result.push(nodeId);
228
+ continue;
229
+ }
230
+ let inserted = false;
231
+ for (let index = 0; index < result.length; index++) {
232
+ const parent = result[index];
233
+ const parentReachable = reachable.get(parent) ?? /* @__PURE__ */ new Set();
234
+ if (nodeReachable.has(parent)) {
235
+ if (parentReachable.has(nodeId)) result.push(nodeId);
236
+ else result.splice(index, 0, nodeId);
237
+ inserted = true;
238
+ break;
239
+ }
240
+ }
241
+ if (!inserted) result.push(nodeId);
242
+ }
243
+ result.reverse();
244
+ return result;
245
+ }
246
+ buildTransitiveClosureForSort() {
247
+ const closure = /* @__PURE__ */ new Map();
248
+ for (const node of this.nodes.values()) closure.set(node.id, new Set(node.outputs));
249
+ const order = this.topologicalOrder();
250
+ for (const nodeId of [...order].reverse()) {
251
+ const node = this.at(nodeId);
252
+ if (!node) continue;
253
+ const nodeClosure = closure.get(nodeId) ?? /* @__PURE__ */ new Set();
254
+ for (const parentId of node.inputs) {
255
+ const parentClosure = closure.get(parentId) ?? /* @__PURE__ */ new Set();
256
+ for (const childId of nodeClosure) parentClosure.add(childId);
257
+ closure.set(parentId, parentClosure);
258
+ }
259
+ }
260
+ return closure;
261
+ }
262
+ transitiveReduction() {
263
+ const order = this.topologicalOrder();
264
+ const marked = /* @__PURE__ */ new Map();
265
+ order.forEach((nodeID) => {
266
+ if (marked.get(nodeID)) return;
267
+ const stack = [];
268
+ stack.push({
269
+ id: nodeID,
270
+ parents: []
271
+ });
272
+ while (stack.length > 0) {
273
+ const item = stack.splice(0, 1)[0];
274
+ const node = this.nodes.get(item.id);
275
+ if (node) node.outputs.forEach((child) => {
276
+ item.parents.forEach((parent) => this.removeEdge(parent, child));
277
+ stack.push({
278
+ id: child,
279
+ parents: [item.id, ...item.parents]
280
+ });
281
+ });
282
+ marked.set(item.id, true);
283
+ }
284
+ });
285
+ }
286
+ /**
287
+ * Finds a cycle in the graph.
288
+ *
289
+ * @returns {NodeID[] | null} The cycle if found, otherwise `null`.
290
+ * Uses non-recursive DFS.
291
+ */
292
+ findCycle() {
293
+ const visited = /* @__PURE__ */ new Set();
294
+ const nodeStack = /* @__PURE__ */ new Set();
295
+ const parents = /* @__PURE__ */ new Map();
296
+ for (const nodeId of this.nodes.keys()) {
297
+ if (visited.has(nodeId)) continue;
298
+ const callStack = [];
299
+ callStack.push({
300
+ nodeId,
301
+ parentId: null
302
+ });
303
+ while (callStack.length > 0) {
304
+ const { nodeId, parentId } = callStack[callStack.length - 1];
305
+ if (visited.has(nodeId)) {
306
+ nodeStack.delete(nodeId);
307
+ callStack.pop();
308
+ continue;
309
+ }
310
+ visited.add(nodeId);
311
+ nodeStack.add(nodeId);
312
+ if (parentId !== null) parents.set(nodeId, parentId);
313
+ const currentNode = this.nodes.get(nodeId);
314
+ for (const child of currentNode.outputs) {
315
+ if (!visited.has(child)) {
316
+ callStack.push({
317
+ nodeId: child,
318
+ parentId: nodeId
319
+ });
320
+ continue;
321
+ }
322
+ if (!nodeStack.has(child)) continue;
323
+ const cycle = [];
324
+ let current = nodeId;
325
+ cycle.push(child);
326
+ while (current !== child) {
327
+ cycle.push(current);
328
+ current = parents.get(current);
329
+ }
330
+ cycle.push(child);
331
+ cycle.reverse();
332
+ return cycle;
333
+ }
334
+ }
335
+ }
336
+ return null;
337
+ }
384
338
  };
339
+ //#endregion
340
+ export { Graph, GraphNode };
341
+
385
342
  //# sourceMappingURL=graph.js.map