返回 DeepSeek-Reasonix
useCommittedAsyncCommand.ts
根目录 / desktop / frontend / src / lib / useCommittedAsyncCommand.ts
1 import { useMemo } from "react";
2 import { CommandCancelled, executeCapturedCommand, type CommandAuthority, type CommandOutcome } from "./commandOutcome";
3 import { useCommittedSlot, type CommittedSlot } from "./useCommittedSlot";
4
5 type CommandDefinition<Args extends unknown[], Input, Result> = {
6 capture: (...args: Args) => Input;
7 execute: (input: Input, authority: CommandAuthority) => Result;
8 };
9
10 function captureAuthority(slot: CommittedSlot<unknown>): CommandAuthority {
11 const epoch = slot.epoch;
12 const requestId = ++slot.requestId;
13 return {
14 checkpoint() {
15 if (slot.phase !== "ready" || slot.epoch !== epoch) throw new CommandCancelled("disposed");
16 if (slot.requestId !== requestId) throw new CommandCancelled("superseded");
17 },
18 };
19 }
20
21 function bindCommittedAsync<Args extends unknown[], Input, Result>(
22 slot: CommittedSlot<CommandDefinition<Args, Input, Result>>,
23 ) {
24 return (...args: Args): Promise<CommandOutcome<Awaited<Result>>> => {
25 if (!slot.value || slot.phase !== "ready") {
26 return Promise.resolve({ status: "cancelled", reason: slot.phase === "disposed" ? "disposed" : "not-ready" });
27 }
28 const authority = captureAuthority(slot);
29 try {
30 const { capture, execute } = slot.value;
31 return executeCapturedCommand(capture(...args), execute, authority);
32 } catch (error) {
33 return Promise.resolve(error instanceof CommandCancelled
34 ? { status: "cancelled", reason: error.reason }
35 : { status: "failed", error });
36 }
37 };
38 }
39
40 /** One command lane. Use independent owners for unrelated resource operations. */
41 export function useCommittedAsyncCommand<Args extends unknown[], Input, Result>(
42 capture: (...args: Args) => Input,
43 execute: (input: Input, authority: CommandAuthority) => Result,
44 ) {
45 const slot = useCommittedSlot({ capture, execute });
46 return useMemo(() => bindCommittedAsync(slot), [slot]);
47 }
48
48 lines TYPESCRIPT