@tldraw/editor 4.5.0-canary.f284eeb67609 → 4.5.0-next.74a79354f99f

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/dist-cjs/index.js CHANGED
@@ -369,7 +369,7 @@ var import_LocalIndexedDb = require("./lib/utils/sync/LocalIndexedDb");
369
369
  var import_uniq = require("./lib/utils/uniq");
370
370
  (0, import_utils.registerTldrawLibraryVersion)(
371
371
  "@tldraw/editor",
372
- "4.5.0-canary.f284eeb67609",
372
+ "4.5.0-next.74a79354f99f",
373
373
  "cjs"
374
374
  );
375
375
  //# sourceMappingURL=index.js.map
@@ -24,15 +24,16 @@ module.exports = __toCommonJS(HistoryManager_exports);
24
24
  var import_state = require("@tldraw/state");
25
25
  var import_store = require("@tldraw/store");
26
26
  var import_utils = require("@tldraw/utils");
27
- const HistoryRecorderState = {
28
- Recording: "recording",
29
- RecordingPreserveRedoStack: "recordingPreserveRedoStack",
30
- Paused: "paused"
31
- };
27
+ var HistoryRecorderState = /* @__PURE__ */ ((HistoryRecorderState2) => {
28
+ HistoryRecorderState2["Recording"] = "recording";
29
+ HistoryRecorderState2["RecordingPreserveRedoStack"] = "recordingPreserveRedoStack";
30
+ HistoryRecorderState2["Paused"] = "paused";
31
+ return HistoryRecorderState2;
32
+ })(HistoryRecorderState || {});
32
33
  class HistoryManager {
33
34
  store;
34
35
  dispose;
35
- state = HistoryRecorderState.Recording;
36
+ state = "recording" /* Recording */;
36
37
  pendingDiff = new PendingDiff();
37
38
  stacks = (0, import_state.atom)(
38
39
  "HistoryManager.stacks",
@@ -51,14 +52,14 @@ class HistoryManager {
51
52
  this.dispose = this.store.addHistoryInterceptor((entry, source) => {
52
53
  if (source !== "user") return;
53
54
  switch (this.state) {
54
- case HistoryRecorderState.Recording:
55
+ case "recording" /* Recording */:
55
56
  this.pendingDiff.apply(entry.changes);
56
57
  this.stacks.update(({ undos }) => ({ undos, redos: stack() }));
57
58
  break;
58
- case HistoryRecorderState.RecordingPreserveRedoStack:
59
+ case "recordingPreserveRedoStack" /* RecordingPreserveRedoStack */:
59
60
  this.pendingDiff.apply(entry.changes);
60
61
  break;
61
- case HistoryRecorderState.Paused:
62
+ case "paused" /* Paused */:
62
63
  break;
63
64
  default:
64
65
  (0, import_utils.exhaustiveSwitchError)(this.state);
@@ -83,7 +84,7 @@ class HistoryManager {
83
84
  _isInBatch = false;
84
85
  batch(fn, opts) {
85
86
  const previousState = this.state;
86
- if (previousState !== HistoryRecorderState.Paused && opts?.history) {
87
+ if (previousState !== "paused" /* Paused */ && opts?.history) {
87
88
  this.state = modeToState[opts.history];
88
89
  }
89
90
  try {
@@ -108,7 +109,7 @@ class HistoryManager {
108
109
  // History
109
110
  _undo({ pushToRedoStack, toMark = void 0 }) {
110
111
  const previousState = this.state;
111
- this.state = HistoryRecorderState.Paused;
112
+ this.state = "paused" /* Paused */;
112
113
  try {
113
114
  let { undos, redos } = this.stacks.get();
114
115
  const pendingDiff = this.pendingDiff.clear();
@@ -171,7 +172,7 @@ class HistoryManager {
171
172
  }
172
173
  redo() {
173
174
  const previousState = this.state;
174
- this.state = HistoryRecorderState.Paused;
175
+ this.state = "paused" /* Paused */;
175
176
  try {
176
177
  this.flushPendingDiff();
177
178
  let { undos, redos } = this.stacks.get();
@@ -272,9 +273,9 @@ class HistoryManager {
272
273
  }
273
274
  }
274
275
  const modeToState = {
275
- record: HistoryRecorderState.Recording,
276
- "record-preserveRedoStack": HistoryRecorderState.RecordingPreserveRedoStack,
277
- ignore: HistoryRecorderState.Paused
276
+ record: "recording" /* Recording */,
277
+ "record-preserveRedoStack": "recordingPreserveRedoStack" /* RecordingPreserveRedoStack */,
278
+ ignore: "paused" /* Paused */
278
279
  };
279
280
  class PendingDiff {
280
281
  diff = (0, import_store.createEmptyRecordsDiff)();
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../src/lib/editor/managers/HistoryManager/HistoryManager.ts"],
4
- "sourcesContent": ["import { atom, EMPTY_ARRAY, transact } from '@tldraw/state'\nimport {\n\tcreateEmptyRecordsDiff,\n\tisRecordsDiffEmpty,\n\tRecordsDiff,\n\treverseRecordsDiff,\n\tsquashRecordDiffsMutable,\n\tStore,\n\tUnknownRecord,\n} from '@tldraw/store'\nimport { exhaustiveSwitchError, noop } from '@tldraw/utils'\nimport { TLHistoryBatchOptions, TLHistoryEntry } from '../../types/history-types'\n\nconst HistoryRecorderState = {\n\tRecording: 'recording',\n\tRecordingPreserveRedoStack: 'recordingPreserveRedoStack',\n\tPaused: 'paused',\n} as const\ntype HistoryRecorderState = (typeof HistoryRecorderState)[keyof typeof HistoryRecorderState]\n\n/** @public */\nexport class HistoryManager<R extends UnknownRecord> {\n\tprivate readonly store: Store<R>\n\n\treadonly dispose: () => void\n\n\tprivate state: HistoryRecorderState = HistoryRecorderState.Recording\n\tprivate readonly pendingDiff = new PendingDiff<R>()\n\tprivate stacks = atom(\n\t\t'HistoryManager.stacks',\n\t\t{\n\t\t\tundos: stack<TLHistoryEntry<R>>(),\n\t\t\tredos: stack<TLHistoryEntry<R>>(),\n\t\t},\n\t\t{\n\t\t\tisEqual: (a, b) => a.undos === b.undos && a.redos === b.redos,\n\t\t}\n\t)\n\n\tprivate readonly annotateError: (error: unknown) => void\n\n\tconstructor(opts: { store: Store<R>; annotateError?(error: unknown): void }) {\n\t\tthis.store = opts.store\n\t\tthis.annotateError = opts.annotateError ?? noop\n\t\tthis.dispose = this.store.addHistoryInterceptor((entry, source) => {\n\t\t\tif (source !== 'user') return\n\n\t\t\tswitch (this.state) {\n\t\t\t\tcase HistoryRecorderState.Recording:\n\t\t\t\t\tthis.pendingDiff.apply(entry.changes)\n\t\t\t\t\tthis.stacks.update(({ undos }) => ({ undos, redos: stack() }))\n\t\t\t\t\tbreak\n\t\t\t\tcase HistoryRecorderState.RecordingPreserveRedoStack:\n\t\t\t\t\tthis.pendingDiff.apply(entry.changes)\n\t\t\t\t\tbreak\n\t\t\t\tcase HistoryRecorderState.Paused:\n\t\t\t\t\tbreak\n\t\t\t\tdefault:\n\t\t\t\t\texhaustiveSwitchError(this.state)\n\t\t\t}\n\t\t})\n\t}\n\n\tprivate flushPendingDiff() {\n\t\tif (this.pendingDiff.isEmpty()) return\n\n\t\tconst diff = this.pendingDiff.clear()\n\t\tthis.stacks.update(({ undos, redos }) => ({\n\t\t\tundos: undos.push({ type: 'diff', diff }),\n\t\t\tredos,\n\t\t}))\n\t}\n\n\tgetNumUndos() {\n\t\treturn this.stacks.get().undos.length + (this.pendingDiff.isEmpty() ? 0 : 1)\n\t}\n\n\tgetNumRedos() {\n\t\treturn this.stacks.get().redos.length\n\t}\n\n\t/** @internal */\n\t_isInBatch = false\n\n\tbatch(fn: () => void, opts?: TLHistoryBatchOptions) {\n\t\tconst previousState = this.state\n\n\t\t// we move to the new state only if we haven't explicitly paused\n\t\tif (previousState !== HistoryRecorderState.Paused && opts?.history) {\n\t\t\tthis.state = modeToState[opts.history]\n\t\t}\n\n\t\ttry {\n\t\t\tif (this._isInBatch) {\n\t\t\t\ttransact(fn)\n\t\t\t\treturn this\n\t\t\t}\n\n\t\t\tthis._isInBatch = true\n\t\t\ttry {\n\t\t\t\ttransact(fn)\n\t\t\t} catch (error) {\n\t\t\t\tthis.annotateError(error)\n\t\t\t\tthrow error\n\t\t\t} finally {\n\t\t\t\tthis._isInBatch = false\n\t\t\t}\n\n\t\t\treturn this\n\t\t} finally {\n\t\t\tthis.state = previousState\n\t\t}\n\t}\n\n\t// History\n\t_undo({ pushToRedoStack, toMark = undefined }: { pushToRedoStack: boolean; toMark?: string }) {\n\t\tconst previousState = this.state\n\t\tthis.state = HistoryRecorderState.Paused\n\t\ttry {\n\t\t\tlet { undos, redos } = this.stacks.get()\n\n\t\t\t// start by collecting the pending diff (everything since the last mark).\n\t\t\t// we'll accumulate the diff to undo in this variable so we can apply it atomically.\n\t\t\tconst pendingDiff = this.pendingDiff.clear()\n\t\t\tconst isPendingDiffEmpty = isRecordsDiffEmpty(pendingDiff)\n\t\t\tconst diffToUndo = reverseRecordsDiff(pendingDiff)\n\n\t\t\tif (pushToRedoStack && !isPendingDiffEmpty) {\n\t\t\t\tredos = redos.push({ type: 'diff', diff: pendingDiff })\n\t\t\t}\n\n\t\t\tlet didFindMark = false\n\t\t\tif (isPendingDiffEmpty) {\n\t\t\t\t// if nothing has happened since the last mark, pop any intermediate marks off the stack\n\t\t\t\twhile (undos.head?.type === 'stop') {\n\t\t\t\t\tconst mark = undos.head\n\t\t\t\t\tundos = undos.tail\n\t\t\t\t\tif (pushToRedoStack) {\n\t\t\t\t\t\tredos = redos.push(mark)\n\t\t\t\t\t}\n\t\t\t\t\tif (mark.id === toMark) {\n\t\t\t\t\t\tdidFindMark = true\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (!didFindMark) {\n\t\t\t\tloop: while (undos.head) {\n\t\t\t\t\tconst undo = undos.head\n\t\t\t\t\tundos = undos.tail\n\n\t\t\t\t\tif (pushToRedoStack) {\n\t\t\t\t\t\tredos = redos.push(undo)\n\t\t\t\t\t}\n\n\t\t\t\t\tswitch (undo.type) {\n\t\t\t\t\t\tcase 'diff':\n\t\t\t\t\t\t\tsquashRecordDiffsMutable(diffToUndo, [reverseRecordsDiff(undo.diff)])\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\tcase 'stop':\n\t\t\t\t\t\t\tif (!toMark) break loop\n\t\t\t\t\t\t\tif (undo.id === toMark) {\n\t\t\t\t\t\t\t\tdidFindMark = true\n\t\t\t\t\t\t\t\tbreak loop\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\texhaustiveSwitchError(undo)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (!didFindMark && toMark) {\n\t\t\t\t// whoops, we didn't find the mark we were looking for\n\t\t\t\t// don't do anything\n\t\t\t\treturn this\n\t\t\t}\n\n\t\t\tthis.store.applyDiff(diffToUndo, { ignoreEphemeralKeys: true })\n\t\t\tthis.store.ensureStoreIsUsable()\n\t\t\tthis.stacks.set({ undos, redos })\n\t\t} finally {\n\t\t\tthis.state = previousState\n\t\t}\n\n\t\treturn this\n\t}\n\n\tundo() {\n\t\tthis._undo({ pushToRedoStack: true })\n\n\t\treturn this\n\t}\n\n\tredo() {\n\t\tconst previousState = this.state\n\t\tthis.state = HistoryRecorderState.Paused\n\t\ttry {\n\t\t\tthis.flushPendingDiff()\n\n\t\t\tlet { undos, redos } = this.stacks.get()\n\t\t\tif (redos.length === 0) {\n\t\t\t\treturn this\n\t\t\t}\n\n\t\t\t// ignore any intermediate marks - this should take us to the first `diff` entry\n\t\t\twhile (redos.head?.type === 'stop') {\n\t\t\t\tundos = undos.push(redos.head)\n\t\t\t\tredos = redos.tail\n\t\t\t}\n\n\t\t\t// accumulate diffs to be redone so they can be applied atomically\n\t\t\tconst diffToRedo = createEmptyRecordsDiff<R>()\n\n\t\t\twhile (redos.head) {\n\t\t\t\tconst redo = redos.head\n\t\t\t\tundos = undos.push(redo)\n\t\t\t\tredos = redos.tail\n\n\t\t\t\tif (redo.type === 'diff') {\n\t\t\t\t\tsquashRecordDiffsMutable(diffToRedo, [redo.diff])\n\t\t\t\t} else {\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tthis.store.applyDiff(diffToRedo, { ignoreEphemeralKeys: true })\n\t\t\tthis.store.ensureStoreIsUsable()\n\t\t\tthis.stacks.set({ undos, redos })\n\t\t} finally {\n\t\t\tthis.state = previousState\n\t\t}\n\n\t\treturn this\n\t}\n\n\tbail() {\n\t\tthis._undo({ pushToRedoStack: false })\n\n\t\treturn this\n\t}\n\n\tbailToMark(id: string) {\n\t\tif (id) {\n\t\t\tthis._undo({ pushToRedoStack: false, toMark: id })\n\t\t}\n\n\t\treturn this\n\t}\n\n\tsquashToMark(id: string) {\n\t\t// remove marks between head and the mark\n\n\t\tlet top = this.stacks.get().undos\n\t\tconst popped: Array<RecordsDiff<R>> = []\n\n\t\twhile (top.head && !(top.head.type === 'stop' && top.head.id === id)) {\n\t\t\tif (top.head.type === 'diff') {\n\t\t\t\tpopped.push(top.head.diff)\n\t\t\t}\n\t\t\ttop = top.tail\n\t\t}\n\n\t\tif (!top.head || top.head?.id !== id) {\n\t\t\tconsole.error('Could not find mark to squash to: ', id)\n\t\t\treturn this\n\t\t}\n\t\tif (popped.length === 0) {\n\t\t\treturn this\n\t\t}\n\n\t\tconst diff = createEmptyRecordsDiff<R>()\n\t\tsquashRecordDiffsMutable(diff, popped.reverse())\n\n\t\tthis.stacks.update(({ redos }) => ({\n\t\t\tundos: top.push({\n\t\t\t\ttype: 'diff',\n\t\t\t\tdiff,\n\t\t\t}),\n\t\t\tredos,\n\t\t}))\n\n\t\treturn this\n\t}\n\n\t/** @internal */\n\t_mark(id: string) {\n\t\ttransact(() => {\n\t\t\tthis.flushPendingDiff()\n\t\t\tthis.stacks.update(({ undos, redos }) => ({ undos: undos.push({ type: 'stop', id }), redos }))\n\t\t})\n\t}\n\n\tclear() {\n\t\tthis.stacks.set({ undos: stack(), redos: stack() })\n\t\tthis.pendingDiff.clear()\n\t}\n\n\t/** @internal */\n\tgetMarkIdMatching(idSubstring: string) {\n\t\tlet top = this.stacks.get().undos\n\t\twhile (top.head) {\n\t\t\tif (top.head.type === 'stop' && top.head.id.includes(idSubstring)) {\n\t\t\t\treturn top.head.id\n\t\t\t}\n\t\t\ttop = top.tail\n\t\t}\n\t\treturn null\n\t}\n\n\t/** @internal */\n\tdebug() {\n\t\tconst { undos, redos } = this.stacks.get()\n\t\treturn {\n\t\t\tundos: stackToArray(undos),\n\t\t\tredos: stackToArray(redos),\n\t\t\tpendingDiff: this.pendingDiff.debug(),\n\t\t\tstate: this.state as string,\n\t\t}\n\t}\n}\n\nconst modeToState = {\n\trecord: HistoryRecorderState.Recording,\n\t'record-preserveRedoStack': HistoryRecorderState.RecordingPreserveRedoStack,\n\tignore: HistoryRecorderState.Paused,\n} as const\n\nclass PendingDiff<R extends UnknownRecord> {\n\tprivate diff = createEmptyRecordsDiff<R>()\n\tprivate isEmptyAtom = atom('PendingDiff.isEmpty', true)\n\n\tclear() {\n\t\tconst diff = this.diff\n\t\tthis.diff = createEmptyRecordsDiff<R>()\n\t\tthis.isEmptyAtom.set(true)\n\t\treturn diff\n\t}\n\n\tisEmpty() {\n\t\treturn this.isEmptyAtom.get()\n\t}\n\n\tapply(diff: RecordsDiff<R>) {\n\t\tsquashRecordDiffsMutable(this.diff, [diff])\n\t\tthis.isEmptyAtom.set(isRecordsDiffEmpty(this.diff))\n\t}\n\n\tdebug() {\n\t\treturn { diff: this.diff, isEmpty: this.isEmpty() }\n\t}\n}\n\ntype Stack<T> = StackItem<T> | EmptyStackItem<T>\n\nfunction stack<T>(): Stack<T> {\n\treturn EMPTY_STACK_ITEM as any\n}\n\nclass EmptyStackItem<T> {\n\treadonly length = 0\n\treadonly head = null\n\treadonly tail: Stack<T> = this\n\n\tpush(head: T): Stack<T> {\n\t\treturn new StackItem<T>(head, this)\n\t}\n}\n\nconst EMPTY_STACK_ITEM = new EmptyStackItem()\n\nclass StackItem<T> {\n\tlength: number\n\tconstructor(\n\t\tpublic readonly head: T,\n\t\tpublic readonly tail: Stack<T>\n\t) {\n\t\tthis.length = tail.length + 1\n\t}\n\n\tpush(head: T): Stack<T> {\n\t\treturn new StackItem(head, this)\n\t}\n}\n\nfunction stackToArray<T>(stack: Stack<T>) {\n\tif (!stack.length) {\n\t\treturn EMPTY_ARRAY\n\t}\n\tconst arr: T[] = []\n\twhile (stack.length) {\n\t\tarr.push(stack.head!)\n\t\tstack = stack.tail\n\t}\n\treturn arr\n}\n"],
5
- "mappings": "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",
6
- "names": ["stack"]
4
+ "sourcesContent": ["import { atom, EMPTY_ARRAY, transact } from '@tldraw/state'\nimport {\n\tcreateEmptyRecordsDiff,\n\tisRecordsDiffEmpty,\n\tRecordsDiff,\n\treverseRecordsDiff,\n\tsquashRecordDiffsMutable,\n\tStore,\n\tUnknownRecord,\n} from '@tldraw/store'\nimport { exhaustiveSwitchError, noop } from '@tldraw/utils'\nimport { TLHistoryBatchOptions, TLHistoryEntry } from '../../types/history-types'\n\nenum HistoryRecorderState {\n\tRecording = 'recording',\n\tRecordingPreserveRedoStack = 'recordingPreserveRedoStack',\n\tPaused = 'paused',\n}\n\n/** @public */\nexport class HistoryManager<R extends UnknownRecord> {\n\tprivate readonly store: Store<R>\n\n\treadonly dispose: () => void\n\n\tprivate state: HistoryRecorderState = HistoryRecorderState.Recording\n\tprivate readonly pendingDiff = new PendingDiff<R>()\n\tprivate stacks = atom(\n\t\t'HistoryManager.stacks',\n\t\t{\n\t\t\tundos: stack<TLHistoryEntry<R>>(),\n\t\t\tredos: stack<TLHistoryEntry<R>>(),\n\t\t},\n\t\t{\n\t\t\tisEqual: (a, b) => a.undos === b.undos && a.redos === b.redos,\n\t\t}\n\t)\n\n\tprivate readonly annotateError: (error: unknown) => void\n\n\tconstructor(opts: { store: Store<R>; annotateError?(error: unknown): void }) {\n\t\tthis.store = opts.store\n\t\tthis.annotateError = opts.annotateError ?? noop\n\t\tthis.dispose = this.store.addHistoryInterceptor((entry, source) => {\n\t\t\tif (source !== 'user') return\n\n\t\t\tswitch (this.state) {\n\t\t\t\tcase HistoryRecorderState.Recording:\n\t\t\t\t\tthis.pendingDiff.apply(entry.changes)\n\t\t\t\t\tthis.stacks.update(({ undos }) => ({ undos, redos: stack() }))\n\t\t\t\t\tbreak\n\t\t\t\tcase HistoryRecorderState.RecordingPreserveRedoStack:\n\t\t\t\t\tthis.pendingDiff.apply(entry.changes)\n\t\t\t\t\tbreak\n\t\t\t\tcase HistoryRecorderState.Paused:\n\t\t\t\t\tbreak\n\t\t\t\tdefault:\n\t\t\t\t\texhaustiveSwitchError(this.state)\n\t\t\t}\n\t\t})\n\t}\n\n\tprivate flushPendingDiff() {\n\t\tif (this.pendingDiff.isEmpty()) return\n\n\t\tconst diff = this.pendingDiff.clear()\n\t\tthis.stacks.update(({ undos, redos }) => ({\n\t\t\tundos: undos.push({ type: 'diff', diff }),\n\t\t\tredos,\n\t\t}))\n\t}\n\n\tgetNumUndos() {\n\t\treturn this.stacks.get().undos.length + (this.pendingDiff.isEmpty() ? 0 : 1)\n\t}\n\n\tgetNumRedos() {\n\t\treturn this.stacks.get().redos.length\n\t}\n\n\t/** @internal */\n\t_isInBatch = false\n\n\tbatch(fn: () => void, opts?: TLHistoryBatchOptions) {\n\t\tconst previousState = this.state\n\n\t\t// we move to the new state only if we haven't explicitly paused\n\t\tif (previousState !== HistoryRecorderState.Paused && opts?.history) {\n\t\t\tthis.state = modeToState[opts.history]\n\t\t}\n\n\t\ttry {\n\t\t\tif (this._isInBatch) {\n\t\t\t\ttransact(fn)\n\t\t\t\treturn this\n\t\t\t}\n\n\t\t\tthis._isInBatch = true\n\t\t\ttry {\n\t\t\t\ttransact(fn)\n\t\t\t} catch (error) {\n\t\t\t\tthis.annotateError(error)\n\t\t\t\tthrow error\n\t\t\t} finally {\n\t\t\t\tthis._isInBatch = false\n\t\t\t}\n\n\t\t\treturn this\n\t\t} finally {\n\t\t\tthis.state = previousState\n\t\t}\n\t}\n\n\t// History\n\t_undo({ pushToRedoStack, toMark = undefined }: { pushToRedoStack: boolean; toMark?: string }) {\n\t\tconst previousState = this.state\n\t\tthis.state = HistoryRecorderState.Paused\n\t\ttry {\n\t\t\tlet { undos, redos } = this.stacks.get()\n\n\t\t\t// start by collecting the pending diff (everything since the last mark).\n\t\t\t// we'll accumulate the diff to undo in this variable so we can apply it atomically.\n\t\t\tconst pendingDiff = this.pendingDiff.clear()\n\t\t\tconst isPendingDiffEmpty = isRecordsDiffEmpty(pendingDiff)\n\t\t\tconst diffToUndo = reverseRecordsDiff(pendingDiff)\n\n\t\t\tif (pushToRedoStack && !isPendingDiffEmpty) {\n\t\t\t\tredos = redos.push({ type: 'diff', diff: pendingDiff })\n\t\t\t}\n\n\t\t\tlet didFindMark = false\n\t\t\tif (isPendingDiffEmpty) {\n\t\t\t\t// if nothing has happened since the last mark, pop any intermediate marks off the stack\n\t\t\t\twhile (undos.head?.type === 'stop') {\n\t\t\t\t\tconst mark = undos.head\n\t\t\t\t\tundos = undos.tail\n\t\t\t\t\tif (pushToRedoStack) {\n\t\t\t\t\t\tredos = redos.push(mark)\n\t\t\t\t\t}\n\t\t\t\t\tif (mark.id === toMark) {\n\t\t\t\t\t\tdidFindMark = true\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (!didFindMark) {\n\t\t\t\tloop: while (undos.head) {\n\t\t\t\t\tconst undo = undos.head\n\t\t\t\t\tundos = undos.tail\n\n\t\t\t\t\tif (pushToRedoStack) {\n\t\t\t\t\t\tredos = redos.push(undo)\n\t\t\t\t\t}\n\n\t\t\t\t\tswitch (undo.type) {\n\t\t\t\t\t\tcase 'diff':\n\t\t\t\t\t\t\tsquashRecordDiffsMutable(diffToUndo, [reverseRecordsDiff(undo.diff)])\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\tcase 'stop':\n\t\t\t\t\t\t\tif (!toMark) break loop\n\t\t\t\t\t\t\tif (undo.id === toMark) {\n\t\t\t\t\t\t\t\tdidFindMark = true\n\t\t\t\t\t\t\t\tbreak loop\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\texhaustiveSwitchError(undo)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (!didFindMark && toMark) {\n\t\t\t\t// whoops, we didn't find the mark we were looking for\n\t\t\t\t// don't do anything\n\t\t\t\treturn this\n\t\t\t}\n\n\t\t\tthis.store.applyDiff(diffToUndo, { ignoreEphemeralKeys: true })\n\t\t\tthis.store.ensureStoreIsUsable()\n\t\t\tthis.stacks.set({ undos, redos })\n\t\t} finally {\n\t\t\tthis.state = previousState\n\t\t}\n\n\t\treturn this\n\t}\n\n\tundo() {\n\t\tthis._undo({ pushToRedoStack: true })\n\n\t\treturn this\n\t}\n\n\tredo() {\n\t\tconst previousState = this.state\n\t\tthis.state = HistoryRecorderState.Paused\n\t\ttry {\n\t\t\tthis.flushPendingDiff()\n\n\t\t\tlet { undos, redos } = this.stacks.get()\n\t\t\tif (redos.length === 0) {\n\t\t\t\treturn this\n\t\t\t}\n\n\t\t\t// ignore any intermediate marks - this should take us to the first `diff` entry\n\t\t\twhile (redos.head?.type === 'stop') {\n\t\t\t\tundos = undos.push(redos.head)\n\t\t\t\tredos = redos.tail\n\t\t\t}\n\n\t\t\t// accumulate diffs to be redone so they can be applied atomically\n\t\t\tconst diffToRedo = createEmptyRecordsDiff<R>()\n\n\t\t\twhile (redos.head) {\n\t\t\t\tconst redo = redos.head\n\t\t\t\tundos = undos.push(redo)\n\t\t\t\tredos = redos.tail\n\n\t\t\t\tif (redo.type === 'diff') {\n\t\t\t\t\tsquashRecordDiffsMutable(diffToRedo, [redo.diff])\n\t\t\t\t} else {\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tthis.store.applyDiff(diffToRedo, { ignoreEphemeralKeys: true })\n\t\t\tthis.store.ensureStoreIsUsable()\n\t\t\tthis.stacks.set({ undos, redos })\n\t\t} finally {\n\t\t\tthis.state = previousState\n\t\t}\n\n\t\treturn this\n\t}\n\n\tbail() {\n\t\tthis._undo({ pushToRedoStack: false })\n\n\t\treturn this\n\t}\n\n\tbailToMark(id: string) {\n\t\tif (id) {\n\t\t\tthis._undo({ pushToRedoStack: false, toMark: id })\n\t\t}\n\n\t\treturn this\n\t}\n\n\tsquashToMark(id: string) {\n\t\t// remove marks between head and the mark\n\n\t\tlet top = this.stacks.get().undos\n\t\tconst popped: Array<RecordsDiff<R>> = []\n\n\t\twhile (top.head && !(top.head.type === 'stop' && top.head.id === id)) {\n\t\t\tif (top.head.type === 'diff') {\n\t\t\t\tpopped.push(top.head.diff)\n\t\t\t}\n\t\t\ttop = top.tail\n\t\t}\n\n\t\tif (!top.head || top.head?.id !== id) {\n\t\t\tconsole.error('Could not find mark to squash to: ', id)\n\t\t\treturn this\n\t\t}\n\t\tif (popped.length === 0) {\n\t\t\treturn this\n\t\t}\n\n\t\tconst diff = createEmptyRecordsDiff<R>()\n\t\tsquashRecordDiffsMutable(diff, popped.reverse())\n\n\t\tthis.stacks.update(({ redos }) => ({\n\t\t\tundos: top.push({\n\t\t\t\ttype: 'diff',\n\t\t\t\tdiff,\n\t\t\t}),\n\t\t\tredos,\n\t\t}))\n\n\t\treturn this\n\t}\n\n\t/** @internal */\n\t_mark(id: string) {\n\t\ttransact(() => {\n\t\t\tthis.flushPendingDiff()\n\t\t\tthis.stacks.update(({ undos, redos }) => ({ undos: undos.push({ type: 'stop', id }), redos }))\n\t\t})\n\t}\n\n\tclear() {\n\t\tthis.stacks.set({ undos: stack(), redos: stack() })\n\t\tthis.pendingDiff.clear()\n\t}\n\n\t/** @internal */\n\tgetMarkIdMatching(idSubstring: string) {\n\t\tlet top = this.stacks.get().undos\n\t\twhile (top.head) {\n\t\t\tif (top.head.type === 'stop' && top.head.id.includes(idSubstring)) {\n\t\t\t\treturn top.head.id\n\t\t\t}\n\t\t\ttop = top.tail\n\t\t}\n\t\treturn null\n\t}\n\n\t/** @internal */\n\tdebug() {\n\t\tconst { undos, redos } = this.stacks.get()\n\t\treturn {\n\t\t\tundos: stackToArray(undos),\n\t\t\tredos: stackToArray(redos),\n\t\t\tpendingDiff: this.pendingDiff.debug(),\n\t\t\tstate: this.state as string,\n\t\t}\n\t}\n}\n\nconst modeToState = {\n\trecord: HistoryRecorderState.Recording,\n\t'record-preserveRedoStack': HistoryRecorderState.RecordingPreserveRedoStack,\n\tignore: HistoryRecorderState.Paused,\n} as const\n\nclass PendingDiff<R extends UnknownRecord> {\n\tprivate diff = createEmptyRecordsDiff<R>()\n\tprivate isEmptyAtom = atom('PendingDiff.isEmpty', true)\n\n\tclear() {\n\t\tconst diff = this.diff\n\t\tthis.diff = createEmptyRecordsDiff<R>()\n\t\tthis.isEmptyAtom.set(true)\n\t\treturn diff\n\t}\n\n\tisEmpty() {\n\t\treturn this.isEmptyAtom.get()\n\t}\n\n\tapply(diff: RecordsDiff<R>) {\n\t\tsquashRecordDiffsMutable(this.diff, [diff])\n\t\tthis.isEmptyAtom.set(isRecordsDiffEmpty(this.diff))\n\t}\n\n\tdebug() {\n\t\treturn { diff: this.diff, isEmpty: this.isEmpty() }\n\t}\n}\n\ntype Stack<T> = StackItem<T> | EmptyStackItem<T>\n\nfunction stack<T>(): Stack<T> {\n\treturn EMPTY_STACK_ITEM as any\n}\n\nclass EmptyStackItem<T> {\n\treadonly length = 0\n\treadonly head = null\n\treadonly tail: Stack<T> = this\n\n\tpush(head: T): Stack<T> {\n\t\treturn new StackItem<T>(head, this)\n\t}\n}\n\nconst EMPTY_STACK_ITEM = new EmptyStackItem()\n\nclass StackItem<T> {\n\tlength: number\n\tconstructor(\n\t\tpublic readonly head: T,\n\t\tpublic readonly tail: Stack<T>\n\t) {\n\t\tthis.length = tail.length + 1\n\t}\n\n\tpush(head: T): Stack<T> {\n\t\treturn new StackItem(head, this)\n\t}\n}\n\nfunction stackToArray<T>(stack: Stack<T>) {\n\tif (!stack.length) {\n\t\treturn EMPTY_ARRAY\n\t}\n\tconst arr: T[] = []\n\twhile (stack.length) {\n\t\tarr.push(stack.head!)\n\t\tstack = stack.tail\n\t}\n\treturn arr\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["HistoryRecorderState", "stack"]
7
7
  }
@@ -22,10 +22,10 @@ __export(version_exports, {
22
22
  version: () => version
23
23
  });
24
24
  module.exports = __toCommonJS(version_exports);
25
- const version = "4.5.0-canary.f284eeb67609";
25
+ const version = "4.5.0-next.74a79354f99f";
26
26
  const publishDates = {
27
27
  major: "2025-09-18T14:39:22.803Z",
28
- minor: "2026-02-26T09:42:31.895Z",
29
- patch: "2026-02-26T09:42:31.895Z"
28
+ minor: "2026-02-26T11:31:57.370Z",
29
+ patch: "2026-02-26T11:31:57.370Z"
30
30
  };
31
31
  //# sourceMappingURL=version.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/version.ts"],
4
- "sourcesContent": ["// This file is automatically generated by internal/scripts/refresh-assets.ts.\n// Do not edit manually. Or do, I'm a comment, not a cop.\n\nexport const version = '4.5.0-canary.f284eeb67609'\nexport const publishDates = {\n\tmajor: '2025-09-18T14:39:22.803Z',\n\tminor: '2026-02-26T09:42:31.895Z',\n\tpatch: '2026-02-26T09:42:31.895Z',\n}\n"],
4
+ "sourcesContent": ["// This file is automatically generated by internal/scripts/refresh-assets.ts.\n// Do not edit manually. Or do, I'm a comment, not a cop.\n\nexport const version = '4.5.0-next.74a79354f99f'\nexport const publishDates = {\n\tmajor: '2025-09-18T14:39:22.803Z',\n\tminor: '2026-02-26T11:31:57.370Z',\n\tpatch: '2026-02-26T11:31:57.370Z',\n}\n"],
5
5
  "mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAGO,MAAM,UAAU;AAChB,MAAM,eAAe;AAAA,EAC3B,OAAO;AAAA,EACP,OAAO;AAAA,EACP,OAAO;AACR;",
6
6
  "names": []
7
7
  }
@@ -303,7 +303,7 @@ import { LocalIndexedDb, Table } from "./lib/utils/sync/LocalIndexedDb.mjs";
303
303
  import { uniq } from "./lib/utils/uniq.mjs";
304
304
  registerTldrawLibraryVersion(
305
305
  "@tldraw/editor",
306
- "4.5.0-canary.f284eeb67609",
306
+ "4.5.0-next.74a79354f99f",
307
307
  "esm"
308
308
  );
309
309
  export {
@@ -6,15 +6,16 @@ import {
6
6
  squashRecordDiffsMutable
7
7
  } from "@tldraw/store";
8
8
  import { exhaustiveSwitchError, noop } from "@tldraw/utils";
9
- const HistoryRecorderState = {
10
- Recording: "recording",
11
- RecordingPreserveRedoStack: "recordingPreserveRedoStack",
12
- Paused: "paused"
13
- };
9
+ var HistoryRecorderState = /* @__PURE__ */ ((HistoryRecorderState2) => {
10
+ HistoryRecorderState2["Recording"] = "recording";
11
+ HistoryRecorderState2["RecordingPreserveRedoStack"] = "recordingPreserveRedoStack";
12
+ HistoryRecorderState2["Paused"] = "paused";
13
+ return HistoryRecorderState2;
14
+ })(HistoryRecorderState || {});
14
15
  class HistoryManager {
15
16
  store;
16
17
  dispose;
17
- state = HistoryRecorderState.Recording;
18
+ state = "recording" /* Recording */;
18
19
  pendingDiff = new PendingDiff();
19
20
  stacks = atom(
20
21
  "HistoryManager.stacks",
@@ -33,14 +34,14 @@ class HistoryManager {
33
34
  this.dispose = this.store.addHistoryInterceptor((entry, source) => {
34
35
  if (source !== "user") return;
35
36
  switch (this.state) {
36
- case HistoryRecorderState.Recording:
37
+ case "recording" /* Recording */:
37
38
  this.pendingDiff.apply(entry.changes);
38
39
  this.stacks.update(({ undos }) => ({ undos, redos: stack() }));
39
40
  break;
40
- case HistoryRecorderState.RecordingPreserveRedoStack:
41
+ case "recordingPreserveRedoStack" /* RecordingPreserveRedoStack */:
41
42
  this.pendingDiff.apply(entry.changes);
42
43
  break;
43
- case HistoryRecorderState.Paused:
44
+ case "paused" /* Paused */:
44
45
  break;
45
46
  default:
46
47
  exhaustiveSwitchError(this.state);
@@ -65,7 +66,7 @@ class HistoryManager {
65
66
  _isInBatch = false;
66
67
  batch(fn, opts) {
67
68
  const previousState = this.state;
68
- if (previousState !== HistoryRecorderState.Paused && opts?.history) {
69
+ if (previousState !== "paused" /* Paused */ && opts?.history) {
69
70
  this.state = modeToState[opts.history];
70
71
  }
71
72
  try {
@@ -90,7 +91,7 @@ class HistoryManager {
90
91
  // History
91
92
  _undo({ pushToRedoStack, toMark = void 0 }) {
92
93
  const previousState = this.state;
93
- this.state = HistoryRecorderState.Paused;
94
+ this.state = "paused" /* Paused */;
94
95
  try {
95
96
  let { undos, redos } = this.stacks.get();
96
97
  const pendingDiff = this.pendingDiff.clear();
@@ -153,7 +154,7 @@ class HistoryManager {
153
154
  }
154
155
  redo() {
155
156
  const previousState = this.state;
156
- this.state = HistoryRecorderState.Paused;
157
+ this.state = "paused" /* Paused */;
157
158
  try {
158
159
  this.flushPendingDiff();
159
160
  let { undos, redos } = this.stacks.get();
@@ -254,9 +255,9 @@ class HistoryManager {
254
255
  }
255
256
  }
256
257
  const modeToState = {
257
- record: HistoryRecorderState.Recording,
258
- "record-preserveRedoStack": HistoryRecorderState.RecordingPreserveRedoStack,
259
- ignore: HistoryRecorderState.Paused
258
+ record: "recording" /* Recording */,
259
+ "record-preserveRedoStack": "recordingPreserveRedoStack" /* RecordingPreserveRedoStack */,
260
+ ignore: "paused" /* Paused */
260
261
  };
261
262
  class PendingDiff {
262
263
  diff = createEmptyRecordsDiff();
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../src/lib/editor/managers/HistoryManager/HistoryManager.ts"],
4
- "sourcesContent": ["import { atom, EMPTY_ARRAY, transact } from '@tldraw/state'\nimport {\n\tcreateEmptyRecordsDiff,\n\tisRecordsDiffEmpty,\n\tRecordsDiff,\n\treverseRecordsDiff,\n\tsquashRecordDiffsMutable,\n\tStore,\n\tUnknownRecord,\n} from '@tldraw/store'\nimport { exhaustiveSwitchError, noop } from '@tldraw/utils'\nimport { TLHistoryBatchOptions, TLHistoryEntry } from '../../types/history-types'\n\nconst HistoryRecorderState = {\n\tRecording: 'recording',\n\tRecordingPreserveRedoStack: 'recordingPreserveRedoStack',\n\tPaused: 'paused',\n} as const\ntype HistoryRecorderState = (typeof HistoryRecorderState)[keyof typeof HistoryRecorderState]\n\n/** @public */\nexport class HistoryManager<R extends UnknownRecord> {\n\tprivate readonly store: Store<R>\n\n\treadonly dispose: () => void\n\n\tprivate state: HistoryRecorderState = HistoryRecorderState.Recording\n\tprivate readonly pendingDiff = new PendingDiff<R>()\n\tprivate stacks = atom(\n\t\t'HistoryManager.stacks',\n\t\t{\n\t\t\tundos: stack<TLHistoryEntry<R>>(),\n\t\t\tredos: stack<TLHistoryEntry<R>>(),\n\t\t},\n\t\t{\n\t\t\tisEqual: (a, b) => a.undos === b.undos && a.redos === b.redos,\n\t\t}\n\t)\n\n\tprivate readonly annotateError: (error: unknown) => void\n\n\tconstructor(opts: { store: Store<R>; annotateError?(error: unknown): void }) {\n\t\tthis.store = opts.store\n\t\tthis.annotateError = opts.annotateError ?? noop\n\t\tthis.dispose = this.store.addHistoryInterceptor((entry, source) => {\n\t\t\tif (source !== 'user') return\n\n\t\t\tswitch (this.state) {\n\t\t\t\tcase HistoryRecorderState.Recording:\n\t\t\t\t\tthis.pendingDiff.apply(entry.changes)\n\t\t\t\t\tthis.stacks.update(({ undos }) => ({ undos, redos: stack() }))\n\t\t\t\t\tbreak\n\t\t\t\tcase HistoryRecorderState.RecordingPreserveRedoStack:\n\t\t\t\t\tthis.pendingDiff.apply(entry.changes)\n\t\t\t\t\tbreak\n\t\t\t\tcase HistoryRecorderState.Paused:\n\t\t\t\t\tbreak\n\t\t\t\tdefault:\n\t\t\t\t\texhaustiveSwitchError(this.state)\n\t\t\t}\n\t\t})\n\t}\n\n\tprivate flushPendingDiff() {\n\t\tif (this.pendingDiff.isEmpty()) return\n\n\t\tconst diff = this.pendingDiff.clear()\n\t\tthis.stacks.update(({ undos, redos }) => ({\n\t\t\tundos: undos.push({ type: 'diff', diff }),\n\t\t\tredos,\n\t\t}))\n\t}\n\n\tgetNumUndos() {\n\t\treturn this.stacks.get().undos.length + (this.pendingDiff.isEmpty() ? 0 : 1)\n\t}\n\n\tgetNumRedos() {\n\t\treturn this.stacks.get().redos.length\n\t}\n\n\t/** @internal */\n\t_isInBatch = false\n\n\tbatch(fn: () => void, opts?: TLHistoryBatchOptions) {\n\t\tconst previousState = this.state\n\n\t\t// we move to the new state only if we haven't explicitly paused\n\t\tif (previousState !== HistoryRecorderState.Paused && opts?.history) {\n\t\t\tthis.state = modeToState[opts.history]\n\t\t}\n\n\t\ttry {\n\t\t\tif (this._isInBatch) {\n\t\t\t\ttransact(fn)\n\t\t\t\treturn this\n\t\t\t}\n\n\t\t\tthis._isInBatch = true\n\t\t\ttry {\n\t\t\t\ttransact(fn)\n\t\t\t} catch (error) {\n\t\t\t\tthis.annotateError(error)\n\t\t\t\tthrow error\n\t\t\t} finally {\n\t\t\t\tthis._isInBatch = false\n\t\t\t}\n\n\t\t\treturn this\n\t\t} finally {\n\t\t\tthis.state = previousState\n\t\t}\n\t}\n\n\t// History\n\t_undo({ pushToRedoStack, toMark = undefined }: { pushToRedoStack: boolean; toMark?: string }) {\n\t\tconst previousState = this.state\n\t\tthis.state = HistoryRecorderState.Paused\n\t\ttry {\n\t\t\tlet { undos, redos } = this.stacks.get()\n\n\t\t\t// start by collecting the pending diff (everything since the last mark).\n\t\t\t// we'll accumulate the diff to undo in this variable so we can apply it atomically.\n\t\t\tconst pendingDiff = this.pendingDiff.clear()\n\t\t\tconst isPendingDiffEmpty = isRecordsDiffEmpty(pendingDiff)\n\t\t\tconst diffToUndo = reverseRecordsDiff(pendingDiff)\n\n\t\t\tif (pushToRedoStack && !isPendingDiffEmpty) {\n\t\t\t\tredos = redos.push({ type: 'diff', diff: pendingDiff })\n\t\t\t}\n\n\t\t\tlet didFindMark = false\n\t\t\tif (isPendingDiffEmpty) {\n\t\t\t\t// if nothing has happened since the last mark, pop any intermediate marks off the stack\n\t\t\t\twhile (undos.head?.type === 'stop') {\n\t\t\t\t\tconst mark = undos.head\n\t\t\t\t\tundos = undos.tail\n\t\t\t\t\tif (pushToRedoStack) {\n\t\t\t\t\t\tredos = redos.push(mark)\n\t\t\t\t\t}\n\t\t\t\t\tif (mark.id === toMark) {\n\t\t\t\t\t\tdidFindMark = true\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (!didFindMark) {\n\t\t\t\tloop: while (undos.head) {\n\t\t\t\t\tconst undo = undos.head\n\t\t\t\t\tundos = undos.tail\n\n\t\t\t\t\tif (pushToRedoStack) {\n\t\t\t\t\t\tredos = redos.push(undo)\n\t\t\t\t\t}\n\n\t\t\t\t\tswitch (undo.type) {\n\t\t\t\t\t\tcase 'diff':\n\t\t\t\t\t\t\tsquashRecordDiffsMutable(diffToUndo, [reverseRecordsDiff(undo.diff)])\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\tcase 'stop':\n\t\t\t\t\t\t\tif (!toMark) break loop\n\t\t\t\t\t\t\tif (undo.id === toMark) {\n\t\t\t\t\t\t\t\tdidFindMark = true\n\t\t\t\t\t\t\t\tbreak loop\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\texhaustiveSwitchError(undo)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (!didFindMark && toMark) {\n\t\t\t\t// whoops, we didn't find the mark we were looking for\n\t\t\t\t// don't do anything\n\t\t\t\treturn this\n\t\t\t}\n\n\t\t\tthis.store.applyDiff(diffToUndo, { ignoreEphemeralKeys: true })\n\t\t\tthis.store.ensureStoreIsUsable()\n\t\t\tthis.stacks.set({ undos, redos })\n\t\t} finally {\n\t\t\tthis.state = previousState\n\t\t}\n\n\t\treturn this\n\t}\n\n\tundo() {\n\t\tthis._undo({ pushToRedoStack: true })\n\n\t\treturn this\n\t}\n\n\tredo() {\n\t\tconst previousState = this.state\n\t\tthis.state = HistoryRecorderState.Paused\n\t\ttry {\n\t\t\tthis.flushPendingDiff()\n\n\t\t\tlet { undos, redos } = this.stacks.get()\n\t\t\tif (redos.length === 0) {\n\t\t\t\treturn this\n\t\t\t}\n\n\t\t\t// ignore any intermediate marks - this should take us to the first `diff` entry\n\t\t\twhile (redos.head?.type === 'stop') {\n\t\t\t\tundos = undos.push(redos.head)\n\t\t\t\tredos = redos.tail\n\t\t\t}\n\n\t\t\t// accumulate diffs to be redone so they can be applied atomically\n\t\t\tconst diffToRedo = createEmptyRecordsDiff<R>()\n\n\t\t\twhile (redos.head) {\n\t\t\t\tconst redo = redos.head\n\t\t\t\tundos = undos.push(redo)\n\t\t\t\tredos = redos.tail\n\n\t\t\t\tif (redo.type === 'diff') {\n\t\t\t\t\tsquashRecordDiffsMutable(diffToRedo, [redo.diff])\n\t\t\t\t} else {\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tthis.store.applyDiff(diffToRedo, { ignoreEphemeralKeys: true })\n\t\t\tthis.store.ensureStoreIsUsable()\n\t\t\tthis.stacks.set({ undos, redos })\n\t\t} finally {\n\t\t\tthis.state = previousState\n\t\t}\n\n\t\treturn this\n\t}\n\n\tbail() {\n\t\tthis._undo({ pushToRedoStack: false })\n\n\t\treturn this\n\t}\n\n\tbailToMark(id: string) {\n\t\tif (id) {\n\t\t\tthis._undo({ pushToRedoStack: false, toMark: id })\n\t\t}\n\n\t\treturn this\n\t}\n\n\tsquashToMark(id: string) {\n\t\t// remove marks between head and the mark\n\n\t\tlet top = this.stacks.get().undos\n\t\tconst popped: Array<RecordsDiff<R>> = []\n\n\t\twhile (top.head && !(top.head.type === 'stop' && top.head.id === id)) {\n\t\t\tif (top.head.type === 'diff') {\n\t\t\t\tpopped.push(top.head.diff)\n\t\t\t}\n\t\t\ttop = top.tail\n\t\t}\n\n\t\tif (!top.head || top.head?.id !== id) {\n\t\t\tconsole.error('Could not find mark to squash to: ', id)\n\t\t\treturn this\n\t\t}\n\t\tif (popped.length === 0) {\n\t\t\treturn this\n\t\t}\n\n\t\tconst diff = createEmptyRecordsDiff<R>()\n\t\tsquashRecordDiffsMutable(diff, popped.reverse())\n\n\t\tthis.stacks.update(({ redos }) => ({\n\t\t\tundos: top.push({\n\t\t\t\ttype: 'diff',\n\t\t\t\tdiff,\n\t\t\t}),\n\t\t\tredos,\n\t\t}))\n\n\t\treturn this\n\t}\n\n\t/** @internal */\n\t_mark(id: string) {\n\t\ttransact(() => {\n\t\t\tthis.flushPendingDiff()\n\t\t\tthis.stacks.update(({ undos, redos }) => ({ undos: undos.push({ type: 'stop', id }), redos }))\n\t\t})\n\t}\n\n\tclear() {\n\t\tthis.stacks.set({ undos: stack(), redos: stack() })\n\t\tthis.pendingDiff.clear()\n\t}\n\n\t/** @internal */\n\tgetMarkIdMatching(idSubstring: string) {\n\t\tlet top = this.stacks.get().undos\n\t\twhile (top.head) {\n\t\t\tif (top.head.type === 'stop' && top.head.id.includes(idSubstring)) {\n\t\t\t\treturn top.head.id\n\t\t\t}\n\t\t\ttop = top.tail\n\t\t}\n\t\treturn null\n\t}\n\n\t/** @internal */\n\tdebug() {\n\t\tconst { undos, redos } = this.stacks.get()\n\t\treturn {\n\t\t\tundos: stackToArray(undos),\n\t\t\tredos: stackToArray(redos),\n\t\t\tpendingDiff: this.pendingDiff.debug(),\n\t\t\tstate: this.state as string,\n\t\t}\n\t}\n}\n\nconst modeToState = {\n\trecord: HistoryRecorderState.Recording,\n\t'record-preserveRedoStack': HistoryRecorderState.RecordingPreserveRedoStack,\n\tignore: HistoryRecorderState.Paused,\n} as const\n\nclass PendingDiff<R extends UnknownRecord> {\n\tprivate diff = createEmptyRecordsDiff<R>()\n\tprivate isEmptyAtom = atom('PendingDiff.isEmpty', true)\n\n\tclear() {\n\t\tconst diff = this.diff\n\t\tthis.diff = createEmptyRecordsDiff<R>()\n\t\tthis.isEmptyAtom.set(true)\n\t\treturn diff\n\t}\n\n\tisEmpty() {\n\t\treturn this.isEmptyAtom.get()\n\t}\n\n\tapply(diff: RecordsDiff<R>) {\n\t\tsquashRecordDiffsMutable(this.diff, [diff])\n\t\tthis.isEmptyAtom.set(isRecordsDiffEmpty(this.diff))\n\t}\n\n\tdebug() {\n\t\treturn { diff: this.diff, isEmpty: this.isEmpty() }\n\t}\n}\n\ntype Stack<T> = StackItem<T> | EmptyStackItem<T>\n\nfunction stack<T>(): Stack<T> {\n\treturn EMPTY_STACK_ITEM as any\n}\n\nclass EmptyStackItem<T> {\n\treadonly length = 0\n\treadonly head = null\n\treadonly tail: Stack<T> = this\n\n\tpush(head: T): Stack<T> {\n\t\treturn new StackItem<T>(head, this)\n\t}\n}\n\nconst EMPTY_STACK_ITEM = new EmptyStackItem()\n\nclass StackItem<T> {\n\tlength: number\n\tconstructor(\n\t\tpublic readonly head: T,\n\t\tpublic readonly tail: Stack<T>\n\t) {\n\t\tthis.length = tail.length + 1\n\t}\n\n\tpush(head: T): Stack<T> {\n\t\treturn new StackItem(head, this)\n\t}\n}\n\nfunction stackToArray<T>(stack: Stack<T>) {\n\tif (!stack.length) {\n\t\treturn EMPTY_ARRAY\n\t}\n\tconst arr: T[] = []\n\twhile (stack.length) {\n\t\tarr.push(stack.head!)\n\t\tstack = stack.tail\n\t}\n\treturn arr\n}\n"],
5
- "mappings": "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",
6
- "names": ["stack"]
4
+ "sourcesContent": ["import { atom, EMPTY_ARRAY, transact } from '@tldraw/state'\nimport {\n\tcreateEmptyRecordsDiff,\n\tisRecordsDiffEmpty,\n\tRecordsDiff,\n\treverseRecordsDiff,\n\tsquashRecordDiffsMutable,\n\tStore,\n\tUnknownRecord,\n} from '@tldraw/store'\nimport { exhaustiveSwitchError, noop } from '@tldraw/utils'\nimport { TLHistoryBatchOptions, TLHistoryEntry } from '../../types/history-types'\n\nenum HistoryRecorderState {\n\tRecording = 'recording',\n\tRecordingPreserveRedoStack = 'recordingPreserveRedoStack',\n\tPaused = 'paused',\n}\n\n/** @public */\nexport class HistoryManager<R extends UnknownRecord> {\n\tprivate readonly store: Store<R>\n\n\treadonly dispose: () => void\n\n\tprivate state: HistoryRecorderState = HistoryRecorderState.Recording\n\tprivate readonly pendingDiff = new PendingDiff<R>()\n\tprivate stacks = atom(\n\t\t'HistoryManager.stacks',\n\t\t{\n\t\t\tundos: stack<TLHistoryEntry<R>>(),\n\t\t\tredos: stack<TLHistoryEntry<R>>(),\n\t\t},\n\t\t{\n\t\t\tisEqual: (a, b) => a.undos === b.undos && a.redos === b.redos,\n\t\t}\n\t)\n\n\tprivate readonly annotateError: (error: unknown) => void\n\n\tconstructor(opts: { store: Store<R>; annotateError?(error: unknown): void }) {\n\t\tthis.store = opts.store\n\t\tthis.annotateError = opts.annotateError ?? noop\n\t\tthis.dispose = this.store.addHistoryInterceptor((entry, source) => {\n\t\t\tif (source !== 'user') return\n\n\t\t\tswitch (this.state) {\n\t\t\t\tcase HistoryRecorderState.Recording:\n\t\t\t\t\tthis.pendingDiff.apply(entry.changes)\n\t\t\t\t\tthis.stacks.update(({ undos }) => ({ undos, redos: stack() }))\n\t\t\t\t\tbreak\n\t\t\t\tcase HistoryRecorderState.RecordingPreserveRedoStack:\n\t\t\t\t\tthis.pendingDiff.apply(entry.changes)\n\t\t\t\t\tbreak\n\t\t\t\tcase HistoryRecorderState.Paused:\n\t\t\t\t\tbreak\n\t\t\t\tdefault:\n\t\t\t\t\texhaustiveSwitchError(this.state)\n\t\t\t}\n\t\t})\n\t}\n\n\tprivate flushPendingDiff() {\n\t\tif (this.pendingDiff.isEmpty()) return\n\n\t\tconst diff = this.pendingDiff.clear()\n\t\tthis.stacks.update(({ undos, redos }) => ({\n\t\t\tundos: undos.push({ type: 'diff', diff }),\n\t\t\tredos,\n\t\t}))\n\t}\n\n\tgetNumUndos() {\n\t\treturn this.stacks.get().undos.length + (this.pendingDiff.isEmpty() ? 0 : 1)\n\t}\n\n\tgetNumRedos() {\n\t\treturn this.stacks.get().redos.length\n\t}\n\n\t/** @internal */\n\t_isInBatch = false\n\n\tbatch(fn: () => void, opts?: TLHistoryBatchOptions) {\n\t\tconst previousState = this.state\n\n\t\t// we move to the new state only if we haven't explicitly paused\n\t\tif (previousState !== HistoryRecorderState.Paused && opts?.history) {\n\t\t\tthis.state = modeToState[opts.history]\n\t\t}\n\n\t\ttry {\n\t\t\tif (this._isInBatch) {\n\t\t\t\ttransact(fn)\n\t\t\t\treturn this\n\t\t\t}\n\n\t\t\tthis._isInBatch = true\n\t\t\ttry {\n\t\t\t\ttransact(fn)\n\t\t\t} catch (error) {\n\t\t\t\tthis.annotateError(error)\n\t\t\t\tthrow error\n\t\t\t} finally {\n\t\t\t\tthis._isInBatch = false\n\t\t\t}\n\n\t\t\treturn this\n\t\t} finally {\n\t\t\tthis.state = previousState\n\t\t}\n\t}\n\n\t// History\n\t_undo({ pushToRedoStack, toMark = undefined }: { pushToRedoStack: boolean; toMark?: string }) {\n\t\tconst previousState = this.state\n\t\tthis.state = HistoryRecorderState.Paused\n\t\ttry {\n\t\t\tlet { undos, redos } = this.stacks.get()\n\n\t\t\t// start by collecting the pending diff (everything since the last mark).\n\t\t\t// we'll accumulate the diff to undo in this variable so we can apply it atomically.\n\t\t\tconst pendingDiff = this.pendingDiff.clear()\n\t\t\tconst isPendingDiffEmpty = isRecordsDiffEmpty(pendingDiff)\n\t\t\tconst diffToUndo = reverseRecordsDiff(pendingDiff)\n\n\t\t\tif (pushToRedoStack && !isPendingDiffEmpty) {\n\t\t\t\tredos = redos.push({ type: 'diff', diff: pendingDiff })\n\t\t\t}\n\n\t\t\tlet didFindMark = false\n\t\t\tif (isPendingDiffEmpty) {\n\t\t\t\t// if nothing has happened since the last mark, pop any intermediate marks off the stack\n\t\t\t\twhile (undos.head?.type === 'stop') {\n\t\t\t\t\tconst mark = undos.head\n\t\t\t\t\tundos = undos.tail\n\t\t\t\t\tif (pushToRedoStack) {\n\t\t\t\t\t\tredos = redos.push(mark)\n\t\t\t\t\t}\n\t\t\t\t\tif (mark.id === toMark) {\n\t\t\t\t\t\tdidFindMark = true\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (!didFindMark) {\n\t\t\t\tloop: while (undos.head) {\n\t\t\t\t\tconst undo = undos.head\n\t\t\t\t\tundos = undos.tail\n\n\t\t\t\t\tif (pushToRedoStack) {\n\t\t\t\t\t\tredos = redos.push(undo)\n\t\t\t\t\t}\n\n\t\t\t\t\tswitch (undo.type) {\n\t\t\t\t\t\tcase 'diff':\n\t\t\t\t\t\t\tsquashRecordDiffsMutable(diffToUndo, [reverseRecordsDiff(undo.diff)])\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\tcase 'stop':\n\t\t\t\t\t\t\tif (!toMark) break loop\n\t\t\t\t\t\t\tif (undo.id === toMark) {\n\t\t\t\t\t\t\t\tdidFindMark = true\n\t\t\t\t\t\t\t\tbreak loop\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\texhaustiveSwitchError(undo)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (!didFindMark && toMark) {\n\t\t\t\t// whoops, we didn't find the mark we were looking for\n\t\t\t\t// don't do anything\n\t\t\t\treturn this\n\t\t\t}\n\n\t\t\tthis.store.applyDiff(diffToUndo, { ignoreEphemeralKeys: true })\n\t\t\tthis.store.ensureStoreIsUsable()\n\t\t\tthis.stacks.set({ undos, redos })\n\t\t} finally {\n\t\t\tthis.state = previousState\n\t\t}\n\n\t\treturn this\n\t}\n\n\tundo() {\n\t\tthis._undo({ pushToRedoStack: true })\n\n\t\treturn this\n\t}\n\n\tredo() {\n\t\tconst previousState = this.state\n\t\tthis.state = HistoryRecorderState.Paused\n\t\ttry {\n\t\t\tthis.flushPendingDiff()\n\n\t\t\tlet { undos, redos } = this.stacks.get()\n\t\t\tif (redos.length === 0) {\n\t\t\t\treturn this\n\t\t\t}\n\n\t\t\t// ignore any intermediate marks - this should take us to the first `diff` entry\n\t\t\twhile (redos.head?.type === 'stop') {\n\t\t\t\tundos = undos.push(redos.head)\n\t\t\t\tredos = redos.tail\n\t\t\t}\n\n\t\t\t// accumulate diffs to be redone so they can be applied atomically\n\t\t\tconst diffToRedo = createEmptyRecordsDiff<R>()\n\n\t\t\twhile (redos.head) {\n\t\t\t\tconst redo = redos.head\n\t\t\t\tundos = undos.push(redo)\n\t\t\t\tredos = redos.tail\n\n\t\t\t\tif (redo.type === 'diff') {\n\t\t\t\t\tsquashRecordDiffsMutable(diffToRedo, [redo.diff])\n\t\t\t\t} else {\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tthis.store.applyDiff(diffToRedo, { ignoreEphemeralKeys: true })\n\t\t\tthis.store.ensureStoreIsUsable()\n\t\t\tthis.stacks.set({ undos, redos })\n\t\t} finally {\n\t\t\tthis.state = previousState\n\t\t}\n\n\t\treturn this\n\t}\n\n\tbail() {\n\t\tthis._undo({ pushToRedoStack: false })\n\n\t\treturn this\n\t}\n\n\tbailToMark(id: string) {\n\t\tif (id) {\n\t\t\tthis._undo({ pushToRedoStack: false, toMark: id })\n\t\t}\n\n\t\treturn this\n\t}\n\n\tsquashToMark(id: string) {\n\t\t// remove marks between head and the mark\n\n\t\tlet top = this.stacks.get().undos\n\t\tconst popped: Array<RecordsDiff<R>> = []\n\n\t\twhile (top.head && !(top.head.type === 'stop' && top.head.id === id)) {\n\t\t\tif (top.head.type === 'diff') {\n\t\t\t\tpopped.push(top.head.diff)\n\t\t\t}\n\t\t\ttop = top.tail\n\t\t}\n\n\t\tif (!top.head || top.head?.id !== id) {\n\t\t\tconsole.error('Could not find mark to squash to: ', id)\n\t\t\treturn this\n\t\t}\n\t\tif (popped.length === 0) {\n\t\t\treturn this\n\t\t}\n\n\t\tconst diff = createEmptyRecordsDiff<R>()\n\t\tsquashRecordDiffsMutable(diff, popped.reverse())\n\n\t\tthis.stacks.update(({ redos }) => ({\n\t\t\tundos: top.push({\n\t\t\t\ttype: 'diff',\n\t\t\t\tdiff,\n\t\t\t}),\n\t\t\tredos,\n\t\t}))\n\n\t\treturn this\n\t}\n\n\t/** @internal */\n\t_mark(id: string) {\n\t\ttransact(() => {\n\t\t\tthis.flushPendingDiff()\n\t\t\tthis.stacks.update(({ undos, redos }) => ({ undos: undos.push({ type: 'stop', id }), redos }))\n\t\t})\n\t}\n\n\tclear() {\n\t\tthis.stacks.set({ undos: stack(), redos: stack() })\n\t\tthis.pendingDiff.clear()\n\t}\n\n\t/** @internal */\n\tgetMarkIdMatching(idSubstring: string) {\n\t\tlet top = this.stacks.get().undos\n\t\twhile (top.head) {\n\t\t\tif (top.head.type === 'stop' && top.head.id.includes(idSubstring)) {\n\t\t\t\treturn top.head.id\n\t\t\t}\n\t\t\ttop = top.tail\n\t\t}\n\t\treturn null\n\t}\n\n\t/** @internal */\n\tdebug() {\n\t\tconst { undos, redos } = this.stacks.get()\n\t\treturn {\n\t\t\tundos: stackToArray(undos),\n\t\t\tredos: stackToArray(redos),\n\t\t\tpendingDiff: this.pendingDiff.debug(),\n\t\t\tstate: this.state as string,\n\t\t}\n\t}\n}\n\nconst modeToState = {\n\trecord: HistoryRecorderState.Recording,\n\t'record-preserveRedoStack': HistoryRecorderState.RecordingPreserveRedoStack,\n\tignore: HistoryRecorderState.Paused,\n} as const\n\nclass PendingDiff<R extends UnknownRecord> {\n\tprivate diff = createEmptyRecordsDiff<R>()\n\tprivate isEmptyAtom = atom('PendingDiff.isEmpty', true)\n\n\tclear() {\n\t\tconst diff = this.diff\n\t\tthis.diff = createEmptyRecordsDiff<R>()\n\t\tthis.isEmptyAtom.set(true)\n\t\treturn diff\n\t}\n\n\tisEmpty() {\n\t\treturn this.isEmptyAtom.get()\n\t}\n\n\tapply(diff: RecordsDiff<R>) {\n\t\tsquashRecordDiffsMutable(this.diff, [diff])\n\t\tthis.isEmptyAtom.set(isRecordsDiffEmpty(this.diff))\n\t}\n\n\tdebug() {\n\t\treturn { diff: this.diff, isEmpty: this.isEmpty() }\n\t}\n}\n\ntype Stack<T> = StackItem<T> | EmptyStackItem<T>\n\nfunction stack<T>(): Stack<T> {\n\treturn EMPTY_STACK_ITEM as any\n}\n\nclass EmptyStackItem<T> {\n\treadonly length = 0\n\treadonly head = null\n\treadonly tail: Stack<T> = this\n\n\tpush(head: T): Stack<T> {\n\t\treturn new StackItem<T>(head, this)\n\t}\n}\n\nconst EMPTY_STACK_ITEM = new EmptyStackItem()\n\nclass StackItem<T> {\n\tlength: number\n\tconstructor(\n\t\tpublic readonly head: T,\n\t\tpublic readonly tail: Stack<T>\n\t) {\n\t\tthis.length = tail.length + 1\n\t}\n\n\tpush(head: T): Stack<T> {\n\t\treturn new StackItem(head, this)\n\t}\n}\n\nfunction stackToArray<T>(stack: Stack<T>) {\n\tif (!stack.length) {\n\t\treturn EMPTY_ARRAY\n\t}\n\tconst arr: T[] = []\n\twhile (stack.length) {\n\t\tarr.push(stack.head!)\n\t\tstack = stack.tail\n\t}\n\treturn arr\n}\n"],
5
+ "mappings": "AAAA,SAAS,MAAM,aAAa,gBAAgB;AAC5C;AAAA,EACC;AAAA,EACA;AAAA,EAEA;AAAA,EACA;AAAA,OAGM;AACP,SAAS,uBAAuB,YAAY;AAG5C,IAAK,uBAAL,kBAAKA,0BAAL;AACC,EAAAA,sBAAA,eAAY;AACZ,EAAAA,sBAAA,gCAA6B;AAC7B,EAAAA,sBAAA,YAAS;AAHL,SAAAA;AAAA,GAAA;AAOE,MAAM,eAAwC;AAAA,EACnC;AAAA,EAER;AAAA,EAED,QAA8B;AAAA,EACrB,cAAc,IAAI,YAAe;AAAA,EAC1C,SAAS;AAAA,IAChB;AAAA,IACA;AAAA,MACC,OAAO,MAAyB;AAAA,MAChC,OAAO,MAAyB;AAAA,IACjC;AAAA,IACA;AAAA,MACC,SAAS,CAAC,GAAG,MAAM,EAAE,UAAU,EAAE,SAAS,EAAE,UAAU,EAAE;AAAA,IACzD;AAAA,EACD;AAAA,EAEiB;AAAA,EAEjB,YAAY,MAAiE;AAC5E,SAAK,QAAQ,KAAK;AAClB,SAAK,gBAAgB,KAAK,iBAAiB;AAC3C,SAAK,UAAU,KAAK,MAAM,sBAAsB,CAAC,OAAO,WAAW;AAClE,UAAI,WAAW,OAAQ;AAEvB,cAAQ,KAAK,OAAO;AAAA,QACnB,KAAK;AACJ,eAAK,YAAY,MAAM,MAAM,OAAO;AACpC,eAAK,OAAO,OAAO,CAAC,EAAE,MAAM,OAAO,EAAE,OAAO,OAAO,MAAM,EAAE,EAAE;AAC7D;AAAA,QACD,KAAK;AACJ,eAAK,YAAY,MAAM,MAAM,OAAO;AACpC;AAAA,QACD,KAAK;AACJ;AAAA,QACD;AACC,gCAAsB,KAAK,KAAK;AAAA,MAClC;AAAA,IACD,CAAC;AAAA,EACF;AAAA,EAEQ,mBAAmB;AAC1B,QAAI,KAAK,YAAY,QAAQ,EAAG;AAEhC,UAAM,OAAO,KAAK,YAAY,MAAM;AACpC,SAAK,OAAO,OAAO,CAAC,EAAE,OAAO,MAAM,OAAO;AAAA,MACzC,OAAO,MAAM,KAAK,EAAE,MAAM,QAAQ,KAAK,CAAC;AAAA,MACxC;AAAA,IACD,EAAE;AAAA,EACH;AAAA,EAEA,cAAc;AACb,WAAO,KAAK,OAAO,IAAI,EAAE,MAAM,UAAU,KAAK,YAAY,QAAQ,IAAI,IAAI;AAAA,EAC3E;AAAA,EAEA,cAAc;AACb,WAAO,KAAK,OAAO,IAAI,EAAE,MAAM;AAAA,EAChC;AAAA;AAAA,EAGA,aAAa;AAAA,EAEb,MAAM,IAAgB,MAA8B;AACnD,UAAM,gBAAgB,KAAK;AAG3B,QAAI,kBAAkB,yBAA+B,MAAM,SAAS;AACnE,WAAK,QAAQ,YAAY,KAAK,OAAO;AAAA,IACtC;AAEA,QAAI;AACH,UAAI,KAAK,YAAY;AACpB,iBAAS,EAAE;AACX,eAAO;AAAA,MACR;AAEA,WAAK,aAAa;AAClB,UAAI;AACH,iBAAS,EAAE;AAAA,MACZ,SAAS,OAAO;AACf,aAAK,cAAc,KAAK;AACxB,cAAM;AAAA,MACP,UAAE;AACD,aAAK,aAAa;AAAA,MACnB;AAEA,aAAO;AAAA,IACR,UAAE;AACD,WAAK,QAAQ;AAAA,IACd;AAAA,EACD;AAAA;AAAA,EAGA,MAAM,EAAE,iBAAiB,SAAS,OAAU,GAAkD;AAC7F,UAAM,gBAAgB,KAAK;AAC3B,SAAK,QAAQ;AACb,QAAI;AACH,UAAI,EAAE,OAAO,MAAM,IAAI,KAAK,OAAO,IAAI;AAIvC,YAAM,cAAc,KAAK,YAAY,MAAM;AAC3C,YAAM,qBAAqB,mBAAmB,WAAW;AACzD,YAAM,aAAa,mBAAmB,WAAW;AAEjD,UAAI,mBAAmB,CAAC,oBAAoB;AAC3C,gBAAQ,MAAM,KAAK,EAAE,MAAM,QAAQ,MAAM,YAAY,CAAC;AAAA,MACvD;AAEA,UAAI,cAAc;AAClB,UAAI,oBAAoB;AAEvB,eAAO,MAAM,MAAM,SAAS,QAAQ;AACnC,gBAAM,OAAO,MAAM;AACnB,kBAAQ,MAAM;AACd,cAAI,iBAAiB;AACpB,oBAAQ,MAAM,KAAK,IAAI;AAAA,UACxB;AACA,cAAI,KAAK,OAAO,QAAQ;AACvB,0BAAc;AACd;AAAA,UACD;AAAA,QACD;AAAA,MACD;AAEA,UAAI,CAAC,aAAa;AACjB,aAAM,QAAO,MAAM,MAAM;AACxB,gBAAM,OAAO,MAAM;AACnB,kBAAQ,MAAM;AAEd,cAAI,iBAAiB;AACpB,oBAAQ,MAAM,KAAK,IAAI;AAAA,UACxB;AAEA,kBAAQ,KAAK,MAAM;AAAA,YAClB,KAAK;AACJ,uCAAyB,YAAY,CAAC,mBAAmB,KAAK,IAAI,CAAC,CAAC;AACpE;AAAA,YACD,KAAK;AACJ,kBAAI,CAAC,OAAQ,OAAM;AACnB,kBAAI,KAAK,OAAO,QAAQ;AACvB,8BAAc;AACd,sBAAM;AAAA,cACP;AACA;AAAA,YACD;AACC,oCAAsB,IAAI;AAAA,UAC5B;AAAA,QACD;AAAA,MACD;AAEA,UAAI,CAAC,eAAe,QAAQ;AAG3B,eAAO;AAAA,MACR;AAEA,WAAK,MAAM,UAAU,YAAY,EAAE,qBAAqB,KAAK,CAAC;AAC9D,WAAK,MAAM,oBAAoB;AAC/B,WAAK,OAAO,IAAI,EAAE,OAAO,MAAM,CAAC;AAAA,IACjC,UAAE;AACD,WAAK,QAAQ;AAAA,IACd;AAEA,WAAO;AAAA,EACR;AAAA,EAEA,OAAO;AACN,SAAK,MAAM,EAAE,iBAAiB,KAAK,CAAC;AAEpC,WAAO;AAAA,EACR;AAAA,EAEA,OAAO;AACN,UAAM,gBAAgB,KAAK;AAC3B,SAAK,QAAQ;AACb,QAAI;AACH,WAAK,iBAAiB;AAEtB,UAAI,EAAE,OAAO,MAAM,IAAI,KAAK,OAAO,IAAI;AACvC,UAAI,MAAM,WAAW,GAAG;AACvB,eAAO;AAAA,MACR;AAGA,aAAO,MAAM,MAAM,SAAS,QAAQ;AACnC,gBAAQ,MAAM,KAAK,MAAM,IAAI;AAC7B,gBAAQ,MAAM;AAAA,MACf;AAGA,YAAM,aAAa,uBAA0B;AAE7C,aAAO,MAAM,MAAM;AAClB,cAAM,OAAO,MAAM;AACnB,gBAAQ,MAAM,KAAK,IAAI;AACvB,gBAAQ,MAAM;AAEd,YAAI,KAAK,SAAS,QAAQ;AACzB,mCAAyB,YAAY,CAAC,KAAK,IAAI,CAAC;AAAA,QACjD,OAAO;AACN;AAAA,QACD;AAAA,MACD;AAEA,WAAK,MAAM,UAAU,YAAY,EAAE,qBAAqB,KAAK,CAAC;AAC9D,WAAK,MAAM,oBAAoB;AAC/B,WAAK,OAAO,IAAI,EAAE,OAAO,MAAM,CAAC;AAAA,IACjC,UAAE;AACD,WAAK,QAAQ;AAAA,IACd;AAEA,WAAO;AAAA,EACR;AAAA,EAEA,OAAO;AACN,SAAK,MAAM,EAAE,iBAAiB,MAAM,CAAC;AAErC,WAAO;AAAA,EACR;AAAA,EAEA,WAAW,IAAY;AACtB,QAAI,IAAI;AACP,WAAK,MAAM,EAAE,iBAAiB,OAAO,QAAQ,GAAG,CAAC;AAAA,IAClD;AAEA,WAAO;AAAA,EACR;AAAA,EAEA,aAAa,IAAY;AAGxB,QAAI,MAAM,KAAK,OAAO,IAAI,EAAE;AAC5B,UAAM,SAAgC,CAAC;AAEvC,WAAO,IAAI,QAAQ,EAAE,IAAI,KAAK,SAAS,UAAU,IAAI,KAAK,OAAO,KAAK;AACrE,UAAI,IAAI,KAAK,SAAS,QAAQ;AAC7B,eAAO,KAAK,IAAI,KAAK,IAAI;AAAA,MAC1B;AACA,YAAM,IAAI;AAAA,IACX;AAEA,QAAI,CAAC,IAAI,QAAQ,IAAI,MAAM,OAAO,IAAI;AACrC,cAAQ,MAAM,sCAAsC,EAAE;AACtD,aAAO;AAAA,IACR;AACA,QAAI,OAAO,WAAW,GAAG;AACxB,aAAO;AAAA,IACR;AAEA,UAAM,OAAO,uBAA0B;AACvC,6BAAyB,MAAM,OAAO,QAAQ,CAAC;AAE/C,SAAK,OAAO,OAAO,CAAC,EAAE,MAAM,OAAO;AAAA,MAClC,OAAO,IAAI,KAAK;AAAA,QACf,MAAM;AAAA,QACN;AAAA,MACD,CAAC;AAAA,MACD;AAAA,IACD,EAAE;AAEF,WAAO;AAAA,EACR;AAAA;AAAA,EAGA,MAAM,IAAY;AACjB,aAAS,MAAM;AACd,WAAK,iBAAiB;AACtB,WAAK,OAAO,OAAO,CAAC,EAAE,OAAO,MAAM,OAAO,EAAE,OAAO,MAAM,KAAK,EAAE,MAAM,QAAQ,GAAG,CAAC,GAAG,MAAM,EAAE;AAAA,IAC9F,CAAC;AAAA,EACF;AAAA,EAEA,QAAQ;AACP,SAAK,OAAO,IAAI,EAAE,OAAO,MAAM,GAAG,OAAO,MAAM,EAAE,CAAC;AAClD,SAAK,YAAY,MAAM;AAAA,EACxB;AAAA;AAAA,EAGA,kBAAkB,aAAqB;AACtC,QAAI,MAAM,KAAK,OAAO,IAAI,EAAE;AAC5B,WAAO,IAAI,MAAM;AAChB,UAAI,IAAI,KAAK,SAAS,UAAU,IAAI,KAAK,GAAG,SAAS,WAAW,GAAG;AAClE,eAAO,IAAI,KAAK;AAAA,MACjB;AACA,YAAM,IAAI;AAAA,IACX;AACA,WAAO;AAAA,EACR;AAAA;AAAA,EAGA,QAAQ;AACP,UAAM,EAAE,OAAO,MAAM,IAAI,KAAK,OAAO,IAAI;AACzC,WAAO;AAAA,MACN,OAAO,aAAa,KAAK;AAAA,MACzB,OAAO,aAAa,KAAK;AAAA,MACzB,aAAa,KAAK,YAAY,MAAM;AAAA,MACpC,OAAO,KAAK;AAAA,IACb;AAAA,EACD;AACD;AAEA,MAAM,cAAc;AAAA,EACnB,QAAQ;AAAA,EACR,4BAA4B;AAAA,EAC5B,QAAQ;AACT;AAEA,MAAM,YAAqC;AAAA,EAClC,OAAO,uBAA0B;AAAA,EACjC,cAAc,KAAK,uBAAuB,IAAI;AAAA,EAEtD,QAAQ;AACP,UAAM,OAAO,KAAK;AAClB,SAAK,OAAO,uBAA0B;AACtC,SAAK,YAAY,IAAI,IAAI;AACzB,WAAO;AAAA,EACR;AAAA,EAEA,UAAU;AACT,WAAO,KAAK,YAAY,IAAI;AAAA,EAC7B;AAAA,EAEA,MAAM,MAAsB;AAC3B,6BAAyB,KAAK,MAAM,CAAC,IAAI,CAAC;AAC1C,SAAK,YAAY,IAAI,mBAAmB,KAAK,IAAI,CAAC;AAAA,EACnD;AAAA,EAEA,QAAQ;AACP,WAAO,EAAE,MAAM,KAAK,MAAM,SAAS,KAAK,QAAQ,EAAE;AAAA,EACnD;AACD;AAIA,SAAS,QAAqB;AAC7B,SAAO;AACR;AAEA,MAAM,eAAkB;AAAA,EACd,SAAS;AAAA,EACT,OAAO;AAAA,EACP,OAAiB;AAAA,EAE1B,KAAK,MAAmB;AACvB,WAAO,IAAI,UAAa,MAAM,IAAI;AAAA,EACnC;AACD;AAEA,MAAM,mBAAmB,IAAI,eAAe;AAE5C,MAAM,UAAa;AAAA,EAElB,YACiB,MACA,MACf;AAFe;AACA;AAEhB,SAAK,SAAS,KAAK,SAAS;AAAA,EAC7B;AAAA,EANA;AAAA,EAQA,KAAK,MAAmB;AACvB,WAAO,IAAI,UAAU,MAAM,IAAI;AAAA,EAChC;AACD;AAEA,SAAS,aAAgBC,QAAiB;AACzC,MAAI,CAACA,OAAM,QAAQ;AAClB,WAAO;AAAA,EACR;AACA,QAAM,MAAW,CAAC;AAClB,SAAOA,OAAM,QAAQ;AACpB,QAAI,KAAKA,OAAM,IAAK;AACpB,IAAAA,SAAQA,OAAM;AAAA,EACf;AACA,SAAO;AACR;",
6
+ "names": ["HistoryRecorderState", "stack"]
7
7
  }
@@ -1,8 +1,8 @@
1
- const version = "4.5.0-canary.f284eeb67609";
1
+ const version = "4.5.0-next.74a79354f99f";
2
2
  const publishDates = {
3
3
  major: "2025-09-18T14:39:22.803Z",
4
- minor: "2026-02-26T09:42:31.895Z",
5
- patch: "2026-02-26T09:42:31.895Z"
4
+ minor: "2026-02-26T11:31:57.370Z",
5
+ patch: "2026-02-26T11:31:57.370Z"
6
6
  };
7
7
  export {
8
8
  publishDates,
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/version.ts"],
4
- "sourcesContent": ["// This file is automatically generated by internal/scripts/refresh-assets.ts.\n// Do not edit manually. Or do, I'm a comment, not a cop.\n\nexport const version = '4.5.0-canary.f284eeb67609'\nexport const publishDates = {\n\tmajor: '2025-09-18T14:39:22.803Z',\n\tminor: '2026-02-26T09:42:31.895Z',\n\tpatch: '2026-02-26T09:42:31.895Z',\n}\n"],
4
+ "sourcesContent": ["// This file is automatically generated by internal/scripts/refresh-assets.ts.\n// Do not edit manually. Or do, I'm a comment, not a cop.\n\nexport const version = '4.5.0-next.74a79354f99f'\nexport const publishDates = {\n\tmajor: '2025-09-18T14:39:22.803Z',\n\tminor: '2026-02-26T11:31:57.370Z',\n\tpatch: '2026-02-26T11:31:57.370Z',\n}\n"],
5
5
  "mappings": "AAGO,MAAM,UAAU;AAChB,MAAM,eAAe;AAAA,EAC3B,OAAO;AAAA,EACP,OAAO;AAAA,EACP,OAAO;AACR;",
6
6
  "names": []
7
7
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@tldraw/editor",
3
3
  "description": "tldraw infinite canvas SDK (editor).",
4
- "version": "4.5.0-canary.f284eeb67609",
4
+ "version": "4.5.0-next.74a79354f99f",
5
5
  "author": {
6
6
  "name": "tldraw Inc.",
7
7
  "email": "hello@tldraw.com"
@@ -49,12 +49,12 @@
49
49
  "@tiptap/core": "^3.12.1",
50
50
  "@tiptap/pm": "^3.12.1",
51
51
  "@tiptap/react": "^3.12.1",
52
- "@tldraw/state": "4.5.0-canary.f284eeb67609",
53
- "@tldraw/state-react": "4.5.0-canary.f284eeb67609",
54
- "@tldraw/store": "4.5.0-canary.f284eeb67609",
55
- "@tldraw/tlschema": "4.5.0-canary.f284eeb67609",
56
- "@tldraw/utils": "4.5.0-canary.f284eeb67609",
57
- "@tldraw/validate": "4.5.0-canary.f284eeb67609",
52
+ "@tldraw/state": "4.5.0-next.74a79354f99f",
53
+ "@tldraw/state-react": "4.5.0-next.74a79354f99f",
54
+ "@tldraw/store": "4.5.0-next.74a79354f99f",
55
+ "@tldraw/tlschema": "4.5.0-next.74a79354f99f",
56
+ "@tldraw/utils": "4.5.0-next.74a79354f99f",
57
+ "@tldraw/validate": "4.5.0-next.74a79354f99f",
58
58
  "@use-gesture/react": "^10.3.1",
59
59
  "classnames": "^2.5.1",
60
60
  "eventemitter3": "^4.0.7",
@@ -11,12 +11,11 @@ import {
11
11
  import { exhaustiveSwitchError, noop } from '@tldraw/utils'
12
12
  import { TLHistoryBatchOptions, TLHistoryEntry } from '../../types/history-types'
13
13
 
14
- const HistoryRecorderState = {
15
- Recording: 'recording',
16
- RecordingPreserveRedoStack: 'recordingPreserveRedoStack',
17
- Paused: 'paused',
18
- } as const
19
- type HistoryRecorderState = (typeof HistoryRecorderState)[keyof typeof HistoryRecorderState]
14
+ enum HistoryRecorderState {
15
+ Recording = 'recording',
16
+ RecordingPreserveRedoStack = 'recordingPreserveRedoStack',
17
+ Paused = 'paused',
18
+ }
20
19
 
21
20
  /** @public */
22
21
  export class HistoryManager<R extends UnknownRecord> {
package/src/version.ts CHANGED
@@ -1,9 +1,9 @@
1
1
  // This file is automatically generated by internal/scripts/refresh-assets.ts.
2
2
  // Do not edit manually. Or do, I'm a comment, not a cop.
3
3
 
4
- export const version = '4.5.0-canary.f284eeb67609'
4
+ export const version = '4.5.0-next.74a79354f99f'
5
5
  export const publishDates = {
6
6
  major: '2025-09-18T14:39:22.803Z',
7
- minor: '2026-02-26T09:42:31.895Z',
8
- patch: '2026-02-26T09:42:31.895Z',
7
+ minor: '2026-02-26T11:31:57.370Z',
8
+ patch: '2026-02-26T11:31:57.370Z',
9
9
  }