@weasel-js/history 1.17.1 → 1.17.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +2 -0
- package/dist/index.js +4 -2
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.d.ts
CHANGED
|
@@ -86,7 +86,9 @@ interface Journal {
|
|
|
86
86
|
getVersion(): number;
|
|
87
87
|
/** Fires whenever `getVersion` bumps. Returns an unsubscribe fn. */
|
|
88
88
|
subscribe(listener: () => void): () => void;
|
|
89
|
+
/** Throws while a journal opened inside this one is still active. */
|
|
89
90
|
commit(label: string): void;
|
|
91
|
+
/** Cancels a journal still active inside this one first. */
|
|
90
92
|
cancel(): void;
|
|
91
93
|
suspend(): void;
|
|
92
94
|
isActive(): boolean;
|
package/dist/index.js
CHANGED
|
@@ -300,6 +300,7 @@ function createJournalInternal(parent, adapter, opts, onClose, inherited = {}) {
|
|
|
300
300
|
subscribe: changed.subscribe,
|
|
301
301
|
commit(label) {
|
|
302
302
|
if (state !== "active") throw new Error("Journal is not active");
|
|
303
|
+
if (inner.activeJournal?.()) throw new Error("A journal inside this one is still active \u2014 commit, cancel, or suspend it first");
|
|
303
304
|
const { forwardOps, baseOps } = _journalAccessInternal(inner).appliedOps();
|
|
304
305
|
_journalAccessInternal(parent).record(
|
|
305
306
|
forwardOps,
|
|
@@ -314,6 +315,7 @@ function createJournalInternal(parent, adapter, opts, onClose, inherited = {}) {
|
|
|
314
315
|
},
|
|
315
316
|
cancel() {
|
|
316
317
|
if (state !== "active") throw new Error("Journal is not active");
|
|
318
|
+
inner.activeJournal?.()?.cancel();
|
|
317
319
|
inner.goto(0);
|
|
318
320
|
state = "closed";
|
|
319
321
|
RESUMERS.delete(journal);
|
|
@@ -576,7 +578,7 @@ function createHistory(adapter, options = {}) {
|
|
|
576
578
|
},
|
|
577
579
|
goto(n) {
|
|
578
580
|
const total = undoStack.length + redoStack.length;
|
|
579
|
-
if (n < 0 || n > total || n === undoStack.length) return;
|
|
581
|
+
if (!Number.isInteger(n) || n < 0 || n > total || n === undoStack.length) return;
|
|
580
582
|
const start = undoStack.length;
|
|
581
583
|
let walked;
|
|
582
584
|
try {
|
|
@@ -593,7 +595,7 @@ function createHistory(adapter, options = {}) {
|
|
|
593
595
|
bump(stepOf("goto", walked));
|
|
594
596
|
},
|
|
595
597
|
timestampAt(i) {
|
|
596
|
-
if (i < 0) return void 0;
|
|
598
|
+
if (!Number.isInteger(i) || i < 0) return void 0;
|
|
597
599
|
if (i < undoStack.length) return undoStack[i].timestamp;
|
|
598
600
|
return redoStack[redoStack.length - 1 - (i - undoStack.length)]?.timestamp;
|
|
599
601
|
},
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/serialized.ts","../src/entryOps.ts","../src/journal.ts","../src/history.ts","../src/swapOp.ts"],"names":["snapshot","createEmitter","options"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * A history's entries, their wire form, and the trip between the two.\n */\nimport type { Op } from './op';\n\nexport interface Entry {\n /** Monotonic id assigned at first push. Stable across coalesce merges\n * (a merged entry keeps the original id) so UI lists keyed on `id` don't\n * flicker when the underlying entry mutates. */\n id: number;\n /** Forward ops — applied on redo, reflect the latest to-state after any\n * coalescing. Diverges from `baseOps` only after a coalesce. */\n forwardOps: Op[];\n /** Original ops at first push — their `.invert()` is what undo replays.\n * Preserved across coalesces so undo always returns to the original\n * pre-edit state, no matter how many coalesces happened. */\n baseOps: Op[];\n label: string;\n /** `now()` at last push or coalesce: gates the coalesce window, and is the\n * entry's place in time for `depthAt` and `prune`. */\n timestamp: number;\n /** See `HistoryEntry.pushes`. */\n pushes: number;\n /** Node ids touched by ops in this entry. See `HistoryEntry.touchedIds`. */\n touchedIds: ReadonlySet<string>;\n /** Selection as of just before this entry's ops ran; restored by undo.\n * Undefined when nothing supplied one (no `selection` option, or a\n * `recordEntry` call that captured none). */\n selectionBefore?: readonly string[];\n /** Selection as of just before this entry was last undone; restored by\n * redo. Written on the way past, so it reflects where the user actually\n * was rather than where the entry's ops left them. */\n selectionAfter?: readonly string[];\n /** The key a `recordEntry` gave it, which a later one with the same key folds into. */\n coalesceKey?: string;\n}\n\n/** Wire form of a single op inside a serialized history. The pair\n * `(name, args)` reconstructs a live `Op` via the op-factory registry. */\nexport interface SerializedOp {\n name: string;\n args: unknown;\n}\n\n/** Wire form of one history entry. `forwardOps` / `baseOps` mirror the\n * in-memory entry's fields (see `Entry` above) but only carry the\n * serializable `(name, args)` projection of each op. */\nexport interface SerializedHistoryEntry {\n id: number;\n label: string;\n forwardOps: SerializedOp[];\n baseOps: SerializedOp[];\n /** See `HistoryEntry.pushes`. Absent in snapshots that predate it; read as 1. */\n pushes?: number;\n /** See `HistoryEntry.timestamp`. Absent in snapshots that predate it; read as 0. */\n timestamp?: number;\n selectionBefore?: readonly string[];\n selectionAfter?: readonly string[];\n}\n\n/** Snapshot of an entire `History` instance. Designed to live alongside the\n * scene snapshot so a reload restores the undo / redo stacks to exactly\n * where they were. Op `args` are carried by reference, so the snapshot is\n * as serializable as they are: JSON drops a function an op's args hold,\n * where a structured clone (IndexedDB, `postMessage`) throws on it. */\nexport interface SerializedHistory {\n version: 1;\n undoStack: SerializedHistoryEntry[];\n /** Stored newest-first, mirroring the in-memory stack so a deserialized\n * history matches the original's `entries().redo` ordering. */\n redoStack: SerializedHistoryEntry[];\n nextEntryId: number;\n /** Futures kept by a branching history, each under the id of the entry it\n * forks from (`floor`'s for the oldest reachable state), entries in time\n * order. Absent when none. */\n branches?: { at: number; entries: SerializedHistoryEntry[] }[];\n /** The id naming the state beneath the undo stack: that of the last undo\n * entry evicted or left out of the snapshot. Absent, and read as 0, when\n * the stack reaches back to the start. */\n floor?: number;\n /** Entries left out: those with an op lacking a `name`, which can't\n * round-trip through the op-factory registry, and those only reachable\n * across one. Always present (zero when nothing was dropped) so callers\n * can detect loss without parsing the debug log. */\n droppedEntries: number;\n}\n\n/** Diagnostics sink for {@link CreateHistoryOptions.debug}. Messages arrive\n * pre-formatted and unconditional; deciding whether to emit them is the\n * caller's job. */\nexport interface HistoryLogger {\n log(message: string): void;\n warn(message: string): void;\n}\n\n/** The stacks a history holds, as `snapshot` reads them and `rebuilt` answers. */\nexport interface Stacks {\n undoStack: Entry[];\n redoStack: Entry[];\n /** Futures set aside, by the id of the entry they fork from. */\n forks: Map<number, Entry[][]>;\n floorId: number;\n nextEntryId: number;\n}\n\n/** `stacks` as a snapshot: see `History.serialize` for what is left out. */\nexport function snapshot(stacks: Stacks, logger: HistoryLogger): SerializedHistory {\n const { undoStack, redoStack, forks, floorId, nextEntryId } = stacks;\n let total = 0;\n const project = (entries: readonly Entry[]): (SerializedHistoryEntry | null)[] => {\n total += entries.length;\n return entries.map((e) => entryToSerial(e, logger));\n };\n // Both stacks keep the entries nearest the current state at their end,\n // so what survives a nameless entry is whatever follows the last one.\n const nearest = (stack: readonly Entry[]): SerializedHistoryEntry[] => {\n const serial = project(stack);\n return serial.slice(serial.lastIndexOf(null) + 1) as SerializedHistoryEntry[];\n };\n const undo = nearest(undoStack);\n const redo = nearest(redoStack);\n\n // Cutting the undo stack raises the snapshot's floor to the last entry cut.\n const floor = undo.length === undoStack.length ? floorId : undoStack[undoStack.length - undo.length - 1]!.id;\n const reachable = new Set<number>([floor, ...[...undo, ...redo].map((e) => e.id)]);\n let pending = [...forks].flatMap(([at, kept]) => kept.map((b) => {\n const serial = project(b);\n const cut = serial.indexOf(null);\n return { at, entries: (cut < 0 ? serial : serial.slice(0, cut)) as SerializedHistoryEntry[] };\n })).filter((b) => b.entries.length > 0);\n const branches: { at: number; entries: SerializedHistoryEntry[] }[] = [];\n for (let grew = true; grew; ) {\n grew = false;\n const waiting: typeof pending = [];\n for (const b of pending) {\n if (!reachable.has(b.at)) { waiting.push(b); continue; }\n branches.push(b);\n for (const e of b.entries) reachable.add(e.id);\n grew = true;\n }\n pending = waiting;\n }\n\n const carried = undo.length + redo.length + branches.reduce((n, b) => n + b.entries.length, 0);\n return {\n version: 1,\n undoStack: undo,\n redoStack: redo,\n ...(branches.length > 0 ? { branches } : {}),\n ...(floor !== 0 ? { floor } : {}),\n nextEntryId,\n droppedEntries: total - carried,\n };\n}\n\n/** The stacks `snapshot` describes, each op rebuilt through `custom`. */\nexport function rebuilt(snapshot: SerializedHistory, custom: CustomRebuild | undefined, logger: HistoryLogger): Stacks {\n const entry = (se: SerializedHistoryEntry): Entry => serialToEntry(se, custom, logger);\n const undoStack = snapshot.undoStack.map(entry);\n const redoStack = snapshot.redoStack.map(entry);\n const forks = new Map<number, Entry[][]>();\n for (const b of snapshot.branches ?? []) {\n const entries = b.entries.map(entry);\n const kept = forks.get(b.at);\n if (kept) kept.push(entries);\n else forks.set(b.at, [entries]);\n }\n // Seed nextEntryId from the snapshot, then defensively bump past any\n // restored id — a malformed snapshot with duplicate or out-of-range\n // ids should never produce a collision with future entries.\n let nextEntryId = snapshot.nextEntryId;\n const seen = [undoStack, redoStack, ...[...forks.values()].flat()];\n for (const entries of seen) for (const e of entries) if (e.id >= nextEntryId) nextEntryId = e.id + 1;\n return { undoStack, redoStack, forks, floorId: snapshot.floor ?? 0, nextEntryId };\n}\n\n/** Extract node ids from an op's `args`. Handles the common patterns:\n * - `args.id` (string) — transform, setPath, reparent\n * - `args.node.id` (string) — insert, delete\n * - `args.nodes[].id` (string) — an op that takes several nodes at once\n * Ops that match none of them contribute nothing. */\nexport function touchedIdsFromOps(ops: readonly Op[]): ReadonlySet<string> {\n const ids = new Set<string>();\n for (const op of ops) {\n if (op.args === null || typeof op.args !== 'object') continue;\n const a = op.args as Record<string, unknown>;\n if (typeof a['id'] === 'string') {\n ids.add(a['id']);\n } else if (a['node'] !== null && typeof a['node'] === 'object') {\n const n = a['node'] as Record<string, unknown>;\n if (typeof n['id'] === 'string') ids.add(n['id']);\n } else if (Array.isArray(a['nodes'])) {\n for (const n of a['nodes'] as unknown[]) {\n const id = n !== null && typeof n === 'object' ? (n as Record<string, unknown>)['id'] : undefined;\n if (typeof id === 'string') ids.add(id);\n }\n }\n }\n return ids;\n}\n\n/** Project an `Op` to its `(name, args)` wire form. Returns `null` for ops\n * missing `name` — the caller drops the containing entry. */\nfunction opToSerial(op: Op): SerializedOp | null {\n if (typeof op.name !== 'string') return null;\n return { name: op.name, args: op.args };\n}\n\n/** Project a runtime entry to its serialized form, or `null` if any op in\n * the entry can't be serialized (we drop the whole entry then — a partially\n * serializable entry would invert against the wrong baseline on undo). */\nfunction entryToSerial(e: Entry, logger: HistoryLogger): SerializedHistoryEntry | null {\n const forwardOps: SerializedOp[] = [];\n for (const op of e.forwardOps) {\n const s = opToSerial(op);\n if (s === null) {\n logger.log(`serialize: dropping entry id=${e.id} \"${e.label}\" — forwardOp without name`);\n return null;\n }\n forwardOps.push(s);\n }\n const baseOps: SerializedOp[] = [];\n for (const op of e.baseOps) {\n const s = opToSerial(op);\n if (s === null) {\n logger.log(`serialize: dropping entry id=${e.id} \"${e.label}\" — baseOp without name`);\n return null;\n }\n baseOps.push(s);\n }\n return {\n id: e.id, label: e.label, forwardOps, baseOps, pushes: e.pushes, timestamp: e.timestamp,\n ...(e.selectionBefore ? { selectionBefore: e.selectionBefore } : {}),\n ...(e.selectionAfter ? { selectionAfter: e.selectionAfter } : {}),\n };\n}\n\n/** Placeholder op used when the registry lacks the requested name. Stable\n * identity (each placeholder is its own invert) keeps undo/redo plumbing\n * happy without performing any adapter mutation. */\nfunction placeholderOp(name: string, args: unknown, label?: string): Op {\n const op: Op = {\n name,\n args,\n label,\n apply: () => 'noop' as const,\n invert: () => op,\n };\n return op;\n}\n\n/** Signature of a per-instance op rebuilder (`CreateHistoryOptions.rebuildOp`). */\ntype CustomRebuild = (name: string, args: unknown) => Op | null;\n\n/** Rebuild a single serialized op via `custom` (if provided), falling back to\n * a no-op placeholder.\n *\n * This engine deliberately knows nothing about any op registry: hydrating a\n * `(name, args)` pair back into an op is the caller's concern, injected\n * through `CreateHistoryOptions.rebuildOp`. `@weasel-js/core`'s\n * `createHistory` wrapper supplies its global op-factory registry as that\n * hook, so core consumers see unchanged behavior. */\nfunction rebuildSerialOp(so: SerializedOp, label: string, custom: CustomRebuild | undefined, logger: HistoryLogger): Op {\n const viaCustom = custom ? custom(so.name, so.args) : null;\n if (viaCustom !== null) return viaCustom;\n logger.log(`restore: unknown op name \"${so.name}\" — substituting no-op placeholder`);\n return placeholderOp(so.name, so.args, label);\n}\n\nfunction sameSerialOps(a: readonly SerializedOp[], b: readonly SerializedOp[]): boolean {\n if (a === b) return true;\n if (a.length !== b.length) return false;\n try {\n return JSON.stringify(a) === JSON.stringify(b);\n } catch {\n return false;\n }\n}\n\n/** Rebuild a runtime entry from its serialized form. Unknown op names become\n * no-op placeholders so the entry still occupies its slot in the stack. */\nfunction serialToEntry(se: SerializedHistoryEntry, custom: CustomRebuild | undefined, logger: HistoryLogger): Entry {\n const forwardOps = se.forwardOps.map((so) => rebuildSerialOp(so, se.label, custom, logger));\n // An entry nothing coalesced into holds one array as both halves, and a\n // step that throws unwinds differently when they differ.\n const baseOps = sameSerialOps(se.forwardOps, se.baseOps)\n ? forwardOps\n : se.baseOps.map((so) => rebuildSerialOp(so, se.label, custom, logger));\n return {\n id: se.id,\n label: se.label,\n forwardOps,\n baseOps,\n timestamp: se.timestamp ?? 0,\n pushes: se.pushes ?? 1,\n // Re-derive touchedIds from the rebuilt ops rather than trying to\n // round-trip the Set through the serialized form (Sets aren't JSON-safe).\n touchedIds: touchedIdsFromOps(forwardOps),\n ...(se.selectionBefore ? { selectionBefore: [...se.selectionBefore] } : {}),\n ...(se.selectionAfter ? { selectionAfter: [...se.selectionAfter] } : {}),\n };\n}\n","/**\n * The parts of a history that read or apply an entry's ops without touching\n * its stacks.\n */\nimport type { Op } from './op';\nimport { touchedIdsFromOps, type Entry, type HistoryLogger } from './serialized';\nimport type { HistoryEntry, HistoryStep } from './historyTypes';\n\nexport /** Whether both lists are non-empty, every op is keyed, and the keys match as multisets. */\nfunction sameCoalesceKeys(top: readonly Op[], incoming: readonly Op[]): boolean {\n if (top.length === 0 || incoming.length === 0 || top.length !== incoming.length) return false;\n const counts = new Map<string, number>();\n for (const op of top) {\n const k = op.coalesceKey;\n if (k === undefined) return false;\n counts.set(k, (counts.get(k) ?? 0) + 1);\n }\n for (const op of incoming) {\n const k = op.coalesceKey;\n const c = k === undefined ? 0 : counts.get(k) ?? 0;\n if (!c) return false;\n counts.set(k!, c - 1);\n }\n return true;\n}\n\nexport function entryView(e: Entry): HistoryEntry {\n return {\n id: e.id, label: e.label, timestamp: e.timestamp, pushes: e.pushes, touchedIds: e.touchedIds,\n ...(e.selectionBefore ? { selectionBefore: e.selectionBefore } : {}),\n ...(e.selectionAfter ? { selectionAfter: e.selectionAfter } : {}),\n };\n}\n\nexport function stepOf(kind: HistoryStep['kind'], entries: readonly Entry[] = []): HistoryStep {\n return { kind, entries: entries.map((e) => ({ id: e.id, label: e.label, ops: e.forwardOps })) };\n}\n\n/** Build the all-or-nothing apply a history runs every step through, against `adapter`. */\nexport function createApplier(adapter: unknown, logger: HistoryLogger) {\n /** Apply `ops` best-effort while unwinding a failed step: the throw being\n * unwound is the one the caller sees, so a second one is only logged. */\n function applyUnwinding(ops: Op[]): void {\n for (const op of ops) {\n try {\n op.apply(adapter);\n } catch (err) {\n logger.warn(`unwinding a failed step: op \"${op.name ?? '?'}\" threw: ${String(err)}`);\n }\n }\n }\n\n /** Apply every op or none: when one throws, the ops that ran before it are\n * inverted, newest first, then `settle` is applied, and the throw\n * propagates. Returns true iff at least one op did NOT explicitly return\n * `false` / `'noop'` — `pushOrCoalesce` skips the entry when every op in\n * the batch was a silent no-op (e.g. reorder where the order already\n * matched). Ops returning `undefined`/`void` count as \"mutated\".\n *\n * `settle` is for a coalesced entry, whose two halves are not each\n * other's inverse: inverting what ran lands on the other half's far side,\n * and re-applying that half is what returns to where the step began. */\n function applyAllOrNothing(ops: Op[], settle?: () => Op[], idle?: Op[]): boolean {\n let anyMutated = false;\n let done = 0;\n try {\n for (; done < ops.length; done++) {\n const r = ops[done]!.apply(adapter);\n if (r !== false && r !== 'noop') anyMutated = true;\n else idle?.push(ops[done]!);\n }\n } catch (err) {\n if (done > 0) {\n applyUnwinding(ops.slice(0, done).reverse().map((op) => op.invert()));\n if (settle) applyUnwinding(settle());\n }\n throw err;\n }\n return anyMutated;\n }\n return applyAllOrNothing;\n}\n\n/** Fold `ops`, recorded under the key `top` carries, into `top`: they run after its own, so its\n * undo inverts them first and then the state they started from. */\nexport function foldEntry(top: Entry, ops: Op[], at: number): void {\n const same = top.forwardOps === top.baseOps;\n top.forwardOps = [...top.forwardOps, ...ops];\n top.baseOps = same ? top.forwardOps : [...top.baseOps, ...ops];\n top.timestamp = at;\n top.pushes++;\n const merged = new Set(top.touchedIds);\n for (const id of touchedIdsFromOps(ops)) merged.add(id);\n top.touchedIds = merged;\n}\n\n/** Whether any op in `ops` records the ops it caused in its place: a loop\n * rather than `some`, since every push asks. */\nexport function anyCaused(ops: readonly Op[]): boolean {\n for (let i = 0; i < ops.length; i++) if (ops[i]!.caused !== undefined) return true;\n return false;\n}\n\n/** Both halves of `entries` run end to end, as one entry would hold them: one\n * list when nothing coalesced, since a step that throws unwinds a two-list\n * entry by replaying its other half. */\nexport function appliedHalves(entries: readonly Entry[]): { forwardOps: Op[]; baseOps: Op[] } {\n const forwardOps = entries.flatMap((e) => e.forwardOps);\n if (entries.every((e) => e.forwardOps === e.baseOps)) return { forwardOps, baseOps: forwardOps };\n return { forwardOps, baseOps: entries.flatMap((e) => e.baseOps) };\n}\n","import { createEmitter } from '@weasel-js/registry';\nimport type { Op } from './op';\nimport { _journalAccessInternal, createHistory, type CreateHistoryOptions, type History, type HistoryEntry, type HistoryStep } from './history';\n\nconst RESUMERS = new WeakMap<Journal, () => void>();\n\n/** Called by `history.resumeJournal`. Not part of the public API. */\nexport function _resumeJournalInternal(j: Journal): void {\n const r = RESUMERS.get(j);\n if (!r) throw new Error('Journal is not resumable (already committed or cancelled)');\n r();\n}\n\n/** Options for `history.beginJournal()`. */\nexport interface BeginJournalOptions {\n /** Label for the single parent-history entry the journal flushes on commit. */\n label: string;\n /** Caller-supplied tag naming what this journal is scoped to — typically the\n * id of the node being edited. The history layer only carries it; callers\n * read it back off the journal to decide whether a suspended journal\n * matches what they are about to edit. */\n targetId?: string;\n /** Coalesce window for the journal's own entries, as\n * `CreateHistoryOptions.coalesceWindowMs`. Defaults to the parent's. */\n coalesceWindowMs?: number;\n}\n\n/**\n * A scoped sub-history forked from a `History`, opened by\n * `history.beginJournal()`. Applies, undoes and redoes against the same\n * adapter as its parent, but keeps its entries to itself: `commit` flushes the\n * journal's applied ops to the parent as one entry, `cancel` rewinds them\n * and contributes nothing. Use it when a self-contained editing session (a\n * text edit, a modal drag) should collapse to a single step in the parent's\n * undo stack while still offering undo *within* the session.\n *\n * A journal is active, suspended or closed. `commit` and `cancel` are\n * terminal; `suspend` lets the parent be used again and can be reversed with\n * `history.resumeJournal()`. Every mutating method throws when the journal is\n * not active.\n */\nexport interface Journal {\n readonly targetId: string | undefined;\n readonly forkedAtEntryId: number;\n\n // Same operational surface as History\n applyBatch(ops: Op[], label: string): void;\n undo(): void;\n redo(): void;\n canUndo(): boolean;\n canRedo(): boolean;\n entries(): { undo: readonly HistoryEntry[]; redo: readonly HistoryEntry[] };\n /** As `History.seal`, for the journal's own entries. */\n seal(): void;\n /** As `History.observe`, for the journal's own entries: each push, coalesce, undo and redo inside it. */\n observe(listener: (step: HistoryStep) => void): () => void;\n /** Open a journal inside this one, as `History.beginJournal` does on a\n * history: its commit lands here as one entry, and its cancel leaves this\n * journal as it was. */\n beginJournal(opts: BeginJournalOptions): Journal;\n /** Counter bumped on every change a reader of this journal could see: an\n * apply, undo, redo or coalesce inside it, and every lifecycle transition\n * (`isActive` changes). Pairs with `subscribe` for `useSyncExternalStore`. */\n getVersion(): number;\n /** Fires whenever `getVersion` bumps. Returns an unsubscribe fn. */\n subscribe(listener: () => void): () => void;\n\n // Lifecycle\n commit(label: string): void;\n cancel(): void;\n suspend(): void;\n isActive(): boolean;\n}\n\n/** Internal factory used by `createHistory`'s `beginJournal` method.\n * Not exported via the package's `index.ts` — callers go through\n * `history.beginJournal()`. */\nexport function createJournalInternal(\n parent: History,\n adapter: unknown,\n opts: BeginJournalOptions,\n onClose?: () => void,\n inherited: Pick<CreateHistoryOptions, 'coalesceWindowMs' | 'now' | 'debug' | 'selection'> = {},\n): Journal {\n const inner = createHistory(adapter, {\n ...inherited,\n ...(opts.coalesceWindowMs !== undefined ? { coalesceWindowMs: opts.coalesceWindowMs } : {}),\n });\n const selection = inherited.selection;\n let version = 0;\n const changed = createEmitter();\n function bump(): void {\n version++;\n changed.emit();\n }\n inner.subscribe(bump);\n const forkedAtEntryId = parent.currentEntryId();\n // The whole session collapses to one parent entry, so the selection that\n // entry restores is the one the session opened under — not whatever the\n // last keystroke left.\n const selectionBefore = selection ? [...selection.get()] : undefined;\n type State = 'active' | 'suspended' | 'closed';\n let state: State = 'active';\n const targetId = opts.targetId;\n\n const journal: Journal = {\n targetId,\n forkedAtEntryId,\n\n applyBatch(ops: Op[], label: string): void {\n if (state !== 'active') throw new Error('Journal is not active');\n inner.applyOps(ops, label);\n },\n undo(): void {\n if (state !== 'active') throw new Error('Journal is not active');\n inner.undo();\n },\n redo(): void {\n if (state !== 'active') throw new Error('Journal is not active');\n inner.redo();\n },\n canUndo(): boolean {\n return inner.canUndo();\n },\n canRedo(): boolean {\n return inner.canRedo();\n },\n entries() {\n return inner.entries();\n },\n seal(): void {\n inner.seal();\n },\n observe: (listener) => inner.observe(listener),\n beginJournal(nested: BeginJournalOptions): Journal {\n if (state !== 'active') throw new Error('Journal is not active');\n return inner.beginJournal(nested);\n },\n getVersion: () => version,\n subscribe: changed.subscribe,\n commit(label: string): void {\n if (state !== 'active') throw new Error('Journal is not active');\n // Coalescing splits an entry in two: the forward half is the latest\n // push, the base half the first, and undo inverts the base.\n const { forwardOps, baseOps } = _journalAccessInternal(inner).appliedOps();\n _journalAccessInternal(parent).record(\n forwardOps, baseOps, label, selectionBefore ? { selectionBefore } : undefined,\n );\n state = 'closed';\n RESUMERS.delete(journal);\n onClose?.();\n bump();\n },\n cancel(): void {\n if (state !== 'active') throw new Error('Journal is not active');\n inner.goto(0);\n state = 'closed';\n RESUMERS.delete(journal);\n onClose?.();\n bump();\n },\n suspend(): void {\n if (state !== 'active') throw new Error('Journal is not active');\n state = 'suspended';\n onClose?.();\n bump();\n },\n isActive(): boolean {\n return state === 'active';\n },\n };\n\n RESUMERS.set(journal, () => {\n if (state !== 'suspended') throw new Error('Journal is not suspended');\n state = 'active';\n bump();\n });\n\n return journal;\n}\n","import { createEmitter } from '@weasel-js/registry';\nimport type { Op } from './op';\nimport { anyCaused, appliedHalves, createApplier, entryView, foldEntry, sameCoalesceKeys, stepOf } from './entryOps';\nimport { createJournalInternal, _resumeJournalInternal, type Journal, type BeginJournalOptions } from './journal';\nimport {\n rebuilt, snapshot, touchedIdsFromOps,\n type Entry, type HistoryLogger, type SerializedHistory,\n} from './serialized';\nimport type {\n CreateHistoryOptions, History, HistoryBranch, HistoryStep, RecordEntryOptions,\n} from './historyTypes';\n\nexport { touchedIdsFromOps } from './serialized';\nexport type { HistoryLogger, SerializedHistory, SerializedHistoryEntry, SerializedOp } from './serialized';\nexport type {\n EvictedEntry, HistoryEntry, HistoryBranch, History, HistorySelection, HistoryStep, RecordEntryOptions,\n CreateHistoryOptions,\n} from './historyTypes';\n\n/** What a journal needs from a history beyond its public surface: both halves\n * of every applied entry, and a way to record both on its parent. */\ninterface JournalAccess {\n appliedOps(): { forwardOps: Op[]; baseOps: Op[] };\n record(forwardOps: Op[], baseOps: Op[], label: string, options?: RecordEntryOptions): void;\n}\n\nconst JOURNAL_ACCESS = new WeakMap<History, JournalAccess>();\n\n/** Called by `Journal.commit`. Not part of the public API. */\nexport function _journalAccessInternal(history: History): JournalAccess {\n const access = JOURNAL_ACCESS.get(history);\n if (!access) throw new Error('Not a history built by createHistory');\n return access;\n}\n\n/** Silent default — keeps every call site unconditional. */\nconst SILENT: HistoryLogger = { log: () => {}, warn: () => {} };\n\n/** Build an op-batched undo/redo `History`. The adapter is passed to each op's `apply`/`invert`. */\nexport function createHistory(adapter: unknown, options: CreateHistoryOptions = {}): History {\n const undoStack: Entry[] = [];\n const redoStack: Entry[] = [];\n let activeJournal: Journal | null = null;\n const coalesceWindowMs = options.coalesceWindowMs ?? 0;\n const now = options.now ?? (() => Date.now());\n const historyLimit = Math.max(0, options.historyLimit ?? Infinity);\n const onEvict = options.onEvict;\n const branching = options.branching ?? false;\n /** Futures a push set aside, by the id of the entry they fork from (the\n * floor's for the oldest reachable state), each in time order. Only a\n * branching history adds to it. */\n const forks = new Map<number, Entry[][]>();\n /** Names the state beneath the undo stack: 0 at the start, then the id of\n * the last undo entry evicted. */\n let floorId = 0;\n const customRebuild = options.rebuildOp;\n const selection = options.selection;\n const logger = options.debug ?? SILENT;\n let nextEntryId = 1;\n let version = 0;\n /** `version` as of the last push or coalesce. A batch may only merge into\n * the top entry while this still matches: every other operation bumps\n * `version`, so undo, redo, goto, clear, restore and `recordEntry` all\n * expire the merge window without having to remember to. Without that, an\n * edit made after stepping back rewrites whatever entry the step left on\n * top, and one undo then jumps past it. */\n let coalesceAnchorVersion = -1;\n const changed = createEmitter();\n const stepped = createEmitter<[HistoryStep]>();\n function bump(step?: HistoryStep): void {\n version++;\n if (step && stepped.size > 0) stepped.emit(step);\n changed.emit();\n }\n\n /** Report entries that just became permanently unreachable. A throwing\n * callback must not desync the stacks mid-mutation, so failures are\n * contained and surfaced via the debug flag. */\n function reportEvicted(entries: Entry[]): void {\n if (!onEvict) return;\n for (const e of entries) {\n try {\n onEvict({ id: e.id, label: e.label, forwardOps: e.forwardOps, baseOps: e.baseOps });\n } catch (err) {\n logger.warn(`onEvict callback threw for entry id=${e.id} \"${e.label}\": ${String(err)}`);\n }\n }\n }\n\n /** Report `entries` evicted, and evict every branch forking from them. */\n function evict(entries: Entry[]): void {\n reportEvicted(entries);\n for (const e of entries) {\n const kept = forks.get(e.id);\n if (!kept) continue;\n forks.delete(e.id);\n for (const branch of kept) evict(branch);\n }\n }\n\n /** Evict `entries` off the bottom of the undo stack, oldest first. Each one\n * raises the floor to the state it leaves: the futures forking from the old\n * floor go with it, and the ones forking from the entry now fork from the\n * floor. */\n function evictFloor(entries: Entry[]): void {\n for (const e of entries) {\n if (onEvict) reportEvicted([e]);\n const stranded = forks.size > 0 ? forks.get(floorId) : undefined;\n if (stranded !== undefined) forks.delete(floorId);\n floorId = e.id;\n if (stranded !== undefined) for (const branch of stranded) evict(branch);\n }\n }\n\n /** The id of the entry the history stands on, the floor's beneath them all. */\n function forkPoint(): number {\n return undoStack[undoStack.length - 1]?.id ?? floorId;\n }\n\n /** Clear the redo stack after a push forking from `at`: kept as a branch\n * when branching, else dropped and reported. */\n function retireRedo(at: number): void {\n if (redoStack.length === 0) return;\n const future = redoStack.splice(0);\n if (!branching) return evict(future);\n const kept = forks.get(at);\n if (kept) kept.push(future.reverse());\n else forks.set(at, [future.reverse()]);\n }\n\n /** Evict the oldest undo entries past `historyLimit`, reporting each. */\n function enforceLimit(): void {\n while (undoStack.length > historyLimit) {\n evictFloor([undoStack.shift()!]);\n }\n }\n\n const applyAllOrNothing = createApplier(adapter, logger);\n\n function invertEntry(entry: Entry): Op[] {\n return [...entry.baseOps].reverse().map((op) => op.invert());\n }\n\n /** Copy on read: the caller's array is theirs to mutate. */\n function readSelection(): readonly string[] | undefined {\n return selection ? [...selection.get()] : undefined;\n }\n\n /** Walk one entry backwards. The selection is restored *after* the\n * inverted ops apply, so an entry that also carries a `setSelection`-style\n * op can't overwrite the snapshot. */\n function stepBack(entry: Entry): void {\n const leaving = readSelection();\n const coalesced = entry.forwardOps !== entry.baseOps;\n applyAllOrNothing(invertEntry(entry), coalesced ? () => entry.forwardOps : undefined);\n if (leaving) entry.selectionAfter = leaving;\n if (selection && entry.selectionBefore) selection.set(entry.selectionBefore);\n }\n\n /** Walk one entry forwards. Mirror of `stepBack`. */\n function stepForward(entry: Entry): void {\n const leaving = readSelection();\n const coalesced = entry.forwardOps !== entry.baseOps;\n applyAllOrNothing(entry.forwardOps, coalesced ? () => invertEntry(entry) : undefined);\n if (leaving) entry.selectionBefore = leaving;\n if (selection && entry.selectionAfter) selection.set(entry.selectionAfter);\n }\n\n /** Step until `n` entries are on the undo stack. An entry changes stacks\n * only once its step has run, so a throw leaves both stacks describing\n * the state as it is. */\n function walkTo(n: number): Entry[] {\n const walked: Entry[] = [];\n while (undoStack.length > n) {\n const entry = undoStack[undoStack.length - 1]!;\n stepBack(entry);\n undoStack.pop();\n redoStack.push(entry);\n walked.push(entry);\n }\n while (undoStack.length < n && redoStack.length > 0) {\n const entry = redoStack[redoStack.length - 1]!;\n stepForward(entry);\n redoStack.pop();\n undoStack.push(entry);\n walked.push(entry);\n }\n return walked;\n }\n\n /** Coalesce eligibility: inside the window, and the same keys. Matched by\n * multiset rather than position so a multi-id selection can re-emit ops in\n * any order between batches without breaking the merge. */\n function canCoalesce(top: Entry, incoming: Op[]): boolean {\n const windowMs = typeof coalesceWindowMs === 'function' ? coalesceWindowMs() : coalesceWindowMs;\n if (!(windowMs > 0) || top.coalesceKey !== undefined || version !== coalesceAnchorVersion || now() - top.timestamp > windowMs) return false;\n return sameCoalesceKeys(top.forwardOps, incoming);\n }\n\n function pushOrCoalesce(applied: Op[], label: string, owned = false): void {\n if (applied.length === 0) return;\n const selectionBefore = readSelection();\n const idle: Op[] = [];\n const anyMutated = applyAllOrNothing(applied, undefined, idle);\n const kept = idle.length === 0 ? applied : applied.filter((op) => !(op.elideNoop && idle.includes(op)));\n const ops = anyCaused(kept) ? kept.flatMap((op) => op.caused?.() ?? [op]) : owned || kept !== applied ? kept : kept.slice();\n if (!anyMutated) {\n // Every op reported `false`/`'noop'`. Skip the push so undo stays\n // tied to real state changes. Surfaced through the kit's debug\n // flag so the upstream caller can consider avoiding the dispatch\n // entirely. Hidden by default; enable via\n // `localStorage.setItem('weasel.debug', '1')`.\n logger.warn(\n `'${label}' batch was a no-op — every op reported false/'noop'. ` +\n `Skipping the undo entry; consider gating the dispatch upstream to avoid the wasted work.`,\n );\n return;\n }\n if (ops.length === 0) return;\n const incoming = touchedIdsFromOps(ops);\n const top = undoStack[undoStack.length - 1];\n if (top && canCoalesce(top, ops)) {\n top.forwardOps = ops;\n top.timestamp = now();\n top.pushes++;\n // Merge incoming touched ids into the coalesced entry's set.\n if (incoming.size > 0) {\n const merged = new Set(top.touchedIds);\n for (const id of incoming) merged.add(id);\n top.touchedIds = merged;\n }\n // baseOps + label + id intentionally preserved — undo returns to the\n // pre-edit state, the original label sticks, and the entry id stays\n // stable so React lists keyed on id don't flicker. No dropRedo() here:\n // the anchor only survives until the stack is stepped, and every step\n // clears it, so a live anchor implies an empty redo stack.\n logger.log(`coalesce '${label}' into entry id=${top.id} (${ops.length} ops)`);\n bump(stepped.size > 0 ? { kind: 'coalesce', entries: [{ id: top.id, label: top.label, ops }] } : undefined);\n coalesceAnchorVersion = version;\n return;\n }\n logger.log(`push '${label}' (${ops.length} ops)`);\n const at = forkPoint();\n const entry: Entry = {\n id: nextEntryId++, forwardOps: ops, baseOps: ops, label, timestamp: now(), pushes: 1, touchedIds: incoming,\n ...(selectionBefore ? { selectionBefore } : {}),\n };\n undoStack.push(entry);\n retireRedo(at);\n enforceLimit();\n bump(stepped.size > 0 ? stepOf('push', [entry]) : undefined);\n coalesceAnchorVersion = version;\n }\n\n function fold(top: Entry, ops: Op[]): void {\n foldEntry(top, ops, now());\n bump(stepped.size > 0 ? { kind: 'coalesce', entries: [{ id: top.id, label: top.label, ops }] } : undefined);\n coalesceAnchorVersion = version;\n }\n\n function record(forwardOps: Op[], baseOps: Op[], label: string, options: RecordEntryOptions = {}): void {\n if (forwardOps.length === 0) return;\n const key = options.coalesceKey;\n const top = undoStack[undoStack.length - 1];\n if (key !== undefined && top?.coalesceKey === key && version === coalesceAnchorVersion && forwardOps === baseOps) {\n return fold(top, forwardOps);\n }\n const at = forkPoint();\n const entry: Entry = {\n id: nextEntryId++, forwardOps, baseOps, label, timestamp: now(), pushes: 1,\n touchedIds: touchedIdsFromOps(forwardOps),\n ...(options.selectionBefore ? { selectionBefore: [...options.selectionBefore] } : {}),\n ...(key !== undefined ? { coalesceKey: key } : {}),\n };\n undoStack.push(entry);\n retireRedo(at);\n enforceLimit();\n bump(stepped.size > 0 ? stepOf('push', [entry]) : undefined);\n if (key !== undefined) coalesceAnchorVersion = version;\n }\n\n const history: History = {\n apply(op, label) {\n pushOrCoalesce([op], label ?? op.label ?? '', true);\n },\n applyOps(ops, label) {\n pushOrCoalesce(ops, label);\n },\n undo() {\n if (undoStack.length === 0) return;\n bump(stepOf('undo', walkTo(undoStack.length - 1)));\n },\n redo() {\n if (redoStack.length === 0) return;\n bump(stepOf('redo', walkTo(undoStack.length + 1)));\n },\n seal() {\n coalesceAnchorVersion = -1;\n },\n canUndo: () => undoStack.length > 0,\n canRedo: () => redoStack.length > 0,\n undoDepth: () => undoStack.length,\n redoDepth: () => redoStack.length,\n clear: () => {\n const had = undoStack.length > 0 || redoStack.length > 0 || forks.size > 0;\n undoStack.length = 0;\n redoStack.length = 0;\n forks.clear();\n floorId = 0;\n if (had) bump(stepOf('clear'));\n },\n entries() {\n // redoStack is internally stored newest-on-top (so `pop()` redoes the\n // next-most-recent undo). Reverse on the way out so callers see the\n // entries in chronological order — the user's next redo is the first\n // element, matching `entries().redo[0]` semantics.\n return {\n undo: undoStack.map(entryView),\n redo: [...redoStack].reverse().map(entryView),\n };\n },\n goto(n) {\n // Total length stays constant during this walk (we only shuffle\n // entries between undo and redo stacks).\n const total = undoStack.length + redoStack.length;\n if (n < 0 || n > total || n === undoStack.length) return;\n const start = undoStack.length;\n let walked: Entry[];\n try {\n walked = walkTo(n);\n } catch (err) {\n // Stop where the walk began rather than partway. A second throw on\n // the way back is logged: the stacks still match the state, at\n // whatever depth that walk reached.\n try {\n walkTo(start);\n } catch (back) {\n logger.warn(`goto: returning to depth ${start} threw: ${String(back)}`);\n }\n if (undoStack.length !== start) bump();\n throw err;\n }\n bump(stepOf('goto', walked));\n },\n timestampAt(i) {\n if (i < 0) return undefined;\n if (i < undoStack.length) return undoStack[i]!.timestamp;\n // redoStack is newest-on-top, so time order runs from its end.\n return redoStack[redoStack.length - 1 - (i - undoStack.length)]?.timestamp;\n },\n depthAt(t) {\n let n = undoStack.length;\n while (n > 0 && undoStack[n - 1]!.timestamp > t) n--;\n if (n < undoStack.length) return n;\n for (let r = redoStack.length - 1; r >= 0 && redoStack[r]!.timestamp <= t; r--) n++;\n return n;\n },\n prune(t) {\n let k = 0;\n while (k < undoStack.length && undoStack[k]!.timestamp < t) k++;\n if (k === 0) return;\n const evicted = undoStack.splice(0, k);\n evictFloor(evicted);\n bump(stepOf('prune', evicted));\n },\n branches() {\n const view = (entries: readonly Entry[], current: boolean): HistoryBranch => {\n const first = entries[0]!;\n return { id: first.id, label: first.label, timestamp: first.timestamp, length: entries.length, current };\n };\n const out = (forks.get(forkPoint()) ?? []).map((b) => view(b, false));\n if (redoStack.length > 0) out.push(view([...redoStack].reverse(), true));\n return out.sort((a, b) => a.id - b.id);\n },\n switchBranch(id) {\n if (redoStack[redoStack.length - 1]?.id === id) return;\n const at = forkPoint();\n const kept = forks.get(at) ?? [];\n const i = kept.findIndex((b) => b[0]!.id === id);\n if (i < 0) throw new Error(`No branch ${id} forks from entry ${at}`);\n const [chosen] = kept.splice(i, 1);\n if (redoStack.length > 0) kept.push(redoStack.splice(0).reverse());\n if (kept.length > 0) forks.set(at, kept);\n else forks.delete(at);\n redoStack.push(...[...chosen!].reverse());\n bump(stepOf('branch', chosen));\n },\n getVersion: () => version,\n subscribe: changed.subscribe,\n observe: stepped.subscribe,\n serialize: () => snapshot({ undoStack, redoStack, forks, floorId, nextEntryId }, logger),\n recordEntry(ops: Op[], label: string, options?: RecordEntryOptions): void {\n record(ops, ops, label, options);\n },\n allForwardOps(): Op[] {\n const out: Op[] = [];\n for (const e of undoStack) {\n for (const op of e.forwardOps) out.push(op);\n }\n return out;\n },\n currentEntryId: () => nextEntryId,\n beginJournal(opts: BeginJournalOptions): Journal {\n if (activeJournal !== null && activeJournal.isActive()) {\n throw new Error('A journal is already active — commit, cancel, or suspend it first');\n }\n // `adapter` is the closure-captured adapter passed to createHistory.\n // The returned History object's `this` doesn't carry it, so we pass\n // it through to the factory directly.\n const j = createJournalInternal(history, adapter, opts, () => { activeJournal = null; }, {\n coalesceWindowMs, now, debug: logger,\n ...(selection ? { selection } : {}),\n });\n activeJournal = j;\n return j;\n },\n activeJournal: () => (activeJournal?.isActive() ? activeJournal : null),\n resumeJournal(journal: Journal): void {\n if (activeJournal !== null && activeJournal !== journal && activeJournal.isActive()) {\n throw new Error('A journal is already active — commit, cancel, or suspend it first');\n }\n _resumeJournalInternal(journal);\n activeJournal = journal;\n },\n restore(serialized: SerializedHistory): void {\n const next = rebuilt(serialized, customRebuild, logger);\n undoStack.splice(0, undoStack.length, ...next.undoStack);\n redoStack.splice(0, redoStack.length, ...next.redoStack);\n forks.clear();\n for (const [at, kept] of next.forks) forks.set(at, kept);\n floorId = next.floorId;\n nextEntryId = next.nextEntryId;\n bump(stepOf('restore'));\n },\n };\n JOURNAL_ACCESS.set(history, {\n appliedOps: () => appliedHalves(undoStack),\n record,\n });\n return history;\n}\n","import type { Op } from './op';\n\n/** What a {@link swapOp} carries as its `args`: the value it leaves and the one it makes. */\nexport interface SwapArgs<V> {\n before: V;\n after: V;\n}\n\n/** What {@link swapOp} is built from. */\nexport interface SwapOpOptions<V> extends SwapArgs<V> {\n /** The op's `name`, which a history's `rebuildOp` matches to rebuild it from a snapshot. */\n name: string;\n label: string;\n /** Puts a value in force. Called with `after` to apply and `before` to undo. */\n emit(value: V): void;\n coalesceKey?: string;\n}\n\n/**\n * An edit as the swap of one whole value for another. For a value held immutably the two snapshots are\n * references, and the op carries both as `args`, so a serialized history can rebuild the step.\n */\nexport function swapOp<V>({ name, label, before, after, emit, coalesceKey }: SwapOpOptions<V>): Op {\n const forward: Op = {\n label,\n name,\n args: { before, after } satisfies SwapArgs<V>,\n ...(coalesceKey !== undefined ? { coalesceKey } : {}),\n apply: () => emit(after),\n invert: () => ({ label, apply: () => emit(before), invert: () => forward }),\n };\n return forward;\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/serialized.ts","../src/entryOps.ts","../src/journal.ts","../src/history.ts","../src/swapOp.ts"],"names":["snapshot","createEmitter","options"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * A history's entries, their wire form, and the trip between the two.\n */\nimport type { Op } from './op';\n\nexport interface Entry {\n /** Monotonic id assigned at first push. Stable across coalesce merges\n * (a merged entry keeps the original id) so UI lists keyed on `id` don't\n * flicker when the underlying entry mutates. */\n id: number;\n /** Forward ops — applied on redo, reflect the latest to-state after any\n * coalescing. Diverges from `baseOps` only after a coalesce. */\n forwardOps: Op[];\n /** Original ops at first push — their `.invert()` is what undo replays.\n * Preserved across coalesces so undo always returns to the original\n * pre-edit state, no matter how many coalesces happened. */\n baseOps: Op[];\n label: string;\n /** `now()` at last push or coalesce: gates the coalesce window, and is the\n * entry's place in time for `depthAt` and `prune`. */\n timestamp: number;\n /** See `HistoryEntry.pushes`. */\n pushes: number;\n /** Node ids touched by ops in this entry. See `HistoryEntry.touchedIds`. */\n touchedIds: ReadonlySet<string>;\n /** Selection as of just before this entry's ops ran; restored by undo.\n * Undefined when nothing supplied one (no `selection` option, or a\n * `recordEntry` call that captured none). */\n selectionBefore?: readonly string[];\n /** Selection as of just before this entry was last undone; restored by\n * redo. Written on the way past, so it reflects where the user actually\n * was rather than where the entry's ops left them. */\n selectionAfter?: readonly string[];\n /** The key a `recordEntry` gave it, which a later one with the same key folds into. */\n coalesceKey?: string;\n}\n\n/** Wire form of a single op inside a serialized history. The pair\n * `(name, args)` reconstructs a live `Op` via the op-factory registry. */\nexport interface SerializedOp {\n name: string;\n args: unknown;\n}\n\n/** Wire form of one history entry. `forwardOps` / `baseOps` mirror the\n * in-memory entry's fields (see `Entry` above) but only carry the\n * serializable `(name, args)` projection of each op. */\nexport interface SerializedHistoryEntry {\n id: number;\n label: string;\n forwardOps: SerializedOp[];\n baseOps: SerializedOp[];\n /** See `HistoryEntry.pushes`. Absent in snapshots that predate it; read as 1. */\n pushes?: number;\n /** See `HistoryEntry.timestamp`. Absent in snapshots that predate it; read as 0. */\n timestamp?: number;\n selectionBefore?: readonly string[];\n selectionAfter?: readonly string[];\n}\n\n/** Snapshot of an entire `History` instance. Designed to live alongside the\n * scene snapshot so a reload restores the undo / redo stacks to exactly\n * where they were. Op `args` are carried by reference, so the snapshot is\n * as serializable as they are: JSON drops a function an op's args hold,\n * where a structured clone (IndexedDB, `postMessage`) throws on it. */\nexport interface SerializedHistory {\n version: 1;\n undoStack: SerializedHistoryEntry[];\n /** Stored newest-first, mirroring the in-memory stack so a deserialized\n * history matches the original's `entries().redo` ordering. */\n redoStack: SerializedHistoryEntry[];\n nextEntryId: number;\n /** Futures kept by a branching history, each under the id of the entry it\n * forks from (`floor`'s for the oldest reachable state), entries in time\n * order. Absent when none. */\n branches?: { at: number; entries: SerializedHistoryEntry[] }[];\n /** The id naming the state beneath the undo stack: that of the last undo\n * entry evicted or left out of the snapshot. Absent, and read as 0, when\n * the stack reaches back to the start. */\n floor?: number;\n /** Entries left out: those with an op lacking a `name`, which can't\n * round-trip through the op-factory registry, and those only reachable\n * across one. Always present (zero when nothing was dropped) so callers\n * can detect loss without parsing the debug log. */\n droppedEntries: number;\n}\n\n/** Diagnostics sink for {@link CreateHistoryOptions.debug}. Messages arrive\n * pre-formatted and unconditional; deciding whether to emit them is the\n * caller's job. */\nexport interface HistoryLogger {\n log(message: string): void;\n warn(message: string): void;\n}\n\n/** The stacks a history holds, as `snapshot` reads them and `rebuilt` answers. */\nexport interface Stacks {\n undoStack: Entry[];\n redoStack: Entry[];\n /** Futures set aside, by the id of the entry they fork from. */\n forks: Map<number, Entry[][]>;\n floorId: number;\n nextEntryId: number;\n}\n\n/** `stacks` as a snapshot: see `History.serialize` for what is left out. */\nexport function snapshot(stacks: Stacks, logger: HistoryLogger): SerializedHistory {\n const { undoStack, redoStack, forks, floorId, nextEntryId } = stacks;\n let total = 0;\n const project = (entries: readonly Entry[]): (SerializedHistoryEntry | null)[] => {\n total += entries.length;\n return entries.map((e) => entryToSerial(e, logger));\n };\n // Both stacks keep the entries nearest the current state at their end,\n // so what survives a nameless entry is whatever follows the last one.\n const nearest = (stack: readonly Entry[]): SerializedHistoryEntry[] => {\n const serial = project(stack);\n return serial.slice(serial.lastIndexOf(null) + 1) as SerializedHistoryEntry[];\n };\n const undo = nearest(undoStack);\n const redo = nearest(redoStack);\n\n // Cutting the undo stack raises the snapshot's floor to the last entry cut.\n const floor = undo.length === undoStack.length ? floorId : undoStack[undoStack.length - undo.length - 1]!.id;\n const reachable = new Set<number>([floor, ...[...undo, ...redo].map((e) => e.id)]);\n let pending = [...forks].flatMap(([at, kept]) => kept.map((b) => {\n const serial = project(b);\n const cut = serial.indexOf(null);\n return { at, entries: (cut < 0 ? serial : serial.slice(0, cut)) as SerializedHistoryEntry[] };\n })).filter((b) => b.entries.length > 0);\n const branches: { at: number; entries: SerializedHistoryEntry[] }[] = [];\n for (let grew = true; grew; ) {\n grew = false;\n const waiting: typeof pending = [];\n for (const b of pending) {\n if (!reachable.has(b.at)) { waiting.push(b); continue; }\n branches.push(b);\n for (const e of b.entries) reachable.add(e.id);\n grew = true;\n }\n pending = waiting;\n }\n\n const carried = undo.length + redo.length + branches.reduce((n, b) => n + b.entries.length, 0);\n return {\n version: 1,\n undoStack: undo,\n redoStack: redo,\n ...(branches.length > 0 ? { branches } : {}),\n ...(floor !== 0 ? { floor } : {}),\n nextEntryId,\n droppedEntries: total - carried,\n };\n}\n\n/** The stacks `snapshot` describes, each op rebuilt through `custom`. */\nexport function rebuilt(snapshot: SerializedHistory, custom: CustomRebuild | undefined, logger: HistoryLogger): Stacks {\n const entry = (se: SerializedHistoryEntry): Entry => serialToEntry(se, custom, logger);\n const undoStack = snapshot.undoStack.map(entry);\n const redoStack = snapshot.redoStack.map(entry);\n const forks = new Map<number, Entry[][]>();\n for (const b of snapshot.branches ?? []) {\n const entries = b.entries.map(entry);\n const kept = forks.get(b.at);\n if (kept) kept.push(entries);\n else forks.set(b.at, [entries]);\n }\n // Seed nextEntryId from the snapshot, then defensively bump past any\n // restored id — a malformed snapshot with duplicate or out-of-range\n // ids should never produce a collision with future entries.\n let nextEntryId = snapshot.nextEntryId;\n const seen = [undoStack, redoStack, ...[...forks.values()].flat()];\n for (const entries of seen) for (const e of entries) if (e.id >= nextEntryId) nextEntryId = e.id + 1;\n return { undoStack, redoStack, forks, floorId: snapshot.floor ?? 0, nextEntryId };\n}\n\n/** Extract node ids from an op's `args`. Handles the common patterns:\n * - `args.id` (string) — transform, setPath, reparent\n * - `args.node.id` (string) — insert, delete\n * - `args.nodes[].id` (string) — an op that takes several nodes at once\n * Ops that match none of them contribute nothing. */\nexport function touchedIdsFromOps(ops: readonly Op[]): ReadonlySet<string> {\n const ids = new Set<string>();\n for (const op of ops) {\n if (op.args === null || typeof op.args !== 'object') continue;\n const a = op.args as Record<string, unknown>;\n if (typeof a['id'] === 'string') {\n ids.add(a['id']);\n } else if (a['node'] !== null && typeof a['node'] === 'object') {\n const n = a['node'] as Record<string, unknown>;\n if (typeof n['id'] === 'string') ids.add(n['id']);\n } else if (Array.isArray(a['nodes'])) {\n for (const n of a['nodes'] as unknown[]) {\n const id = n !== null && typeof n === 'object' ? (n as Record<string, unknown>)['id'] : undefined;\n if (typeof id === 'string') ids.add(id);\n }\n }\n }\n return ids;\n}\n\n/** Project an `Op` to its `(name, args)` wire form. Returns `null` for ops\n * missing `name` — the caller drops the containing entry. */\nfunction opToSerial(op: Op): SerializedOp | null {\n if (typeof op.name !== 'string') return null;\n return { name: op.name, args: op.args };\n}\n\n/** Project a runtime entry to its serialized form, or `null` if any op in\n * the entry can't be serialized (we drop the whole entry then — a partially\n * serializable entry would invert against the wrong baseline on undo). */\nfunction entryToSerial(e: Entry, logger: HistoryLogger): SerializedHistoryEntry | null {\n const forwardOps: SerializedOp[] = [];\n for (const op of e.forwardOps) {\n const s = opToSerial(op);\n if (s === null) {\n logger.log(`serialize: dropping entry id=${e.id} \"${e.label}\" — forwardOp without name`);\n return null;\n }\n forwardOps.push(s);\n }\n const baseOps: SerializedOp[] = [];\n for (const op of e.baseOps) {\n const s = opToSerial(op);\n if (s === null) {\n logger.log(`serialize: dropping entry id=${e.id} \"${e.label}\" — baseOp without name`);\n return null;\n }\n baseOps.push(s);\n }\n return {\n id: e.id, label: e.label, forwardOps, baseOps, pushes: e.pushes, timestamp: e.timestamp,\n ...(e.selectionBefore ? { selectionBefore: e.selectionBefore } : {}),\n ...(e.selectionAfter ? { selectionAfter: e.selectionAfter } : {}),\n };\n}\n\n/** Placeholder op used when the registry lacks the requested name. Stable\n * identity (each placeholder is its own invert) keeps undo/redo plumbing\n * happy without performing any adapter mutation. */\nfunction placeholderOp(name: string, args: unknown, label?: string): Op {\n const op: Op = {\n name,\n args,\n label,\n apply: () => 'noop' as const,\n invert: () => op,\n };\n return op;\n}\n\n/** Signature of a per-instance op rebuilder (`CreateHistoryOptions.rebuildOp`). */\ntype CustomRebuild = (name: string, args: unknown) => Op | null;\n\n/** Rebuild a single serialized op via `custom` (if provided), falling back to\n * a no-op placeholder.\n *\n * This engine deliberately knows nothing about any op registry: hydrating a\n * `(name, args)` pair back into an op is the caller's concern, injected\n * through `CreateHistoryOptions.rebuildOp`. `@weasel-js/core`'s\n * `createHistory` wrapper supplies its global op-factory registry as that\n * hook, so core consumers see unchanged behavior. */\nfunction rebuildSerialOp(so: SerializedOp, label: string, custom: CustomRebuild | undefined, logger: HistoryLogger): Op {\n const viaCustom = custom ? custom(so.name, so.args) : null;\n if (viaCustom !== null) return viaCustom;\n logger.log(`restore: unknown op name \"${so.name}\" — substituting no-op placeholder`);\n return placeholderOp(so.name, so.args, label);\n}\n\nfunction sameSerialOps(a: readonly SerializedOp[], b: readonly SerializedOp[]): boolean {\n if (a === b) return true;\n if (a.length !== b.length) return false;\n try {\n return JSON.stringify(a) === JSON.stringify(b);\n } catch {\n return false;\n }\n}\n\n/** Rebuild a runtime entry from its serialized form. Unknown op names become\n * no-op placeholders so the entry still occupies its slot in the stack. */\nfunction serialToEntry(se: SerializedHistoryEntry, custom: CustomRebuild | undefined, logger: HistoryLogger): Entry {\n const forwardOps = se.forwardOps.map((so) => rebuildSerialOp(so, se.label, custom, logger));\n // An entry nothing coalesced into holds one array as both halves, and a\n // step that throws unwinds differently when they differ.\n const baseOps = sameSerialOps(se.forwardOps, se.baseOps)\n ? forwardOps\n : se.baseOps.map((so) => rebuildSerialOp(so, se.label, custom, logger));\n return {\n id: se.id,\n label: se.label,\n forwardOps,\n baseOps,\n timestamp: se.timestamp ?? 0,\n pushes: se.pushes ?? 1,\n // Re-derive touchedIds from the rebuilt ops rather than trying to\n // round-trip the Set through the serialized form (Sets aren't JSON-safe).\n touchedIds: touchedIdsFromOps(forwardOps),\n ...(se.selectionBefore ? { selectionBefore: [...se.selectionBefore] } : {}),\n ...(se.selectionAfter ? { selectionAfter: [...se.selectionAfter] } : {}),\n };\n}\n","/**\n * The parts of a history that read or apply an entry's ops without touching\n * its stacks.\n */\nimport type { Op } from './op';\nimport { touchedIdsFromOps, type Entry, type HistoryLogger } from './serialized';\nimport type { HistoryEntry, HistoryStep } from './historyTypes';\n\nexport /** Whether both lists are non-empty, every op is keyed, and the keys match as multisets. */\nfunction sameCoalesceKeys(top: readonly Op[], incoming: readonly Op[]): boolean {\n if (top.length === 0 || incoming.length === 0 || top.length !== incoming.length) return false;\n const counts = new Map<string, number>();\n for (const op of top) {\n const k = op.coalesceKey;\n if (k === undefined) return false;\n counts.set(k, (counts.get(k) ?? 0) + 1);\n }\n for (const op of incoming) {\n const k = op.coalesceKey;\n const c = k === undefined ? 0 : counts.get(k) ?? 0;\n if (!c) return false;\n counts.set(k!, c - 1);\n }\n return true;\n}\n\nexport function entryView(e: Entry): HistoryEntry {\n return {\n id: e.id, label: e.label, timestamp: e.timestamp, pushes: e.pushes, touchedIds: e.touchedIds,\n ...(e.selectionBefore ? { selectionBefore: e.selectionBefore } : {}),\n ...(e.selectionAfter ? { selectionAfter: e.selectionAfter } : {}),\n };\n}\n\nexport function stepOf(kind: HistoryStep['kind'], entries: readonly Entry[] = []): HistoryStep {\n return { kind, entries: entries.map((e) => ({ id: e.id, label: e.label, ops: e.forwardOps })) };\n}\n\n/** Build the all-or-nothing apply a history runs every step through, against `adapter`. */\nexport function createApplier(adapter: unknown, logger: HistoryLogger) {\n /** Apply `ops` best-effort while unwinding a failed step: the throw being\n * unwound is the one the caller sees, so a second one is only logged. */\n function applyUnwinding(ops: Op[]): void {\n for (const op of ops) {\n try {\n op.apply(adapter);\n } catch (err) {\n logger.warn(`unwinding a failed step: op \"${op.name ?? '?'}\" threw: ${String(err)}`);\n }\n }\n }\n\n /** Apply every op or none: when one throws, the ops that ran before it are\n * inverted, newest first, then `settle` is applied, and the throw\n * propagates. Returns true iff at least one op did NOT explicitly return\n * `false` / `'noop'` — `pushOrCoalesce` skips the entry when every op in\n * the batch was a silent no-op (e.g. reorder where the order already\n * matched). Ops returning `undefined`/`void` count as \"mutated\".\n *\n * `settle` is for a coalesced entry, whose two halves are not each\n * other's inverse: inverting what ran lands on the other half's far side,\n * and re-applying that half is what returns to where the step began. */\n function applyAllOrNothing(ops: Op[], settle?: () => Op[], idle?: Op[]): boolean {\n let anyMutated = false;\n let done = 0;\n try {\n for (; done < ops.length; done++) {\n const r = ops[done]!.apply(adapter);\n if (r !== false && r !== 'noop') anyMutated = true;\n else idle?.push(ops[done]!);\n }\n } catch (err) {\n if (done > 0) {\n applyUnwinding(ops.slice(0, done).reverse().map((op) => op.invert()));\n if (settle) applyUnwinding(settle());\n }\n throw err;\n }\n return anyMutated;\n }\n return applyAllOrNothing;\n}\n\n/** Fold `ops`, recorded under the key `top` carries, into `top`: they run after its own, so its\n * undo inverts them first and then the state they started from. */\nexport function foldEntry(top: Entry, ops: Op[], at: number): void {\n const same = top.forwardOps === top.baseOps;\n top.forwardOps = [...top.forwardOps, ...ops];\n top.baseOps = same ? top.forwardOps : [...top.baseOps, ...ops];\n top.timestamp = at;\n top.pushes++;\n const merged = new Set(top.touchedIds);\n for (const id of touchedIdsFromOps(ops)) merged.add(id);\n top.touchedIds = merged;\n}\n\n/** Whether any op in `ops` records the ops it caused in its place: a loop\n * rather than `some`, since every push asks. */\nexport function anyCaused(ops: readonly Op[]): boolean {\n for (let i = 0; i < ops.length; i++) if (ops[i]!.caused !== undefined) return true;\n return false;\n}\n\n/** Both halves of `entries` run end to end, as one entry would hold them: one\n * list when nothing coalesced, since a step that throws unwinds a two-list\n * entry by replaying its other half. */\nexport function appliedHalves(entries: readonly Entry[]): { forwardOps: Op[]; baseOps: Op[] } {\n const forwardOps = entries.flatMap((e) => e.forwardOps);\n if (entries.every((e) => e.forwardOps === e.baseOps)) return { forwardOps, baseOps: forwardOps };\n return { forwardOps, baseOps: entries.flatMap((e) => e.baseOps) };\n}\n","import { createEmitter } from '@weasel-js/registry';\nimport type { Op } from './op';\nimport { _journalAccessInternal, createHistory, type CreateHistoryOptions, type History, type HistoryEntry, type HistoryStep } from './history';\n\nconst RESUMERS = new WeakMap<Journal, () => void>();\n\n/** Called by `history.resumeJournal`. Not part of the public API. */\nexport function _resumeJournalInternal(j: Journal): void {\n const r = RESUMERS.get(j);\n if (!r) throw new Error('Journal is not resumable (already committed or cancelled)');\n r();\n}\n\n/** Options for `history.beginJournal()`. */\nexport interface BeginJournalOptions {\n /** Label for the single parent-history entry the journal flushes on commit. */\n label: string;\n /** Caller-supplied tag naming what this journal is scoped to — typically the\n * id of the node being edited. The history layer only carries it; callers\n * read it back off the journal to decide whether a suspended journal\n * matches what they are about to edit. */\n targetId?: string;\n /** Coalesce window for the journal's own entries, as\n * `CreateHistoryOptions.coalesceWindowMs`. Defaults to the parent's. */\n coalesceWindowMs?: number;\n}\n\n/**\n * A scoped sub-history forked from a `History`, opened by\n * `history.beginJournal()`. Applies, undoes and redoes against the same\n * adapter as its parent, but keeps its entries to itself: `commit` flushes the\n * journal's applied ops to the parent as one entry, `cancel` rewinds them\n * and contributes nothing. Use it when a self-contained editing session (a\n * text edit, a modal drag) should collapse to a single step in the parent's\n * undo stack while still offering undo *within* the session.\n *\n * A journal is active, suspended or closed. `commit` and `cancel` are\n * terminal; `suspend` lets the parent be used again and can be reversed with\n * `history.resumeJournal()`. Every mutating method throws when the journal is\n * not active.\n */\nexport interface Journal {\n readonly targetId: string | undefined;\n readonly forkedAtEntryId: number;\n\n // Same operational surface as History\n applyBatch(ops: Op[], label: string): void;\n undo(): void;\n redo(): void;\n canUndo(): boolean;\n canRedo(): boolean;\n entries(): { undo: readonly HistoryEntry[]; redo: readonly HistoryEntry[] };\n /** As `History.seal`, for the journal's own entries. */\n seal(): void;\n /** As `History.observe`, for the journal's own entries: each push, coalesce, undo and redo inside it. */\n observe(listener: (step: HistoryStep) => void): () => void;\n /** Open a journal inside this one, as `History.beginJournal` does on a\n * history: its commit lands here as one entry, and its cancel leaves this\n * journal as it was. */\n beginJournal(opts: BeginJournalOptions): Journal;\n /** Counter bumped on every change a reader of this journal could see: an\n * apply, undo, redo or coalesce inside it, and every lifecycle transition\n * (`isActive` changes). Pairs with `subscribe` for `useSyncExternalStore`. */\n getVersion(): number;\n /** Fires whenever `getVersion` bumps. Returns an unsubscribe fn. */\n subscribe(listener: () => void): () => void;\n\n // Lifecycle\n /** Throws while a journal opened inside this one is still active. */\n commit(label: string): void;\n /** Cancels a journal still active inside this one first. */\n cancel(): void;\n suspend(): void;\n isActive(): boolean;\n}\n\n/** Internal factory used by `createHistory`'s `beginJournal` method.\n * Not exported via the package's `index.ts` — callers go through\n * `history.beginJournal()`. */\nexport function createJournalInternal(\n parent: History,\n adapter: unknown,\n opts: BeginJournalOptions,\n onClose?: () => void,\n inherited: Pick<CreateHistoryOptions, 'coalesceWindowMs' | 'now' | 'debug' | 'selection'> = {},\n): Journal {\n const inner = createHistory(adapter, {\n ...inherited,\n ...(opts.coalesceWindowMs !== undefined ? { coalesceWindowMs: opts.coalesceWindowMs } : {}),\n });\n const selection = inherited.selection;\n let version = 0;\n const changed = createEmitter();\n function bump(): void {\n version++;\n changed.emit();\n }\n inner.subscribe(bump);\n const forkedAtEntryId = parent.currentEntryId();\n // The whole session collapses to one parent entry, so the selection that\n // entry restores is the one the session opened under — not whatever the\n // last keystroke left.\n const selectionBefore = selection ? [...selection.get()] : undefined;\n type State = 'active' | 'suspended' | 'closed';\n let state: State = 'active';\n const targetId = opts.targetId;\n\n const journal: Journal = {\n targetId,\n forkedAtEntryId,\n\n applyBatch(ops: Op[], label: string): void {\n if (state !== 'active') throw new Error('Journal is not active');\n inner.applyOps(ops, label);\n },\n undo(): void {\n if (state !== 'active') throw new Error('Journal is not active');\n inner.undo();\n },\n redo(): void {\n if (state !== 'active') throw new Error('Journal is not active');\n inner.redo();\n },\n canUndo(): boolean {\n return inner.canUndo();\n },\n canRedo(): boolean {\n return inner.canRedo();\n },\n entries() {\n return inner.entries();\n },\n seal(): void {\n inner.seal();\n },\n observe: (listener) => inner.observe(listener),\n beginJournal(nested: BeginJournalOptions): Journal {\n if (state !== 'active') throw new Error('Journal is not active');\n return inner.beginJournal(nested);\n },\n getVersion: () => version,\n subscribe: changed.subscribe,\n commit(label: string): void {\n if (state !== 'active') throw new Error('Journal is not active');\n // Its ops are applied but recorded nowhere this commit reads.\n if (inner.activeJournal?.()) throw new Error('A journal inside this one is still active — commit, cancel, or suspend it first');\n // Coalescing splits an entry in two: the forward half is the latest\n // push, the base half the first, and undo inverts the base.\n const { forwardOps, baseOps } = _journalAccessInternal(inner).appliedOps();\n _journalAccessInternal(parent).record(\n forwardOps, baseOps, label, selectionBefore ? { selectionBefore } : undefined,\n );\n state = 'closed';\n RESUMERS.delete(journal);\n onClose?.();\n bump();\n },\n cancel(): void {\n if (state !== 'active') throw new Error('Journal is not active');\n inner.activeJournal?.()?.cancel();\n inner.goto(0);\n state = 'closed';\n RESUMERS.delete(journal);\n onClose?.();\n bump();\n },\n suspend(): void {\n if (state !== 'active') throw new Error('Journal is not active');\n state = 'suspended';\n onClose?.();\n bump();\n },\n isActive(): boolean {\n return state === 'active';\n },\n };\n\n RESUMERS.set(journal, () => {\n if (state !== 'suspended') throw new Error('Journal is not suspended');\n state = 'active';\n bump();\n });\n\n return journal;\n}\n","import { createEmitter } from '@weasel-js/registry';\nimport type { Op } from './op';\nimport { anyCaused, appliedHalves, createApplier, entryView, foldEntry, sameCoalesceKeys, stepOf } from './entryOps';\nimport { createJournalInternal, _resumeJournalInternal, type Journal, type BeginJournalOptions } from './journal';\nimport {\n rebuilt, snapshot, touchedIdsFromOps,\n type Entry, type HistoryLogger, type SerializedHistory,\n} from './serialized';\nimport type {\n CreateHistoryOptions, History, HistoryBranch, HistoryStep, RecordEntryOptions,\n} from './historyTypes';\n\nexport { touchedIdsFromOps } from './serialized';\nexport type { HistoryLogger, SerializedHistory, SerializedHistoryEntry, SerializedOp } from './serialized';\nexport type {\n EvictedEntry, HistoryEntry, HistoryBranch, History, HistorySelection, HistoryStep, RecordEntryOptions,\n CreateHistoryOptions,\n} from './historyTypes';\n\n/** What a journal needs from a history beyond its public surface: both halves\n * of every applied entry, and a way to record both on its parent. */\ninterface JournalAccess {\n appliedOps(): { forwardOps: Op[]; baseOps: Op[] };\n record(forwardOps: Op[], baseOps: Op[], label: string, options?: RecordEntryOptions): void;\n}\n\nconst JOURNAL_ACCESS = new WeakMap<History, JournalAccess>();\n\n/** Called by `Journal.commit`. Not part of the public API. */\nexport function _journalAccessInternal(history: History): JournalAccess {\n const access = JOURNAL_ACCESS.get(history);\n if (!access) throw new Error('Not a history built by createHistory');\n return access;\n}\n\n/** Silent default — keeps every call site unconditional. */\nconst SILENT: HistoryLogger = { log: () => {}, warn: () => {} };\n\n/** Build an op-batched undo/redo `History`. The adapter is passed to each op's `apply`/`invert`. */\nexport function createHistory(adapter: unknown, options: CreateHistoryOptions = {}): History {\n const undoStack: Entry[] = [];\n const redoStack: Entry[] = [];\n let activeJournal: Journal | null = null;\n const coalesceWindowMs = options.coalesceWindowMs ?? 0;\n const now = options.now ?? (() => Date.now());\n const historyLimit = Math.max(0, options.historyLimit ?? Infinity);\n const onEvict = options.onEvict;\n const branching = options.branching ?? false;\n /** Futures a push set aside, by the id of the entry they fork from (the\n * floor's for the oldest reachable state), each in time order. Only a\n * branching history adds to it. */\n const forks = new Map<number, Entry[][]>();\n /** Names the state beneath the undo stack: 0 at the start, then the id of\n * the last undo entry evicted. */\n let floorId = 0;\n const customRebuild = options.rebuildOp;\n const selection = options.selection;\n const logger = options.debug ?? SILENT;\n let nextEntryId = 1;\n let version = 0;\n /** `version` as of the last push or coalesce. A batch may only merge into\n * the top entry while this still matches: every other operation bumps\n * `version`, so undo, redo, goto, clear, restore and `recordEntry` all\n * expire the merge window without having to remember to. Without that, an\n * edit made after stepping back rewrites whatever entry the step left on\n * top, and one undo then jumps past it. */\n let coalesceAnchorVersion = -1;\n const changed = createEmitter();\n const stepped = createEmitter<[HistoryStep]>();\n function bump(step?: HistoryStep): void {\n version++;\n if (step && stepped.size > 0) stepped.emit(step);\n changed.emit();\n }\n\n /** Report entries that just became permanently unreachable. A throwing\n * callback must not desync the stacks mid-mutation, so failures are\n * contained and surfaced via the debug flag. */\n function reportEvicted(entries: Entry[]): void {\n if (!onEvict) return;\n for (const e of entries) {\n try {\n onEvict({ id: e.id, label: e.label, forwardOps: e.forwardOps, baseOps: e.baseOps });\n } catch (err) {\n logger.warn(`onEvict callback threw for entry id=${e.id} \"${e.label}\": ${String(err)}`);\n }\n }\n }\n\n /** Report `entries` evicted, and evict every branch forking from them. */\n function evict(entries: Entry[]): void {\n reportEvicted(entries);\n for (const e of entries) {\n const kept = forks.get(e.id);\n if (!kept) continue;\n forks.delete(e.id);\n for (const branch of kept) evict(branch);\n }\n }\n\n /** Evict `entries` off the bottom of the undo stack, oldest first. Each one\n * raises the floor to the state it leaves: the futures forking from the old\n * floor go with it, and the ones forking from the entry now fork from the\n * floor. */\n function evictFloor(entries: Entry[]): void {\n for (const e of entries) {\n if (onEvict) reportEvicted([e]);\n const stranded = forks.size > 0 ? forks.get(floorId) : undefined;\n if (stranded !== undefined) forks.delete(floorId);\n floorId = e.id;\n if (stranded !== undefined) for (const branch of stranded) evict(branch);\n }\n }\n\n /** The id of the entry the history stands on, the floor's beneath them all. */\n function forkPoint(): number {\n return undoStack[undoStack.length - 1]?.id ?? floorId;\n }\n\n /** Clear the redo stack after a push forking from `at`: kept as a branch\n * when branching, else dropped and reported. */\n function retireRedo(at: number): void {\n if (redoStack.length === 0) return;\n const future = redoStack.splice(0);\n if (!branching) return evict(future);\n const kept = forks.get(at);\n if (kept) kept.push(future.reverse());\n else forks.set(at, [future.reverse()]);\n }\n\n /** Evict the oldest undo entries past `historyLimit`, reporting each. */\n function enforceLimit(): void {\n while (undoStack.length > historyLimit) {\n evictFloor([undoStack.shift()!]);\n }\n }\n\n const applyAllOrNothing = createApplier(adapter, logger);\n\n function invertEntry(entry: Entry): Op[] {\n return [...entry.baseOps].reverse().map((op) => op.invert());\n }\n\n /** Copy on read: the caller's array is theirs to mutate. */\n function readSelection(): readonly string[] | undefined {\n return selection ? [...selection.get()] : undefined;\n }\n\n /** Walk one entry backwards. The selection is restored *after* the\n * inverted ops apply, so an entry that also carries a `setSelection`-style\n * op can't overwrite the snapshot. */\n function stepBack(entry: Entry): void {\n const leaving = readSelection();\n const coalesced = entry.forwardOps !== entry.baseOps;\n applyAllOrNothing(invertEntry(entry), coalesced ? () => entry.forwardOps : undefined);\n if (leaving) entry.selectionAfter = leaving;\n if (selection && entry.selectionBefore) selection.set(entry.selectionBefore);\n }\n\n /** Walk one entry forwards. Mirror of `stepBack`. */\n function stepForward(entry: Entry): void {\n const leaving = readSelection();\n const coalesced = entry.forwardOps !== entry.baseOps;\n applyAllOrNothing(entry.forwardOps, coalesced ? () => invertEntry(entry) : undefined);\n if (leaving) entry.selectionBefore = leaving;\n if (selection && entry.selectionAfter) selection.set(entry.selectionAfter);\n }\n\n /** Step until `n` entries are on the undo stack. An entry changes stacks\n * only once its step has run, so a throw leaves both stacks describing\n * the state as it is. */\n function walkTo(n: number): Entry[] {\n const walked: Entry[] = [];\n while (undoStack.length > n) {\n const entry = undoStack[undoStack.length - 1]!;\n stepBack(entry);\n undoStack.pop();\n redoStack.push(entry);\n walked.push(entry);\n }\n while (undoStack.length < n && redoStack.length > 0) {\n const entry = redoStack[redoStack.length - 1]!;\n stepForward(entry);\n redoStack.pop();\n undoStack.push(entry);\n walked.push(entry);\n }\n return walked;\n }\n\n /** Coalesce eligibility: inside the window, and the same keys. Matched by\n * multiset rather than position so a multi-id selection can re-emit ops in\n * any order between batches without breaking the merge. */\n function canCoalesce(top: Entry, incoming: Op[]): boolean {\n const windowMs = typeof coalesceWindowMs === 'function' ? coalesceWindowMs() : coalesceWindowMs;\n if (!(windowMs > 0) || top.coalesceKey !== undefined || version !== coalesceAnchorVersion || now() - top.timestamp > windowMs) return false;\n return sameCoalesceKeys(top.forwardOps, incoming);\n }\n\n function pushOrCoalesce(applied: Op[], label: string, owned = false): void {\n if (applied.length === 0) return;\n const selectionBefore = readSelection();\n const idle: Op[] = [];\n const anyMutated = applyAllOrNothing(applied, undefined, idle);\n const kept = idle.length === 0 ? applied : applied.filter((op) => !(op.elideNoop && idle.includes(op)));\n const ops = anyCaused(kept) ? kept.flatMap((op) => op.caused?.() ?? [op]) : owned || kept !== applied ? kept : kept.slice();\n if (!anyMutated) {\n // Every op reported `false`/`'noop'`. Skip the push so undo stays\n // tied to real state changes. Surfaced through the kit's debug\n // flag so the upstream caller can consider avoiding the dispatch\n // entirely. Hidden by default; enable via\n // `localStorage.setItem('weasel.debug', '1')`.\n logger.warn(\n `'${label}' batch was a no-op — every op reported false/'noop'. ` +\n `Skipping the undo entry; consider gating the dispatch upstream to avoid the wasted work.`,\n );\n return;\n }\n if (ops.length === 0) return;\n const incoming = touchedIdsFromOps(ops);\n const top = undoStack[undoStack.length - 1];\n if (top && canCoalesce(top, ops)) {\n top.forwardOps = ops;\n top.timestamp = now();\n top.pushes++;\n // Merge incoming touched ids into the coalesced entry's set.\n if (incoming.size > 0) {\n const merged = new Set(top.touchedIds);\n for (const id of incoming) merged.add(id);\n top.touchedIds = merged;\n }\n // baseOps + label + id intentionally preserved — undo returns to the\n // pre-edit state, the original label sticks, and the entry id stays\n // stable so React lists keyed on id don't flicker. No dropRedo() here:\n // the anchor only survives until the stack is stepped, and every step\n // clears it, so a live anchor implies an empty redo stack.\n logger.log(`coalesce '${label}' into entry id=${top.id} (${ops.length} ops)`);\n bump(stepped.size > 0 ? { kind: 'coalesce', entries: [{ id: top.id, label: top.label, ops }] } : undefined);\n coalesceAnchorVersion = version;\n return;\n }\n logger.log(`push '${label}' (${ops.length} ops)`);\n const at = forkPoint();\n const entry: Entry = {\n id: nextEntryId++, forwardOps: ops, baseOps: ops, label, timestamp: now(), pushes: 1, touchedIds: incoming,\n ...(selectionBefore ? { selectionBefore } : {}),\n };\n undoStack.push(entry);\n retireRedo(at);\n enforceLimit();\n bump(stepped.size > 0 ? stepOf('push', [entry]) : undefined);\n coalesceAnchorVersion = version;\n }\n\n function fold(top: Entry, ops: Op[]): void {\n foldEntry(top, ops, now());\n bump(stepped.size > 0 ? { kind: 'coalesce', entries: [{ id: top.id, label: top.label, ops }] } : undefined);\n coalesceAnchorVersion = version;\n }\n\n function record(forwardOps: Op[], baseOps: Op[], label: string, options: RecordEntryOptions = {}): void {\n if (forwardOps.length === 0) return;\n const key = options.coalesceKey;\n const top = undoStack[undoStack.length - 1];\n if (key !== undefined && top?.coalesceKey === key && version === coalesceAnchorVersion && forwardOps === baseOps) {\n return fold(top, forwardOps);\n }\n const at = forkPoint();\n const entry: Entry = {\n id: nextEntryId++, forwardOps, baseOps, label, timestamp: now(), pushes: 1,\n touchedIds: touchedIdsFromOps(forwardOps),\n ...(options.selectionBefore ? { selectionBefore: [...options.selectionBefore] } : {}),\n ...(key !== undefined ? { coalesceKey: key } : {}),\n };\n undoStack.push(entry);\n retireRedo(at);\n enforceLimit();\n bump(stepped.size > 0 ? stepOf('push', [entry]) : undefined);\n if (key !== undefined) coalesceAnchorVersion = version;\n }\n\n const history: History = {\n apply(op, label) {\n pushOrCoalesce([op], label ?? op.label ?? '', true);\n },\n applyOps(ops, label) {\n pushOrCoalesce(ops, label);\n },\n undo() {\n if (undoStack.length === 0) return;\n bump(stepOf('undo', walkTo(undoStack.length - 1)));\n },\n redo() {\n if (redoStack.length === 0) return;\n bump(stepOf('redo', walkTo(undoStack.length + 1)));\n },\n seal() {\n coalesceAnchorVersion = -1;\n },\n canUndo: () => undoStack.length > 0,\n canRedo: () => redoStack.length > 0,\n undoDepth: () => undoStack.length,\n redoDepth: () => redoStack.length,\n clear: () => {\n const had = undoStack.length > 0 || redoStack.length > 0 || forks.size > 0;\n undoStack.length = 0;\n redoStack.length = 0;\n forks.clear();\n floorId = 0;\n if (had) bump(stepOf('clear'));\n },\n entries() {\n // redoStack is internally stored newest-on-top (so `pop()` redoes the\n // next-most-recent undo). Reverse on the way out so callers see the\n // entries in chronological order — the user's next redo is the first\n // element, matching `entries().redo[0]` semantics.\n return {\n undo: undoStack.map(entryView),\n redo: [...redoStack].reverse().map(entryView),\n };\n },\n goto(n) {\n // Total length stays constant during this walk (we only shuffle\n // entries between undo and redo stacks).\n const total = undoStack.length + redoStack.length;\n if (!Number.isInteger(n) || n < 0 || n > total || n === undoStack.length) return;\n const start = undoStack.length;\n let walked: Entry[];\n try {\n walked = walkTo(n);\n } catch (err) {\n // Stop where the walk began rather than partway. A second throw on\n // the way back is logged: the stacks still match the state, at\n // whatever depth that walk reached.\n try {\n walkTo(start);\n } catch (back) {\n logger.warn(`goto: returning to depth ${start} threw: ${String(back)}`);\n }\n if (undoStack.length !== start) bump();\n throw err;\n }\n bump(stepOf('goto', walked));\n },\n timestampAt(i) {\n if (!Number.isInteger(i) || i < 0) return undefined;\n if (i < undoStack.length) return undoStack[i]!.timestamp;\n // redoStack is newest-on-top, so time order runs from its end.\n return redoStack[redoStack.length - 1 - (i - undoStack.length)]?.timestamp;\n },\n depthAt(t) {\n let n = undoStack.length;\n while (n > 0 && undoStack[n - 1]!.timestamp > t) n--;\n if (n < undoStack.length) return n;\n for (let r = redoStack.length - 1; r >= 0 && redoStack[r]!.timestamp <= t; r--) n++;\n return n;\n },\n prune(t) {\n let k = 0;\n while (k < undoStack.length && undoStack[k]!.timestamp < t) k++;\n if (k === 0) return;\n const evicted = undoStack.splice(0, k);\n evictFloor(evicted);\n bump(stepOf('prune', evicted));\n },\n branches() {\n const view = (entries: readonly Entry[], current: boolean): HistoryBranch => {\n const first = entries[0]!;\n return { id: first.id, label: first.label, timestamp: first.timestamp, length: entries.length, current };\n };\n const out = (forks.get(forkPoint()) ?? []).map((b) => view(b, false));\n if (redoStack.length > 0) out.push(view([...redoStack].reverse(), true));\n return out.sort((a, b) => a.id - b.id);\n },\n switchBranch(id) {\n if (redoStack[redoStack.length - 1]?.id === id) return;\n const at = forkPoint();\n const kept = forks.get(at) ?? [];\n const i = kept.findIndex((b) => b[0]!.id === id);\n if (i < 0) throw new Error(`No branch ${id} forks from entry ${at}`);\n const [chosen] = kept.splice(i, 1);\n if (redoStack.length > 0) kept.push(redoStack.splice(0).reverse());\n if (kept.length > 0) forks.set(at, kept);\n else forks.delete(at);\n redoStack.push(...[...chosen!].reverse());\n bump(stepOf('branch', chosen));\n },\n getVersion: () => version,\n subscribe: changed.subscribe,\n observe: stepped.subscribe,\n serialize: () => snapshot({ undoStack, redoStack, forks, floorId, nextEntryId }, logger),\n recordEntry(ops: Op[], label: string, options?: RecordEntryOptions): void {\n record(ops, ops, label, options);\n },\n allForwardOps(): Op[] {\n const out: Op[] = [];\n for (const e of undoStack) {\n for (const op of e.forwardOps) out.push(op);\n }\n return out;\n },\n currentEntryId: () => nextEntryId,\n beginJournal(opts: BeginJournalOptions): Journal {\n if (activeJournal !== null && activeJournal.isActive()) {\n throw new Error('A journal is already active — commit, cancel, or suspend it first');\n }\n // `adapter` is the closure-captured adapter passed to createHistory.\n // The returned History object's `this` doesn't carry it, so we pass\n // it through to the factory directly.\n const j = createJournalInternal(history, adapter, opts, () => { activeJournal = null; }, {\n coalesceWindowMs, now, debug: logger,\n ...(selection ? { selection } : {}),\n });\n activeJournal = j;\n return j;\n },\n activeJournal: () => (activeJournal?.isActive() ? activeJournal : null),\n resumeJournal(journal: Journal): void {\n if (activeJournal !== null && activeJournal !== journal && activeJournal.isActive()) {\n throw new Error('A journal is already active — commit, cancel, or suspend it first');\n }\n _resumeJournalInternal(journal);\n activeJournal = journal;\n },\n restore(serialized: SerializedHistory): void {\n const next = rebuilt(serialized, customRebuild, logger);\n undoStack.splice(0, undoStack.length, ...next.undoStack);\n redoStack.splice(0, redoStack.length, ...next.redoStack);\n forks.clear();\n for (const [at, kept] of next.forks) forks.set(at, kept);\n floorId = next.floorId;\n nextEntryId = next.nextEntryId;\n bump(stepOf('restore'));\n },\n };\n JOURNAL_ACCESS.set(history, {\n appliedOps: () => appliedHalves(undoStack),\n record,\n });\n return history;\n}\n","import type { Op } from './op';\n\n/** What a {@link swapOp} carries as its `args`: the value it leaves and the one it makes. */\nexport interface SwapArgs<V> {\n before: V;\n after: V;\n}\n\n/** What {@link swapOp} is built from. */\nexport interface SwapOpOptions<V> extends SwapArgs<V> {\n /** The op's `name`, which a history's `rebuildOp` matches to rebuild it from a snapshot. */\n name: string;\n label: string;\n /** Puts a value in force. Called with `after` to apply and `before` to undo. */\n emit(value: V): void;\n coalesceKey?: string;\n}\n\n/**\n * An edit as the swap of one whole value for another. For a value held immutably the two snapshots are\n * references, and the op carries both as `args`, so a serialized history can rebuild the step.\n */\nexport function swapOp<V>({ name, label, before, after, emit, coalesceKey }: SwapOpOptions<V>): Op {\n const forward: Op = {\n label,\n name,\n args: { before, after } satisfies SwapArgs<V>,\n ...(coalesceKey !== undefined ? { coalesceKey } : {}),\n apply: () => emit(after),\n invert: () => ({ label, apply: () => emit(before), invert: () => forward }),\n };\n return forward;\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@weasel-js/history",
|
|
3
|
-
"version": "1.17.
|
|
3
|
+
"version": "1.17.3",
|
|
4
4
|
"description": "Undo/redo history with scoped sub-history (Journal) primitive. No React, no DOM.",
|
|
5
5
|
"weasel": {
|
|
6
6
|
"tier": "base"
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
"./package.json": "./package.json"
|
|
20
20
|
},
|
|
21
21
|
"dependencies": {
|
|
22
|
-
"@weasel-js/registry": "1.17.
|
|
22
|
+
"@weasel-js/registry": "1.17.3"
|
|
23
23
|
},
|
|
24
24
|
"author": "orochi235",
|
|
25
25
|
"homepage": "https://orochi235.github.io/weasel/",
|