Skip to content

Commit b2e6bfd

Browse files
committed
use discriminated union for worker state to remove duplicated state
1 parent 802d59c commit b2e6bfd

File tree

3 files changed

+23
-30
lines changed

3 files changed

+23
-30
lines changed

src/main/components/EditorParseListener.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,16 +7,16 @@ const PARSE_DEBOUNCE_MS = 600;
77

88
export const EditorParseListener: React.FC = () => {
99
const text = useSelector(selectEditorText);
10-
const { getClient, status, prepared } = usePyodideWorker();
10+
const { getClient, workerState } = usePyodideWorker();
1111
const timeoutRef = useRef<number | null>(null);
1212

1313
useEffect(() => {
1414
const client = getClient();
15+
const status = workerState.status;
1516

1617
if (
1718
!client ||
1819
status !== "ready" ||
19-
!prepared ||
2020
text.trim().length === 0
2121
) {
2222
return;
@@ -42,7 +42,7 @@ export const EditorParseListener: React.FC = () => {
4242
timeoutRef.current = null;
4343
}
4444
};
45-
}, [getClient, prepared, status, text]);
45+
}, [getClient, text, workerState]);
4646

4747
return null;
4848
};

src/main/components/layout.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,16 +65,17 @@ const json: IJsonModel = {
6565
const model = Model.fromJson(json);
6666

6767
const LayoutWrapper = () => {
68-
const { status, getClient, prepared } = usePyodideWorker();
68+
const { workerState, getClient } = usePyodideWorker();
6969

7070
const factory = (node: TabNode) => {
7171
const component = node.getComponent();
7272
const client = getClient();
73+
const status = workerState.status;
7374
if (component === "terminal") {
7475
if (!client || status === "error") {
7576
return <div className="p-3">Pyodide failed to start.</div>;
7677
}
77-
if (!prepared || status !== "ready") {
78+
if (status !== "ready") {
7879
return <div className="p-3">Pyodide is starting...</div>;
7980
}
8081
return <PlaygroundTerminal client={client} />;

src/main/hooks/usePyodideWorker.tsx

Lines changed: 17 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -10,25 +10,23 @@ import React, {
1010
import { wrap, Remote } from "comlink";
1111
import { MyWorker } from "../../pyodide-worker/worker";
1212

13-
type PyodideWorkerStatus =
14-
| "idle"
15-
| "starting"
16-
| "preparing"
17-
| "ready"
18-
| "error";
13+
type WorkerState =
14+
| { status: "idle" }
15+
| { status: "starting" }
16+
| { status: "preparing" }
17+
| { status: "ready" }
18+
| { status: "error"; error: Error };
1919

2020
export type BitbakeSpec = {
2121
version: string;
2222
url?: string;
2323
};
2424

2525
type PyodideWorkerContextValue = {
26-
status: PyodideWorkerStatus;
26+
workerState: WorkerState;
2727
getClient: () => Remote<MyWorker> | null;
28-
error: Error | null;
2928
bitbakeSpec: BitbakeSpec;
3029
bitbakeZipUrl: string;
31-
prepared: boolean;
3230
};
3331

3432
const DEFAULT_BITBAKE_VERSION = "2.8.0";
@@ -61,9 +59,9 @@ export const PyodideWorkerProvider: React.FC<{
6159
[normalizedSpec]
6260
);
6361

64-
const [status, setStatus] = useState<PyodideWorkerStatus>("idle");
65-
const [error, setError] = useState<Error | null>(null);
66-
const [prepared, setPrepared] = useState<boolean>(false);
62+
const [workerState, setWorkerState] = useState<WorkerState>({
63+
status: "idle",
64+
});
6765

6866
const workerRef = useRef<Worker | null>(null);
6967
const clientRef = useRef<Remote<MyWorker> | null>(null);
@@ -72,8 +70,7 @@ export const PyodideWorkerProvider: React.FC<{
7270
let cancelled = false;
7371

7472
const setup = async () => {
75-
setStatus("starting");
76-
setError(null);
73+
setWorkerState({ status: "starting" });
7774
clientRef.current = null;
7875

7976
const worker = new Worker(
@@ -91,24 +88,21 @@ export const PyodideWorkerProvider: React.FC<{
9188
}
9289

9390
clientRef.current = api;
94-
setStatus("preparing");
95-
setPrepared(false);
91+
setWorkerState({ status: "preparing" });
9692

9793
await api.prepareBitbake(bitbakeZipUrl, normalizedSpec.version);
9894

9995
if (cancelled) {
10096
worker.terminate();
10197
return;
10298
}
103-
setPrepared(true);
104-
setStatus("ready");
99+
setWorkerState({ status: "ready" });
105100
} catch (err) {
106101
if (cancelled) {
107102
return;
108103
}
109104
clientRef.current = null;
110-
setError(err as Error);
111-
setStatus("error");
105+
setWorkerState({ status: "error", error: err as Error });
112106
}
113107
};
114108

@@ -119,22 +113,20 @@ export const PyodideWorkerProvider: React.FC<{
119113
workerRef.current?.terminate();
120114
workerRef.current = null;
121115
clientRef.current = null;
122-
setPrepared(false);
116+
setWorkerState({ status: "idle" });
123117
};
124118
}, [bitbakeZipUrl, normalizedSpec.version]);
125119

126120
const getClient = useCallback(() => clientRef.current, []);
127121

128122
const value = useMemo<PyodideWorkerContextValue>(
129123
() => ({
130-
status,
124+
workerState,
131125
getClient,
132-
error,
133126
bitbakeSpec: normalizedSpec,
134127
bitbakeZipUrl,
135-
prepared,
136128
}),
137-
[bitbakeZipUrl, error, getClient, normalizedSpec, prepared, status]
129+
[bitbakeZipUrl, getClient, normalizedSpec, workerState]
138130
);
139131

140132
return (

0 commit comments

Comments
 (0)