@@ -52,63 +52,63 @@ export default {
5252
5353 dependsOn : 'metadata' ,
5454
55- /**
56- * Process a chunk of items in a worker thread.
57- * Builds HTML template objects - FS operations happen in generate().
58- *
59- * @param {Input } fullInput - Full metadata input for context rebuilding
60- * @param {number[] } itemIndices - Indices of head nodes to process
61- * @param {Partial<Omit<GeneratorOptions, 'worker'>> } options - Serializable options
62- * @returns {Promise<TemplateValues[]> } Template objects for each processed module
63- */
64- async processChunk ( fullInput , itemIndices , { version, parsedSideNav } ) {
65- const groupedModules = groupNodesByModule ( fullInput ) ;
66-
67- const headNodes = fullInput
68- . filter ( node => node . heading . depth === 1 )
69- . sort ( ( a , b ) => a . heading . data . name . localeCompare ( b . heading . data . name ) ) ;
70-
71- const results = [ ] ;
72-
73- for ( const idx of itemIndices ) {
74- const head = headNodes [ idx ] ;
75- const nodes = groupedModules . get ( head . api ) ;
76-
77- const activeSideNav = String ( parsedSideNav ) . replace (
78- `class="nav-${ head . api } ` ,
79- `class="nav-${ head . api } active`
80- ) ;
81-
82- const parsedToC = remarkRehypeProcessor . processSync (
83- tableOfContents ( nodes , {
84- maxDepth : 4 ,
85- parser : tableOfContents . parseToCNode ,
86- } )
87- ) ;
88-
89- const parsedContent = buildContent (
90- headNodes ,
91- nodes ,
92- remarkRehypeProcessor
93- ) ;
94-
95- const apiAsHeading = head . api . charAt ( 0 ) . toUpperCase ( ) + head . api . slice ( 1 ) ;
96-
97- const template = {
98- api : head . api ,
99- added : head . introduced_in ?? '' ,
100- section : head . heading . data . name || apiAsHeading ,
101- version : `v${ version . version } ` ,
102- toc : String ( parsedToC ) ,
103- nav : String ( activeSideNav ) ,
104- content : parsedContent ,
105- } ;
106-
107- results . push ( template ) ;
108- }
55+ processChunk : Object . assign (
56+ /**
57+ * Process a chunk of items in a worker thread.
58+ * Builds HTML template objects - FS operations happen in generate().
59+ *
60+ * With sliceInput, each item is pre-grouped {head, nodes, headNodes} - no need to
61+ * recompute groupNodesByModule for every chunk.
62+ *
63+ * @param {Array<{head: ApiDocMetadataEntry, nodes: ApiDocMetadataEntry[], headNodes: ApiDocMetadataEntry[]}> } slicedInput - Pre-sliced module data
64+ * @param {number[] } itemIndices - Indices into the sliced array
65+ * @param {{version: string, parsedSideNav: string} } options - Dependencies passed from generate()
66+ * @returns {Promise<TemplateValues[]> } Template objects for each processed module
67+ */
68+ async ( slicedInput , itemIndices , { version, parsedSideNav } ) => {
69+ const results = [ ] ;
70+
71+ for ( const idx of itemIndices ) {
72+ const { head, nodes, headNodes } = slicedInput [ idx ] ;
73+
74+ const activeSideNav = String ( parsedSideNav ) . replace (
75+ `class="nav-${ head . api } ` ,
76+ `class="nav-${ head . api } active`
77+ ) ;
78+
79+ const parsedToC = remarkRehypeProcessor . processSync (
80+ tableOfContents ( nodes , {
81+ maxDepth : 4 ,
82+ parser : tableOfContents . parseToCNode ,
83+ } )
84+ ) ;
85+
86+ const parsedContent = buildContent (
87+ headNodes ,
88+ nodes ,
89+ remarkRehypeProcessor
90+ ) ;
91+
92+ const apiAsHeading =
93+ head . api . charAt ( 0 ) . toUpperCase ( ) + head . api . slice ( 1 ) ;
94+
95+ const template = {
96+ api : head . api ,
97+ added : head . introduced_in ?? '' ,
98+ section : head . heading . data . name || apiAsHeading ,
99+ version : `v${ version . version } ` ,
100+ toc : String ( parsedToC ) ,
101+ nav : String ( activeSideNav ) ,
102+ content : parsedContent ,
103+ } ;
104+
105+ results . push ( template ) ;
106+ }
109107
110- return results ;
111- } ,
108+ return results ;
109+ } ,
110+ { sliceInput : true }
111+ ) ,
112112
113113 /**
114114 * Generates the legacy version of the API docs in HTML
@@ -121,6 +121,8 @@ export default {
121121
122122 const apiTemplate = await readFile ( join ( baseDir , 'template.html' ) , 'utf-8' ) ;
123123
124+ const groupedModules = groupNodesByModule ( input ) ;
125+
124126 const headNodes = input
125127 . filter ( node => node . heading . depth === 1 )
126128 . sort ( ( a , b ) => a . heading . data . name . localeCompare ( b . heading . data . name ) ) ;
@@ -136,6 +138,14 @@ export default {
136138 } )
137139 ) ;
138140
141+ // Create sliced input: each item contains head + its module's entries + headNodes reference
142+ // This avoids sending all ~4900 entries to every worker and recomputing groupings
143+ const slicedInput = headNodes . map ( head => ( {
144+ head,
145+ nodes : groupedModules . get ( head . api ) ,
146+ headNodes,
147+ } ) ) ;
148+
139149 const deps = {
140150 version,
141151 parsedSideNav : String ( parsedSideNav ) ,
@@ -156,7 +166,11 @@ export default {
156166 }
157167
158168 // Stream chunks as they complete - HTML files are written immediately
159- for await ( const chunkResult of worker . stream ( headNodes , input , deps ) ) {
169+ for await ( const chunkResult of worker . stream (
170+ slicedInput ,
171+ slicedInput ,
172+ deps
173+ ) ) {
160174 // Write files for this chunk in the generate method (main thread)
161175 if ( output ) {
162176 for ( const template of chunkResult ) {
0 commit comments