@pixerate/editor 0.14.3 → 0.15.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 (71) hide show
  1. package/dist/agent/index.cjs +28 -220
  2. package/dist/agent/index.cjs.map +1 -1
  3. package/dist/agent/index.d.cts +1 -1
  4. package/dist/agent/index.d.ts +1 -1
  5. package/dist/agent/index.js +5 -154
  6. package/dist/agent/index.js.map +1 -1
  7. package/dist/canvas/index.cjs +113 -377
  8. package/dist/canvas/index.cjs.map +1 -1
  9. package/dist/canvas/index.d.cts +2 -2
  10. package/dist/canvas/index.d.ts +2 -2
  11. package/dist/canvas/index.js +18 -208
  12. package/dist/canvas/index.js.map +1 -1
  13. package/dist/chunk-33UVEDOS.cjs +233 -0
  14. package/dist/chunk-33UVEDOS.cjs.map +1 -0
  15. package/dist/chunk-7FWEWE6T.js +1888 -0
  16. package/dist/chunk-7FWEWE6T.js.map +1 -0
  17. package/dist/chunk-BYCOFZAA.js +514 -0
  18. package/dist/chunk-BYCOFZAA.js.map +1 -0
  19. package/dist/chunk-CYKQLDYH.cjs +1290 -0
  20. package/dist/chunk-CYKQLDYH.cjs.map +1 -0
  21. package/dist/chunk-GLSIZKOX.js +17 -0
  22. package/dist/chunk-GLSIZKOX.js.map +1 -0
  23. package/dist/chunk-GWHJVZPI.js +233 -0
  24. package/dist/chunk-GWHJVZPI.js.map +1 -0
  25. package/dist/chunk-LDES3EOS.cjs +1888 -0
  26. package/dist/chunk-LDES3EOS.cjs.map +1 -0
  27. package/dist/chunk-MPPXH7U5.cjs +336 -0
  28. package/dist/chunk-MPPXH7U5.cjs.map +1 -0
  29. package/dist/chunk-NNJRJJSC.js +1290 -0
  30. package/dist/chunk-NNJRJJSC.js.map +1 -0
  31. package/dist/chunk-O7LOPQMH.js +336 -0
  32. package/dist/chunk-O7LOPQMH.js.map +1 -0
  33. package/dist/chunk-SEDR75VH.cjs +17 -0
  34. package/dist/chunk-SEDR75VH.cjs.map +1 -0
  35. package/dist/chunk-SHWP2A43.cjs +514 -0
  36. package/dist/chunk-SHWP2A43.cjs.map +1 -0
  37. package/dist/chunk-VHZCXHS4.js +222 -0
  38. package/dist/chunk-VHZCXHS4.js.map +1 -0
  39. package/dist/chunk-WADCJ7A7.cjs +222 -0
  40. package/dist/chunk-WADCJ7A7.cjs.map +1 -0
  41. package/dist/extensions/index.cjs +25 -1920
  42. package/dist/extensions/index.cjs.map +1 -1
  43. package/dist/extensions/index.js +22 -1868
  44. package/dist/extensions/index.js.map +1 -1
  45. package/dist/grammar/index.cjs +44 -387
  46. package/dist/grammar/index.cjs.map +1 -1
  47. package/dist/grammar/index.js +23 -321
  48. package/dist/grammar/index.js.map +1 -1
  49. package/dist/history/index.cjs +6 -257
  50. package/dist/history/index.cjs.map +1 -1
  51. package/dist/history/index.js +4 -227
  52. package/dist/history/index.js.map +1 -1
  53. package/dist/image-editor/index.cjs +63 -106
  54. package/dist/image-editor/index.cjs.map +1 -1
  55. package/dist/index.cjs +324 -7232
  56. package/dist/index.cjs.map +1 -1
  57. package/dist/index.d.cts +0 -4
  58. package/dist/index.d.ts +0 -4
  59. package/dist/index.js +258 -7007
  60. package/dist/index.js.map +1 -1
  61. package/dist/serializers/index.cjs +28 -558
  62. package/dist/serializers/index.cjs.map +1 -1
  63. package/dist/serializers/index.js +16 -496
  64. package/dist/serializers/index.js.map +1 -1
  65. package/dist/spreadsheet/index.cjs +21 -1319
  66. package/dist/spreadsheet/index.cjs.map +1 -1
  67. package/dist/spreadsheet/index.js +14 -1274
  68. package/dist/spreadsheet/index.js.map +1 -1
  69. package/dist/{types-lGtRobRV.d.cts → types-DC8b2TsA.d.cts} +1 -1
  70. package/dist/{types-lGtRobRV.d.ts → types-DC8b2TsA.d.ts} +1 -1
  71. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/history/index.ts","../../src/history/HistoryManager.ts"],"sourcesContent":["export * from \"./types\";\nexport * from \"./HistoryManager\";\n","import {\n Command,\n HistoryManagerOptions,\n HistoryState,\n MergedExecutionOptions,\n SnapshotCommandOptions,\n} from \"./types\";\n\n/**\n * UI-agnostic History and Undo/Redo manager supporting command closures,\n * snapshot diffs, transaction batching, and high-frequency event coalescing.\n */\nexport class HistoryManager {\n private undoStack: Command[] = [];\n private redoStack: Command[] = [];\n private readonly maxDepth: number;\n private isApplying = false;\n private batchDepth = 0;\n private currentBatch: Command[] | null = null;\n private listeners: Set<(state: HistoryState) => void> = new Set();\n private onStateChange?: (state: HistoryState) => void;\n private cachedState: HistoryState;\n\n constructor(options: HistoryManagerOptions = {}) {\n this.maxDepth = options.maxDepth ?? 50;\n this.onStateChange = options.onStateChange;\n this.cachedState = this.computeState();\n }\n\n private computeState(): HistoryState {\n const canUndo = this.undoStack.length > 0;\n const canRedo = this.redoStack.length > 0;\n return {\n canUndo,\n canRedo,\n undoName: canUndo ? this.undoStack[this.undoStack.length - 1].name : \"\",\n redoName: canRedo ? this.redoStack[this.redoStack.length - 1].name : \"\",\n undoCount: this.undoStack.length,\n redoCount: this.redoStack.length,\n };\n }\n\n /**\n * Returns a snapshot of the current history state.\n * Cached to maintain referential equality across renders for useSyncExternalStore.\n */\n public getState(): HistoryState {\n return this.cachedState;\n }\n\n private notify(): void {\n this.cachedState = this.computeState();\n const state = this.cachedState;\n this.onStateChange?.(state);\n this.listeners.forEach((listener) => {\n try {\n listener(state);\n } catch (err) {\n console.error(\"[HistoryManager] Error in state listener:\", err);\n }\n });\n }\n\n /**\n * Executes a command and pushes it onto the undo stack.\n * Clears the redo stack.\n */\n public execute(command: Command): void {\n if (this.isApplying) {\n command.execute();\n return;\n }\n\n if (this.batchDepth > 0 && this.currentBatch) {\n command.execute();\n this.currentBatch.push({\n ...command,\n timestamp: command.timestamp ?? Date.now(),\n });\n return;\n }\n\n command.execute();\n\n this.undoStack.push({\n ...command,\n timestamp: command.timestamp ?? Date.now(),\n });\n\n if (this.undoStack.length > this.maxDepth) {\n this.undoStack.shift();\n }\n\n this.redoStack = [];\n this.notify();\n }\n\n /**\n * Executes a command, coalescing it with the previous command if they share\n * the same `tag` and occurred within `windowMs` (default: 300ms).\n * Useful for high-frequency interactions like slider scrubs or node drags.\n */\n public executeMerged(\n command: Command,\n options: MergedExecutionOptions = {},\n ): void {\n const windowMs = options.windowMs ?? 300;\n const now = Date.now();\n\n if (\n command.tag &&\n this.undoStack.length > 0 &&\n this.batchDepth === 0 &&\n !this.isApplying\n ) {\n const top = this.undoStack[this.undoStack.length - 1];\n const elapsed = top.timestamp ? now - top.timestamp : Infinity;\n\n if (top.tag === command.tag && elapsed <= windowMs) {\n command.execute();\n // Replace top with merged command keeping the original initial undo\n const initialUndo = top.undo;\n this.undoStack[this.undoStack.length - 1] = {\n name: command.name,\n tag: command.tag,\n timestamp: now,\n execute: command.execute,\n undo: initialUndo,\n redo: command.redo ?? command.execute,\n };\n this.redoStack = [];\n this.notify();\n return;\n }\n }\n\n this.execute({ ...command, timestamp: now });\n }\n\n /**\n * Batches multiple commands executed within `fn` into a single atomic undo entry.\n */\n public batch(name: string, fn: () => void): void {\n if (this.isApplying) {\n fn();\n return;\n }\n\n if (this.batchDepth > 0) {\n // Already inside a batch; execute directly\n fn();\n return;\n }\n\n this.batchDepth++;\n this.currentBatch = [];\n\n try {\n fn();\n } finally {\n this.batchDepth--;\n const batchCommands = this.currentBatch;\n this.currentBatch = null;\n\n if (batchCommands && batchCommands.length > 0) {\n const compoundCommand: Command = {\n name,\n timestamp: Date.now(),\n execute: () => {\n for (let i = 0; i < batchCommands.length; i++) {\n (batchCommands[i].redo ?? batchCommands[i].execute)();\n }\n },\n undo: () => {\n for (let i = batchCommands.length - 1; i >= 0; i--) {\n batchCommands[i].undo();\n }\n },\n redo: () => {\n for (let i = 0; i < batchCommands.length; i++) {\n (batchCommands[i].redo ?? batchCommands[i].execute)();\n }\n },\n };\n\n this.undoStack.push(compoundCommand);\n if (this.undoStack.length > this.maxDepth) {\n this.undoStack.shift();\n }\n this.redoStack = [];\n this.notify();\n }\n }\n }\n\n /**\n * Reverts the most recent command on the undo stack.\n * Returns true if a command was undone, false otherwise.\n */\n public undo(): boolean {\n if (this.undoStack.length === 0 || this.isApplying || this.batchDepth > 0) {\n return false;\n }\n\n this.isApplying = true;\n try {\n const command = this.undoStack.pop()!;\n command.undo();\n this.redoStack.push(command);\n return true;\n } finally {\n this.isApplying = false;\n this.notify();\n }\n }\n\n /**\n * Re-applies the most recent undone command on the redo stack.\n * Returns true if a command was redone, false otherwise.\n */\n public redo(): boolean {\n if (this.redoStack.length === 0 || this.isApplying || this.batchDepth > 0) {\n return false;\n }\n\n this.isApplying = true;\n try {\n const command = this.redoStack.pop()!;\n (command.redo ?? command.execute)();\n this.undoStack.push(command);\n return true;\n } finally {\n this.isApplying = false;\n this.notify();\n }\n }\n\n /**\n * Clears both undo and redo stacks.\n */\n public clear(): void {\n this.undoStack = [];\n this.redoStack = [];\n this.notify();\n }\n\n /**\n * Subscribes to history state changes.\n * The listener is immediately invoked with the current state.\n * Returns an unsubscribe function.\n */\n public subscribe(listener: (state: HistoryState) => void): () => void {\n this.listeners.add(listener);\n listener(this.getState());\n return () => {\n this.listeners.delete(listener);\n };\n }\n\n /**\n * Utility helper to create a Command from before/after state snapshots.\n */\n public static createSnapshotCommand<T>(\n options: SnapshotCommandOptions<T>,\n ): Command {\n return {\n name: options.name,\n tag: options.tag,\n execute: () => options.apply(options.after),\n undo: () => options.apply(options.before),\n redo: () => options.apply(options.after),\n };\n }\n}\n\n/**\n * Creates and initializes a new HistoryManager instance.\n */\nexport function createHistoryManager(\n options: HistoryManagerOptions = {},\n): HistoryManager {\n return new HistoryManager(options);\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["/home/runner/work/editor/editor/packages/core/dist/history/index.cjs"],"names":[],"mappings":"AAAA;AACE;AACA;AACF,yDAA8B;AAC9B;AACE;AACA;AACF,iIAAC","file":"/home/runner/work/editor/editor/packages/core/dist/history/index.cjs"}
@@ -1,230 +1,7 @@
1
- // src/history/HistoryManager.ts
2
- var HistoryManager = class {
3
- undoStack = [];
4
- redoStack = [];
5
- maxDepth;
6
- isApplying = false;
7
- batchDepth = 0;
8
- currentBatch = null;
9
- listeners = /* @__PURE__ */ new Set();
10
- onStateChange;
11
- cachedState;
12
- constructor(options = {}) {
13
- this.maxDepth = options.maxDepth ?? 50;
14
- this.onStateChange = options.onStateChange;
15
- this.cachedState = this.computeState();
16
- }
17
- computeState() {
18
- const canUndo = this.undoStack.length > 0;
19
- const canRedo = this.redoStack.length > 0;
20
- return {
21
- canUndo,
22
- canRedo,
23
- undoName: canUndo ? this.undoStack[this.undoStack.length - 1].name : "",
24
- redoName: canRedo ? this.redoStack[this.redoStack.length - 1].name : "",
25
- undoCount: this.undoStack.length,
26
- redoCount: this.redoStack.length
27
- };
28
- }
29
- /**
30
- * Returns a snapshot of the current history state.
31
- * Cached to maintain referential equality across renders for useSyncExternalStore.
32
- */
33
- getState() {
34
- return this.cachedState;
35
- }
36
- notify() {
37
- this.cachedState = this.computeState();
38
- const state = this.cachedState;
39
- this.onStateChange?.(state);
40
- this.listeners.forEach((listener) => {
41
- try {
42
- listener(state);
43
- } catch (err) {
44
- console.error("[HistoryManager] Error in state listener:", err);
45
- }
46
- });
47
- }
48
- /**
49
- * Executes a command and pushes it onto the undo stack.
50
- * Clears the redo stack.
51
- */
52
- execute(command) {
53
- if (this.isApplying) {
54
- command.execute();
55
- return;
56
- }
57
- if (this.batchDepth > 0 && this.currentBatch) {
58
- command.execute();
59
- this.currentBatch.push({
60
- ...command,
61
- timestamp: command.timestamp ?? Date.now()
62
- });
63
- return;
64
- }
65
- command.execute();
66
- this.undoStack.push({
67
- ...command,
68
- timestamp: command.timestamp ?? Date.now()
69
- });
70
- if (this.undoStack.length > this.maxDepth) {
71
- this.undoStack.shift();
72
- }
73
- this.redoStack = [];
74
- this.notify();
75
- }
76
- /**
77
- * Executes a command, coalescing it with the previous command if they share
78
- * the same `tag` and occurred within `windowMs` (default: 300ms).
79
- * Useful for high-frequency interactions like slider scrubs or node drags.
80
- */
81
- executeMerged(command, options = {}) {
82
- const windowMs = options.windowMs ?? 300;
83
- const now = Date.now();
84
- if (command.tag && this.undoStack.length > 0 && this.batchDepth === 0 && !this.isApplying) {
85
- const top = this.undoStack[this.undoStack.length - 1];
86
- const elapsed = top.timestamp ? now - top.timestamp : Infinity;
87
- if (top.tag === command.tag && elapsed <= windowMs) {
88
- command.execute();
89
- const initialUndo = top.undo;
90
- this.undoStack[this.undoStack.length - 1] = {
91
- name: command.name,
92
- tag: command.tag,
93
- timestamp: now,
94
- execute: command.execute,
95
- undo: initialUndo,
96
- redo: command.redo ?? command.execute
97
- };
98
- this.redoStack = [];
99
- this.notify();
100
- return;
101
- }
102
- }
103
- this.execute({ ...command, timestamp: now });
104
- }
105
- /**
106
- * Batches multiple commands executed within `fn` into a single atomic undo entry.
107
- */
108
- batch(name, fn) {
109
- if (this.isApplying) {
110
- fn();
111
- return;
112
- }
113
- if (this.batchDepth > 0) {
114
- fn();
115
- return;
116
- }
117
- this.batchDepth++;
118
- this.currentBatch = [];
119
- try {
120
- fn();
121
- } finally {
122
- this.batchDepth--;
123
- const batchCommands = this.currentBatch;
124
- this.currentBatch = null;
125
- if (batchCommands && batchCommands.length > 0) {
126
- const compoundCommand = {
127
- name,
128
- timestamp: Date.now(),
129
- execute: () => {
130
- for (let i = 0; i < batchCommands.length; i++) {
131
- (batchCommands[i].redo ?? batchCommands[i].execute)();
132
- }
133
- },
134
- undo: () => {
135
- for (let i = batchCommands.length - 1; i >= 0; i--) {
136
- batchCommands[i].undo();
137
- }
138
- },
139
- redo: () => {
140
- for (let i = 0; i < batchCommands.length; i++) {
141
- (batchCommands[i].redo ?? batchCommands[i].execute)();
142
- }
143
- }
144
- };
145
- this.undoStack.push(compoundCommand);
146
- if (this.undoStack.length > this.maxDepth) {
147
- this.undoStack.shift();
148
- }
149
- this.redoStack = [];
150
- this.notify();
151
- }
152
- }
153
- }
154
- /**
155
- * Reverts the most recent command on the undo stack.
156
- * Returns true if a command was undone, false otherwise.
157
- */
158
- undo() {
159
- if (this.undoStack.length === 0 || this.isApplying || this.batchDepth > 0) {
160
- return false;
161
- }
162
- this.isApplying = true;
163
- try {
164
- const command = this.undoStack.pop();
165
- command.undo();
166
- this.redoStack.push(command);
167
- return true;
168
- } finally {
169
- this.isApplying = false;
170
- this.notify();
171
- }
172
- }
173
- /**
174
- * Re-applies the most recent undone command on the redo stack.
175
- * Returns true if a command was redone, false otherwise.
176
- */
177
- redo() {
178
- if (this.redoStack.length === 0 || this.isApplying || this.batchDepth > 0) {
179
- return false;
180
- }
181
- this.isApplying = true;
182
- try {
183
- const command = this.redoStack.pop();
184
- (command.redo ?? command.execute)();
185
- this.undoStack.push(command);
186
- return true;
187
- } finally {
188
- this.isApplying = false;
189
- this.notify();
190
- }
191
- }
192
- /**
193
- * Clears both undo and redo stacks.
194
- */
195
- clear() {
196
- this.undoStack = [];
197
- this.redoStack = [];
198
- this.notify();
199
- }
200
- /**
201
- * Subscribes to history state changes.
202
- * The listener is immediately invoked with the current state.
203
- * Returns an unsubscribe function.
204
- */
205
- subscribe(listener) {
206
- this.listeners.add(listener);
207
- listener(this.getState());
208
- return () => {
209
- this.listeners.delete(listener);
210
- };
211
- }
212
- /**
213
- * Utility helper to create a Command from before/after state snapshots.
214
- */
215
- static createSnapshotCommand(options) {
216
- return {
217
- name: options.name,
218
- tag: options.tag,
219
- execute: () => options.apply(options.after),
220
- undo: () => options.apply(options.before),
221
- redo: () => options.apply(options.after)
222
- };
223
- }
224
- };
225
- function createHistoryManager(options = {}) {
226
- return new HistoryManager(options);
227
- }
1
+ import {
2
+ HistoryManager,
3
+ createHistoryManager
4
+ } from "../chunk-GWHJVZPI.js";
228
5
  export {
229
6
  HistoryManager,
230
7
  createHistoryManager
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/history/HistoryManager.ts"],"sourcesContent":["import {\n Command,\n HistoryManagerOptions,\n HistoryState,\n MergedExecutionOptions,\n SnapshotCommandOptions,\n} from \"./types\";\n\n/**\n * UI-agnostic History and Undo/Redo manager supporting command closures,\n * snapshot diffs, transaction batching, and high-frequency event coalescing.\n */\nexport class HistoryManager {\n private undoStack: Command[] = [];\n private redoStack: Command[] = [];\n private readonly maxDepth: number;\n private isApplying = false;\n private batchDepth = 0;\n private currentBatch: Command[] | null = null;\n private listeners: Set<(state: HistoryState) => void> = new Set();\n private onStateChange?: (state: HistoryState) => void;\n private cachedState: HistoryState;\n\n constructor(options: HistoryManagerOptions = {}) {\n this.maxDepth = options.maxDepth ?? 50;\n this.onStateChange = options.onStateChange;\n this.cachedState = this.computeState();\n }\n\n private computeState(): HistoryState {\n const canUndo = this.undoStack.length > 0;\n const canRedo = this.redoStack.length > 0;\n return {\n canUndo,\n canRedo,\n undoName: canUndo ? this.undoStack[this.undoStack.length - 1].name : \"\",\n redoName: canRedo ? this.redoStack[this.redoStack.length - 1].name : \"\",\n undoCount: this.undoStack.length,\n redoCount: this.redoStack.length,\n };\n }\n\n /**\n * Returns a snapshot of the current history state.\n * Cached to maintain referential equality across renders for useSyncExternalStore.\n */\n public getState(): HistoryState {\n return this.cachedState;\n }\n\n private notify(): void {\n this.cachedState = this.computeState();\n const state = this.cachedState;\n this.onStateChange?.(state);\n this.listeners.forEach((listener) => {\n try {\n listener(state);\n } catch (err) {\n console.error(\"[HistoryManager] Error in state listener:\", err);\n }\n });\n }\n\n /**\n * Executes a command and pushes it onto the undo stack.\n * Clears the redo stack.\n */\n public execute(command: Command): void {\n if (this.isApplying) {\n command.execute();\n return;\n }\n\n if (this.batchDepth > 0 && this.currentBatch) {\n command.execute();\n this.currentBatch.push({\n ...command,\n timestamp: command.timestamp ?? Date.now(),\n });\n return;\n }\n\n command.execute();\n\n this.undoStack.push({\n ...command,\n timestamp: command.timestamp ?? Date.now(),\n });\n\n if (this.undoStack.length > this.maxDepth) {\n this.undoStack.shift();\n }\n\n this.redoStack = [];\n this.notify();\n }\n\n /**\n * Executes a command, coalescing it with the previous command if they share\n * the same `tag` and occurred within `windowMs` (default: 300ms).\n * Useful for high-frequency interactions like slider scrubs or node drags.\n */\n public executeMerged(\n command: Command,\n options: MergedExecutionOptions = {},\n ): void {\n const windowMs = options.windowMs ?? 300;\n const now = Date.now();\n\n if (\n command.tag &&\n this.undoStack.length > 0 &&\n this.batchDepth === 0 &&\n !this.isApplying\n ) {\n const top = this.undoStack[this.undoStack.length - 1];\n const elapsed = top.timestamp ? now - top.timestamp : Infinity;\n\n if (top.tag === command.tag && elapsed <= windowMs) {\n command.execute();\n // Replace top with merged command keeping the original initial undo\n const initialUndo = top.undo;\n this.undoStack[this.undoStack.length - 1] = {\n name: command.name,\n tag: command.tag,\n timestamp: now,\n execute: command.execute,\n undo: initialUndo,\n redo: command.redo ?? command.execute,\n };\n this.redoStack = [];\n this.notify();\n return;\n }\n }\n\n this.execute({ ...command, timestamp: now });\n }\n\n /**\n * Batches multiple commands executed within `fn` into a single atomic undo entry.\n */\n public batch(name: string, fn: () => void): void {\n if (this.isApplying) {\n fn();\n return;\n }\n\n if (this.batchDepth > 0) {\n // Already inside a batch; execute directly\n fn();\n return;\n }\n\n this.batchDepth++;\n this.currentBatch = [];\n\n try {\n fn();\n } finally {\n this.batchDepth--;\n const batchCommands = this.currentBatch;\n this.currentBatch = null;\n\n if (batchCommands && batchCommands.length > 0) {\n const compoundCommand: Command = {\n name,\n timestamp: Date.now(),\n execute: () => {\n for (let i = 0; i < batchCommands.length; i++) {\n (batchCommands[i].redo ?? batchCommands[i].execute)();\n }\n },\n undo: () => {\n for (let i = batchCommands.length - 1; i >= 0; i--) {\n batchCommands[i].undo();\n }\n },\n redo: () => {\n for (let i = 0; i < batchCommands.length; i++) {\n (batchCommands[i].redo ?? batchCommands[i].execute)();\n }\n },\n };\n\n this.undoStack.push(compoundCommand);\n if (this.undoStack.length > this.maxDepth) {\n this.undoStack.shift();\n }\n this.redoStack = [];\n this.notify();\n }\n }\n }\n\n /**\n * Reverts the most recent command on the undo stack.\n * Returns true if a command was undone, false otherwise.\n */\n public undo(): boolean {\n if (this.undoStack.length === 0 || this.isApplying || this.batchDepth > 0) {\n return false;\n }\n\n this.isApplying = true;\n try {\n const command = this.undoStack.pop()!;\n command.undo();\n this.redoStack.push(command);\n return true;\n } finally {\n this.isApplying = false;\n this.notify();\n }\n }\n\n /**\n * Re-applies the most recent undone command on the redo stack.\n * Returns true if a command was redone, false otherwise.\n */\n public redo(): boolean {\n if (this.redoStack.length === 0 || this.isApplying || this.batchDepth > 0) {\n return false;\n }\n\n this.isApplying = true;\n try {\n const command = this.redoStack.pop()!;\n (command.redo ?? command.execute)();\n this.undoStack.push(command);\n return true;\n } finally {\n this.isApplying = false;\n this.notify();\n }\n }\n\n /**\n * Clears both undo and redo stacks.\n */\n public clear(): void {\n this.undoStack = [];\n this.redoStack = [];\n this.notify();\n }\n\n /**\n * Subscribes to history state changes.\n * The listener is immediately invoked with the current state.\n * Returns an unsubscribe function.\n */\n public subscribe(listener: (state: HistoryState) => void): () => void {\n this.listeners.add(listener);\n listener(this.getState());\n return () => {\n this.listeners.delete(listener);\n };\n }\n\n /**\n * Utility helper to create a Command from before/after state snapshots.\n */\n public static createSnapshotCommand<T>(\n options: SnapshotCommandOptions<T>,\n ): Command {\n return {\n name: options.name,\n tag: options.tag,\n execute: () => options.apply(options.after),\n undo: () => options.apply(options.before),\n redo: () => options.apply(options.after),\n };\n }\n}\n\n/**\n * Creates and initializes a new HistoryManager instance.\n */\nexport function createHistoryManager(\n options: HistoryManagerOptions = {},\n): HistoryManager {\n return new HistoryManager(options);\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
@@ -1,46 +1,4 @@
1
- "use strict";
2
- var __defProp = Object.defineProperty;
3
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
- var __getOwnPropNames = Object.getOwnPropertyNames;
5
- var __hasOwnProp = Object.prototype.hasOwnProperty;
6
- var __export = (target, all) => {
7
- for (var name in all)
8
- __defProp(target, name, { get: all[name], enumerable: true });
9
- };
10
- var __copyProps = (to, from, except, desc) => {
11
- if (from && typeof from === "object" || typeof from === "function") {
12
- for (let key of __getOwnPropNames(from))
13
- if (!__hasOwnProp.call(to, key) && key !== except)
14
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
- }
16
- return to;
17
- };
18
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
-
20
- // src/image-editor/index.ts
21
- var image_editor_exports = {};
22
- __export(image_editor_exports, {
23
- DEFAULT_ADJUSTMENTS: () => DEFAULT_ADJUSTMENTS,
24
- DEFAULT_DEPTH_MASK: () => DEFAULT_DEPTH_MASK,
25
- DEFAULT_TRANSFORM: () => DEFAULT_TRANSFORM,
26
- ImageEditorController: () => ImageEditorController,
27
- ImageEditorRenderer: () => ImageEditorRenderer,
28
- applyAdjustments: () => applyAdjustments,
29
- applyDepthMask: () => applyDepthMask,
30
- calculateCropDrag: () => calculateCropDrag,
31
- canvasToImagePoint: () => canvasToImagePoint,
32
- getAnnotationBounds: () => getAnnotationBounds,
33
- getCropCursor: () => getCropCursor,
34
- getViewportMetrics: () => getViewportMetrics,
35
- globalImageCache: () => globalImageCache,
36
- hitTestAnnotation: () => hitTestAnnotation,
37
- hitTestCrop: () => hitTestCrop,
38
- imageToCanvasPoint: () => imageToCanvasPoint,
39
- removeAlpha: () => removeAlpha
40
- });
41
- module.exports = __toCommonJS(image_editor_exports);
42
-
43
- // src/image-editor/filters.ts
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; } var _class; var _class2; var _class3;// src/image-editor/filters.ts
44
2
  function clamp(value, min = 0, max = 255) {
45
3
  return Math.max(min, Math.min(max, value));
46
4
  }
@@ -191,8 +149,8 @@ function removeAlpha(imageData) {
191
149
  }
192
150
 
193
151
  // src/image-editor/renderer.ts
194
- var ImageCache = class {
195
- cache = /* @__PURE__ */ new Map();
152
+ var ImageCache = (_class = class {constructor() { _class.prototype.__init.call(this); }
153
+ __init() {this.cache = /* @__PURE__ */ new Map()}
196
154
  async get(src) {
197
155
  const existing = this.cache.get(src);
198
156
  if (existing && existing.complete) {
@@ -217,7 +175,7 @@ var ImageCache = class {
217
175
  Object.defineProperty(img, "naturalWidth", { value: 800, configurable: true });
218
176
  Object.defineProperty(img, "naturalHeight", { value: 600, configurable: true });
219
177
  Object.defineProperty(img, "complete", { value: true, configurable: true });
220
- } catch {
178
+ } catch (e2) {
221
179
  }
222
180
  this.cache.set(src, img);
223
181
  resolve(img);
@@ -231,12 +189,12 @@ var ImageCache = class {
231
189
  clear() {
232
190
  this.cache.clear();
233
191
  }
234
- };
192
+ }, _class);
235
193
  var globalImageCache = new ImageCache();
236
- var ImageEditorRenderer = class {
237
- imageCache = globalImageCache;
238
- cachedBaseCanvas = null;
239
- cachedBaseKey = "";
194
+ var ImageEditorRenderer = (_class2 = class {constructor() { _class2.prototype.__init2.call(this);_class2.prototype.__init3.call(this);_class2.prototype.__init4.call(this); }
195
+ __init2() {this.imageCache = globalImageCache}
196
+ __init3() {this.cachedBaseCanvas = null}
197
+ __init4() {this.cachedBaseKey = ""}
240
198
  /**
241
199
  * Helper to create a canvas element safely in browser/JSDOM.
242
200
  */
@@ -289,7 +247,7 @@ var ImageEditorRenderer = class {
289
247
  const isSwapped = angle === 90 || angle === 270;
290
248
  const baseW = isSwapped ? cropH : cropW;
291
249
  const baseH = isSwapped ? cropW : cropH;
292
- const baseKey = `${state.sourceUrl}-${naturalWidth}x${naturalHeight}-${cropX},${cropY},${cropW},${cropH}-${angle},${transform.flipH},${transform.flipV}-${adjustments.brightness},${adjustments.contrast},${adjustments.saturation},${adjustments.exposure},${adjustments.temperature},${adjustments.blur},${adjustments.opacity}-${depthMask.enabled},${depthMask.depthRange?.[0]}-${depthMask.depthRange?.[1]},${depthMask.softness},${depthMask.invert},${depthMask.mode}`;
250
+ const baseKey = `${state.sourceUrl}-${naturalWidth}x${naturalHeight}-${cropX},${cropY},${cropW},${cropH}-${angle},${transform.flipH},${transform.flipV}-${adjustments.brightness},${adjustments.contrast},${adjustments.saturation},${adjustments.exposure},${adjustments.temperature},${adjustments.blur},${adjustments.opacity}-${depthMask.enabled},${_optionalChain([depthMask, 'access', _ => _.depthRange, 'optionalAccess', _2 => _2[0]])}-${_optionalChain([depthMask, 'access', _3 => _3.depthRange, 'optionalAccess', _4 => _4[1]])},${depthMask.softness},${depthMask.invert},${depthMask.mode}`;
293
251
  let baseCanvas = this.cachedBaseCanvas;
294
252
  if (!baseCanvas || this.cachedBaseKey !== baseKey) {
295
253
  baseCanvas = this.createCanvas(baseW, baseH);
@@ -327,7 +285,7 @@ var ImageEditorRenderer = class {
327
285
  applyDepthMask(imageData, maskData, depthMask);
328
286
  }
329
287
  }
330
- } catch {
288
+ } catch (e3) {
331
289
  }
332
290
  }
333
291
  baseCtx.putImageData(imageData, 0, 0);
@@ -359,12 +317,12 @@ var ImageEditorRenderer = class {
359
317
  ctx.restore();
360
318
  ctx.restore();
361
319
  const isCroppingActive = Boolean(options.showCropOverlay || state.activeTool === "crop");
362
- const activeCrop = options.draftCrop !== void 0 && options.draftCrop !== null ? options.draftCrop : crop ?? (isCroppingActive ? {
320
+ const activeCrop = options.draftCrop !== void 0 && options.draftCrop !== null ? options.draftCrop : _nullishCoalesce(crop, () => ( (isCroppingActive ? {
363
321
  x: 0,
364
322
  y: 0,
365
323
  width: naturalWidth,
366
324
  height: naturalHeight
367
- } : null);
325
+ } : null)));
368
326
  if (isCroppingActive && activeCrop) {
369
327
  this.drawCropOverlay(ctx, state, vpWidth, vpHeight, naturalWidth, naturalHeight, activeCrop);
370
328
  }
@@ -475,7 +433,7 @@ var ImageEditorRenderer = class {
475
433
  try {
476
434
  const loadedImg = await this.imageCache.get(imgAnn.src);
477
435
  ctx.drawImage(loadedImg, imgAnn.x, imgAnn.y, imgAnn.width, imgAnn.height);
478
- } catch {
436
+ } catch (e4) {
479
437
  }
480
438
  break;
481
439
  }
@@ -558,12 +516,12 @@ var ImageEditorRenderer = class {
558
516
  * Draws a rule-of-thirds crop grid overlay.
559
517
  */
560
518
  drawCropOverlay(ctx, state, vpWidth, vpHeight, imgWidth, imgHeight, cropOverride) {
561
- const crop = cropOverride !== void 0 && cropOverride !== null ? cropOverride : state.crop ?? {
519
+ const crop = cropOverride !== void 0 && cropOverride !== null ? cropOverride : _nullishCoalesce(state.crop, () => ( {
562
520
  x: 0,
563
521
  y: 0,
564
522
  width: imgWidth,
565
523
  height: imgHeight
566
- };
524
+ }));
567
525
  if (!crop) return;
568
526
  const { transform, pan, zoom } = state;
569
527
  const angle = (transform.rotate % 360 + 360) % 360;
@@ -683,7 +641,7 @@ var ImageEditorRenderer = class {
683
641
  applyDepthMask(imageData, maskData, depthMask);
684
642
  }
685
643
  }
686
- } catch {
644
+ } catch (e5) {
687
645
  }
688
646
  }
689
647
  interCtx.putImageData(imageData, 0, 0);
@@ -714,8 +672,8 @@ var ImageEditorRenderer = class {
714
672
  if (!ctx) return maskCanvas;
715
673
  ctx.fillStyle = "#000000";
716
674
  ctx.fillRect(0, 0, naturalWidth, naturalHeight);
717
- const useCrop = options?.useCrop ?? true;
718
- const useAnnotations = options?.useAnnotations ?? true;
675
+ const useCrop = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _5 => _5.useCrop]), () => ( true));
676
+ const useAnnotations = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _6 => _6.useAnnotations]), () => ( true));
719
677
  if (useCrop && state.crop) {
720
678
  ctx.fillStyle = "#ffffff";
721
679
  ctx.fillRect(state.crop.x, state.crop.y, state.crop.width, state.crop.height);
@@ -762,7 +720,7 @@ var ImageEditorRenderer = class {
762
720
  }
763
721
  return maskCanvas;
764
722
  }
765
- };
723
+ }, _class2);
766
724
 
767
725
  // src/image-editor/controller.ts
768
726
  var DEFAULT_ADJUSTMENTS = {
@@ -787,42 +745,42 @@ var DEFAULT_DEPTH_MASK = {
787
745
  softness: 10,
788
746
  invert: false
789
747
  };
790
- var ImageEditorController = class {
791
- state;
792
- renderer;
793
- imageElement = null;
794
- listeners = /* @__PURE__ */ new Set();
795
- onStateChange;
748
+ var ImageEditorController = (_class3 = class {
749
+
750
+
751
+ __init5() {this.imageElement = null}
752
+ __init6() {this.listeners = /* @__PURE__ */ new Set()}
753
+
796
754
  // History stacks
797
- undoStack = [];
798
- redoStack = [];
799
- maxHistoryDepth;
800
- isApplyingHistory = false;
801
- initialSnapshot;
802
- constructor(options = {}) {
803
- this.maxHistoryDepth = options.maxHistoryDepth ?? 50;
755
+ __init7() {this.undoStack = []}
756
+ __init8() {this.redoStack = []}
757
+
758
+ __init9() {this.isApplyingHistory = false}
759
+
760
+ constructor(options = {}) {;_class3.prototype.__init5.call(this);_class3.prototype.__init6.call(this);_class3.prototype.__init7.call(this);_class3.prototype.__init8.call(this);_class3.prototype.__init9.call(this);
761
+ this.maxHistoryDepth = _nullishCoalesce(options.maxHistoryDepth, () => ( 50));
804
762
  this.onStateChange = options.onStateChange;
805
763
  this.renderer = new ImageEditorRenderer();
806
764
  const initialAdjustments = {
807
765
  ...DEFAULT_ADJUSTMENTS,
808
- ...options.initialState?.adjustments
766
+ ..._optionalChain([options, 'access', _7 => _7.initialState, 'optionalAccess', _8 => _8.adjustments])
809
767
  };
810
768
  const initialTransform = {
811
769
  ...DEFAULT_TRANSFORM,
812
- ...options.initialState?.transform
770
+ ..._optionalChain([options, 'access', _9 => _9.initialState, 'optionalAccess', _10 => _10.transform])
813
771
  };
814
772
  const initialDepthMask = {
815
773
  ...DEFAULT_DEPTH_MASK,
816
- ...options.initialState?.depthMask
774
+ ..._optionalChain([options, 'access', _11 => _11.initialState, 'optionalAccess', _12 => _12.depthMask])
817
775
  };
818
776
  this.state = {
819
777
  sourceUrl: typeof options.image === "string" ? options.image : null,
820
778
  imageDimensions: { width: 800, height: 600 },
821
- crop: options.initialState?.crop ?? null,
779
+ crop: _nullishCoalesce(_optionalChain([options, 'access', _13 => _13.initialState, 'optionalAccess', _14 => _14.crop]), () => ( null)),
822
780
  transform: initialTransform,
823
781
  adjustments: initialAdjustments,
824
782
  depthMask: initialDepthMask,
825
- annotations: options.initialState?.annotations ?? [],
783
+ annotations: _nullishCoalesce(_optionalChain([options, 'access', _15 => _15.initialState, 'optionalAccess', _16 => _16.annotations]), () => ( [])),
826
784
  selectedAnnotationId: null,
827
785
  activeTool: "select",
828
786
  zoom: 1,
@@ -881,7 +839,7 @@ var ImageEditorController = class {
881
839
  }
882
840
  notify() {
883
841
  const currentState = { ...this.state };
884
- this.onStateChange?.(currentState);
842
+ _optionalChain([this, 'access', _17 => _17.onStateChange, 'optionalCall', _18 => _18(currentState)]);
885
843
  this.listeners.forEach((l) => l(currentState));
886
844
  }
887
845
  // --- History (Undo / Redo / Reset) ---
@@ -1106,7 +1064,7 @@ var ImageEditorController = class {
1106
1064
  if (!source) return;
1107
1065
  try {
1108
1066
  await this.renderer.renderToCanvas(targetCanvas, source, this.state, options);
1109
- } catch {
1067
+ } catch (e6) {
1110
1068
  }
1111
1069
  }
1112
1070
  async renderExport(options) {
@@ -1119,13 +1077,13 @@ var ImageEditorController = class {
1119
1077
  async toDataURL(options = {}) {
1120
1078
  const canvas = await this.renderExport(options);
1121
1079
  const format = options.format || "image/png";
1122
- const quality = options.quality ?? 0.92;
1080
+ const quality = _nullishCoalesce(options.quality, () => ( 0.92));
1123
1081
  return canvas.toDataURL(format, quality);
1124
1082
  }
1125
1083
  async toBlob(options = {}) {
1126
1084
  const canvas = await this.renderExport(options);
1127
1085
  const format = options.format || "image/png";
1128
- const quality = options.quality ?? 0.92;
1086
+ const quality = _nullishCoalesce(options.quality, () => ( 0.92));
1129
1087
  return new Promise((resolve, reject) => {
1130
1088
  if (canvas.toBlob) {
1131
1089
  canvas.toBlob((blob) => {
@@ -1198,14 +1156,14 @@ var ImageEditorController = class {
1198
1156
  };
1199
1157
  this.state.annotations = JSON.parse(JSON.stringify(data.annotations || []));
1200
1158
  }
1201
- };
1159
+ }, _class3);
1202
1160
 
1203
1161
  // src/image-editor/geometry.ts
1204
1162
  function getViewportMetrics(state, vpWidth, vpHeight, isActivelyCropping = false, cropOverride) {
1205
1163
  const { imageDimensions, crop: stateCrop, transform, zoom, pan } = state;
1206
1164
  const naturalWidth = imageDimensions.width || 800;
1207
1165
  const naturalHeight = imageDimensions.height || 600;
1208
- const activeCrop = cropOverride !== void 0 && cropOverride !== null ? cropOverride : stateCrop ?? (isActivelyCropping ? { x: 0, y: 0, width: naturalWidth, height: naturalHeight } : null);
1166
+ const activeCrop = cropOverride !== void 0 && cropOverride !== null ? cropOverride : _nullishCoalesce(stateCrop, () => ( (isActivelyCropping ? { x: 0, y: 0, width: naturalWidth, height: naturalHeight } : null)));
1209
1167
  const cropW = !isActivelyCropping && activeCrop ? activeCrop.width : naturalWidth;
1210
1168
  const cropH = !isActivelyCropping && activeCrop ? activeCrop.height : naturalHeight;
1211
1169
  const angle = (transform.rotate % 360 + 360) % 360;
@@ -1419,24 +1377,23 @@ function hitTestAnnotation(imgPt, ann, padding = 10) {
1419
1377
  const b = getAnnotationBounds(ann);
1420
1378
  return imgPt.x >= b.x - padding && imgPt.x <= b.x + b.width + padding && imgPt.y >= b.y - padding && imgPt.y <= b.y + b.height + padding;
1421
1379
  }
1422
- // Annotate the CommonJS export names for ESM import in node:
1423
- 0 && (module.exports = {
1424
- DEFAULT_ADJUSTMENTS,
1425
- DEFAULT_DEPTH_MASK,
1426
- DEFAULT_TRANSFORM,
1427
- ImageEditorController,
1428
- ImageEditorRenderer,
1429
- applyAdjustments,
1430
- applyDepthMask,
1431
- calculateCropDrag,
1432
- canvasToImagePoint,
1433
- getAnnotationBounds,
1434
- getCropCursor,
1435
- getViewportMetrics,
1436
- globalImageCache,
1437
- hitTestAnnotation,
1438
- hitTestCrop,
1439
- imageToCanvasPoint,
1440
- removeAlpha
1441
- });
1380
+
1381
+
1382
+
1383
+
1384
+
1385
+
1386
+
1387
+
1388
+
1389
+
1390
+
1391
+
1392
+
1393
+
1394
+
1395
+
1396
+
1397
+
1398
+ exports.DEFAULT_ADJUSTMENTS = DEFAULT_ADJUSTMENTS; exports.DEFAULT_DEPTH_MASK = DEFAULT_DEPTH_MASK; exports.DEFAULT_TRANSFORM = DEFAULT_TRANSFORM; exports.ImageEditorController = ImageEditorController; exports.ImageEditorRenderer = ImageEditorRenderer; exports.applyAdjustments = applyAdjustments; exports.applyDepthMask = applyDepthMask; exports.calculateCropDrag = calculateCropDrag; exports.canvasToImagePoint = canvasToImagePoint; exports.getAnnotationBounds = getAnnotationBounds; exports.getCropCursor = getCropCursor; exports.getViewportMetrics = getViewportMetrics; exports.globalImageCache = globalImageCache; exports.hitTestAnnotation = hitTestAnnotation; exports.hitTestCrop = hitTestCrop; exports.imageToCanvasPoint = imageToCanvasPoint; exports.removeAlpha = removeAlpha;
1442
1399
  //# sourceMappingURL=index.cjs.map