@@ -3,6 +3,7 @@ import { WorkerPoolManager } from "@pierre/diffs/worker";
33import DiffsWorker from "@pierre/diffs/worker/worker.js?worker" ;
44import * as Schema from "effect/Schema" ;
55import { useEffect , useState , useSyncExternalStore , type ReactNode } from "react" ;
6+ import { useStableCallback } from "../hooks/useStableCallback" ;
67import { useTheme } from "../hooks/useTheme" ;
78import { resolveDiffThemeName , type DiffThemeName } from "../lib/diffRendering" ;
89import { PREFERRED_HIGHLIGHTER } from "../lib/syntaxHighlighting" ;
@@ -18,11 +19,11 @@ export class DiffWorkerError extends Schema.TaggedError<DiffWorkerError>()("Diff
1819}
1920
2021const DIFF_WORKER_IDLE_TTL_MS = 30_000 ;
21- const DIFF_WORKER_POOL_SIZE = ( ( ) => {
22+ function resolveDiffWorkerPoolSize ( ) {
2223 const cores =
2324 typeof navigator === "undefined" ? 4 : Math . max ( 1 , navigator . hardwareConcurrency || 4 ) ;
2425 return Math . max ( 2 , Math . min ( 6 , Math . floor ( cores / 2 ) ) ) ;
25- } ) ( ) ;
26+ }
2627let sharedWorkerPool :
2728 | {
2829 readonly pool : WorkerPoolManager ;
@@ -127,21 +128,24 @@ function DiffWorkerReady({ children }: { children?: ReactNode }) {
127128export function DiffWorkerPoolProvider ( { children } : { children ?: ReactNode } ) {
128129 const { resolvedTheme } = useTheme ( ) ;
129130 const diffThemeName = resolveDiffThemeName ( resolvedTheme ) ;
131+ const [ workerPoolSize ] = useState ( resolveDiffWorkerPoolSize ) ;
132+ // A new subscribe identity makes React release and reacquire the shared pool on every render.
133+ const subscribe = useStableCallback ( ( onStoreChange : ( ) => void ) => {
134+ if ( typeof window === "undefined" ) return ( ) => { } ;
135+ const entry = acquireDiffWorkerPool ( diffThemeName , workerPoolSize ) ;
136+ onStoreChange ( ) ;
137+ return ( ) => {
138+ entry . consumers -= 1 ;
139+ if ( entry . consumers !== 0 ) return ;
140+ entry . idleTimer = setTimeout ( ( ) => {
141+ entry . idleTimer = undefined ;
142+ entry . pool . terminate ( ) ;
143+ if ( sharedWorkerPool === entry ) sharedWorkerPool = undefined ;
144+ } , DIFF_WORKER_IDLE_TTL_MS ) ;
145+ } ;
146+ } ) ;
130147 const workerPool = useSyncExternalStore (
131- ( onStoreChange ) => {
132- if ( typeof window === "undefined" ) return ( ) => { } ;
133- const entry = acquireDiffWorkerPool ( diffThemeName , DIFF_WORKER_POOL_SIZE ) ;
134- onStoreChange ( ) ;
135- return ( ) => {
136- entry . consumers -= 1 ;
137- if ( entry . consumers !== 0 ) return ;
138- entry . idleTimer = setTimeout ( ( ) => {
139- entry . idleTimer = undefined ;
140- entry . pool . terminate ( ) ;
141- if ( sharedWorkerPool === entry ) sharedWorkerPool = undefined ;
142- } , DIFF_WORKER_IDLE_TTL_MS ) ;
143- } ;
144- } ,
148+ subscribe ,
145149 ( ) => sharedWorkerPool ?. pool ,
146150 ( ) => undefined ,
147151 ) ;
0 commit comments