Files
houseplan-card/src/serialized-write-queue.ts
T
claude[bot] 7194fb2df0 feat(adoption): one owner for config/layout identity and the adoption sequence
`src/config-adoption.ts` owns config/layout with revision and fingerprint;
the host keeps `_serverCfg`/`_cfgRev`/`_layout`/`_layoutRev` as delegates.
All seven authoritative adoptions go through `adoptAuthoritativeGated`
(backdrop readiness → continuity → adopt → profile tail); the post-write
paths (space/delete ×2, optimize_undo, import/apply) gain the gate and take
revisions from the re-read bodies. `rollbackOptimistic` moves to the owner;
plan-optimize, space copy and the vacuum writers stop assigning identity.

Issue: #500
User-Visible: no
2026-09-10 11:41:16 +00:00

40 lines
1.1 KiB
TypeScript

/**
* Append one write to a promise chain without letting an earlier rejection
* poison later edits. The callback is deliberately invoked only when its turn
* starts, so it can read the latest local state at that moment.
*/
export function enqueueSerializedWrite(
previous: Promise<void>,
write: () => Promise<void>,
): Promise<void> {
return previous.catch(() => undefined).then(write);
}
export interface OptimisticAttempt<T> {
previous: T;
previousFingerprint: string;
revision: number;
attempted: T;
attemptedFingerprint: string;
}
/** Capture the server-backed value before exposing a write candidate locally. */
export function optimisticAttempt<T>(
previous: T,
attempted: T,
previousFingerprint: string,
revision: number,
fingerprint: (value: T) => string,
): OptimisticAttempt<T> {
return {
previous: JSON.parse(JSON.stringify(previous)) as T,
previousFingerprint,
revision,
attempted,
attemptedFingerprint: fingerprint(attempted),
};
}
// The rollback of an attempt lives with the identity owner:
// `ConfigAdoption.rollbackOptimistic` (#500).