Repository navigation
Conversation
This was referenced Oct 17, 2026
merryman
force-pushed
the
robin/morphic-change-engine
branch
from
October 17, 2026 14:28
2ff4d2c to
faadecd
Compare
merryman
force-pushed
the
robin/morphic-change-engine
branch
from
October 21, 2026 06:49
da02f7b to
a4fc836
Compare
This was referenced Oct 21, 2026
merryman
force-pushed
the
robin/morphic-change-engine
branch
from
October 22, 2026 13:37
a4fc836 to
502250b
Compare
This was referenced Oct 28, 2026
merryman
force-pushed
the
robin/morphic-change-engine
branch
from
November 2, 2026 15:07
3fa256b to
cdedfc3
Compare
Extract operation/change-set recording, structural undo and transaction tests. Ship the synchronous metadata contract with its rich-text callers and the two synchronous legacy fixture callbacks. Move the existing browser test cache bypass to the first slice whose CI runs the full IDE suite. Retain main text before-values while the legacy tracker remains. The committed-listener snapshot optimization and its test ship with S7.
Capture setters and structural primitives before effects; commit outer scopes once and verify reverse recovery on failure. Add synchronous savepoints, typed replay without history, committed/deferred delivery and change-set undo. Absorb the generic F5/F6 history and notification mechanics, and remove the parallel transaction classes after migrating their contract tests. Keep the ordinary recording path unchanged outside atomic frames.
Reverse the captured endpoints without materializing them. A domain materializer can return the current cached object, replacing both endpoints with its present state if invoked while planning an inverse. Keep materialization at replay and retain exact precondition and recovery checks. Cover cached identity adoption and stale replay rejection in a standalone morphic regression.
Clear the recording token after its joined entries are copied into the composite history entry. This restores the F5 cleanup at both normal closure and the next undoStart boundary without losing replay history. Add standalone coverage for both closure paths.
Temporarily proxy enlisted state during synchronous atomic scopes. Reject direct proxy writes and recover shallow alias or state-slot damage. Restore the original state objects and revoke captured views on every exit.
Capture supported Text edits as compact ReplaceText operations before document mutation. Keep the legacy notification view and use its matching commit receipt for exact attachment replay. Preserve existing non-transaction Text behavior and selection rules. Journal synchronous reactions with their source and reconcile replay and rollback to exact unit targets. Compose same-Text edits from their recorded ranges into one covering-span repair, preserving attributes, anchors and embedded ownership. Verify recovery and report incomplete rollback under C3. Keep source-unit parent and replay-journal state on the atomic frame, so a completed scope leaves no new manager slots. Cover commit, failure, thenable, nested and replay cleanup without changing ordinary recording or delivery.
Replace contiguous legacy records atomically at their chronological slot, with pending-only ownership transfer authenticated by a live commit token. Stage provisional history before committed consumers so only the final owner publishes an entry, and reject incomplete or interleaved ownership. Compensate committed sets or legacy receipts exactly once, discarding owned and inverse records and cancelling only genuinely empty groups. Keep ordinary committed-context construction unchanged and create ownership state only when requested through commitTokenFor(context).
Register lifetime handles only while rooted, release unclaimed context handles on scope exit, sweep dead registry references incrementally, and reuse the supplied operation context during replay. History-owned handles and per-node disposal receipts keep their existing release semantics. Consume rejected withMetaDo thenables before rejecting asynchronous use, hold rollback diagnostics weakly, and reject undoStop during replay before it can discard an active gesture recorder. Add regressions for bounded registry size, context reuse and cleanup, metadata rejection handling, diagnostic retention and replay ownership.
Main now caches static text lines (#1826) and lets static text embed morphs without a document (#1825). Transactional text replay has to honor both: - applying a text edit to a document-free text invalidates the cached static lines and the document backup before assigning the new text, so undo, redo and replay refresh static text and survive switching back to editable mode; - only doits force a document; embedded morphs stay document-free and are attached through the regular embedded-morph update. The change engine tests that create their own world now restore the previous $world, so later suites keep rendering into the active world. The text transaction tests cover read-only round trips and keeping static text embedding document-free across undo and redo.
merryman
force-pushed
the
robin/morphic-change-engine
branch
from
November 5, 2026 10:46
cdedfc3 to
e30452d
Compare
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Extend
ChangeManagerandUndoManagerwith synchronous atomic transactions and exact replay. Supported morph edits can commit as one undoable unit or recover their captured state when a mutation or reaction fails.transaction(opts, fn)captures property, structural and typed text operations before their effects, including partially failing primitives. Nested transactions provide savepoints. Complete rollback rethrows the original error by identity; incomplete recovery reportsMorphicRollbackError. A caught incomplete nested rollback prevents the outer transaction from committing.applyChangeSetreplays without creating history. Synchronous reactions run normally; their writes are journaled, repaired and verified against the intended state. Value snapshots preserve mutable graphics values, container prototypes, own__proto__fields, sparse arrays and symbol keys.replaceRecordedChangespreserve chronological history ownership.compensatereverses rejected committed work exactly once;abortGroupreverses an owned active group without a redo entry.performEditenlists domain edits with recovery receipts.historyStats()reports retained objects and estimated payload;clearHistory()releases history handles. Attached objects are never disposed.Committed listeners receive one delivery after a successful outer transaction and none after rollback. Synchronous
onChangeobservers can see intermediate writes and their inverses. Metadata callbacks propagate exceptions after restoring their scope. Existing recording batches retain their non-atomic behavior, and caller adoption remains opt-in.Transactions cannot span asynchronous work. Returning a thenable rolls back synchronously and throws
MorphicTransactionAsyncError; later continuations run outside that transaction. The state guard rejects direct state-object writes, while slot replacement and retained shallow aliases are checked at scope exit. Deep alias mutations, never-enlisted morphs, uninstrumented document methods, arbitrary DOM/JavaScript state and external effects remain outside the guarantee.Browser regressions cover savepoints, partial failures, late-enlisted guards, reaction recovery, text and embedded morphs, history ownership, domain receipts and retained-object lifetimes. Focused transaction/foundation tests pass, including snapshot regressions that fail without the own-key correction.
Refs #104: this supplies the change foundation; world-level direct-manipulation adoption and the CRDT experiment remain open.