Skip to content

Commit 8292801

Browse files
committed
chore: slice input approach on legacy-html
1 parent 583564a commit 8292801

File tree

1 file changed

+71
-57
lines changed

1 file changed

+71
-57
lines changed

src/generators/legacy-html/index.mjs

Lines changed: 71 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)