Document engine
Document Model
Document, Handle, ChangeSet, Version, Anchor, Range, Proposal, and the editor bridge.
Three ideas carry most of Lextrix:
- Document — the content right now (immutable)
- ChangeSet — how you get to the next Document
- Version — a named point in that history
Handles, proposals, and anchors hang off those.
ChangeSet → Handle.apply → new Document → new VersionChangeSet
Compose, invert, transform, diff. Ops are Quill-compatible JSON.
import { ChangeSet } from 'lextrix-change';The published lextrix editor bundle also re-exports ChangeSet for app code.
Document and DocumentHandle
You do not mutate a Document in place. A DocumentHandle owns the live session.
import { DocumentHandle } from 'lextrix-change/document';
const handle = DocumentHandle.create(/* initial contents */);
const head = handle.getVersion();No required dispose — the handle is GC-owned.
Versions
History is linear. Restore does not rewrite the past; it diffs and appends a new Version.
handle.listVersions();
handle.restoreVersion(olderId);
handle.diffVersions(a, b);Toolbar undo/redo is editor History. That list is not listVersions().
Anchors and ranges
Offsets go stale when the document changes. Anchors and ranges bind to a Version and map forward through accepted ChangeSets.
handle.createAnchor(versionId, index);
handle.createRange(versionId, start, end);Proposals
A proposal is a ChangeSet aimed at a base Version. Inspect it, rebase if HEAD moved, then accept or reject. Nothing auto-rebases.
import { rebaseProposal } from 'lextrix-change/document';Editor bridge
You can ignore this if you only mount the editor and use importContent / exportContent.
When the Document runtime is on (default in 3.0), local typing settles in the editor first, then mirrors into the Handle. Remote or accepted proposals apply on the Handle first, then project into the editor. Origins are tagged so projected updates do not bounce back and duplicate content.
new Lextrix('#editor', { experimentalDocument: false }); // editor only
editor.getExperimentalHandle();
editor.acceptProposalAndProject(proposal);Those helpers are experimental — not all of them appear in published typings yet.