mirror of
https://github.com/Matysh/houseplan-card
synced 2026-09-30 03:38:47 +00:00
`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
40 lines
1.1 KiB
TypeScript
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).
|