@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.
- package/ChunkProvider/ChunkContext.d.mts +10 -0
- package/ChunkProvider/ChunkContext.mjs +15 -0
- package/ChunkProvider/ChunkProvider.d.mts +14 -0
- package/ChunkProvider/ChunkProvider.mjs +38 -0
- package/ChunkProvider/PreloadContext.d.mts +14 -0
- package/ChunkProvider/PreloadContext.mjs +18 -0
- package/ChunkProvider/PreloadProvider.d.mts +13 -0
- package/ChunkProvider/PreloadProvider.mjs +33 -0
- package/ChunkProvider/index.d.mts +7 -0
- package/ChunkProvider/index.mjs +7 -0
- package/ChunkProvider/types.d.mts +23 -0
- package/ChunkProvider/types.mjs +1 -0
- package/ChunkProvider/usePreload.d.mts +8 -0
- package/ChunkProvider/usePreload.mjs +21 -0
- package/CodeControllerContext/CodeControllerContext.d.mts +11 -0
- package/CodeControllerContext/CodeControllerContext.mjs +2 -1
- package/CodeHighlighter/CodeHighlighter.d.mts +15 -1
- package/CodeHighlighter/CodeHighlighter.mjs +97 -319
- package/CodeHighlighter/CodeHighlighterChunk.d.mts +42 -0
- package/CodeHighlighter/CodeHighlighterChunk.mjs +77 -0
- package/CodeHighlighter/CodeHighlighterClient.mjs +597 -128
- package/CodeHighlighter/CodeHighlighterContext.d.mts +57 -1
- package/CodeHighlighter/CodeHighlighterFallbackContext.d.mts +14 -2
- package/CodeHighlighter/CodeHighlighterFallbackContext.mjs +1 -3
- package/CodeHighlighter/CodeInitialSourceLoader.d.mts +10 -0
- package/CodeHighlighter/CodeInitialSourceLoader.mjs +108 -0
- package/CodeHighlighter/CodeSourceLoader.d.mts +11 -0
- package/CodeHighlighter/CodeSourceLoader.mjs +128 -0
- package/CodeHighlighter/buildCodeHighlighterChunkProps.d.mts +47 -0
- package/CodeHighlighter/buildCodeHighlighterChunkProps.mjs +61 -0
- package/CodeHighlighter/buildStringFallback.d.mts +29 -0
- package/CodeHighlighter/buildStringFallback.mjs +42 -0
- package/CodeHighlighter/codeToFallbackProps.d.mts +31 -2
- package/CodeHighlighter/codeToFallbackProps.mjs +347 -42
- package/CodeHighlighter/createClientProps.d.mts +17 -0
- package/CodeHighlighter/createClientProps.mjs +78 -0
- package/CodeHighlighter/errors.d.mts +6 -0
- package/CodeHighlighter/errors.mjs +10 -0
- package/CodeHighlighter/fallbackCompression.d.mts +96 -0
- package/CodeHighlighter/fallbackCompression.mjs +253 -0
- package/CodeHighlighter/fallbackFormat.d.mts +137 -0
- package/CodeHighlighter/fallbackFormat.mjs +422 -0
- package/CodeHighlighter/index.d.mts +4 -1
- package/CodeHighlighter/index.mjs +3 -1
- package/CodeHighlighter/mergeComments.d.mts +38 -0
- package/CodeHighlighter/mergeComments.mjs +80 -0
- package/CodeHighlighter/prepareInitialSource.d.mts +42 -0
- package/CodeHighlighter/prepareInitialSource.mjs +292 -0
- package/CodeHighlighter/resolveFallbackCritical.d.mts +23 -0
- package/CodeHighlighter/resolveFallbackCritical.mjs +44 -0
- package/CodeHighlighter/types.d.mts +272 -8
- package/CodeHighlighter/useCodeFallback.d.mts +94 -0
- package/CodeHighlighter/useCodeFallback.mjs +204 -0
- package/CodeHighlighter/useGrammarsReady.d.mts +18 -0
- package/CodeHighlighter/useGrammarsReady.mjs +45 -0
- package/CodeHighlighter/useSpeculativeCodePreload.d.mts +26 -0
- package/CodeHighlighter/useSpeculativeCodePreload.mjs +40 -0
- package/CodeHighlighter/useSpeculativeEditingPreload.d.mts +33 -0
- package/CodeHighlighter/useSpeculativeEditingPreload.mjs +58 -0
- package/CodeHighlighter/useSpeculativeGrammarPreload.d.mts +23 -0
- package/CodeHighlighter/useSpeculativeGrammarPreload.mjs +31 -0
- package/CodeHighlighter/useSpeculativeUseCodePreload.d.mts +22 -0
- package/CodeHighlighter/useSpeculativeUseCodePreload.mjs +41 -0
- package/CodeProvider/CodeContext.d.mts +47 -12
- package/CodeProvider/CodeContext.mjs +7 -0
- package/CodeProvider/CodeProvider.d.mts +4 -2
- package/CodeProvider/CodeProvider.mjs +40 -102
- package/CodeProvider/CodeProviderLazy.d.mts +40 -0
- package/CodeProvider/CodeProviderLazy.mjs +96 -0
- package/CodeProvider/constants.d.mts +26 -0
- package/CodeProvider/constants.mjs +24 -0
- package/CodeProvider/createParseSourceWorkerClient.d.mts +6 -0
- package/CodeProvider/createParseSourceWorkerClient.mjs +22 -2
- package/CodeProvider/index.d.mts +2 -1
- package/CodeProvider/index.mjs +9 -1
- package/CodeProvider/parseSourceWorker.mjs +33 -0
- package/CodeProvider/useCodeProviderValue.d.mts +54 -0
- package/CodeProvider/useCodeProviderValue.mjs +188 -0
- package/CoordinatedLazy/ChunkServerLoader.d.mts +25 -0
- package/CoordinatedLazy/ChunkServerLoader.mjs +97 -0
- package/CoordinatedLazy/CoordinatedContentContext.d.mts +15 -0
- package/CoordinatedLazy/CoordinatedContentContext.mjs +22 -0
- package/CoordinatedLazy/CoordinatedFallbackContext.d.mts +11 -0
- package/CoordinatedLazy/CoordinatedFallbackContext.mjs +13 -0
- package/CoordinatedLazy/CoordinatedGateContext.d.mts +14 -0
- package/CoordinatedLazy/CoordinatedGateContext.mjs +19 -0
- package/CoordinatedLazy/CoordinatedLazy.d.mts +14 -0
- package/CoordinatedLazy/CoordinatedLazy.mjs +86 -0
- package/CoordinatedLazy/CoordinatedLazyClient.d.mts +24 -0
- package/CoordinatedLazy/CoordinatedLazyClient.mjs +65 -0
- package/CoordinatedLazy/LazyContent.d.mts +26 -0
- package/CoordinatedLazy/LazyContent.mjs +80 -0
- package/CoordinatedLazy/LazyContentServer.d.mts +18 -0
- package/CoordinatedLazy/LazyContentServer.mjs +25 -0
- package/CoordinatedLazy/buildChunkRenderInputs.d.mts +8 -0
- package/CoordinatedLazy/buildChunkRenderInputs.mjs +35 -0
- package/CoordinatedLazy/createCoordinatedLazy.d.mts +32 -0
- package/CoordinatedLazy/createCoordinatedLazy.mjs +127 -0
- package/CoordinatedLazy/index.d.mts +14 -0
- package/CoordinatedLazy/index.mjs +18 -0
- package/CoordinatedLazy/resolveChunkRender.d.mts +26 -0
- package/CoordinatedLazy/resolveChunkRender.mjs +73 -0
- package/CoordinatedLazy/types.d.mts +408 -0
- package/CoordinatedLazy/types.mjs +1 -0
- package/CoordinatedLazy/useChunk.d.mts +30 -0
- package/CoordinatedLazy/useChunk.mjs +135 -0
- package/CoordinatedLazy/useCoordinatedFallback.d.mts +12 -0
- package/CoordinatedLazy/useCoordinatedFallback.mjs +40 -0
- package/CoordinatedLazy/useCoordinatedSwap.d.mts +16 -0
- package/CoordinatedLazy/useCoordinatedSwap.mjs +124 -0
- package/LICENSE +1 -1
- package/abstractCreateDemo/abstractCreateDemo.d.mts +54 -3
- package/abstractCreateDemo/abstractCreateDemo.mjs +47 -7
- package/abstractCreateDemo/resolveDemoFlag.d.mts +20 -0
- package/abstractCreateDemo/resolveDemoFlag.mjs +25 -0
- package/abstractCreateStream/abstractCreateStream.d.mts +18 -0
- package/abstractCreateStream/abstractCreateStream.mjs +45 -0
- package/abstractCreateStream/index.d.mts +2 -0
- package/abstractCreateStream/index.mjs +1 -0
- package/abstractCreateStream/types.d.mts +34 -0
- package/abstractCreateStream/types.mjs +1 -0
- package/abstractCreateTypes/TypeCode.mjs +12 -11
- package/abstractCreateTypes/typesToJsx.mjs +30 -9
- package/cli/ensureDemoClients.mjs +4 -148
- package/cli/ensureDemoPages.d.mts +45 -0
- package/cli/ensureDemoPages.mjs +99 -0
- package/cli/fileUtils/index.d.mts +11 -0
- package/cli/fileUtils/index.mjs +48 -0
- package/cli/findDemoIndexFiles.d.mts +15 -0
- package/cli/findDemoIndexFiles.mjs +121 -0
- package/cli/index.mjs +1 -1
- package/cli/loadNextConfig.d.mts +25 -0
- package/cli/loadNextConfig.mjs +60 -1
- package/cli/runBrowser.mjs +1 -1
- package/cli/runValidate.mjs +44 -1
- package/package.json +84 -4
- package/pipeline/enhanceCodeEmphasis/enhanceCodeEmphasis.mjs +30 -0
- package/pipeline/enhanceCodeEmphasis/enhanceCodeEmphasisLazy.d.mts +17 -0
- package/pipeline/enhanceCodeEmphasis/enhanceCodeEmphasisLazy.mjs +52 -0
- package/pipeline/hastUtils/frameFallbackFromSpans.d.mts +18 -0
- package/pipeline/hastUtils/frameFallbackFromSpans.mjs +24 -0
- package/pipeline/hastUtils/hast.d.mts +27 -0
- package/pipeline/hastUtils/hastCompression.d.mts +3 -1
- package/pipeline/hastUtils/hastCompression.mjs +9 -1
- package/pipeline/hastUtils/hastDecompress.mjs +10 -4
- package/pipeline/hastUtils/hastDictionary.mjs +9 -0
- package/pipeline/hastUtils/hastUtils.d.mts +4 -3
- package/pipeline/hastUtils/hastUtils.mjs +24 -12
- package/pipeline/hastUtils/index.d.mts +2 -1
- package/pipeline/hastUtils/index.mjs +2 -1
- package/pipeline/hastUtils/stripHighlightingSpans.d.mts +6 -2
- package/pipeline/hastUtils/stripHighlightingSpans.mjs +22 -10
- package/pipeline/lintJavascriptDemoFocus/lintJavascriptDemoFocus.mjs +10 -7
- package/pipeline/loadIsomorphicCodeVariant/applyCodeTransform.d.mts +31 -13
- package/pipeline/loadIsomorphicCodeVariant/applyCodeTransform.mjs +50 -55
- package/pipeline/loadIsomorphicCodeVariant/applyCodeTransformWithComments.d.mts +78 -0
- package/pipeline/loadIsomorphicCodeVariant/applyCodeTransformWithComments.mjs +405 -0
- package/pipeline/loadIsomorphicCodeVariant/computeHastDeltas.d.mts +5 -5
- package/pipeline/loadIsomorphicCodeVariant/computeHastDeltas.mjs +36 -66
- package/pipeline/loadIsomorphicCodeVariant/decodeHastSource.d.mts +23 -0
- package/pipeline/loadIsomorphicCodeVariant/decodeHastSource.mjs +92 -0
- package/pipeline/loadIsomorphicCodeVariant/decodeSource.d.mts +19 -0
- package/pipeline/loadIsomorphicCodeVariant/decodeSource.mjs +25 -0
- package/pipeline/loadIsomorphicCodeVariant/decodeSourceToText.d.mts +17 -0
- package/pipeline/loadIsomorphicCodeVariant/decodeSourceToText.mjs +26 -0
- package/pipeline/loadIsomorphicCodeVariant/diffHast.d.mts +26 -2
- package/pipeline/loadIsomorphicCodeVariant/diffHast.mjs +563 -19
- package/pipeline/loadIsomorphicCodeVariant/embedTransforms.d.mts +49 -0
- package/pipeline/loadIsomorphicCodeVariant/embedTransforms.mjs +152 -0
- package/pipeline/loadIsomorphicCodeVariant/findExpandingRanges.d.mts +51 -0
- package/pipeline/loadIsomorphicCodeVariant/findExpandingRanges.mjs +161 -0
- package/pipeline/loadIsomorphicCodeVariant/flattenCodeVariant.mjs +6 -3
- package/pipeline/loadIsomorphicCodeVariant/getAvailableTransforms.d.mts +12 -0
- package/pipeline/loadIsomorphicCodeVariant/getAvailableTransforms.mjs +44 -0
- package/pipeline/loadIsomorphicCodeVariant/getInitialVisibleSourceLines.d.mts +16 -0
- package/pipeline/loadIsomorphicCodeVariant/getInitialVisibleSourceLines.mjs +74 -0
- package/pipeline/loadIsomorphicCodeVariant/loadCodeFallback.mjs +17 -5
- package/pipeline/loadIsomorphicCodeVariant/loadIsomorphicCodeVariant.mjs +229 -15
- package/pipeline/loadIsomorphicCodeVariant/transformSource.d.mts +2 -2
- package/pipeline/loadIsomorphicCodeVariant/transformSource.mjs +56 -22
- package/pipeline/loadPrecomputedCodeHighlighter/loadPrecomputedCodeHighlighter.d.mts +18 -0
- package/pipeline/loadPrecomputedCodeHighlighter/loadPrecomputedCodeHighlighter.mjs +11 -7
- package/pipeline/loadServerTypes/hastTypeUtils.d.mts +2 -2
- package/pipeline/loadServerTypes/hastTypeUtils.mjs +4 -4
- package/pipeline/loadServerTypes/loadServerTypes.mjs +1 -1
- package/pipeline/loadServerTypesMeta/extractJSDocText.d.mts +14 -0
- package/pipeline/loadServerTypesMeta/extractJSDocText.mjs +60 -0
- package/pipeline/loadServerTypesMeta/processTypes.mjs +43 -46
- package/pipeline/loadServerTypesText/order.mjs +1 -1
- package/pipeline/loadServerTypesText/parseTypesMarkdown.mjs +3 -1
- package/pipeline/loaderUtils/index.d.mts +0 -1
- package/pipeline/loaderUtils/index.mjs +0 -1
- package/pipeline/loaderUtils/parseImportsAndComments.d.mts +5 -1
- package/pipeline/loaderUtils/parseImportsAndComments.mjs +19 -9
- package/pipeline/loaderUtils/resolveModulePath.mjs +23 -1
- package/pipeline/parseCreateFactoryCall/parseCreateFactoryCall.d.mts +12 -0
- package/pipeline/parseCreateFactoryCall/parseCreateFactoryCall.mjs +17 -13
- package/pipeline/parseSource/addLineGutters.mjs +45 -11
- package/pipeline/parseSource/calculateFrameRanges.d.mts +22 -0
- package/pipeline/parseSource/calculateFrameRanges.mjs +69 -25
- package/pipeline/parseSource/detectGrammarScopes.d.mts +13 -0
- package/pipeline/parseSource/detectGrammarScopes.mjs +35 -0
- package/pipeline/parseSource/extendSyntaxTokens.mjs +501 -43
- package/pipeline/parseSource/frameVisibility.d.mts +47 -0
- package/pipeline/parseSource/frameVisibility.mjs +114 -0
- package/pipeline/parseSource/grammarCache.d.mts +33 -0
- package/pipeline/parseSource/grammarCache.mjs +73 -0
- package/pipeline/parseSource/grammarLoaders.d.mts +14 -0
- package/pipeline/parseSource/grammarLoaders.mjs +24 -0
- package/pipeline/parseSource/grammarMaps.d.mts +21 -1
- package/pipeline/parseSource/grammarMaps.mjs +36 -0
- package/pipeline/parseSource/isFrameSpan.d.mts +19 -0
- package/pipeline/parseSource/isFrameSpan.mjs +24 -0
- package/pipeline/parseSource/parseSource.d.mts +41 -6
- package/pipeline/parseSource/parseSource.mjs +184 -36
- package/pipeline/parseSource/redistributeFrameFallbacks.d.mts +40 -0
- package/pipeline/parseSource/redistributeFrameFallbacks.mjs +138 -0
- package/pipeline/parseSource/restructureFrames.d.mts +5 -0
- package/pipeline/parseSource/restructureFrames.mjs +179 -16
- package/pipeline/syncPageIndex/metadataToMarkdown.mjs +6 -2
- package/pipeline/transformHtmlCodeBlock/transformHtmlCodeBlock.d.mts +26 -0
- package/pipeline/transformHtmlCodeBlock/transformHtmlCodeBlock.mjs +181 -114
- package/pipeline/transformHtmlCodeInline/removeSuffixFromHighlightedNodes.d.mts +12 -0
- package/pipeline/transformHtmlCodeInline/removeSuffixFromHighlightedNodes.mjs +52 -0
- package/pipeline/transformHtmlCodeInline/transformHtmlCodeInline.mjs +22 -1
- package/pipeline/transformTypescriptToJavascript/removeTypes.d.mts +5 -8
- package/pipeline/transformTypescriptToJavascript/removeTypes.mjs +27 -93
- package/useCode/EditableEngine.d.mts +233 -0
- package/useCode/EditableEngine.mjs +1712 -0
- package/useCode/EditingEngine.d.mts +13 -0
- package/useCode/EditingEngine.mjs +14 -0
- package/useCode/Pre.browser.mjs +5 -1
- package/useCode/Pre.d.mts +127 -1
- package/useCode/Pre.mjs +417 -165
- package/useCode/SourceEditingEngine.d.mts +50 -0
- package/useCode/SourceEditingEngine.mjs +461 -0
- package/useCode/TransformEngine.d.mts +39 -0
- package/useCode/TransformEngine.mjs +208 -0
- package/useCode/editingEngineCache.d.mts +29 -0
- package/useCode/editingEngineCache.mjs +68 -0
- package/useCode/sourceLineCounts.d.mts +80 -0
- package/useCode/sourceLineCounts.mjs +284 -0
- package/useCode/subscribeToggleNudge.d.mts +3 -0
- package/useCode/subscribeToggleNudge.mjs +95 -0
- package/useCode/transformEngineCache.d.mts +21 -0
- package/useCode/transformEngineCache.mjs +60 -0
- package/useCode/useCode.d.mts +140 -1
- package/useCode/useCode.mjs +250 -19
- package/useCode/useCodeUtils.d.mts +131 -20
- package/useCode/useCodeUtils.mjs +267 -194
- package/useCode/useCopyFunctionality.d.mts +13 -1
- package/useCode/useCopyFunctionality.mjs +39 -9
- package/useCode/useEditable.browser.mjs +10 -2
- package/useCode/useEditable.d.mts +27 -106
- package/useCode/useEditable.integration.browser.d.mts +1 -0
- package/useCode/useEditable.integration.browser.mjs +870 -0
- package/useCode/useEditable.mjs +198 -1247
- package/useCode/useEditableUtils.d.mts +50 -1
- package/useCode/useEditableUtils.mjs +29 -0
- package/useCode/useFileNavigation.d.mts +91 -3
- package/useCode/useFileNavigation.mjs +201 -41
- package/useCode/useHighlightGate.d.mts +17 -0
- package/useCode/useHighlightGate.mjs +147 -0
- package/useCode/useSourceEditing.d.mts +8 -0
- package/useCode/useSourceEditing.mjs +158 -314
- package/useCode/useSourceEnhancing.d.mts +5 -1
- package/useCode/useSourceEnhancing.mjs +22 -36
- package/useCode/useTransformManagement.d.mts +93 -5
- package/useCode/useTransformManagement.mjs +496 -28
- package/useCode/useTransitionPhase.d.mts +24 -0
- package/useCode/useTransitionPhase.mjs +49 -0
- package/useCode/useUIState.d.mts +2 -2
- package/useCode/useUIState.mjs +8 -8
- package/useCode/useVariantSelection.d.mts +130 -6
- package/useCode/useVariantSelection.mjs +529 -93
- package/useCodeWindow/useCodeWindow.d.mts +19 -2
- package/useCodeWindow/useCodeWindow.mjs +98 -71
- package/useCoordinated/coordinatePreference.d.mts +439 -0
- package/useCoordinated/coordinatePreference.mjs +951 -0
- package/useCoordinated/coordinatePreference.testUtils.d.mts +21 -0
- package/useCoordinated/coordinatePreference.testUtils.mjs +69 -0
- package/useCoordinated/createSettleGate.d.mts +96 -0
- package/useCoordinated/createSettleGate.mjs +171 -0
- package/useCoordinated/index.d.mts +8 -0
- package/useCoordinated/index.mjs +8 -0
- package/useCoordinated/layoutShiftGate.d.mts +24 -0
- package/useCoordinated/layoutShiftGate.mjs +79 -0
- package/useCoordinated/pageSettleGate.d.mts +11 -0
- package/useCoordinated/pageSettleGate.mjs +13 -0
- package/useCoordinated/scheduleTasks.d.mts +23 -0
- package/useCoordinated/scheduleTasks.mjs +45 -0
- package/useCoordinated/useCoordinated.d.mts +193 -0
- package/useCoordinated/useCoordinated.mjs +469 -0
- package/useCoordinated/useCoordinatedLazy.d.mts +17 -0
- package/useCoordinated/useCoordinatedLazy.mjs +38 -0
- package/useCoordinated/useCoordinatedLocalStorage.d.mts +16 -0
- package/useCoordinated/useCoordinatedLocalStorage.mjs +22 -0
- package/useCoordinated/useCoordinatedPreference.d.mts +20 -0
- package/useCoordinated/useCoordinatedPreference.mjs +26 -0
- package/useCoordinated/useSettleGate.d.mts +11 -0
- package/useCoordinated/useSettleGate.mjs +34 -0
- package/useDemo/exportVariant.d.mts +12 -5
- package/useDemo/exportVariant.mjs +59 -5
- package/useDemo/useDemo.d.mts +5 -2
- package/useScrollAnchor/useScrollAnchor.mjs +28 -5
- package/useStream/index.d.mts +6 -0
- package/useStream/index.mjs +6 -0
- package/useStream/streamChunks.d.mts +23 -0
- package/useStream/streamChunks.mjs +85 -0
- package/useStream/types.d.mts +45 -0
- package/useStream/types.mjs +1 -0
- package/useStream/useStream.d.mts +57 -0
- package/useStream/useStream.mjs +119 -0
- package/useStream/useStreamController.d.mts +15 -0
- package/useStream/useStreamController.mjs +90 -0
- package/withDocsInfra/withDocsInfra.d.mts +19 -0
- package/withDocsInfra/withDocsInfra.mjs +13 -5
- package/pipeline/loaderUtils/convertCommentsToOneIndexed.d.mts +0 -8
- package/pipeline/loaderUtils/convertCommentsToOneIndexed.mjs +0 -16
package/useCode/useCodeUtils.mjs
CHANGED
|
@@ -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
|
-
*
|
|
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
|
|
13
|
+
* @returns Array of available transform keys (toggle-visible only)
|
|
9
14
|
*/
|
|
10
15
|
export function getAvailableTransforms(effectiveCode, selectedVariantKey) {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
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
|
-
*
|
|
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
|
|
61
|
-
* @param
|
|
62
|
-
* @
|
|
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
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
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
|
-
|
|
74
|
-
|
|
75
|
-
|
|
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
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
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
|
-
*
|
|
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
|
-
*
|
|
113
|
-
*
|
|
114
|
-
*
|
|
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
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
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
|
-
//
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
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
|
-
//
|
|
137
|
-
if (
|
|
138
|
-
|
|
139
|
-
if (
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
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
|
-
//
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
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
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
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
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
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
|
-
|
|
189
|
-
|
|
190
|
-
|
|
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
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
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
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
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
|
-
|
|
230
|
-
|
|
231
|
-
|
|
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
|
-
|
|
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
|