Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions bin/commands/generate.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,7 @@ export default {
await runGenerators({
generators: opts.target,
input: opts.input,
ignore: opts.ignore,
output: opts.output && resolve(opts.output),
version: coerce(opts.version),
releases: await parseChangelog(opts.changelog),
Expand Down
26 changes: 13 additions & 13 deletions npm-shrinkwrap.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@
"lightningcss": "^1.30.2",
"mdast-util-slice-markdown": "^2.0.1",
"piscina": "^5.1.4",
"preact": "^10.28.0",
"preact": "^11.0.0-beta.0",
"preact-render-to-string": "^6.6.3",
"reading-time": "^1.5.0",
"recma-jsx": "^1.0.1",
Expand Down
10 changes: 7 additions & 3 deletions src/generators/ast-js/index.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -56,12 +56,16 @@ export default {
* @param {Partial<GeneratorOptions>} options
* @returns {AsyncGenerator<Output>}
*/
async *generate(_, { input = [], worker }) {
const source = globSync(input).filter(path => extname(path) === '.js');
async *generate(_, { input = [], ignore = [], worker }) {
const toIgnore = globSync(ignore);

const files = globSync(input)
.filter(path => extname(path) === '.js')
.filter(path => !toIgnore.includes(path));

// Parse the Javascript sources into ASTs in parallel using worker threads
// source is both the items list and the fullInput since we use sliceInput
for await (const chunkResult of worker.stream(source, source)) {
for await (const chunkResult of worker.stream(files, files)) {
yield chunkResult;
}
},
Expand Down
10 changes: 7 additions & 3 deletions src/generators/ast/index.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -55,14 +55,18 @@ export default {
},

/**
* Generates AST trees from markdown input files.
* Generates AST trees from markdown input fileAs.
*
* @param {Input} _ - Unused (top-level generator)
* @param {Partial<GeneratorOptions>} options
* @returns {AsyncGenerator<Output>}
*/
async *generate(_, { input = [], worker }) {
const files = globSync(input).filter(path => extname(path) === '.md');
async *generate(_, { input = [], ignore = [], worker }) {
const toIgnore = globSync(ignore);

const files = globSync(input)
.filter(path => extname(path) === '.md')
.filter(path => !toIgnore.includes(path));

// Parse markdown files in parallel using worker threads
for await (const chunkResult of worker.stream(files, files)) {
Expand Down
22 changes: 20 additions & 2 deletions src/generators/legacy-json-all/index.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ export default {
* @param {Partial<GeneratorOptions>} options
* @returns {Promise<Output>}
*/
async generate(input, { output }) {
async generate(input, { output, index }) {
/**
* The consolidated output object that will contain
* combined data from all sections in the input.
Expand All @@ -49,8 +49,26 @@ export default {
*/
const propertiesToCopy = Object.keys(generatedValue);

// Create a map of api name to index position for sorting
const indexOrder = new Map(
index?.map(({ api }, position) => [`doc/api/${api}.md`, position]) ?? []
);

// Sort input by index order (documents not in index go to the end)
const sortedInput = [...input].sort((a, b) => {
const aOrder = indexOrder.get(a.source) ?? Infinity;
const bOrder = indexOrder.get(b.source) ?? Infinity;

return aOrder - bOrder;
});

// Aggregate all sections into the output
for (const section of input) {
for (const section of sortedInput) {
// Skip index.json - it has no useful content, just navigation
if (section.api === 'index') {
continue;
}

for (const property of propertiesToCopy) {
const items = section[property];

Expand Down
11 changes: 8 additions & 3 deletions src/generators/legacy-json/utils/buildSection.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -45,12 +45,14 @@ export const createSectionBuilder = () => {
removed_in = [],
changes,
}) => {
const meta = { changes };
const meta = {};

if (added_in?.length) {
meta.added = enforceArray(added_in);
}

meta.changes = changes;

if (n_api_version?.length) {
meta.napiVersion = enforceArray(n_api_version);
}
Expand Down Expand Up @@ -81,8 +83,8 @@ export const createSectionBuilder = () => {
const section = {
textRaw: transformNodesToString(head.children),
name: head.data.name,
type: head.data.type,
introduced_in: entry.introduced_in,
type: head.data.type,
};

const meta = createMeta(entry);
Expand Down Expand Up @@ -135,8 +137,11 @@ export const createSectionBuilder = () => {
* @param {import('../../types.d.ts').NodeWithData} heading - The heading node of the section.
*/
const addAdditionalMetadata = (section, parent, heading) => {
if (!section.type) {
if (!section.type || section.type === 'module') {
section.name = section.textRaw.toLowerCase().trim().replace(/\s+/g, '_');
}

if (!section.type) {
section.displayName = heading.data.name;
section.type = parent.type === 'misc' ? 'misc' : 'module';
}
Expand Down
3 changes: 3 additions & 0 deletions src/generators/types.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@ declare global {
// be a glob when passed to a generator.
input: string | string[];

// The path or glob patterns used to ignore files from the input source files.
ignore?: string | string[];

// The path used to output generated files, this is to be considered
// the base path that any generator will use for generating files
// This parameter accepts globs but when passed to generators will contain
Expand Down
5 changes: 1 addition & 4 deletions src/generators/web/utils/generate.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -88,8 +88,5 @@ export default () => {
].join('\n');
};

return {
buildClientProgram,
buildServerProgram,
};
return { buildClientProgram, buildServerProgram };
};
16 changes: 11 additions & 5 deletions src/generators/web/utils/processing.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { randomUUID } from 'node:crypto';

import HTMLMinifier from '@minify-html/node';
import { jsx, toJs } from 'estree-util-to-js';
import { transform } from 'lightningcss';

import { SPECULATION_RULES } from '../constants.mjs';
import bundleCode from './bundle.mjs';
Expand Down Expand Up @@ -48,13 +49,13 @@ export function convertJSXToCode(
*
* @param {Map<string, string>} serverCodeMap - Map of fileName to server-side JavaScript code.
* @param {ReturnType<import('node:module').createRequire>} requireFn - Node.js require function for external packages.
* @returns {Promise<Map<string, string>>} Map of fileName to dehydrated (server-rendered) HTML content.
* @returns {{ pages: Map<string, string>, css: string }} Map of fileName to dehydrated (server-rendered) HTML content.
*/
export async function executeServerCode(serverCodeMap, requireFn) {
const dehydratedMap = new Map();

// Bundle all server-side code, which may produce code-split chunks
const { chunks } = await bundleCode(serverCodeMap, { server: true });
const { chunks, css } = await bundleCode(serverCodeMap, { server: true });

const entryChunks = chunks.filter(c => c.isEntry);
const otherChunks = chunks.filter(c => !c.isEntry);
Expand All @@ -71,7 +72,7 @@ export async function executeServerCode(serverCodeMap, requireFn) {
dehydratedMap.set(chunk.fileName, executedFunction(enhancedRequire));
}

return dehydratedMap;
return { pages: dehydratedMap, css };
}

/**
Expand Down Expand Up @@ -115,7 +116,7 @@ export async function processJSXEntries(
// Replace template placeholders with actual content
const renderedHtml = template
.replace('{{title}}', `${heading.data.name} | ${titleSuffix}`)
.replace('{{dehydrated}}', serverBundle.get(fileName) ?? '')
.replace('{{dehydrated}}', serverBundle.pages.get(fileName) ?? '')
.replace('{{importMap}}', clientBundle.importMap ?? '')
.replace('{{entrypoint}}', `./${fileName}?${randomUUID()}`)
.replace('{{speculationRules}}', speculationRulesString);
Expand All @@ -126,5 +127,10 @@ export async function processJSXEntries(
return { html: finalHTMLBuffer, api };
});

return { results, ...clientBundle };
const { code: minifiedCSS } = transform({
code: Buffer.from(`${serverBundle.css}\n${clientBundle.css}`),
minify: true,
});

return { results, chunks: clientBundle.chunks, css: minifiedCSS };
}
Loading