@pixerate/editor 0.27.0 → 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.
- package/README.md +44 -2
- package/dist/HistoryManager-DWSLd6Tf.d.ts +150 -0
- package/dist/HistoryManager-DeQQMBCj.d.cts +150 -0
- package/dist/agent/index.cjs +20 -427
- package/dist/agent/index.cjs.map +1 -1
- package/dist/agent/index.d.cts +4 -342
- package/dist/agent/index.d.ts +4 -342
- package/dist/agent/index.js +14 -421
- package/dist/agent/index.js.map +1 -1
- package/dist/animation/index.cjs +62 -0
- package/dist/animation/index.cjs.map +1 -0
- package/dist/animation/index.d.cts +226 -0
- package/dist/animation/index.d.ts +226 -0
- package/dist/animation/index.js +62 -0
- package/dist/animation/index.js.map +1 -0
- package/dist/{builtins-nMXh9sT3.d.cts → builtins-DxC3aUR2.d.cts} +2 -2
- package/dist/{builtins-haN82vjT.d.ts → builtins-NGxNxQfJ.d.ts} +2 -2
- package/dist/canvas/index.cjs +177 -743
- package/dist/canvas/index.cjs.map +1 -1
- package/dist/canvas/index.d.cts +6 -289
- package/dist/canvas/index.d.ts +6 -289
- package/dist/canvas/index.js +49 -615
- package/dist/canvas/index.js.map +1 -1
- package/dist/chunk-36BLROHV.js +438 -0
- package/dist/chunk-36BLROHV.js.map +1 -0
- package/dist/{chunk-JT7AXQTE.js → chunk-3RPOW4CS.js} +7 -7
- package/dist/{chunk-AGR7EVRW.cjs → chunk-6MDQKHRH.cjs} +6 -6
- package/dist/{chunk-AGR7EVRW.cjs.map → chunk-6MDQKHRH.cjs.map} +1 -1
- package/dist/chunk-A6PHCAGX.cjs +87 -0
- package/dist/chunk-A6PHCAGX.cjs.map +1 -0
- package/dist/{chunk-HRMEDT2L.js → chunk-D6AVOTSD.js} +6 -85
- package/dist/chunk-D6AVOTSD.js.map +1 -0
- package/dist/{chunk-ARRTP33I.js → chunk-D6S5M7HV.js} +2 -2
- package/dist/{chunk-ARRTP33I.js.map → chunk-D6S5M7HV.js.map} +1 -1
- package/dist/{chunk-6IO7WUSU.js → chunk-DDADOHJW.js} +17 -17
- package/dist/{chunk-CPOKFNBG.cjs → chunk-I6BZB5ZH.cjs} +2 -2
- package/dist/{chunk-CPOKFNBG.cjs.map → chunk-I6BZB5ZH.cjs.map} +1 -1
- package/dist/{chunk-4BVP64JJ.cjs → chunk-K2UYKJ6M.cjs} +24 -103
- package/dist/chunk-K2UYKJ6M.cjs.map +1 -0
- package/dist/chunk-PIIAZV3L.cjs +244 -0
- package/dist/chunk-PIIAZV3L.cjs.map +1 -0
- package/dist/chunk-PWJARCI4.js +637 -0
- package/dist/chunk-PWJARCI4.js.map +1 -0
- package/dist/{chunk-G2I4QJOT.cjs → chunk-QKLRAA4T.cjs} +3 -244
- package/dist/chunk-QKLRAA4T.cjs.map +1 -0
- package/dist/{chunk-2H7ZHPEJ.js → chunk-QVZZGT4X.js} +1 -242
- package/dist/chunk-QVZZGT4X.js.map +1 -0
- package/dist/chunk-TGD52FEZ.js +87 -0
- package/dist/chunk-TGD52FEZ.js.map +1 -0
- package/dist/chunk-TTYCN6ZH.cjs +637 -0
- package/dist/chunk-TTYCN6ZH.cjs.map +1 -0
- package/dist/{chunk-YK5TATOF.cjs → chunk-U7VGDSNY.cjs} +3 -3
- package/dist/{chunk-YK5TATOF.cjs.map → chunk-U7VGDSNY.cjs.map} +1 -1
- package/dist/chunk-V7CC7RZ6.cjs +438 -0
- package/dist/chunk-V7CC7RZ6.cjs.map +1 -0
- package/dist/chunk-YK57D7PW.js +244 -0
- package/dist/chunk-YK57D7PW.js.map +1 -0
- package/dist/commands/index.cjs +2 -2
- package/dist/commands/index.cjs.map +1 -1
- package/dist/commands/index.d.cts +2 -2
- package/dist/commands/index.d.ts +2 -2
- package/dist/commands/index.js +1 -1
- package/dist/commands/index.js.map +1 -1
- package/dist/easing-B6iAnJHk.d.cts +74 -0
- package/dist/easing-B6iAnJHk.d.ts +74 -0
- package/dist/extensions/index.cjs +5 -5
- package/dist/extensions/index.cjs.map +1 -1
- package/dist/extensions/index.js +4 -4
- package/dist/generation/index.cjs +4 -4
- package/dist/generation/index.cjs.map +1 -1
- package/dist/generation/index.js +3 -3
- package/dist/generation/index.js.map +1 -1
- package/dist/history/index.cjs +4 -2
- package/dist/history/index.cjs.map +1 -1
- package/dist/history/index.d.cts +3 -149
- package/dist/history/index.d.ts +3 -149
- package/dist/history/index.js +5 -3
- package/dist/image-editor/index.cjs.map +1 -1
- package/dist/image-editor/index.js.map +1 -1
- package/dist/index.cjs +24 -22
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +3 -2
- package/dist/index.d.ts +3 -2
- package/dist/index.js +112 -110
- package/dist/index.js.map +1 -1
- package/dist/parameters/index.cjs +1283 -0
- package/dist/parameters/index.cjs.map +1 -0
- package/dist/parameters/index.d.cts +595 -0
- package/dist/parameters/index.d.ts +595 -0
- package/dist/parameters/index.js +1283 -0
- package/dist/parameters/index.js.map +1 -0
- package/dist/spreadsheet/index.cjs +4 -4
- package/dist/spreadsheet/index.cjs.map +1 -1
- package/dist/spreadsheet/index.js +8 -8
- package/dist/tokens/index.cjs +4 -2
- package/dist/tokens/index.cjs.map +1 -1
- package/dist/tokens/index.js +6 -4
- package/dist/tools/index.cjs +31 -0
- package/dist/tools/index.cjs.map +1 -0
- package/dist/tools/index.d.cts +343 -0
- package/dist/tools/index.d.ts +343 -0
- package/dist/tools/index.js +31 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/{types-GT5a5YAX.d.cts → types-DsiXGmjo.d.cts} +1 -1
- package/dist/{types-GT5a5YAX.d.ts → types-DsiXGmjo.d.ts} +1 -1
- package/package.json +16 -1
- package/dist/chunk-2H7ZHPEJ.js.map +0 -1
- package/dist/chunk-4BVP64JJ.cjs.map +0 -1
- package/dist/chunk-G2I4QJOT.cjs.map +0 -1
- package/dist/chunk-HRMEDT2L.js.map +0 -1
- /package/dist/{chunk-JT7AXQTE.js.map → chunk-3RPOW4CS.js.map} +0 -0
- /package/dist/{chunk-6IO7WUSU.js.map → chunk-DDADOHJW.js.map} +0 -0
package/README.md
CHANGED
|
@@ -208,6 +208,23 @@ await registry.callTool("insert_text", { text: "Hello" }); // { content: [...],
|
|
|
208
208
|
|
|
209
209
|
`createEditorMcpToolProvider` exposes the static tools (`get_editor_state`, `edit_canvas`, `edit_prompt`, `view_editor`) through the registry, and `planToolCall` turns any tool call into planner steps (`step:tool_call` for registry tools).
|
|
210
210
|
|
|
211
|
+
### Without TipTap: `@pixerate/editor/tools`
|
|
212
|
+
|
|
213
|
+
`@pixerate/editor/agent` loads TipTap, ProseMirror and (through the canvas planner) dagre, because the rich-text, spreadsheet and canvas providers live there. Hosts that only need the registry, such as a canvas-only app or an effect editor exposing commands, can import it from `@pixerate/editor/tools`, which has no third-party imports:
|
|
214
|
+
|
|
215
|
+
```ts
|
|
216
|
+
import { createToolRegistry } from "@pixerate/editor/tools";
|
|
217
|
+
import { createCommandToolProvider } from "@pixerate/editor/commands";
|
|
218
|
+
|
|
219
|
+
const registry = createToolRegistry();
|
|
220
|
+
registry.register(createCommandToolProvider(commands, { id: "effects" }));
|
|
221
|
+
|
|
222
|
+
const list = registry.listTools(); // MCP tools/list result
|
|
223
|
+
const result = await registry.callTool(name, args); // MCP tools/call result
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
It exports `ToolRegistry`, `createToolRegistry`, `ToolRegistryError`, the tool types (`AgentTool`, `AgentToolProvider`, `AgentToolHandler`, `ToolCallContext`, `McpToolDefinition`, `McpToolResult`, `McpListToolsResult`, `ToolCallError`), `validateJsonSchema` / `SchemaValidationError`, and the static `EDITOR_MCP_TOOLS` definitions. `/agent` re-exports all of it, so existing imports keep working. `createEditorMcpToolProvider` stays in `/agent` because its `layout` operation runs dagre.
|
|
227
|
+
|
|
211
228
|
## Commands, shortcuts and the command palette
|
|
212
229
|
|
|
213
230
|
`@pixerate/editor/commands` gives every action one id that menus, keyboard shortcuts, the command palette and agents all run, so they share enablement and parameter validation. It has no third-party imports.
|
|
@@ -399,16 +416,41 @@ Each module is also available as a subpath import:
|
|
|
399
416
|
| `@pixerate/editor/history` | `HistoryManager`: a command-pattern undo/redo stack with gesture merge keys, undo marks, a byte budget and a History-panel listing; `DirtyTracker` / `bindDirtyToHistory` |
|
|
400
417
|
| `@pixerate/editor/spreadsheet` | `SpreadsheetController`, formula parser/evaluator and dependency graph, formula function registry (`registerFormulaFunction`, `listFormulaFunctions`, `searchFormulaFunctions`, `getFormulaSignature`) and autocomplete helpers (`getFormulaHints`, `applyFormulaSuggestion`) |
|
|
401
418
|
| `@pixerate/editor/image-editor` | `ImageEditorController` and Canvas 2D renderer: crop, adjustments, annotations, depth masks, selections and layer masks, and AI hooks. Needs a DOM/canvas environment (the selection algorithms themselves are pure). |
|
|
402
|
-
| `@pixerate/editor/
|
|
419
|
+
| `@pixerate/editor/animation` | The keyframe model without canvas nodes: `AnimationTrack` / `AnimationKeyframe`, easing (`resolveEasing`, `evaluateEasing`, `cubicBezierAt`, `springAt`, presets, `parseCssEasing`, `easingToCss`), `evaluateTrack`, `interpolateAnimationValue`, `normalizeKeyframes`, OKLab colour mixing, `AnimationPlayer` and the `Clock` / `ManualClock` / `realClock` time sources (no third-party imports) |
|
|
420
|
+
| `@pixerate/editor/canvas` | Node-graph layout (needs the optional `@dagrejs/dagre` peer), placement, trajectories, displacement, clipboard and streaming layout helpers, and node keyframe animation (re-exports everything in `/animation`) |
|
|
403
421
|
| `@pixerate/editor/agent` | MCP tool schemas, a planner for agent-driven canvas edits, and the dynamic `ToolRegistry` with editor/spreadsheet tool providers |
|
|
422
|
+
| `@pixerate/editor/tools` | `ToolRegistry`, tool types, `validateJsonSchema` and the static MCP tool definitions, without TipTap or dagre (no third-party imports) |
|
|
404
423
|
| `@pixerate/editor/commands` | `CommandRegistry`, `ShortcutMap`, palette ranking, `createCommandToolProvider` and built-in history / arrange / spreadsheet commands (no third-party imports) |
|
|
405
424
|
| `@pixerate/editor/persistence` | Autosave and crash recovery (`createAutosaveController`, `createRecoveryPolicy`, `createRevisionTracker`), storage adapters (memory, localStorage, IndexedDB, OPFS) and document migration (`migrateDocument`, `loadSections`, `LoadReport`) (no third-party imports) |
|
|
406
425
|
| `@pixerate/editor/generation` | Model capability descriptors, `planGenerationRequest`, `capabilitiesToJsonSchema`, `createGenerationToolProvider`, provenance, `createBatchResolver` and job-progress estimates (no third-party imports) |
|
|
407
426
|
| `@pixerate/editor/compare` | `diffSequences` (Myers + patience), `compareDocuments` and `compareHtml`: two versions of a document as tracked changes (also re-exported from the root entry) |
|
|
408
427
|
| `@pixerate/editor/export` | Word export: `exportDocx`, `exportDocxBlob`, `createDocxParts`, `DocxExportController`, plus the zip writer and XML escapers it uses (no third-party imports; also re-exported from the root entry) |
|
|
409
428
|
| `@pixerate/editor/tokens` | Design tokens: collections, modes, aliases, `TokenStore`, `resolveToken`, W3C Design Tokens JSON and CSS custom-property export (no third-party imports) |
|
|
429
|
+
| `@pixerate/editor/parameters` | Schema-driven parameters editor for effects, shaders, generators and component props: `ParameterSchema` (number, int, boolean, choice, color, vector, image and text fields; groups; `showIf`), `ParametersController` (validation, undo with merged slider gestures, reset, randomize, presets, keyframe hooks), `createParameterCommands` for agents and `parameterSchemaFromShaderControls` (no third-party imports) |
|
|
430
|
+
|
|
431
|
+
The root entry (`@pixerate/editor`) re-exports everything except animation, canvas, agent, commands, persistence, generation, tokens, parameters and image editor, including TipTap. Import from the narrowest subpath you need: `grammar`, `history`, `animation`, `spreadsheet`, `commands`, `persistence` and `image-editor` have no third-party imports, so a spreadsheet-only app bundles no TipTap, markdown or dagre code. The package is marked `sideEffects: false`, so unused root exports are also tree-shaken.
|
|
432
|
+
|
|
433
|
+
## Keyframe animation without the canvas
|
|
434
|
+
|
|
435
|
+
`@pixerate/editor/animation` is the keyframe model on its own: no dagre, TipTap or canvas nodes. Use it to animate anything you can describe as a track of numbers or CSS colours.
|
|
436
|
+
|
|
437
|
+
```ts
|
|
438
|
+
import { evaluateTrack, createAnimationPlayer, ManualClock, type AnimationTrack } from "@pixerate/editor/animation";
|
|
439
|
+
|
|
440
|
+
const opacity: AnimationTrack = {
|
|
441
|
+
keyframes: [
|
|
442
|
+
{ time: 0, value: 0, easing: "ease-out" },
|
|
443
|
+
{ time: 600, value: 1, easing: { type: "spring", stiffness: 170, damping: 26 } },
|
|
444
|
+
{ time: 1200, value: 0.5 },
|
|
445
|
+
],
|
|
446
|
+
};
|
|
447
|
+
evaluateTrack(opacity, 300); // eased value at 300 ms
|
|
448
|
+
evaluateTrack({ keyframes: [{ time: 0, value: "#ff0000" }, { time: 1000, value: "transparent" }] }, 500, "color"); // OKLab mix
|
|
449
|
+
|
|
450
|
+
const player = createAnimationPlayer({ clock: new ManualClock(), duration: 1200, loop: "ping-pong", onTime: (t) => console.log(evaluateTrack(opacity, t)) });
|
|
451
|
+
```
|
|
410
452
|
|
|
411
|
-
|
|
453
|
+
`@pixerate/editor/canvas` re-exports all of it, and adds node tracks (`evaluateAnimation`, `applyAnimation`), editing, timeline and export helpers on top.
|
|
412
454
|
|
|
413
455
|
## Autosave, crash recovery and document migration
|
|
414
456
|
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
import { a as HistoryManagerOptions, H as HistoryState, C as Command, M as MergedExecutionOptions, b as HistoryMark, c as HistoryEntry, S as SnapshotCommandOptions } from './types-DsiXGmjo.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* UI-agnostic History and Undo/Redo manager supporting command closures,
|
|
5
|
+
* snapshot diffs, transaction batching, high-frequency event coalescing,
|
|
6
|
+
* keyed gestures, undo marks, a memory budget and a History-panel listing.
|
|
7
|
+
*/
|
|
8
|
+
declare class HistoryManager {
|
|
9
|
+
private undoStack;
|
|
10
|
+
private redoStack;
|
|
11
|
+
private readonly maxDepth;
|
|
12
|
+
private readonly maxBytes;
|
|
13
|
+
private readonly sizeOf?;
|
|
14
|
+
private isApplying;
|
|
15
|
+
private batchDepth;
|
|
16
|
+
private currentBatch;
|
|
17
|
+
private listeners;
|
|
18
|
+
private onStateChange?;
|
|
19
|
+
private cachedState;
|
|
20
|
+
private cachedEntries;
|
|
21
|
+
private nextId;
|
|
22
|
+
private revision;
|
|
23
|
+
/** Bumped by `clear()`; marks from an earlier epoch are stale. */
|
|
24
|
+
private epoch;
|
|
25
|
+
/** Number of steps dropped from the bottom (depth / byte budget) so far. */
|
|
26
|
+
private dropped;
|
|
27
|
+
/** Key of the gesture that the top step belongs to (see `executeMerged`). */
|
|
28
|
+
private gestureKey;
|
|
29
|
+
private gestureEntryId;
|
|
30
|
+
/** Key every merged execute takes while a gesture is held (`beginGesture`). */
|
|
31
|
+
private heldKey;
|
|
32
|
+
constructor(options?: HistoryManagerOptions);
|
|
33
|
+
private computeState;
|
|
34
|
+
/**
|
|
35
|
+
* Returns a snapshot of the current history state.
|
|
36
|
+
* Cached to maintain referential equality across renders for useSyncExternalStore.
|
|
37
|
+
*/
|
|
38
|
+
getState(): HistoryState;
|
|
39
|
+
/**
|
|
40
|
+
* Monotonic counter bumped on every history change (execute, merge, undo,
|
|
41
|
+
* redo, revert, clear). Useful as a cache key, e.g. for `DirtyTracker`.
|
|
42
|
+
*/
|
|
43
|
+
getRevision(): number;
|
|
44
|
+
private notify;
|
|
45
|
+
private measure;
|
|
46
|
+
private makeEntry;
|
|
47
|
+
/** Pushes a step, clears redo and applies the depth and byte limits. */
|
|
48
|
+
private record;
|
|
49
|
+
/**
|
|
50
|
+
* Keeps the stacks within `maxBytes`: the oldest undo steps that do not fit
|
|
51
|
+
* are dropped, but the most recent undo step is always kept.
|
|
52
|
+
*/
|
|
53
|
+
private trim;
|
|
54
|
+
/** Approximate bytes held by the undo and redo stacks (see `maxBytes`). */
|
|
55
|
+
getByteSize(): number;
|
|
56
|
+
private resetGesture;
|
|
57
|
+
/**
|
|
58
|
+
* Executes a command and pushes it onto the undo stack.
|
|
59
|
+
* Clears the redo stack and ends the current gesture.
|
|
60
|
+
*/
|
|
61
|
+
execute(command: Command): void;
|
|
62
|
+
/**
|
|
63
|
+
* Executes a command as part of a continuous interaction (slider scrub, node drag).
|
|
64
|
+
*
|
|
65
|
+
* - With `options.key` (or while a gesture is held with `beginGesture`):
|
|
66
|
+
* consecutive merged executes with the same key fold into one undo step,
|
|
67
|
+
* however long the gesture lasts. Recording any other command, undo, redo,
|
|
68
|
+
* `revertTo`, `goTo`, `clear` or `endGesture()` ends the gesture.
|
|
69
|
+
* - Without a key: coalesces with the previous command if they share the same
|
|
70
|
+
* `tag` and occurred within `windowMs` (default: 300ms).
|
|
71
|
+
*/
|
|
72
|
+
executeMerged(command: Command, options?: MergedExecutionOptions): void;
|
|
73
|
+
/**
|
|
74
|
+
* Holds a gesture: until `endGesture()`, every `executeMerged` call (whatever
|
|
75
|
+
* its own key or tag) joins one undo step, e.g. an automation pass and
|
|
76
|
+
* whatever is dragged during it. Commands recorded with `execute` still end
|
|
77
|
+
* the current step; the next merged execute then starts a new one.
|
|
78
|
+
*/
|
|
79
|
+
beginGesture(key: string): void;
|
|
80
|
+
/** Ends the current (keyed or held) gesture; the next merged execute starts a new step. */
|
|
81
|
+
endGesture(): void;
|
|
82
|
+
/** The key of the gesture currently merging into the top step, if any. */
|
|
83
|
+
getGestureKey(): string | null;
|
|
84
|
+
/**
|
|
85
|
+
* Batches multiple commands executed within `fn` into a single atomic undo entry.
|
|
86
|
+
*/
|
|
87
|
+
batch(name: string, fn: () => void): void;
|
|
88
|
+
/**
|
|
89
|
+
* Reverts already-executed commands of an aborted batch, newest first.
|
|
90
|
+
* Commands executed by the undo closures themselves are not recorded.
|
|
91
|
+
*/
|
|
92
|
+
private rollback;
|
|
93
|
+
/** Undoes the top step (caller holds `isApplying`). Throws leave it on the stack. */
|
|
94
|
+
private undoOne;
|
|
95
|
+
private redoOne;
|
|
96
|
+
/**
|
|
97
|
+
* Reverts the most recent command on the undo stack.
|
|
98
|
+
* Returns true if a command was undone, false otherwise.
|
|
99
|
+
*/
|
|
100
|
+
undo(): boolean;
|
|
101
|
+
/**
|
|
102
|
+
* Re-applies the most recent undone command on the redo stack.
|
|
103
|
+
* Returns true if a command was redone, false otherwise.
|
|
104
|
+
*/
|
|
105
|
+
redo(): boolean;
|
|
106
|
+
/**
|
|
107
|
+
* Captures the current point in the history (its top step), for `revertTo`.
|
|
108
|
+
*/
|
|
109
|
+
mark(): HistoryMark;
|
|
110
|
+
/** Whether `mark` still points into the undo history. */
|
|
111
|
+
isMarkValid(mark: HistoryMark): boolean;
|
|
112
|
+
/**
|
|
113
|
+
* Takes back every step made since `mark` (merged or not), e.g. to cancel a
|
|
114
|
+
* drag with Escape: the state returns to how it was at `mark`, and neither
|
|
115
|
+
* undo nor redo keeps the reverted steps. Does nothing when `mark` has left
|
|
116
|
+
* the history (undone past, dropped by the limits, or cleared).
|
|
117
|
+
* Returns how many steps were taken back.
|
|
118
|
+
*/
|
|
119
|
+
revertTo(mark: HistoryMark): number;
|
|
120
|
+
/**
|
|
121
|
+
* Lists the steps for a History panel: undo steps oldest first, then redo
|
|
122
|
+
* steps (the next redo first). Cached until the history changes.
|
|
123
|
+
*/
|
|
124
|
+
getEntries(): HistoryEntry[];
|
|
125
|
+
/**
|
|
126
|
+
* Undoes or redoes until the step at `index` (from `getEntries`) is the
|
|
127
|
+
* current one; `-1` undoes everything. Returns how many steps were applied.
|
|
128
|
+
*/
|
|
129
|
+
goTo(index: number): number;
|
|
130
|
+
/**
|
|
131
|
+
* Clears both undo and redo stacks.
|
|
132
|
+
*/
|
|
133
|
+
clear(): void;
|
|
134
|
+
/**
|
|
135
|
+
* Subscribes to history state changes.
|
|
136
|
+
* The listener is immediately invoked with the current state.
|
|
137
|
+
* Returns an unsubscribe function.
|
|
138
|
+
*/
|
|
139
|
+
subscribe(listener: (state: HistoryState) => void): () => void;
|
|
140
|
+
/**
|
|
141
|
+
* Utility helper to create a Command from before/after state snapshots.
|
|
142
|
+
*/
|
|
143
|
+
static createSnapshotCommand<T>(options: SnapshotCommandOptions<T>): Command;
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Creates and initializes a new HistoryManager instance.
|
|
147
|
+
*/
|
|
148
|
+
declare function createHistoryManager(options?: HistoryManagerOptions): HistoryManager;
|
|
149
|
+
|
|
150
|
+
export { HistoryManager as H, createHistoryManager as c };
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
import { a as HistoryManagerOptions, H as HistoryState, C as Command, M as MergedExecutionOptions, b as HistoryMark, c as HistoryEntry, S as SnapshotCommandOptions } from './types-DsiXGmjo.cjs';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* UI-agnostic History and Undo/Redo manager supporting command closures,
|
|
5
|
+
* snapshot diffs, transaction batching, high-frequency event coalescing,
|
|
6
|
+
* keyed gestures, undo marks, a memory budget and a History-panel listing.
|
|
7
|
+
*/
|
|
8
|
+
declare class HistoryManager {
|
|
9
|
+
private undoStack;
|
|
10
|
+
private redoStack;
|
|
11
|
+
private readonly maxDepth;
|
|
12
|
+
private readonly maxBytes;
|
|
13
|
+
private readonly sizeOf?;
|
|
14
|
+
private isApplying;
|
|
15
|
+
private batchDepth;
|
|
16
|
+
private currentBatch;
|
|
17
|
+
private listeners;
|
|
18
|
+
private onStateChange?;
|
|
19
|
+
private cachedState;
|
|
20
|
+
private cachedEntries;
|
|
21
|
+
private nextId;
|
|
22
|
+
private revision;
|
|
23
|
+
/** Bumped by `clear()`; marks from an earlier epoch are stale. */
|
|
24
|
+
private epoch;
|
|
25
|
+
/** Number of steps dropped from the bottom (depth / byte budget) so far. */
|
|
26
|
+
private dropped;
|
|
27
|
+
/** Key of the gesture that the top step belongs to (see `executeMerged`). */
|
|
28
|
+
private gestureKey;
|
|
29
|
+
private gestureEntryId;
|
|
30
|
+
/** Key every merged execute takes while a gesture is held (`beginGesture`). */
|
|
31
|
+
private heldKey;
|
|
32
|
+
constructor(options?: HistoryManagerOptions);
|
|
33
|
+
private computeState;
|
|
34
|
+
/**
|
|
35
|
+
* Returns a snapshot of the current history state.
|
|
36
|
+
* Cached to maintain referential equality across renders for useSyncExternalStore.
|
|
37
|
+
*/
|
|
38
|
+
getState(): HistoryState;
|
|
39
|
+
/**
|
|
40
|
+
* Monotonic counter bumped on every history change (execute, merge, undo,
|
|
41
|
+
* redo, revert, clear). Useful as a cache key, e.g. for `DirtyTracker`.
|
|
42
|
+
*/
|
|
43
|
+
getRevision(): number;
|
|
44
|
+
private notify;
|
|
45
|
+
private measure;
|
|
46
|
+
private makeEntry;
|
|
47
|
+
/** Pushes a step, clears redo and applies the depth and byte limits. */
|
|
48
|
+
private record;
|
|
49
|
+
/**
|
|
50
|
+
* Keeps the stacks within `maxBytes`: the oldest undo steps that do not fit
|
|
51
|
+
* are dropped, but the most recent undo step is always kept.
|
|
52
|
+
*/
|
|
53
|
+
private trim;
|
|
54
|
+
/** Approximate bytes held by the undo and redo stacks (see `maxBytes`). */
|
|
55
|
+
getByteSize(): number;
|
|
56
|
+
private resetGesture;
|
|
57
|
+
/**
|
|
58
|
+
* Executes a command and pushes it onto the undo stack.
|
|
59
|
+
* Clears the redo stack and ends the current gesture.
|
|
60
|
+
*/
|
|
61
|
+
execute(command: Command): void;
|
|
62
|
+
/**
|
|
63
|
+
* Executes a command as part of a continuous interaction (slider scrub, node drag).
|
|
64
|
+
*
|
|
65
|
+
* - With `options.key` (or while a gesture is held with `beginGesture`):
|
|
66
|
+
* consecutive merged executes with the same key fold into one undo step,
|
|
67
|
+
* however long the gesture lasts. Recording any other command, undo, redo,
|
|
68
|
+
* `revertTo`, `goTo`, `clear` or `endGesture()` ends the gesture.
|
|
69
|
+
* - Without a key: coalesces with the previous command if they share the same
|
|
70
|
+
* `tag` and occurred within `windowMs` (default: 300ms).
|
|
71
|
+
*/
|
|
72
|
+
executeMerged(command: Command, options?: MergedExecutionOptions): void;
|
|
73
|
+
/**
|
|
74
|
+
* Holds a gesture: until `endGesture()`, every `executeMerged` call (whatever
|
|
75
|
+
* its own key or tag) joins one undo step, e.g. an automation pass and
|
|
76
|
+
* whatever is dragged during it. Commands recorded with `execute` still end
|
|
77
|
+
* the current step; the next merged execute then starts a new one.
|
|
78
|
+
*/
|
|
79
|
+
beginGesture(key: string): void;
|
|
80
|
+
/** Ends the current (keyed or held) gesture; the next merged execute starts a new step. */
|
|
81
|
+
endGesture(): void;
|
|
82
|
+
/** The key of the gesture currently merging into the top step, if any. */
|
|
83
|
+
getGestureKey(): string | null;
|
|
84
|
+
/**
|
|
85
|
+
* Batches multiple commands executed within `fn` into a single atomic undo entry.
|
|
86
|
+
*/
|
|
87
|
+
batch(name: string, fn: () => void): void;
|
|
88
|
+
/**
|
|
89
|
+
* Reverts already-executed commands of an aborted batch, newest first.
|
|
90
|
+
* Commands executed by the undo closures themselves are not recorded.
|
|
91
|
+
*/
|
|
92
|
+
private rollback;
|
|
93
|
+
/** Undoes the top step (caller holds `isApplying`). Throws leave it on the stack. */
|
|
94
|
+
private undoOne;
|
|
95
|
+
private redoOne;
|
|
96
|
+
/**
|
|
97
|
+
* Reverts the most recent command on the undo stack.
|
|
98
|
+
* Returns true if a command was undone, false otherwise.
|
|
99
|
+
*/
|
|
100
|
+
undo(): boolean;
|
|
101
|
+
/**
|
|
102
|
+
* Re-applies the most recent undone command on the redo stack.
|
|
103
|
+
* Returns true if a command was redone, false otherwise.
|
|
104
|
+
*/
|
|
105
|
+
redo(): boolean;
|
|
106
|
+
/**
|
|
107
|
+
* Captures the current point in the history (its top step), for `revertTo`.
|
|
108
|
+
*/
|
|
109
|
+
mark(): HistoryMark;
|
|
110
|
+
/** Whether `mark` still points into the undo history. */
|
|
111
|
+
isMarkValid(mark: HistoryMark): boolean;
|
|
112
|
+
/**
|
|
113
|
+
* Takes back every step made since `mark` (merged or not), e.g. to cancel a
|
|
114
|
+
* drag with Escape: the state returns to how it was at `mark`, and neither
|
|
115
|
+
* undo nor redo keeps the reverted steps. Does nothing when `mark` has left
|
|
116
|
+
* the history (undone past, dropped by the limits, or cleared).
|
|
117
|
+
* Returns how many steps were taken back.
|
|
118
|
+
*/
|
|
119
|
+
revertTo(mark: HistoryMark): number;
|
|
120
|
+
/**
|
|
121
|
+
* Lists the steps for a History panel: undo steps oldest first, then redo
|
|
122
|
+
* steps (the next redo first). Cached until the history changes.
|
|
123
|
+
*/
|
|
124
|
+
getEntries(): HistoryEntry[];
|
|
125
|
+
/**
|
|
126
|
+
* Undoes or redoes until the step at `index` (from `getEntries`) is the
|
|
127
|
+
* current one; `-1` undoes everything. Returns how many steps were applied.
|
|
128
|
+
*/
|
|
129
|
+
goTo(index: number): number;
|
|
130
|
+
/**
|
|
131
|
+
* Clears both undo and redo stacks.
|
|
132
|
+
*/
|
|
133
|
+
clear(): void;
|
|
134
|
+
/**
|
|
135
|
+
* Subscribes to history state changes.
|
|
136
|
+
* The listener is immediately invoked with the current state.
|
|
137
|
+
* Returns an unsubscribe function.
|
|
138
|
+
*/
|
|
139
|
+
subscribe(listener: (state: HistoryState) => void): () => void;
|
|
140
|
+
/**
|
|
141
|
+
* Utility helper to create a Command from before/after state snapshots.
|
|
142
|
+
*/
|
|
143
|
+
static createSnapshotCommand<T>(options: SnapshotCommandOptions<T>): Command;
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Creates and initializes a new HistoryManager instance.
|
|
147
|
+
*/
|
|
148
|
+
declare function createHistoryManager(options?: HistoryManagerOptions): HistoryManager;
|
|
149
|
+
|
|
150
|
+
export { HistoryManager as H, createHistoryManager as c };
|