import { WorkerPoolContextProvider, useWorkerPool } from "@pierre/diffs/react"; import DiffsWorker from "@pierre/diffs/worker/worker.js?worker"; import * as Schema from "effect/Schema"; import { useEffect, useMemo, type ReactNode } from "react"; import { useTheme } from "../hooks/useTheme"; import { resolveDiffThemeName, type DiffThemeName } from "../lib/diffRendering"; export class DiffWorkerError extends Schema.TaggedErrorClass()("DiffWorkerError", { operation: Schema.Literals(["create-worker", "get-render-options", "set-render-options"]), themeName: Schema.Literals(["pierre-light", "pierre-dark"]), cause: Schema.Defect(), }) { override get message(): string { return `Diff worker operation ${this.operation} failed for theme ${this.themeName}.`; } } function DiffWorkerThemeSync({ themeName }: { themeName: DiffThemeName }) { const workerPool = useWorkerPool(); useEffect(() => { if (!workerPool) { return; } let operation: DiffWorkerError["operation"] = "get-render-options"; void (async () => { try { const current = workerPool.getDiffRenderOptions(); if (current.theme === themeName) { return; } operation = "set-render-options"; await workerPool.setRenderOptions({ ...current, theme: themeName, }); } catch (cause) { console.error(new DiffWorkerError({ operation, themeName, cause })); } })(); }, [themeName, workerPool]); return null; } export function DiffWorkerPoolProvider({ children }: { children?: ReactNode }) { const { resolvedTheme } = useTheme(); const diffThemeName = resolveDiffThemeName(resolvedTheme); const workerPoolSize = useMemo(() => { const cores = typeof navigator === "undefined" ? 4 : Math.max(1, navigator.hardwareConcurrency || 4); return Math.max(2, Math.min(6, Math.floor(cores / 2))); }, []); return ( { try { return new DiffsWorker(); } catch (cause) { throw new DiffWorkerError({ operation: "create-worker", themeName: diffThemeName, cause, }); } }, poolSize: workerPoolSize, totalASTLRUCacheSize: 240, }} highlighterOptions={{ theme: diffThemeName, tokenizeMaxLineLength: 1_000, useTokenTransformer: true, }} > {children} ); }