@mui/internal-docs-infra 0.12.1-canary.2 → 0.12.1-canary.21

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (221) hide show
  1. package/ChunkProvider/PreloadProvider.mjs +1 -2
  2. package/ChunkProvider/usePreload.d.mts +1 -1
  3. package/ChunkProvider/usePreload.mjs +0 -1
  4. package/CodeControllerContext/CodeControllerContext.d.mts +45 -10
  5. package/CodeControllerContext/CodeControllerContext.mjs +15 -1
  6. package/CodeHighlighter/CodeHighlighterClient.d.mts +3 -2
  7. package/CodeHighlighter/CodeHighlighterClient.mjs +113 -18
  8. package/CodeHighlighter/CodeHighlighterContext.d.mts +9 -3
  9. package/CodeHighlighter/buildStringFallback.d.mts +1 -1
  10. package/CodeHighlighter/codeToFallbackProps.d.mts +1 -1
  11. package/CodeHighlighter/createClientProps.mjs +3 -0
  12. package/CodeHighlighter/fallbackCompression.d.mts +1 -1
  13. package/CodeHighlighter/parseControlledCode.d.mts +13 -4
  14. package/CodeHighlighter/parseControlledCode.mjs +41 -49
  15. package/CodeHighlighter/types.d.mts +21 -0
  16. package/CodeHighlighter/useGrammarsReady.mjs +44 -9
  17. package/CodeProvider/CodeProvider.d.mts +1 -1
  18. package/CodeProvider/CodeProviderLazy.d.mts +1 -1
  19. package/CodeProvider/createParseSourceWorkerClient.d.mts +6 -0
  20. package/CodeProvider/createParseSourceWorkerClient.mjs +83 -15
  21. package/CodeProvider/useCodeProviderValue.mjs +50 -4
  22. package/abstractCreateDemo/abstractCreateDemo.d.mts +15 -1
  23. package/abstractCreateDemo/abstractCreateDemo.mjs +8 -0
  24. package/abstractCreateDemoClient/abstractCreateDemoClient.mjs +4 -0
  25. package/abstractCreateTypes/abstractCreateTypes.d.mts +12 -1
  26. package/abstractCreateTypes/abstractCreateTypes.mjs +4 -0
  27. package/abstractCreateTypes/typesToJsx.d.mts +8 -0
  28. package/abstractCreateTypes/typesToJsx.mjs +2 -1
  29. package/cli/loadNextConfig.d.mts +9 -0
  30. package/cli/loadNextConfig.mjs +11 -2
  31. package/cli/runValidate.mjs +15 -7
  32. package/cli/validateWorker.d.mts +1 -0
  33. package/cli/validateWorker.mjs +2 -1
  34. package/createDemoData/createDemoData.d.mts +1 -1
  35. package/package.json +34 -5
  36. package/pipeline/cacheUtils/constants.d.mts +5 -0
  37. package/pipeline/cacheUtils/constants.mjs +5 -0
  38. package/pipeline/cacheUtils/hashCacheContent.d.mts +5 -0
  39. package/pipeline/cacheUtils/hashCacheContent.mjs +9 -0
  40. package/pipeline/cacheUtils/index.d.mts +9 -0
  41. package/pipeline/cacheUtils/index.mjs +7 -0
  42. package/pipeline/cacheUtils/loadFileCache.d.mts +13 -0
  43. package/pipeline/cacheUtils/loadFileCache.mjs +20 -0
  44. package/pipeline/cacheUtils/loadFileCacheEntry.d.mts +13 -0
  45. package/pipeline/cacheUtils/loadFileCacheEntry.mjs +47 -0
  46. package/pipeline/cacheUtils/resolveCachePath.d.mts +16 -0
  47. package/pipeline/cacheUtils/resolveCachePath.mjs +24 -0
  48. package/pipeline/cacheUtils/saveFileCache.d.mts +17 -0
  49. package/pipeline/cacheUtils/saveFileCache.mjs +54 -0
  50. package/pipeline/cacheUtils/types.d.mts +23 -0
  51. package/pipeline/cacheUtils/types.mjs +1 -0
  52. package/pipeline/cacheUtils/withFileCache.d.mts +40 -0
  53. package/pipeline/cacheUtils/withFileCache.mjs +81 -0
  54. package/pipeline/hastUtils/hastUtils.d.mts +1 -1
  55. package/pipeline/hastUtils/hastUtils.mjs +0 -1
  56. package/pipeline/loadIsomorphicCodeSource/loadIsomorphicCodeSource.d.mts +1 -1
  57. package/pipeline/loadIsomorphicCodeSource/loadIsomorphicCodeSource.mjs +1 -1
  58. package/pipeline/loadIsomorphicCodeVariant/applyCodeTransform.mjs +0 -1
  59. package/pipeline/loadIsomorphicCodeVariant/diffHast.d.mts +1 -1
  60. package/pipeline/loadIsomorphicCodeVariant/hasAllCodeVariants.d.mts +1 -1
  61. package/pipeline/loadIsomorphicCodeVariant/maybeCodeInitialData.d.mts +1 -1
  62. package/pipeline/loadPrecomputedSitemap/loadPrecomputedSitemap.d.mts +6 -0
  63. package/pipeline/loadPrecomputedSitemap/loadPrecomputedSitemap.mjs +2 -1
  64. package/pipeline/loadPrecomputedTypes/loadPrecomputedTypes.d.mts +6 -0
  65. package/pipeline/loadPrecomputedTypes/loadPrecomputedTypes.mjs +5 -1
  66. package/pipeline/loadServerCodeMeta/resolveModulePathWithFs.d.mts +1 -1
  67. package/pipeline/loadServerCodeMeta/resolveModulePathWithFs.mjs +0 -1
  68. package/pipeline/loadServerPageIndex/enrichPageIndex.d.mts +15 -0
  69. package/pipeline/loadServerPageIndex/enrichPageIndex.mjs +50 -0
  70. package/pipeline/loadServerPageIndex/extractPrefixAndTitle.d.mts +19 -0
  71. package/pipeline/loadServerPageIndex/extractPrefixAndTitle.mjs +80 -0
  72. package/pipeline/loadServerPageIndex/index.d.mts +5 -2
  73. package/pipeline/loadServerPageIndex/index.mjs +4 -1
  74. package/pipeline/loadServerPageIndex/loadServerPageIndex.d.mts +13 -22
  75. package/pipeline/loadServerPageIndex/loadServerPageIndex.mjs +32 -124
  76. package/pipeline/loadServerPageIndex/resolvePageIndexCacheKey.d.mts +13 -0
  77. package/pipeline/loadServerPageIndex/resolvePageIndexCacheKey.mjs +23 -0
  78. package/pipeline/loadServerTypes/highlightTypes.d.mts +3 -3
  79. package/pipeline/loadServerTypes/highlightTypesMeta.d.mts +4 -4
  80. package/pipeline/loadServerTypes/loadServerTypes.d.mts +2 -2
  81. package/pipeline/loadServerTypes/loadServerTypes.mjs +67 -7
  82. package/pipeline/loadServerTypesMeta/createOptimizedProgram.d.mts +2 -1
  83. package/pipeline/loadServerTypesMeta/formatClass.d.mts +2 -2
  84. package/pipeline/loadServerTypesMeta/formatComponent.d.mts +2 -2
  85. package/pipeline/loadServerTypesMeta/formatFunction.d.mts +2 -2
  86. package/pipeline/loadServerTypesMeta/formatHook.d.mts +2 -2
  87. package/pipeline/loadServerTypesMeta/formatRaw.d.mts +2 -2
  88. package/pipeline/loadServerTypesMeta/formatType.d.mts +1 -1
  89. package/pipeline/loadServerTypesMeta/loadServerTypesMeta.d.mts +7 -7
  90. package/pipeline/loadServerTypesMeta/loadServerTypesMeta.mjs +1 -1
  91. package/pipeline/loadServerTypesMeta/processTypes.d.mts +2 -2
  92. package/pipeline/loadServerTypesMeta/worker.d.mts +1 -1
  93. package/pipeline/loadServerTypesText/loadServerTypesText.d.mts +16 -2
  94. package/pipeline/loadServerTypesText/loadServerTypesText.mjs +30 -8
  95. package/pipeline/loadServerTypesText/normalizeTypesSourceDataForCache.d.mts +2 -0
  96. package/pipeline/loadServerTypesText/normalizeTypesSourceDataForCache.mjs +144 -0
  97. package/pipeline/loadServerTypesText/resolveTypesCacheKey.d.mts +19 -0
  98. package/pipeline/loadServerTypesText/resolveTypesCacheKey.mjs +29 -0
  99. package/pipeline/loaderUtils/parseImportsAndComments.d.mts +5 -3
  100. package/pipeline/loaderUtils/parseImportsAndComments.mjs +284 -40
  101. package/pipeline/parseCreateFactoryCall/parseCreateFactoryCall.d.mts +2 -2
  102. package/pipeline/parseCreateFactoryCall/parseCreateFactoryCall.mjs +2 -3
  103. package/pipeline/parseSource/detectFileTypes.d.mts +16 -0
  104. package/pipeline/parseSource/detectFileTypes.mjs +44 -0
  105. package/pipeline/syncPageIndex/mergeMetadataMarkdown.d.mts +25 -1
  106. package/pipeline/syncPageIndex/mergeMetadataMarkdown.mjs +79 -49
  107. package/pipeline/syncPageIndex/metadataToMarkdown.d.mts +15 -1
  108. package/pipeline/syncPageIndex/metadataToMarkdown.mjs +32 -10
  109. package/pipeline/syncPageIndex/syncPageIndex.d.mts +12 -0
  110. package/pipeline/syncPageIndex/syncPageIndex.mjs +154 -40
  111. package/pipeline/syncTypes/generateTypesMarkdown.d.mts +2 -2
  112. package/pipeline/syncTypes/syncTypes.d.mts +7 -0
  113. package/pipeline/syncTypes/syncTypes.mjs +31 -1
  114. package/pipeline/transformHtmlCodeBlock/transformHtmlCodeBlock.mjs +1 -1
  115. package/pipeline/transformMarkdownCode/transformMarkdownCode.mjs +25 -15
  116. package/pipeline/transformMarkdownMetadata/transformMarkdownMetadata.mjs +3 -0
  117. package/pipeline/transformMarkdownMetadata/types.d.mts +8 -1
  118. package/useCode/EditableEngine.d.mts +1 -1
  119. package/useCode/Pre.d.mts +9 -2
  120. package/useCode/Pre.mjs +4 -3
  121. package/useCode/TransformEngine.d.mts +1 -1
  122. package/useCode/useCode.d.mts +17 -1
  123. package/useCode/useCode.mjs +22 -1
  124. package/useCode/useCopyFunctionality.d.mts +2 -2
  125. package/useCode/useEditable.browser.mjs +0 -1
  126. package/useCode/useFileNavigation.d.mts +3 -0
  127. package/useCode/useFileNavigation.mjs +3 -1
  128. package/useCode/useSourceEditing.mjs +45 -10
  129. package/useCode/useSourceEnhancing.mjs +41 -9
  130. package/useCode/useTransformManagement.d.mts +2 -2
  131. package/useCode/useTransformManagement.mjs +19 -3
  132. package/useCode/useUIState.d.mts +4 -0
  133. package/useCode/useUIState.mjs +8 -1
  134. package/useCode/useVariantSelection.d.mts +1 -1
  135. package/useCoordinated/useCoordinated.d.mts +1 -1
  136. package/useCoordinated/useCoordinatedLocalStorage.d.mts +1 -1
  137. package/useCoordinated/useCoordinatedLocalStorage.mjs +0 -1
  138. package/useCoordinated/useCoordinatedPreference.d.mts +1 -1
  139. package/useCoordinated/useCoordinatedPreference.mjs +0 -1
  140. package/useCrossTabState/index.d.mts +2 -0
  141. package/useCrossTabState/index.mjs +2 -0
  142. package/useCrossTabState/useCrossTabMirror.d.mts +26 -0
  143. package/useCrossTabState/useCrossTabMirror.mjs +108 -0
  144. package/useCrossTabState/useCrossTabState.d.mts +21 -0
  145. package/useCrossTabState/useCrossTabState.mjs +31 -0
  146. package/useDemo/exportVariant.mjs +2 -4
  147. package/useDemo/exportVariantAsCra.d.mts +1 -1
  148. package/useDemo/exportVariantAsCra.mjs +0 -1
  149. package/useDemo/useDemo.d.mts +4 -1
  150. package/useDemo/useDemo.mjs +5 -0
  151. package/useDemoController/BuildEngine.d.mts +2 -0
  152. package/useDemoController/BuildEngine.mjs +10 -0
  153. package/useDemoController/DemoRunner.d.mts +34 -0
  154. package/useDemoController/DemoRunner.mjs +83 -0
  155. package/useDemoController/ErrorBoundary.d.mts +34 -0
  156. package/useDemoController/ErrorBoundary.mjs +49 -0
  157. package/useDemoController/Runner.d.mts +44 -0
  158. package/useDemoController/Runner.mjs +71 -0
  159. package/useDemoController/absolutizeImports.d.mts +13 -0
  160. package/useDemoController/absolutizeImports.mjs +73 -0
  161. package/useDemoController/buildScope.d.mts +48 -0
  162. package/useDemoController/buildScope.mjs +270 -0
  163. package/useDemoController/collectSources.d.mts +67 -0
  164. package/useDemoController/collectSources.mjs +92 -0
  165. package/useDemoController/compileCssModule.d.mts +64 -0
  166. package/useDemoController/compileCssModule.mjs +40 -0
  167. package/useDemoController/compileCssWithPostcss.d.mts +17 -0
  168. package/useDemoController/compileCssWithPostcss.mjs +89 -0
  169. package/useDemoController/compileModule.d.mts +14 -0
  170. package/useDemoController/compileModule.mjs +17 -0
  171. package/useDemoController/constants.d.mts +13 -0
  172. package/useDemoController/constants.mjs +13 -0
  173. package/useDemoController/createRequire.d.mts +10 -0
  174. package/useDemoController/createRequire.mjs +17 -0
  175. package/useDemoController/createTranspileWorkerClient.d.mts +27 -0
  176. package/useDemoController/createTranspileWorkerClient.mjs +139 -0
  177. package/useDemoController/cssModules.d.mts +47 -0
  178. package/useDemoController/currentBrowserTarget.d.mts +16 -0
  179. package/useDemoController/currentBrowserTarget.mjs +36 -0
  180. package/useDemoController/evalCode.d.mts +12 -0
  181. package/useDemoController/evalCode.mjs +35 -0
  182. package/useDemoController/generateCssModuleSource.d.mts +11 -0
  183. package/useDemoController/generateCssModuleSource.mjs +55 -0
  184. package/useDemoController/generateElement.d.mts +21 -0
  185. package/useDemoController/generateElement.mjs +26 -0
  186. package/useDemoController/hashString.d.mts +11 -0
  187. package/useDemoController/hashString.mjs +20 -0
  188. package/useDemoController/importCode.d.mts +11 -0
  189. package/useDemoController/importCode.mjs +15 -0
  190. package/useDemoController/index.d.mts +1 -0
  191. package/useDemoController/index.mjs +1 -0
  192. package/useDemoController/instantiateElement.d.mts +24 -0
  193. package/useDemoController/instantiateElement.mjs +57 -0
  194. package/useDemoController/instantiateModule.d.mts +17 -0
  195. package/useDemoController/instantiateModule.mjs +24 -0
  196. package/useDemoController/resolveCssImports.d.mts +27 -0
  197. package/useDemoController/resolveCssImports.mjs +79 -0
  198. package/useDemoController/transformCode.d.mts +14 -0
  199. package/useDemoController/transformCode.mjs +42 -0
  200. package/useDemoController/transpileClientSingleton.d.mts +10 -0
  201. package/useDemoController/transpileClientSingleton.mjs +83 -0
  202. package/useDemoController/transpileSource.d.mts +29 -0
  203. package/useDemoController/transpileSource.mjs +36 -0
  204. package/useDemoController/transpileWorker.d.mts +14 -0
  205. package/useDemoController/transpileWorker.mjs +41 -0
  206. package/useDemoController/types.d.mts +30 -0
  207. package/useDemoController/types.mjs +1 -0
  208. package/useDemoController/useDemoController.d.mts +54 -0
  209. package/useDemoController/useDemoController.mjs +186 -0
  210. package/useDemoController/useRunner.d.mts +53 -0
  211. package/useDemoController/useRunner.mjs +118 -0
  212. package/useDemoController/useVariantBuilds.d.mts +31 -0
  213. package/useDemoController/useVariantBuilds.mjs +188 -0
  214. package/useSearch/types.d.mts +1 -1
  215. package/useType/TypesDataProvider.d.mts +1 -1
  216. package/useType/TypesDataProvider.mjs +1 -2
  217. package/useType/useType.d.mts +1 -1
  218. package/useType/useTypeProp.d.mts +1 -1
  219. package/withDocsInfra/withDeploymentConfig.mjs +57 -0
  220. package/withDocsInfra/withDocsInfra.d.mts +14 -0
  221. package/withDocsInfra/withDocsInfra.mjs +25 -11
@@ -1,5 +1,5 @@
1
1
  import type { Nodes } from 'hast';
2
- import { type SourceComments, type Transforms } from "../../CodeHighlighter/types.mjs";
2
+ import type { SourceComments, Transforms } from "../../CodeHighlighter/types.mjs";
3
3
  /**
4
4
  * Async-friendly variant of {@link ParseSource}. The build-time diff path
5
5
  * may wrap the synchronous highlighter with enhancers that need to run
@@ -1,4 +1,4 @@
1
- import { type Code } from "../../CodeHighlighter/types.mjs";
1
+ import type { Code } from "../../CodeHighlighter/types.mjs";
2
2
  /**
3
3
  * Determines if all code variants are fully loaded and ready to render the complete content component.
4
4
  *
@@ -1,4 +1,4 @@
1
- import { type Code, type VariantExtraFiles, type VariantSource } from "../../CodeHighlighter/types.mjs";
1
+ import type { Code, VariantExtraFiles, VariantSource } from "../../CodeHighlighter/types.mjs";
2
2
  /**
3
3
  * Type guard function that determines if we have sufficient data to render a code highlighter
4
4
  * component immediately, or if we need to start loading data first.
@@ -6,5 +6,11 @@ export type LoaderOptions = {
6
6
  showWrapperMeasures?: boolean;
7
7
  significantDependencyCountThreshold?: number;
8
8
  };
9
+ /**
10
+ * Directory for the sha256-validated JSON cache of parsed page indexes. When set,
11
+ * unchanged indexes are read from `{cacheDir}/pages-index/{route}.json` instead of
12
+ * being re-parsed.
13
+ */
14
+ cacheDir?: string;
9
15
  };
10
16
  export declare function loadPrecomputedSitemap(this: LoaderContext<LoaderOptions>, source: string): Promise<void>;
@@ -72,7 +72,8 @@ export async function loadPrecomputedSitemap(source) {
72
72
  // Create page index loader with root context
73
73
  const rootContext = this.rootContext || process.cwd();
74
74
  const loadPageIndex = createLoadServerPageIndex({
75
- rootContext
75
+ rootContext,
76
+ cacheDir: options.cacheDir
76
77
  });
77
78
 
78
79
  // Process all markdown files in parallel using shared logic
@@ -56,6 +56,12 @@ export type LoaderOptions = {
56
56
  descriptionReplacements?: DescriptionReplacement[];
57
57
  /** Options for code blocks highlighted inside generated type metadata */
58
58
  codeBlockEmphasisOptions?: TransformHtmlCodeBlockOptions;
59
+ /**
60
+ * Directory for the sha256-validated JSON cache of the types pipeline. When set, the
61
+ * parsed types.md (`types-text`) and the enhanced/highlighted result (`types-enhanced`)
62
+ * are cached under it, keyed by content hash.
63
+ */
64
+ cacheDir?: string;
59
65
  };
60
66
  /**
61
67
  * Webpack loader that processes types and precomputes meta.
@@ -73,7 +73,10 @@ export async function loadPrecomputedTypes(source) {
73
73
  // Skip if excludeFromIndex is set in the factory call options
74
74
  const updateParentIndex = options.updateParentIndex && !excludeFromIndex ? {
75
75
  baseDir: options.updateParentIndex.baseDir ? path.resolve(rootContext, options.updateParentIndex.baseDir) : rootContext,
76
- indexFileName: options.updateParentIndex.indexFileName
76
+ indexFileName: options.updateParentIndex.indexFileName,
77
+ // Forward cacheDir so the types-driven parent-index update also warms the
78
+ // pages-index cache (otherwise only the MDX path / on-miss reader populate it).
79
+ cacheDir: options.updateParentIndex.cacheDir
77
80
  } : undefined;
78
81
 
79
82
  // Call the core server-side logic
@@ -90,6 +93,7 @@ export async function loadPrecomputedTypes(source) {
90
93
  ordering: options.ordering,
91
94
  descriptionReplacements: options.descriptionReplacements,
92
95
  codeBlockEmphasisOptions: options.codeBlockEmphasisOptions,
96
+ cacheDir: options.cacheDir,
93
97
  sync: true,
94
98
  output: 'hastCompressed'
95
99
  });
@@ -1,4 +1,4 @@
1
- import { type DirectoryEntry, type DirectoryReader, type ResolveModulePathOptions, type TypeAwareResolveResult } from "../loaderUtils/resolveModulePath.mjs";
1
+ import type { DirectoryEntry, DirectoryReader, ResolveModulePathOptions, TypeAwareResolveResult } from "../loaderUtils/resolveModulePath.mjs";
2
2
  /**
3
3
  * Resolves a module path using Node.js filesystem APIs.
4
4
  * This is a convenience wrapper around the generic resolveModulePath function.
@@ -4,7 +4,6 @@ import { readdir } from 'fs/promises';
4
4
  // eslint-disable-next-line n/prefer-node-protocol
5
5
  import { fileURLToPath } from 'url';
6
6
  import { resolveModulePath, resolveModulePaths, resolveImportResult, resolveVariantPaths } from "../loaderUtils/resolveModulePath.mjs";
7
-
8
7
  /**
9
8
  * Node.js filesystem-based directory reader that converts Dirent objects
10
9
  * to the DirectoryEntry interface expected by the resolver functions.
@@ -0,0 +1,15 @@
1
+ import type { PagesMetadata } from "../syncPageIndex/metadataToMarkdown.mjs";
2
+ import type { SitemapSectionData } from "../../createSitemap/types.mjs";
3
+ /**
4
+ * Converts parsed page-index metadata into the `SitemapSectionData` read-model.
5
+ *
6
+ * Derives `prefix` and `title` from the file path (overriding the markdown H1), strips the
7
+ * markdown AST fields (`descriptionMarkdown`, section `titleMarkdown`) to reduce bundle size, and
8
+ * normalizes description whitespace exactly as the parser does so the cache (built from in-memory
9
+ * metadata) matches a fresh parse of the written markdown.
10
+ *
11
+ * Shared by `loadServerPageIndex` (read path) and `syncPageIndex` (cache pre-population on write).
12
+ * Normalization is idempotent, so re-applying it on the read path (where descriptions are already
13
+ * normalized) is a no-op.
14
+ */
15
+ export declare function enrichPageIndex(metadata: PagesMetadata, absolutePath: string, rootContext: string): SitemapSectionData;
@@ -0,0 +1,50 @@
1
+ import { extractPrefixAndTitle, stripTitleMarkdown } from "./extractPrefixAndTitle.mjs";
2
+ import { collapseInlineWhitespace } from "../syncPageIndex/metadataToMarkdown.mjs";
3
+ /**
4
+ * Converts parsed page-index metadata into the `SitemapSectionData` read-model.
5
+ *
6
+ * Derives `prefix` and `title` from the file path (overriding the markdown H1), strips the
7
+ * markdown AST fields (`descriptionMarkdown`, section `titleMarkdown`) to reduce bundle size, and
8
+ * normalizes description whitespace exactly as the parser does so the cache (built from in-memory
9
+ * metadata) matches a fresh parse of the written markdown.
10
+ *
11
+ * Shared by `loadServerPageIndex` (read path) and `syncPageIndex` (cache pre-population on write).
12
+ * Normalization is idempotent, so re-applying it on the read path (where descriptions are already
13
+ * normalized) is a no-op.
14
+ */
15
+ export function enrichPageIndex(metadata, absolutePath, rootContext) {
16
+ // Override the markdown's H1 with the title generated from the path.
17
+ const {
18
+ prefix,
19
+ title
20
+ } = extractPrefixAndTitle(absolutePath, rootContext);
21
+ return {
22
+ ...metadata,
23
+ prefix,
24
+ title,
25
+ // Normalize the index's own (leaked) description like the parser. Spread instead of an explicit
26
+ // key because SitemapSectionData does not declare `description`.
27
+ ...(metadata.description !== undefined ? {
28
+ description: collapseInlineWhitespace(metadata.description)
29
+ } : {}),
30
+ // Strip markdown AST fields and normalize each page's description. keywords and types are
31
+ // comma-split from a whitespace-collapsed paragraph by the parser, so normalize each element
32
+ // the same way (collapse-then-split equals split-then-per-element-collapse, since the comma
33
+ // delimiter can't appear inside a value) — otherwise a cache hit diverges from a fresh parse.
34
+ pages: metadata.pages.map(page => {
35
+ const {
36
+ descriptionMarkdown,
37
+ sections,
38
+ ...pageWithoutMarkdown
39
+ } = page;
40
+ return {
41
+ ...pageWithoutMarkdown,
42
+ description: page.description === undefined ? undefined : collapseInlineWhitespace(page.description),
43
+ keywords: page.keywords?.map(collapseInlineWhitespace),
44
+ types: page.types?.map(collapseInlineWhitespace),
45
+ // Strip titleMarkdown from the sections hierarchy.
46
+ sections: sections ? stripTitleMarkdown(sections) : undefined
47
+ };
48
+ })
49
+ };
50
+ }
@@ -0,0 +1,19 @@
1
+ import type { HeadingHierarchy } from "../transformMarkdownMetadata/types.mjs";
2
+ import type { SitemapSection } from "../../createSitemap/types.mjs";
3
+ /**
4
+ * Converts a path segment to a title
5
+ * e.g., "docs-infra" -> "Docs Infra", "components" -> "Components"
6
+ */
7
+ export declare function pathSegmentToTitle(segment: string): string;
8
+ /**
9
+ * Recursively removes titleMarkdown fields from a heading hierarchy
10
+ */
11
+ export declare function stripTitleMarkdown(hierarchy: HeadingHierarchy): Record<string, SitemapSection>;
12
+ /**
13
+ * Extracts prefix and title from an import path
14
+ * e.g., "/path/to/app/docs-infra/components/page.mdx" -> { prefix: "/docs-infra/components/", title: "Docs Infra Components" }
15
+ */
16
+ export declare function extractPrefixAndTitle(absolutePath: string, rootContext: string): {
17
+ prefix: string;
18
+ title: string;
19
+ };
@@ -0,0 +1,80 @@
1
+ import path from 'node:path';
2
+ /**
3
+ * Converts a path segment to a title
4
+ * e.g., "docs-infra" -> "Docs Infra", "components" -> "Components"
5
+ */
6
+ export function pathSegmentToTitle(segment) {
7
+ return segment.split('-').map(word => word.charAt(0).toUpperCase() + word.slice(1)).join(' ');
8
+ }
9
+
10
+ /**
11
+ * Recursively removes titleMarkdown fields from a heading hierarchy
12
+ */
13
+ export function stripTitleMarkdown(hierarchy) {
14
+ const result = {};
15
+ for (const [key, value] of Object.entries(hierarchy)) {
16
+ if (typeof value === 'object' && value !== null) {
17
+ const {
18
+ titleMarkdown,
19
+ children,
20
+ ...rest
21
+ } = value;
22
+ const strippedChildren = children ? stripTitleMarkdown(children) : {};
23
+ result[key] = {
24
+ ...rest,
25
+ // Only include children if it has keys, otherwise set to undefined
26
+ children: Object.keys(strippedChildren).length > 0 ? strippedChildren : undefined
27
+ };
28
+ }
29
+ }
30
+ return result;
31
+ }
32
+
33
+ /**
34
+ * Extracts prefix and title from an import path
35
+ * e.g., "/path/to/app/docs-infra/components/page.mdx" -> { prefix: "/docs-infra/components/", title: "Docs Infra Components" }
36
+ */
37
+ export function extractPrefixAndTitle(absolutePath, rootContext) {
38
+ // Get the relative path from the root context
39
+ const relativePath = path.relative(rootContext, absolutePath);
40
+
41
+ // Extract the directory path (remove filename)
42
+ const dirPath = path.dirname(relativePath);
43
+
44
+ // Split into segments
45
+ const allSegments = dirPath.split(path.sep);
46
+
47
+ // Filter out segments:
48
+ // - Remove leading 'src' and 'app' directory markers (only if they're at the start)
49
+ // - Remove Next.js route groups (segments in parentheses like '(public)')
50
+ // - Remove current directory markers ('.' and empty strings)
51
+ const segments = allSegments.filter((seg, index) => {
52
+ // Remove 'src' only if it's the first segment
53
+ if (seg === 'src' && index === 0) {
54
+ return false;
55
+ }
56
+ // Remove 'app' only if it's the first or second segment (after 'src')
57
+ if (seg === 'app' && (index === 0 || index === 1 && allSegments[0] === 'src')) {
58
+ return false;
59
+ }
60
+ // Filter out Next.js route groups (e.g., '(public)', '(content)')
61
+ if (seg.startsWith('(') && seg.endsWith(')')) {
62
+ return false;
63
+ }
64
+ // Filter out current directory markers
65
+ if (seg === '.' || seg === '') {
66
+ return false;
67
+ }
68
+ return true;
69
+ });
70
+
71
+ // Generate prefix with leading and trailing slashes
72
+ const prefix = segments.length > 0 ? `/${segments.join('/')}/` : '/';
73
+
74
+ // Generate title from path segments
75
+ const title = segments.map(pathSegmentToTitle).join(' ');
76
+ return {
77
+ prefix,
78
+ title
79
+ };
80
+ }
@@ -1,2 +1,5 @@
1
- export { loadServerPageIndex, createLoadServerPageIndex, extractPrefixAndTitle, pathSegmentToTitle, stripTitleMarkdown } from "./loadServerPageIndex.mjs";
2
- export type { CreateLoadServerPageIndexOptions, LoadServerPageIndex } from "./loadServerPageIndex.mjs";
1
+ export { loadServerPageIndex, createLoadServerPageIndex } from "./loadServerPageIndex.mjs";
2
+ export type { CreateLoadServerPageIndexOptions, LoadServerPageIndex } from "./loadServerPageIndex.mjs";
3
+ export { extractPrefixAndTitle, pathSegmentToTitle, stripTitleMarkdown } from "./extractPrefixAndTitle.mjs";
4
+ export { enrichPageIndex } from "./enrichPageIndex.mjs";
5
+ export { resolvePageIndexCacheKey } from "./resolvePageIndexCacheKey.mjs";
@@ -1 +1,4 @@
1
- export { loadServerPageIndex, createLoadServerPageIndex, extractPrefixAndTitle, pathSegmentToTitle, stripTitleMarkdown } from "./loadServerPageIndex.mjs";
1
+ export { loadServerPageIndex, createLoadServerPageIndex } from "./loadServerPageIndex.mjs";
2
+ export { extractPrefixAndTitle, pathSegmentToTitle, stripTitleMarkdown } from "./extractPrefixAndTitle.mjs";
3
+ export { enrichPageIndex } from "./enrichPageIndex.mjs";
4
+ export { resolvePageIndexCacheKey } from "./resolvePageIndexCacheKey.mjs";
@@ -1,5 +1,4 @@
1
- import type { HeadingHierarchy } from "../transformMarkdownMetadata/types.mjs";
2
- import type { SitemapSection, SitemapSectionData } from "../../createSitemap/types.mjs";
1
+ import type { SitemapSectionData } from "../../createSitemap/types.mjs";
3
2
  /**
4
3
  * Options for creating a loadServerPageIndex function
5
4
  */
@@ -9,28 +8,19 @@ export interface CreateLoadServerPageIndexOptions {
9
8
  * Defaults to process.cwd().
10
9
  */
11
10
  rootContext?: string;
11
+ /**
12
+ * Directory for the sha256-validated JSON cache of parsed page indexes.
13
+ *
14
+ * When set, a read first checks `{cacheDir}/pages-index/{route}.json`; on a hash
15
+ * match it returns the cached data and skips the markdown parse, and on a miss it
16
+ * parses, writes the cache, and returns. When unset, no cache is read or written.
17
+ */
18
+ cacheDir?: string;
12
19
  }
13
20
  /**
14
21
  * Function type for loading page index data from a markdown file
15
22
  */
16
23
  export type LoadServerPageIndex = (filePath: string) => Promise<SitemapSectionData | null>;
17
- /**
18
- * Converts a path segment to a title
19
- * e.g., "docs-infra" -> "Docs Infra", "components" -> "Components"
20
- */
21
- export declare function pathSegmentToTitle(segment: string): string;
22
- /**
23
- * Recursively removes titleMarkdown fields from a heading hierarchy
24
- */
25
- export declare function stripTitleMarkdown(hierarchy: HeadingHierarchy): Record<string, SitemapSection>;
26
- /**
27
- * Extracts prefix and title from an import path
28
- * e.g., "/path/to/app/docs-infra/components/page.mdx" -> { prefix: "/docs-infra/components/", title: "Docs Infra Components" }
29
- */
30
- export declare function extractPrefixAndTitle(absolutePath: string, rootContext: string): {
31
- prefix: string;
32
- title: string;
33
- };
34
24
  /**
35
25
  * Default loadServerPageIndex function that loads page index data from a markdown file.
36
26
  * This function uses process.cwd() as the root context for resolving relative paths.
@@ -41,9 +31,10 @@ export declare const loadServerPageIndex: LoadServerPageIndex;
41
31
  *
42
32
  * This factory function creates a LoadServerPageIndex implementation that:
43
33
  * 1. Reads the markdown file from the provided file path
44
- * 2. Parses the markdown to extract metadata using markdownToMetadata
45
- * 3. Enriches the metadata with prefix and title derived from the file path
46
- * 4. Returns a SitemapSectionData object with page data
34
+ * 2. Returns a cached `SitemapSectionData` when `cacheDir` is set and the markdown is unchanged
35
+ * 3. Otherwise parses the markdown to extract metadata using markdownToMetadata
36
+ * 4. Enriches the metadata with prefix and title derived from the file path
37
+ * 5. Pre-populates the cache (when `cacheDir` is set) for the next cold read
47
38
  *
48
39
  * @param options - Configuration options for the loader
49
40
  * @returns LoadServerPageIndex function that takes a file path and returns Promise<SitemapSectionData | null>
@@ -1,7 +1,9 @@
1
1
  import fs from 'node:fs/promises';
2
- import path from 'node:path';
3
2
  import { fileURLToPath } from 'node:url';
4
3
  import { markdownToMetadata } from "../syncPageIndex/metadataToMarkdown.mjs";
4
+ import { withFileCache } from "../cacheUtils/index.mjs";
5
+ import { enrichPageIndex } from "./enrichPageIndex.mjs";
6
+ import { resolvePageIndexCacheKey, PAGE_INDEX_CACHE_NAMESPACE } from "./resolvePageIndexCacheKey.mjs";
5
7
 
6
8
  /**
7
9
  * Options for creating a loadServerPageIndex function
@@ -11,86 +13,6 @@ import { markdownToMetadata } from "../syncPageIndex/metadataToMarkdown.mjs";
11
13
  * Function type for loading page index data from a markdown file
12
14
  */
13
15
 
14
- /**
15
- * Converts a path segment to a title
16
- * e.g., "docs-infra" -> "Docs Infra", "components" -> "Components"
17
- */
18
- export function pathSegmentToTitle(segment) {
19
- return segment.split('-').map(word => word.charAt(0).toUpperCase() + word.slice(1)).join(' ');
20
- }
21
-
22
- /**
23
- * Recursively removes titleMarkdown fields from a heading hierarchy
24
- */
25
- export function stripTitleMarkdown(hierarchy) {
26
- const result = {};
27
- for (const [key, value] of Object.entries(hierarchy)) {
28
- if (typeof value === 'object' && value !== null) {
29
- const {
30
- titleMarkdown,
31
- children,
32
- ...rest
33
- } = value;
34
- const strippedChildren = children ? stripTitleMarkdown(children) : {};
35
- result[key] = {
36
- ...rest,
37
- // Only include children if it has keys, otherwise set to undefined
38
- children: Object.keys(strippedChildren).length > 0 ? strippedChildren : undefined
39
- };
40
- }
41
- }
42
- return result;
43
- }
44
-
45
- /**
46
- * Extracts prefix and title from an import path
47
- * e.g., "/path/to/app/docs-infra/components/page.mdx" -> { prefix: "/docs-infra/components/", title: "Docs Infra Components" }
48
- */
49
- export function extractPrefixAndTitle(absolutePath, rootContext) {
50
- // Get the relative path from the root context
51
- const relativePath = path.relative(rootContext, absolutePath);
52
-
53
- // Extract the directory path (remove filename)
54
- const dirPath = path.dirname(relativePath);
55
-
56
- // Split into segments
57
- const allSegments = dirPath.split(path.sep);
58
-
59
- // Filter out segments:
60
- // - Remove leading 'src' and 'app' directory markers (only if they're at the start)
61
- // - Remove Next.js route groups (segments in parentheses like '(public)')
62
- // - Remove current directory markers ('.' and empty strings)
63
- const segments = allSegments.filter((seg, index) => {
64
- // Remove 'src' only if it's the first segment
65
- if (seg === 'src' && index === 0) {
66
- return false;
67
- }
68
- // Remove 'app' only if it's the first or second segment (after 'src')
69
- if (seg === 'app' && (index === 0 || index === 1 && allSegments[0] === 'src')) {
70
- return false;
71
- }
72
- // Filter out Next.js route groups (e.g., '(public)', '(content)')
73
- if (seg.startsWith('(') && seg.endsWith(')')) {
74
- return false;
75
- }
76
- // Filter out current directory markers
77
- if (seg === '.' || seg === '') {
78
- return false;
79
- }
80
- return true;
81
- });
82
-
83
- // Generate prefix with leading and trailing slashes
84
- const prefix = segments.length > 0 ? `/${segments.join('/')}/` : '/';
85
-
86
- // Generate title from path segments
87
- const title = segments.map(pathSegmentToTitle).join(' ');
88
- return {
89
- prefix,
90
- title
91
- };
92
- }
93
-
94
16
  /**
95
17
  * Default loadServerPageIndex function that loads page index data from a markdown file.
96
18
  * This function uses process.cwd() as the root context for resolving relative paths.
@@ -102,56 +24,42 @@ export const loadServerPageIndex = createLoadServerPageIndex();
102
24
  *
103
25
  * This factory function creates a LoadServerPageIndex implementation that:
104
26
  * 1. Reads the markdown file from the provided file path
105
- * 2. Parses the markdown to extract metadata using markdownToMetadata
106
- * 3. Enriches the metadata with prefix and title derived from the file path
107
- * 4. Returns a SitemapSectionData object with page data
27
+ * 2. Returns a cached `SitemapSectionData` when `cacheDir` is set and the markdown is unchanged
28
+ * 3. Otherwise parses the markdown to extract metadata using markdownToMetadata
29
+ * 4. Enriches the metadata with prefix and title derived from the file path
30
+ * 5. Pre-populates the cache (when `cacheDir` is set) for the next cold read
108
31
  *
109
32
  * @param options - Configuration options for the loader
110
33
  * @returns LoadServerPageIndex function that takes a file path and returns Promise<SitemapSectionData | null>
111
34
  */
112
35
  export function createLoadServerPageIndex(options = {}) {
113
36
  const rootContext = options.rootContext ?? process.cwd();
114
- return async function loadPageIndex(filePath) {
115
- // Convert file:// URLs to proper file system paths for reading the file
37
+ const {
38
+ cacheDir
39
+ } = options;
40
+ return function loadPageIndex(filePath) {
41
+ // Convert file:// URLs to proper file system paths for reading the file.
116
42
  // Using fileURLToPath handles Windows drive letters correctly (e.g., file:///C:/... → C:\...)
117
43
  const absolutePath = filePath.startsWith('file://') ? fileURLToPath(filePath) : filePath;
118
-
119
- // Extract prefix and title from the import path
120
- const {
121
- prefix,
122
- title: generatedTitle
123
- } = extractPrefixAndTitle(absolutePath, rootContext);
124
-
125
- // Read the markdown file
126
- const markdownContent = await fs.readFile(absolutePath, 'utf-8');
127
-
128
- // Parse the markdown to extract metadata
129
- const metadata = await markdownToMetadata(markdownContent);
130
- if (!metadata) {
131
- return null;
132
- }
133
-
134
- // Add prefix and override title with the generated one from the path
135
- // Strip descriptionMarkdown and titleMarkdown to reduce bundle size
136
- const enrichedMetadata = {
137
- ...metadata,
138
- prefix,
139
- // Use the generated title from the path (override markdown's H1)
140
- title: generatedTitle,
141
- // Strip markdown AST fields from each page to reduce size
142
- pages: metadata.pages.map(page => {
143
- const {
144
- descriptionMarkdown,
145
- sections,
146
- ...pageWithoutMarkdown
147
- } = page;
148
- return {
149
- ...pageWithoutMarkdown,
150
- // Strip titleMarkdown from sections hierarchy
151
- sections: sections ? stripTitleMarkdown(sections) : undefined
152
- };
153
- })
154
- };
155
- return enrichedMetadata;
44
+ const cacheRef = cacheDir ? {
45
+ cacheDir,
46
+ namespace: PAGE_INDEX_CACHE_NAMESPACE,
47
+ cacheKey: resolvePageIndexCacheKey(absolutePath, rootContext)
48
+ } : undefined;
49
+
50
+ // The cache stores the enriched read-model keyed by the markdown hash, so a hit skips the
51
+ // markdownToMetadata parse.
52
+ return withFileCache({
53
+ ref: cacheRef,
54
+ readOrigin: () => fs.readFile(absolutePath, 'utf-8'),
55
+ getCacheContent: markdownContent => markdownContent,
56
+ processor: async markdownContent => {
57
+ const metadata = await markdownToMetadata(markdownContent);
58
+ if (!metadata) {
59
+ return null;
60
+ }
61
+ return enrichPageIndex(metadata, absolutePath, rootContext);
62
+ }
63
+ });
156
64
  };
157
65
  }
@@ -0,0 +1,13 @@
1
+ /** Cache namespace (subdirectory) for page-index entries. */
2
+ export declare const PAGE_INDEX_CACHE_NAMESPACE = "pages-index";
3
+ /**
4
+ * Derives the cache key for a page-index file from its path, reusing the same
5
+ * route derivation as the loaded data so a writer and reader of the same index
6
+ * agree on the cache location.
7
+ *
8
+ * @example
9
+ * resolvePageIndexCacheKey('/root/src/app/components/page.mdx', '/root') // 'components'
10
+ * resolvePageIndexCacheKey('/root/app/utilities/parsing/page.mdx', '/root') // 'utilities/parsing'
11
+ * resolvePageIndexCacheKey('/root/app/page.mdx', '/root') // 'index' (root)
12
+ */
13
+ export declare function resolvePageIndexCacheKey(absolutePath: string, rootContext: string): string;
@@ -0,0 +1,23 @@
1
+ import { extractPrefixAndTitle } from "./extractPrefixAndTitle.mjs";
2
+
3
+ /** Cache namespace (subdirectory) for page-index entries. */
4
+ export const PAGE_INDEX_CACHE_NAMESPACE = 'pages-index';
5
+
6
+ /**
7
+ * Derives the cache key for a page-index file from its path, reusing the same
8
+ * route derivation as the loaded data so a writer and reader of the same index
9
+ * agree on the cache location.
10
+ *
11
+ * @example
12
+ * resolvePageIndexCacheKey('/root/src/app/components/page.mdx', '/root') // 'components'
13
+ * resolvePageIndexCacheKey('/root/app/utilities/parsing/page.mdx', '/root') // 'utilities/parsing'
14
+ * resolvePageIndexCacheKey('/root/app/page.mdx', '/root') // 'index' (root)
15
+ */
16
+ export function resolvePageIndexCacheKey(absolutePath, rootContext) {
17
+ const {
18
+ prefix
19
+ } = extractPrefixAndTitle(absolutePath, rootContext);
20
+ // prefix is like '/components/' or '/utilities/parsing/' (or '/' for the root index).
21
+ const segments = prefix.split('/').filter(Boolean);
22
+ return segments.length > 0 ? segments.join('/') : 'index';
23
+ }
@@ -1,7 +1,7 @@
1
1
  import type { Root as HastRoot } from 'hast';
2
- import { type TransformHtmlCodeBlockOptions } from "../transformHtmlCodeBlock/transformHtmlCodeBlock.mjs";
3
- import { type TypesMeta } from "../loadServerTypesMeta/index.mjs";
4
- import { type TypesOutputFormat } from "./hastTypeUtils.mjs";
2
+ import type { TransformHtmlCodeBlockOptions } from "../transformHtmlCodeBlock/transformHtmlCodeBlock.mjs";
3
+ import type { TypesMeta } from "../loadServerTypesMeta/index.mjs";
4
+ import type { TypesOutputFormat } from "./hastTypeUtils.mjs";
5
5
  /**
6
6
  * Result of the highlightTypes function.
7
7
  */
@@ -8,12 +8,12 @@
8
8
  * 4. Converts defaultText to syntax-highlighted HAST (default field)
9
9
  */
10
10
  import type { Root as HastRoot } from 'hast';
11
- import { type TransformHtmlCodeBlockOptions } from "../transformHtmlCodeBlock/transformHtmlCodeBlock.mjs";
12
- import { type TypesMeta, type ComponentTypeMeta, type HookTypeMeta, type FunctionTypeMeta, type ClassTypeMeta, type RawTypeMeta, type FormattedProperty, type FormattedParameter } from "../loadServerTypesMeta/index.mjs";
11
+ import type { TransformHtmlCodeBlockOptions } from "../transformHtmlCodeBlock/transformHtmlCodeBlock.mjs";
12
+ import type { TypesMeta, ComponentTypeMeta, HookTypeMeta, FunctionTypeMeta, ClassTypeMeta, RawTypeMeta, FormattedProperty, FormattedParameter } from "../loadServerTypesMeta/index.mjs";
13
13
  import type { FormattedMethod } from "../loadServerTypesMeta/formatClass.mjs";
14
14
  import type { EnumMemberMeta } from "../loadServerTypesMeta/formatRaw.mjs";
15
- import { type FormatInlineTypeOptions } from "./typeHighlighting.mjs";
16
- import { type SerializedHastRoot, type SerializedHastCompressed, type TypesOutputFormat } from "./hastTypeUtils.mjs";
15
+ import type { FormatInlineTypeOptions } from "./typeHighlighting.mjs";
16
+ import type { SerializedHastRoot, SerializedHastCompressed, TypesOutputFormat } from "./hastTypeUtils.mjs";
17
17
  /** A HAST root or its serialized/compressed wrapper. */
18
18
  type HastField = HastRoot | SerializedHastRoot | SerializedHastCompressed;
19
19
  /**
@@ -1,5 +1,5 @@
1
- import { type HighlightedTypesMeta, type HighlightedComponentTypeMeta, type HighlightedHookTypeMeta, type HighlightedFunctionTypeMeta, type HighlightedClassTypeMeta, type HighlightedMethod, type HighlightedRawTypeMeta, type HighlightedEnumMemberMeta, type HighlightedProperty, type HighlightedParameter, type HighlightedClassProperty } from "./highlightTypesMeta.mjs";
2
- import { type SyncTypesOptions } from "../syncTypes/index.mjs";
1
+ import type { HighlightedTypesMeta, HighlightedComponentTypeMeta, HighlightedHookTypeMeta, HighlightedFunctionTypeMeta, HighlightedClassTypeMeta, HighlightedMethod, HighlightedRawTypeMeta, HighlightedEnumMemberMeta, HighlightedProperty, HighlightedParameter, HighlightedClassProperty } from "./highlightTypesMeta.mjs";
2
+ import type { SyncTypesOptions } from "../syncTypes/index.mjs";
3
3
  import type { ExportData } from "../../abstractCreateTypes/index.mjs";
4
4
  import type { TypesOutputFormat } from "./hastTypeUtils.mjs";
5
5
  import type { TransformHtmlCodeBlockOptions } from "../transformHtmlCodeBlock/transformHtmlCodeBlock.mjs";