From 4ee0c11c5a645c1ab8ff4d031dbb63e8172f711d Mon Sep 17 00:00:00 2001 From: Aviv Keller Date: Mon, 30 Mar 2026 10:49:08 -0400 Subject: [PATCH 1/2] chore(remark): reduce drilling --- src/generators/ast/generate.mjs | 6 +- .../utils/__tests__/buildContent.test.mjs | 6 +- .../jsx-ast/utils/__tests__/types.test.mjs | 58 ++++++++++--------- src/generators/jsx-ast/utils/buildContent.mjs | 49 +++++----------- src/generators/jsx-ast/utils/signature.mjs | 5 +- src/generators/jsx-ast/utils/types.mjs | 16 +++-- src/generators/legacy-html-all/generate.mjs | 7 +-- src/generators/legacy-html/generate.mjs | 10 ++-- .../legacy-html/utils/buildContent.mjs | 25 +++----- .../legacy-json/utils/buildSection.mjs | 8 +-- src/generators/metadata/utils/parse.mjs | 7 +-- src/generators/metadata/utils/visitors.mjs | 4 +- src/utils/remark.mjs | 21 ++++--- 13 files changed, 95 insertions(+), 127 deletions(-) diff --git a/src/generators/ast/generate.mjs b/src/generators/ast/generate.mjs index 97724e03..e0c5a6c5 100644 --- a/src/generators/ast/generate.mjs +++ b/src/generators/ast/generate.mjs @@ -10,9 +10,7 @@ import { STABILITY_INDEX_URL } from './constants.mjs'; import getConfig from '../../utils/configuration/index.mjs'; import { withExt } from '../../utils/file.mjs'; import { QUERIES } from '../../utils/queries/index.mjs'; -import { getRemark } from '../../utils/remark.mjs'; - -const remarkProcessor = getRemark(); +import { getRemark as remark } from '../../utils/remark.mjs'; /** * Process a chunk of markdown files in a worker thread. @@ -40,7 +38,7 @@ export async function processChunk(inputSlice, itemIndices) { const relativePath = sep + withExt(relative(parent, path)); results.push({ - tree: remarkProcessor.parse(value), + tree: remark().parse(value), // The path is the relative path minus the extension path: relativePath, }); diff --git a/src/generators/jsx-ast/utils/__tests__/buildContent.test.mjs b/src/generators/jsx-ast/utils/__tests__/buildContent.test.mjs index 5166a319..afb86405 100644 --- a/src/generators/jsx-ast/utils/__tests__/buildContent.test.mjs +++ b/src/generators/jsx-ast/utils/__tests__/buildContent.test.mjs @@ -29,7 +29,7 @@ describe('transformHeadingNode (deprecation Type -> AlertBox level)', () => { const parent = makeParent('Documentation'); const node = parent.children[0]; - transformHeadingNode(entry, {}, node, 0, parent); + transformHeadingNode(entry, node, 0, parent); const alert = parent.children[1]; const levelAttr = alert.attributes.find(a => a.name === 'level'); @@ -43,7 +43,7 @@ describe('transformHeadingNode (deprecation Type -> AlertBox level)', () => { const parent = makeParent('Runtime'); const node = parent.children[0]; - transformHeadingNode(entry, {}, node, 0, parent); + transformHeadingNode(entry, node, 0, parent); const alert = parent.children[1]; const levelAttr = alert.attributes.find(a => a.name === 'level'); @@ -57,7 +57,7 @@ describe('transformHeadingNode (deprecation Type -> AlertBox level)', () => { const parent = makeParent('SomeOtherThing'); const node = parent.children[0]; - transformHeadingNode(entry, {}, node, 0, parent); + transformHeadingNode(entry, node, 0, parent); const alert = parent.children[1]; const levelAttr = alert.attributes.find(a => a.name === 'level'); diff --git a/src/generators/jsx-ast/utils/__tests__/types.test.mjs b/src/generators/jsx-ast/utils/__tests__/types.test.mjs index 37caf401..b50c9810 100644 --- a/src/generators/jsx-ast/utils/__tests__/types.test.mjs +++ b/src/generators/jsx-ast/utils/__tests__/types.test.mjs @@ -1,19 +1,23 @@ import assert from 'node:assert/strict'; -import { describe, it } from 'node:test'; +import { describe, it, mock } from 'node:test'; + +// Mock remark +mock.module('../../../../utils/remark.mjs', { + namedExports: { + getRemarkRecma: () => ({ + runSync: () => ({ + body: [{ expression: 'mock-expression' }], + }), + }), + }, +}); -import { +const { classifyTypeNode, extractPropertyName, extractTypeAnnotations, parseListIntoProperties, -} from '../types.mjs'; - -// Mock remark processor for tests -const remark = { - runSync: () => ({ - body: [{ expression: 'mock-expression' }], - }), -}; +} = await import('../types.mjs'); describe('classifyTypeNode', () => { it('returns 2 for union separator text node', () => { @@ -183,7 +187,7 @@ describe('extractTypeAnnotations', () => { { type: 'text', value: ' description follows' }, ]; - const result = extractTypeAnnotations(nodes, remark); + const result = extractTypeAnnotations(nodes); assert.strictEqual(result, 'mock-expression'); assert.strictEqual(nodes.length, 1); @@ -204,7 +208,7 @@ describe('extractTypeAnnotations', () => { { type: 'text', value: ' description' }, ]; - const result = extractTypeAnnotations(nodes, remark); + const result = extractTypeAnnotations(nodes); assert.strictEqual(result, 'mock-expression'); assert.strictEqual(nodes.length, 1); @@ -220,7 +224,7 @@ describe('extractTypeAnnotations', () => { { type: 'text', value: ' | ' }, ]; - const result = extractTypeAnnotations(nodes, remark); + const result = extractTypeAnnotations(nodes); assert.strictEqual(result, 'mock-expression'); assert.strictEqual(nodes.length, 0); @@ -232,7 +236,7 @@ describe('extractTypeAnnotations', () => { { type: 'emphasis', children: [{ type: 'text', value: 'emphasized' }] }, ]; - const result = extractTypeAnnotations(nodes, remark); + const result = extractTypeAnnotations(nodes); assert.strictEqual(result, undefined); assert.strictEqual(nodes.length, 2); @@ -248,7 +252,7 @@ describe('extractTypeAnnotations', () => { { type: 'text', value: ' | ' }, // This shouldn't be consumed ]; - const result = extractTypeAnnotations(nodes, remark); + const result = extractTypeAnnotations(nodes); assert.strictEqual(result, 'mock-expression'); assert.strictEqual(nodes.length, 2); @@ -259,7 +263,7 @@ describe('extractTypeAnnotations', () => { it('handles empty nodes array', () => { const nodes = []; - const result = extractTypeAnnotations(nodes, remark); + const result = extractTypeAnnotations(nodes); assert.strictEqual(result, undefined); assert.strictEqual(nodes.length, 0); @@ -275,7 +279,7 @@ describe('extractTypeAnnotations', () => { { type: 'text', value: ' description' }, ]; - const result = extractTypeAnnotations(nodes, remark); + const result = extractTypeAnnotations(nodes); assert.strictEqual(result, 'mock-expression'); assert.strictEqual(nodes.length, 1); @@ -300,7 +304,7 @@ describe('parseListIntoProperties', () => { ], }; - const result = parseListIntoProperties(node, remark); + const result = parseListIntoProperties(node); assert.deepStrictEqual(result, [ { @@ -333,7 +337,7 @@ describe('parseListIntoProperties', () => { ], }; - const result = parseListIntoProperties(node, remark); + const result = parseListIntoProperties(node); assert.deepStrictEqual(result, [ { @@ -362,7 +366,7 @@ describe('parseListIntoProperties', () => { ], }; - const result = parseListIntoProperties(node, remark); + const result = parseListIntoProperties(node); assert.deepStrictEqual(result, [ { @@ -388,7 +392,7 @@ describe('parseListIntoProperties', () => { ], }; - const result = parseListIntoProperties(node, remark); + const result = parseListIntoProperties(node); assert.deepStrictEqual(result, [ { @@ -416,7 +420,7 @@ describe('parseListIntoProperties', () => { ], }; - const result = parseListIntoProperties(node, remark); + const result = parseListIntoProperties(node); assert.deepStrictEqual(result, [ { @@ -460,7 +464,7 @@ describe('parseListIntoProperties', () => { ], }; - const result = parseListIntoProperties(node, remark); + const result = parseListIntoProperties(node); assert.deepStrictEqual(result, [ { @@ -507,7 +511,7 @@ describe('parseListIntoProperties', () => { ], }; - const result = parseListIntoProperties(node, remark); + const result = parseListIntoProperties(node); assert.deepStrictEqual(result, [ { @@ -542,7 +546,7 @@ describe('parseListIntoProperties', () => { ], }; - const result = parseListIntoProperties(node, remark); + const result = parseListIntoProperties(node); assert.deepStrictEqual(result, [ { @@ -561,7 +565,7 @@ describe('parseListIntoProperties', () => { children: [], }; - const result = parseListIntoProperties(node, remark); + const result = parseListIntoProperties(node); assert.deepStrictEqual(result, []); }); @@ -605,7 +609,7 @@ describe('parseListIntoProperties', () => { ], }; - const result = parseListIntoProperties(node, remark); + const result = parseListIntoProperties(node); assert.deepStrictEqual(result, [ { children: [ diff --git a/src/generators/jsx-ast/utils/buildContent.mjs b/src/generators/jsx-ast/utils/buildContent.mjs index 3091e80d..c3dddbe8 100644 --- a/src/generators/jsx-ast/utils/buildContent.mjs +++ b/src/generators/jsx-ast/utils/buildContent.mjs @@ -30,13 +30,13 @@ import { populate, } from '../../../utils/configuration/templates.mjs'; import { UNIST } from '../../../utils/queries/index.mjs'; +import { getRemarkRecma as remark } from '../../../utils/remark.mjs'; /** * Processes lifecycle and change history data into a sorted array of change entries. * @param {import('../../metadata/types').MetadataEntry} entry - The metadata entry - * @param {import('unified').Processor} remark - The remark processor */ -export const gatherChangeEntries = (entry, remark) => { +export const gatherChangeEntries = entry => { // Lifecycle changes (e.g., added, deprecated) const lifecycleChanges = Object.entries(LIFECYCLE_LABELS) .filter(([field]) => entry[field]) @@ -48,7 +48,8 @@ export const gatherChangeEntries = (entry, remark) => { // Explicit changes with parsed JSX labels const explicitChanges = (entry.changes || []).map(change => ({ versions: enforceArray(change.version), - label: remark.runSync(remark.parse(change.description)).body[0].expression, + label: remark().runSync(remark().parse(change.description)).body[0] + .expression, url: change['pr-url'], })); @@ -58,10 +59,9 @@ export const gatherChangeEntries = (entry, remark) => { /** * Creates a JSX ChangeHistory element or returns null if no changes. * @param {import('../../metadata/types').MetadataEntry} entry - The metadata entry - * @param {import('unified').Processor} remark - The remark processor */ -export const createChangeElement = (entry, remark) => { - const changes = gatherChangeEntries(entry, remark); +export const createChangeElement = entry => { + const changes = gatherChangeEntries(entry); if (!changes.length) { return null; @@ -197,22 +197,15 @@ const getLevelFromDeprecationType = typeText => { /** * Transforms a heading node by injecting metadata, source links, and signatures. * @param {import('../../metadata/types').MetadataEntry} entry - The API metadata entry - * @param {import('unified').Processor} remark - The remark processor * @param {import('../../metadata/types').HeadingNode} node - The heading node to transform * @param {number} index - The index of the node in its parent's children array * @param {import('unist').Parent} parent - The parent node containing the heading */ -export const transformHeadingNode = async ( - entry, - remark, - node, - index, - parent -) => { +export const transformHeadingNode = async (entry, node, index, parent) => { // Replace heading node with our enhanced heading element parent.children[index] = createHeadingElement( node, - createChangeElement(entry, remark) + createChangeElement(entry) ); if (entry.api === 'deprecations' && node.depth === 3) { @@ -254,9 +247,8 @@ export const transformHeadingNode = async ( /** * Processes a single API documentation entry's content * @param {import('../../metadata/types').MetadataEntry} entry - The API metadata entry to process - * @param {import('unified').Processor} remark - The remark processor */ -export const processEntry = (entry, remark) => { +export const processEntry = entry => { // Deep copy content to avoid mutations on original const content = structuredClone(entry.content); @@ -265,15 +257,14 @@ export const processEntry = (entry, remark) => { // Visit and transform headings with metadata and links visit(content, UNIST.isHeading, (...args) => - transformHeadingNode(entry, remark, ...args) + transformHeadingNode(entry, ...args) ); // Transform typed lists into property tables visit( content, UNIST.isStronglyTypedList, - (node, idx, parent) => - (parent.children[idx] = createSignatureTable(node, remark)) + (node, idx, parent) => (parent.children[idx] = createSignatureTable(node)) ); return content; @@ -284,19 +275,13 @@ export const processEntry = (entry, remark) => { * @param {Array} entries - API documentation metadata entries * @param {ReturnType} sideBarProps - Props for the sidebar component * @param {ReturnType} metaBarProps - Props for the meta bar component - * @param {import('unified').Processor} remark - The remark processor */ -export const createDocumentLayout = ( - entries, - sideBarProps, - metaBarProps, - remark -) => +export const createDocumentLayout = (entries, sideBarProps, metaBarProps) => createTree('root', [ createJSXElement(JSX_IMPORTS.Layout.name, { sideBarProps, metaBarProps, - children: entries.map(entry => processEntry(entry, remark)), + children: entries.map(processEntry), }), ]); @@ -307,10 +292,9 @@ export const createDocumentLayout = ( * @param {Array} metadataEntries - API documentation metadata entries * @param {import('../../metadata/types').MetadataEntry} head - Main API metadata entry with version information * @param {Object} sideBarProps - Props for the sidebar component - * @param {import('unified').Processor} remark - Remark processor instance for markdown processing * @returns {Promise} */ -const buildContent = async (metadataEntries, head, sideBarProps, remark) => { +const buildContent = async (metadataEntries, head, sideBarProps) => { // Build props for the MetaBar from head and entries const metaBarProps = buildMetaBarProps(head, metadataEntries); @@ -318,12 +302,11 @@ const buildContent = async (metadataEntries, head, sideBarProps, remark) => { const root = createDocumentLayout( metadataEntries, sideBarProps, - metaBarProps, - remark + metaBarProps ); // Run remark processor to transform AST (parse markdown, plugins, etc.) - const ast = await remark.run(root); + const ast = await remark().run(root); // The final MDX content is the expression in the Program's first body node return { ...ast.body[0].expression, data: head }; diff --git a/src/generators/jsx-ast/utils/signature.mjs b/src/generators/jsx-ast/utils/signature.mjs index 4d8df94e..42d4cf4b 100644 --- a/src/generators/jsx-ast/utils/signature.mjs +++ b/src/generators/jsx-ast/utils/signature.mjs @@ -135,10 +135,9 @@ export const insertSignatureCodeBlock = ({ children }, { data }, idx) => { * Renders a table of properties based on parsed metadata from a Markdown list. * * @param {import('mdast').List} node - * @param {import('unified').Processor} remark - The remark processor */ -export const createSignatureTable = (node, remark) => { - const items = parseListIntoProperties(node, remark); +export const createSignatureTable = node => { + const items = parseListIntoProperties(node); return createJSXElement(JSX_IMPORTS.FunctionSignature.name, { title: items.length === 1 && 'kind' in items[0] ? null : 'Attributes', diff --git a/src/generators/jsx-ast/utils/types.mjs b/src/generators/jsx-ast/utils/types.mjs index 3b9c14dd..d16ec1a5 100644 --- a/src/generators/jsx-ast/utils/types.mjs +++ b/src/generators/jsx-ast/utils/types.mjs @@ -1,6 +1,7 @@ import { u as createTree } from 'unist-builder'; import { QUERIES, UNIST } from '../../../utils/queries/index.mjs'; +import { getRemarkRecma as remark } from '../../../utils/remark.mjs'; import { transformNodesToString } from '../../../utils/unist.mjs'; import { DEFAULT_EXPRESSION } from '../../legacy-json/constants.mjs'; import { TRIMMABLE_PADDING_REGEX } from '../constants.mjs'; @@ -87,9 +88,8 @@ export const extractPropertyName = (nodes, current) => { * separators) from the front of `nodes` and updates the current object. * * @param {Array} nodes - * @param {import('unified').Processor} remark - The remark processor */ -export const extractTypeAnnotations = (nodes, remark) => { +export const extractTypeAnnotations = nodes => { const types = []; while (nodes.length) { @@ -107,7 +107,7 @@ export const extractTypeAnnotations = (nodes, remark) => { } if (types.length > 0) { - return remark.runSync(createTree('root', types)).body[0].expression; + return remark().runSync(createTree('root', types)).body[0].expression; } }; @@ -115,9 +115,8 @@ export const extractTypeAnnotations = (nodes, remark) => { * Parses each list item into a structured property descriptor * * @param {import('mdast').List} node - * @param {import('unified').Processor} remark - The remark processor */ -export const parseListIntoProperties = (node, remark) => +export const parseListIntoProperties = node => node?.children.map(item => { const [{ children }, ...rest] = item.children; const current = {}; @@ -127,7 +126,7 @@ export const parseListIntoProperties = (node, remark) => // Strip stale whitespace left over after name extraction shiftIfBlankText(children); - current.type = extractTypeAnnotations(children, remark); + current.type = extractTypeAnnotations(children); if (children.length > 0) { children[0].value &&= children[0].value.replace( @@ -139,14 +138,13 @@ export const parseListIntoProperties = (node, remark) => transformNodesToString(children) ); - current.description = remark.runSync( + current.description = remark().runSync( createTree('root', children) ).body[0].expression; } current.children = parseListIntoProperties( - rest.find(UNIST.isLooselyTypedList), - remark + rest.find(UNIST.isLooselyTypedList) ); return current; diff --git a/src/generators/legacy-html-all/generate.mjs b/src/generators/legacy-html-all/generate.mjs index ad4e2ca1..1aa7bfdf 100644 --- a/src/generators/legacy-html-all/generate.mjs +++ b/src/generators/legacy-html-all/generate.mjs @@ -5,7 +5,7 @@ import { join } from 'node:path'; import getConfig from '../../utils/configuration/index.mjs'; import { minifyHTML } from '../../utils/html-minifier.mjs'; -import { getRemarkRehype } from '../../utils/remark.mjs'; +import { getRemarkRehype as remark } from '../../utils/remark.mjs'; import { replaceTemplateValues } from '../legacy-html/utils/replaceTemplateValues.mjs'; import tableOfContents from '../legacy-html/utils/tableOfContents.mjs'; @@ -17,9 +17,6 @@ import tableOfContents from '../legacy-html/utils/tableOfContents.mjs'; export async function generate(input) { const config = getConfig('legacy-html-all'); - // Gets a Remark Processor that parses Markdown to minified HTML - const remarkWithRehype = getRemarkRehype(); - // Reads the API template.html file to be used as a base for the HTML files const apiTemplate = await readFile(config.templatePath, 'utf-8'); @@ -40,7 +37,7 @@ export async function generate(input) { })); // Generates the global Table of Contents (Sidebar Navigation) - const parsedSideNav = remarkWithRehype.processSync( + const parsedSideNav = remark().processSync( tableOfContents(sideNavigationFromValues, { maxDepth: 1, parser: tableOfContents.parseNavigationNode, diff --git a/src/generators/legacy-html/generate.mjs b/src/generators/legacy-html/generate.mjs index cff2698d..a6a9de4e 100644 --- a/src/generators/legacy-html/generate.mjs +++ b/src/generators/legacy-html/generate.mjs @@ -10,7 +10,7 @@ import getConfig from '../../utils/configuration/index.mjs'; import { writeFile } from '../../utils/file.mjs'; import { groupNodesByModule } from '../../utils/generators.mjs'; import { minifyHTML } from '../../utils/html-minifier.mjs'; -import { getRemarkRehypeWithShiki } from '../../utils/remark.mjs'; +import { getRemarkRehypeWithShiki as remark } from '../../utils/remark.mjs'; /** * Creates a heading object with the given name. @@ -19,8 +19,6 @@ import { getRemarkRehypeWithShiki } from '../../utils/remark.mjs'; */ const getHeading = name => ({ depth: 1, data: { name } }); -const remarkRehypeProcessor = getRemarkRehypeWithShiki(); - /** * Process a chunk of items in a worker thread. * Builds HTML template objects - FS operations happen in generate(). @@ -42,7 +40,7 @@ export async function processChunk(slicedInput, itemIndices, navigation) { ); const toc = String( - remarkRehypeProcessor.processSync( + remark().processSync( tableOfContents(nodes, { maxDepth: 5, parser: tableOfContents.parseToCNode, @@ -50,7 +48,7 @@ export async function processChunk(slicedInput, itemIndices, navigation) { ) ); - const content = buildContent(headNodes, nodes, remarkRehypeProcessor); + const content = buildContent(headNodes, nodes); const apiAsHeading = head.api.charAt(0).toUpperCase() + head.api.slice(1); @@ -94,7 +92,7 @@ export async function* generate(input, worker) { : headNodes; const navigation = String( - remarkRehypeProcessor.processSync( + remark().processSync( tableOfContents(indexOfFiles, { maxDepth: 1, parser: tableOfContents.parseNavigationNode, diff --git a/src/generators/legacy-html/utils/buildContent.mjs b/src/generators/legacy-html/utils/buildContent.mjs index 32776bad..bcc119e7 100644 --- a/src/generators/legacy-html/utils/buildContent.mjs +++ b/src/generators/legacy-html/utils/buildContent.mjs @@ -12,6 +12,7 @@ import { populate, } from '../../../utils/configuration/templates.mjs'; import { QUERIES, UNIST } from '../../../utils/queries/index.mjs'; +import { getRemarkRehypeWithShiki as remark } from '../../utils/remark.mjs'; /** * Builds a Markdown heading for a given node @@ -87,13 +88,9 @@ const buildHtmlTypeLink = node => { * Creates a history table row. * * @param {import('../../metadata/types').ChangeEntry} change - * @param {import('unified').Processor} remark */ -const createHistoryTableRow = ( - { version: changeVersions, description }, - remark -) => { - const descriptionNode = remark.parse(description); +const createHistoryTableRow = ({ version: changeVersions, description }) => { + const descriptionNode = remark().parse(description); return createElement('tr', [ createElement( @@ -108,10 +105,9 @@ const createHistoryTableRow = ( * Builds the Metadata Properties into content * * @param {import('../../metadata/types').MetadataEntry} node The node to build the properties from - * @param {import('unified').Processor} remark The Remark instance to be used to process changes table * @returns {import('unist').Parent} The HTML AST tree of the properties content */ -const buildMetadataElement = (node, remark) => { +const buildMetadataElement = node => { const config = getConfig('legacy-html'); const metadataElement = createElement('div.api_metadata'); @@ -190,9 +186,7 @@ const buildMetadataElement = (node, remark) => { if (typeof node.changes !== 'undefined' && node.changes.length) { // Maps the changes into a `tr` element with the version and the description // An array containing hast nodes for the history entries if any - const historyEntries = node.changes.map(change => - createHistoryTableRow(change, remark) - ); + const historyEntries = node.changes.map(createHistoryTableRow); const historyDetailsElement = createElement('details.changelog', [ createElement('summary', 'History'), @@ -220,9 +214,8 @@ const buildMetadataElement = (node, remark) => { * * @param {Array} headNodes The API metadata Nodes that are considered the "head" of each module * @param {Array} metadataEntries The API metadata Nodes to be transformed into HTML content - * @param {import('unified').Processor} remark The Remark instance to be used to process */ -export default (headNodes, metadataEntries, remark) => { +export default (headNodes, metadataEntries) => { const getLegacySlug = createLegacySlugger(); // Creates the root node for the content @@ -258,15 +251,15 @@ export default (headNodes, metadataEntries, remark) => { // Concatenates all the strings and parses with remark into an AST tree return createElement('section', [ headingNode, - buildMetadataElement(entry, remark), + buildMetadataElement(entry), buildExtraContent(headNodes, entry), ...restNodes, ]); }) ); - const processedNodes = remark.runSync(parsedNodes); + const processedNodes = remark().runSync(parsedNodes); // Stringifies the processed nodes to return the final Markdown content - return remark.stringify(processedNodes); + return remark().stringify(processedNodes); }; diff --git a/src/generators/legacy-json/utils/buildSection.mjs b/src/generators/legacy-json/utils/buildSection.mjs index 624cbc4b..dd5dea05 100644 --- a/src/generators/legacy-json/utils/buildSection.mjs +++ b/src/generators/legacy-json/utils/buildSection.mjs @@ -1,7 +1,7 @@ import { buildHierarchy } from './buildHierarchy.mjs'; import { parseList } from './parseList.mjs'; import { enforceArray } from '../../../utils/array.mjs'; -import { getRemarkRehype } from '../../../utils/remark.mjs'; +import { getRemarkRehype as remark } from '../../../utils/remark.mjs'; import { transformNodesToString } from '../../../utils/unist.mjs'; import { SECTION_TYPE_PLURALS, UNPROMOTED_KEYS } from '../constants.mjs'; @@ -31,8 +31,6 @@ export const promoteMiscChildren = (section, parent) => { * */ export const createSectionBuilder = () => { - const html = getRemarkRehype(); - /** * Creates metadata from a hierarchized entry. * @param {import('../types.d.ts').HierarchizedEntry} entry - The entry to create metadata from. @@ -125,8 +123,8 @@ export const createSectionBuilder = () => { return; } - const rendered = html.stringify( - html.runSync({ type: 'root', children: nodes }) + const rendered = remark().stringify( + remark().runSync({ type: 'root', children: nodes }) ); section.shortDesc = section.desc || undefined; diff --git a/src/generators/metadata/utils/parse.mjs b/src/generators/metadata/utils/parse.mjs index 7a3d98b2..a06ae68d 100644 --- a/src/generators/metadata/utils/parse.mjs +++ b/src/generators/metadata/utils/parse.mjs @@ -20,13 +20,10 @@ import { visitYAML, } from './visitors.mjs'; import { UNIST } from '../../../utils/queries/index.mjs'; -import { getRemark } from '../../../utils/remark.mjs'; +import { getRemark as remark } from '../../../utils/remark.mjs'; import { relative } from '../../../utils/url.mjs'; import { IGNORE_STABILITY_STEMS } from '../constants.mjs'; -// Creates an instance of the Remark processor with GFM support -const remarkProcessor = getRemark(); - /** * This generator generates a flattened list of metadata entries from a API doc * @@ -131,7 +128,7 @@ export const parseApiDoc = ({ path, tree }, typeMap) => { remove(subTree, [UNIST.isYamlNode]); // Apply AST transformations - const parsedSubTree = remarkProcessor.runSync(subTree); + const parsedSubTree = remark().runSync(subTree); metadata.content = parsedSubTree; // Add to collection diff --git a/src/generators/metadata/utils/visitors.mjs b/src/generators/metadata/utils/visitors.mjs index 0008e1de..f260079d 100644 --- a/src/generators/metadata/utils/visitors.mjs +++ b/src/generators/metadata/utils/visitors.mjs @@ -7,12 +7,10 @@ import { transformUnixManualToLink, } from './transformers.mjs'; import { extractYamlContent, parseYAMLIntoMetadata } from './yaml.mjs'; -import { lazy } from '../../../utils/misc.mjs'; import { QUERIES } from '../../../utils/queries/index.mjs'; -import { getRemark } from '../../../utils/remark.mjs'; +import { getRemark as remark } from '../../../utils/remark.mjs'; import { transformNodesToString } from '../../../utils/unist.mjs'; -const remark = lazy(getRemark); /** * Updates a Markdown link into a HTML link for API docs * @param {import('@types/mdast').Link} node A Markdown link node diff --git a/src/utils/remark.mjs b/src/utils/remark.mjs index 2192516b..1dcadc19 100644 --- a/src/utils/remark.mjs +++ b/src/utils/remark.mjs @@ -13,6 +13,7 @@ import remarkStringify from 'remark-stringify'; import { unified } from 'unified'; import syntaxHighlighter, { highlighter } from './highlighter.mjs'; +import { lazy } from './misc.mjs'; import { AST_NODE_TYPES } from '../generators/jsx-ast/constants.mjs'; import transformElements from '../generators/jsx-ast/utils/transformer.mjs'; @@ -21,13 +22,14 @@ const passThrough = ['element', ...Object.values(AST_NODE_TYPES.MDX)]; /** * Retrieves an instance of Remark configured to parse GFM (GitHub Flavored Markdown) */ -export const getRemark = () => - unified().use(remarkParse).use(remarkGfm).use(remarkStringify); +export const getRemark = lazy(() => + unified().use(remarkParse).use(remarkGfm).use(remarkStringify) +); /** * Retrieves an instance of Remark configured to output stringified HTML code */ -export const getRemarkRehype = () => +export const getRemarkRehype = lazy(() => unified() .use(remarkParse) // We make Rehype ignore existing HTML nodes (just the node itself, not its children) @@ -37,13 +39,14 @@ export const getRemarkRehype = () => .use(remarkRehype, { allowDangerousHtml: true, passThrough }) // We allow dangerous HTML to be passed through, since we have HTML within our Markdown // and we trust the sources of the Markdown files - .use(rehypeStringify, { allowDangerousHtml: true }); + .use(rehypeStringify, { allowDangerousHtml: true }) +); /** * Retrieves an instance of Remark configured to output stringified HTML code * including parsing Code Boxes with syntax highlighting */ -export const getRemarkRehypeWithShiki = () => +export const getRemarkRehypeWithShiki = lazy(() => unified() .use(remarkParse) // We make Rehype ignore existing HTML nodes (just the node itself, not its children) @@ -56,7 +59,8 @@ export const getRemarkRehypeWithShiki = () => .use(syntaxHighlighter) // We allow dangerous HTML to be passed through, since we have HTML within our Markdown // and we trust the sources of the Markdown files - .use(rehypeStringify, { allowDangerousHtml: true }); + .use(rehypeStringify, { allowDangerousHtml: true }) +); const singletonShiki = await rehypeShikiji({ highlighter }); @@ -64,7 +68,7 @@ const singletonShiki = await rehypeShikiji({ highlighter }); * Retrieves an instance of Remark configured to output JSX code. * including parsing Code Boxes with syntax highlighting */ -export const getRemarkRecma = () => +export const getRemarkRecma = lazy(() => unified() .use(remarkParse) // We make Rehype ignore existing HTML nodes, and JSX nodes @@ -78,4 +82,5 @@ export const getRemarkRecma = () => .use(transformElements) .use(rehypeRecma) .use(recmaJsx) - .use(recmaStringify); + .use(recmaStringify) +); From b9bb60e031697338b49636a44b25fa857d43ff86 Mon Sep 17 00:00:00 2001 From: Aviv Keller Date: Mon, 30 Mar 2026 11:59:52 -0400 Subject: [PATCH 2/2] Update src/generators/legacy-html/utils/buildContent.mjs Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- src/generators/legacy-html/utils/buildContent.mjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/generators/legacy-html/utils/buildContent.mjs b/src/generators/legacy-html/utils/buildContent.mjs index bcc119e7..22e4a0e2 100644 --- a/src/generators/legacy-html/utils/buildContent.mjs +++ b/src/generators/legacy-html/utils/buildContent.mjs @@ -12,7 +12,7 @@ import { populate, } from '../../../utils/configuration/templates.mjs'; import { QUERIES, UNIST } from '../../../utils/queries/index.mjs'; -import { getRemarkRehypeWithShiki as remark } from '../../utils/remark.mjs'; +import { getRemarkRehypeWithShiki as remark } from '../../../utils/remark.mjs'; /** * Builds a Markdown heading for a given node