Trim per-release overhead in the scene

Only re-measure the viewport at begin() when a container is mounted, and
only allocate waiting machinery when an interrupted finish() actually
needs to wait for a later release. Interrupted releases now resolve with
the final decided outcome in every case.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Faarh2Ts6StJPcz2mRiHiR
This commit is contained in:
Claude
2026-10-16 04:28:43 +00:00
parent a46c411ec4
commit 7033814550
+34 -27
View File
@@ -285,9 +285,12 @@ class Scene implements OriginScene {
*/
/** The latest release (finish call) of each operation. */
private readonly releases = new WeakMap<MutableOriginOperation, object>();
private readonly outcomes = new WeakMap<
/** Final outcome of each operation, once a release has decided it. */
private readonly outcomes = new WeakMap<MutableOriginOperation, boolean>();
/** Interrupted releases waiting for a later release to decide. */
private readonly waiters = new WeakMap<
MutableOriginOperation,
{ promise: Promise<boolean>; resolve(committed: boolean): void }
Array<(committed: boolean) => void>
>();
private readonly effectSets = new WeakMap<
MutableOriginOperation,
@@ -322,7 +325,7 @@ class Scene implements OriginScene {
originKey: string,
action: OriginAction,
): Promise<OriginOperationHandle> {
this.refreshViewport();
if (this.container) this.refreshViewport();
const operation = this.graph.begin(
originKey,
action,
@@ -383,36 +386,40 @@ class Scene implements OriginScene {
current,
);
const outcome = this.outcomeOf(operation);
// Another release already decided this operation.
const decided = this.outcomes.get(operation);
if (decided !== undefined) return decided;
// A later operation may already have finalized this edge.
const finished = (operation.phase as OriginOperationPhase) === "finished";
if (!this.graph.operation(operation.id) || finished) {
const committed = this.graph.operation(operation.id)
? operation.intent === "commit"
: commit;
outcome.resolve(committed);
return committed;
}
// Caught by update() or superseded by a later finish().
if (!current()) return outcome.promise;
if (!this.graph.operation(operation.id) || finished)
return this.decide(
operation,
finished ? operation.intent === "commit" : commit,
);
// Caught by update() or superseded by a later finish(): wait for the
// release that decides.
if (!current())
return new Promise<boolean>((resolve) =>
this.waiters.set(operation, [
...(this.waiters.get(operation) ?? []),
resolve,
]),
);
const committed = commit
return this.decide(
operation,
commit
? this.graph.commit(operation.id)
: (this.graph.cancel(operation.id), false);
outcome.resolve(committed);
return committed;
: (this.graph.cancel(operation.id), false),
);
}
/** Resolves with an operation's final outcome, whichever release decides. */
private outcomeOf(operation: MutableOriginOperation) {
let outcome = this.outcomes.get(operation);
if (!outcome) {
let resolve!: (committed: boolean) => void;
const promise = new Promise<boolean>((done) => (resolve = done));
outcome = { promise, resolve };
this.outcomes.set(operation, outcome);
}
return outcome;
/** Record an operation's final outcome and settle interrupted releases. */
private decide(operation: MutableOriginOperation, committed: boolean) {
this.outcomes.set(operation, committed);
for (const resolve of this.waiters.get(operation) ?? []) resolve(committed);
this.waiters.delete(operation);
return committed;
}
registerElement(nodeKey: string, element: HTMLElement | null): void {