@mui/internal-docs-infra 0.11.1-canary.9 → 0.11.1

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 (319) hide show
  1. package/ChunkProvider/ChunkContext.d.mts +10 -0
  2. package/ChunkProvider/ChunkContext.mjs +15 -0
  3. package/ChunkProvider/ChunkProvider.d.mts +14 -0
  4. package/ChunkProvider/ChunkProvider.mjs +38 -0
  5. package/ChunkProvider/PreloadContext.d.mts +14 -0
  6. package/ChunkProvider/PreloadContext.mjs +18 -0
  7. package/ChunkProvider/PreloadProvider.d.mts +13 -0
  8. package/ChunkProvider/PreloadProvider.mjs +33 -0
  9. package/ChunkProvider/index.d.mts +7 -0
  10. package/ChunkProvider/index.mjs +7 -0
  11. package/ChunkProvider/types.d.mts +23 -0
  12. package/ChunkProvider/types.mjs +1 -0
  13. package/ChunkProvider/usePreload.d.mts +8 -0
  14. package/ChunkProvider/usePreload.mjs +21 -0
  15. package/CodeControllerContext/CodeControllerContext.d.mts +11 -0
  16. package/CodeControllerContext/CodeControllerContext.mjs +2 -1
  17. package/CodeHighlighter/CodeHighlighter.d.mts +15 -1
  18. package/CodeHighlighter/CodeHighlighter.mjs +97 -319
  19. package/CodeHighlighter/CodeHighlighterChunk.d.mts +42 -0
  20. package/CodeHighlighter/CodeHighlighterChunk.mjs +77 -0
  21. package/CodeHighlighter/CodeHighlighterClient.mjs +597 -128
  22. package/CodeHighlighter/CodeHighlighterContext.d.mts +57 -1
  23. package/CodeHighlighter/CodeHighlighterFallbackContext.d.mts +14 -2
  24. package/CodeHighlighter/CodeHighlighterFallbackContext.mjs +1 -3
  25. package/CodeHighlighter/CodeInitialSourceLoader.d.mts +10 -0
  26. package/CodeHighlighter/CodeInitialSourceLoader.mjs +108 -0
  27. package/CodeHighlighter/CodeSourceLoader.d.mts +11 -0
  28. package/CodeHighlighter/CodeSourceLoader.mjs +128 -0
  29. package/CodeHighlighter/buildCodeHighlighterChunkProps.d.mts +47 -0
  30. package/CodeHighlighter/buildCodeHighlighterChunkProps.mjs +61 -0
  31. package/CodeHighlighter/buildStringFallback.d.mts +29 -0
  32. package/CodeHighlighter/buildStringFallback.mjs +42 -0
  33. package/CodeHighlighter/codeToFallbackProps.d.mts +31 -2
  34. package/CodeHighlighter/codeToFallbackProps.mjs +347 -42
  35. package/CodeHighlighter/createClientProps.d.mts +17 -0
  36. package/CodeHighlighter/createClientProps.mjs +78 -0
  37. package/CodeHighlighter/errors.d.mts +6 -0
  38. package/CodeHighlighter/errors.mjs +10 -0
  39. package/CodeHighlighter/fallbackCompression.d.mts +96 -0
  40. package/CodeHighlighter/fallbackCompression.mjs +253 -0
  41. package/CodeHighlighter/fallbackFormat.d.mts +137 -0
  42. package/CodeHighlighter/fallbackFormat.mjs +422 -0
  43. package/CodeHighlighter/index.d.mts +4 -1
  44. package/CodeHighlighter/index.mjs +3 -1
  45. package/CodeHighlighter/mergeComments.d.mts +38 -0
  46. package/CodeHighlighter/mergeComments.mjs +80 -0
  47. package/CodeHighlighter/prepareInitialSource.d.mts +42 -0
  48. package/CodeHighlighter/prepareInitialSource.mjs +292 -0
  49. package/CodeHighlighter/resolveFallbackCritical.d.mts +23 -0
  50. package/CodeHighlighter/resolveFallbackCritical.mjs +44 -0
  51. package/CodeHighlighter/types.d.mts +272 -8
  52. package/CodeHighlighter/useCodeFallback.d.mts +94 -0
  53. package/CodeHighlighter/useCodeFallback.mjs +204 -0
  54. package/CodeHighlighter/useGrammarsReady.d.mts +18 -0
  55. package/CodeHighlighter/useGrammarsReady.mjs +45 -0
  56. package/CodeHighlighter/useSpeculativeCodePreload.d.mts +26 -0
  57. package/CodeHighlighter/useSpeculativeCodePreload.mjs +40 -0
  58. package/CodeHighlighter/useSpeculativeEditingPreload.d.mts +33 -0
  59. package/CodeHighlighter/useSpeculativeEditingPreload.mjs +58 -0
  60. package/CodeHighlighter/useSpeculativeGrammarPreload.d.mts +23 -0
  61. package/CodeHighlighter/useSpeculativeGrammarPreload.mjs +31 -0
  62. package/CodeHighlighter/useSpeculativeUseCodePreload.d.mts +22 -0
  63. package/CodeHighlighter/useSpeculativeUseCodePreload.mjs +41 -0
  64. package/CodeProvider/CodeContext.d.mts +47 -12
  65. package/CodeProvider/CodeContext.mjs +7 -0
  66. package/CodeProvider/CodeProvider.d.mts +4 -2
  67. package/CodeProvider/CodeProvider.mjs +40 -102
  68. package/CodeProvider/CodeProviderLazy.d.mts +40 -0
  69. package/CodeProvider/CodeProviderLazy.mjs +96 -0
  70. package/CodeProvider/constants.d.mts +26 -0
  71. package/CodeProvider/constants.mjs +24 -0
  72. package/CodeProvider/createParseSourceWorkerClient.d.mts +6 -0
  73. package/CodeProvider/createParseSourceWorkerClient.mjs +22 -2
  74. package/CodeProvider/index.d.mts +2 -1
  75. package/CodeProvider/index.mjs +9 -1
  76. package/CodeProvider/parseSourceWorker.mjs +33 -0
  77. package/CodeProvider/useCodeProviderValue.d.mts +54 -0
  78. package/CodeProvider/useCodeProviderValue.mjs +188 -0
  79. package/CoordinatedLazy/ChunkServerLoader.d.mts +25 -0
  80. package/CoordinatedLazy/ChunkServerLoader.mjs +97 -0
  81. package/CoordinatedLazy/CoordinatedContentContext.d.mts +15 -0
  82. package/CoordinatedLazy/CoordinatedContentContext.mjs +22 -0
  83. package/CoordinatedLazy/CoordinatedFallbackContext.d.mts +11 -0
  84. package/CoordinatedLazy/CoordinatedFallbackContext.mjs +13 -0
  85. package/CoordinatedLazy/CoordinatedGateContext.d.mts +14 -0
  86. package/CoordinatedLazy/CoordinatedGateContext.mjs +19 -0
  87. package/CoordinatedLazy/CoordinatedLazy.d.mts +14 -0
  88. package/CoordinatedLazy/CoordinatedLazy.mjs +86 -0
  89. package/CoordinatedLazy/CoordinatedLazyClient.d.mts +24 -0
  90. package/CoordinatedLazy/CoordinatedLazyClient.mjs +65 -0
  91. package/CoordinatedLazy/LazyContent.d.mts +26 -0
  92. package/CoordinatedLazy/LazyContent.mjs +80 -0
  93. package/CoordinatedLazy/LazyContentServer.d.mts +18 -0
  94. package/CoordinatedLazy/LazyContentServer.mjs +25 -0
  95. package/CoordinatedLazy/buildChunkRenderInputs.d.mts +8 -0
  96. package/CoordinatedLazy/buildChunkRenderInputs.mjs +35 -0
  97. package/CoordinatedLazy/createCoordinatedLazy.d.mts +32 -0
  98. package/CoordinatedLazy/createCoordinatedLazy.mjs +127 -0
  99. package/CoordinatedLazy/index.d.mts +14 -0
  100. package/CoordinatedLazy/index.mjs +18 -0
  101. package/CoordinatedLazy/resolveChunkRender.d.mts +26 -0
  102. package/CoordinatedLazy/resolveChunkRender.mjs +73 -0
  103. package/CoordinatedLazy/types.d.mts +408 -0
  104. package/CoordinatedLazy/types.mjs +1 -0
  105. package/CoordinatedLazy/useChunk.d.mts +30 -0
  106. package/CoordinatedLazy/useChunk.mjs +135 -0
  107. package/CoordinatedLazy/useCoordinatedFallback.d.mts +12 -0
  108. package/CoordinatedLazy/useCoordinatedFallback.mjs +40 -0
  109. package/CoordinatedLazy/useCoordinatedSwap.d.mts +16 -0
  110. package/CoordinatedLazy/useCoordinatedSwap.mjs +124 -0
  111. package/LICENSE +1 -1
  112. package/abstractCreateDemo/abstractCreateDemo.d.mts +54 -3
  113. package/abstractCreateDemo/abstractCreateDemo.mjs +47 -7
  114. package/abstractCreateDemo/resolveDemoFlag.d.mts +20 -0
  115. package/abstractCreateDemo/resolveDemoFlag.mjs +25 -0
  116. package/abstractCreateStream/abstractCreateStream.d.mts +18 -0
  117. package/abstractCreateStream/abstractCreateStream.mjs +45 -0
  118. package/abstractCreateStream/index.d.mts +2 -0
  119. package/abstractCreateStream/index.mjs +1 -0
  120. package/abstractCreateStream/types.d.mts +34 -0
  121. package/abstractCreateStream/types.mjs +1 -0
  122. package/abstractCreateTypes/TypeCode.mjs +12 -11
  123. package/abstractCreateTypes/typesToJsx.mjs +30 -9
  124. package/cli/ensureDemoClients.mjs +4 -148
  125. package/cli/ensureDemoPages.d.mts +45 -0
  126. package/cli/ensureDemoPages.mjs +99 -0
  127. package/cli/fileUtils/index.d.mts +11 -0
  128. package/cli/fileUtils/index.mjs +48 -0
  129. package/cli/findDemoIndexFiles.d.mts +15 -0
  130. package/cli/findDemoIndexFiles.mjs +121 -0
  131. package/cli/index.mjs +1 -1
  132. package/cli/loadNextConfig.d.mts +25 -0
  133. package/cli/loadNextConfig.mjs +60 -1
  134. package/cli/runBrowser.mjs +1 -1
  135. package/cli/runValidate.mjs +44 -1
  136. package/package.json +84 -4
  137. package/pipeline/enhanceCodeEmphasis/enhanceCodeEmphasis.mjs +30 -0
  138. package/pipeline/enhanceCodeEmphasis/enhanceCodeEmphasisLazy.d.mts +17 -0
  139. package/pipeline/enhanceCodeEmphasis/enhanceCodeEmphasisLazy.mjs +52 -0
  140. package/pipeline/hastUtils/frameFallbackFromSpans.d.mts +18 -0
  141. package/pipeline/hastUtils/frameFallbackFromSpans.mjs +24 -0
  142. package/pipeline/hastUtils/hast.d.mts +27 -0
  143. package/pipeline/hastUtils/hastCompression.d.mts +3 -1
  144. package/pipeline/hastUtils/hastCompression.mjs +9 -1
  145. package/pipeline/hastUtils/hastDecompress.mjs +10 -4
  146. package/pipeline/hastUtils/hastDictionary.mjs +9 -0
  147. package/pipeline/hastUtils/hastUtils.d.mts +4 -3
  148. package/pipeline/hastUtils/hastUtils.mjs +24 -12
  149. package/pipeline/hastUtils/index.d.mts +2 -1
  150. package/pipeline/hastUtils/index.mjs +2 -1
  151. package/pipeline/hastUtils/stripHighlightingSpans.d.mts +6 -2
  152. package/pipeline/hastUtils/stripHighlightingSpans.mjs +22 -10
  153. package/pipeline/lintJavascriptDemoFocus/lintJavascriptDemoFocus.mjs +10 -7
  154. package/pipeline/loadIsomorphicCodeVariant/applyCodeTransform.d.mts +31 -13
  155. package/pipeline/loadIsomorphicCodeVariant/applyCodeTransform.mjs +50 -55
  156. package/pipeline/loadIsomorphicCodeVariant/applyCodeTransformWithComments.d.mts +78 -0
  157. package/pipeline/loadIsomorphicCodeVariant/applyCodeTransformWithComments.mjs +405 -0
  158. package/pipeline/loadIsomorphicCodeVariant/computeHastDeltas.d.mts +5 -5
  159. package/pipeline/loadIsomorphicCodeVariant/computeHastDeltas.mjs +36 -66
  160. package/pipeline/loadIsomorphicCodeVariant/decodeHastSource.d.mts +23 -0
  161. package/pipeline/loadIsomorphicCodeVariant/decodeHastSource.mjs +92 -0
  162. package/pipeline/loadIsomorphicCodeVariant/decodeSource.d.mts +19 -0
  163. package/pipeline/loadIsomorphicCodeVariant/decodeSource.mjs +25 -0
  164. package/pipeline/loadIsomorphicCodeVariant/decodeSourceToText.d.mts +17 -0
  165. package/pipeline/loadIsomorphicCodeVariant/decodeSourceToText.mjs +26 -0
  166. package/pipeline/loadIsomorphicCodeVariant/diffHast.d.mts +26 -2
  167. package/pipeline/loadIsomorphicCodeVariant/diffHast.mjs +563 -19
  168. package/pipeline/loadIsomorphicCodeVariant/embedTransforms.d.mts +49 -0
  169. package/pipeline/loadIsomorphicCodeVariant/embedTransforms.mjs +152 -0
  170. package/pipeline/loadIsomorphicCodeVariant/findExpandingRanges.d.mts +51 -0
  171. package/pipeline/loadIsomorphicCodeVariant/findExpandingRanges.mjs +161 -0
  172. package/pipeline/loadIsomorphicCodeVariant/flattenCodeVariant.mjs +6 -3
  173. package/pipeline/loadIsomorphicCodeVariant/getAvailableTransforms.d.mts +12 -0
  174. package/pipeline/loadIsomorphicCodeVariant/getAvailableTransforms.mjs +44 -0
  175. package/pipeline/loadIsomorphicCodeVariant/getInitialVisibleSourceLines.d.mts +16 -0
  176. package/pipeline/loadIsomorphicCodeVariant/getInitialVisibleSourceLines.mjs +74 -0
  177. package/pipeline/loadIsomorphicCodeVariant/loadCodeFallback.mjs +17 -5
  178. package/pipeline/loadIsomorphicCodeVariant/loadIsomorphicCodeVariant.mjs +229 -15
  179. package/pipeline/loadIsomorphicCodeVariant/transformSource.d.mts +2 -2
  180. package/pipeline/loadIsomorphicCodeVariant/transformSource.mjs +56 -22
  181. package/pipeline/loadPrecomputedCodeHighlighter/loadPrecomputedCodeHighlighter.d.mts +18 -0
  182. package/pipeline/loadPrecomputedCodeHighlighter/loadPrecomputedCodeHighlighter.mjs +11 -7
  183. package/pipeline/loadServerTypes/hastTypeUtils.d.mts +2 -2
  184. package/pipeline/loadServerTypes/hastTypeUtils.mjs +4 -4
  185. package/pipeline/loadServerTypes/loadServerTypes.mjs +1 -1
  186. package/pipeline/loadServerTypesMeta/extractJSDocText.d.mts +14 -0
  187. package/pipeline/loadServerTypesMeta/extractJSDocText.mjs +60 -0
  188. package/pipeline/loadServerTypesMeta/processTypes.mjs +43 -46
  189. package/pipeline/loadServerTypesText/order.mjs +1 -1
  190. package/pipeline/loadServerTypesText/parseTypesMarkdown.mjs +3 -1
  191. package/pipeline/loaderUtils/index.d.mts +0 -1
  192. package/pipeline/loaderUtils/index.mjs +0 -1
  193. package/pipeline/loaderUtils/parseImportsAndComments.d.mts +5 -1
  194. package/pipeline/loaderUtils/parseImportsAndComments.mjs +19 -9
  195. package/pipeline/loaderUtils/resolveModulePath.mjs +23 -1
  196. package/pipeline/parseCreateFactoryCall/parseCreateFactoryCall.d.mts +12 -0
  197. package/pipeline/parseCreateFactoryCall/parseCreateFactoryCall.mjs +17 -13
  198. package/pipeline/parseSource/addLineGutters.mjs +45 -11
  199. package/pipeline/parseSource/calculateFrameRanges.d.mts +22 -0
  200. package/pipeline/parseSource/calculateFrameRanges.mjs +69 -25
  201. package/pipeline/parseSource/detectGrammarScopes.d.mts +13 -0
  202. package/pipeline/parseSource/detectGrammarScopes.mjs +35 -0
  203. package/pipeline/parseSource/extendSyntaxTokens.mjs +501 -43
  204. package/pipeline/parseSource/frameVisibility.d.mts +47 -0
  205. package/pipeline/parseSource/frameVisibility.mjs +114 -0
  206. package/pipeline/parseSource/grammarCache.d.mts +33 -0
  207. package/pipeline/parseSource/grammarCache.mjs +73 -0
  208. package/pipeline/parseSource/grammarLoaders.d.mts +14 -0
  209. package/pipeline/parseSource/grammarLoaders.mjs +24 -0
  210. package/pipeline/parseSource/grammarMaps.d.mts +21 -1
  211. package/pipeline/parseSource/grammarMaps.mjs +36 -0
  212. package/pipeline/parseSource/isFrameSpan.d.mts +19 -0
  213. package/pipeline/parseSource/isFrameSpan.mjs +24 -0
  214. package/pipeline/parseSource/parseSource.d.mts +41 -6
  215. package/pipeline/parseSource/parseSource.mjs +184 -36
  216. package/pipeline/parseSource/redistributeFrameFallbacks.d.mts +40 -0
  217. package/pipeline/parseSource/redistributeFrameFallbacks.mjs +138 -0
  218. package/pipeline/parseSource/restructureFrames.d.mts +5 -0
  219. package/pipeline/parseSource/restructureFrames.mjs +179 -16
  220. package/pipeline/syncPageIndex/metadataToMarkdown.mjs +6 -2
  221. package/pipeline/transformHtmlCodeBlock/transformHtmlCodeBlock.d.mts +26 -0
  222. package/pipeline/transformHtmlCodeBlock/transformHtmlCodeBlock.mjs +181 -114
  223. package/pipeline/transformHtmlCodeInline/removeSuffixFromHighlightedNodes.d.mts +12 -0
  224. package/pipeline/transformHtmlCodeInline/removeSuffixFromHighlightedNodes.mjs +52 -0
  225. package/pipeline/transformHtmlCodeInline/transformHtmlCodeInline.mjs +22 -1
  226. package/pipeline/transformTypescriptToJavascript/removeTypes.d.mts +5 -8
  227. package/pipeline/transformTypescriptToJavascript/removeTypes.mjs +27 -93
  228. package/useCode/EditableEngine.d.mts +233 -0
  229. package/useCode/EditableEngine.mjs +1712 -0
  230. package/useCode/EditingEngine.d.mts +13 -0
  231. package/useCode/EditingEngine.mjs +14 -0
  232. package/useCode/Pre.browser.mjs +5 -1
  233. package/useCode/Pre.d.mts +127 -1
  234. package/useCode/Pre.mjs +417 -165
  235. package/useCode/SourceEditingEngine.d.mts +50 -0
  236. package/useCode/SourceEditingEngine.mjs +461 -0
  237. package/useCode/TransformEngine.d.mts +39 -0
  238. package/useCode/TransformEngine.mjs +208 -0
  239. package/useCode/editingEngineCache.d.mts +29 -0
  240. package/useCode/editingEngineCache.mjs +68 -0
  241. package/useCode/sourceLineCounts.d.mts +80 -0
  242. package/useCode/sourceLineCounts.mjs +284 -0
  243. package/useCode/subscribeToggleNudge.d.mts +3 -0
  244. package/useCode/subscribeToggleNudge.mjs +95 -0
  245. package/useCode/transformEngineCache.d.mts +21 -0
  246. package/useCode/transformEngineCache.mjs +60 -0
  247. package/useCode/useCode.d.mts +140 -1
  248. package/useCode/useCode.mjs +250 -19
  249. package/useCode/useCodeUtils.d.mts +131 -20
  250. package/useCode/useCodeUtils.mjs +267 -194
  251. package/useCode/useCopyFunctionality.d.mts +13 -1
  252. package/useCode/useCopyFunctionality.mjs +39 -9
  253. package/useCode/useEditable.browser.mjs +10 -2
  254. package/useCode/useEditable.d.mts +27 -106
  255. package/useCode/useEditable.integration.browser.d.mts +1 -0
  256. package/useCode/useEditable.integration.browser.mjs +870 -0
  257. package/useCode/useEditable.mjs +198 -1247
  258. package/useCode/useEditableUtils.d.mts +50 -1
  259. package/useCode/useEditableUtils.mjs +29 -0
  260. package/useCode/useFileNavigation.d.mts +91 -3
  261. package/useCode/useFileNavigation.mjs +201 -41
  262. package/useCode/useHighlightGate.d.mts +17 -0
  263. package/useCode/useHighlightGate.mjs +147 -0
  264. package/useCode/useSourceEditing.d.mts +8 -0
  265. package/useCode/useSourceEditing.mjs +158 -314
  266. package/useCode/useSourceEnhancing.d.mts +5 -1
  267. package/useCode/useSourceEnhancing.mjs +22 -36
  268. package/useCode/useTransformManagement.d.mts +93 -5
  269. package/useCode/useTransformManagement.mjs +496 -28
  270. package/useCode/useTransitionPhase.d.mts +24 -0
  271. package/useCode/useTransitionPhase.mjs +49 -0
  272. package/useCode/useUIState.d.mts +2 -2
  273. package/useCode/useUIState.mjs +8 -8
  274. package/useCode/useVariantSelection.d.mts +130 -6
  275. package/useCode/useVariantSelection.mjs +529 -93
  276. package/useCodeWindow/useCodeWindow.d.mts +19 -2
  277. package/useCodeWindow/useCodeWindow.mjs +98 -71
  278. package/useCoordinated/coordinatePreference.d.mts +439 -0
  279. package/useCoordinated/coordinatePreference.mjs +951 -0
  280. package/useCoordinated/coordinatePreference.testUtils.d.mts +21 -0
  281. package/useCoordinated/coordinatePreference.testUtils.mjs +69 -0
  282. package/useCoordinated/createSettleGate.d.mts +96 -0
  283. package/useCoordinated/createSettleGate.mjs +171 -0
  284. package/useCoordinated/index.d.mts +8 -0
  285. package/useCoordinated/index.mjs +8 -0
  286. package/useCoordinated/layoutShiftGate.d.mts +24 -0
  287. package/useCoordinated/layoutShiftGate.mjs +79 -0
  288. package/useCoordinated/pageSettleGate.d.mts +11 -0
  289. package/useCoordinated/pageSettleGate.mjs +13 -0
  290. package/useCoordinated/scheduleTasks.d.mts +23 -0
  291. package/useCoordinated/scheduleTasks.mjs +45 -0
  292. package/useCoordinated/useCoordinated.d.mts +193 -0
  293. package/useCoordinated/useCoordinated.mjs +469 -0
  294. package/useCoordinated/useCoordinatedLazy.d.mts +17 -0
  295. package/useCoordinated/useCoordinatedLazy.mjs +38 -0
  296. package/useCoordinated/useCoordinatedLocalStorage.d.mts +16 -0
  297. package/useCoordinated/useCoordinatedLocalStorage.mjs +22 -0
  298. package/useCoordinated/useCoordinatedPreference.d.mts +20 -0
  299. package/useCoordinated/useCoordinatedPreference.mjs +26 -0
  300. package/useCoordinated/useSettleGate.d.mts +11 -0
  301. package/useCoordinated/useSettleGate.mjs +34 -0
  302. package/useDemo/exportVariant.d.mts +12 -5
  303. package/useDemo/exportVariant.mjs +59 -5
  304. package/useDemo/useDemo.d.mts +5 -2
  305. package/useScrollAnchor/useScrollAnchor.mjs +28 -5
  306. package/useStream/index.d.mts +6 -0
  307. package/useStream/index.mjs +6 -0
  308. package/useStream/streamChunks.d.mts +23 -0
  309. package/useStream/streamChunks.mjs +85 -0
  310. package/useStream/types.d.mts +45 -0
  311. package/useStream/types.mjs +1 -0
  312. package/useStream/useStream.d.mts +57 -0
  313. package/useStream/useStream.mjs +119 -0
  314. package/useStream/useStreamController.d.mts +15 -0
  315. package/useStream/useStreamController.mjs +90 -0
  316. package/withDocsInfra/withDocsInfra.d.mts +19 -0
  317. package/withDocsInfra/withDocsInfra.mjs +13 -5
  318. package/pipeline/loaderUtils/convertCommentsToOneIndexed.d.mts +0 -8
  319. package/pipeline/loaderUtils/convertCommentsToOneIndexed.mjs +0 -16
@@ -1,14 +1,17 @@
1
1
  import * as path from 'path-module';
2
2
  import { compressHastAsync } from "../hastUtils/index.mjs";
3
+ import { buildRootFallback, buildCriticalFallback, fallbackToText } from "../../CodeHighlighter/fallbackFormat.mjs";
4
+ import { getInitialVisibleFrames } from "../parseSource/frameVisibility.mjs";
3
5
  import { transformSource } from "./transformSource.mjs";
4
6
  import { diffHast } from "./diffHast.mjs";
7
+ import { isFrameSpan } from "../parseSource/isFrameSpan.mjs";
5
8
  import { getFileNameFromUrl, getLanguageFromExtension, normalizeLanguage } from "../loaderUtils/index.mjs";
6
- import { convertCommentsToOneIndexed } from "../loaderUtils/convertCommentsToOneIndexed.mjs";
7
9
  import { mergeExternals } from "../loaderUtils/mergeExternals.mjs";
8
10
  import { applyUrlPrefixToVariant } from "../loaderUtils/applyUrlPrefix.mjs";
9
11
  import { performanceMeasure } from "../loadPrecomputedCodeHighlighter/performanceLogger.mjs";
10
12
  import { starryNightGutter } from "../parseSource/addLineGutters.mjs";
11
13
  import { applyEnhancers } from "./runSourceEnhancers.mjs";
14
+ import { embedTransformsInRoot, splitTransformsForEmbed } from "./embedTransforms.mjs";
12
15
 
13
16
  /**
14
17
  * Check if a path is absolute (either filesystem absolute or URL)
@@ -17,6 +20,23 @@ function isAbsolutePath(filePath) {
17
20
  return path.isAbsolute(filePath) || filePath.includes('://');
18
21
  }
19
22
 
23
+ /**
24
+ * Removes the per-frame `data.fallback` text from each `span.frame` before the
25
+ * hast is serialized. The variant-level root fallback already carries this text
26
+ * (and `redistributeRootFallback` puts it back on decode), so keeping it on the
27
+ * stored tree would duplicate it in every payload.
28
+ */
29
+ function stripFrameFallbacks(root) {
30
+ for (const child of root.children) {
31
+ if (child.type !== 'element' || child.tagName !== 'span' || !child.data) {
32
+ continue;
33
+ }
34
+ if (isFrameSpan(child) && 'fallback' in child.data) {
35
+ delete child.data.fallback;
36
+ }
37
+ }
38
+ }
39
+
20
40
  /**
21
41
  * Generate a conflict-free filename for globalsCode files.
22
42
  * Strategy:
@@ -158,9 +178,15 @@ function normalizePathKey(key) {
158
178
  async function loadSingleFile(variantName, fileName, source, url, loadSource, sourceParser, sourceTransformers, sourceEnhancers, loadSourceCache, transforms, options = {}, allFilesListed = false, knownExtraFiles = new Set(), language, variantComments) {
159
179
  const {
160
180
  disableTransforms = false,
161
- disableParsing = false
181
+ disableParsing = false,
182
+ framePlainFallback = false
162
183
  } = options;
163
184
  let finalSource = source;
185
+ let finalFallback;
186
+ let finalFallbackCritical;
187
+ let finalTotalLines;
188
+ let finalFocusedLines;
189
+ let finalCollapsible;
164
190
  let extraFilesFromSource;
165
191
  let extraDependenciesFromSource;
166
192
  let externalsFromSource;
@@ -249,14 +275,16 @@ async function loadSingleFile(variantName, fileName, source, url, loadSource, so
249
275
  if (error instanceof Error && (error.message.startsWith('Invalid extraFiles from loadSource:') || error.message.startsWith('Invalid extraDependencies from loadSource:') || error.message.startsWith('Unexpected files discovered via loadSource when allFilesListed=true'))) {
250
276
  throw error;
251
277
  }
252
- throw new Error(`Failed to load source code (variant: ${variantName}, file: ${fileName}, url: ${url}): ${JSON.stringify(error)}`);
278
+ throw new Error(`Failed to load source code (variant: ${variantName}, file: ${fileName}, url: ${url}): ${error instanceof Error ? error.message : String(error)}`, {
279
+ cause: error
280
+ });
253
281
  }
254
282
  }
255
283
 
256
284
  // Apply source transformers if no transforms exist and transforms are not disabled
257
285
  let finalTransforms = transforms;
258
286
  if (sourceTransformers && !finalTransforms && !disableTransforms && finalSource) {
259
- finalTransforms = await transformSource(finalSource, normalizePathKey(fileName), sourceTransformers);
287
+ finalTransforms = await transformSource(finalSource, normalizePathKey(fileName), sourceTransformers, commentsFromSource);
260
288
  currentMark = performanceMeasure(currentMark, {
261
289
  mark: 'Transformed File',
262
290
  measure: 'File Transforming'
@@ -277,13 +305,18 @@ async function loadSingleFile(variantName, fileName, source, url, loadSource, so
277
305
  measure: 'File Parsing'
278
306
  }, [functionName, url || fileName]);
279
307
 
308
+ // `commentsFromSource` is already 1-indexed (both `Code` comments and
309
+ // `parseImportsAndComments`/`loadSource` output use the 1-indexed convention).
310
+ // Aliased so the diff path (below) can reuse it when wrapping `parseSource` for
311
+ // transformed sources — the comments live in the code itself and don't shift for
312
+ // transforms that only blank lines.
313
+ const oneIndexedComments = commentsFromSource;
314
+
280
315
  // Apply source enhancers if provided (run sequentially as a pipeline).
281
316
  // Enhancers with a stable `enhancerName` are recorded on the HAST root
282
317
  // and skipped if they have already been applied (e.g. by a previous
283
318
  // server-side pass).
284
319
  if (sourceEnhancers && sourceEnhancers.length > 0) {
285
- // Convert comments from 0-indexed to 1-indexed for HAST compatibility
286
- const oneIndexedComments = convertCommentsToOneIndexed(commentsFromSource);
287
320
  parsedSource = await applyEnhancers(parsedSource, oneIndexedComments, fileName, sourceEnhancers);
288
321
  currentMark = performanceMeasure(currentMark, {
289
322
  mark: 'Enhanced File',
@@ -292,16 +325,93 @@ async function loadSingleFile(variantName, fileName, source, url, loadSource, so
292
325
  }
293
326
  finalSource = parsedSource;
294
327
  if (finalTransforms && !disableTransforms) {
295
- finalTransforms = await diffHast(sourceString, finalSource, normalizePathKey(fileName), finalTransforms, parseSource);
328
+ // Wrap parseSource so transformed sources receive the same source
329
+ // enhancers as the original. The frame structure produced by
330
+ // enhanceCodeEmphasis depends on `@focus`/`@padding-*` comments;
331
+ // running enhancers on both sides keeps the per-frame children
332
+ // layout aligned for a positional diff. Without this the diff
333
+ // balloons at the frame level (source has N frames, transform
334
+ // has 1) and jsondiffpatch deletes the extras.
335
+ const parseSourceForDiff = sourceEnhancers && sourceEnhancers.length > 0 ? async (transformedSourceString, transformedFileName, _language, transformedComments) => {
336
+ const transformedTree = await parseSource(transformedSourceString, transformedFileName);
337
+ // Prefer the transform-provided comment map (already
338
+ // 1-indexed against the transformed source) so enhancers
339
+ // emit the same frame structure on both sides. Falling
340
+ // back to the source's `oneIndexedComments` is safe for
341
+ // transforms that only blank lines in place, where the
342
+ // comment positions don't shift.
343
+ return applyEnhancers(transformedTree, transformedComments ?? oneIndexedComments, transformedFileName, sourceEnhancers);
344
+ } : parseSource;
345
+ finalTransforms = await diffHast(sourceString, finalSource, normalizePathKey(fileName), finalTransforms, parseSourceForDiff);
296
346
  currentMark = performanceMeasure(currentMark, {
297
347
  mark: 'Transform Parsed File',
298
348
  measure: 'Parsed File Transforming'
299
349
  }, [functionName, url || fileName]);
300
350
  }
351
+
352
+ // When the source is about to be serialized (compressed or stringified to
353
+ // JSON), embed the transform deltas inside the hast root's `data` field
354
+ // so they ride along inside the compressed payload — DEFLATE then
355
+ // shares the dictionary across the tree and the deltas, and the deltas
356
+ // never appear as plain JSON in the rendered HTML / module graph.
357
+ // The variant-level `finalTransforms` becomes a manifest (no `delta`).
358
+ if (finalTransforms && (options.output === 'hastCompressed' || options.output === 'hastJson') && finalSource && typeof finalSource === 'object' && !('hastJson' in finalSource) && !('hastCompressed' in finalSource)) {
359
+ const root = finalSource;
360
+ const split = splitTransformsForEmbed(finalTransforms);
361
+ if (split) {
362
+ embedTransformsInRoot(root, split.embedded);
363
+ finalTransforms = split.manifest;
364
+ } else {
365
+ // Every entry was empty; drop transforms entirely so we don't emit
366
+ // an empty manifest.
367
+ finalTransforms = undefined;
368
+ }
369
+ }
370
+
371
+ // Derive a variant-level root fallback from the per-frame `data.fallback`
372
+ // text before any serialization. This fallback is rendered by a
373
+ // `ContentLoading` component before the hast is decoded, and its text
374
+ // doubles as the DEFLATE dictionary so the compressed payload can be
375
+ // decompressed on the client once the fallback travels over via context.
376
+ if (finalSource && typeof finalSource === 'object' && !('hastJson' in finalSource) && !('hastCompressed' in finalSource)) {
377
+ finalFallback = buildRootFallback(finalSource);
378
+ // Sparse highlighted-visible companion (see `VariantCode.fallbackCritical`),
379
+ // computed here while the source is still a live `HastRoot` (no
380
+ // decompression) and BEFORE `stripFrameFallbacks` removes the per-frame
381
+ // text it reuses. `false` builds the `collapseToEmpty: false` form (the only
382
+ // one carrying highlighting); the boundary skips promoting it under
383
+ // `collapseToEmpty`. Empty (no visible frames) → omit it entirely.
384
+ const critical = buildCriticalFallback(finalSource, getInitialVisibleFrames(finalSource, false));
385
+ finalFallbackCritical = Object.keys(critical).length > 0 ? critical : undefined;
386
+
387
+ // Hoist the window counts off `root.data` while the source is still a live
388
+ // `HastRoot`. They then ride on the variant (see the return below) so every
389
+ // downstream reader (`prepareInitialSource`, `getVariantFileLineCounts`,
390
+ // layout-shift classification) gets `totalLines`/`focusedLines`/`collapsible`
391
+ // WITHOUT decompressing the payload — the compact fallback and the compressed
392
+ // source both drop `root.data`, so without this the only way to recover the
393
+ // counts is to decode the hast (the first-render decompression we want to avoid).
394
+ const rootData = finalSource.data;
395
+ if (rootData?.totalLines !== undefined) {
396
+ const total = Number(rootData.totalLines);
397
+ if (Number.isFinite(total) && total >= 0) {
398
+ finalTotalLines = total;
399
+ const focused = Number(rootData.focusedLines);
400
+ finalFocusedLines = Number.isFinite(focused) && focused >= 0 ? focused : total;
401
+ finalCollapsible = rootData.collapsible === true;
402
+ }
403
+ }
404
+ }
301
405
  if (options.output === 'hastCompressed' && process.env.NODE_ENV === 'production') {
302
- const hastCompressed = await compressHastAsync(JSON.stringify(finalSource));
406
+ if (finalFallback) {
407
+ stripFrameFallbacks(finalSource);
408
+ }
409
+ const json = JSON.stringify(finalSource);
410
+ // Use the fallback text as a DEFLATE dictionary for better compression.
411
+ // The same dictionary is rebuilt on decode from the variant `fallback`.
412
+ const dictionary = finalFallback ? fallbackToText(finalFallback) : undefined;
303
413
  finalSource = {
304
- hastCompressed
414
+ hastCompressed: await compressHastAsync(json, dictionary)
305
415
  };
306
416
  currentMark = performanceMeasure(currentMark, {
307
417
  mark: 'Compressed File',
@@ -309,6 +419,9 @@ async function loadSingleFile(variantName, fileName, source, url, loadSource, so
309
419
  }, [functionName, url || fileName]);
310
420
  } else if (options.output === 'hastJson' || options.output === 'hastCompressed') {
311
421
  // in development, we skip compression but still convert to JSON
422
+ if (finalFallback) {
423
+ stripFrameFallbacks(finalSource);
424
+ }
312
425
  finalSource = {
313
426
  hastJson: JSON.stringify(finalSource)
314
427
  };
@@ -321,14 +434,49 @@ async function loadSingleFile(variantName, fileName, source, url, loadSource, so
321
434
  throw new Error(`Failed to parse source code (variant: ${variantName}, file: ${fileName}, url: ${url}): ${error instanceof Error ? error.message : ''}`);
322
435
  }
323
436
  }
437
+
438
+ // Parsing disabled (deferred highlight) but a framed fallback was requested: keep
439
+ // `finalSource` a plain string so the client still knows it needs syntax
440
+ // highlighting — a HAST source reads as "already loaded" (see `isSourceLoaded`) and
441
+ // would never re-highlight. But the loading fallback MUST be framed — rendered code
442
+ // needs frames — so build a line-guttered plain-text HAST (no syntax engine: the
443
+ // light `starryNightGutter`), run the same enhancers (focus window / truncation),
444
+ // and derive the root fallback from it. The string source is returned unchanged;
445
+ // only `fallback` is produced. Gated by `framePlainFallback` so lazy variant loads
446
+ // (which never paint a fallback) keep skipping the work.
447
+ if (framePlainFallback && typeof finalSource === 'string' && !finalFallback) {
448
+ const plainRoot = {
449
+ type: 'root',
450
+ children: [{
451
+ type: 'text',
452
+ value: finalSource
453
+ }]
454
+ };
455
+ starryNightGutter(plainRoot, finalSource.split(/\r?\n|\r/));
456
+ let framedRoot = plainRoot;
457
+ if (sourceEnhancers && sourceEnhancers.length > 0) {
458
+ framedRoot = await applyEnhancers(framedRoot, commentsFromSource, fileName, sourceEnhancers);
459
+ }
460
+ finalFallback = buildRootFallback(framedRoot);
461
+ // Surface the enhancer's window counts (the compact fallback drops `root.data`,
462
+ // and a plain-string source can't recompute `focusedLines`/`collapsible` downstream).
463
+ finalTotalLines = framedRoot.data?.totalLines ?? 0;
464
+ finalFocusedLines = framedRoot.data?.focusedLines ?? finalTotalLines;
465
+ finalCollapsible = framedRoot.data?.collapsible === true;
466
+ }
324
467
  return {
325
468
  source: finalSource,
469
+ fallback: finalFallback,
470
+ fallbackCritical: finalFallbackCritical,
471
+ totalLines: finalTotalLines,
472
+ focusedLines: finalFocusedLines,
473
+ collapsible: finalCollapsible,
326
474
  transforms: finalTransforms,
327
475
  extraFiles: extraFilesFromSource,
328
476
  extraDependencies: extraDependenciesFromSource,
329
477
  externals: externalsFromSource,
330
- // Convert comments to 1-indexed for HAST compatibility when stored on variant
331
- comments: convertCommentsToOneIndexed(commentsFromSource)
478
+ // `commentsFromSource` is already 1-indexed (the stored `Code` convention).
479
+ comments: commentsFromSource
332
480
  };
333
481
  }
334
482
 
@@ -356,6 +504,7 @@ loadSource, sourceParser, sourceTransformers, sourceEnhancers, loadSourceCache,
356
504
  try {
357
505
  let fileUrl;
358
506
  let sourceData;
507
+ let inlineComments;
359
508
  let transforms;
360
509
  let nextLoadedFiles;
361
510
  // True when the entry references an external file to load (string form
@@ -391,6 +540,10 @@ loadSource, sourceParser, sourceTransformers, sourceEnhancers, loadSourceCache,
391
540
  } else {
392
541
  // fileData is an object with source and/or transforms
393
542
  sourceData = fileData.source;
543
+ // Inline extra files carry their own 1-indexed comments (their marker lines were
544
+ // stripped from the source upstream); forward them so the enhancers apply the
545
+ // `@focus`/`@highlight` frames instead of silently dropping them.
546
+ inlineComments = fileData.comments;
394
547
  transforms = fileData.transforms;
395
548
  fileUrl = baseUrl; // Use base URL as fallback
396
549
  // For inline source, just pass a copy of loadedFiles without adding current file
@@ -406,7 +559,7 @@ loadSource, sourceParser, sourceTransformers, sourceEnhancers, loadSourceCache,
406
559
  ...options,
407
560
  maxDepth: maxDepth - 1,
408
561
  loadedFiles: nextLoadedFiles
409
- }, allFilesListed, knownExtraFiles, extraFileLanguage);
562
+ }, allFilesListed, knownExtraFiles, extraFileLanguage, inlineComments);
410
563
 
411
564
  // Collect files used from this file load
412
565
  const filesUsedFromFile = [];
@@ -481,6 +634,18 @@ loadSource, sourceParser, sourceTransformers, sourceEnhancers, loadSourceCache,
481
634
  const extraFileLanguage = getLanguageFromExtension(extraFileExtension);
482
635
  processedExtraFiles[normalizedFileName] = {
483
636
  source: result.source,
637
+ ...(result.fallback && {
638
+ fallback: result.fallback
639
+ }),
640
+ ...(result.totalLines !== undefined && {
641
+ totalLines: result.totalLines
642
+ }),
643
+ ...(result.focusedLines !== undefined && {
644
+ focusedLines: result.focusedLines
645
+ }),
646
+ ...(result.collapsible !== undefined && {
647
+ collapsible: result.collapsible
648
+ }),
484
649
  ...(extraFileLanguage && {
485
650
  language: extraFileLanguage
486
651
  }),
@@ -606,7 +771,9 @@ export async function loadIsomorphicCodeVariant(url, variantName, variant, optio
606
771
  try {
607
772
  variant = await loadVariantMeta(variantName, variant);
608
773
  } catch (error) {
609
- throw new Error(`Failed to load variant code (variant: ${variantName}, url: ${variant}): ${JSON.stringify(error)}`);
774
+ throw new Error(`Failed to load variant code (variant: ${variantName}, url: ${variant}): ${error instanceof Error ? error.message : String(error)}`, {
775
+ cause: error
776
+ });
610
777
  }
611
778
  currentMark = performanceMeasure(currentMark, {
612
779
  mark: 'Loaded Variant Meta',
@@ -643,6 +810,8 @@ export async function loadIsomorphicCodeVariant(url, variantName, variant, optio
643
810
  // If we don't have a fileName and no URL, we can still parse if we have language
644
811
  if (!fileName && !url) {
645
812
  let finalSource = variant.source;
813
+ let finalFallback;
814
+ let finalFallbackCritical;
646
815
 
647
816
  // Parse the source if we have language and sourceParser
648
817
  if (typeof finalSource === 'string' && language && sourceParser && !disableParsing) {
@@ -664,13 +833,43 @@ export async function loadIsomorphicCodeVariant(url, variantName, variant, optio
664
833
 
665
834
  // Apply source enhancers if provided and parsing is not disabled
666
835
  if (!disableParsing && sourceEnhancers && sourceEnhancers.length > 0) {
667
- const oneIndexedComments = convertCommentsToOneIndexed(variant.comments);
836
+ // `variant.comments` is already 1-indexed (the stored `Code` convention).
837
+ const oneIndexedComments = variant.comments;
668
838
  finalSource = await applyEnhancers(finalSource, oneIndexedComments, '', sourceEnhancers);
669
839
  }
840
+
841
+ // Apply output format compression in production. Other format conversions
842
+ // happen lazily via the loader so tests can inspect the parsed HAST directly.
843
+ if (finalSource && typeof finalSource === 'object' && 'type' in finalSource) {
844
+ // Always derive a variant-level root fallback from the per-frame text so a
845
+ // `ContentLoading` component can render before the hast is decoded.
846
+ finalFallback = buildRootFallback(finalSource);
847
+ // Sparse highlighted-visible companion (see `VariantCode.fallbackCritical`),
848
+ // built from the live `HastRoot` before `stripFrameFallbacks` runs.
849
+ const critical = buildCriticalFallback(finalSource, getInitialVisibleFrames(finalSource, false));
850
+ finalFallbackCritical = Object.keys(critical).length > 0 ? critical : undefined;
851
+ if (options.output === 'hastCompressed' && process.env.NODE_ENV === 'production') {
852
+ if (finalFallback) {
853
+ stripFrameFallbacks(finalSource);
854
+ }
855
+ const json = JSON.stringify(finalSource);
856
+ // Use the fallback text as a DEFLATE dictionary; rebuilt on decode.
857
+ const dictionary = finalFallback ? fallbackToText(finalFallback) : undefined;
858
+ finalSource = {
859
+ hastCompressed: await compressHastAsync(json, dictionary)
860
+ };
861
+ }
862
+ }
670
863
  const finalVariant = {
671
864
  ...variant,
672
865
  language,
673
- source: finalSource
866
+ source: finalSource,
867
+ ...(finalFallback ? {
868
+ fallback: finalFallback
869
+ } : {}),
870
+ ...(finalFallbackCritical ? {
871
+ fallbackCritical: finalFallbackCritical
872
+ } : {})
674
873
  };
675
874
  return {
676
875
  code: finalVariant,
@@ -919,6 +1118,21 @@ export async function loadIsomorphicCodeVariant(url, variantName, variant, optio
919
1118
  ...variant,
920
1119
  language,
921
1120
  source: mainFileResult.source,
1121
+ ...(mainFileResult.fallback && {
1122
+ fallback: mainFileResult.fallback
1123
+ }),
1124
+ ...(mainFileResult.fallbackCritical && {
1125
+ fallbackCritical: mainFileResult.fallbackCritical
1126
+ }),
1127
+ ...(mainFileResult.totalLines !== undefined && {
1128
+ totalLines: mainFileResult.totalLines
1129
+ }),
1130
+ ...(mainFileResult.focusedLines !== undefined && {
1131
+ focusedLines: mainFileResult.focusedLines
1132
+ }),
1133
+ ...(mainFileResult.collapsible !== undefined && {
1134
+ collapsible: mainFileResult.collapsible
1135
+ }),
922
1136
  transforms: mainFileResult.transforms,
923
1137
  extraFiles: Object.keys(allExtraFiles).length > 0 ? allExtraFiles : undefined,
924
1138
  externals: Object.keys(allExternals).length > 0 ? Object.keys(allExternals) : undefined,
@@ -1,2 +1,2 @@
1
- import type { VariantSource, SourceTransformers, Transforms } from "../../CodeHighlighter/types.mjs";
2
- export declare function transformSource(source: VariantSource, fileName: string, sourceTransformers: SourceTransformers): Promise<Transforms | undefined>;
1
+ import type { VariantSource, SourceComments, SourceTransformers, Transforms } from "../../CodeHighlighter/types.mjs";
2
+ export declare function transformSource(source: VariantSource, fileName: string, sourceTransformers: SourceTransformers, comments?: SourceComments): Promise<Transforms | undefined>;
@@ -5,36 +5,70 @@ const differ = create({
5
5
  omitRemovedValues: true,
6
6
  cloneDiffValues: true
7
7
  });
8
- export async function transformSource(source, fileName, sourceTransformers) {
9
- const transforms = await Promise.all(sourceTransformers.map(async ({
10
- extensions,
8
+ export async function transformSource(source, fileName, sourceTransformers, comments) {
9
+ // Find applicable transformers up front so we can short-circuit before
10
+ // doing any source decoding work.
11
+ const applicableTransformers = sourceTransformers.filter(({
12
+ extensions
13
+ }) => extensions.some(ext => fileName.endsWith(`.${ext}`)));
14
+ if (applicableTransformers.length === 0) {
15
+ return undefined;
16
+ }
17
+
18
+ // Decode the source string and split it once. Both are independent of
19
+ // which transformer is running, so doing this per-transformer (as the
20
+ // previous implementation did) wasted work proportional to the number
21
+ // of registered transformers.
22
+ let sourceString;
23
+ if (typeof source === 'string') {
24
+ sourceString = source;
25
+ } else if ('hastJson' in source) {
26
+ sourceString = toText(JSON.parse(source.hastJson));
27
+ } else if ('hastCompressed' in source) {
28
+ sourceString = toText(JSON.parse(await decompressHastAsync(source.hastCompressed)));
29
+ } else {
30
+ sourceString = toText(source);
31
+ }
32
+ const splitSource = sourceString.split('\n');
33
+ const transforms = await Promise.all(applicableTransformers.map(async ({
11
34
  transformer
12
35
  }) => {
13
- if (!extensions.some(ext => fileName.endsWith(`.${ext}`))) {
14
- return undefined;
15
- }
16
36
  try {
17
- let sourceString;
18
- if (typeof source === 'string') {
19
- sourceString = source;
20
- } else if ('hastJson' in source) {
21
- sourceString = toText(JSON.parse(source.hastJson));
22
- } else if ('hastCompressed' in source) {
23
- sourceString = toText(JSON.parse(await decompressHastAsync(source.hastCompressed)));
24
- } else {
25
- sourceString = toText(source);
26
- }
27
- const transformed = await transformer(sourceString, fileName);
37
+ const transformed = await transformer(sourceString, fileName, comments);
28
38
  if (transformed) {
29
- const splitSource = sourceString.split('\n');
30
- return Object.keys(transformed).reduce((acc, key) => {
31
- const delta = differ.diff(splitSource, transformed[key].source.split('\n'));
39
+ const reduced = Object.keys(transformed).reduce((acc, key) => {
40
+ const entry = transformed[key];
41
+ const delta = differ.diff(splitSource, entry.source.split('\n'));
42
+
43
+ // Comments are 1-indexed everywhere, including transformer input and output
44
+ // (keyed against the transformed source's 1-indexed lines).
45
+ const transformedComments = entry.comments;
46
+ const hasDelta = !!delta && typeof delta === 'object' && Object.keys(delta).length > 0;
47
+ const renamed = !!entry.fileName && entry.fileName !== fileName;
48
+
49
+ // Drop entries that neither change the source nor rename the
50
+ // file — there's nothing for the runtime to apply.
51
+ if (!hasDelta && !renamed) {
52
+ return acc;
53
+ }
32
54
  acc[key] = {
33
- delta,
34
- fileName: transformed[key].fileName
55
+ ...(hasDelta && {
56
+ delta,
57
+ hasDelta: true
58
+ }),
59
+ ...(entry.fileName !== undefined && {
60
+ fileName: entry.fileName
61
+ }),
62
+ ...(transformedComments && {
63
+ comments: transformedComments
64
+ })
35
65
  };
36
66
  return acc;
37
67
  }, {});
68
+ // If every entry was dropped (e.g. a transformer that only
69
+ // produced noop entries), surface `undefined` so the caller
70
+ // treats the variant as untransformed.
71
+ return Object.keys(reduced).length > 0 ? reduced : undefined;
38
72
  }
39
73
  return undefined;
40
74
  } catch (error) {
@@ -39,6 +39,24 @@ export type LoaderOptions = {
39
39
  * to be relative to each generated `client.ts`.
40
40
  */
41
41
  requireClient?: string;
42
+ /**
43
+ * Marker option consumed by `pnpm docs-infra validate` (not by this loader).
44
+ *
45
+ * When `true` on a demo `index.ts` rule, the validate command ensures every
46
+ * matched demo has a sibling `page.tsx` that renders the demo as the route's
47
+ * default export, so each demo is browsable on its own page.
48
+ *
49
+ * Existing `page.tsx`/`page.ts` files are never overwritten.
50
+ */
51
+ requirePage?: boolean;
52
+ /**
53
+ * When `true`, registers the `TypescriptToJavascriptTransformer` so that
54
+ * TypeScript variants also produce a JavaScript counterpart at build time.
55
+ *
56
+ * Defaults to `false` because the transform is comparatively expensive;
57
+ * enable it when the rendered demos need both TS and JS sources.
58
+ */
59
+ transformTypescriptToJavascript?: boolean;
42
60
  };
43
61
  /**
44
62
  * Webpack loader that processes demo files and precomputes variant data.
@@ -5,9 +5,7 @@ import path from 'path';
5
5
  import { fileURLToPath, pathToFileURL } from 'url';
6
6
  import { loadIsomorphicCodeVariant } from "../loadIsomorphicCodeVariant/loadIsomorphicCodeVariant.mjs";
7
7
  import { createParseSource } from "../parseSource/index.mjs";
8
- // TODO: re-enable following benchmarking
9
- // import { TypescriptToJavascriptTransformer } from '../transformTypescriptToJavascript';
10
-
8
+ import { TypescriptToJavascriptTransformer } from "../transformTypescriptToJavascript/index.mjs";
11
9
  import { createEnhanceCodeEmphasis, EMPHASIS_COMMENT_PREFIX, FOCUS_COMMENT_PREFIX } from "../enhanceCodeEmphasis/enhanceCodeEmphasis.mjs";
12
10
  import { parseCreateFactoryCall } from "../parseCreateFactoryCall/parseCreateFactoryCall.mjs";
13
11
  import { resolveVariantPathsWithFs } from "../loadServerCodeMeta/resolveModulePathWithFs.mjs";
@@ -132,9 +130,7 @@ export async function loadPrecomputedCodeHighlighter(source) {
132
130
  });
133
131
 
134
132
  // Setup source transformers for TypeScript to JavaScript conversion
135
- // const sourceTransformers: SourceTransformers = [TypescriptToJavascriptTransformer];
136
- // TODO: maybe we should have `loadPrecomputedCodeHighlighterWithJsToTs`
137
- const sourceTransformers = [];
133
+ const sourceTransformers = options.transformTypescriptToJavascript ? [TypescriptToJavascriptTransformer] : [];
138
134
 
139
135
  // Setup source enhancers for post-parsing modifications
140
136
  const sourceEnhancers = [createEnhanceCodeEmphasis(options.emphasisOptions)];
@@ -205,10 +201,18 @@ export async function loadPrecomputedCodeHighlighter(source) {
205
201
  });
206
202
  const variantResults = await Promise.all(variantPromises);
207
203
 
204
+ // Diagnostic: re-serialize each variant through JSON to sever any
205
+ // `SlicedString`/`ConsString` references that may pin large parent strings
206
+ // (e.g. raw source files) alive inside the precomputed hast tree. Enabled
207
+ // by `DEBUG_DOCS_INFRA_FLATTEN=1`. If memory usage drops noticeably with
208
+ // this on, the leak is SlicedString retention in variant data and we
209
+ // should flatten at the source instead.
210
+ const flattenVariants = typeof process !== 'undefined' && process.env?.DEBUG_DOCS_INFRA_FLATTEN === '1';
211
+
208
212
  // Process results and collect dependencies
209
213
  for (const result of variantResults) {
210
214
  if (result) {
211
- variantData[result.variantName] = result.variantData;
215
+ variantData[result.variantName] = flattenVariants ? JSON.parse(JSON.stringify(result.variantData)) : result.variantData;
212
216
  result.dependencies.forEach(file => {
213
217
  allDependencies.push(file);
214
218
  });
@@ -147,8 +147,8 @@ export type TypesOutputFormat = 'hast' | 'hastJson' | 'hastCompressed';
147
147
  /** Converts a HastRoot to a JSON-serialized wrapper. */
148
148
  export declare function serializeHastRoot(hast: HastRoot): SerializedHastRoot;
149
149
  /** Converts a HastRoot to a dictionary-compressed, base64-encoded wrapper. */
150
- export declare function compressHastRoot(hast: HastRoot): SerializedHastCompressed;
150
+ export declare function compressHastRoot(hast: HastRoot, textContent?: string): SerializedHastCompressed;
151
151
  /** Returns the appropriate serializer function for the given output format. */
152
- export declare function resolveSerializer(output: TypesOutputFormat): (hast: HastRoot) => HastRoot | SerializedHastRoot | SerializedHastCompressed;
152
+ export declare function resolveSerializer(output: TypesOutputFormat, textContent?: string): (hast: HastRoot) => HastRoot | SerializedHastRoot | SerializedHastCompressed;
153
153
  /** No-op passthrough — avoids allocating a fresh closure on every call. */
154
154
  export declare function hastIdentity(hast: HastRoot): HastRoot;
@@ -460,16 +460,16 @@ export function serializeHastRoot(hast) {
460
460
  }
461
461
 
462
462
  /** Converts a HastRoot to a dictionary-compressed, base64-encoded wrapper. */
463
- export function compressHastRoot(hast) {
463
+ export function compressHastRoot(hast, textContent) {
464
464
  return {
465
- hastCompressed: compressHast(JSON.stringify(hast))
465
+ hastCompressed: compressHast(JSON.stringify(hast), textContent)
466
466
  };
467
467
  }
468
468
 
469
469
  /** Returns the appropriate serializer function for the given output format. */
470
- export function resolveSerializer(output) {
470
+ export function resolveSerializer(output, textContent) {
471
471
  if (output === 'hastCompressed') {
472
- return compressHastRoot;
472
+ return hast => compressHastRoot(hast, textContent);
473
473
  }
474
474
  if (output === 'hastJson') {
475
475
  return serializeHastRoot;
@@ -60,7 +60,7 @@ export async function loadServerTypes(options) {
60
60
  return parts.slice(1).join('.').toLowerCase();
61
61
  }
62
62
  // No prefix match, use the full name
63
- return name.replace(/\./g, '.').toLowerCase();
63
+ return name.toLowerCase();
64
64
  }
65
65
  // Non-dotted name: use as-is
66
66
  return name.toLowerCase();
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Extracts text content from a JSDoc description array.
3
+ *
4
+ * typescript-api-extractor returns a description as an array of JSDoc nodes when
5
+ * the comment contains `{@link}` tags: plain-text nodes carry a `text` property,
6
+ * while link nodes carry the referenced symbol in `name.escapedText`. Link nodes
7
+ * are turned into markdown via {@link renderJSDocLink}, gated on `documentedNames`.
8
+ */
9
+ export declare function extractJSDocText(nodes: unknown[], documentedNames?: Set<string>): string;
10
+ /**
11
+ * Checks if an array looks like JSDoc description nodes from typescript-api-extractor.
12
+ * These have properties like 'pos', 'end', 'kind', 'text' from the TypeScript AST.
13
+ */
14
+ export declare function isJSDocNodeArray(value: unknown[]): boolean;