Files
tutti/apps/desktop/src/main/capture/captureSelectionTransition.ts
T
agent-radar 2ed3415fb7
Publish Claude Code Binaries / Stage and publish binaries (push) Canceled after 0s
Publish Tutti App Runtime / Build darwin-arm64 (push) Canceled after 0s
Publish Tutti App Runtime / Build darwin-amd64 (push) Canceled after 0s
Publish Tutti App Runtime / Build linux-amd64 (push) Canceled after 0s
Publish Tutti App Runtime / Build windows-amd64 (push) Canceled after 0s
Sync Tutti Agent Skills / sync (push) Canceled after 0s
Windows Agent Adapters / Test Windows agent adapters (push) Canceled after 0s
Windows Daemon Adapters / Test Windows daemon adapters (push) Canceled after 0s
Publish Tutti App Runtime / Publish runtime catalog (push) Canceled after 0s
源码快照 @ 2026-09-01 (source-only, 剔除非源码素材)
2026-09-01 20:17:27 +08:00

43 lines
1.2 KiB
TypeScript

export type CaptureSelectionTransitionPhase =
| "before_present"
| "during_present"
| "after_present"
| "after_metadata";
export class CaptureSelectionSupersededError extends Error {
readonly captureId: string;
readonly phase: CaptureSelectionTransitionPhase;
constructor(captureId: string, phase: CaptureSelectionTransitionPhase) {
super(`Screenshot capture ${captureId} was superseded during ${phase}`);
this.name = "CaptureSelectionSupersededError";
this.captureId = captureId;
this.phase = phase;
}
}
export async function runCaptureSelectionTransition<T>({
captureId,
isCurrent,
metadata,
present
}: {
captureId: string;
isCurrent(): boolean;
metadata: Promise<T>;
present(assertCurrent: () => void): Promise<void>;
}): Promise<T> {
const assertCurrent = (phase: CaptureSelectionTransitionPhase) => {
if (!isCurrent()) {
throw new CaptureSelectionSupersededError(captureId, phase);
}
};
assertCurrent("before_present");
await present(() => assertCurrent("during_present"));
assertCurrent("after_present");
const resolvedMetadata = await metadata;
assertCurrent("after_metadata");
return resolvedMetadata;
}