@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
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 strelok2012
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,55 @@
1
+ # @xenolithengine/graph-core
2
+
3
+ [![BETA](https://img.shields.io/badge/status-BETA-FCB400?style=flat-square)](https://github.com/XenolithEngine/xenolith-graph#status)
4
+ [![MIT](https://img.shields.io/badge/license-MIT-FCB400?style=flat-square)](https://github.com/XenolithEngine/xenolith-graph/blob/main/LICENSE)
5
+
6
+ Headless graph model, type system, command bus, and event emitter for XenolithGraph. Zero runtime dependencies.
7
+
8
+ > **Beta** — public API in `STABLE-API.md` is the surface we plan to freeze, but it is **NOT frozen yet** — breaking changes can land at any point before v1.0. If you adopt now, pin an exact version.
9
+
10
+ Part of [XenolithGraph](https://github.com/XenolithEngine/xenolith-graph) — an AI-native, embeddable node-graph editor for the web with its own visual design language (Xen).
11
+
12
+ ## Install
13
+
14
+ ```bash
15
+ pnpm add @xenolithengine/graph-core
16
+ ```
17
+
18
+ Zero runtime dependencies. Pure ESM, TypeScript-first.
19
+
20
+ ## Usage
21
+
22
+ ```ts
23
+ import { Graph, CommandBus, AddNode, ConnectPins, createNodeId } from '@xenolithengine/graph-core'
24
+
25
+ const graph = new Graph()
26
+ const bus = new CommandBus({ graph })
27
+
28
+ const a = createNodeId()
29
+ const b = createNodeId()
30
+
31
+ bus.apply(new AddNode({ id: a, type: 'math.add', position: { x: 0, y: 0 }, pins: [] }))
32
+ bus.apply(new AddNode({ id: b, type: 'math.mul', position: { x: 200, y: 0 }, pins: [] }))
33
+
34
+ bus.undo() // removes b
35
+ bus.redo() // re-adds b
36
+ ```
37
+
38
+ ## What's exported
39
+
40
+ - `Graph` — node/edge/comment store; `Node`, `Edge`, `Pin`, `Comment` types
41
+ - `CommandBus` + commands: `AddNode`, `RemoveNode`, `ConnectPins`, `DisconnectEdge`, `MoveNode`, `ResizeNode`, `SetNodeState`, `SetNodePins`, `SetNodeWidgets`, `AddComment`, `RemoveComment`, `MoveComment`, `ResizeComment`, `SetCommentText`
42
+ - `Selection` — selection model with `SelectionMode`
43
+ - `NodeRegistry`, `TypeRegistry` — schemas + type compatibility
44
+ - Traversal: `incomers`, `outgoers`, `topoOrder`, `wouldCreateCycle`, `reachableFrom`, `connectedEdges`, `roots`, `leaves`
45
+ - Templates & macros: `MACRO_TYPE`, `createMacro`, `planMacroCollapse`, `planMacroExpand`, `templateInterface`, `materializeInterface`, `planTemplateExtraction`, `planTemplateUnpack`, `flattenTemplateInstance`
46
+ - Widgets: `defaultWidgetValue`, `widgetValue`, `clampWidgetValue`, `widgetIsVisible`; `WidgetSpec`, `WidgetType`
47
+ - `EventEmitter`, `fuzzyMatch`, ID helpers (`createNodeId`, `createEdgeId`, `createPinId`, `createCommentId`, `createTypeId`, `isUuidV7`)
48
+
49
+ ## Docs
50
+
51
+ - [Full guide](https://xenolithengine.github.io/xenolith-graph/guides/api/) — top-level architecture
52
+ - [API reference](https://xenolithengine.github.io/xenolith-graph/guides/api/) — every method exposed by `XenolithEditor`
53
+ - [GitHub](https://github.com/XenolithEngine/xenolith-graph)
54
+
55
+ MIT © XenolithEngine
@@ -0,0 +1,56 @@
1
+ import type { EventEmitter } from './event-emitter.js';
2
+ import type { Graph } from './graph.js';
3
+ export interface CommandContext {
4
+ graph: Graph;
5
+ events: EventEmitter<CoreEvents>;
6
+ }
7
+ export interface Command<T = unknown> {
8
+ readonly type: string;
9
+ apply(ctx: CommandContext): T;
10
+ undo(ctx: CommandContext, applied: T): void;
11
+ }
12
+ export type CoreEvents = {
13
+ 'command:applied': {
14
+ command: Command<unknown>;
15
+ result: unknown;
16
+ };
17
+ 'command:undone': {
18
+ command: Command<unknown>;
19
+ };
20
+ 'command:redone': {
21
+ command: Command<unknown>;
22
+ };
23
+ 'transaction:committed': {
24
+ commands: Command<unknown>[];
25
+ };
26
+ 'transaction:reverted': {
27
+ commands: Command<unknown>[];
28
+ };
29
+ };
30
+ export interface CommandBusOptions {
31
+ /** Maximum number of undo entries to retain. Older entries are dropped when exceeded. */
32
+ maxHistory?: number;
33
+ }
34
+ export declare class CommandBus {
35
+ #private;
36
+ constructor(ctx: CommandContext, opts?: CommandBusOptions);
37
+ apply<T>(command: Command<T>): T;
38
+ /** Open a manual undo group: subsequent applies collapse into one entry until `endGroup()` or
39
+ * the idle timer fires. Re-entrant: a second call while a group is open is a no-op (does NOT
40
+ * reset the buffer). `idleTimeoutMs > 0` auto-flushes after that many ms of inactivity
41
+ * (every apply resets the timer); `0` means "explicit endGroup only". */
42
+ beginGroup(opts?: {
43
+ label?: string;
44
+ idleTimeoutMs?: number;
45
+ }): void;
46
+ /** Close the active group. No-op if none open. Empty group leaves history untouched (no
47
+ * zero-command entry). Idempotent — calling twice is safe. */
48
+ endGroup(): void;
49
+ undo(): boolean;
50
+ redo(): boolean;
51
+ canUndo(): boolean;
52
+ canRedo(): boolean;
53
+ transaction<R>(fn: () => R): R;
54
+ clearHistory(): void;
55
+ }
56
+ //# sourceMappingURL=command-bus.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"command-bus.d.ts","sourceRoot":"","sources":["../src/command-bus.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AACtD,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAA;AAEvC,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,KAAK,CAAA;IACZ,MAAM,EAAE,YAAY,CAAC,UAAU,CAAC,CAAA;CACjC;AAED,MAAM,WAAW,OAAO,CAAC,CAAC,GAAG,OAAO;IAClC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,KAAK,CAAC,GAAG,EAAE,cAAc,GAAG,CAAC,CAAA;IAC7B,IAAI,CAAC,GAAG,EAAE,cAAc,EAAE,OAAO,EAAE,CAAC,GAAG,IAAI,CAAA;CAC5C;AAED,MAAM,MAAM,UAAU,GAAG;IACvB,iBAAiB,EAAQ;QAAE,OAAO,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC;QAAC,MAAM,EAAE,OAAO,CAAA;KAAE,CAAA;IACvE,gBAAgB,EAAS;QAAE,OAAO,EAAE,OAAO,CAAC,OAAO,CAAC,CAAA;KAAE,CAAA;IACtD,gBAAgB,EAAS;QAAE,OAAO,EAAE,OAAO,CAAC,OAAO,CAAC,CAAA;KAAE,CAAA;IACtD,uBAAuB,EAAE;QAAE,QAAQ,EAAE,OAAO,CAAC,OAAO,CAAC,EAAE,CAAA;KAAE,CAAA;IACzD,sBAAsB,EAAG;QAAE,QAAQ,EAAE,OAAO,CAAC,OAAO,CAAC,EAAE,CAAA;KAAE,CAAA;CAC1D,CAAA;AAWD,MAAM,WAAW,iBAAiB;IAChC,yFAAyF;IACzF,UAAU,CAAC,EAAE,MAAM,CAAA;CACpB;AAED,qBAAa,UAAU;;gBAgBT,GAAG,EAAE,cAAc,EAAE,IAAI,GAAE,iBAAsB;IAK7D,KAAK,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC;IAkBhC;;;8EAG0E;IAC1E,UAAU,CAAC,IAAI,GAAE;QAAE,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,aAAa,CAAC,EAAE,MAAM,CAAA;KAAO,GAAG,IAAI;IAQvE;mEAC+D;IAC/D,QAAQ,IAAI,IAAI;IAsBhB,IAAI,IAAI,OAAO;IAcf,IAAI,IAAI,OAAO;IAcf,OAAO,IAAI,OAAO;IAClB,OAAO,IAAI,OAAO;IAElB,WAAW,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,CAAC,GAAG,CAAC;IAyC9B,YAAY,IAAI,IAAI;CA2BrB"}
@@ -0,0 +1,180 @@
1
+ export class CommandBus {
2
+ #ctx;
3
+ #maxHistory;
4
+ #log = [];
5
+ #cursor = 0;
6
+ #txBuffer = null;
7
+ // Open group (G10 — Baklava rete-history-plugin parity). Unlike a transaction (synchronous
8
+ // scope via a fn), a group spans multiple top-level apply() calls and is closed either by an
9
+ // explicit `endGroup()` OR by an idle timer (every apply resets it). All applies between
10
+ // beginGroup → endGroup commit as ONE undo entry, even when interleaved with caller code
11
+ // returning to the event loop (drag-move per-frame ticks, rapid widget edits, etc.).
12
+ #groupBuffer = null;
13
+ #groupLabel = undefined;
14
+ #groupIdleMs = 0;
15
+ #groupTimer = null;
16
+ constructor(ctx, opts = {}) {
17
+ this.#ctx = ctx;
18
+ this.#maxHistory = opts.maxHistory ?? Number.POSITIVE_INFINITY;
19
+ }
20
+ apply(command) {
21
+ const result = command.apply(this.#ctx);
22
+ const applied = { command: command, result };
23
+ if (this.#txBuffer) {
24
+ this.#txBuffer.push(applied);
25
+ }
26
+ else if (this.#groupBuffer) {
27
+ this.#groupBuffer.push(applied);
28
+ this.#bumpGroupIdle();
29
+ }
30
+ else {
31
+ this.#truncateRedo();
32
+ this.#log.push({ kind: 'single', entry: applied });
33
+ this.#cursor++;
34
+ this.#enforceHistoryBound();
35
+ }
36
+ this.#ctx.events.emit('command:applied', { command: applied.command, result });
37
+ return result;
38
+ }
39
+ /** Open a manual undo group: subsequent applies collapse into one entry until `endGroup()` or
40
+ * the idle timer fires. Re-entrant: a second call while a group is open is a no-op (does NOT
41
+ * reset the buffer). `idleTimeoutMs > 0` auto-flushes after that many ms of inactivity
42
+ * (every apply resets the timer); `0` means "explicit endGroup only". */
43
+ beginGroup(opts = {}) {
44
+ if (this.#groupBuffer || this.#txBuffer)
45
+ return;
46
+ this.#groupBuffer = [];
47
+ this.#groupLabel = opts.label;
48
+ this.#groupIdleMs = opts.idleTimeoutMs ?? 0;
49
+ this.#bumpGroupIdle();
50
+ }
51
+ /** Close the active group. No-op if none open. Empty group leaves history untouched (no
52
+ * zero-command entry). Idempotent — calling twice is safe. */
53
+ endGroup() {
54
+ if (!this.#groupBuffer)
55
+ return;
56
+ const buffer = this.#groupBuffer;
57
+ this.#groupBuffer = null;
58
+ this.#groupLabel = undefined;
59
+ this.#groupIdleMs = 0;
60
+ if (this.#groupTimer) {
61
+ clearTimeout(this.#groupTimer);
62
+ this.#groupTimer = null;
63
+ }
64
+ if (buffer.length === 0)
65
+ return;
66
+ this.#truncateRedo();
67
+ this.#log.push({ kind: 'tx', entries: buffer });
68
+ this.#cursor++;
69
+ this.#enforceHistoryBound();
70
+ this.#ctx.events.emit('transaction:committed', { commands: buffer.map((e) => e.command) });
71
+ }
72
+ /** Auto-flush group after inactivity. Setting groupIdleMs:0 (or no timer source) opts out. */
73
+ #bumpGroupIdle() {
74
+ if (this.#groupIdleMs <= 0)
75
+ return;
76
+ if (this.#groupTimer)
77
+ clearTimeout(this.#groupTimer);
78
+ this.#groupTimer = setTimeout(() => { this.endGroup(); }, this.#groupIdleMs);
79
+ }
80
+ undo() {
81
+ if (!this.canUndo())
82
+ return false;
83
+ this.#cursor--;
84
+ const entry = this.#log[this.#cursor];
85
+ if (entry.kind === 'single') {
86
+ this.#undoOne(entry.entry);
87
+ }
88
+ else {
89
+ for (let i = entry.entries.length - 1; i >= 0; i--) {
90
+ this.#undoOne(entry.entries[i]);
91
+ }
92
+ }
93
+ return true;
94
+ }
95
+ redo() {
96
+ if (!this.canRedo())
97
+ return false;
98
+ const entry = this.#log[this.#cursor];
99
+ // Advance the cursor before re-applying so listeners observing command:redone read a consistent
100
+ // canUndo/canRedo (mirrors undo(), which decrements first). #redoOne doesn't depend on the cursor.
101
+ this.#cursor++;
102
+ if (entry.kind === 'single') {
103
+ this.#redoOne(entry.entry);
104
+ }
105
+ else {
106
+ for (const e of entry.entries)
107
+ this.#redoOne(e);
108
+ }
109
+ return true;
110
+ }
111
+ canUndo() { return this.#cursor > 0; }
112
+ canRedo() { return this.#cursor < this.#log.length; }
113
+ transaction(fn) {
114
+ // Nested transactions join the outer one — commands accumulate in the same buffer, and the
115
+ // OUTERMOST call is the only one that commits or reverts. Lets a high-level multi-step
116
+ // operation (e.g. macro→template) call into building-block methods that each open a transaction
117
+ // and still produce a SINGLE undoable history entry. Inner errors propagate so the outermost
118
+ // handler rolls everything back atomically.
119
+ if (this.#txBuffer) {
120
+ return fn();
121
+ }
122
+ // A group is the outer scope when one's open — fold the transaction's applies into the
123
+ // group buffer so endGroup() commits everything as ONE history entry. apply() already
124
+ // routes to #groupBuffer when no #txBuffer exists.
125
+ if (this.#groupBuffer) {
126
+ return fn();
127
+ }
128
+ const buffer = [];
129
+ this.#txBuffer = buffer;
130
+ try {
131
+ const result = fn();
132
+ this.#txBuffer = null;
133
+ if (buffer.length === 0)
134
+ return result;
135
+ this.#truncateRedo();
136
+ this.#log.push({ kind: 'tx', entries: buffer });
137
+ this.#cursor++;
138
+ this.#enforceHistoryBound();
139
+ this.#ctx.events.emit('transaction:committed', { commands: buffer.map((e) => e.command) });
140
+ return result;
141
+ }
142
+ catch (err) {
143
+ this.#txBuffer = null;
144
+ for (let i = buffer.length - 1; i >= 0; i--) {
145
+ try {
146
+ this.#undoOne(buffer[i]);
147
+ }
148
+ catch {
149
+ // continue rollback even if a single undo throws
150
+ }
151
+ }
152
+ this.#ctx.events.emit('transaction:reverted', { commands: buffer.map((e) => e.command) });
153
+ throw err;
154
+ }
155
+ }
156
+ clearHistory() {
157
+ this.#log.length = 0;
158
+ this.#cursor = 0;
159
+ }
160
+ #truncateRedo() {
161
+ if (this.#cursor < this.#log.length) {
162
+ this.#log.length = this.#cursor;
163
+ }
164
+ }
165
+ #enforceHistoryBound() {
166
+ while (this.#log.length > this.#maxHistory) {
167
+ this.#log.shift();
168
+ this.#cursor--;
169
+ }
170
+ }
171
+ #undoOne(applied) {
172
+ applied.command.undo(this.#ctx, applied.result);
173
+ this.#ctx.events.emit('command:undone', { command: applied.command });
174
+ }
175
+ #redoOne(applied) {
176
+ applied.result = applied.command.apply(this.#ctx);
177
+ this.#ctx.events.emit('command:redone', { command: applied.command });
178
+ }
179
+ }
180
+ //# sourceMappingURL=command-bus.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"command-bus.js","sourceRoot":"","sources":["../src/command-bus.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,52 @@
1
+ import type { Command, CommandContext } from './command-bus.js';
2
+ import type { Comment, Vec2 } from './graph.js';
3
+ import type { CommentId } from './ids.js';
4
+ export declare class AddComment implements Command<void> {
5
+ readonly comment: Comment;
6
+ readonly type = "AddComment";
7
+ constructor(comment: Comment);
8
+ apply(ctx: CommandContext): void;
9
+ undo(ctx: CommandContext): void;
10
+ }
11
+ export declare class RemoveComment implements Command<Comment> {
12
+ readonly commentId: CommentId;
13
+ readonly type = "RemoveComment";
14
+ constructor(commentId: CommentId);
15
+ apply(ctx: CommandContext): Comment;
16
+ undo(ctx: CommandContext, removed: Comment): void;
17
+ }
18
+ export declare class MoveComment implements Command<Vec2> {
19
+ #private;
20
+ readonly commentId: CommentId;
21
+ readonly type = "MoveComment";
22
+ constructor(commentId: CommentId, target: Vec2);
23
+ apply(ctx: CommandContext): Vec2;
24
+ undo(ctx: CommandContext, old: Vec2): void;
25
+ }
26
+ export declare class ResizeComment implements Command<Vec2> {
27
+ #private;
28
+ readonly commentId: CommentId;
29
+ readonly type = "ResizeComment";
30
+ constructor(commentId: CommentId, target: Vec2);
31
+ apply(ctx: CommandContext): Vec2;
32
+ undo(ctx: CommandContext, old: Vec2): void;
33
+ }
34
+ export declare class SetCommentText implements Command<{
35
+ text: string;
36
+ color: string | undefined;
37
+ }> {
38
+ readonly commentId: CommentId;
39
+ private readonly text;
40
+ private readonly color?;
41
+ readonly type = "SetCommentText";
42
+ constructor(commentId: CommentId, text: string, color?: string | undefined);
43
+ apply(ctx: CommandContext): {
44
+ text: string;
45
+ color: string | undefined;
46
+ };
47
+ undo(ctx: CommandContext, old: {
48
+ text: string;
49
+ color: string | undefined;
50
+ }): void;
51
+ }
52
+ //# sourceMappingURL=commands-comment.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"commands-comment.d.ts","sourceRoot":"","sources":["../src/commands-comment.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAA;AAC/D,OAAO,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,YAAY,CAAA;AAC/C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,UAAU,CAAA;AAEzC,qBAAa,UAAW,YAAW,OAAO,CAAC,IAAI,CAAC;IAElC,QAAQ,CAAC,OAAO,EAAE,OAAO;IADrC,QAAQ,CAAC,IAAI,gBAAe;gBACP,OAAO,EAAE,OAAO;IAErC,KAAK,CAAC,GAAG,EAAE,cAAc,GAAG,IAAI;IAIhC,IAAI,CAAC,GAAG,EAAE,cAAc,GAAG,IAAI;CAGhC;AAED,qBAAa,aAAc,YAAW,OAAO,CAAC,OAAO,CAAC;IAExC,QAAQ,CAAC,SAAS,EAAE,SAAS;IADzC,QAAQ,CAAC,IAAI,mBAAkB;gBACV,SAAS,EAAE,SAAS;IAEzC,KAAK,CAAC,GAAG,EAAE,cAAc,GAAG,OAAO;IAMnC,IAAI,CAAC,GAAG,EAAE,cAAc,EAAE,OAAO,EAAE,OAAO,GAAG,IAAI;CAGlD;AAED,qBAAa,WAAY,YAAW,OAAO,CAAC,IAAI,CAAC;;IAGnC,QAAQ,CAAC,SAAS,EAAE,SAAS;IAFzC,QAAQ,CAAC,IAAI,iBAAgB;gBAER,SAAS,EAAE,SAAS,EAAE,MAAM,EAAE,IAAI;IAIvD,KAAK,CAAC,GAAG,EAAE,cAAc,GAAG,IAAI;IAQhC,IAAI,CAAC,GAAG,EAAE,cAAc,EAAE,GAAG,EAAE,IAAI,GAAG,IAAI;CAG3C;AAED,qBAAa,aAAc,YAAW,OAAO,CAAC,IAAI,CAAC;;IAGrC,QAAQ,CAAC,SAAS,EAAE,SAAS;IAFzC,QAAQ,CAAC,IAAI,mBAAkB;gBAEV,SAAS,EAAE,SAAS,EAAE,MAAM,EAAE,IAAI;IAIvD,KAAK,CAAC,GAAG,EAAE,cAAc,GAAG,IAAI;IAQhC,IAAI,CAAC,GAAG,EAAE,cAAc,EAAE,GAAG,EAAE,IAAI,GAAG,IAAI;CAG3C;AAED,qBAAa,cAAe,YAAW,OAAO,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,GAAG,SAAS,CAAA;CAAE,CAAC;IAGvF,QAAQ,CAAC,SAAS,EAAE,SAAS;IAC7B,OAAO,CAAC,QAAQ,CAAC,IAAI;IACrB,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC;IAJzB,QAAQ,CAAC,IAAI,oBAAmB;gBAErB,SAAS,EAAE,SAAS,EACZ,IAAI,EAAE,MAAM,EACZ,KAAK,CAAC,EAAE,MAAM,YAAA;IAGjC,KAAK,CAAC,GAAG,EAAE,cAAc,GAAG;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,GAAG,SAAS,CAAA;KAAE;IAQvE,IAAI,CAAC,GAAG,EAAE,cAAc,EAAE,GAAG,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,GAAG,SAAS,CAAA;KAAE,GAAG,IAAI;CAGlF"}
@@ -0,0 +1,92 @@
1
+ export class AddComment {
2
+ comment;
3
+ type = 'AddComment';
4
+ constructor(comment) {
5
+ this.comment = comment;
6
+ }
7
+ apply(ctx) {
8
+ ctx.graph._addComment(this.comment);
9
+ }
10
+ undo(ctx) {
11
+ ctx.graph._removeComment(this.comment.id);
12
+ }
13
+ }
14
+ export class RemoveComment {
15
+ commentId;
16
+ type = 'RemoveComment';
17
+ constructor(commentId) {
18
+ this.commentId = commentId;
19
+ }
20
+ apply(ctx) {
21
+ const removed = ctx.graph._removeComment(this.commentId);
22
+ if (!removed)
23
+ throw new Error(`RemoveComment: comment not found: ${this.commentId}`);
24
+ return removed;
25
+ }
26
+ undo(ctx, removed) {
27
+ ctx.graph._addComment(removed);
28
+ }
29
+ }
30
+ export class MoveComment {
31
+ commentId;
32
+ type = 'MoveComment';
33
+ #target;
34
+ constructor(commentId, target) {
35
+ this.commentId = commentId;
36
+ this.#target = { x: target.x, y: target.y };
37
+ }
38
+ apply(ctx) {
39
+ const c = ctx.graph.getComment(this.commentId);
40
+ if (!c)
41
+ throw new Error(`MoveComment: comment not found: ${this.commentId}`);
42
+ const old = { x: c.position.x, y: c.position.y };
43
+ ctx.graph._patchComment(this.commentId, { position: { x: this.#target.x, y: this.#target.y } });
44
+ return old;
45
+ }
46
+ undo(ctx, old) {
47
+ ctx.graph._patchComment(this.commentId, { position: old });
48
+ }
49
+ }
50
+ export class ResizeComment {
51
+ commentId;
52
+ type = 'ResizeComment';
53
+ #target;
54
+ constructor(commentId, target) {
55
+ this.commentId = commentId;
56
+ this.#target = { x: target.x, y: target.y };
57
+ }
58
+ apply(ctx) {
59
+ const c = ctx.graph.getComment(this.commentId);
60
+ if (!c)
61
+ throw new Error(`ResizeComment: comment not found: ${this.commentId}`);
62
+ const old = { x: c.size.x, y: c.size.y };
63
+ ctx.graph._patchComment(this.commentId, { size: { x: this.#target.x, y: this.#target.y } });
64
+ return old;
65
+ }
66
+ undo(ctx, old) {
67
+ ctx.graph._patchComment(this.commentId, { size: old });
68
+ }
69
+ }
70
+ export class SetCommentText {
71
+ commentId;
72
+ text;
73
+ color;
74
+ type = 'SetCommentText';
75
+ constructor(commentId, text, color) {
76
+ this.commentId = commentId;
77
+ this.text = text;
78
+ this.color = color;
79
+ }
80
+ apply(ctx) {
81
+ const c = ctx.graph.getComment(this.commentId);
82
+ if (!c)
83
+ throw new Error(`SetCommentText: comment not found: ${this.commentId}`);
84
+ const old = { text: c.text, color: c.color };
85
+ ctx.graph._patchComment(this.commentId, { text: this.text, ...(this.color !== undefined ? { color: this.color } : {}) });
86
+ return old;
87
+ }
88
+ undo(ctx, old) {
89
+ ctx.graph._patchComment(this.commentId, { text: old.text, ...(old.color !== undefined ? { color: old.color } : {}) });
90
+ }
91
+ }
92
+ //# sourceMappingURL=commands-comment.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"commands-comment.js","sourceRoot":"","sources":["../src/commands-comment.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,58 @@
1
+ import type { Command, CommandContext } from './command-bus.js';
2
+ import type { Edge, Pin, Vec2 } from './graph.js';
3
+ import type { NodeId } from './ids.js';
4
+ import type { WidgetSpec } from './widget.js';
5
+ export declare class MoveNode implements Command<Vec2> {
6
+ #private;
7
+ readonly nodeId: NodeId;
8
+ readonly type = "MoveNode";
9
+ constructor(nodeId: NodeId, target: Vec2);
10
+ apply(ctx: CommandContext): Vec2;
11
+ undo(ctx: CommandContext, old: Vec2): void;
12
+ }
13
+ export declare class ResizeNode implements Command<Vec2 | undefined> {
14
+ #private;
15
+ private readonly nodeId;
16
+ readonly type = "ResizeNode";
17
+ constructor(nodeId: NodeId, target: Vec2);
18
+ apply(ctx: CommandContext): Vec2 | undefined;
19
+ undo(ctx: CommandContext, old: Vec2 | undefined): void;
20
+ }
21
+ export declare class SetNodeState implements Command<Record<string, unknown>> {
22
+ private readonly nodeId;
23
+ private readonly partial;
24
+ readonly type = "SetNodeState";
25
+ constructor(nodeId: NodeId, partial: Record<string, unknown>);
26
+ apply(ctx: CommandContext): Record<string, unknown>;
27
+ undo(ctx: CommandContext, old: Record<string, unknown>): void;
28
+ }
29
+ export interface SetNodePinsUndo {
30
+ pins: Pin[];
31
+ prunedEdges: Edge[];
32
+ }
33
+ /** Replace a node's pin list wholesale (variadic pins: Sequence/MakeArray "+", Branch true/false).
34
+ * Edges incident to a pin that no longer exists are pruned and restored on undo. */
35
+ export declare class SetNodePins implements Command<SetNodePinsUndo> {
36
+ #private;
37
+ private readonly nodeId;
38
+ readonly type = "SetNodePins";
39
+ constructor(nodeId: NodeId, pins: Pin[]);
40
+ apply(ctx: CommandContext): SetNodePinsUndo;
41
+ undo(ctx: CommandContext, applied: SetNodePinsUndo): void;
42
+ }
43
+ export interface SetNodeWidgetsUndo {
44
+ widgets: WidgetSpec[] | undefined;
45
+ }
46
+ /** Replace a node's widget list wholesale. Used by runtime plugins to synthesise widgets in
47
+ * response to schema changes (e.g. `@xenolithengine/graph-plugin-runtime`'s Schema-node flow that derives a
48
+ * Struct's editable fields from a wired Schema). Per-widget `state[key]` values survive removal,
49
+ * so re-adding a widget under the same key picks up the previously typed value. */
50
+ export declare class SetNodeWidgets implements Command<SetNodeWidgetsUndo> {
51
+ #private;
52
+ private readonly nodeId;
53
+ readonly type = "SetNodeWidgets";
54
+ constructor(nodeId: NodeId, widgets: WidgetSpec[] | undefined);
55
+ apply(ctx: CommandContext): SetNodeWidgetsUndo;
56
+ undo(ctx: CommandContext, applied: SetNodeWidgetsUndo): void;
57
+ }
58
+ //# sourceMappingURL=commands-mut.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"commands-mut.d.ts","sourceRoot":"","sources":["../src/commands-mut.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAA;AAC/D,OAAO,KAAK,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,YAAY,CAAA;AACjD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,UAAU,CAAA;AACtC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AAE7C,qBAAa,QAAS,YAAW,OAAO,CAAC,IAAI,CAAC;;IAI1C,QAAQ,CAAC,MAAM,EAAE,MAAM;IAHzB,QAAQ,CAAC,IAAI,cAAa;gBAGf,MAAM,EAAE,MAAM,EACvB,MAAM,EAAE,IAAI;IAKd,KAAK,CAAC,GAAG,EAAE,cAAc,GAAG,IAAI;IAQhC,IAAI,CAAC,GAAG,EAAE,cAAc,EAAE,GAAG,EAAE,IAAI,GAAG,IAAI;CAG3C;AAED,qBAAa,UAAW,YAAW,OAAO,CAAC,IAAI,GAAG,SAAS,CAAC;;IAIxD,OAAO,CAAC,QAAQ,CAAC,MAAM;IAHzB,QAAQ,CAAC,IAAI,gBAAe;gBAGT,MAAM,EAAE,MAAM,EAC/B,MAAM,EAAE,IAAI;IAKd,KAAK,CAAC,GAAG,EAAE,cAAc,GAAG,IAAI,GAAG,SAAS;IAQ5C,IAAI,CAAC,GAAG,EAAE,cAAc,EAAE,GAAG,EAAE,IAAI,GAAG,SAAS,GAAG,IAAI;CAGvD;AAED,qBAAa,YAAa,YAAW,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAGjE,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,OAAO;IAH1B,QAAQ,CAAC,IAAI,kBAAiB;gBAEX,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAGnD,KAAK,CAAC,GAAG,EAAE,cAAc,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAQnD,IAAI,CAAC,GAAG,EAAE,cAAc,EAAE,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;CAG9D;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,GAAG,EAAE,CAAA;IACX,WAAW,EAAE,IAAI,EAAE,CAAA;CACpB;AAED;qFACqF;AACrF,qBAAa,WAAY,YAAW,OAAO,CAAC,eAAe,CAAC;;IAIxD,OAAO,CAAC,QAAQ,CAAC,MAAM;IAHzB,QAAQ,CAAC,IAAI,iBAAgB;gBAGV,MAAM,EAAE,MAAM,EAC/B,IAAI,EAAE,GAAG,EAAE;IAKb,KAAK,CAAC,GAAG,EAAE,cAAc,GAAG,eAAe;IAiB3C,IAAI,CAAC,GAAG,EAAE,cAAc,EAAE,OAAO,EAAE,eAAe,GAAG,IAAI;CAI1D;AAED,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,UAAU,EAAE,GAAG,SAAS,CAAA;CAClC;AAED;;;oFAGoF;AACpF,qBAAa,cAAe,YAAW,OAAO,CAAC,kBAAkB,CAAC;;IAI9D,OAAO,CAAC,QAAQ,CAAC,MAAM;IAHzB,QAAQ,CAAC,IAAI,oBAAmB;gBAGb,MAAM,EAAE,MAAM,EAC/B,OAAO,EAAE,UAAU,EAAE,GAAG,SAAS;IAKnC,KAAK,CAAC,GAAG,EAAE,cAAc,GAAG,kBAAkB;IAQ9C,IAAI,CAAC,GAAG,EAAE,cAAc,EAAE,OAAO,EAAE,kBAAkB,GAAG,IAAI;CAG7D"}