@rsconcept/domain 1.0.0 → 1.1.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 (183) 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 +257 -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/rsform-api.test.ts +24 -0
  172. package/src/library/rsform-api.ts +12 -4
  173. package/dist/cctext/index.js.map +0 -1
  174. package/dist/graph/index.js.map +0 -1
  175. package/dist/index.js.map +0 -1
  176. package/dist/library/index.js.map +0 -1
  177. package/dist/library/oss-layout.js.map +0 -1
  178. package/dist/parsing/index.js.map +0 -1
  179. package/dist/rslang/eval/value-api.js.map +0 -1
  180. package/dist/rslang/eval/value.js.map +0 -1
  181. package/dist/rslang/index.js.map +0 -1
  182. package/dist/shared/branded.js.map +0 -1
  183. package/dist/shared/index.js.map +0 -1
@@ -1,330 +1,253 @@
1
- // src/library/oss.ts
2
- var NodeType = {
3
- OPERATION: 1,
4
- BLOCK: 2
5
- };
6
- var OperationType = {
7
- INPUT: "input",
8
- SYNTHESIS: "synthesis",
9
- REPLICA: "replica"
10
- };
11
-
12
- // src/library/oss-layout-api.ts
13
- var GRID_SIZE = 10;
14
- var MIN_DISTANCE = 2 * GRID_SIZE;
15
- var OPERATION_NODE_WIDTH = 150;
16
- var OPERATION_NODE_HEIGHT = 40;
1
+ import { NodeType, OperationType } from "./oss.js";
2
+ //#region src/library/oss-layout-api.ts
3
+ const GRID_SIZE = 10;
4
+ const MIN_DISTANCE = 20;
5
+ const OPERATION_NODE_WIDTH = 150;
6
+ const OPERATION_NODE_HEIGHT = 40;
7
+ /** Layout manipulations for {@link OperationSchema}. */
17
8
  var LayoutManager = class {
18
- oss;
19
- layout;
20
- constructor(oss, layout) {
21
- this.oss = oss;
22
- if (layout) {
23
- this.layout = layout;
24
- } else {
25
- this.layout = this.oss.layout;
26
- }
27
- }
28
- /** Calculate insert position for a new {@link Operation} */
29
- newOperationPosition(position, parent, args = []) {
30
- const result = { ...position };
31
- const parentNode = this.layout.find((pos) => pos.nodeID === `b${parent}`) ?? null;
32
- const operations = this.layout.filter((pos) => pos.nodeID.startsWith("o"));
33
- const hasArguments = args.length !== 0;
34
- if (hasArguments) {
35
- const pos = calculatePositionFromArgs(operations.filter((node) => args.includes(Number(node.nodeID.slice(1)))));
36
- result.x = pos.x;
37
- result.y = pos.y;
38
- } else if (parentNode) {
39
- result.x = parentNode.x + MIN_DISTANCE;
40
- result.y = parentNode.y + MIN_DISTANCE;
41
- } else {
42
- const pos = this.calculatePositionForFreeOperation(result);
43
- result.x = pos.x;
44
- result.y = pos.y;
45
- }
46
- const siblingBlocks = this.oss.blocks.filter((block) => block.parent === parent).map((block) => block.nodeID);
47
- preventOverlap(
48
- result,
49
- this.layout.filter((node) => siblingBlocks.includes(node.nodeID)),
50
- {
51
- moveX: !hasArguments,
52
- moveY: hasArguments
53
- }
54
- );
55
- preventOverlap(result, operations);
56
- this.extendParentBounds(parentNode, result);
57
- return result;
58
- }
59
- /** Calculate insert position for a new {@link Block} */
60
- newBlockPosition(position, parent, blocks, operations) {
61
- const blockNodes = blocks.map((id) => this.layout.find((block) => block.nodeID === `b${id}`)).filter((node) => !!node);
62
- const operationNodes = operations.map((id) => this.layout.find((operation) => operation.nodeID === `o${id}`)).filter((node) => !!node);
63
- const parentNode = this.layout.find((pos) => pos.nodeID === `b${parent}`) ?? null;
64
- const parentID = parentNode ? parent : null;
65
- let result = { ...position };
66
- if (blockNodes.length !== 0 || operationNodes.length !== 0) {
67
- result = calculatePositionFromChildren(position, operationNodes, blockNodes);
68
- } else if (parentNode) {
69
- result = {
70
- x: parentNode.x + MIN_DISTANCE,
71
- y: parentNode.y + MIN_DISTANCE,
72
- width: position.width,
73
- height: position.height
74
- };
75
- } else {
76
- result = this.calculatePositionForFreeBlock(result);
77
- }
78
- if (blockNodes.length === 0 && operationNodes.length === 0) {
79
- const siblings = this.oss.blocks.filter((block) => block.parent === parentID).map((block) => block.nodeID);
80
- preventOverlap(
81
- result,
82
- this.layout.filter((node) => siblings.includes(node.nodeID))
83
- );
84
- }
85
- this.extendParentBounds(parentNode, result);
86
- return result;
87
- }
88
- /** Calculate insert position for a new clone of {@link Operation} */
89
- newClonePosition(targetID) {
90
- const targetNode = this.layout.find((pos) => pos.nodeID === targetID);
91
- if (!targetNode) {
92
- return null;
93
- } else {
94
- return {
95
- x: targetNode.x + targetNode.width / 2 + GRID_SIZE,
96
- y: targetNode.y + targetNode.height / 2 + GRID_SIZE,
97
- width: OPERATION_NODE_WIDTH,
98
- height: OPERATION_NODE_HEIGHT
99
- };
100
- }
101
- }
102
- /** Update layout when parent changes */
103
- onChangeParent(targetID, newParent) {
104
- const targetNode = this.layout.find((pos) => pos.nodeID === targetID);
105
- if (!targetNode) {
106
- return;
107
- }
108
- const parentNode = this.layout.find((pos) => pos.nodeID === newParent) ?? null;
109
- const offset = this.calculateOffsetForParentChange(targetNode, parentNode);
110
- if (offset.x === 0 && offset.y === 0) {
111
- return;
112
- }
113
- targetNode.x += offset.x;
114
- targetNode.y += offset.y;
115
- const children = this.oss.hierarchy.expandAllOutputs([targetID]);
116
- const childrenPositions = this.layout.filter((pos) => children.includes(pos.nodeID));
117
- for (const child of childrenPositions) {
118
- child.x += offset.x;
119
- child.y += offset.y;
120
- }
121
- this.extendParentBounds(parentNode, targetNode);
122
- }
123
- /** Calculate closest node to the left */
124
- selectLeft(targetID) {
125
- const targetNode = this.layout.find((pos) => pos.nodeID === targetID);
126
- if (!targetNode) {
127
- return null;
128
- }
129
- const operationNodes = this.layout.filter((pos) => pos.nodeID !== targetID && pos.nodeID.startsWith("o"));
130
- const leftNodes = operationNodes.filter((pos) => pos.x <= targetNode.x);
131
- if (leftNodes.length === 0) {
132
- return null;
133
- }
134
- const similarYNodes = leftNodes.filter((pos) => Math.abs(pos.y - targetNode.y) <= MIN_DISTANCE);
135
- let closestNode = null;
136
- if (similarYNodes.length > 0) {
137
- closestNode = similarYNodes.reduce((prev, curr) => curr.x > prev.x ? curr : prev);
138
- } else {
139
- closestNode = findClosestNodeByDistance(leftNodes, targetNode);
140
- }
141
- return closestNode?.nodeID ?? null;
142
- }
143
- /** Calculate closest node to the right */
144
- selectRight(targetID) {
145
- const targetNode = this.layout.find((pos) => pos.nodeID === targetID);
146
- if (!targetNode) {
147
- return null;
148
- }
149
- const operationNodes = this.layout.filter((pos) => pos.nodeID !== targetID && pos.nodeID.startsWith("o"));
150
- const rightNodes = operationNodes.filter((pos) => pos.x >= targetNode.x);
151
- if (rightNodes.length === 0) {
152
- return null;
153
- }
154
- const similarYNodes = rightNodes.filter((pos) => Math.abs(pos.y - targetNode.y) <= MIN_DISTANCE);
155
- let closestNode = null;
156
- if (similarYNodes.length > 0) {
157
- closestNode = similarYNodes.reduce((prev, curr) => curr.x < prev.x ? curr : prev);
158
- } else {
159
- closestNode = findClosestNodeByDistance(rightNodes, targetNode);
160
- }
161
- return closestNode?.nodeID ?? null;
162
- }
163
- /** Calculate closest node upwards */
164
- selectUp(targetID) {
165
- const targetNode = this.layout.find((pos) => pos.nodeID === targetID);
166
- if (!targetNode) {
167
- return null;
168
- }
169
- const operationNodes = this.layout.filter((pos) => pos.nodeID !== targetID && pos.nodeID.startsWith("o"));
170
- const upperNodes = operationNodes.filter((pos) => pos.y <= targetNode.y - MIN_DISTANCE);
171
- const targetOperation = this.oss.itemByNodeID.get(targetID);
172
- if (upperNodes.length === 0 || !targetOperation || targetOperation.nodeType === NodeType.BLOCK) {
173
- return null;
174
- }
175
- const predecessors = this.oss.graph.expandAllInputs([targetOperation.id]);
176
- const predecessorNodes = upperNodes.filter((pos) => predecessors.includes(Number(pos.nodeID.slice(1))));
177
- let closestNode = null;
178
- if (predecessorNodes.length > 0) {
179
- closestNode = findClosestNodeByDistance(predecessorNodes, targetNode);
180
- } else {
181
- closestNode = findClosestNodeByDistance(upperNodes, targetNode);
182
- }
183
- return closestNode?.nodeID ?? null;
184
- }
185
- /** Calculate closest node downwards */
186
- selectDown(targetID) {
187
- const targetNode = this.layout.find((pos) => pos.nodeID === targetID);
188
- if (!targetNode) {
189
- return null;
190
- }
191
- const operationNodes = this.layout.filter((pos) => pos.nodeID !== targetID && pos.nodeID.startsWith("o"));
192
- const lowerNodes = operationNodes.filter((pos) => pos.y >= targetNode.y - MIN_DISTANCE);
193
- const targetOperation = this.oss.itemByNodeID.get(targetID);
194
- if (lowerNodes.length === 0 || !targetOperation || targetOperation.nodeType === NodeType.BLOCK) {
195
- return null;
196
- }
197
- const descendants = this.oss.graph.expandAllOutputs([targetOperation.id]);
198
- const descendantsNodes = lowerNodes.filter((pos) => descendants.includes(Number(pos.nodeID.slice(1))));
199
- let closestNode = null;
200
- if (descendantsNodes.length > 0) {
201
- closestNode = findClosestNodeByDistance(descendantsNodes, targetNode);
202
- } else {
203
- closestNode = findClosestNodeByDistance(lowerNodes, targetNode);
204
- }
205
- return closestNode?.nodeID ?? null;
206
- }
207
- extendParentBounds(parent, child) {
208
- if (!parent) {
209
- return;
210
- }
211
- const borderX = child.x + child.width + MIN_DISTANCE;
212
- const borderY = child.y + child.height + MIN_DISTANCE;
213
- parent.width = Math.max(parent.width, borderX - parent.x);
214
- parent.height = Math.max(parent.height, borderY - parent.y);
215
- }
216
- calculatePositionForFreeOperation(initial) {
217
- if (this.oss.operations.length === 0) {
218
- return initial;
219
- }
220
- const freeInputs = this.oss.operations.filter(
221
- (operation) => operation.parent === null && (operation.operation_type !== OperationType.SYNTHESIS || operation.arguments.length === 0)
222
- ).map((operation) => operation.nodeID);
223
- let inputsPositions = this.layout.filter((pos) => freeInputs.includes(pos.nodeID));
224
- if (inputsPositions.length === 0) {
225
- inputsPositions = this.layout.filter((pos) => pos.nodeID.startsWith("o"));
226
- }
227
- const maxX = Math.max(...inputsPositions.map((node) => node.x));
228
- const minY = Math.min(...inputsPositions.map((node) => node.y));
229
- return {
230
- x: maxX + OPERATION_NODE_WIDTH + MIN_DISTANCE + GRID_SIZE,
231
- y: minY
232
- };
233
- }
234
- calculatePositionForFreeBlock(initial) {
235
- const rootBlocks = this.oss.blocks.filter((block) => block.parent === null).map((block) => block.nodeID);
236
- const blocksPositions = this.layout.filter((pos) => rootBlocks.includes(pos.nodeID));
237
- if (blocksPositions.length === 0) {
238
- return initial;
239
- }
240
- const maxX = Math.max(...blocksPositions.map((node) => node.x + node.width));
241
- const minY = Math.min(...blocksPositions.map((node) => node.y));
242
- return { ...initial, x: maxX + MIN_DISTANCE, y: minY };
243
- }
244
- calculateOffsetForParentChange(target, parent) {
245
- const newPosition = { ...target };
246
- if (parent === null) {
247
- const rootElements = this.oss.hierarchy.rootNodes();
248
- const positions = this.layout.filter((pos) => rootElements.includes(pos.nodeID));
249
- preventOverlap(newPosition, positions);
250
- } else if (!rectanglesStrictOverlap(target, parent)) {
251
- newPosition.x = parent.x + MIN_DISTANCE;
252
- newPosition.y = parent.y + MIN_DISTANCE;
253
- const siblings = this.oss.hierarchy.at(parent.nodeID)?.outputs ?? [];
254
- const siblingsPositions = this.layout.filter((pos) => siblings.includes(pos.nodeID));
255
- preventOverlap(newPosition, siblingsPositions);
256
- }
257
- return { x: newPosition.x - target.x, y: newPosition.y - target.y };
258
- }
9
+ oss;
10
+ layout;
11
+ constructor(oss, layout) {
12
+ this.oss = oss;
13
+ if (layout) this.layout = layout;
14
+ else this.layout = this.oss.layout;
15
+ }
16
+ /** Calculate insert position for a new {@link Operation} */
17
+ newOperationPosition(position, parent, args = []) {
18
+ const result = { ...position };
19
+ const parentNode = this.layout.find((pos) => pos.nodeID === `b${parent}`) ?? null;
20
+ const operations = this.layout.filter((pos) => pos.nodeID.startsWith("o"));
21
+ const hasArguments = args.length !== 0;
22
+ if (hasArguments) {
23
+ const pos = calculatePositionFromArgs(operations.filter((node) => args.includes(Number(node.nodeID.slice(1)))));
24
+ result.x = pos.x;
25
+ result.y = pos.y;
26
+ } else if (parentNode) {
27
+ result.x = parentNode.x + MIN_DISTANCE;
28
+ result.y = parentNode.y + MIN_DISTANCE;
29
+ } else {
30
+ const pos = this.calculatePositionForFreeOperation(result);
31
+ result.x = pos.x;
32
+ result.y = pos.y;
33
+ }
34
+ const siblingBlocks = this.oss.blocks.filter((block) => block.parent === parent).map((block) => block.nodeID);
35
+ preventOverlap(result, this.layout.filter((node) => siblingBlocks.includes(node.nodeID)), {
36
+ moveX: !hasArguments,
37
+ moveY: hasArguments
38
+ });
39
+ preventOverlap(result, operations);
40
+ this.extendParentBounds(parentNode, result);
41
+ return result;
42
+ }
43
+ /** Calculate insert position for a new {@link Block} */
44
+ newBlockPosition(position, parent, blocks, operations) {
45
+ const blockNodes = blocks.map((id) => this.layout.find((block) => block.nodeID === `b${id}`)).filter((node) => !!node);
46
+ const operationNodes = operations.map((id) => this.layout.find((operation) => operation.nodeID === `o${id}`)).filter((node) => !!node);
47
+ const parentNode = this.layout.find((pos) => pos.nodeID === `b${parent}`) ?? null;
48
+ const parentID = parentNode ? parent : null;
49
+ let result = { ...position };
50
+ if (blockNodes.length !== 0 || operationNodes.length !== 0) result = calculatePositionFromChildren(position, operationNodes, blockNodes);
51
+ else if (parentNode) result = {
52
+ x: parentNode.x + MIN_DISTANCE,
53
+ y: parentNode.y + MIN_DISTANCE,
54
+ width: position.width,
55
+ height: position.height
56
+ };
57
+ else result = this.calculatePositionForFreeBlock(result);
58
+ if (blockNodes.length === 0 && operationNodes.length === 0) {
59
+ const siblings = this.oss.blocks.filter((block) => block.parent === parentID).map((block) => block.nodeID);
60
+ preventOverlap(result, this.layout.filter((node) => siblings.includes(node.nodeID)));
61
+ }
62
+ this.extendParentBounds(parentNode, result);
63
+ return result;
64
+ }
65
+ /** Calculate insert position for a new clone of {@link Operation} */
66
+ newClonePosition(targetID) {
67
+ const targetNode = this.layout.find((pos) => pos.nodeID === targetID);
68
+ if (!targetNode) return null;
69
+ else return {
70
+ x: targetNode.x + targetNode.width / 2 + 10,
71
+ y: targetNode.y + targetNode.height / 2 + 10,
72
+ width: 150,
73
+ height: 40
74
+ };
75
+ }
76
+ /** Update layout when parent changes */
77
+ onChangeParent(targetID, newParent) {
78
+ const targetNode = this.layout.find((pos) => pos.nodeID === targetID);
79
+ if (!targetNode) return;
80
+ const parentNode = this.layout.find((pos) => pos.nodeID === newParent) ?? null;
81
+ const offset = this.calculateOffsetForParentChange(targetNode, parentNode);
82
+ if (offset.x === 0 && offset.y === 0) return;
83
+ targetNode.x += offset.x;
84
+ targetNode.y += offset.y;
85
+ const children = this.oss.hierarchy.expandAllOutputs([targetID]);
86
+ const childrenPositions = this.layout.filter((pos) => children.includes(pos.nodeID));
87
+ for (const child of childrenPositions) {
88
+ child.x += offset.x;
89
+ child.y += offset.y;
90
+ }
91
+ this.extendParentBounds(parentNode, targetNode);
92
+ }
93
+ /** Calculate closest node to the left */
94
+ selectLeft(targetID) {
95
+ const targetNode = this.layout.find((pos) => pos.nodeID === targetID);
96
+ if (!targetNode) return null;
97
+ const leftNodes = this.layout.filter((pos) => pos.nodeID !== targetID && pos.nodeID.startsWith("o")).filter((pos) => pos.x <= targetNode.x);
98
+ if (leftNodes.length === 0) return null;
99
+ const similarYNodes = leftNodes.filter((pos) => Math.abs(pos.y - targetNode.y) <= MIN_DISTANCE);
100
+ let closestNode = null;
101
+ if (similarYNodes.length > 0) closestNode = similarYNodes.reduce((prev, curr) => curr.x > prev.x ? curr : prev);
102
+ else closestNode = findClosestNodeByDistance(leftNodes, targetNode);
103
+ return closestNode?.nodeID ?? null;
104
+ }
105
+ /** Calculate closest node to the right */
106
+ selectRight(targetID) {
107
+ const targetNode = this.layout.find((pos) => pos.nodeID === targetID);
108
+ if (!targetNode) return null;
109
+ const rightNodes = this.layout.filter((pos) => pos.nodeID !== targetID && pos.nodeID.startsWith("o")).filter((pos) => pos.x >= targetNode.x);
110
+ if (rightNodes.length === 0) return null;
111
+ const similarYNodes = rightNodes.filter((pos) => Math.abs(pos.y - targetNode.y) <= MIN_DISTANCE);
112
+ let closestNode = null;
113
+ if (similarYNodes.length > 0) closestNode = similarYNodes.reduce((prev, curr) => curr.x < prev.x ? curr : prev);
114
+ else closestNode = findClosestNodeByDistance(rightNodes, targetNode);
115
+ return closestNode?.nodeID ?? null;
116
+ }
117
+ /** Calculate closest node upwards */
118
+ selectUp(targetID) {
119
+ const targetNode = this.layout.find((pos) => pos.nodeID === targetID);
120
+ if (!targetNode) return null;
121
+ const upperNodes = this.layout.filter((pos) => pos.nodeID !== targetID && pos.nodeID.startsWith("o")).filter((pos) => pos.y <= targetNode.y - MIN_DISTANCE);
122
+ const targetOperation = this.oss.itemByNodeID.get(targetID);
123
+ if (upperNodes.length === 0 || !targetOperation || targetOperation.nodeType === NodeType.BLOCK) return null;
124
+ const predecessors = this.oss.graph.expandAllInputs([targetOperation.id]);
125
+ const predecessorNodes = upperNodes.filter((pos) => predecessors.includes(Number(pos.nodeID.slice(1))));
126
+ let closestNode = null;
127
+ if (predecessorNodes.length > 0) closestNode = findClosestNodeByDistance(predecessorNodes, targetNode);
128
+ else closestNode = findClosestNodeByDistance(upperNodes, targetNode);
129
+ return closestNode?.nodeID ?? null;
130
+ }
131
+ /** Calculate closest node downwards */
132
+ selectDown(targetID) {
133
+ const targetNode = this.layout.find((pos) => pos.nodeID === targetID);
134
+ if (!targetNode) return null;
135
+ const lowerNodes = this.layout.filter((pos) => pos.nodeID !== targetID && pos.nodeID.startsWith("o")).filter((pos) => pos.y >= targetNode.y - MIN_DISTANCE);
136
+ const targetOperation = this.oss.itemByNodeID.get(targetID);
137
+ if (lowerNodes.length === 0 || !targetOperation || targetOperation.nodeType === NodeType.BLOCK) return null;
138
+ const descendants = this.oss.graph.expandAllOutputs([targetOperation.id]);
139
+ const descendantsNodes = lowerNodes.filter((pos) => descendants.includes(Number(pos.nodeID.slice(1))));
140
+ let closestNode = null;
141
+ if (descendantsNodes.length > 0) closestNode = findClosestNodeByDistance(descendantsNodes, targetNode);
142
+ else closestNode = findClosestNodeByDistance(lowerNodes, targetNode);
143
+ return closestNode?.nodeID ?? null;
144
+ }
145
+ extendParentBounds(parent, child) {
146
+ if (!parent) return;
147
+ const borderX = child.x + child.width + MIN_DISTANCE;
148
+ const borderY = child.y + child.height + MIN_DISTANCE;
149
+ parent.width = Math.max(parent.width, borderX - parent.x);
150
+ parent.height = Math.max(parent.height, borderY - parent.y);
151
+ }
152
+ calculatePositionForFreeOperation(initial) {
153
+ if (this.oss.operations.length === 0) return initial;
154
+ const freeInputs = this.oss.operations.filter((operation) => operation.parent === null && (operation.operation_type !== OperationType.SYNTHESIS || operation.arguments.length === 0)).map((operation) => operation.nodeID);
155
+ let inputsPositions = this.layout.filter((pos) => freeInputs.includes(pos.nodeID));
156
+ if (inputsPositions.length === 0) inputsPositions = this.layout.filter((pos) => pos.nodeID.startsWith("o"));
157
+ const maxX = Math.max(...inputsPositions.map((node) => node.x));
158
+ const minY = Math.min(...inputsPositions.map((node) => node.y));
159
+ return {
160
+ x: maxX + 150 + MIN_DISTANCE + 10,
161
+ y: minY
162
+ };
163
+ }
164
+ calculatePositionForFreeBlock(initial) {
165
+ const rootBlocks = this.oss.blocks.filter((block) => block.parent === null).map((block) => block.nodeID);
166
+ const blocksPositions = this.layout.filter((pos) => rootBlocks.includes(pos.nodeID));
167
+ if (blocksPositions.length === 0) return initial;
168
+ const maxX = Math.max(...blocksPositions.map((node) => node.x + node.width));
169
+ const minY = Math.min(...blocksPositions.map((node) => node.y));
170
+ return {
171
+ ...initial,
172
+ x: maxX + MIN_DISTANCE,
173
+ y: minY
174
+ };
175
+ }
176
+ calculateOffsetForParentChange(target, parent) {
177
+ const newPosition = { ...target };
178
+ if (parent === null) {
179
+ const rootElements = this.oss.hierarchy.rootNodes();
180
+ preventOverlap(newPosition, this.layout.filter((pos) => rootElements.includes(pos.nodeID)));
181
+ } else if (!rectanglesStrictOverlap(target, parent)) {
182
+ newPosition.x = parent.x + MIN_DISTANCE;
183
+ newPosition.y = parent.y + MIN_DISTANCE;
184
+ const siblings = this.oss.hierarchy.at(parent.nodeID)?.outputs ?? [];
185
+ preventOverlap(newPosition, this.layout.filter((pos) => siblings.includes(pos.nodeID)));
186
+ }
187
+ return {
188
+ x: newPosition.x - target.x,
189
+ y: newPosition.y - target.y
190
+ };
191
+ }
259
192
  };
260
193
  function rectanglesOverlap(a, b) {
261
- return !(a.x + a.width + MIN_DISTANCE <= b.x || b.x + b.width + MIN_DISTANCE <= a.x || a.y + a.height + MIN_DISTANCE <= b.y || b.y + b.height + MIN_DISTANCE <= a.y);
194
+ return !(a.x + a.width + MIN_DISTANCE <= b.x || b.x + b.width + MIN_DISTANCE <= a.x || a.y + a.height + MIN_DISTANCE <= b.y || b.y + b.height + MIN_DISTANCE <= a.y);
262
195
  }
263
196
  function rectanglesStrictOverlap(a, b) {
264
- return !(a.x + a.width <= b.x || b.x + b.width <= a.x || a.y + a.height <= b.y || b.y + b.height <= a.y);
197
+ return !(a.x + a.width <= b.x || b.x + b.width <= a.x || a.y + a.height <= b.y || b.y + b.height <= a.y);
265
198
  }
266
- function preventOverlap(target, fixedRectangles, options = { moveX: true, moveY: true }) {
267
- if (!options.moveX && !options.moveY || fixedRectangles.length === 0) {
268
- return;
269
- }
270
- let hasOverlap;
271
- do {
272
- hasOverlap = false;
273
- for (const fixed of fixedRectangles) {
274
- if (rectanglesOverlap(target, fixed)) {
275
- hasOverlap = true;
276
- if (options.moveX) {
277
- target.x += MIN_DISTANCE;
278
- }
279
- if (options.moveY) {
280
- target.y += MIN_DISTANCE;
281
- }
282
- break;
283
- }
284
- }
285
- } while (hasOverlap);
199
+ function preventOverlap(target, fixedRectangles, options = {
200
+ moveX: true,
201
+ moveY: true
202
+ }) {
203
+ if (!options.moveX && !options.moveY || fixedRectangles.length === 0) return;
204
+ let hasOverlap;
205
+ do {
206
+ hasOverlap = false;
207
+ for (const fixed of fixedRectangles) if (rectanglesOverlap(target, fixed)) {
208
+ hasOverlap = true;
209
+ if (options.moveX) target.x += MIN_DISTANCE;
210
+ if (options.moveY) target.y += MIN_DISTANCE;
211
+ break;
212
+ }
213
+ } while (hasOverlap);
286
214
  }
287
215
  function calculatePositionFromArgs(args) {
288
- const maxY = Math.max(...args.map((node) => node.y));
289
- const minX = Math.min(...args.map((node) => node.x));
290
- const maxX = Math.max(...args.map((node) => node.x));
291
- return {
292
- x: Math.ceil((maxX + minX) / 2 / GRID_SIZE) * GRID_SIZE,
293
- y: maxY + 2 * OPERATION_NODE_HEIGHT + MIN_DISTANCE
294
- };
216
+ const maxY = Math.max(...args.map((node) => node.y));
217
+ const minX = Math.min(...args.map((node) => node.x));
218
+ const maxX = Math.max(...args.map((node) => node.x));
219
+ return {
220
+ x: Math.ceil((maxX + minX) / 2 / 10) * 10,
221
+ y: maxY + 80 + MIN_DISTANCE
222
+ };
295
223
  }
296
224
  function calculatePositionFromChildren(initial, operations, blocks) {
297
- const allNodes = [...blocks, ...operations];
298
- if (allNodes.length === 0) {
299
- return initial;
300
- }
301
- const left = Math.min(...allNodes.map((n) => n.x)) - MIN_DISTANCE;
302
- const top = Math.min(...allNodes.map((n) => n.y)) - MIN_DISTANCE;
303
- const right = Math.max(...allNodes.map((n) => n.x + n.width)) + MIN_DISTANCE;
304
- const bottom = Math.max(...allNodes.map((n) => n.y + n.height)) + MIN_DISTANCE;
305
- return {
306
- x: left,
307
- y: top,
308
- width: right - left,
309
- height: bottom - top
310
- };
225
+ const allNodes = [...blocks, ...operations];
226
+ if (allNodes.length === 0) return initial;
227
+ const left = Math.min(...allNodes.map((n) => n.x)) - MIN_DISTANCE;
228
+ const top = Math.min(...allNodes.map((n) => n.y)) - MIN_DISTANCE;
229
+ const right = Math.max(...allNodes.map((n) => n.x + n.width)) + MIN_DISTANCE;
230
+ const bottom = Math.max(...allNodes.map((n) => n.y + n.height)) + MIN_DISTANCE;
231
+ return {
232
+ x: left,
233
+ y: top,
234
+ width: right - left,
235
+ height: bottom - top
236
+ };
311
237
  }
312
238
  function findClosestNodeByDistance(nodes, target) {
313
- let minDist = Infinity;
314
- let minNode = null;
315
- for (const curr of nodes) {
316
- const currDist = Math.hypot(curr.x - target.x, curr.y - target.y);
317
- if (currDist < minDist) {
318
- minDist = currDist;
319
- minNode = curr;
320
- }
321
- }
322
- return minNode;
239
+ let minDist = Infinity;
240
+ let minNode = null;
241
+ for (const curr of nodes) {
242
+ const currDist = Math.hypot(curr.x - target.x, curr.y - target.y);
243
+ if (currDist < minDist) {
244
+ minDist = currDist;
245
+ minNode = curr;
246
+ }
247
+ }
248
+ return minNode;
323
249
  }
324
- export {
325
- GRID_SIZE,
326
- LayoutManager,
327
- OPERATION_NODE_HEIGHT,
328
- OPERATION_NODE_WIDTH
329
- };
250
+ //#endregion
251
+ export { GRID_SIZE, LayoutManager, OPERATION_NODE_HEIGHT, OPERATION_NODE_WIDTH };
252
+
330
253
  //# sourceMappingURL=oss-layout-api.js.map