Budget growing history and import recovery encoding

This commit is contained in:
2026-11-11 04:16:21 +08:00
parent b4c40d3087
commit 210bc14074
11 changed files with 120 additions and 22 deletions
+6 -5
View File
@@ -1,3 +1,4 @@
import {dataArray,dataRecord} from './data-containers.ts';
import {stageCreation,materializeCreations} from './creation-draft.ts';
import type { Applied, Availability, Capability, Change, Command, Commit, CoreSnapshot, Document, ElementRecord, Geometry, HistoryEntry, HistoryState, Id, OperationIntent, Origin, Registry, Result, Snapshot } from './types.ts';
import { applyChanges, createDocument, invert, targetElement, validateDocument } from './document.ts';
@@ -151,7 +152,7 @@ export function createEditor<Runtime = undefined>(options: EditorOptions<Runtime
if (!Number.isSafeInteger(nextSequence) || outbound && nextSequence <= sequence) throw fault('invalid_operation_sequence');
if (historyEntryId) {
const entries = new Map(history.entries), entry = entries.get(historyEntryId)!;
entries.set(entry.id, freeze({ ...entry, operationIds: [...entry.operationIds, ...operationIds] }));
entries.set(entry.id, dataRecord(freeze({ ...entry, operationIds: dataArray(freeze([...entry.operationIds, ...operationIds])) })));
history = Object.freeze({ ...history, entries: readMap(entries) });
}
if (outbound) {
@@ -232,10 +233,10 @@ export function createEditor<Runtime = undefined>(options: EditorOptions<Runtime
const prior = undo.length ? entries.get(undo[undo.length - 1]) : undefined;
if (settings.groupId && prior?.groupId === settings.groupId) {
historyEntryId = prior.id;
entries.set(prior.id, freeze({ ...prior, changes: [...prior.changes, ...changes] }));
entries.set(prior.id, dataRecord(freeze({ ...prior, changes: dataArray(freeze([...prior.changes, ...changes])) })));
} else {
historyEntryId = uniqueId(new Set());
entries.set(historyEntryId, freeze({ id: historyEntryId, label: settings.label || 'Edit', changes: [...changes], operationIds: [], ...(settings.groupId ? { groupId: settings.groupId } : {}) }));
entries.set(historyEntryId, dataRecord(freeze({ id: historyEntryId, label: settings.label || 'Edit', changes: dataArray(freeze([...changes])), operationIds: dataArray<Id>([]), ...(settings.groupId ? { groupId: settings.groupId } : {}) })));
undo.push(historyEntryId);
}
while (undo.length > limit) entries.delete(undo.shift()!);
@@ -266,8 +267,8 @@ export function createEditor<Runtime = undefined>(options: EditorOptions<Runtime
const entries=new Map(state.history.entries);
// Later redo entries belong to the lifecycle restored by this explicit history action.
// Frozen operations retain their original identities and incarnations.
if(restored)for(const [otherId,other]of entries)if(otherId!==id)entries.set(otherId,freeze({...other,changes:other.changes.map(remap)}));
entries.set(id,freeze({...entry,changes:direction==='undo'?invert(changes):changes}));
if(restored)for(const [otherId,other]of entries)if(otherId!==id)entries.set(otherId,dataRecord(freeze({...other,changes:dataArray(freeze(other.changes.map(remap)))})));
entries.set(id,dataRecord(freeze({...entry,changes:dataArray(freeze(direction==='undo'?invert(changes):changes))})));
const history: HistoryState = Object.freeze({ undo: Object.freeze(direction === 'undo' ? state.history.undo.slice(0, -1) : [...state.history.undo, id]), redo: Object.freeze(direction === 'redo' ? state.history.redo.slice(0, -1) : [...state.history.redo, id]), entries: readMap(entries) });
return publish(document, changes, direction, history, id);
} catch (error) { return reject(error); }