Files
workinf_Blender_Wasm/web/protocol/dirty-state.ts
mes123456 7c16b279ae
Some checks failed
M6 deployable RC / quick (push) Has been cancelled
M6 deployable RC / chromium (push) Has been cancelled
M6 deployable RC / release (push) Has been cancelled
Advance M7 workflows and release operations
2026-08-15 17:43:53 -04:00

54 lines
2.4 KiB
TypeScript

export interface DirtyState {
currentMainRevision: number;
committedMainRevision: number;
dirty: boolean;
}
export type DirtyStateResult =
| { ok: true; state: DirtyState }
| { ok: false; state: DirtyState; errorCode: "DIRTY_REVISION_INVALID" | "DIRTY_REVISION_STALE" | "DIRTY_SAVE_REVISION_MISMATCH" };
function validRevision(revision: number): boolean {
return Number.isSafeInteger(revision) && revision >= 0;
}
export function createDirtyState(revision = 0): DirtyState {
if (!validRevision(revision)) throw new Error("DIRTY_REVISION_INVALID");
return { currentMainRevision: revision, committedMainRevision: revision, dirty: false };
}
export function recoverDirtyState(currentMainRevision: number, committedMainRevision: number): DirtyState {
if (!validRevision(currentMainRevision) || !validRevision(committedMainRevision) || currentMainRevision < committedMainRevision) {
throw new Error("DIRTY_REVISION_INVALID");
}
return { currentMainRevision, committedMainRevision, dirty: currentMainRevision !== committedMainRevision };
}
export function acceptMainTransaction(state: DirtyState, revision: number): DirtyStateResult {
if (!validRevision(revision)) return { ok: false, state, errorCode: "DIRTY_REVISION_INVALID" };
if (revision <= state.currentMainRevision) return { ok: false, state, errorCode: "DIRTY_REVISION_STALE" };
return {
ok: true,
state: { ...state, currentMainRevision: revision, dirty: revision !== state.committedMainRevision },
};
}
export function acceptMainSave(state: DirtyState, revision: number): DirtyStateResult {
if (!validRevision(revision)) return { ok: false, state, errorCode: "DIRTY_REVISION_INVALID" };
if (revision !== state.currentMainRevision) return { ok: false, state, errorCode: "DIRTY_SAVE_REVISION_MISMATCH" };
return { ok: true, state: { currentMainRevision: revision, committedMainRevision: revision, dirty: false } };
}
export function acceptHistoryTransaction(state: DirtyState, revision: number, matchesCommittedContent: boolean): DirtyStateResult {
if (!validRevision(revision)) return { ok: false, state, errorCode: "DIRTY_REVISION_INVALID" };
if (revision <= state.currentMainRevision) return { ok: false, state, errorCode: "DIRTY_REVISION_STALE" };
return {
ok: true,
state: {
currentMainRevision: revision,
committedMainRevision: matchesCommittedContent ? revision : state.committedMainRevision,
dirty: !matchesCommittedContent,
},
};
}