Skip to content

Commit 60cabf8

Browse files
committed
refactor: extract experimental sync target wrapper
1 parent 16acf57 commit 60cabf8

3 files changed

Lines changed: 96 additions & 15 deletions

File tree

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
import type { AccountStorageV3 } from "../storage.js";
2+
3+
export async function loadExperimentalSyncTargetEntry(params: {
4+
loadExperimentalSyncTargetState: (args: {
5+
detectTarget: () => ReturnType<
6+
typeof import("../oc-chatgpt-target-detection.js").detectOcChatgptMultiAuthTarget
7+
>;
8+
readJson: (path: string) => Promise<unknown>;
9+
normalizeAccountStorage: (value: unknown) => AccountStorageV3 | null;
10+
}) => Promise<
11+
| {
12+
kind: "blocked-ambiguous";
13+
detection: ReturnType<
14+
typeof import("../oc-chatgpt-target-detection.js").detectOcChatgptMultiAuthTarget
15+
>;
16+
}
17+
| {
18+
kind: "blocked-none";
19+
detection: ReturnType<
20+
typeof import("../oc-chatgpt-target-detection.js").detectOcChatgptMultiAuthTarget
21+
>;
22+
}
23+
| { kind: "error"; message: string }
24+
| {
25+
kind: "target";
26+
detection: ReturnType<
27+
typeof import("../oc-chatgpt-target-detection.js").detectOcChatgptMultiAuthTarget
28+
>;
29+
destination: AccountStorageV3 | null;
30+
}
31+
>;
32+
detectTarget: () => ReturnType<
33+
typeof import("../oc-chatgpt-target-detection.js").detectOcChatgptMultiAuthTarget
34+
>;
35+
readFileWithRetry: (
36+
path: string,
37+
options: {
38+
retryableCodes: Set<string>;
39+
maxAttempts: number;
40+
sleep: (ms: number) => Promise<void>;
41+
},
42+
) => Promise<string>;
43+
normalizeAccountStorage: (value: unknown) => AccountStorageV3 | null;
44+
sleep: (ms: number) => Promise<void>;
45+
}): ReturnType<typeof params.loadExperimentalSyncTargetState> {
46+
return params.loadExperimentalSyncTargetState({
47+
detectTarget: params.detectTarget,
48+
readJson: async (path) =>
49+
JSON.parse(
50+
await params.readFileWithRetry(path, {
51+
retryableCodes: new Set([
52+
"EBUSY",
53+
"EPERM",
54+
"EAGAIN",
55+
"ENOTEMPTY",
56+
"EACCES",
57+
]),
58+
maxAttempts: 4,
59+
sleep: params.sleep,
60+
}),
61+
),
62+
normalizeAccountStorage: params.normalizeAccountStorage,
63+
});
64+
}

lib/codex-manager/settings-hub.ts

Lines changed: 5 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ import {
7070
mapExperimentalStatusHotkey,
7171
} from "./experimental-settings-schema.js";
7272
import { loadExperimentalSyncTargetState } from "./experimental-sync-target.js";
73+
import { loadExperimentalSyncTargetEntry } from "./experimental-sync-target-entry.js";
7374
import {
7475
buildSettingsHubItems,
7576
findSettingsHubInitialCursor,
@@ -769,23 +770,12 @@ async function loadExperimentalSyncTarget(): Promise<
769770
destination: import("../storage.js").AccountStorageV3 | null;
770771
}
771772
> {
772-
return loadExperimentalSyncTargetState({
773+
return loadExperimentalSyncTargetEntry({
774+
loadExperimentalSyncTargetState,
773775
detectTarget: detectOcChatgptMultiAuthTarget,
774-
readJson: async (path) =>
775-
JSON.parse(
776-
await readFileWithRetry(path, {
777-
retryableCodes: new Set([
778-
"EBUSY",
779-
"EPERM",
780-
"EAGAIN",
781-
"ENOTEMPTY",
782-
"EACCES",
783-
]),
784-
maxAttempts: 4,
785-
sleep,
786-
}),
787-
),
776+
readFileWithRetry,
788777
normalizeAccountStorage,
778+
sleep,
789779
});
790780
}
791781

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import { describe, expect, it, vi } from "vitest";
2+
import { loadExperimentalSyncTargetEntry } from "../lib/codex-manager/experimental-sync-target-entry.js";
3+
4+
describe("experimental sync target entry", () => {
5+
it("delegates retrying file read and normalization through the target loader", async () => {
6+
const loadExperimentalSyncTargetState = vi.fn(async () => ({
7+
kind: "target",
8+
detection: { kind: "target" },
9+
destination: null,
10+
}));
11+
12+
const result = await loadExperimentalSyncTargetEntry({
13+
loadExperimentalSyncTargetState,
14+
detectTarget: () => ({ kind: "target" }) as never,
15+
readFileWithRetry: vi.fn(async () => "{}"),
16+
normalizeAccountStorage: vi.fn(() => null),
17+
sleep: vi.fn(async () => undefined),
18+
});
19+
20+
expect(loadExperimentalSyncTargetState).toHaveBeenCalled();
21+
expect(result).toEqual({
22+
kind: "target",
23+
detection: { kind: "target" },
24+
destination: null,
25+
});
26+
});
27+
});

0 commit comments

Comments
 (0)