pixifact 0.1.3

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 (168) hide show
  1. package/README.md +44 -0
  2. package/dist/authoring/ActionRegistry.d.ts +10 -0
  3. package/dist/authoring/ActionRegistry.js +26 -0
  4. package/dist/authoring/ComponentPalette.d.ts +16 -0
  5. package/dist/authoring/ComponentPalette.js +50 -0
  6. package/dist/authoring/DesignToken.d.ts +16 -0
  7. package/dist/authoring/DesignToken.js +33 -0
  8. package/dist/authoring/DiffModel.d.ts +10 -0
  9. package/dist/authoring/DiffModel.js +104 -0
  10. package/dist/authoring/InspectorModel.d.ts +27 -0
  11. package/dist/authoring/InspectorModel.js +139 -0
  12. package/dist/authoring/LogicGraph.d.ts +66 -0
  13. package/dist/authoring/LogicGraph.js +184 -0
  14. package/dist/authoring/OverrideJournal.d.ts +18 -0
  15. package/dist/authoring/OverrideJournal.js +23 -0
  16. package/dist/authoring/PreferenceMemory.d.ts +21 -0
  17. package/dist/authoring/PreferenceMemory.js +39 -0
  18. package/dist/authoring/ProjectConfig.d.ts +20 -0
  19. package/dist/authoring/ProjectConfig.js +78 -0
  20. package/dist/authoring/RuntimePreview.d.ts +11 -0
  21. package/dist/authoring/RuntimePreview.js +25 -0
  22. package/dist/authoring/SceneDocument.d.ts +74 -0
  23. package/dist/authoring/SceneDocument.js +332 -0
  24. package/dist/authoring/SceneProjectState.d.ts +20 -0
  25. package/dist/authoring/SceneProjectState.js +8 -0
  26. package/dist/authoring/SceneSelection.d.ts +11 -0
  27. package/dist/authoring/SceneSelection.js +1 -0
  28. package/dist/authoring/index.d.ts +13 -0
  29. package/dist/authoring/index.js +13 -0
  30. package/dist/commands/Command.d.ts +63 -0
  31. package/dist/commands/Command.js +1 -0
  32. package/dist/commands/CommandStack.d.ts +14 -0
  33. package/dist/commands/CommandStack.js +45 -0
  34. package/dist/commands/applyCommand.d.ts +23 -0
  35. package/dist/commands/applyCommand.js +316 -0
  36. package/dist/commands/index.d.ts +4 -0
  37. package/dist/commands/index.js +4 -0
  38. package/dist/commands/utils.d.ts +17 -0
  39. package/dist/commands/utils.js +77 -0
  40. package/dist/commands/validateCommand.d.ts +12 -0
  41. package/dist/commands/validateCommand.js +285 -0
  42. package/dist/compiler/commands/index.d.ts +109 -0
  43. package/dist/compiler/commands/index.js +492 -0
  44. package/dist/compiler/compileScenes.d.ts +11 -0
  45. package/dist/compiler/compileScenes.js +220 -0
  46. package/dist/compiler/decorators.d.ts +6 -0
  47. package/dist/compiler/decorators.js +79 -0
  48. package/dist/compiler/eventRuntime.d.ts +8 -0
  49. package/dist/compiler/eventRuntime.js +29 -0
  50. package/dist/compiler/index.d.ts +14 -0
  51. package/dist/compiler/index.js +14 -0
  52. package/dist/compiler/pixiNodeSchema.d.ts +39 -0
  53. package/dist/compiler/pixiNodeSchema.js +267 -0
  54. package/dist/compiler/sceneAssetPair.d.ts +11 -0
  55. package/dist/compiler/sceneAssetPair.js +92 -0
  56. package/dist/compiler/scenePartValidation.d.ts +6 -0
  57. package/dist/compiler/scenePartValidation.js +24 -0
  58. package/dist/compiler/sceneRuntime.d.ts +13 -0
  59. package/dist/compiler/sceneRuntime.js +22 -0
  60. package/dist/compiler/sceneValidation.d.ts +48 -0
  61. package/dist/compiler/sceneValidation.js +383 -0
  62. package/dist/compiler/scriptInterfaceExtractor.d.ts +6 -0
  63. package/dist/compiler/scriptInterfaceExtractor.js +258 -0
  64. package/dist/compiler/slotRuntime.d.ts +3 -0
  65. package/dist/compiler/slotRuntime.js +17 -0
  66. package/dist/compiler/spec.d.ts +95 -0
  67. package/dist/compiler/spec.js +1 -0
  68. package/dist/compiler/templateParser.d.ts +2 -0
  69. package/dist/compiler/templateParser.js +302 -0
  70. package/dist/compiler/templateSerializer.d.ts +2 -0
  71. package/dist/compiler/templateSerializer.js +101 -0
  72. package/dist/compiler/typescriptCompiler.d.ts +2 -0
  73. package/dist/compiler/typescriptCompiler.js +494 -0
  74. package/dist/compiler-node/index.d.ts +2 -0
  75. package/dist/compiler-node/index.js +2 -0
  76. package/dist/compiler-node/vite.d.ts +8 -0
  77. package/dist/compiler-node/vite.js +21 -0
  78. package/dist/index.d.ts +6 -0
  79. package/dist/index.js +6 -0
  80. package/dist/nodes/Input.d.ts +91 -0
  81. package/dist/nodes/Input.js +352 -0
  82. package/dist/nodes/Textarea.d.ts +10 -0
  83. package/dist/nodes/Textarea.js +38 -0
  84. package/dist/nodes/components/Button.d.ts +8 -0
  85. package/dist/nodes/components/Button.js +45 -0
  86. package/dist/nodes/components/InputField.d.ts +12 -0
  87. package/dist/nodes/components/InputField.js +53 -0
  88. package/dist/nodes/components/ProgressBar.d.ts +14 -0
  89. package/dist/nodes/components/ProgressBar.js +66 -0
  90. package/dist/nodes/components/ScrollRect.d.ts +23 -0
  91. package/dist/nodes/components/ScrollRect.js +108 -0
  92. package/dist/nodes/components/Selectable.d.ts +32 -0
  93. package/dist/nodes/components/Selectable.js +153 -0
  94. package/dist/nodes/components/index.d.ts +5 -0
  95. package/dist/nodes/components/index.js +5 -0
  96. package/dist/nodes/graphics/Graphic.d.ts +14 -0
  97. package/dist/nodes/graphics/Graphic.js +47 -0
  98. package/dist/nodes/graphics/ImageGraphic.d.ts +9 -0
  99. package/dist/nodes/graphics/ImageGraphic.js +42 -0
  100. package/dist/nodes/graphics/RoundedRectGraphic.d.ts +13 -0
  101. package/dist/nodes/graphics/RoundedRectGraphic.js +65 -0
  102. package/dist/nodes/graphics/TextGraphic.d.ts +13 -0
  103. package/dist/nodes/graphics/TextGraphic.js +70 -0
  104. package/dist/nodes/graphics/index.d.ts +4 -0
  105. package/dist/nodes/graphics/index.js +4 -0
  106. package/dist/nodes/index.d.ts +3 -0
  107. package/dist/nodes/index.js +3 -0
  108. package/dist/runtime/Application.d.ts +15 -0
  109. package/dist/runtime/Application.js +67 -0
  110. package/dist/runtime/GameObject.d.ts +100 -0
  111. package/dist/runtime/GameObject.js +297 -0
  112. package/dist/runtime/GameObjectEvent.d.ts +52 -0
  113. package/dist/runtime/GameObjectEvent.js +38 -0
  114. package/dist/runtime/Transform.d.ts +32 -0
  115. package/dist/runtime/Transform.js +157 -0
  116. package/dist/runtime/component/Component.d.ts +13 -0
  117. package/dist/runtime/component/Component.js +13 -0
  118. package/dist/runtime/component/ComponentRegistry.d.ts +49 -0
  119. package/dist/runtime/component/ComponentRegistry.js +25 -0
  120. package/dist/runtime/component/Flex.d.ts +6 -0
  121. package/dist/runtime/component/Flex.js +15 -0
  122. package/dist/runtime/component/FlexGroup.d.ts +26 -0
  123. package/dist/runtime/component/FlexGroup.js +136 -0
  124. package/dist/runtime/component/GridLayout.d.ts +47 -0
  125. package/dist/runtime/component/GridLayout.js +129 -0
  126. package/dist/runtime/component/Layout.d.ts +104 -0
  127. package/dist/runtime/component/Layout.js +248 -0
  128. package/dist/runtime/component/decorators.d.ts +4 -0
  129. package/dist/runtime/component/decorators.js +52 -0
  130. package/dist/runtime/component/index.d.ts +7 -0
  131. package/dist/runtime/component/index.js +7 -0
  132. package/dist/runtime/graphics/index.d.ts +11 -0
  133. package/dist/runtime/graphics/index.js +29 -0
  134. package/dist/runtime/group/index.d.ts +39 -0
  135. package/dist/runtime/group/index.js +102 -0
  136. package/dist/runtime/image/Image.d.ts +19 -0
  137. package/dist/runtime/image/Image.js +60 -0
  138. package/dist/runtime/image/NineSliceImage.d.ts +23 -0
  139. package/dist/runtime/image/NineSliceImage.js +64 -0
  140. package/dist/runtime/image/index.d.ts +2 -0
  141. package/dist/runtime/image/index.js +2 -0
  142. package/dist/runtime/index.d.ts +9 -0
  143. package/dist/runtime/index.js +9 -0
  144. package/dist/runtime/label/Label.d.ts +11 -0
  145. package/dist/runtime/label/Label.js +26 -0
  146. package/dist/runtime/label/LabelStyle.d.ts +3 -0
  147. package/dist/runtime/label/LabelStyle.js +3 -0
  148. package/dist/runtime/label/index.d.ts +2 -0
  149. package/dist/runtime/label/index.js +2 -0
  150. package/dist/runtime/utils/index.d.ts +1 -0
  151. package/dist/runtime/utils/index.js +1 -0
  152. package/dist/runtime/utils/onlyOnceQueueMicrotask.d.ts +1 -0
  153. package/dist/runtime/utils/onlyOnceQueueMicrotask.js +12 -0
  154. package/dist/runtime/utils/setProps.d.ts +10 -0
  155. package/dist/runtime/utils/setProps.js +17 -0
  156. package/dist/scene/dsl.d.ts +25 -0
  157. package/dist/scene/dsl.js +112 -0
  158. package/dist/scene/index.d.ts +5 -0
  159. package/dist/scene/index.js +5 -0
  160. package/dist/scene/instantiate.d.ts +8 -0
  161. package/dist/scene/instantiate.js +208 -0
  162. package/dist/scene/nodesDsl.d.ts +42 -0
  163. package/dist/scene/nodesDsl.js +169 -0
  164. package/dist/scene/spec.d.ts +100 -0
  165. package/dist/scene/spec.js +1 -0
  166. package/dist/scene/templates.d.ts +21 -0
  167. package/dist/scene/templates.js +239 -0
  168. package/package.json +90 -0
@@ -0,0 +1,332 @@
1
+ import EventEmitter from "eventemitter3";
2
+ import { CommandStack } from "../commands/CommandStack.js";
3
+ import { findNode } from "../commands/utils.js";
4
+ import { emptySelection } from "./SceneSelection.js";
5
+ import { buildInspectorModel } from "./InspectorModel.js";
6
+ import { createRuntimePreview, destroyRuntimePreview } from "./RuntimePreview.js";
7
+ import { lockKey } from "./OverrideJournal.js";
8
+ import { createMemorySuggestions } from "./PreferenceMemory.js";
9
+ import { isSceneProjectState } from "./SceneProjectState.js";
10
+ import { upsertAction } from "./ActionRegistry.js";
11
+ import { createLogicGraph, validateLogicGraph } from "./LogicGraph.js";
12
+ function cloneScene(scene) {
13
+ return structuredClone(scene);
14
+ }
15
+ export class SceneDocument {
16
+ scene;
17
+ selection = emptySelection;
18
+ dirty = false;
19
+ emitter = new EventEmitter();
20
+ preview;
21
+ locks = [];
22
+ overrides = [];
23
+ memory = [];
24
+ designTokens;
25
+ actions = [];
26
+ logicGraph = createLogicGraph();
27
+ commandStack = new CommandStack();
28
+ previewContext;
29
+ previewParent;
30
+ constructor(scene) {
31
+ this.scene = cloneScene(scene);
32
+ }
33
+ apply(command, source = 'manual') {
34
+ const result = this.commandStack.execute(this.scene, command, {
35
+ actions: this.actions.length > 0 ? this.actions : undefined,
36
+ });
37
+ if (!result.ok) {
38
+ return result;
39
+ }
40
+ this.recordOverride(result, source);
41
+ this.dirty = true;
42
+ this.ensureSelectionValid();
43
+ this.rebuildPreview();
44
+ this.emitter.emit('changed', result);
45
+ return result;
46
+ }
47
+ addLock(lock) {
48
+ const key = lockKey(lock);
49
+ if (!this.locks.some((item) => lockKey(item) === key)) {
50
+ this.locks.push(lock);
51
+ this.dirty = true;
52
+ }
53
+ }
54
+ removeLock(lock) {
55
+ const key = lockKey(lock);
56
+ const previousLength = this.locks.length;
57
+ this.locks = this.locks.filter((item) => lockKey(item) !== key);
58
+ if (this.locks.length !== previousLength) {
59
+ this.dirty = true;
60
+ }
61
+ }
62
+ getMemorySuggestions() {
63
+ const accepted = new Set(this.memory.map((item) => item.context));
64
+ return createMemorySuggestions(this.overrides)
65
+ .filter((suggestion) => !accepted.has(suggestion.memory.context));
66
+ }
67
+ acceptMemorySuggestion(suggestion) {
68
+ if (!this.memory.some((item) => item.id === suggestion.memory.id || item.context === suggestion.memory.context)) {
69
+ this.memory.push(suggestion.memory);
70
+ this.dirty = true;
71
+ }
72
+ }
73
+ upsertMemory(memory) {
74
+ const existing = this.memory.find((item) => item.id === memory.id);
75
+ if (existing) {
76
+ Object.assign(existing, memory);
77
+ }
78
+ else {
79
+ this.memory.push(memory);
80
+ }
81
+ this.dirty = true;
82
+ }
83
+ setMemoryEnabled(id, enabled) {
84
+ const item = this.memory.find((memory) => memory.id === id);
85
+ if (item && item.enabled !== enabled) {
86
+ item.enabled = enabled;
87
+ this.dirty = true;
88
+ }
89
+ }
90
+ removeMemory(id) {
91
+ const previousLength = this.memory.length;
92
+ this.memory = this.memory.filter((memory) => memory.id !== id);
93
+ if (this.memory.length !== previousLength) {
94
+ this.dirty = true;
95
+ }
96
+ }
97
+ importMemory(memory, replace = false) {
98
+ if (replace) {
99
+ this.memory = structuredClone([...memory]);
100
+ }
101
+ else {
102
+ for (const item of memory) {
103
+ this.upsertMemory({
104
+ ...structuredClone(item),
105
+ source: item.source ?? 'imported',
106
+ });
107
+ }
108
+ }
109
+ this.dirty = true;
110
+ }
111
+ addAction(action) {
112
+ upsertAction(this.actions, action);
113
+ this.dirty = true;
114
+ }
115
+ removeAction(key) {
116
+ const previousLength = this.actions.length;
117
+ this.actions = this.actions.filter((action) => action.key !== key);
118
+ if (this.actions.length !== previousLength) {
119
+ this.dirty = true;
120
+ }
121
+ }
122
+ addLogicFlow(flow) {
123
+ const graph = structuredClone(this.logicGraph);
124
+ const index = graph.flows.findIndex((item) => item.id === flow.id);
125
+ if (index === -1) {
126
+ graph.flows.push(flow);
127
+ }
128
+ else {
129
+ graph.flows[index] = flow;
130
+ }
131
+ const validation = validateLogicGraph(graph, {
132
+ actions: this.actions.length > 0 ? this.actions : undefined,
133
+ scene: this.scene,
134
+ });
135
+ if (!validation.ok) {
136
+ return {
137
+ ok: false,
138
+ errors: validation.errors,
139
+ };
140
+ }
141
+ this.logicGraph = graph;
142
+ this.dirty = true;
143
+ return {
144
+ ok: true,
145
+ graph: this.logicGraph,
146
+ };
147
+ }
148
+ removeLogicFlow(id) {
149
+ const previousLength = this.logicGraph.flows.length;
150
+ this.logicGraph = {
151
+ ...this.logicGraph,
152
+ flows: this.logicGraph.flows.filter((flow) => flow.id !== id),
153
+ };
154
+ if (this.logicGraph.flows.length !== previousLength) {
155
+ this.dirty = true;
156
+ }
157
+ }
158
+ recordOverride(result, source) {
159
+ const command = result.command;
160
+ const inverse = result.inverse;
161
+ if (command.op === 'batch' && inverse.op === 'batch') {
162
+ for (let i = 0; i < command.commands.length; i++) {
163
+ const child = command.commands[i];
164
+ const inverseChild = inverse.commands[inverse.commands.length - 1 - i];
165
+ this.recordOverride({ ok: true, command: child, inverse: inverseChild }, source);
166
+ }
167
+ return;
168
+ }
169
+ if (command.op === 'setNodeProp' && inverse.op === 'setNodeProp') {
170
+ this.overrides.push({
171
+ source,
172
+ target: `${command.node}.${command.prop}`,
173
+ before: inverse.value,
174
+ after: command.value,
175
+ timestamp: Date.now(),
176
+ });
177
+ }
178
+ if (command.op === 'setComponentProp' && inverse.op === 'setComponentProp') {
179
+ this.overrides.push({
180
+ source,
181
+ target: `${command.node}.${command.component}.${command.prop}`,
182
+ before: inverse.value,
183
+ after: command.value,
184
+ timestamp: Date.now(),
185
+ });
186
+ }
187
+ if (command.op === 'setTransform' && inverse.op === 'setTransform') {
188
+ for (const [prop, after] of Object.entries(command.values)) {
189
+ this.overrides.push({
190
+ source,
191
+ target: `${command.node}.transform.${prop}`,
192
+ before: inverse.values[prop],
193
+ after,
194
+ timestamp: Date.now(),
195
+ });
196
+ }
197
+ }
198
+ if (command.op === 'setNodeData' && inverse.op === 'setNodeData') {
199
+ this.overrides.push({
200
+ source,
201
+ target: `${command.node}.${command.field}.${command.prop}`,
202
+ before: inverse.value,
203
+ after: command.value,
204
+ timestamp: Date.now(),
205
+ });
206
+ }
207
+ }
208
+ undo() {
209
+ const result = this.commandStack.undo(this.scene, {
210
+ actions: this.actions.length > 0 ? this.actions : undefined,
211
+ });
212
+ if (result?.ok) {
213
+ this.dirty = true;
214
+ this.ensureSelectionValid();
215
+ this.rebuildPreview();
216
+ this.emitter.emit('changed', result);
217
+ }
218
+ return result;
219
+ }
220
+ redo() {
221
+ const result = this.commandStack.redo(this.scene, {
222
+ actions: this.actions.length > 0 ? this.actions : undefined,
223
+ });
224
+ if (result?.ok) {
225
+ this.dirty = true;
226
+ this.ensureSelectionValid();
227
+ this.rebuildPreview();
228
+ this.emitter.emit('changed', result);
229
+ }
230
+ return result;
231
+ }
232
+ get canUndo() {
233
+ return this.commandStack.canUndo;
234
+ }
235
+ get canRedo() {
236
+ return this.commandStack.canRedo;
237
+ }
238
+ setSelection(selection) {
239
+ this.selection = selection;
240
+ this.emitter.emit('selectionChanged', selection);
241
+ }
242
+ ensureSelectionValid() {
243
+ if (this.selection.type === 'none') {
244
+ return;
245
+ }
246
+ if (!findNode(this.scene, this.selection.node)) {
247
+ this.selection = emptySelection;
248
+ this.emitter.emit('selectionChanged', this.selection);
249
+ }
250
+ }
251
+ serialize() {
252
+ return JSON.stringify(this.scene, null, 2);
253
+ }
254
+ serializeState() {
255
+ return JSON.stringify(this.getState(), null, 2);
256
+ }
257
+ getState() {
258
+ return {
259
+ version: 1,
260
+ type: 'pixifact.aiEditorProject',
261
+ scene: cloneScene(this.scene),
262
+ selection: this.selection,
263
+ designTokens: this.designTokens ? structuredClone(this.designTokens) : undefined,
264
+ actions: structuredClone(this.actions),
265
+ logicGraph: structuredClone(this.logicGraph),
266
+ locks: structuredClone(this.locks),
267
+ overrides: structuredClone(this.overrides),
268
+ memory: structuredClone(this.memory),
269
+ };
270
+ }
271
+ load(json) {
272
+ const parsed = typeof json === 'string'
273
+ ? JSON.parse(json)
274
+ : json;
275
+ if (isSceneProjectState(parsed)) {
276
+ this.loadState(parsed);
277
+ return;
278
+ }
279
+ this.scene = cloneScene(parsed);
280
+ this.selection = emptySelection;
281
+ this.designTokens = undefined;
282
+ this.actions = [];
283
+ this.logicGraph = createLogicGraph();
284
+ this.locks = [];
285
+ this.overrides = [];
286
+ this.memory = [];
287
+ this.ensureSelectionValid();
288
+ this.dirty = false;
289
+ this.commandStack.clear();
290
+ this.rebuildPreview();
291
+ this.emitter.emit('loaded', this.scene);
292
+ }
293
+ loadState(state) {
294
+ this.scene = cloneScene(state.scene);
295
+ this.selection = state.selection ?? emptySelection;
296
+ this.designTokens = state.designTokens ? structuredClone(state.designTokens) : undefined;
297
+ this.actions = structuredClone(state.actions ?? []);
298
+ this.logicGraph = state.logicGraph ? structuredClone(state.logicGraph) : createLogicGraph();
299
+ this.locks = structuredClone(state.locks ?? []);
300
+ this.overrides = structuredClone(state.overrides ?? []);
301
+ this.memory = structuredClone(state.memory ?? []);
302
+ this.ensureSelectionValid();
303
+ this.dirty = false;
304
+ this.commandStack.clear();
305
+ this.rebuildPreview();
306
+ this.emitter.emit('loaded', this.scene);
307
+ this.emitter.emit('selectionChanged', this.selection);
308
+ }
309
+ rebuildPreview(context = this.previewContext, parent = this.previewParent) {
310
+ this.previewContext = context;
311
+ this.previewParent = parent;
312
+ destroyRuntimePreview(this.preview);
313
+ this.preview = createRuntimePreview(this.scene, parent, context);
314
+ this.emitter.emit('previewRebuilt', this.preview);
315
+ return this.preview;
316
+ }
317
+ getInspectorModel(node = this.selection.type === 'none' ? undefined : this.selection.node) {
318
+ if (!node) {
319
+ return undefined;
320
+ }
321
+ return buildInspectorModel(this.scene, node);
322
+ }
323
+ clearPreview() {
324
+ destroyRuntimePreview(this.preview);
325
+ this.preview = undefined;
326
+ this.previewParent = undefined;
327
+ }
328
+ destroy() {
329
+ this.clearPreview();
330
+ this.emitter.removeAllListeners();
331
+ }
332
+ }
@@ -0,0 +1,20 @@
1
+ import type { SceneSpec } from "../scene/index.js";
2
+ import type { DesignTokenSpec } from "./DesignToken.js";
3
+ import type { SceneSelection } from "./SceneSelection.js";
4
+ import type { LockSpec, OverrideSpec } from "./OverrideJournal.js";
5
+ import type { PreferenceMemory } from "./PreferenceMemory.js";
6
+ import type { ActionSpec } from "./ActionRegistry.js";
7
+ import type { LogicGraphSpec } from "./LogicGraph.js";
8
+ export interface SceneProjectState {
9
+ version: 1;
10
+ type: 'pixifact.aiEditorProject';
11
+ scene: SceneSpec;
12
+ selection?: SceneSelection;
13
+ designTokens?: DesignTokenSpec;
14
+ actions: ActionSpec[];
15
+ logicGraph?: LogicGraphSpec;
16
+ locks: LockSpec[];
17
+ overrides: OverrideSpec[];
18
+ memory: PreferenceMemory[];
19
+ }
20
+ export declare function isSceneProjectState(value: unknown): value is SceneProjectState;
@@ -0,0 +1,8 @@
1
+ export function isSceneProjectState(value) {
2
+ return typeof value === 'object'
3
+ && value !== null
4
+ && value.type === 'pixifact.aiEditorProject'
5
+ && value.version === 1
6
+ && typeof value.scene === 'object'
7
+ && value.scene?.type === 'scene';
8
+ }
@@ -0,0 +1,11 @@
1
+ export type SceneSelection = {
2
+ type: 'none';
3
+ } | {
4
+ type: 'node';
5
+ node: string;
6
+ } | {
7
+ type: 'component';
8
+ node: string;
9
+ component: string;
10
+ };
11
+ export declare const emptySelection: SceneSelection;
@@ -0,0 +1 @@
1
+ export const emptySelection = { type: 'none' };
@@ -0,0 +1,13 @@
1
+ export * from './SceneSelection.js';
2
+ export * from './SceneDocument.js';
3
+ export * from './RuntimePreview.js';
4
+ export * from './InspectorModel.js';
5
+ export * from './DesignToken.js';
6
+ export * from './DiffModel.js';
7
+ export * from './OverrideJournal.js';
8
+ export * from './PreferenceMemory.js';
9
+ export * from './SceneProjectState.js';
10
+ export * from './ComponentPalette.js';
11
+ export * from './ActionRegistry.js';
12
+ export * from './LogicGraph.js';
13
+ export * from './ProjectConfig.js';
@@ -0,0 +1,13 @@
1
+ export * from './SceneSelection.js';
2
+ export * from './SceneDocument.js';
3
+ export * from './RuntimePreview.js';
4
+ export * from './InspectorModel.js';
5
+ export * from './DesignToken.js';
6
+ export * from './DiffModel.js';
7
+ export * from './OverrideJournal.js';
8
+ export * from './PreferenceMemory.js';
9
+ export * from './SceneProjectState.js';
10
+ export * from './ComponentPalette.js';
11
+ export * from './ActionRegistry.js';
12
+ export * from './LogicGraph.js';
13
+ export * from './ProjectConfig.js';
@@ -0,0 +1,63 @@
1
+ import type { ComponentSpec, NodeSpec, RectTransformSpec, SceneNodeKind } from "../scene/index.js";
2
+ export interface SetNodePropCommand {
3
+ op: 'setNodeProp';
4
+ node: string;
5
+ prop: 'id' | 'key' | 'role' | 'name';
6
+ value: string | undefined;
7
+ }
8
+ export interface SetTransformCommand {
9
+ op: 'setTransform';
10
+ node: string;
11
+ values: Partial<RectTransformSpec>;
12
+ }
13
+ export interface SetNodeDataCommand {
14
+ op: 'setNodeData';
15
+ node: string;
16
+ field: Exclude<SceneNodeKind, 'container'>;
17
+ prop: string;
18
+ value: unknown;
19
+ }
20
+ export interface SetComponentPropCommand {
21
+ op: 'setComponentProp';
22
+ node: string;
23
+ component: string;
24
+ prop: string;
25
+ value: unknown;
26
+ }
27
+ export interface AddComponentCommand {
28
+ op: 'addComponent';
29
+ node: string;
30
+ component: ComponentSpec;
31
+ index?: number;
32
+ }
33
+ export interface RemoveComponentCommand {
34
+ op: 'removeComponent';
35
+ node: string;
36
+ component: string;
37
+ }
38
+ export interface CreateNodeCommand {
39
+ op: 'createNode';
40
+ parent?: string;
41
+ node: NodeSpec;
42
+ index?: number;
43
+ }
44
+ export interface DeleteNodeCommand {
45
+ op: 'deleteNode';
46
+ node: string;
47
+ }
48
+ export interface ReparentNodeCommand {
49
+ op: 'reparentNode';
50
+ node: string;
51
+ parent?: string;
52
+ index?: number;
53
+ }
54
+ export interface ReorderNodeCommand {
55
+ op: 'reorderNode';
56
+ node: string;
57
+ index: number;
58
+ }
59
+ export interface BatchCommand {
60
+ op: 'batch';
61
+ commands: SceneCommand[];
62
+ }
63
+ export type SceneCommand = SetNodePropCommand | SetTransformCommand | SetNodeDataCommand | SetComponentPropCommand | AddComponentCommand | RemoveComponentCommand | CreateNodeCommand | DeleteNodeCommand | ReparentNodeCommand | ReorderNodeCommand | BatchCommand;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,14 @@
1
+ import type { SceneSpec } from "../scene/index.js";
2
+ import type { CommandResult } from "./applyCommand.js";
3
+ import type { SceneCommand } from "./Command.js";
4
+ import type { CommandValidationContext } from "./validateCommand.js";
5
+ export declare class CommandStack {
6
+ private undoStack;
7
+ private redoStack;
8
+ get canUndo(): boolean;
9
+ get canRedo(): boolean;
10
+ execute(scene: SceneSpec, command: SceneCommand, context?: CommandValidationContext): CommandResult;
11
+ undo(scene: SceneSpec, context?: CommandValidationContext): CommandResult | undefined;
12
+ redo(scene: SceneSpec, context?: CommandValidationContext): CommandResult | undefined;
13
+ clear(): void;
14
+ }
@@ -0,0 +1,45 @@
1
+ import { applyCommand } from "./applyCommand.js";
2
+ export class CommandStack {
3
+ undoStack = [];
4
+ redoStack = [];
5
+ get canUndo() {
6
+ return this.undoStack.length > 0;
7
+ }
8
+ get canRedo() {
9
+ return this.redoStack.length > 0;
10
+ }
11
+ execute(scene, command, context = {}) {
12
+ const result = applyCommand(scene, command, context);
13
+ if (result.ok) {
14
+ this.undoStack.push(result.inverse);
15
+ this.redoStack.length = 0;
16
+ }
17
+ return result;
18
+ }
19
+ undo(scene, context = {}) {
20
+ const command = this.undoStack.pop();
21
+ if (!command) {
22
+ return undefined;
23
+ }
24
+ const result = applyCommand(scene, command, context);
25
+ if (result.ok) {
26
+ this.redoStack.push(result.inverse);
27
+ }
28
+ return result;
29
+ }
30
+ redo(scene, context = {}) {
31
+ const command = this.redoStack.pop();
32
+ if (!command) {
33
+ return undefined;
34
+ }
35
+ const result = applyCommand(scene, command, context);
36
+ if (result.ok) {
37
+ this.undoStack.push(result.inverse);
38
+ }
39
+ return result;
40
+ }
41
+ clear() {
42
+ this.undoStack.length = 0;
43
+ this.redoStack.length = 0;
44
+ }
45
+ }
@@ -0,0 +1,23 @@
1
+ import type { SceneSpec } from "../scene/index.js";
2
+ import type { SceneCommand } from "./Command.js";
3
+ import type { CommandValidationContext } from "./validateCommand.js";
4
+ export type CommandResult = {
5
+ ok: true;
6
+ command: SceneCommand;
7
+ inverse: SceneCommand;
8
+ } | {
9
+ ok: false;
10
+ command: SceneCommand;
11
+ error: string;
12
+ };
13
+ export interface CommandFailureDetails {
14
+ commandIndex?: number;
15
+ op?: SceneCommand['op'];
16
+ node?: string;
17
+ target?: string;
18
+ hint?: string;
19
+ }
20
+ export declare function hintForCommandError(error: string): "Use a project-relative scene path that stays inside projectRoot." | "Choose a different scene path or inspect the existing file before writing." | "Use one of: button, progressBar, scrollView, loginForm." | "Re-run scene get or node inspect to refresh locators before regenerating the command." | "Choose a container node as the parent, or create a container template before adding children." | "Verify that the field belongs to the target node or component schema before retrying." | "Check the target schema and send a value with the expected type." | undefined;
21
+ export declare function commandFailureDetails(commands: SceneCommand[], results: CommandResult[], error: string | undefined): CommandFailureDetails;
22
+ export declare function applyCommand(scene: SceneSpec, command: SceneCommand, context?: CommandValidationContext): CommandResult;
23
+ export declare const applySceneCommand: typeof applyCommand;