@xenolithengine/graph-core 0.7.0-beta.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 (79) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +55 -0
  3. package/dist/command-bus.d.ts +56 -0
  4. package/dist/command-bus.d.ts.map +1 -0
  5. package/dist/command-bus.js +180 -0
  6. package/dist/command-bus.js.map +1 -0
  7. package/dist/commands-comment.d.ts +52 -0
  8. package/dist/commands-comment.d.ts.map +1 -0
  9. package/dist/commands-comment.js +92 -0
  10. package/dist/commands-comment.js.map +1 -0
  11. package/dist/commands-mut.d.ts +58 -0
  12. package/dist/commands-mut.d.ts.map +1 -0
  13. package/dist/commands-mut.js +119 -0
  14. package/dist/commands-mut.js.map +1 -0
  15. package/dist/commands.d.ts +36 -0
  16. package/dist/commands.d.ts.map +1 -0
  17. package/dist/commands.js +72 -0
  18. package/dist/commands.js.map +1 -0
  19. package/dist/comment-spatial.d.ts +20 -0
  20. package/dist/comment-spatial.d.ts.map +1 -0
  21. package/dist/comment-spatial.js +21 -0
  22. package/dist/comment-spatial.js.map +1 -0
  23. package/dist/event-emitter.d.ts +15 -0
  24. package/dist/event-emitter.d.ts.map +1 -0
  25. package/dist/event-emitter.js +55 -0
  26. package/dist/event-emitter.js.map +1 -0
  27. package/dist/fuzzy.d.ts +17 -0
  28. package/dist/fuzzy.d.ts.map +1 -0
  29. package/dist/fuzzy.js +55 -0
  30. package/dist/fuzzy.js.map +1 -0
  31. package/dist/graph.d.ts +108 -0
  32. package/dist/graph.d.ts.map +1 -0
  33. package/dist/graph.js +141 -0
  34. package/dist/graph.js.map +1 -0
  35. package/dist/ids.d.ts +28 -0
  36. package/dist/ids.d.ts.map +1 -0
  37. package/dist/ids.js +31 -0
  38. package/dist/ids.js.map +1 -0
  39. package/dist/index.d.ts +35 -0
  40. package/dist/index.d.ts.map +1 -0
  41. package/dist/index.js +20 -0
  42. package/dist/index.js.map +1 -0
  43. package/dist/macro.d.ts +120 -0
  44. package/dist/macro.d.ts.map +1 -0
  45. package/dist/macro.js +226 -0
  46. package/dist/macro.js.map +1 -0
  47. package/dist/node-registry.d.ts +101 -0
  48. package/dist/node-registry.d.ts.map +1 -0
  49. package/dist/node-registry.js +96 -0
  50. package/dist/node-registry.js.map +1 -0
  51. package/dist/reroute.d.ts +21 -0
  52. package/dist/reroute.d.ts.map +1 -0
  53. package/dist/reroute.js +40 -0
  54. package/dist/reroute.js.map +1 -0
  55. package/dist/selection.d.ts +17 -0
  56. package/dist/selection.d.ts.map +1 -0
  57. package/dist/selection.js +56 -0
  58. package/dist/selection.js.map +1 -0
  59. package/dist/template-def.d.ts +113 -0
  60. package/dist/template-def.d.ts.map +1 -0
  61. package/dist/template-def.js +0 -0
  62. package/dist/template-def.js.map +1 -0
  63. package/dist/template-flatten.d.ts +38 -0
  64. package/dist/template-flatten.d.ts.map +1 -0
  65. package/dist/template-flatten.js +157 -0
  66. package/dist/template-flatten.js.map +1 -0
  67. package/dist/traversal.d.ts +27 -0
  68. package/dist/traversal.d.ts.map +1 -0
  69. package/dist/traversal.js +119 -0
  70. package/dist/traversal.js.map +1 -0
  71. package/dist/types-registry.d.ts +41 -0
  72. package/dist/types-registry.d.ts.map +1 -0
  73. package/dist/types-registry.js +60 -0
  74. package/dist/types-registry.js.map +1 -0
  75. package/dist/widget.d.ts +141 -0
  76. package/dist/widget.d.ts.map +1 -0
  77. package/dist/widget.js +112 -0
  78. package/dist/widget.js.map +1 -0
  79. package/package.json +55 -0
@@ -0,0 +1,157 @@
1
+ import { TEMPLATE_INPUT_TYPE, TEMPLATE_OUTPUT_TYPE, isTemplateBoundary, isTemplateInstance, } from './template-def.js';
2
+ /** Flatten `instance` against the definitions reachable through `resolveDef`. Returns null if a
3
+ * definition is missing or a recursion cycle is detected (a definition transitively containing an
4
+ * instance of itself). Pure — never mutates the instance, definitions, or document. */
5
+ export function flattenTemplateInstance(instance, resolveDef, mint) {
6
+ return flatten(instance, resolveDef, mint, []);
7
+ }
8
+ function flatten(instance, resolveDef, mint, path) {
9
+ const defId = instance.state['definitionId'];
10
+ if (defId === undefined)
11
+ return null;
12
+ if (path.includes(defId))
13
+ return null; // cycle: this definition is already being flattened above us
14
+ const def = resolveDef(defId);
15
+ if (!def)
16
+ return null;
17
+ const childPath = [...path, defId];
18
+ const boundaryToInstPin = invertPinBoundary(instance);
19
+ const nodes = [];
20
+ const edges = [];
21
+ const inputs = {};
22
+ const outputs = {};
23
+ // Resolve each definition member: a primitive gets a fresh-id clone; a nested instance is flattened
24
+ // recursively and remembered so edges touching its pins redirect to its internal pins.
25
+ const primitive = new Map();
26
+ const nested = new Map();
27
+ for (const m of def.nodes) {
28
+ if (isTemplateBoundary(m))
29
+ continue;
30
+ if (isTemplateInstance(m)) {
31
+ const child = flatten(m, resolveDef, mint, childPath);
32
+ if (!child)
33
+ return null;
34
+ nodes.push(...child.nodes);
35
+ edges.push(...child.edges);
36
+ nested.set(String(m.id), child);
37
+ continue;
38
+ }
39
+ const id = mint.node();
40
+ const pinRemap = new Map();
41
+ const pins = m.pins.map((p) => { const np = mint.pin(); pinRemap.set(String(p.id), np); return { ...p, id: np }; });
42
+ primitive.set(String(m.id), { id, pinRemap });
43
+ nodes.push({
44
+ ...m, id, position: { ...m.position }, state: { ...m.state }, pins,
45
+ ...(m.size ? { size: { ...m.size } } : {}),
46
+ ...(m.widgets ? { widgets: m.widgets.map((w) => ({ ...w })) } : {}),
47
+ ...(m.meta ? { meta: { ...m.meta } } : {}),
48
+ });
49
+ }
50
+ // Resolve an OUT endpoint (the producing pin) to its concrete internal pin(s) — normally one.
51
+ const resolveOut = (node, pin) => {
52
+ const prim = primitive.get(String(node));
53
+ if (prim)
54
+ return [{ node: prim.id, pin: prim.pinRemap.get(String(pin)) }];
55
+ const child = nested.get(String(node));
56
+ if (child) {
57
+ const o = child.boundary.outputs[String(pin)];
58
+ return o ? [o] : [];
59
+ }
60
+ return [];
61
+ };
62
+ // Resolve an IN endpoint (the consuming pin) to its concrete internal pin(s) — a nested input may
63
+ // fan out to several internal pins.
64
+ const resolveIn = (node, pin) => {
65
+ const prim = primitive.get(String(node));
66
+ if (prim)
67
+ return [{ node: prim.id, pin: prim.pinRemap.get(String(pin)) }];
68
+ const child = nested.get(String(node));
69
+ if (child)
70
+ return child.boundary.inputs[String(pin)] ?? [];
71
+ return [];
72
+ };
73
+ for (const e of def.edges) {
74
+ const srcInput = isType(def, e.from.node, TEMPLATE_INPUT_TYPE);
75
+ const dstOutput = isType(def, e.to.node, TEMPLATE_OUTPUT_TYPE);
76
+ if (srcInput && dstOutput)
77
+ continue; // degenerate passthrough (input wired straight to output)
78
+ if (srcInput) {
79
+ const instPin = boundaryToInstPin.get(String(e.from.node));
80
+ if (instPin === undefined)
81
+ continue;
82
+ (inputs[instPin] ??= []).push(...resolveIn(e.to.node, e.to.pin));
83
+ }
84
+ else if (dstOutput) {
85
+ const instPin = boundaryToInstPin.get(String(e.to.node));
86
+ if (instPin === undefined)
87
+ continue;
88
+ const producer = resolveOut(e.from.node, e.from.pin)[0];
89
+ if (producer)
90
+ outputs[instPin] = producer;
91
+ }
92
+ else {
93
+ const srcs = resolveOut(e.from.node, e.from.pin);
94
+ const dsts = resolveIn(e.to.node, e.to.pin);
95
+ for (const s of srcs)
96
+ for (const d of dsts)
97
+ edges.push({ id: mint.edge(), from: s, to: d });
98
+ }
99
+ }
100
+ return { nodes, edges, boundary: { inputs, outputs } };
101
+ }
102
+ /** Snapshot-level helper: replace every `$templateInstance` in (`nodes`, `edges`) with its flattened
103
+ * primitive sub-graph and rewire the external edges that touched the instance's interface pins to
104
+ * the boundary-mapped internal pins. Mirrors `flattenMacroProxies` for templates. Pure — inputs are
105
+ * not mutated. An instance whose definition is missing or recursive is left in place. */
106
+ export function flattenAllTemplateInstances(nodes, edges, resolveDef, mint) {
107
+ const instanceFlat = new Map();
108
+ const outNodes = [];
109
+ for (const n of nodes) {
110
+ if (!isTemplateInstance(n)) {
111
+ outNodes.push(n);
112
+ continue;
113
+ }
114
+ const flat = flattenTemplateInstance(n, resolveDef, mint);
115
+ if (!flat) {
116
+ outNodes.push(n);
117
+ continue;
118
+ } // unresolved / recursive — leave as data so the host sees it
119
+ instanceFlat.set(String(n.id), flat);
120
+ outNodes.push(...flat.nodes);
121
+ }
122
+ const outEdges = [];
123
+ for (const e of edges) {
124
+ const srcFlat = instanceFlat.get(String(e.from.node));
125
+ const dstFlat = instanceFlat.get(String(e.to.node));
126
+ if (!srcFlat && !dstFlat) {
127
+ outEdges.push(e);
128
+ continue;
129
+ }
130
+ const sources = srcFlat
131
+ ? (srcFlat.boundary.outputs[String(e.from.pin)] ? [srcFlat.boundary.outputs[String(e.from.pin)]] : [])
132
+ : [{ node: e.from.node, pin: e.from.pin }];
133
+ const targets = dstFlat
134
+ ? (dstFlat.boundary.inputs[String(e.to.pin)] ?? [])
135
+ : [{ node: e.to.node, pin: e.to.pin }];
136
+ for (const s of sources)
137
+ for (const t of targets)
138
+ outEdges.push({ id: mint.edge(), from: s, to: t });
139
+ }
140
+ // Internal definition edges already live in flat.edges (carried via outNodes' spread above isn't right —
141
+ // edges live separately). Concat them explicitly.
142
+ for (const flat of instanceFlat.values())
143
+ outEdges.push(...flat.edges);
144
+ return { nodes: outNodes, edges: outEdges };
145
+ }
146
+ function invertPinBoundary(instance) {
147
+ const pinBoundary = (instance.state['pinBoundary'] ?? {});
148
+ const out = new Map();
149
+ for (const [pinId, boundaryId] of Object.entries(pinBoundary))
150
+ out.set(boundaryId, pinId);
151
+ return out;
152
+ }
153
+ function isType(def, nodeId, type) {
154
+ const n = def.nodes.find((x) => String(x.id) === String(nodeId));
155
+ return n?.type === type;
156
+ }
157
+ //# sourceMappingURL=template-flatten.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"template-flatten.js","sourceRoot":"","sources":["../src/template-flatten.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,mBAAmB,EACnB,oBAAoB,EACpB,kBAAkB,EAClB,kBAAkB,GAGnB,MAAM,mBAAmB,CAAA;AAuB1B;;wFAEwF;AACxF,MAAM,UAAU,uBAAuB,CACrC,QAAc,EACd,UAAoE,EACpE,IAAiB;IAEjB,OAAO,OAAO,CAAC,QAAQ,EAAE,UAAU,EAAE,IAAI,EAAE,EAAE,CAAC,CAAA;AAChD,CAAC;AAED,SAAS,OAAO,CACd,QAAc,EACd,UAAoE,EACpE,IAAiB,EACjB,IAAqB;IAErB,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC,cAAc,CAA8B,CAAA;IACzE,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,IAAI,CAAA;IACpC,IAAI,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC;QAAE,OAAO,IAAI,CAAA,CAAC,6DAA6D;IACnG,MAAM,GAAG,GAAG,UAAU,CAAC,KAAK,CAAC,CAAA;IAC7B,IAAI,CAAC,GAAG;QAAE,OAAO,IAAI,CAAA;IACrB,MAAM,SAAS,GAAG,CAAC,GAAG,IAAI,EAAE,KAAK,CAAC,CAAA;IAElC,MAAM,iBAAiB,GAAG,iBAAiB,CAAC,QAAQ,CAAC,CAAA;IAErD,MAAM,KAAK,GAAW,EAAE,CAAA;IACxB,MAAM,KAAK,GAAW,EAAE,CAAA;IACxB,MAAM,MAAM,GAA6B,EAAE,CAAA;IAC3C,MAAM,OAAO,GAA2B,EAAE,CAAA;IAE1C,oGAAoG;IACpG,uFAAuF;IACvF,MAAM,SAAS,GAAG,IAAI,GAAG,EAAwD,CAAA;IACjF,MAAM,MAAM,GAAG,IAAI,GAAG,EAA6B,CAAA;IACnD,KAAK,MAAM,CAAC,IAAI,GAAG,CAAC,KAAK,EAAE,CAAC;QAC1B,IAAI,kBAAkB,CAAC,CAAC,CAAC;YAAE,SAAQ;QACnC,IAAI,kBAAkB,CAAC,CAAC,CAAC,EAAE,CAAC;YAC1B,MAAM,KAAK,GAAG,OAAO,CAAC,CAAC,EAAE,UAAU,EAAE,IAAI,EAAE,SAAS,CAAC,CAAA;YACrD,IAAI,CAAC,KAAK;gBAAE,OAAO,IAAI,CAAA;YACvB,KAAK,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC,CAAA;YAC1B,KAAK,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC,CAAA;YAC1B,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,KAAK,CAAC,CAAA;YAC/B,SAAQ;QACV,CAAC;QACD,MAAM,EAAE,GAAG,IAAI,CAAC,IAAI,EAAE,CAAA;QACtB,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAiB,CAAA;QACzC,MAAM,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,GAAG,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,EAAE,GAAG,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,CAAA,CAAC,CAAC,CAAC,CAAA;QAClH,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE,CAAC,CAAA;QAC7C,KAAK,CAAC,IAAI,CAAC;YACT,GAAG,CAAC,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE,KAAK,EAAE,EAAE,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,IAAI;YAClE,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAC1C,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACnE,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SAC3C,CAAC,CAAA;IACJ,CAAC;IAED,8FAA8F;IAC9F,MAAM,UAAU,GAAG,CAAC,IAAY,EAAE,GAAU,EAAY,EAAE;QACxD,MAAM,IAAI,GAAG,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAA;QACxC,IAAI,IAAI;YAAE,OAAO,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,EAAE,GAAG,EAAE,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAE,EAAE,CAAC,CAAA;QAC1E,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAA;QACtC,IAAI,KAAK,EAAE,CAAC;YAAC,MAAM,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;YAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAA;QAAC,CAAC;QACjF,OAAO,EAAE,CAAA;IACX,CAAC,CAAA;IACD,kGAAkG;IAClG,oCAAoC;IACpC,MAAM,SAAS,GAAG,CAAC,IAAY,EAAE,GAAU,EAAY,EAAE;QACvD,MAAM,IAAI,GAAG,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAA;QACxC,IAAI,IAAI;YAAE,OAAO,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,EAAE,GAAG,EAAE,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAE,EAAE,CAAC,CAAA;QAC1E,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAA;QACtC,IAAI,KAAK;YAAE,OAAO,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAA;QAC1D,OAAO,EAAE,CAAA;IACX,CAAC,CAAA;IAED,KAAK,MAAM,CAAC,IAAI,GAAG,CAAC,KAAK,EAAE,CAAC;QAC1B,MAAM,QAAQ,GAAG,MAAM,CAAC,GAAG,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,mBAAmB,CAAC,CAAA;QAC9D,MAAM,SAAS,GAAG,MAAM,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC,IAAI,EAAE,oBAAoB,CAAC,CAAA;QAC9D,IAAI,QAAQ,IAAI,SAAS;YAAE,SAAQ,CAAC,0DAA0D;QAC9F,IAAI,QAAQ,EAAE,CAAC;YACb,MAAM,OAAO,GAAG,iBAAiB,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAA;YAC1D,IAAI,OAAO,KAAK,SAAS;gBAAE,SAC1B;YAAA,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAA;QACnE,CAAC;aAAM,IAAI,SAAS,EAAE,CAAC;YACrB,MAAM,OAAO,GAAG,iBAAiB,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAA;YACxD,IAAI,OAAO,KAAK,SAAS;gBAAE,SAAQ;YACnC,MAAM,QAAQ,GAAG,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAA;YACvD,IAAI,QAAQ;gBAAE,OAAO,CAAC,OAAO,CAAC,GAAG,QAAQ,CAAA;QAC3C,CAAC;aAAM,CAAC;YACN,MAAM,IAAI,GAAG,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;YAChD,MAAM,IAAI,GAAG,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAA;YAC3C,KAAK,MAAM,CAAC,IAAI,IAAI;gBAAE,KAAK,MAAM,CAAC,IAAI,IAAI;oBAAE,KAAK,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,IAAI,CAAC,IAAI,EAAE,EAAE,IAAI,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,CAAA;QAC7F,CAAC;IACH,CAAC;IAED,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE,CAAA;AACxD,CAAC;AAED;;;0FAG0F;AAC1F,MAAM,UAAU,2BAA2B,CACzC,KAAa,EACb,KAAa,EACb,UAAoE,EACpE,IAAiB;IAEjB,MAAM,YAAY,GAAG,IAAI,GAAG,EAA6B,CAAA;IACzD,MAAM,QAAQ,GAAW,EAAE,CAAA;IAC3B,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;QACtB,IAAI,CAAC,kBAAkB,CAAC,CAAC,CAAC,EAAE,CAAC;YAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YAAC,SAAQ;QAAC,CAAC;QAC1D,MAAM,IAAI,GAAG,uBAAuB,CAAC,CAAC,EAAE,UAAU,EAAE,IAAI,CAAC,CAAA;QACzD,IAAI,CAAC,IAAI,EAAE,CAAC;YAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YAAC,SAAQ;QAAC,CAAC,CAAC,6DAA6D;QACvG,YAAY,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,CAAA;QACpC,QAAQ,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAA;IAC9B,CAAC;IACD,MAAM,QAAQ,GAAW,EAAE,CAAA;IAC3B,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;QACtB,MAAM,OAAO,GAAG,YAAY,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAA;QACrD,MAAM,OAAO,GAAG,YAAY,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAA;QACnD,IAAI,CAAC,OAAO,IAAI,CAAC,OAAO,EAAE,CAAC;YAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YAAC,SAAQ;QAAC,CAAC;QACxD,MAAM,OAAO,GAAG,OAAO;YACrB,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;YACvG,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,GAAG,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAA;QAC5C,MAAM,OAAO,GAAG,OAAO;YACrB,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;YACnD,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC,IAAI,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,CAAA;QACxC,KAAK,MAAM,CAAC,IAAI,OAAO;YAAE,KAAK,MAAM,CAAC,IAAI,OAAO;gBAAE,QAAQ,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,IAAI,CAAC,IAAI,EAAE,EAAE,IAAI,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,CAAA;IACtG,CAAC;IACD,yGAAyG;IACzG,kDAAkD;IAClD,KAAK,MAAM,IAAI,IAAI,YAAY,CAAC,MAAM,EAAE;QAAE,QAAQ,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAA;IACtE,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAA;AAC7C,CAAC;AAED,SAAS,iBAAiB,CAAC,QAAc;IACvC,MAAM,WAAW,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,aAAa,CAAC,IAAI,EAAE,CAA2B,CAAA;IACnF,MAAM,GAAG,GAAG,IAAI,GAAG,EAAkB,CAAA;IACrC,KAAK,MAAM,CAAC,KAAK,EAAE,UAAU,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC;QAAE,GAAG,CAAC,GAAG,CAAC,UAAU,EAAE,KAAK,CAAC,CAAA;IACzF,OAAO,GAAG,CAAA;AACZ,CAAC;AAED,SAAS,MAAM,CAAC,GAAuB,EAAE,MAAc,EAAE,IAAY;IACnE,MAAM,CAAC,GAAG,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,MAAM,CAAC,MAAM,CAAC,CAAC,CAAA;IAChE,OAAO,CAAC,EAAE,IAAI,KAAK,IAAI,CAAA;AACzB,CAAC"}
@@ -0,0 +1,27 @@
1
+ import type { Graph, Node, Edge } from './graph.js';
2
+ import type { NodeId } from './ids.js';
3
+ /** Nodes with an edge INTO `id` (its upstream dependencies). De-duplicated. */
4
+ export declare function incomers(graph: Graph, id: NodeId): Node[];
5
+ /** Nodes with an edge OUT of `id` (its downstream consumers). De-duplicated. */
6
+ export declare function outgoers(graph: Graph, id: NodeId): Node[];
7
+ /** Edges touching `id`. `direction` filters to incoming (`in`) or outgoing (`out`); omit for both. */
8
+ export declare function connectedEdges(graph: Graph, id: NodeId, direction?: 'in' | 'out'): Edge[];
9
+ /** Nodes with no incoming edges (sources). */
10
+ export declare function roots(graph: Graph): Node[];
11
+ /** Nodes with no outgoing edges (sinks). */
12
+ export declare function leaves(graph: Graph): Node[];
13
+ /** The set of node ids reachable from `start` by following outgoing edges (the active downstream
14
+ * chain), including `start` itself. Cycle-safe. A host runtime uses this to decide which nodes are
15
+ * actually "live": when an edge is cut or a node deleted, everything past the break drops out of
16
+ * the set, so downstream nodes can stop playing / stop showing as running. */
17
+ export declare function reachableFrom(graph: Graph, start: NodeId): Set<NodeId>;
18
+ /** Kahn topological sort. `order` lists node ids so every edge goes earlier→later; `cyclic` holds
19
+ * the ids that couldn't be ordered because they sit in (or downstream of) a cycle. */
20
+ export declare function topoOrder(graph: Graph): {
21
+ order: NodeId[];
22
+ cyclic: NodeId[];
23
+ };
24
+ /** Would adding an edge `from → to` introduce a cycle? True if `from === to`, or a path already
25
+ * leads from `to` back to `from`. Handy for an `isValidConnection` rule that forbids cycles. */
26
+ export declare function wouldCreateCycle(graph: Graph, from: NodeId, to: NodeId): boolean;
27
+ //# sourceMappingURL=traversal.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"traversal.d.ts","sourceRoot":"","sources":["../src/traversal.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,YAAY,CAAA;AACnD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,UAAU,CAAA;AAEtC,+EAA+E;AAC/E,wBAAgB,QAAQ,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE,EAAE,MAAM,GAAG,IAAI,EAAE,CAEzD;AAED,gFAAgF;AAChF,wBAAgB,QAAQ,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE,EAAE,MAAM,GAAG,IAAI,EAAE,CAEzD;AAgBD,sGAAsG;AACtG,wBAAgB,cAAc,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,IAAI,GAAG,KAAK,GAAG,IAAI,EAAE,CASzF;AAED,8CAA8C;AAC9C,wBAAgB,KAAK,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI,EAAE,CAE1C;AAED,4CAA4C;AAC5C,wBAAgB,MAAM,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI,EAAE,CAE3C;AAED;;;+EAG+E;AAC/E,wBAAgB,aAAa,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,CAWtE;AAED;uFACuF;AACvF,wBAAgB,SAAS,CAAC,KAAK,EAAE,KAAK,GAAG;IAAE,KAAK,EAAE,MAAM,EAAE,CAAC;IAAC,MAAM,EAAE,MAAM,EAAE,CAAA;CAAE,CAuB7E;AAED;iGACiG;AACjG,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAYhF"}
@@ -0,0 +1,119 @@
1
+ /** Nodes with an edge INTO `id` (its upstream dependencies). De-duplicated. */
2
+ export function incomers(graph, id) {
3
+ return neighbours(graph, id, 'in');
4
+ }
5
+ /** Nodes with an edge OUT of `id` (its downstream consumers). De-duplicated. */
6
+ export function outgoers(graph, id) {
7
+ return neighbours(graph, id, 'out');
8
+ }
9
+ function neighbours(graph, id, dir) {
10
+ const seen = new Set();
11
+ const out = [];
12
+ for (const e of graph.edges()) {
13
+ const hit = dir === 'in' ? e.to.node === id : e.from.node === id;
14
+ if (!hit)
15
+ continue;
16
+ const otherId = dir === 'in' ? e.from.node : e.to.node;
17
+ if (seen.has(otherId))
18
+ continue;
19
+ const n = graph.getNode(otherId);
20
+ if (n) {
21
+ seen.add(otherId);
22
+ out.push(n);
23
+ }
24
+ }
25
+ return out;
26
+ }
27
+ /** Edges touching `id`. `direction` filters to incoming (`in`) or outgoing (`out`); omit for both. */
28
+ export function connectedEdges(graph, id, direction) {
29
+ const out = [];
30
+ for (const e of graph.edges()) {
31
+ const isIn = e.to.node === id, isOut = e.from.node === id;
32
+ if ((direction === 'in' && isIn) || (direction === 'out' && isOut) || (!direction && (isIn || isOut))) {
33
+ out.push(e);
34
+ }
35
+ }
36
+ return out;
37
+ }
38
+ /** Nodes with no incoming edges (sources). */
39
+ export function roots(graph) {
40
+ return [...graph.nodes()].filter((n) => connectedEdges(graph, n.id, 'in').length === 0);
41
+ }
42
+ /** Nodes with no outgoing edges (sinks). */
43
+ export function leaves(graph) {
44
+ return [...graph.nodes()].filter((n) => connectedEdges(graph, n.id, 'out').length === 0);
45
+ }
46
+ /** The set of node ids reachable from `start` by following outgoing edges (the active downstream
47
+ * chain), including `start` itself. Cycle-safe. A host runtime uses this to decide which nodes are
48
+ * actually "live": when an edge is cut or a node deleted, everything past the break drops out of
49
+ * the set, so downstream nodes can stop playing / stop showing as running. */
50
+ export function reachableFrom(graph, start) {
51
+ const seen = new Set();
52
+ if (!graph.hasNode(start))
53
+ return seen;
54
+ const stack = [start];
55
+ while (stack.length > 0) {
56
+ const id = stack.pop();
57
+ if (seen.has(id))
58
+ continue;
59
+ seen.add(id);
60
+ for (const n of outgoers(graph, id))
61
+ if (!seen.has(n.id))
62
+ stack.push(n.id);
63
+ }
64
+ return seen;
65
+ }
66
+ /** Kahn topological sort. `order` lists node ids so every edge goes earlier→later; `cyclic` holds
67
+ * the ids that couldn't be ordered because they sit in (or downstream of) a cycle. */
68
+ export function topoOrder(graph) {
69
+ const indegree = new Map();
70
+ const outAdj = new Map();
71
+ for (const n of graph.nodes()) {
72
+ indegree.set(n.id, 0);
73
+ outAdj.set(n.id, []);
74
+ }
75
+ for (const e of graph.edges()) {
76
+ if (!indegree.has(e.from.node) || !indegree.has(e.to.node))
77
+ continue;
78
+ indegree.set(e.to.node, (indegree.get(e.to.node) ?? 0) + 1);
79
+ outAdj.get(e.from.node).push(e.to.node);
80
+ }
81
+ const queue = [];
82
+ for (const [id, deg] of indegree)
83
+ if (deg === 0)
84
+ queue.push(id);
85
+ const order = [];
86
+ while (queue.length) {
87
+ const id = queue.shift();
88
+ order.push(id);
89
+ for (const next of outAdj.get(id)) {
90
+ const d = (indegree.get(next) ?? 0) - 1;
91
+ indegree.set(next, d);
92
+ if (d === 0)
93
+ queue.push(next);
94
+ }
95
+ }
96
+ const cyclic = [...indegree].filter(([, d]) => d > 0).map(([id]) => id);
97
+ return { order, cyclic };
98
+ }
99
+ /** Would adding an edge `from → to` introduce a cycle? True if `from === to`, or a path already
100
+ * leads from `to` back to `from`. Handy for an `isValidConnection` rule that forbids cycles. */
101
+ export function wouldCreateCycle(graph, from, to) {
102
+ if (from === to)
103
+ return true;
104
+ const stack = [to];
105
+ const seen = new Set();
106
+ while (stack.length) {
107
+ const id = stack.pop();
108
+ if (id === from)
109
+ return true;
110
+ if (seen.has(id))
111
+ continue;
112
+ seen.add(id);
113
+ for (const e of graph.edges())
114
+ if (e.from.node === id)
115
+ stack.push(e.to.node);
116
+ }
117
+ return false;
118
+ }
119
+ //# sourceMappingURL=traversal.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"traversal.js","sourceRoot":"","sources":["../src/traversal.ts"],"names":[],"mappings":"AAMA,+EAA+E;AAC/E,MAAM,UAAU,QAAQ,CAAC,KAAY,EAAE,EAAU;IAC/C,OAAO,UAAU,CAAC,KAAK,EAAE,EAAE,EAAE,IAAI,CAAC,CAAA;AACpC,CAAC;AAED,gFAAgF;AAChF,MAAM,UAAU,QAAQ,CAAC,KAAY,EAAE,EAAU;IAC/C,OAAO,UAAU,CAAC,KAAK,EAAE,EAAE,EAAE,KAAK,CAAC,CAAA;AACrC,CAAC;AAED,SAAS,UAAU,CAAC,KAAY,EAAE,EAAU,EAAE,GAAiB;IAC7D,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAA;IAC9B,MAAM,GAAG,GAAW,EAAE,CAAA;IACtB,KAAK,MAAM,CAAC,IAAI,KAAK,CAAC,KAAK,EAAE,EAAE,CAAC;QAC9B,MAAM,GAAG,GAAG,GAAG,KAAK,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,KAAK,EAAE,CAAA;QAChE,IAAI,CAAC,GAAG;YAAE,SAAQ;QAClB,MAAM,OAAO,GAAG,GAAG,KAAK,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAA;QACtD,IAAI,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC;YAAE,SAAQ;QAC/B,MAAM,CAAC,GAAG,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,CAAA;QAChC,IAAI,CAAC,EAAE,CAAC;YAAC,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;YAAC,GAAG,CAAC,IAAI,CAAC,CAAS,CAAC,CAAA;QAAC,CAAC;IACnD,CAAC;IACD,OAAO,GAAG,CAAA;AACZ,CAAC;AAED,sGAAsG;AACtG,MAAM,UAAU,cAAc,CAAC,KAAY,EAAE,EAAU,EAAE,SAAwB;IAC/E,MAAM,GAAG,GAAW,EAAE,CAAA;IACtB,KAAK,MAAM,CAAC,IAAI,KAAK,CAAC,KAAK,EAAE,EAAE,CAAC;QAC9B,MAAM,IAAI,GAAG,CAAC,CAAC,EAAE,CAAC,IAAI,KAAK,EAAE,EAAE,KAAK,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,KAAK,EAAE,CAAA;QACzD,IAAI,CAAC,SAAS,KAAK,IAAI,IAAI,IAAI,CAAC,IAAI,CAAC,SAAS,KAAK,KAAK,IAAI,KAAK,CAAC,IAAI,CAAC,CAAC,SAAS,IAAI,CAAC,IAAI,IAAI,KAAK,CAAC,CAAC,EAAE,CAAC;YACtG,GAAG,CAAC,IAAI,CAAC,CAAS,CAAC,CAAA;QACrB,CAAC;IACH,CAAC;IACD,OAAO,GAAG,CAAA;AACZ,CAAC;AAED,8CAA8C;AAC9C,MAAM,UAAU,KAAK,CAAC,KAAY;IAChC,OAAO,CAAC,GAAG,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,cAAc,CAAC,KAAK,EAAE,CAAC,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC,CAAW,CAAA;AACnG,CAAC;AAED,4CAA4C;AAC5C,MAAM,UAAU,MAAM,CAAC,KAAY;IACjC,OAAO,CAAC,GAAG,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,cAAc,CAAC,KAAK,EAAE,CAAC,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC,MAAM,KAAK,CAAC,CAAW,CAAA;AACpG,CAAC;AAED;;;+EAG+E;AAC/E,MAAM,UAAU,aAAa,CAAC,KAAY,EAAE,KAAa;IACvD,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAA;IAC9B,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QAAE,OAAO,IAAI,CAAA;IACtC,MAAM,KAAK,GAAa,CAAC,KAAK,CAAC,CAAA;IAC/B,OAAO,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACxB,MAAM,EAAE,GAAG,KAAK,CAAC,GAAG,EAAG,CAAA;QACvB,IAAI,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;YAAE,SAAQ;QAC1B,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;QACZ,KAAK,MAAM,CAAC,IAAI,QAAQ,CAAC,KAAK,EAAE,EAAE,CAAC;YAAE,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;gBAAE,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAA;IAC5E,CAAC;IACD,OAAO,IAAI,CAAA;AACb,CAAC;AAED;uFACuF;AACvF,MAAM,UAAU,SAAS,CAAC,KAAY;IACpC,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAkB,CAAA;IAC1C,MAAM,MAAM,GAAG,IAAI,GAAG,EAAoB,CAAA;IAC1C,KAAK,MAAM,CAAC,IAAI,KAAK,CAAC,KAAK,EAAE,EAAE,CAAC;QAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;QAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAA;IAAC,CAAC;IAC9E,KAAK,MAAM,CAAC,IAAI,KAAK,CAAC,KAAK,EAAE,EAAE,CAAC;QAC9B,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC;YAAE,SAAQ;QACpE,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAA;QAC3D,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAE,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAA;IAC1C,CAAC;IACD,MAAM,KAAK,GAAa,EAAE,CAAA;IAC1B,KAAK,MAAM,CAAC,EAAE,EAAE,GAAG,CAAC,IAAI,QAAQ;QAAE,IAAI,GAAG,KAAK,CAAC;YAAE,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;IAC/D,MAAM,KAAK,GAAa,EAAE,CAAA;IAC1B,OAAO,KAAK,CAAC,MAAM,EAAE,CAAC;QACpB,MAAM,EAAE,GAAG,KAAK,CAAC,KAAK,EAAG,CAAA;QACzB,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;QACd,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,GAAG,CAAC,EAAE,CAAE,EAAE,CAAC;YACnC,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAA;YACvC,QAAQ,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC,CAAA;YACrB,IAAI,CAAC,KAAK,CAAC;gBAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QAC/B,CAAC;IACH,CAAC;IACD,MAAM,MAAM,GAAG,CAAC,GAAG,QAAQ,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,CAAA;IACvE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,CAAA;AAC1B,CAAC;AAED;iGACiG;AACjG,MAAM,UAAU,gBAAgB,CAAC,KAAY,EAAE,IAAY,EAAE,EAAU;IACrE,IAAI,IAAI,KAAK,EAAE;QAAE,OAAO,IAAI,CAAA;IAC5B,MAAM,KAAK,GAAa,CAAC,EAAE,CAAC,CAAA;IAC5B,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAA;IAC9B,OAAO,KAAK,CAAC,MAAM,EAAE,CAAC;QACpB,MAAM,EAAE,GAAG,KAAK,CAAC,GAAG,EAAG,CAAA;QACvB,IAAI,EAAE,KAAK,IAAI;YAAE,OAAO,IAAI,CAAA;QAC5B,IAAI,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;YAAE,SAAQ;QAC1B,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;QACZ,KAAK,MAAM,CAAC,IAAI,KAAK,CAAC,KAAK,EAAE;YAAE,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,KAAK,EAAE;gBAAE,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAA;IAC9E,CAAC;IACD,OAAO,KAAK,CAAA;AACd,CAAC"}
@@ -0,0 +1,41 @@
1
+ /** A custom pin data-type the host declares: its colour, optional shape, and extra compatibility.
2
+ * Consumed by both connection validation (`canConnect`) and the renderer (pin fill/stroke). */
3
+ export interface TypeDescriptor {
4
+ id: string;
5
+ color: string;
6
+ shape?: 'circle' | 'diamond' | 'arrow';
7
+ /** Types this one may also connect to, beyond an exact id match. Honoured symmetrically. */
8
+ compatibleWith?: string[];
9
+ }
10
+ /** A directional conversion `from → to`. Applied to values flowing across an edge when the OUT
11
+ * pin's type differs from the IN pin's type. Pure — the same input should always yield the same
12
+ * output. Throwing is allowed (signals an invalid value at runtime) — the editor doesn't catch. */
13
+ export type ConversionFn = (value: unknown) => unknown;
14
+ /** Registry of {@link TypeDescriptor}s. Pure, zero-dep — the editor owns one instance and hands it
15
+ * to `canConnect` and the renderer so custom typed pins get correct colours and connection rules. */
16
+ export declare class TypeRegistry {
17
+ #private;
18
+ get size(): number;
19
+ register(desc: TypeDescriptor): void;
20
+ unregister(id: string): boolean;
21
+ clear(): void;
22
+ has(id: string): boolean;
23
+ get(id: string): TypeDescriptor | undefined;
24
+ all(): TypeDescriptor[];
25
+ /** Register a value-coercion function applied when an OUT pin of type `from` connects to an IN
26
+ * pin of type `to`. Directional — call again with swapped args for the reverse direction.
27
+ * Replaces any prior fn for the same pair. */
28
+ registerConversion(from: string, to: string, fn: ConversionFn): void;
29
+ unregisterConversion(from: string, to: string): boolean;
30
+ hasConversion(from: string, to: string): boolean;
31
+ getConversion(from: string, to: string): ConversionFn | undefined;
32
+ /** Apply the conversion `from → to` to `value`. Identity when `from === to`. Throws when no
33
+ * conversion is registered (use `hasConversion` first if you need to choose at runtime). */
34
+ convert(value: unknown, from: string, to: string): unknown;
35
+ /** Are two pin types connectable by type? True on exact match, or if either descriptor lists the
36
+ * other in `compatibleWith` (symmetric), or if EITHER direction has a registered conversion.
37
+ * Returning true for either-direction conversion keeps `canConnect` orientation-agnostic — the
38
+ * actual cast is applied per-direction at value-flow time using `convert(from, to)`. */
39
+ compatible(a: string, b: string): boolean;
40
+ }
41
+ //# sourceMappingURL=types-registry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types-registry.d.ts","sourceRoot":"","sources":["../src/types-registry.ts"],"names":[],"mappings":"AAAA;gGACgG;AAChG,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAA;IACV,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,CAAC,EAAE,QAAQ,GAAG,SAAS,GAAG,OAAO,CAAA;IACtC,4FAA4F;IAC5F,cAAc,CAAC,EAAE,MAAM,EAAE,CAAA;CAC1B;AAED;;oGAEoG;AACpG,MAAM,MAAM,YAAY,GAAG,CAAC,KAAK,EAAE,OAAO,KAAK,OAAO,CAAA;AAEtD;sGACsG;AACtG,qBAAa,YAAY;;IAOvB,IAAI,IAAI,IAAI,MAAM,CAAkC;IAEpD,QAAQ,CAAC,IAAI,EAAE,cAAc,GAAG,IAAI;IACpC,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO;IAC/B,KAAK,IAAI,IAAI;IAMb,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO;IACxB,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,cAAc,GAAG,SAAS;IAC3C,GAAG,IAAI,cAAc,EAAE;IAIvB;;mDAE+C;IAC/C,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,YAAY,GAAG,IAAI;IAGpE,oBAAoB,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO;IAGvD,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO;IAGhD,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,YAAY,GAAG,SAAS;IAGjE;iGAC6F;IAC7F,OAAO,CAAC,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO;IAO1D;;;6FAGyF;IACzF,UAAU,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,OAAO;CAM1C"}
@@ -0,0 +1,60 @@
1
+ /** Registry of {@link TypeDescriptor}s. Pure, zero-dep — the editor owns one instance and hands it
2
+ * to `canConnect` and the renderer so custom typed pins get correct colours and connection rules. */
3
+ export class TypeRegistry {
4
+ #descriptors = new Map();
5
+ // Conversions are keyed `${from}→${to}` to make lookup O(1) and direction explicit. Symmetry
6
+ // (`from→to` does NOT imply `to→from`) matters: a `number→text` cast is well-defined; the
7
+ // reverse needs its own parse with its own failure mode.
8
+ #conversions = new Map();
9
+ get size() { return this.#descriptors.size; }
10
+ register(desc) { this.#descriptors.set(desc.id, desc); }
11
+ unregister(id) { return this.#descriptors.delete(id); }
12
+ clear() {
13
+ this.#descriptors.clear();
14
+ // Conversions are tied to the type pairs they bridge — clearing types clears conversions too,
15
+ // otherwise stale entries would silently lift `compatible()` for types that no longer exist.
16
+ this.#conversions.clear();
17
+ }
18
+ has(id) { return this.#descriptors.has(id); }
19
+ get(id) { return this.#descriptors.get(id); }
20
+ all() { return [...this.#descriptors.values()]; }
21
+ // ---- conversions (G2 — type-driven value coercion across an edge) ----------------------------
22
+ /** Register a value-coercion function applied when an OUT pin of type `from` connects to an IN
23
+ * pin of type `to`. Directional — call again with swapped args for the reverse direction.
24
+ * Replaces any prior fn for the same pair. */
25
+ registerConversion(from, to, fn) {
26
+ this.#conversions.set(`${from}${to}`, fn);
27
+ }
28
+ unregisterConversion(from, to) {
29
+ return this.#conversions.delete(`${from}${to}`);
30
+ }
31
+ hasConversion(from, to) {
32
+ return this.#conversions.has(`${from}${to}`);
33
+ }
34
+ getConversion(from, to) {
35
+ return this.#conversions.get(`${from}${to}`);
36
+ }
37
+ /** Apply the conversion `from → to` to `value`. Identity when `from === to`. Throws when no
38
+ * conversion is registered (use `hasConversion` first if you need to choose at runtime). */
39
+ convert(value, from, to) {
40
+ if (from === to)
41
+ return value;
42
+ const fn = this.#conversions.get(`${from}${to}`);
43
+ if (!fn)
44
+ throw new Error(`TypeRegistry: no conversion registered for ${from} → ${to}`);
45
+ return fn(value);
46
+ }
47
+ /** Are two pin types connectable by type? True on exact match, or if either descriptor lists the
48
+ * other in `compatibleWith` (symmetric), or if EITHER direction has a registered conversion.
49
+ * Returning true for either-direction conversion keeps `canConnect` orientation-agnostic — the
50
+ * actual cast is applied per-direction at value-flow time using `convert(from, to)`. */
51
+ compatible(a, b) {
52
+ if (a === b)
53
+ return true;
54
+ if ((this.#descriptors.get(a)?.compatibleWith?.includes(b) ?? false) ||
55
+ (this.#descriptors.get(b)?.compatibleWith?.includes(a) ?? false))
56
+ return true;
57
+ return this.hasConversion(a, b) || this.hasConversion(b, a);
58
+ }
59
+ }
60
+ //# sourceMappingURL=types-registry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types-registry.js","sourceRoot":"","sources":["../src/types-registry.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,141 @@
1
+ import type { Node } from './graph.js';
2
+ /** Declarative in-node UI control. Widgets are pure DATA — rendering and interaction live in the
3
+ * render/editor layers. A widget's value is stored in `node.state[key]` (single source of truth),
4
+ * so it serialises with the node and mutates through the command bus (undoable). `button` carries
5
+ * an action name instead of a value; `custom` defers to a host-registered renderer. */
6
+ export type WidgetType = 'number' | 'slider' | 'combo' | 'text' | 'toggle' | 'button' | 'color' | 'custom';
7
+ export type ComboOption = string | {
8
+ label: string;
9
+ value: string | number;
10
+ };
11
+ /** Per-widget visual override. Any field set here wins over the theme's widget tokens for THIS
12
+ * widget only — so every widget instance is fully customisable without touching the theme. */
13
+ export interface WidgetStyle {
14
+ bg?: string;
15
+ bgHover?: string;
16
+ bgFocused?: string;
17
+ track?: string;
18
+ fill?: string;
19
+ fillAlpha?: number;
20
+ text?: string;
21
+ label?: string;
22
+ placeholder?: string;
23
+ border?: string;
24
+ borderFocused?: string;
25
+ selection?: string;
26
+ knob?: string;
27
+ radius?: number;
28
+ paddingX?: number;
29
+ paddingY?: number;
30
+ borderWidth?: number;
31
+ toggleWidth?: number;
32
+ toggleHeight?: number;
33
+ }
34
+ interface WidgetBase {
35
+ id: string;
36
+ label: string;
37
+ /** Key into `node.state` holding the value. Absent for `button`. Also doubles as the implicit
38
+ * pin-binding key (see `pinKey`) — most schemas don't need to set `pinKey` manually if the
39
+ * widget's `key` matches a data IN-pin's `label` / `id`. */
40
+ key?: string;
41
+ disabled?: boolean;
42
+ hint?: string;
43
+ /** Per-widget visual override, merged over the theme's widget tokens. */
44
+ style?: WidgetStyle;
45
+ /** Override the implicit `key`-based pin match. Matched against a data IN-pin's `label` (schema
46
+ * authors can't predict auto-minted pin ids), then by pin `id` (loaded graphs serialize ids).
47
+ * Almost never needed — leave unset and use the same `key` on widget and pin. */
48
+ pinKey?: string;
49
+ /** Render-time visibility against the bound pin:
50
+ * - `'whenDisconnected'` (default for input controls — number/slider/text/combo/toggle/color):
51
+ * UE-Blueprint default-value behaviour. Widget visible only while the pin has no edge;
52
+ * connecting hides it (the pin's wire becomes the value source).
53
+ * - `'always'`: display/preview behaviour. Widget always visible regardless of pin state;
54
+ * when the pin has a wire, the widget reads the runtime's LIVE value and renders read-only.
55
+ * Default for `custom` widgets — most custom controls are visualisations. */
56
+ visibility?: 'whenDisconnected' | 'always';
57
+ /** Opt-in: include this widget in the editor's properties sidebar when one is open for the
58
+ * containing node (G4 — Baklava `displayInSidebar` parity). The SAME widget renders both
59
+ * inline on the node and in the sidebar — no separate component to author. Default: omit
60
+ * (widget appears only inline). */
61
+ showInSidebar?: boolean;
62
+ /** Declarative conditional rendering keyed off OTHER widgets' values in the same node (n8n
63
+ * `displayOptions.show` parity). `show(state)` is evaluated against `node.state` after every
64
+ * `setWidgetValue` — return `false` to hide the widget (renderer skips layout, sidebar skips
65
+ * the row). Fails OPEN if the callback throws (a schema bug must not blank the node). */
66
+ displayOptions?: {
67
+ show?: (state: Readonly<Record<string, unknown>>) => boolean;
68
+ };
69
+ /** Render this widget as a body-band row even if there's no matching pin. Use for node-level
70
+ * config fields that aren't connectable from outside (HTTP body, secret tokens, schema editor)
71
+ * — they get a full-width row under the pin band. Without this, non-custom orphan widgets are
72
+ * silently dropped. Always combines with `displayOptions.show`: hidden widgets disappear
73
+ * entirely, no leftover pin row. */
74
+ freeFloating?: boolean;
75
+ }
76
+ export type WidgetSpec = (WidgetBase & {
77
+ type: 'number';
78
+ key: string;
79
+ min?: number;
80
+ max?: number;
81
+ step?: number;
82
+ precision?: number;
83
+ unit?: string;
84
+ }) | (WidgetBase & {
85
+ type: 'slider';
86
+ key: string;
87
+ min: number;
88
+ max: number;
89
+ step?: number;
90
+ }) | (WidgetBase & {
91
+ type: 'combo';
92
+ key: string;
93
+ values: ComboOption[];
94
+ }) | (WidgetBase & {
95
+ type: 'text';
96
+ key: string;
97
+ multiline?: boolean;
98
+ placeholder?: string;
99
+ maxLength?: number;
100
+ }) | (WidgetBase & {
101
+ type: 'toggle';
102
+ key: string;
103
+ onLabel?: string;
104
+ offLabel?: string;
105
+ }) | (WidgetBase & {
106
+ type: 'button';
107
+ action: string;
108
+ }) | (WidgetBase & {
109
+ type: 'color';
110
+ key: string;
111
+ }) | (WidgetBase & {
112
+ type: 'custom';
113
+ renderer: string;
114
+ key: string;
115
+ height?: number;
116
+ });
117
+ export interface ComboOptionResolved {
118
+ label: string;
119
+ value: string | number;
120
+ }
121
+ export declare function comboOptions(spec: Extract<WidgetSpec, {
122
+ type: 'combo';
123
+ }>): ComboOptionResolved[];
124
+ export declare function defaultWidgetValue(spec: WidgetSpec): unknown;
125
+ export declare function clampWidgetValue(spec: WidgetSpec, raw: unknown): unknown;
126
+ /** Current value of a widget on a node: the clamped `node.state[key]`, or its default. */
127
+ export declare function widgetValue(node: Node, spec: WidgetSpec): unknown;
128
+ /** Effective widget visibility policy. ALL widget types default to `'whenDisconnected'` — they're
129
+ * input controls that the user sets a value for, and connecting a wire makes the widget's value
130
+ * redundant. Display/preview widgets (e.g. an Output node's value readout) opt into `'always'`
131
+ * explicitly. `button` widgets aren't pin-bound — they live in the actions row. */
132
+ export declare function widgetVisibility(spec: WidgetSpec): 'whenDisconnected' | 'always';
133
+ /** Resolve `displayOptions.show(state)` against a node — true (visible) unless the callback exists
134
+ * and explicitly returns false. Defensive: a throwing callback fails OPEN so a schema bug doesn't
135
+ * blank the node entirely. */
136
+ export declare function widgetIsVisible(spec: WidgetSpec, node: Node): boolean;
137
+ /** The lookup key used to bind a widget to its pin: explicit `pinKey`, else the widget's `key`.
138
+ * Returns undefined for widgets that don't bind to a pin (`button` — actions, not values). */
139
+ export declare function widgetBindKey(spec: WidgetSpec): string | undefined;
140
+ export {};
141
+ //# sourceMappingURL=widget.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"widget.d.ts","sourceRoot":"","sources":["../src/widget.ts"],"names":[],"mappings":"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"}