/ proof-of-concept / plate-dynamics-lab
Sign in
proof-of-concept / plate-dynamics-lab
plate-dynamics-lab / packages / components / src / hooks / RunnerContext.tsx
28 lines · 1.1 KBBlameHistoryRaw
1import { createContext, useContext, useEffect, useRef, type ReactNode } from "react";
2import { WorkerRunner, type Runner } from "@plate-dyn/core";
4const RunnerContext = createContext<Runner | null>(null);
6/**
7 * Provides one numbl runner to a tree of components. By default a WorkerRunner
8 * is created lazily; pass `runner` to share or substitute one.
9 */
10export function RunnerProvider({ children, runner }: { children: ReactNode; runner?: Runner }) {
11 const ref = useRef<Runner | null>(null);
12 if (!ref.current) ref.current = runner ?? new WorkerRunner();
13 useEffect(() => {
14 const r = ref.current;
15 return () => {
16 // Dispose terminates the worker; the runner recreates one on the next run,
17 // so React StrictMode's mount-unmount-mount cycle is harmless.
18 r?.dispose();
19 };
20 }, []);
21 return <RunnerContext.Provider value={ref.current}>{children}</RunnerContext.Provider>;
24export function useRunner(): Runner {
25 const r = useContext(RunnerContext);
26 if (!r) throw new Error("useRunner must be used inside a RunnerProvider");
27 return r;
↑↓ move↵openescclose