@xxrandr/conecta-diagram 0.0.0-stage → 0.1.4
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/LICENSE +21 -0
- package/README.md +319 -2
- package/dist/chunk-3QGSCPWL.cjs +663 -0
- package/dist/chunk-43VYPB4U.js +2136 -0
- package/dist/chunk-6ADTOXBT.cjs +626 -0
- package/dist/chunk-B2RLLFGC.js +0 -0
- package/dist/chunk-GXOBW2BK.js +290 -0
- package/dist/chunk-HZER5BPR.js +1122 -0
- package/dist/chunk-IT5H6WO2.js +626 -0
- package/dist/chunk-LKOWNTPR.cjs +1 -0
- package/dist/chunk-Q62JPMJH.js +663 -0
- package/dist/chunk-QI4NNFRQ.cjs +290 -0
- package/dist/chunk-VD32JNDO.cjs +2136 -0
- package/dist/chunk-ZMSQTBVW.cjs +1122 -0
- package/dist/core/index.cjs +56 -0
- package/dist/core/index.d.cts +65 -0
- package/dist/core/index.d.ts +65 -0
- package/dist/core/index.js +56 -0
- package/dist/d3/index.cjs +8 -0
- package/dist/d3/index.d.cts +46 -0
- package/dist/d3/index.d.ts +46 -0
- package/dist/d3/index.js +8 -0
- package/dist/index.cjs +71 -0
- package/dist/index.d.cts +5 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.js +71 -0
- package/dist/photon.css +339 -0
- package/dist/runner-display-BkBJpBY-.d.ts +151 -0
- package/dist/runner-display-DHHtavSX.d.cts +151 -0
- package/dist/store-CtOInpPu.d.cts +242 -0
- package/dist/store-CtOInpPu.d.ts +242 -0
- package/dist/svg/index.cjs +15 -0
- package/dist/svg/index.d.cts +172 -0
- package/dist/svg/index.d.ts +172 -0
- package/dist/svg/index.js +15 -0
- package/docs/devtools-refactor.md +93 -0
- package/docs/java-runtime-integration.md +268 -0
- package/docs/photon-template.html +547 -0
- package/docs/presentation-architecture.md +30 -0
- package/docs/runner-display.md +109 -0
- package/package.json +130 -4
|
@@ -0,0 +1,626 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; } var _class; var _class2; var _class3;
|
|
2
|
+
|
|
3
|
+
var _chunkQI4NNFRQcjs = require('./chunk-QI4NNFRQ.cjs');
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
var _chunk3QGSCPWLcjs = require('./chunk-3QGSCPWL.cjs');
|
|
12
|
+
|
|
13
|
+
// src/core/globals.ts
|
|
14
|
+
function globalValueType(value) {
|
|
15
|
+
return Array.isArray(value) ? "array" : typeof value === "boolean" ? "boolean" : typeof value === "number" && Number.isSafeInteger(value) ? "integer" : "json";
|
|
16
|
+
}
|
|
17
|
+
function flowCreationOrder(document) {
|
|
18
|
+
return document.creationOrder ? [...document.creationOrder] : [
|
|
19
|
+
...document.nodes.map((node) => ({
|
|
20
|
+
type: "node",
|
|
21
|
+
id: node.id
|
|
22
|
+
})),
|
|
23
|
+
...document.edges.map((edge) => ({
|
|
24
|
+
type: "edge",
|
|
25
|
+
id: edge.id
|
|
26
|
+
}))
|
|
27
|
+
];
|
|
28
|
+
}
|
|
29
|
+
function orderedFlowItems(document) {
|
|
30
|
+
return [
|
|
31
|
+
...(_nullishCoalesce(document.globals, () => ( []))).map((variable) => ({
|
|
32
|
+
type: "global",
|
|
33
|
+
id: variable.id
|
|
34
|
+
})),
|
|
35
|
+
...flowCreationOrder(document)
|
|
36
|
+
];
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// src/core/store.ts
|
|
40
|
+
var FlowStore = (_class = class {
|
|
41
|
+
constructor(document, options = {}) {;_class.prototype.__init.call(this);_class.prototype.__init2.call(this);_class.prototype.__init3.call(this);_class.prototype.__init4.call(this);_class.prototype.__init5.call(this);_class.prototype.__init6.call(this);
|
|
42
|
+
this.options = options;
|
|
43
|
+
_chunk3QGSCPWLcjs.assertFlow.call(void 0, document);
|
|
44
|
+
this.limit = _nullishCoalesce(options.historyLimit, () => ( 100));
|
|
45
|
+
if (!Number.isSafeInteger(this.limit) || this.limit < 0)
|
|
46
|
+
throw new (0, _chunk3QGSCPWLcjs.FlowError)(
|
|
47
|
+
"INVALID_LIMIT",
|
|
48
|
+
"historyLimit must be a nonnegative integer."
|
|
49
|
+
);
|
|
50
|
+
this.document = _chunk3QGSCPWLcjs.freeze.call(void 0, _chunk3QGSCPWLcjs.clone.call(void 0, document));
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
__init() {this.past = []}
|
|
55
|
+
__init2() {this.future = []}
|
|
56
|
+
__init3() {this.listeners = /* @__PURE__ */ new Set()}
|
|
57
|
+
__init4() {this.revision = 0}
|
|
58
|
+
__init5() {this.editing = false}
|
|
59
|
+
__init6() {this.notifying = false}
|
|
60
|
+
|
|
61
|
+
/** Frozen at runtime; mutate through transaction() instead. */
|
|
62
|
+
getSnapshot() {
|
|
63
|
+
return this.document;
|
|
64
|
+
}
|
|
65
|
+
getRevision() {
|
|
66
|
+
return this.revision;
|
|
67
|
+
}
|
|
68
|
+
get canUndo() {
|
|
69
|
+
return this.past.length > 0;
|
|
70
|
+
}
|
|
71
|
+
get canRedo() {
|
|
72
|
+
return this.future.length > 0;
|
|
73
|
+
}
|
|
74
|
+
subscribe(listener) {
|
|
75
|
+
this.listeners.add(listener);
|
|
76
|
+
return () => {
|
|
77
|
+
this.listeners.delete(listener);
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
transaction(reason, edit) {
|
|
81
|
+
this.guard();
|
|
82
|
+
this.editing = true;
|
|
83
|
+
let next;
|
|
84
|
+
try {
|
|
85
|
+
next = _chunk3QGSCPWLcjs.clone.call(void 0, this.document);
|
|
86
|
+
const result = edit(next);
|
|
87
|
+
if (result && typeof result.then === "function") {
|
|
88
|
+
throw new (0, _chunk3QGSCPWLcjs.FlowError)(
|
|
89
|
+
"ASYNC_TRANSACTION",
|
|
90
|
+
"Transactions must be synchronous."
|
|
91
|
+
);
|
|
92
|
+
}
|
|
93
|
+
const before = [
|
|
94
|
+
...this.document.nodes.map((node) => ["node", node.id]),
|
|
95
|
+
...this.document.edges.map((edge) => ["edge", edge.id])
|
|
96
|
+
];
|
|
97
|
+
const after = [
|
|
98
|
+
...next.nodes.map((node) => ["node", node.id]),
|
|
99
|
+
...next.edges.map((edge) => ["edge", edge.id])
|
|
100
|
+
];
|
|
101
|
+
if (!_chunk3QGSCPWLcjs.equal.call(void 0, before, after) && _chunk3QGSCPWLcjs.equal.call(void 0, next.creationOrder, this.document.creationOrder)) {
|
|
102
|
+
const current = new Set(
|
|
103
|
+
after.map((reference) => JSON.stringify(reference))
|
|
104
|
+
);
|
|
105
|
+
const order = flowCreationOrder(this.document).filter(
|
|
106
|
+
(reference) => current.has(JSON.stringify([reference.type, reference.id]))
|
|
107
|
+
);
|
|
108
|
+
const recorded = new Set(
|
|
109
|
+
order.map(
|
|
110
|
+
(reference) => JSON.stringify([reference.type, reference.id])
|
|
111
|
+
)
|
|
112
|
+
);
|
|
113
|
+
for (const [type, id] of after)
|
|
114
|
+
if (!recorded.has(JSON.stringify([type, id])))
|
|
115
|
+
order.push({ type, id });
|
|
116
|
+
next.creationOrder = order;
|
|
117
|
+
}
|
|
118
|
+
_chunk3QGSCPWLcjs.assertFlow.call(void 0, next);
|
|
119
|
+
next = _chunk3QGSCPWLcjs.freeze.call(void 0, _chunk3QGSCPWLcjs.clone.call(void 0, next));
|
|
120
|
+
} finally {
|
|
121
|
+
this.editing = false;
|
|
122
|
+
}
|
|
123
|
+
if (_chunk3QGSCPWLcjs.equal.call(void 0, next, this.document)) return;
|
|
124
|
+
if (this.limit)
|
|
125
|
+
this.past = [...this.past, this.document].slice(-this.limit);
|
|
126
|
+
this.future = [];
|
|
127
|
+
this.document = next;
|
|
128
|
+
this.emit(reason);
|
|
129
|
+
}
|
|
130
|
+
replace(document) {
|
|
131
|
+
_chunk3QGSCPWLcjs.assertFlow.call(void 0, document);
|
|
132
|
+
this.transaction("replace", (draft) => {
|
|
133
|
+
for (const key of Object.keys(draft))
|
|
134
|
+
delete draft[key];
|
|
135
|
+
Object.assign(draft, _chunk3QGSCPWLcjs.clone.call(void 0, document));
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
addNode(node) {
|
|
139
|
+
_chunk3QGSCPWLcjs.assertJson.call(void 0, node);
|
|
140
|
+
this.transaction("add-node", (draft) => {
|
|
141
|
+
draft.nodes.push(_chunk3QGSCPWLcjs.clone.call(void 0, node));
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
addGlobal(variable) {
|
|
145
|
+
_chunk3QGSCPWLcjs.assertJson.call(void 0, variable);
|
|
146
|
+
this.transaction("add-global", (draft) => {
|
|
147
|
+
(draft.globals ??= []).push(_chunk3QGSCPWLcjs.clone.call(void 0, variable));
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
updateGlobal(id, update) {
|
|
151
|
+
this.transaction("update-global", (draft) => {
|
|
152
|
+
const index = _nullishCoalesce(_optionalChain([draft, 'access', _ => _.globals, 'optionalAccess', _2 => _2.findIndex, 'call', _3 => _3((variable2) => variable2.id === id)]), () => ( -1));
|
|
153
|
+
if (index < 0)
|
|
154
|
+
throw new (0, _chunk3QGSCPWLcjs.FlowError)("GLOBAL_NOT_FOUND", `Unknown global ${id}.`);
|
|
155
|
+
const variable = update(draft.globals[index]);
|
|
156
|
+
if (variable.id !== id)
|
|
157
|
+
throw new (0, _chunk3QGSCPWLcjs.FlowError)(
|
|
158
|
+
"ID_CHANGE",
|
|
159
|
+
"Global ids cannot be changed by updateGlobal."
|
|
160
|
+
);
|
|
161
|
+
draft.globals[index] = variable;
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
removeGlobal(id) {
|
|
165
|
+
this.transaction("remove-global", (draft) => {
|
|
166
|
+
if (draft.globals)
|
|
167
|
+
draft.globals = draft.globals.filter((variable) => variable.id !== id);
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
updateNode(id, update) {
|
|
171
|
+
this.transaction("update-node", (draft) => {
|
|
172
|
+
const index = draft.nodes.findIndex((node) => node.id === id);
|
|
173
|
+
if (index < 0)
|
|
174
|
+
throw new (0, _chunk3QGSCPWLcjs.FlowError)("NODE_NOT_FOUND", `Unknown node ${id}.`);
|
|
175
|
+
const next = update(draft.nodes[index]);
|
|
176
|
+
if (next.id !== id)
|
|
177
|
+
throw new (0, _chunk3QGSCPWLcjs.FlowError)(
|
|
178
|
+
"ID_CHANGE",
|
|
179
|
+
"Node ids cannot be changed by updateNode."
|
|
180
|
+
);
|
|
181
|
+
draft.nodes[index] = next;
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
moveNode(id, position) {
|
|
185
|
+
this.updateNode(id, (node) => ({ ...node, position }));
|
|
186
|
+
}
|
|
187
|
+
removeNode(id) {
|
|
188
|
+
this.transaction("remove-node", (draft) => {
|
|
189
|
+
draft.nodes = draft.nodes.filter((node) => node.id !== id);
|
|
190
|
+
draft.edges = draft.edges.filter(
|
|
191
|
+
(edge) => edge.source !== id && edge.target !== id
|
|
192
|
+
);
|
|
193
|
+
});
|
|
194
|
+
}
|
|
195
|
+
addEdge(edge) {
|
|
196
|
+
_chunk3QGSCPWLcjs.assertJson.call(void 0, edge);
|
|
197
|
+
this.transaction("add-edge", (draft) => {
|
|
198
|
+
draft.edges.push(_chunk3QGSCPWLcjs.clone.call(void 0, edge));
|
|
199
|
+
});
|
|
200
|
+
}
|
|
201
|
+
updateEdge(id, update) {
|
|
202
|
+
this.transaction("update-edge", (draft) => {
|
|
203
|
+
const index = draft.edges.findIndex((edge) => edge.id === id);
|
|
204
|
+
if (index < 0)
|
|
205
|
+
throw new (0, _chunk3QGSCPWLcjs.FlowError)("EDGE_NOT_FOUND", `Unknown edge ${id}.`);
|
|
206
|
+
const next = update(draft.edges[index]);
|
|
207
|
+
if (next.id !== id)
|
|
208
|
+
throw new (0, _chunk3QGSCPWLcjs.FlowError)(
|
|
209
|
+
"ID_CHANGE",
|
|
210
|
+
"Edge ids cannot be changed by updateEdge."
|
|
211
|
+
);
|
|
212
|
+
draft.edges[index] = next;
|
|
213
|
+
});
|
|
214
|
+
}
|
|
215
|
+
removeEdge(id) {
|
|
216
|
+
this.transaction("remove-edge", (draft) => {
|
|
217
|
+
draft.edges = draft.edges.filter((edge) => edge.id !== id);
|
|
218
|
+
});
|
|
219
|
+
}
|
|
220
|
+
undo() {
|
|
221
|
+
this.guard();
|
|
222
|
+
const previous = this.past.pop();
|
|
223
|
+
if (!previous) return;
|
|
224
|
+
this.future.push(this.document);
|
|
225
|
+
this.document = previous;
|
|
226
|
+
this.emit("undo");
|
|
227
|
+
}
|
|
228
|
+
redo() {
|
|
229
|
+
this.guard();
|
|
230
|
+
const next = this.future.pop();
|
|
231
|
+
if (!next) return;
|
|
232
|
+
this.past.push(this.document);
|
|
233
|
+
this.document = next;
|
|
234
|
+
this.emit("redo");
|
|
235
|
+
}
|
|
236
|
+
guard() {
|
|
237
|
+
if (this.editing || this.notifying)
|
|
238
|
+
throw new (0, _chunk3QGSCPWLcjs.FlowError)(
|
|
239
|
+
"REENTRANT_EDIT",
|
|
240
|
+
"Nested edits and edits during notification are not supported."
|
|
241
|
+
);
|
|
242
|
+
}
|
|
243
|
+
emit(reason) {
|
|
244
|
+
this.revision++;
|
|
245
|
+
this.notifying = true;
|
|
246
|
+
try {
|
|
247
|
+
for (const listener of [...this.listeners]) {
|
|
248
|
+
try {
|
|
249
|
+
listener({
|
|
250
|
+
document: this.document,
|
|
251
|
+
reason,
|
|
252
|
+
revision: this.revision
|
|
253
|
+
});
|
|
254
|
+
} catch (error) {
|
|
255
|
+
try {
|
|
256
|
+
_optionalChain([this, 'access', _4 => _4.options, 'access', _5 => _5.onListenerError, 'optionalCall', _6 => _6(error)]);
|
|
257
|
+
} catch (e) {
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
} finally {
|
|
262
|
+
this.notifying = false;
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
}, _class);
|
|
266
|
+
|
|
267
|
+
// src/core/simulation.ts
|
|
268
|
+
var FlowSimulator = (_class2 = class {
|
|
269
|
+
|
|
270
|
+
|
|
271
|
+
__init7() {this.nextId = 1}
|
|
272
|
+
__init8() {this.sequence = 0}
|
|
273
|
+
|
|
274
|
+
|
|
275
|
+
constructor(document, context = {}, options = {}) {;_class2.prototype.__init7.call(this);_class2.prototype.__init8.call(this);
|
|
276
|
+
_chunk3QGSCPWLcjs.assertFlow.call(void 0, document, "executable");
|
|
277
|
+
this.checkContext(context);
|
|
278
|
+
this.traceLimit = _nullishCoalesce(options.traceLimit, () => ( 1e3));
|
|
279
|
+
this.maxTokens = _nullishCoalesce(options.maxTokens, () => ( 1e4));
|
|
280
|
+
if (!Number.isSafeInteger(this.traceLimit) || this.traceLimit < 0 || !Number.isSafeInteger(this.maxTokens) || this.maxTokens < 1) {
|
|
281
|
+
throw new (0, _chunk3QGSCPWLcjs.FlowError)(
|
|
282
|
+
"INVALID_LIMIT",
|
|
283
|
+
"traceLimit must be nonnegative and maxTokens positive integers."
|
|
284
|
+
);
|
|
285
|
+
}
|
|
286
|
+
this.document = _chunk3QGSCPWLcjs.freeze.call(void 0, _chunk3QGSCPWLcjs.clone.call(void 0, document));
|
|
287
|
+
this.state = {
|
|
288
|
+
status: "running",
|
|
289
|
+
context: _chunk3QGSCPWLcjs.clone.call(void 0, context),
|
|
290
|
+
tokens: [
|
|
291
|
+
{
|
|
292
|
+
id: this.id(),
|
|
293
|
+
nodeId: document.nodes.find((node) => node.type === "start").id,
|
|
294
|
+
status: "ready",
|
|
295
|
+
frames: []
|
|
296
|
+
}
|
|
297
|
+
],
|
|
298
|
+
completedNodes: [],
|
|
299
|
+
traversedEdges: [],
|
|
300
|
+
events: [],
|
|
301
|
+
steps: 0
|
|
302
|
+
};
|
|
303
|
+
}
|
|
304
|
+
getSnapshot() {
|
|
305
|
+
return _chunk3QGSCPWLcjs.freeze.call(void 0, _chunk3QGSCPWLcjs.clone.call(void 0, this.state));
|
|
306
|
+
}
|
|
307
|
+
/** Process one ready token, using stable FIFO order. */
|
|
308
|
+
step() {
|
|
309
|
+
if (this.terminal()) return this.getSnapshot();
|
|
310
|
+
const token = this.state.tokens.find((item) => item.status === "ready");
|
|
311
|
+
if (!token) {
|
|
312
|
+
this.refresh();
|
|
313
|
+
return this.getSnapshot();
|
|
314
|
+
}
|
|
315
|
+
const node = this.document.nodes.find((item) => item.id === token.nodeId);
|
|
316
|
+
const outputs = this.document.edges.filter(
|
|
317
|
+
(edge) => edge.source === node.id
|
|
318
|
+
);
|
|
319
|
+
this.state.steps++;
|
|
320
|
+
this.event({ type: "entered", nodeId: node.id, tokenId: token.id });
|
|
321
|
+
if (node.type === "task" && node.mode === "async") {
|
|
322
|
+
token.status = "async";
|
|
323
|
+
this.event({ type: "waiting", nodeId: node.id, tokenId: token.id });
|
|
324
|
+
} else if (node.type === "wait") {
|
|
325
|
+
token.status = "signal";
|
|
326
|
+
this.event({
|
|
327
|
+
type: "waiting",
|
|
328
|
+
nodeId: node.id,
|
|
329
|
+
tokenId: token.id,
|
|
330
|
+
message: node.signal
|
|
331
|
+
});
|
|
332
|
+
} else if (node.type === "end") {
|
|
333
|
+
this.completed(token);
|
|
334
|
+
this.remove(token);
|
|
335
|
+
} else if (node.type === "decision") {
|
|
336
|
+
const edge = _nullishCoalesce(outputs.filter((item) => !item.default).sort(
|
|
337
|
+
(a, b) => (_nullishCoalesce(a.priority, () => ( 0))) - (_nullishCoalesce(b.priority, () => ( 0))) || (a.id < b.id ? -1 : a.id > b.id ? 1 : 0)
|
|
338
|
+
).find(
|
|
339
|
+
(item) => item.condition && _chunkQI4NNFRQcjs.evaluateCondition.call(void 0, item.condition, this.state.context)
|
|
340
|
+
), () => ( outputs.find((item) => item.default)));
|
|
341
|
+
this.advance(token, edge);
|
|
342
|
+
} else if (node.type === "fork") {
|
|
343
|
+
if (this.state.tokens.length - 1 + outputs.length > this.maxTokens) {
|
|
344
|
+
this.failToken(token, "Active token limit exceeded.");
|
|
345
|
+
} else {
|
|
346
|
+
const group = this.id();
|
|
347
|
+
this.completed(token);
|
|
348
|
+
this.remove(token);
|
|
349
|
+
for (const edge of outputs) {
|
|
350
|
+
const child = {
|
|
351
|
+
id: this.id(),
|
|
352
|
+
nodeId: node.id,
|
|
353
|
+
status: "ready",
|
|
354
|
+
frames: [
|
|
355
|
+
..._chunk3QGSCPWLcjs.clone.call(void 0, token.frames),
|
|
356
|
+
{
|
|
357
|
+
group,
|
|
358
|
+
fork: node.id,
|
|
359
|
+
join: node.join,
|
|
360
|
+
branch: edge.id,
|
|
361
|
+
expected: outputs.length
|
|
362
|
+
}
|
|
363
|
+
]
|
|
364
|
+
};
|
|
365
|
+
this.state.tokens.push(child);
|
|
366
|
+
this.traverse(child, edge);
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
} else if (node.type === "join") {
|
|
370
|
+
const frame = token.frames.at(-1);
|
|
371
|
+
if (!frame || frame.join !== node.id || frame.fork !== node.fork) {
|
|
372
|
+
this.failToken(token, "Token reached a join outside its fork scope.");
|
|
373
|
+
} else {
|
|
374
|
+
token.status = "joining";
|
|
375
|
+
const siblings = this.state.tokens.filter(
|
|
376
|
+
(item) => item.nodeId === node.id && item.status === "joining" && _optionalChain([item, 'access', _7 => _7.frames, 'access', _8 => _8.at, 'call', _9 => _9(-1), 'optionalAccess', _10 => _10.group]) === frame.group
|
|
377
|
+
);
|
|
378
|
+
const branches = new Set(
|
|
379
|
+
siblings.map((item) => item.frames.at(-1).branch)
|
|
380
|
+
);
|
|
381
|
+
if (branches.size !== siblings.length)
|
|
382
|
+
this.failToken(
|
|
383
|
+
token,
|
|
384
|
+
"A parallel branch arrived at the join more than once."
|
|
385
|
+
);
|
|
386
|
+
else if (siblings.length === frame.expected) {
|
|
387
|
+
for (const sibling of siblings) this.remove(sibling);
|
|
388
|
+
token.frames.pop();
|
|
389
|
+
token.status = "ready";
|
|
390
|
+
this.state.tokens.push(token);
|
|
391
|
+
this.advance(token, outputs[0]);
|
|
392
|
+
} else
|
|
393
|
+
this.event({ type: "waiting", nodeId: node.id, tokenId: token.id });
|
|
394
|
+
}
|
|
395
|
+
} else this.advance(token, outputs[0]);
|
|
396
|
+
this.refresh();
|
|
397
|
+
return this.getSnapshot();
|
|
398
|
+
}
|
|
399
|
+
run(maxSteps = 1e3) {
|
|
400
|
+
if (!Number.isSafeInteger(maxSteps) || maxSteps < 1)
|
|
401
|
+
throw new (0, _chunk3QGSCPWLcjs.FlowError)(
|
|
402
|
+
"INVALID_LIMIT",
|
|
403
|
+
"maxSteps must be a positive integer."
|
|
404
|
+
);
|
|
405
|
+
for (let index = 0; index < maxSteps && this.state.status === "running"; index++)
|
|
406
|
+
this.step();
|
|
407
|
+
return {
|
|
408
|
+
reason: this.state.status === "running" ? "step-limit" : this.state.status,
|
|
409
|
+
snapshot: this.getSnapshot()
|
|
410
|
+
};
|
|
411
|
+
}
|
|
412
|
+
/** Complete one async activation, not every activation of the same node. */
|
|
413
|
+
complete(tokenId, patch = {}) {
|
|
414
|
+
return this.resume(tokenId, "async", patch);
|
|
415
|
+
}
|
|
416
|
+
/** External applications collect user input and explicitly deliver it here. */
|
|
417
|
+
signal(tokenId, signal, patch = {}) {
|
|
418
|
+
const token = this.findWaiting(tokenId, "signal");
|
|
419
|
+
const node = this.document.nodes.find((item) => item.id === token.nodeId);
|
|
420
|
+
if (node.type !== "wait" || node.signal !== signal)
|
|
421
|
+
throw new (0, _chunk3QGSCPWLcjs.FlowError)("SIGNAL_MISMATCH", `Unexpected signal ${signal}.`);
|
|
422
|
+
return this.resume(tokenId, "signal", patch);
|
|
423
|
+
}
|
|
424
|
+
fail(tokenId, message) {
|
|
425
|
+
if (this.terminal())
|
|
426
|
+
throw new (0, _chunk3QGSCPWLcjs.FlowError)(
|
|
427
|
+
"TERMINAL_SIMULATION",
|
|
428
|
+
"The simulation has finished."
|
|
429
|
+
);
|
|
430
|
+
const token = this.state.tokens.find((item) => item.id === tokenId);
|
|
431
|
+
if (!token)
|
|
432
|
+
throw new (0, _chunk3QGSCPWLcjs.FlowError)("TOKEN_NOT_FOUND", `Unknown token ${tokenId}.`);
|
|
433
|
+
this.failToken(token, message);
|
|
434
|
+
return this.getSnapshot();
|
|
435
|
+
}
|
|
436
|
+
cancel() {
|
|
437
|
+
if (!this.terminal()) {
|
|
438
|
+
this.state.status = "cancelled";
|
|
439
|
+
this.state.tokens = [];
|
|
440
|
+
this.event({ type: "cancelled" });
|
|
441
|
+
}
|
|
442
|
+
return this.getSnapshot();
|
|
443
|
+
}
|
|
444
|
+
resume(tokenId, status, patch) {
|
|
445
|
+
const token = this.findWaiting(tokenId, status);
|
|
446
|
+
this.checkContext(patch);
|
|
447
|
+
this.state.context = { ...this.state.context, ..._chunk3QGSCPWLcjs.clone.call(void 0, patch) };
|
|
448
|
+
this.advance(
|
|
449
|
+
token,
|
|
450
|
+
this.document.edges.find((edge) => edge.source === token.nodeId)
|
|
451
|
+
);
|
|
452
|
+
this.refresh();
|
|
453
|
+
return this.getSnapshot();
|
|
454
|
+
}
|
|
455
|
+
findWaiting(id, status) {
|
|
456
|
+
if (this.terminal())
|
|
457
|
+
throw new (0, _chunk3QGSCPWLcjs.FlowError)(
|
|
458
|
+
"TERMINAL_SIMULATION",
|
|
459
|
+
"The simulation has finished."
|
|
460
|
+
);
|
|
461
|
+
const token = this.state.tokens.find((item) => item.id === id);
|
|
462
|
+
if (!token || token.status !== status)
|
|
463
|
+
throw new (0, _chunk3QGSCPWLcjs.FlowError)(
|
|
464
|
+
"TOKEN_NOT_WAITING",
|
|
465
|
+
`Token ${id} is not waiting for ${status}.`
|
|
466
|
+
);
|
|
467
|
+
return token;
|
|
468
|
+
}
|
|
469
|
+
advance(token, edge) {
|
|
470
|
+
this.completed(token);
|
|
471
|
+
this.traverse(token, edge);
|
|
472
|
+
this.remove(token);
|
|
473
|
+
this.state.tokens.push(token);
|
|
474
|
+
}
|
|
475
|
+
traverse(token, edge) {
|
|
476
|
+
this.event({ type: "traversed", edgeId: edge.id, tokenId: token.id });
|
|
477
|
+
if (!this.state.traversedEdges.includes(edge.id))
|
|
478
|
+
this.state.traversedEdges.push(edge.id);
|
|
479
|
+
token.nodeId = edge.target;
|
|
480
|
+
token.status = "ready";
|
|
481
|
+
}
|
|
482
|
+
completed(token) {
|
|
483
|
+
if (!this.state.completedNodes.includes(token.nodeId))
|
|
484
|
+
this.state.completedNodes.push(token.nodeId);
|
|
485
|
+
this.event({ type: "completed", nodeId: token.nodeId, tokenId: token.id });
|
|
486
|
+
}
|
|
487
|
+
failToken(token, message) {
|
|
488
|
+
this.state.status = "failed";
|
|
489
|
+
this.state.error = message;
|
|
490
|
+
this.event({
|
|
491
|
+
type: "failed",
|
|
492
|
+
nodeId: token.nodeId,
|
|
493
|
+
tokenId: token.id,
|
|
494
|
+
message
|
|
495
|
+
});
|
|
496
|
+
}
|
|
497
|
+
remove(token) {
|
|
498
|
+
this.state.tokens = this.state.tokens.filter(
|
|
499
|
+
(item) => item.id !== token.id
|
|
500
|
+
);
|
|
501
|
+
}
|
|
502
|
+
id() {
|
|
503
|
+
return `t${this.nextId++}`;
|
|
504
|
+
}
|
|
505
|
+
terminal() {
|
|
506
|
+
return ["completed", "failed", "cancelled"].includes(this.state.status);
|
|
507
|
+
}
|
|
508
|
+
refresh() {
|
|
509
|
+
if (this.terminal()) return;
|
|
510
|
+
if (!this.state.tokens.length) this.state.status = "completed";
|
|
511
|
+
else if (this.state.tokens.some((token) => token.status === "ready"))
|
|
512
|
+
this.state.status = "running";
|
|
513
|
+
else if (this.state.tokens.every((token) => token.status === "joining")) {
|
|
514
|
+
this.failToken(this.state.tokens[0], "Parallel join deadlock.");
|
|
515
|
+
} else this.state.status = "waiting";
|
|
516
|
+
}
|
|
517
|
+
event(event) {
|
|
518
|
+
this.sequence++;
|
|
519
|
+
if (this.traceLimit) {
|
|
520
|
+
this.state.events.push({ ...event, sequence: this.sequence });
|
|
521
|
+
if (this.state.events.length > this.traceLimit) this.state.events.shift();
|
|
522
|
+
}
|
|
523
|
+
}
|
|
524
|
+
checkContext(context) {
|
|
525
|
+
_chunk3QGSCPWLcjs.assertJson.call(void 0, context);
|
|
526
|
+
if (!context || typeof context !== "object" || Array.isArray(context))
|
|
527
|
+
throw new (0, _chunk3QGSCPWLcjs.FlowError)("INVALID_CONTEXT", "Context must be a JSON object.");
|
|
528
|
+
}
|
|
529
|
+
}, _class2);
|
|
530
|
+
|
|
531
|
+
// src/core/layout.ts
|
|
532
|
+
function layoutFlow(document, options = {}) {
|
|
533
|
+
_chunk3QGSCPWLcjs.assertFlow.call(void 0, document);
|
|
534
|
+
const columnGap = _nullishCoalesce(options.columnGap, () => ( 220));
|
|
535
|
+
const rowGap = _nullishCoalesce(options.rowGap, () => ( 120));
|
|
536
|
+
if (!Number.isFinite(columnGap) || columnGap <= 0 || !Number.isFinite(rowGap) || rowGap <= 0)
|
|
537
|
+
throw new RangeError("Layout gaps must be positive finite numbers.");
|
|
538
|
+
const result = _chunk3QGSCPWLcjs.clone.call(void 0, document);
|
|
539
|
+
const levels = /* @__PURE__ */ new Map();
|
|
540
|
+
const queue = result.nodes.filter(
|
|
541
|
+
(node) => node.type === "start" || !result.edges.some((edge) => edge.target === node.id)
|
|
542
|
+
).map((node) => node.id);
|
|
543
|
+
for (const id of queue) levels.set(id, 0);
|
|
544
|
+
for (let index = 0; index < queue.length; index++) {
|
|
545
|
+
const id = queue[index];
|
|
546
|
+
for (const edge of result.edges.filter((edge2) => edge2.source === id)) {
|
|
547
|
+
if (!levels.has(edge.target)) {
|
|
548
|
+
levels.set(edge.target, levels.get(id) + 1);
|
|
549
|
+
queue.push(edge.target);
|
|
550
|
+
}
|
|
551
|
+
}
|
|
552
|
+
}
|
|
553
|
+
let fallback = Math.max(0, ...levels.values()) + 1;
|
|
554
|
+
const rows = /* @__PURE__ */ new Map();
|
|
555
|
+
for (const node of result.nodes) {
|
|
556
|
+
const level = _nullishCoalesce(levels.get(node.id), () => ( fallback++));
|
|
557
|
+
const row = _nullishCoalesce(rows.get(level), () => ( 0));
|
|
558
|
+
rows.set(level, row + 1);
|
|
559
|
+
node.position = options.direction === "down" ? { x: 100 + row * columnGap, y: 80 + level * rowGap } : { x: 100 + level * columnGap, y: 80 + row * rowGap };
|
|
560
|
+
}
|
|
561
|
+
return result;
|
|
562
|
+
}
|
|
563
|
+
|
|
564
|
+
// src/core/performance.ts
|
|
565
|
+
var finite = (value) => typeof value === "number" && Number.isFinite(value) && value >= 0;
|
|
566
|
+
var text = (value) => typeof value === "string" && value.trim().length > 0;
|
|
567
|
+
var uint64 = (value) => typeof value === "string" && /^(0|[1-9][0-9]*)$/.test(value) && value.length <= 20 && BigInt(value) <= 18446744073709551615n;
|
|
568
|
+
var PerformanceTimeline = (_class3 = class {constructor() { _class3.prototype.__init9.call(this); }
|
|
569
|
+
__init9() {this.runs = /* @__PURE__ */ new Map()}
|
|
570
|
+
record(sample) {
|
|
571
|
+
_chunk3QGSCPWLcjs.assertJson.call(void 0, sample);
|
|
572
|
+
if (!sample || ![sample.runId, sample.nodeId, sample.commandId, sample.process].every(
|
|
573
|
+
text
|
|
574
|
+
) || !finite(sample.startMs) || !finite(sample.durationMs) || !Number.isSafeInteger(sample.cost) || sample.cost < 0 || !Number.isFinite(sample.startMs + sample.durationMs))
|
|
575
|
+
throw new (0, _chunk3QGSCPWLcjs.FlowError)(
|
|
576
|
+
"INVALID_PERFORMANCE",
|
|
577
|
+
"Expected backend run identity, finite times and a nonnegative safe integer cost."
|
|
578
|
+
);
|
|
579
|
+
if (sample.network !== void 0 && (!Array.isArray(sample.network) || sample.network.some(
|
|
580
|
+
(item) => !item || !finite(item.startMs) || !finite(item.durationMs) || !Number.isFinite(item.startMs + item.durationMs) || !text(item.label) || item.bytes !== void 0 && !uint64(item.bytes)
|
|
581
|
+
)))
|
|
582
|
+
throw new (0, _chunk3QGSCPWLcjs.FlowError)(
|
|
583
|
+
"INVALID_PERFORMANCE",
|
|
584
|
+
"Invalid backend network interval."
|
|
585
|
+
);
|
|
586
|
+
if (sample.memory !== void 0 && (!Array.isArray(sample.memory) || sample.memory.some(
|
|
587
|
+
(item) => !item || !finite(item.timeMs) || !uint64(item.bytes)
|
|
588
|
+
)))
|
|
589
|
+
throw new (0, _chunk3QGSCPWLcjs.FlowError)(
|
|
590
|
+
"INVALID_PERFORMANCE",
|
|
591
|
+
"Invalid backend memory sample."
|
|
592
|
+
);
|
|
593
|
+
const previous = this.runs.get(sample.runId);
|
|
594
|
+
if (previous) {
|
|
595
|
+
if (!_chunk3QGSCPWLcjs.equal.call(void 0, previous, sample))
|
|
596
|
+
throw new (0, _chunk3QGSCPWLcjs.FlowError)(
|
|
597
|
+
"PERFORMANCE_CONFLICT",
|
|
598
|
+
"A node-run metric id cannot be reused with different data."
|
|
599
|
+
);
|
|
600
|
+
return false;
|
|
601
|
+
}
|
|
602
|
+
if (this.runs.size >= 1e4)
|
|
603
|
+
throw new (0, _chunk3QGSCPWLcjs.FlowError)(
|
|
604
|
+
"PERFORMANCE_LIMIT",
|
|
605
|
+
"Start a new performance view after 10000 node runs."
|
|
606
|
+
);
|
|
607
|
+
this.runs.set(sample.runId, _chunk3QGSCPWLcjs.freeze.call(void 0, _chunk3QGSCPWLcjs.clone.call(void 0, sample)));
|
|
608
|
+
return true;
|
|
609
|
+
}
|
|
610
|
+
getSnapshot() {
|
|
611
|
+
return _chunk3QGSCPWLcjs.freeze.call(void 0, _chunk3QGSCPWLcjs.clone.call(void 0, [...this.runs.values()]));
|
|
612
|
+
}
|
|
613
|
+
clear() {
|
|
614
|
+
this.runs.clear();
|
|
615
|
+
}
|
|
616
|
+
}, _class3);
|
|
617
|
+
|
|
618
|
+
|
|
619
|
+
|
|
620
|
+
|
|
621
|
+
|
|
622
|
+
|
|
623
|
+
|
|
624
|
+
|
|
625
|
+
|
|
626
|
+
exports.globalValueType = globalValueType; exports.flowCreationOrder = flowCreationOrder; exports.orderedFlowItems = orderedFlowItems; exports.FlowStore = FlowStore; exports.FlowSimulator = FlowSimulator; exports.layoutFlow = layoutFlow; exports.PerformanceTimeline = PerformanceTimeline;
|
|
File without changes
|