@tangle-network/agent-app 0.27.2 → 0.29.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 (127) hide show
  1. package/dist/DesignCanvas-AOIVN3SJ.js +12 -0
  2. package/dist/DesignCanvasEditor-IB2FMBBD.js +13 -0
  3. package/dist/InviteAcceptPage-EUOGZO2X.js +7 -0
  4. package/dist/MembersPanel-4CGUQRPF.js +8 -0
  5. package/dist/MembersPanel-4CGUQRPF.js.map +1 -0
  6. package/dist/{TimelineEditor-JDG54OBP.js → TimelineEditor-Z7C6BFP5.js} +2 -2
  7. package/dist/TimelineEditor-Z7C6BFP5.js.map +1 -0
  8. package/dist/access-ChAHG4Tp.d.ts +539 -0
  9. package/dist/{apply-Cp8c3K9D.d.ts → apply-Gk4raT2j.d.ts} +3 -1
  10. package/dist/{chunk-AFDROJ64.js → chunk-2QI7XV2T.js} +1 -1
  11. package/dist/chunk-2QI7XV2T.js.map +1 -0
  12. package/dist/chunk-3G334FVA.js +162 -0
  13. package/dist/chunk-3G334FVA.js.map +1 -0
  14. package/dist/chunk-3SVAA3MA.js +41 -0
  15. package/dist/chunk-3SVAA3MA.js.map +1 -0
  16. package/dist/{chunk-LUE4HO5C.js → chunk-4IQMTTNE.js} +10 -10
  17. package/dist/chunk-4IQMTTNE.js.map +1 -0
  18. package/dist/chunk-535V6BH6.js +128 -0
  19. package/dist/chunk-535V6BH6.js.map +1 -0
  20. package/dist/chunk-63CE7FEZ.js +63 -0
  21. package/dist/chunk-63CE7FEZ.js.map +1 -0
  22. package/dist/{chunk-5RT6KY4G.js → chunk-GQRL6VNU.js} +1 -1
  23. package/dist/chunk-GQRL6VNU.js.map +1 -0
  24. package/dist/{chunk-SCG5JJ4C.js → chunk-HFC4BTWJ.js} +32 -4
  25. package/dist/chunk-HFC4BTWJ.js.map +1 -0
  26. package/dist/{chunk-7QCIYDGC.js → chunk-IOREXWLM.js} +2 -2
  27. package/dist/{chunk-6UOE5CTA.js → chunk-JT6HHO5P.js} +5 -10
  28. package/dist/chunk-JT6HHO5P.js.map +1 -0
  29. package/dist/{chunk-JZAJE3JL.js → chunk-M2EBUDZ7.js} +19 -5
  30. package/dist/chunk-M2EBUDZ7.js.map +1 -0
  31. package/dist/{chunk-HABVCJJT.js → chunk-N4ZFKQ5C.js} +271 -404
  32. package/dist/chunk-N4ZFKQ5C.js.map +1 -0
  33. package/dist/chunk-S5CAJX6O.js +14 -0
  34. package/dist/chunk-S5CAJX6O.js.map +1 -0
  35. package/dist/{chunk-RJ2ZHK5D.js → chunk-S6WS2B32.js} +132 -7
  36. package/dist/chunk-S6WS2B32.js.map +1 -0
  37. package/dist/chunk-SQV7NUEM.js +136 -0
  38. package/dist/chunk-SQV7NUEM.js.map +1 -0
  39. package/dist/chunk-UAKFCMWK.js +1 -0
  40. package/dist/chunk-UAKFCMWK.js.map +1 -0
  41. package/dist/chunk-V5XZKHCL.js +296 -0
  42. package/dist/chunk-V5XZKHCL.js.map +1 -0
  43. package/dist/chunk-XWJXZ6WE.js +604 -0
  44. package/dist/chunk-XWJXZ6WE.js.map +1 -0
  45. package/dist/chunk-Y2SZVW35.js +125 -0
  46. package/dist/chunk-Y2SZVW35.js.map +1 -0
  47. package/dist/{chunk-27LQXQSS.js → chunk-YEWTVDDT.js} +224 -767
  48. package/dist/chunk-YEWTVDDT.js.map +1 -0
  49. package/dist/{chunk-UDXMR3AD.js → chunk-YNALYIQ3.js} +56 -18
  50. package/dist/chunk-YNALYIQ3.js.map +1 -0
  51. package/dist/command-stack-CkjelfK_.d.ts +267 -0
  52. package/dist/design-canvas/drizzle.d.ts +2 -2
  53. package/dist/design-canvas/index.d.ts +7 -6
  54. package/dist/design-canvas/index.js +3 -2
  55. package/dist/design-canvas-react/engine.d.ts +349 -0
  56. package/dist/design-canvas-react/engine.js +86 -0
  57. package/dist/design-canvas-react/engine.js.map +1 -0
  58. package/dist/design-canvas-react/index.d.ts +69 -649
  59. package/dist/design-canvas-react/index.js +84 -173
  60. package/dist/design-canvas-react/index.js.map +1 -1
  61. package/dist/design-canvas-react/lazy.d.ts +6 -0
  62. package/dist/design-canvas-react/lazy.js +9 -0
  63. package/dist/design-canvas-react/lazy.js.map +1 -0
  64. package/dist/{export-presets-Dl5Aa5xj.d.ts → export-presets-DAsU5Wal.d.ts} +2 -143
  65. package/dist/flow-types-Cb_AblZs.d.ts +25 -0
  66. package/dist/index.d.ts +11 -8
  67. package/dist/index.js +21 -8
  68. package/dist/lazy-BHHqS8-j.d.ts +72 -0
  69. package/dist/missions/index.d.ts +12 -0
  70. package/dist/missions/index.js +1 -1
  71. package/dist/{model-BHLN208Z.d.ts → model-BBwyOuWG.d.ts} +3 -1
  72. package/dist/operations-DLIvvD00.d.ts +144 -0
  73. package/dist/platform/index.js +1 -1
  74. package/dist/roles-CLtYKHHl.d.ts +49 -0
  75. package/dist/runtime/index.d.ts +33 -33
  76. package/dist/runtime/index.js +1 -1
  77. package/dist/sequences/index.d.ts +1 -1
  78. package/dist/sequences/index.js +2 -1
  79. package/dist/sequences-react/index.d.ts +15 -1
  80. package/dist/sequences-react/index.js +2 -2
  81. package/dist/{store-CUStmtdH.d.ts → store-CFyxgTlD.d.ts} +1 -1
  82. package/dist/teams/drizzle.d.ts +42 -0
  83. package/dist/teams/drizzle.js +194 -0
  84. package/dist/teams/drizzle.js.map +1 -0
  85. package/dist/teams/index.d.ts +44 -0
  86. package/dist/teams/index.js +39 -0
  87. package/dist/teams/index.js.map +1 -0
  88. package/dist/teams/members-api.d.ts +152 -0
  89. package/dist/teams/members-api.js +261 -0
  90. package/dist/teams/members-api.js.map +1 -0
  91. package/dist/teams-react/index.d.ts +81 -0
  92. package/dist/teams-react/index.js +12 -0
  93. package/dist/teams-react/index.js.map +1 -0
  94. package/dist/teams-react/lazy.d.ts +9 -0
  95. package/dist/teams-react/lazy.js +13 -0
  96. package/dist/teams-react/lazy.js.map +1 -0
  97. package/dist/theme/index.d.ts +80 -0
  98. package/dist/theme/index.js +14 -0
  99. package/dist/theme/index.js.map +1 -0
  100. package/dist/theme/tailwind-preset.d.ts +65 -0
  101. package/dist/theme/tailwind-preset.js +33 -0
  102. package/dist/theme/tailwind-preset.js.map +1 -0
  103. package/dist/theme/tokens.css +95 -0
  104. package/dist/trace/index.d.ts +2 -18
  105. package/dist/trace/index.js +2 -2
  106. package/dist/web/index.d.ts +25 -2
  107. package/dist/web/index.js +3 -1
  108. package/dist/web-react/index.d.ts +71 -31
  109. package/dist/web-react/index.js +625 -486
  110. package/dist/web-react/index.js.map +1 -1
  111. package/package.json +53 -3
  112. package/dist/DesignCanvas-73IUJJUP.js +0 -10
  113. package/dist/DesignCanvasEditor-6F2UTOSW.js +0 -9
  114. package/dist/chunk-27LQXQSS.js.map +0 -1
  115. package/dist/chunk-5RT6KY4G.js.map +0 -1
  116. package/dist/chunk-6UOE5CTA.js.map +0 -1
  117. package/dist/chunk-AFDROJ64.js.map +0 -1
  118. package/dist/chunk-HABVCJJT.js.map +0 -1
  119. package/dist/chunk-JZAJE3JL.js.map +0 -1
  120. package/dist/chunk-LUE4HO5C.js.map +0 -1
  121. package/dist/chunk-RJ2ZHK5D.js.map +0 -1
  122. package/dist/chunk-SCG5JJ4C.js.map +0 -1
  123. package/dist/chunk-UDXMR3AD.js.map +0 -1
  124. /package/dist/{DesignCanvas-73IUJJUP.js.map → DesignCanvas-AOIVN3SJ.js.map} +0 -0
  125. /package/dist/{DesignCanvasEditor-6F2UTOSW.js.map → DesignCanvasEditor-IB2FMBBD.js.map} +0 -0
  126. /package/dist/{TimelineEditor-JDG54OBP.js.map → InviteAcceptPage-EUOGZO2X.js.map} +0 -0
  127. /package/dist/{chunk-7QCIYDGC.js.map → chunk-IOREXWLM.js.map} +0 -0
@@ -0,0 +1,604 @@
1
+ import {
2
+ applySceneOperation,
3
+ applySceneOperations,
4
+ requireElement,
5
+ requirePage
6
+ } from "./chunk-M2EBUDZ7.js";
7
+
8
+ // src/design-canvas-react/engine/command-stack.ts
9
+ var SCENE_COMMAND_HISTORY_LIMIT = 200;
10
+ function createSceneCommandStack(document, activePageId) {
11
+ let state = {
12
+ document,
13
+ activePageId,
14
+ selectedElementIds: [],
15
+ zoom: 1,
16
+ panX: 0,
17
+ panY: 0,
18
+ gridEnabled: false,
19
+ gridSize: 10,
20
+ snapEnabled: true,
21
+ showRulers: true,
22
+ showBleed: false
23
+ };
24
+ const undoStack = [];
25
+ const redoStack = [];
26
+ const listeners = /* @__PURE__ */ new Set();
27
+ const notify = () => {
28
+ for (const listener of [...listeners]) listener();
29
+ };
30
+ return {
31
+ execute(command) {
32
+ state = command.execute(state);
33
+ undoStack.push(command);
34
+ if (undoStack.length > SCENE_COMMAND_HISTORY_LIMIT) {
35
+ undoStack.splice(0, undoStack.length - SCENE_COMMAND_HISTORY_LIMIT);
36
+ }
37
+ redoStack.length = 0;
38
+ notify();
39
+ },
40
+ // Both transforms run BEFORE the stacks move: a throwing transform (e.g.
41
+ // missing element after reset()) leaves history and state exactly as they
42
+ // were. The entry is never silently destroyed — the caller can retry after
43
+ // the next server refresh restores the target.
44
+ undo() {
45
+ const command = undoStack[undoStack.length - 1];
46
+ if (!command) throw new Error("nothing to undo \u2014 guard with canUndo() before calling undo()");
47
+ state = command.undo(state);
48
+ undoStack.pop();
49
+ redoStack.push(command);
50
+ notify();
51
+ return command;
52
+ },
53
+ redo() {
54
+ const command = redoStack[redoStack.length - 1];
55
+ if (!command) throw new Error("nothing to redo \u2014 guard with canRedo() before calling redo()");
56
+ state = command.execute(state);
57
+ redoStack.pop();
58
+ undoStack.push(command);
59
+ notify();
60
+ return command;
61
+ },
62
+ canUndo() {
63
+ return undoStack.length > 0;
64
+ },
65
+ canRedo() {
66
+ return redoStack.length > 0;
67
+ },
68
+ subscribe(listener) {
69
+ listeners.add(listener);
70
+ return () => {
71
+ listeners.delete(listener);
72
+ };
73
+ },
74
+ getState() {
75
+ return state;
76
+ },
77
+ setView(patch) {
78
+ state = { ...state, ...patch };
79
+ notify();
80
+ },
81
+ // A persisted UNDO rejected: the server still has `command` applied, but the
82
+ // local undo already removed it (and a later execute may have cleared the
83
+ // redo stack). Deterministically re-converge — mirror of `rollback`, in the
84
+ // forward direction: re-apply the command's FORWARD transform to current
85
+ // state and ensure it lives on the undo stack (so a later undo can remove it
86
+ // again). Idempotent: if the command is already on the undo stack (the undo
87
+ // never actually left local history), this is a no-op. For disjoint edits the
88
+ // forward transform commutes past commands executed while the undo was
89
+ // pending, so their net effect is preserved.
90
+ reexecute(command) {
91
+ if (undoStack.includes(command)) return;
92
+ state = command.execute(state);
93
+ const redoIdx = redoStack.lastIndexOf(command);
94
+ if (redoIdx !== -1) redoStack.splice(redoIdx, 1);
95
+ undoStack.push(command);
96
+ notify();
97
+ },
98
+ // A persisted REDO rejected: the server does NOT have `command` applied, but
99
+ // the local redo just applied it forward and put it on the undo stack.
100
+ // Re-apply its INVERSE and move it to the redo stack — the redo-side mirror
101
+ // of `reexecute`. No-op if the command is not on the undo stack.
102
+ reundo(command) {
103
+ const undoIdx = undoStack.lastIndexOf(command);
104
+ if (undoIdx === -1) return;
105
+ state = command.undo(state);
106
+ undoStack.splice(undoIdx, 1);
107
+ if (!redoStack.includes(command)) redoStack.push(command);
108
+ notify();
109
+ },
110
+ rollback(command) {
111
+ const idx = undoStack.lastIndexOf(command);
112
+ if (idx === -1) return;
113
+ state = command.undo(state);
114
+ undoStack.splice(idx, 1);
115
+ redoStack.length = 0;
116
+ notify();
117
+ },
118
+ /** Rebase onto a server-refreshed document. History survives; selection
119
+ * drops ids the refresh removed so view state never dangles. */
120
+ reset(newDocument) {
121
+ const liveElementIds = /* @__PURE__ */ new Set();
122
+ for (const page of newDocument.pages) {
123
+ collectElementIds(page.elements, liveElementIds);
124
+ }
125
+ const activePageExists = newDocument.pages.some((p) => p.id === state.activePageId);
126
+ const activePageId2 = activePageExists ? state.activePageId : newDocument.pages[0]?.id ?? state.activePageId;
127
+ state = {
128
+ ...state,
129
+ document: newDocument,
130
+ activePageId: activePageId2,
131
+ selectedElementIds: state.selectedElementIds.filter((id) => liveElementIds.has(id))
132
+ };
133
+ notify();
134
+ }
135
+ };
136
+ }
137
+ function collectElementIds(elements, ids) {
138
+ for (const el of elements) {
139
+ ids.add(el.id);
140
+ if (el.kind === "group" && Array.isArray(el.children)) {
141
+ collectElementIds(el.children, ids);
142
+ }
143
+ }
144
+ }
145
+
146
+ // src/design-canvas-react/engine/commands.ts
147
+ function applyOps(state, ops) {
148
+ return { ...state, document: applySceneOperations(state.document, ops) };
149
+ }
150
+ function applyOp(state, op) {
151
+ return { ...state, document: applySceneOperation(state.document, op) };
152
+ }
153
+ function addElementCommand(input) {
154
+ const addOp = {
155
+ type: "add_element",
156
+ pageId: input.pageId,
157
+ element: structuredClone(input.element),
158
+ ...input.index !== void 0 ? { index: input.index } : {},
159
+ ...input.parentGroupId !== void 0 ? { parentGroupId: input.parentGroupId } : {}
160
+ };
161
+ const deleteOp = {
162
+ type: "delete_element",
163
+ pageId: input.pageId,
164
+ elementId: input.element.id
165
+ };
166
+ return {
167
+ label: `Add ${input.element.kind}`,
168
+ execute: (state) => applyOp(state, addOp),
169
+ undo: (state) => applyOp(state, deleteOp),
170
+ operations: () => [structuredClone(addOp)],
171
+ inverseOperations: () => [structuredClone(deleteOp)]
172
+ };
173
+ }
174
+ function setAttrsCommand(input) {
175
+ const forwardOp = {
176
+ type: "set_attrs",
177
+ pageId: input.pageId,
178
+ elementId: input.elementId,
179
+ attrs: structuredClone(input.attrs)
180
+ };
181
+ const inverseOp = {
182
+ type: "set_attrs",
183
+ pageId: input.pageId,
184
+ elementId: input.elementId,
185
+ attrs: structuredClone(input.priorAttrs)
186
+ };
187
+ return {
188
+ label: "Edit element",
189
+ execute: (state) => applyOp(state, forwardOp),
190
+ undo: (state) => applyOp(state, inverseOp),
191
+ operations: () => [structuredClone(forwardOp)],
192
+ inverseOperations: () => [structuredClone(inverseOp)]
193
+ };
194
+ }
195
+ function multiSetAttrsCommand(entries) {
196
+ if (entries.length === 0) throw new Error("multiSetAttrsCommand: entries must not be empty");
197
+ const forwardOps = entries.map((e) => ({
198
+ type: "set_attrs",
199
+ pageId: e.pageId,
200
+ elementId: e.elementId,
201
+ attrs: structuredClone(e.attrs)
202
+ }));
203
+ const inverseOps = entries.map((e) => ({
204
+ type: "set_attrs",
205
+ pageId: e.pageId,
206
+ elementId: e.elementId,
207
+ attrs: structuredClone(e.priorAttrs)
208
+ }));
209
+ return {
210
+ label: `Edit ${entries.length} elements`,
211
+ execute: (state) => applyOps(state, forwardOps),
212
+ undo: (state) => applyOps(state, inverseOps),
213
+ operations: () => structuredClone(forwardOps),
214
+ inverseOperations: () => structuredClone(inverseOps)
215
+ };
216
+ }
217
+ function reorderElementCommand(input) {
218
+ let capturedFromIndex = null;
219
+ const forwardOp = {
220
+ type: "reorder_element",
221
+ pageId: input.pageId,
222
+ elementId: input.elementId,
223
+ toIndex: input.toIndex
224
+ };
225
+ return {
226
+ label: "Reorder element",
227
+ execute: (state) => {
228
+ if (capturedFromIndex === null) {
229
+ const page = requirePage(state.document, input.pageId);
230
+ const { index } = requireElement(page, input.elementId);
231
+ capturedFromIndex = index;
232
+ }
233
+ return applyOp(state, forwardOp);
234
+ },
235
+ undo: (state) => {
236
+ if (capturedFromIndex === null) {
237
+ throw new Error("reorderElementCommand: undo called before execute");
238
+ }
239
+ return applyOp(state, {
240
+ type: "reorder_element",
241
+ pageId: input.pageId,
242
+ elementId: input.elementId,
243
+ toIndex: capturedFromIndex
244
+ });
245
+ },
246
+ operations: () => [structuredClone(forwardOp)],
247
+ inverseOperations: () => {
248
+ if (capturedFromIndex === null) {
249
+ throw new Error("reorderElementCommand: inverseOperations called before execute");
250
+ }
251
+ return [{
252
+ type: "reorder_element",
253
+ pageId: input.pageId,
254
+ elementId: input.elementId,
255
+ toIndex: capturedFromIndex
256
+ }];
257
+ }
258
+ };
259
+ }
260
+ function deleteElementCommand(input) {
261
+ const page = requirePage(input.document, input.pageId);
262
+ const { element, owner, index } = requireElement(page, input.elementId);
263
+ const snapshot = structuredClone(element);
264
+ const parentGroupId = findParentGroupId(page, owner);
265
+ const deleteOp = {
266
+ type: "delete_element",
267
+ pageId: input.pageId,
268
+ elementId: input.elementId
269
+ };
270
+ const addOp = {
271
+ type: "add_element",
272
+ pageId: input.pageId,
273
+ element: snapshot,
274
+ index,
275
+ ...parentGroupId !== void 0 ? { parentGroupId } : {}
276
+ };
277
+ return {
278
+ label: `Delete ${element.kind}`,
279
+ execute: (state) => {
280
+ const next = applyOp(state, deleteOp);
281
+ return {
282
+ ...next,
283
+ selectedElementIds: next.selectedElementIds.filter((id) => id !== input.elementId)
284
+ };
285
+ },
286
+ undo: (state) => applyOp(state, addOp),
287
+ operations: () => [structuredClone(deleteOp)],
288
+ inverseOperations: () => [structuredClone(addOp)]
289
+ };
290
+ }
291
+ function findParentGroupId(page, owner) {
292
+ if (owner === page.elements) return void 0;
293
+ return findGroupWithChildren(page.elements, owner);
294
+ }
295
+ function findGroupWithChildren(elements, target) {
296
+ for (const el of elements) {
297
+ if (el.kind === "group") {
298
+ if (el.children === target) return el.id;
299
+ const found = findGroupWithChildren(el.children, target);
300
+ if (found !== void 0) return found;
301
+ }
302
+ }
303
+ return void 0;
304
+ }
305
+ function groupElementsCommand(input) {
306
+ if (input.elementIds.length < 2) {
307
+ throw new Error("groupElementsCommand: requires \u2265 2 elementIds");
308
+ }
309
+ const groupOp = {
310
+ type: "group_elements",
311
+ pageId: input.pageId,
312
+ elementIds: input.elementIds.slice(),
313
+ groupId: input.groupId,
314
+ ...input.name !== void 0 ? { name: input.name } : {}
315
+ };
316
+ const ungroupOp = {
317
+ type: "ungroup_element",
318
+ pageId: input.pageId,
319
+ groupId: input.groupId
320
+ };
321
+ return {
322
+ label: `Group ${input.elementIds.length} elements`,
323
+ execute: (state) => {
324
+ const next = applyOp(state, groupOp);
325
+ return {
326
+ ...next,
327
+ selectedElementIds: [input.groupId]
328
+ };
329
+ },
330
+ undo: (state) => {
331
+ const next = applyOp(state, ungroupOp);
332
+ return { ...next, selectedElementIds: input.elementIds.slice() };
333
+ },
334
+ operations: () => [structuredClone(groupOp)],
335
+ inverseOperations: () => [structuredClone(ungroupOp)]
336
+ };
337
+ }
338
+ function ungroupElementCommand(input) {
339
+ const page = requirePage(input.document, input.pageId);
340
+ const { element } = requireElement(page, input.groupId);
341
+ if (element.kind !== "group") {
342
+ throw new Error(`ungroupElementCommand: element ${input.groupId} is kind ${element.kind}, not group`);
343
+ }
344
+ const childIds = element.children.map((c) => c.id);
345
+ const ungroupOp = {
346
+ type: "ungroup_element",
347
+ pageId: input.pageId,
348
+ groupId: input.groupId
349
+ };
350
+ const regroupOp = {
351
+ type: "group_elements",
352
+ pageId: input.pageId,
353
+ elementIds: childIds,
354
+ groupId: input.groupId,
355
+ name: element.name
356
+ };
357
+ return {
358
+ label: `Ungroup`,
359
+ execute: (state) => {
360
+ const next = applyOp(state, ungroupOp);
361
+ return { ...next, selectedElementIds: childIds.slice() };
362
+ },
363
+ undo: (state) => {
364
+ const next = applyOp(state, regroupOp);
365
+ return { ...next, selectedElementIds: [input.groupId] };
366
+ },
367
+ operations: () => [structuredClone(ungroupOp)],
368
+ inverseOperations: () => [structuredClone(regroupOp)]
369
+ };
370
+ }
371
+ function addPageCommand(input) {
372
+ const addOp = {
373
+ type: "add_page",
374
+ pageId: input.pageId,
375
+ ...input.options !== void 0 ? { options: input.options } : {},
376
+ ...input.index !== void 0 ? { index: input.index } : {}
377
+ };
378
+ const deleteOp = { type: "delete_page", pageId: input.pageId };
379
+ return {
380
+ label: "Add page",
381
+ execute: (state) => {
382
+ const next = applyOp(state, addOp);
383
+ return { ...next, activePageId: input.pageId };
384
+ },
385
+ undo: (state) => {
386
+ const next = applyOp(state, deleteOp);
387
+ const activeExists = next.document.pages.some((p) => p.id === next.activePageId);
388
+ return activeExists ? next : { ...next, activePageId: next.document.pages[0].id };
389
+ },
390
+ operations: () => [structuredClone(addOp)],
391
+ inverseOperations: () => [structuredClone(deleteOp)]
392
+ };
393
+ }
394
+ function duplicatePageCommand(input) {
395
+ requirePage(input.document, input.sourcePageId);
396
+ const dupOp = {
397
+ type: "duplicate_page",
398
+ sourcePageId: input.sourcePageId,
399
+ pageId: input.pageId
400
+ };
401
+ const deleteOp = { type: "delete_page", pageId: input.pageId };
402
+ return {
403
+ label: "Duplicate page",
404
+ execute: (state) => {
405
+ const next = applyOp(state, dupOp);
406
+ return { ...next, activePageId: input.pageId };
407
+ },
408
+ undo: (state) => {
409
+ const next = applyOp(state, deleteOp);
410
+ const activeExists = next.document.pages.some((p) => p.id === next.activePageId);
411
+ return activeExists ? next : { ...next, activePageId: input.sourcePageId };
412
+ },
413
+ operations: () => [structuredClone(dupOp)],
414
+ inverseOperations: () => [structuredClone(deleteOp)]
415
+ };
416
+ }
417
+ function deletePageCommand(input) {
418
+ if (input.document.pages.length <= 1) {
419
+ throw new Error("deletePageCommand: cannot delete the last page");
420
+ }
421
+ const page = requirePage(input.document, input.pageId);
422
+ const currentIndex = input.document.pages.findIndex((p) => p.id === input.pageId);
423
+ const snapshot = structuredClone(page);
424
+ const deleteOp = { type: "delete_page", pageId: input.pageId };
425
+ function buildRestoreOps() {
426
+ const ops = [
427
+ {
428
+ type: "add_page",
429
+ pageId: snapshot.id,
430
+ options: {
431
+ name: snapshot.name,
432
+ width: snapshot.width,
433
+ height: snapshot.height,
434
+ background: snapshot.background
435
+ },
436
+ index: currentIndex
437
+ }
438
+ ];
439
+ if (snapshot.bleed) {
440
+ ops.push({ type: "set_page_props", pageId: snapshot.id, bleed: snapshot.bleed });
441
+ }
442
+ if (snapshot.guides.vertical.length > 0 || snapshot.guides.horizontal.length > 0) {
443
+ ops.push({ type: "set_page_guides", pageId: snapshot.id, guides: snapshot.guides });
444
+ }
445
+ for (let i = 0; i < snapshot.elements.length; i++) {
446
+ ops.push({
447
+ type: "add_element",
448
+ pageId: snapshot.id,
449
+ element: structuredClone(snapshot.elements[i]),
450
+ index: i
451
+ });
452
+ }
453
+ return ops;
454
+ }
455
+ return {
456
+ label: "Delete page",
457
+ execute: (state) => {
458
+ const next = applyOp(state, deleteOp);
459
+ const activeExists = next.document.pages.some((p) => p.id === next.activePageId);
460
+ if (activeExists) return next;
461
+ const fallbackIndex = Math.min(currentIndex, next.document.pages.length - 1);
462
+ return { ...next, activePageId: next.document.pages[fallbackIndex].id };
463
+ },
464
+ undo: (state) => {
465
+ const next = applyOps(state, buildRestoreOps());
466
+ return { ...next, activePageId: input.pageId };
467
+ },
468
+ operations: () => [structuredClone(deleteOp)],
469
+ inverseOperations: () => buildRestoreOps()
470
+ };
471
+ }
472
+ function reorderPageCommand(input) {
473
+ let capturedFromIndex = null;
474
+ const forwardOp = {
475
+ type: "reorder_page",
476
+ pageId: input.pageId,
477
+ toIndex: input.toIndex
478
+ };
479
+ return {
480
+ label: "Reorder page",
481
+ execute: (state) => {
482
+ if (capturedFromIndex === null) {
483
+ capturedFromIndex = state.document.pages.findIndex((p) => p.id === input.pageId);
484
+ if (capturedFromIndex === -1) throw new Error(`reorderPageCommand: page ${input.pageId} not found`);
485
+ }
486
+ return applyOp(state, forwardOp);
487
+ },
488
+ undo: (state) => {
489
+ if (capturedFromIndex === null) throw new Error("reorderPageCommand: undo called before execute");
490
+ return applyOp(state, {
491
+ type: "reorder_page",
492
+ pageId: input.pageId,
493
+ toIndex: capturedFromIndex
494
+ });
495
+ },
496
+ operations: () => [structuredClone(forwardOp)],
497
+ inverseOperations: () => {
498
+ if (capturedFromIndex === null) throw new Error("reorderPageCommand: inverseOperations called before execute");
499
+ return [{ type: "reorder_page", pageId: input.pageId, toIndex: capturedFromIndex }];
500
+ }
501
+ };
502
+ }
503
+ function setPagePropsCommand(input) {
504
+ const page = requirePage(input.document, input.pageId);
505
+ const prior = {
506
+ type: "set_page_props",
507
+ pageId: input.pageId,
508
+ ...input.props.name !== void 0 ? { name: page.name } : {},
509
+ ...input.props.width !== void 0 ? { width: page.width } : {},
510
+ ...input.props.height !== void 0 ? { height: page.height } : {},
511
+ ...input.props.background !== void 0 ? { background: page.background } : {},
512
+ ...input.props.bleed !== void 0 ? { bleed: page.bleed } : {}
513
+ };
514
+ const forwardOp = {
515
+ type: "set_page_props",
516
+ pageId: input.pageId,
517
+ ...input.props
518
+ };
519
+ return {
520
+ label: "Edit page",
521
+ execute: (state) => applyOp(state, forwardOp),
522
+ undo: (state) => applyOp(state, prior),
523
+ operations: () => [structuredClone(forwardOp)],
524
+ inverseOperations: () => [structuredClone(prior)]
525
+ };
526
+ }
527
+ function setPageGuidesCommand(input) {
528
+ const page = requirePage(input.document, input.pageId);
529
+ const priorGuides = structuredClone(page.guides);
530
+ const forwardOp = {
531
+ type: "set_page_guides",
532
+ pageId: input.pageId,
533
+ guides: structuredClone(input.guides)
534
+ };
535
+ const inverseOp = {
536
+ type: "set_page_guides",
537
+ pageId: input.pageId,
538
+ guides: priorGuides
539
+ };
540
+ return {
541
+ label: "Edit guides",
542
+ execute: (state) => applyOp(state, forwardOp),
543
+ undo: (state) => applyOp(state, inverseOp),
544
+ operations: () => [structuredClone(forwardOp)],
545
+ inverseOperations: () => [structuredClone(inverseOp)]
546
+ };
547
+ }
548
+ function bindSlotCommand(input) {
549
+ const page = requirePage(input.document, input.pageId);
550
+ const { element } = requireElement(page, input.elementId);
551
+ const priorSlot = element.slot ?? null;
552
+ const forwardOp = {
553
+ type: "bind_slot",
554
+ pageId: input.pageId,
555
+ elementId: input.elementId,
556
+ slot: input.slot
557
+ };
558
+ const inverseOp = {
559
+ type: "bind_slot",
560
+ pageId: input.pageId,
561
+ elementId: input.elementId,
562
+ slot: priorSlot
563
+ };
564
+ return {
565
+ label: input.slot === null ? "Unbind slot" : `Bind slot "${input.slot}"`,
566
+ execute: (state) => applyOp(state, forwardOp),
567
+ undo: (state) => applyOp(state, inverseOp),
568
+ operations: () => [structuredClone(forwardOp)],
569
+ inverseOperations: () => [structuredClone(inverseOp)]
570
+ };
571
+ }
572
+ function setDocumentTitleCommand(input) {
573
+ const priorTitle = input.document.title;
574
+ const forwardOp = { type: "set_document_title", title: input.title };
575
+ const inverseOp = { type: "set_document_title", title: priorTitle };
576
+ return {
577
+ label: `Rename document`,
578
+ execute: (state) => applyOp(state, forwardOp),
579
+ undo: (state) => applyOp(state, inverseOp),
580
+ operations: () => [structuredClone(forwardOp)],
581
+ inverseOperations: () => [structuredClone(inverseOp)]
582
+ };
583
+ }
584
+
585
+ export {
586
+ SCENE_COMMAND_HISTORY_LIMIT,
587
+ createSceneCommandStack,
588
+ addElementCommand,
589
+ setAttrsCommand,
590
+ multiSetAttrsCommand,
591
+ reorderElementCommand,
592
+ deleteElementCommand,
593
+ groupElementsCommand,
594
+ ungroupElementCommand,
595
+ addPageCommand,
596
+ duplicatePageCommand,
597
+ deletePageCommand,
598
+ reorderPageCommand,
599
+ setPagePropsCommand,
600
+ setPageGuidesCommand,
601
+ bindSlotCommand,
602
+ setDocumentTitleCommand
603
+ };
604
+ //# sourceMappingURL=chunk-XWJXZ6WE.js.map