@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,233 +1,306 @@
1
- import { applyCodeTransform } from "../pipeline/loadIsomorphicCodeVariant/applyCodeTransform.mjs";
2
1
  /**
3
2
  * Pure function to get available transforms from effective code data.
4
- * Only includes transforms that have actual deltas (file changes), not just filename changes.
3
+ *
4
+ * Variant-level `transforms` is a manifest produced by `splitTransformsForEmbed`
5
+ * (or by the legacy `Transforms` shape with deltas, for back-compat). Only
6
+ * entries that produced a real source delta are reported here — rename-only
7
+ * entries (manifest entries with `hasDelta: false`, kept around so the
8
+ * runtime can still apply the rename based on user preference) are filtered
9
+ * out so the transform toggle stays hidden when nothing meaningful changes.
5
10
  *
6
11
  * @param effectiveCode - The effective code object containing all variants
7
12
  * @param selectedVariantKey - The currently selected variant key
8
- * @returns Array of available transform keys that have deltas
13
+ * @returns Array of available transform keys (toggle-visible only)
9
14
  */
10
15
  export function getAvailableTransforms(effectiveCode, selectedVariantKey) {
11
- const transforms = new Set();
12
- if (effectiveCode && selectedVariantKey) {
13
- const variantCode = effectiveCode[selectedVariantKey];
14
- if (variantCode && typeof variantCode === 'object') {
15
- // Check main variant transforms
16
- if ('transforms' in variantCode && variantCode.transforms) {
17
- Object.keys(variantCode.transforms).forEach(transformKey => {
18
- const transformData = variantCode.transforms[transformKey];
19
- // Only include transforms that have actual deltas (file changes)
20
- // Check if delta exists and is not empty
21
- if (transformData && typeof transformData === 'object' && 'delta' in transformData) {
22
- const delta = transformData.delta;
23
- // Check if delta has meaningful content (not just an empty object)
24
- const hasContent = delta && typeof delta === 'object' && Object.keys(delta).length > 0;
25
- if (hasContent) {
26
- transforms.add(transformKey);
27
- }
28
- }
29
- });
30
- }
31
-
32
- // Check extraFiles for transforms with deltas
33
- if ('extraFiles' in variantCode && variantCode.extraFiles) {
34
- Object.values(variantCode.extraFiles).forEach(fileData => {
35
- if (fileData && typeof fileData === 'object' && 'transforms' in fileData && fileData.transforms) {
36
- Object.keys(fileData.transforms).forEach(transformKey => {
37
- const transformData = fileData.transforms[transformKey];
38
- // Only include transforms that have actual deltas (file changes)
39
- // Check if delta exists and is not empty
40
- if (transformData && typeof transformData === 'object' && 'delta' in transformData) {
41
- const delta = transformData.delta;
42
- // Check if delta has meaningful content (not just an empty object)
43
- const hasContent = delta && typeof delta === 'object' && Object.keys(delta).length > 0;
44
- if (hasContent) {
45
- transforms.add(transformKey);
46
- }
47
- }
48
- });
49
- }
50
- });
51
- }
52
- }
53
- }
54
- return Array.from(transforms);
16
+ return collectTransformKeys(effectiveCode, selectedVariantKey, {
17
+ onlyWithDelta: true
18
+ });
55
19
  }
56
20
 
57
21
  /**
58
- * Pure helper function to apply transform to a source file.
22
+ * Like `getAvailableTransforms` but also includes rename-only entries
23
+ * (manifest entries with `hasDelta: false`). Used by the transform
24
+ * resolution path so a stored preference can still apply a rename even
25
+ * when its toggle is hidden because no actual delta exists.
59
26
  *
60
- * @param source - The source code to transform
61
- * @param fileName - The filename for the source
62
- * @param transforms - Available transforms for this source
63
- * @param selectedTransform - The transform to apply
64
- * @returns Object with transformed source and name
27
+ * @param effectiveCode - The effective code object containing all variants
28
+ * @param selectedVariantKey - The currently selected variant key
29
+ * @returns Array of all applicable transform keys
65
30
  */
66
- export function applyTransformToSource(source, fileName, transforms, selectedTransform) {
67
- if (!transforms?.[selectedTransform]) {
68
- return {
69
- transformedSource: source,
70
- transformedName: fileName
71
- };
31
+ export function getApplicableTransforms(effectiveCode, selectedVariantKey) {
32
+ return collectTransformKeys(effectiveCode, selectedVariantKey, {
33
+ onlyWithDelta: false
34
+ });
35
+ }
36
+ function collectTransformKeys(effectiveCode, selectedVariantKey, {
37
+ onlyWithDelta
38
+ }) {
39
+ const transforms = new Set();
40
+ if (!effectiveCode || !selectedVariantKey) {
41
+ return [];
42
+ }
43
+ const variantCode = effectiveCode[selectedVariantKey];
44
+ if (!variantCode || typeof variantCode !== 'object') {
45
+ return [];
72
46
  }
73
- try {
74
- // Get transform data
75
- const transformData = transforms[selectedTransform];
76
- if (!transformData || typeof transformData !== 'object' || !('delta' in transformData)) {
77
- return {
78
- transformedSource: source,
79
- transformedName: fileName
80
- };
47
+ const add = entries => {
48
+ if (!entries) {
49
+ return;
81
50
  }
82
-
83
- // Check if delta has meaningful content
84
- const delta = transformData.delta;
85
- const hasContent = delta && typeof delta === 'object' && Object.keys(delta).length > 0;
86
- if (!hasContent) {
87
- return {
88
- transformedSource: source,
89
- transformedName: fileName
90
- };
51
+ for (const [transformKey, entry] of Object.entries(entries)) {
52
+ if (!entry) {
53
+ continue;
54
+ }
55
+ if (!onlyWithDelta) {
56
+ transforms.add(transformKey);
57
+ continue;
58
+ }
59
+ const inlineDelta = !!entry.delta && typeof entry.delta === 'object' && Object.keys(entry.delta).length > 0;
60
+ if (entry.hasDelta || inlineDelta) {
61
+ transforms.add(transformKey);
62
+ }
63
+ }
64
+ };
65
+ if ('transforms' in variantCode) {
66
+ add(variantCode.transforms);
67
+ }
68
+ if ('extraFiles' in variantCode && variantCode.extraFiles) {
69
+ for (const fileData of Object.values(variantCode.extraFiles)) {
70
+ if (fileData && typeof fileData === 'object' && 'transforms' in fileData) {
71
+ add(fileData.transforms);
72
+ }
91
73
  }
92
-
93
- // Apply transform
94
- const result = applyCodeTransform(source, transforms, selectedTransform);
95
- const transformedName = transformData.fileName || fileName;
96
- return {
97
- transformedSource: result,
98
- transformedName
99
- };
100
- } catch (error) {
101
- console.error(`Transform failed for ${fileName}:`, error);
102
- return {
103
- transformedSource: source,
104
- transformedName: fileName
105
- };
106
74
  }
75
+ return Array.from(transforms);
107
76
  }
108
77
 
109
78
  /**
110
- * Pure function to create transformed files from a variant and selected transform.
79
+ * Determines whether applying `transformKey` to `variant` would introduce
80
+ * `.collapse` placeholders into the rendered hast tree — i.e. whether the
81
+ * swap is layout-affecting and must run through the coordinated barrier.
82
+ *
83
+ * Reads the precomputed `hasCollapse` / `hasCollapseInFocus` flags
84
+ * stored on each transform entry by the pipeline (`diffHast` sets them
85
+ * directly, `splitTransformsForEmbed` propagates them onto the
86
+ * manifest). No tree walking or delta decompression happens at runtime.
87
+ *
88
+ * The `mode` option controls *which* file's transform entry is consulted:
111
89
  *
112
- * @param selectedVariant - The currently selected variant
113
- * @param selectedTransform - The transform to apply
114
- * @returns Object with transformed files and filename mapping, or undefined if no transform
90
+ * - `'selected'` (default) Consults only the transform map for the
91
+ * file identified by `selectedFileName` (or `variant.transforms`
92
+ * when `selectedFileName === variant.fileName`). When
93
+ * `selectedFileName` is omitted, treats the variant's main file
94
+ * (`variant.fileName`) as the selection.
95
+ * - `'all'` — Iterates every transform map on the variant
96
+ * (`variant.transforms` + each `extraFiles[*].transforms`) and
97
+ * returns `true` if any one has `hasCollapse: true`. Useful for
98
+ * callers that render multiple files simultaneously and need to
99
+ * coordinate a swap whenever *any* file would shift.
100
+ * - `'focus'` — Like `'selected'`, but consults
101
+ * `hasCollapseInFocus` instead of `hasCollapse` whenever
102
+ * `expanded === false`. Lets consumers skip the coordinated
103
+ * barrier for transforms whose `.collapse` insertion lands
104
+ * outside the initially-visible region of a collapsed code block.
105
+ *
106
+ * Falls back to a conservative phase 1 classification for legacy
107
+ * payloads that carry `hasDelta: true` without the precomputed flag —
108
+ * i.e. transforms produced by an older build that predates
109
+ * `hasCollapse`, or constructed by a direct caller bypassing the
110
+ * pipeline. For `hasCollapseInFocus`, entries that lack the field fall
111
+ * back to the value of `hasCollapse` (matching the embed-side default).
112
+ *
113
+ * Returns `false` when every consulted entry has `hasCollapse: false`
114
+ * (or `hasCollapseInFocus: false` in focus mode while collapsed), is
115
+ * rename-only, is absent, or the variant is `null`.
116
+ *
117
+ * @param variant - The variant whose transforms to inspect.
118
+ * @param transformKey - The transform key to classify, or `null`.
119
+ * @param opts - Optional mode + selected-file + expanded context.
115
120
  */
116
- export function createTransformedFiles(selectedVariant, selectedTransform) {
117
- // Only create transformed files when there's actually a transform selected
118
- if (!selectedVariant || !selectedTransform) {
119
- return undefined;
121
+ export function transformHasCollapsePlaceholder(variant, transformKey, opts) {
122
+ if (!variant || !transformKey) {
123
+ return false;
124
+ }
125
+ const mode = opts?.mode ?? 'selected';
126
+ const expanded = opts?.expanded ?? false;
127
+ // `'selected'`/`'focus'` default to the variant's main file when no
128
+ // selection is supplied. This lines up with the runtime's "render
129
+ // the main file by default" behavior.
130
+ let selectedFileName = opts?.selectedFileName;
131
+ if (selectedFileName === undefined && mode !== 'all' && 'fileName' in variant) {
132
+ selectedFileName = variant.fileName;
120
133
  }
121
- const files = [];
122
- const filenameMap = {};
123
-
124
- // First, check if any file has a meaningful transform delta for the selected transform
125
- const variantTransforms = 'transforms' in selectedVariant ? selectedVariant.transforms : undefined;
126
- let hasAnyMeaningfulTransform = false;
127
134
 
128
- // Check main file for meaningful transform
129
- if (selectedVariant.fileName && variantTransforms?.[selectedTransform]?.delta) {
130
- const delta = variantTransforms[selectedTransform].delta;
131
- if (delta && Object.keys(delta).length > 0) {
132
- hasAnyMeaningfulTransform = true;
135
+ // In focus mode while collapsed, the relevant precomputed flag is
136
+ // the focus-scoped one. Everywhere else we still consult plain
137
+ // `hasCollapse`. The `useFocusFlag` decision is taken once up front
138
+ // so the per-entry checks stay branch-free.
139
+ const useFocusFlag = mode === 'focus' && !expanded;
140
+ const checkEntry = entry => {
141
+ if (!entry) {
142
+ return false;
133
143
  }
134
- }
144
+ if (useFocusFlag) {
145
+ // Prefer the focus-scoped flag; legacy payloads (no
146
+ // `hasCollapseInFocus` field) fall through to `hasCollapse`
147
+ // which itself falls back to the conservative phase 1
148
+ // classification below.
149
+ if (entry.hasCollapseInFocus === true) {
150
+ return true;
151
+ }
152
+ if (entry.hasCollapseInFocus === false) {
153
+ return false;
154
+ }
155
+ }
156
+ if (entry.hasCollapse === true) {
157
+ return true;
158
+ }
159
+ // Legacy fallback: an older payload carries `hasDelta: true` with
160
+ // neither an inline delta nor the precomputed flag. Classify
161
+ // conservatively as phase 1 so the swap stays layout-stable.
162
+ if (entry.hasCollapse === undefined && entry.hasDelta && !entry.delta) {
163
+ return true;
164
+ }
165
+ return false;
166
+ };
135
167
 
136
- // Check extraFiles for meaningful transforms
137
- if (!hasAnyMeaningfulTransform && selectedVariant.extraFiles) {
138
- Object.values(selectedVariant.extraFiles).forEach(fileData => {
139
- if (fileData && typeof fileData === 'object' && 'transforms' in fileData) {
140
- const transformData = fileData.transforms?.[selectedTransform];
141
- if (transformData?.delta && Object.keys(transformData.delta).length > 0) {
142
- hasAnyMeaningfulTransform = true;
168
+ // `'all'` mode walks every transform map on the variant.
169
+ if (mode === 'all') {
170
+ if ('transforms' in variant && variant.transforms) {
171
+ if (checkEntry(variant.transforms[transformKey])) {
172
+ return true;
173
+ }
174
+ }
175
+ if ('extraFiles' in variant && variant.extraFiles) {
176
+ for (const file of Object.values(variant.extraFiles)) {
177
+ if (file && typeof file === 'object' && 'transforms' in file && file.transforms) {
178
+ if (checkEntry(file.transforms[transformKey])) {
179
+ return true;
180
+ }
143
181
  }
144
182
  }
145
- });
183
+ }
184
+ return false;
146
185
  }
147
186
 
148
- // If no file has a meaningful transform, return empty result
149
- if (!hasAnyMeaningfulTransform) {
150
- return {
151
- files: [],
152
- filenameMap: {}
153
- };
187
+ // `'selected'` / `'focus'` consult only the chosen file's transforms.
188
+ // Main file is identified by `variant.fileName`; everything else is
189
+ // looked up under `extraFiles`. `selectedFileName` is guaranteed to
190
+ // be defined here (the default above falls back to `variant.fileName`).
191
+ if (selectedFileName === undefined) {
192
+ return false;
154
193
  }
155
-
156
- // Process main file if we have a fileName and source
157
- if (selectedVariant.fileName && selectedVariant.source) {
158
- const {
159
- transformedSource: mainSource,
160
- transformedName: mainName
161
- } = applyTransformToSource(selectedVariant.source, selectedVariant.fileName, variantTransforms, selectedTransform);
162
- const fileName = selectedVariant.fileName;
163
- filenameMap[fileName] = mainName;
164
- files.push({
165
- name: mainName,
166
- originalName: fileName,
167
- source: mainSource
168
- });
194
+ if ('fileName' in variant && selectedFileName === variant.fileName) {
195
+ if ('transforms' in variant && variant.transforms) {
196
+ return checkEntry(variant.transforms[transformKey]);
197
+ }
198
+ return false;
169
199
  }
200
+ if ('extraFiles' in variant && variant.extraFiles) {
201
+ const file = variant.extraFiles[selectedFileName];
202
+ if (file && typeof file === 'object' && 'transforms' in file && file.transforms) {
203
+ return checkEntry(file.transforms[transformKey]);
204
+ }
205
+ }
206
+ return false;
207
+ }
170
208
 
171
- // Process extra files
172
- if (selectedVariant.extraFiles) {
173
- Object.entries(selectedVariant.extraFiles).forEach(([extraFileName, fileData]) => {
174
- let source;
175
- let transforms;
176
-
177
- // Handle different extraFile structures
178
- if (typeof fileData === 'string') {
179
- source = fileData;
180
- transforms = undefined; // Don't inherit variant transforms for simple string files
181
- } else if (fileData && typeof fileData === 'object' && 'source' in fileData) {
182
- source = fileData.source;
183
- transforms = fileData.transforms; // Only use explicit transforms for this file
184
- } else {
185
- return; // Skip invalid entries
186
- }
209
+ /**
210
+ * Description of a single transform entry that carries
211
+ * `hasCollapseInFocus: true`. Returned by
212
+ * `findCollapseInFocusTransforms` so callers can produce actionable
213
+ * error messages without re-walking the variant tree.
214
+ */
187
215
 
188
- // Skip if source is undefined
189
- if (!source) {
190
- return;
216
+ /**
217
+ * Walk every variant on `effectiveCode` and collect transform entries
218
+ * whose precomputed `hasCollapseInFocus` flag is `true` — i.e. the
219
+ * collapse placeholder introduced by the transform lands inside the
220
+ * focus region that is visible while the surrounding code block is
221
+ * un-expanded.
222
+ *
223
+ * Used by `useCode`'s `strictCollapseInFocus` option to throw with a
224
+ * pointer to the offending variant/file/transform so the demo author
225
+ * can narrow the `@focus` region (or the transform's edit range) until
226
+ * the placeholder lands outside the visible window.
227
+ *
228
+ * Walks main files (`variant.transforms`) and `extraFiles[*].transforms`.
229
+ * Returns an empty array when no entry has the flag set.
230
+ */
231
+ export function findCollapseInFocusTransforms(effectiveCode) {
232
+ const offenders = [];
233
+ const collectFromMap = (variantName, fileName, transforms) => {
234
+ if (!transforms) {
235
+ return;
236
+ }
237
+ for (const [transformKey, entry] of Object.entries(transforms)) {
238
+ if (entry?.hasCollapseInFocus === true) {
239
+ offenders.push({
240
+ variantName,
241
+ fileName,
242
+ transformKey
243
+ });
191
244
  }
192
-
193
- // Apply transforms if available, otherwise use original source
194
- let transformedSource = source;
195
- let transformedName = extraFileName;
196
- if (transforms?.[selectedTransform]) {
197
- try {
198
- const transformData = transforms[selectedTransform];
199
- if (transformData && typeof transformData === 'object' && 'delta' in transformData) {
200
- // Only apply transform if there's a meaningful delta
201
- const hasTransformDelta = transformData.delta && Object.keys(transformData.delta).length > 0;
202
- if (hasTransformDelta) {
203
- transformedSource = applyCodeTransform(source, transforms, selectedTransform);
204
- transformedName = transformData.fileName || extraFileName;
205
- }
206
- }
207
- } catch (error) {
208
- console.error(`Transform failed for ${extraFileName}:`, error);
209
- // Continue with original source if transform fails
245
+ }
246
+ };
247
+ for (const [variantName, variant] of Object.entries(effectiveCode)) {
248
+ if (!variant || typeof variant !== 'object') {
249
+ continue;
250
+ }
251
+ if ('transforms' in variant && variant.transforms) {
252
+ const fileName = 'fileName' in variant && variant.fileName || '<main>';
253
+ collectFromMap(variantName, fileName, variant.transforms);
254
+ }
255
+ if ('extraFiles' in variant && variant.extraFiles) {
256
+ for (const [fileName, file] of Object.entries(variant.extraFiles)) {
257
+ if (file && typeof file === 'object' && 'transforms' in file) {
258
+ collectFromMap(variantName, fileName, file.transforms);
210
259
  }
211
260
  }
261
+ }
262
+ }
263
+ return offenders;
264
+ }
212
265
 
213
- // Only update filenameMap and add to files if this doesn't conflict with existing files
214
- // If a file already exists with the target name, skip this transformation to preserve original files
215
- const existingFile = files.find(f => f.name === transformedName);
216
- if (!existingFile) {
217
- filenameMap[extraFileName] = transformedName;
218
- files.push({
219
- name: transformedName,
220
- originalName: extraFileName,
221
- source: transformedSource
222
- });
223
- } else {
224
- // If there's a conflict, skip this file with a warning
225
- console.warn(`Transform conflict: ${extraFileName} would transform to ${transformedName} but that name is already taken. Skipping this file.`);
226
- }
227
- });
266
+ /**
267
+ * Decide whether the rendered `<Pre>` should emit highlighted spans on
268
+ * this render. Three gates compose:
269
+ *
270
+ * 1. `highlightReady` — the render-side readiness gate published by
271
+ * `CodeHighlighterClient`. `false` while the highlight trigger
272
+ * (`hydration` / `idle` / `visible`) hasn't fired yet *or* the
273
+ * sync `parseCode` pass hasn't resolved. The precomputed HAST on
274
+ * the published `code` would render highlighted spans on first
275
+ * paint otherwise — defeating the deferred trigger. Treated as
276
+ * `true` when undefined so legacy/test consumers without a
277
+ * surrounding context default to rendering highlighted.
278
+ * 2. `deferHighlight` the narrower pipeline-level signal published
279
+ * while the incoming variant's parse / transform deltas are still
280
+ * in flight. Always wins: if the tree isn't ready, highlighting
281
+ * can't happen.
282
+ * 3. `pendingBootstrap` — set while a stored-preference variant swap
283
+ * is queued behind the initial mount. Suppresses the *outgoing*
284
+ * tree's highlighting so we don't burn cycles painting spans the
285
+ * user is about to swap away from.
286
+ *
287
+ * The bootstrap gate is skipped when `highlightAfter === 'init'`:
288
+ * - the precomputed HAST already carries the spans (no "wasted work"),
289
+ * and
290
+ * - leaving it on causes the *incoming* variant to render as plain
291
+ * text for the render between `pendingBootstrap` flipping and the
292
+ * bootstrap commit landing, producing a visible flash of unhighlighted
293
+ * code on first-paint variant swaps.
294
+ */
295
+ export function shouldHighlightForRender(args) {
296
+ if (args.deferHighlight) {
297
+ return false;
228
298
  }
229
- return {
230
- files,
231
- filenameMap
232
- };
299
+ if (args.highlightReady === false) {
300
+ return false;
301
+ }
302
+ if (args.highlightAfter === 'init') {
303
+ return true;
304
+ }
305
+ return !args.pendingBootstrap;
233
306
  }
@@ -1,11 +1,20 @@
1
1
  import * as React from 'react';
2
2
  import { type UseCopierOpts } from "../useCopier/index.mjs";
3
- import type { VariantCode, VariantSource } from "../CodeHighlighter/types.mjs";
3
+ import type { Fallbacks, VariantCode, VariantSource } from "../CodeHighlighter/types.mjs";
4
+ import type { FallbackNode } from "../CodeHighlighter/fallbackFormat.mjs";
5
+ import { type MarkdownFile } from "./generateVariantMarkdown.mjs";
4
6
  import type { TransformedFiles } from "./useCodeUtils.mjs";
5
7
  interface UseCopyFunctionalityProps {
6
8
  selectedFile: VariantSource | null;
7
9
  selectedVariant: VariantCode | null;
8
10
  transformedFiles: TransformedFiles | undefined;
11
+ /**
12
+ * Per-file fallbacks for the selected variant (keyed by file name). Used as
13
+ * the DEFLATE dictionary to decode `hastCompressed` sources back to text.
14
+ */
15
+ fallbacks?: Fallbacks;
16
+ /** Fallback for the single selected file (the dictionary for `selectedFile`). */
17
+ selectedFileFallback?: FallbackNode[];
9
18
  /** Title used as the heading for the Markdown copy. */
10
19
  title?: string;
11
20
  copyOpts?: UseCopierOpts;
@@ -18,6 +27,7 @@ export interface UseCopyFunctionalityResult {
18
27
  */
19
28
  copyMarkdown: (event: React.MouseEvent<Element>) => Promise<void>;
20
29
  }
30
+ export declare function collectVariantFiles(selectedVariant: VariantCode | null, transformedFiles: TransformedFiles | undefined, fallbacks?: Fallbacks): MarkdownFile[];
21
31
  /**
22
32
  * Hook for managing copy-to-clipboard functionality
23
33
  */
@@ -25,6 +35,8 @@ export declare function useCopyFunctionality({
25
35
  selectedFile,
26
36
  selectedVariant,
27
37
  transformedFiles,
38
+ fallbacks,
39
+ selectedFileFallback,
28
40
  title,
29
41
  copyOpts
30
42
  }: UseCopyFunctionalityProps): UseCopyFunctionalityResult;
@@ -2,24 +2,52 @@ import * as React from 'react';
2
2
  import { stringOrHastToString } from "../pipeline/hastUtils/index.mjs";
3
3
  import { useCopier } from "../useCopier/index.mjs";
4
4
  import { generateVariantMarkdown } from "./generateVariantMarkdown.mjs";
5
- function collectVariantFiles(selectedVariant, transformedFiles) {
5
+ export function collectVariantFiles(selectedVariant, transformedFiles, fallbacks) {
6
6
  if (!selectedVariant) {
7
7
  return [];
8
8
  }
9
9
 
10
+ // Resolve per-file DEFLATE dictionaries from both places a fallback can
11
+ // arrive (mirrors `resolvedFallbacks` in `useFileNavigation`): the passed
12
+ // `fallbacks` (hoisted from a `ContentLoading` component) and the variant's
13
+ // own per-file `fallback` fields (kept on `Code` when not stripped — e.g. the
14
+ // standalone `useCode`/`useDemo` path with no `CodeHighlighter` context, so
15
+ // `context?.fallbacks` is undefined). Without this merge, copy-as-markdown
16
+ // throws on a `hastCompressed` source whose dictionary lives on the
17
+ // `VariantCode`. The variant copy wins so the full text — the dictionary
18
+ // `hastCompressed` needs — is used when a `fallbackCollapsed` block hoisted
19
+ // only the visible window.
20
+ const resolvedFallbacks = {
21
+ ...fallbacks
22
+ };
23
+ if (selectedVariant.fileName && selectedVariant.fallback) {
24
+ resolvedFallbacks[selectedVariant.fileName] = selectedVariant.fallback;
25
+ }
26
+ for (const [name, fileData] of Object.entries(selectedVariant.extraFiles || {})) {
27
+ if (typeof fileData === 'object' && fileData?.fallback) {
28
+ resolvedFallbacks[name] = fileData.fallback;
29
+ }
30
+ }
31
+
10
32
  // When a transform has produced files, prefer them so the copied snippet
11
- // matches what the user is currently viewing.
33
+ // matches what the user is currently viewing. Files the transform actually
34
+ // rewrote are live HAST (already decoded), but files it left untouched are
35
+ // passed through as their ORIGINAL source, which may still be `hastCompressed`
36
+ // and needs its dictionary — resolved here by `originalName`.
12
37
  if (transformedFiles && transformedFiles.files.length > 0) {
13
38
  return transformedFiles.files.map(file => ({
14
39
  name: file.name,
15
- source: stringOrHastToString(file.source)
40
+ source: stringOrHastToString(file.source, resolvedFallbacks[file.originalName])
16
41
  }));
17
42
  }
18
43
  const files = [];
19
44
  if (selectedVariant.fileName && selectedVariant.source !== undefined) {
20
45
  files.push({
21
46
  name: selectedVariant.fileName,
22
- source: stringOrHastToString(selectedVariant.source)
47
+ // `resolvedFallbacks` is the active variant's per-file dictionary map, so
48
+ // it decodes a `hastCompressed` source in both the hoisted and the
49
+ // on-`VariantCode` cases.
50
+ source: stringOrHastToString(selectedVariant.source, resolvedFallbacks[selectedVariant.fileName])
23
51
  });
24
52
  }
25
53
  if (selectedVariant.extraFiles) {
@@ -32,7 +60,7 @@ function collectVariantFiles(selectedVariant, transformedFiles) {
32
60
  } else if (fileData && typeof fileData === 'object' && fileData.source !== undefined) {
33
61
  files.push({
34
62
  name,
35
- source: stringOrHastToString(fileData.source)
63
+ source: stringOrHastToString(fileData.source, resolvedFallbacks[name])
36
64
  });
37
65
  }
38
66
  }
@@ -47,6 +75,8 @@ export function useCopyFunctionality({
47
75
  selectedFile,
48
76
  selectedVariant,
49
77
  transformedFiles,
78
+ fallbacks,
79
+ selectedFileFallback,
50
80
  title,
51
81
  copyOpts
52
82
  }) {
@@ -54,10 +84,10 @@ export function useCopyFunctionality({
54
84
  if (!selectedFile) {
55
85
  return undefined;
56
86
  }
57
- return stringOrHastToString(selectedFile);
58
- }, [selectedFile]);
87
+ return stringOrHastToString(selectedFile, selectedFileFallback);
88
+ }, [selectedFile, selectedFileFallback]);
59
89
  const variantToMarkdown = React.useCallback(() => {
60
- const files = collectVariantFiles(selectedVariant, transformedFiles);
90
+ const files = collectVariantFiles(selectedVariant, transformedFiles, fallbacks);
61
91
  if (files.length === 0) {
62
92
  return undefined;
63
93
  }
@@ -65,7 +95,7 @@ export function useCopyFunctionality({
65
95
  title,
66
96
  files
67
97
  });
68
- }, [selectedVariant, transformedFiles, title]);
98
+ }, [selectedVariant, transformedFiles, fallbacks, title]);
69
99
  const {
70
100
  copy
71
101
  } = useCopier(sourceFileToText, copyOpts);
@@ -1,7 +1,15 @@
1
- import { describe, it, expect, vi, afterEach } from 'vitest';
1
+ import { describe, it, expect, vi, afterEach, beforeAll } from 'vitest';
2
2
  import { renderHook, act } from '@testing-library/react';
3
3
  import { userEvent } from 'vitest/browser';
4
- import { useEditable } from "./useEditable.mjs";
4
+ import { useEditable, preloadEditableEngine } from "./useEditable.mjs";
5
+
6
+ // `useEditable` loads its heavy runtime (the `EditableEngine` chunk) on demand
7
+ // and only applies `contentEditable` once it resolves. Warm that load once so
8
+ // the synchronous assertions below see `contentEditable` applied within `act`,
9
+ // mirroring the warmed module cache a real page reaches after its first block.
10
+ beforeAll(async () => {
11
+ await preloadEditableEngine();
12
+ });
5
13
 
6
14
  /**
7
15
  * Places the caret at a given character offset inside `element` and waits