@mui/internal-docs-infra 0.11.1-canary.0 → 0.11.1-canary.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 (107) hide show
  1. package/CodeHighlighter/CodeHighlighter.mjs +25 -10
  2. package/CodeHighlighter/CodeHighlighterClient.mjs +37 -18
  3. package/CodeHighlighter/errors.mjs +2 -2
  4. package/CodeHighlighter/types.d.mts +32 -1
  5. package/CodeProvider/CodeContext.d.mts +1 -1
  6. package/CodeProvider/CodeProvider.mjs +5 -5
  7. package/abstractCreateDemo/abstractCreateDemo.d.mts +18 -0
  8. package/abstractCreateDemo/abstractCreateDemo.mjs +34 -3
  9. package/cli/ensureDemoClients.mjs +2 -2
  10. package/cli/validateWorker.mjs +1 -1
  11. package/package.json +107 -87
  12. package/pipeline/loadIsomorphicCodeSource/index.d.mts +1 -0
  13. package/pipeline/loadIsomorphicCodeSource/index.mjs +1 -0
  14. package/pipeline/loadIsomorphicCodeSource/loadIsomorphicCodeSource.d.mts +76 -0
  15. package/pipeline/loadIsomorphicCodeSource/loadIsomorphicCodeSource.mjs +154 -0
  16. package/pipeline/{loadCodeVariant → loadIsomorphicCodeVariant}/index.d.mts +1 -1
  17. package/pipeline/{loadCodeVariant → loadIsomorphicCodeVariant}/index.mjs +1 -1
  18. package/pipeline/{loadCodeVariant → loadIsomorphicCodeVariant}/loadCodeFallback.mjs +60 -41
  19. package/pipeline/{loadCodeVariant/loadCodeVariant.d.mts → loadIsomorphicCodeVariant/loadIsomorphicCodeVariant.d.mts} +1 -1
  20. package/pipeline/{loadCodeVariant/loadCodeVariant.mjs → loadIsomorphicCodeVariant/loadIsomorphicCodeVariant.mjs} +98 -31
  21. package/pipeline/loadPrecomputedCodeHighlighter/loadPrecomputedCodeHighlighter.mjs +7 -7
  22. package/pipeline/loadPrecomputedCodeHighlighterClient/loadPrecomputedCodeHighlighterClient.mjs +7 -7
  23. package/pipeline/loadPrecomputedSitemap/loadPrecomputedSitemap.mjs +2 -2
  24. package/pipeline/loadPrecomputedTypes/loadPrecomputedTypes.mjs +2 -2
  25. package/pipeline/loadServerCodeMeta/loadServerCodeMeta.d.mts +1 -1
  26. package/pipeline/loadServerCodeMeta/loadServerCodeMeta.mjs +2 -2
  27. package/pipeline/loadServerCodeSource/index.d.mts +1 -0
  28. package/pipeline/loadServerCodeSource/index.mjs +1 -0
  29. package/pipeline/{loadServerSource/loadServerSource.d.mts → loadServerCodeSource/loadServerCodeSource.d.mts} +5 -5
  30. package/pipeline/loadServerCodeSource/loadServerCodeSource.mjs +43 -0
  31. package/pipeline/loadServerSitemap/loadServerSitemap.mjs +1 -1
  32. package/pipeline/loadServerTypesMeta/formatType.mjs +25 -3
  33. package/pipeline/loaderUtils/applyUrlPrefix.d.mts +40 -0
  34. package/pipeline/loaderUtils/applyUrlPrefix.mjs +99 -0
  35. package/pipeline/loaderUtils/convertCommentsToOneIndexed.d.mts +8 -0
  36. package/pipeline/loaderUtils/convertCommentsToOneIndexed.mjs +16 -0
  37. package/pipeline/loaderUtils/generateFileSlug.d.mts +9 -0
  38. package/pipeline/loaderUtils/generateFileSlug.mjs +36 -0
  39. package/pipeline/loaderUtils/index.d.mts +3 -1
  40. package/pipeline/loaderUtils/index.mjs +3 -1
  41. package/pipeline/loaderUtils/parseImportsAndComments.d.mts +7 -4
  42. package/pipeline/loaderUtils/parseImportsAndComments.mjs +33 -13
  43. package/pipeline/parseCreateFactoryCall/index.d.mts +2 -0
  44. package/pipeline/parseCreateFactoryCall/index.mjs +2 -0
  45. package/pipeline/{loadPrecomputedCodeHighlighter → parseCreateFactoryCall}/parseCreateFactoryCall.d.mts +1 -3
  46. package/pipeline/{loadPrecomputedCodeHighlighter → parseCreateFactoryCall}/parseCreateFactoryCall.mjs +2 -1
  47. package/pipeline/transformHtmlCodeBlock/transformHtmlCodeBlock.d.mts +2 -2
  48. package/pipeline/transformHtmlCodeBlock/transformHtmlCodeBlock.mjs +6 -6
  49. package/useCode/generateVariantMarkdown.d.mts +18 -0
  50. package/useCode/generateVariantMarkdown.mjs +89 -0
  51. package/useCode/useCode.d.mts +12 -1
  52. package/useCode/useCode.mjs +12 -1
  53. package/useCode/useCodeUtils.mjs +1 -1
  54. package/useCode/useCopyFunctionality.d.mts +15 -2
  55. package/useCode/useCopyFunctionality.mjs +57 -7
  56. package/useCode/useFileNavigation.d.mts +1 -0
  57. package/useCode/useFileNavigation.mjs +39 -35
  58. package/useCode/useSourceEnhancing.mjs +1 -1
  59. package/useCopier/index.d.mts +2 -2
  60. package/useDemo/createCodeSandbox.d.mts +1 -1
  61. package/useDemo/createStackBlitz.d.mts +1 -1
  62. package/useDemo/exportVariant.mjs +2 -2
  63. package/useDemo/index.d.mts +1 -1
  64. package/useDemo/index.mjs +1 -1
  65. package/useDemo/useDemo.d.mts +3 -1
  66. package/useDemo/useDemo.mjs +1 -1
  67. package/withDocsInfra/withDeploymentConfig.mjs +134 -0
  68. package/pipeline/loadServerSource/index.d.mts +0 -1
  69. package/pipeline/loadServerSource/index.mjs +0 -1
  70. package/pipeline/loadServerSource/loadServerSource.mjs +0 -165
  71. /package/pipeline/{loadCodeVariant → loadIsomorphicCodeVariant}/addCodeVariantPaths.d.mts +0 -0
  72. /package/pipeline/{loadCodeVariant → loadIsomorphicCodeVariant}/addCodeVariantPaths.mjs +0 -0
  73. /package/pipeline/{loadCodeVariant → loadIsomorphicCodeVariant}/applyCodeTransform.d.mts +0 -0
  74. /package/pipeline/{loadCodeVariant → loadIsomorphicCodeVariant}/applyCodeTransform.mjs +0 -0
  75. /package/pipeline/{loadCodeVariant → loadIsomorphicCodeVariant}/calculateMainFilePath.d.mts +0 -0
  76. /package/pipeline/{loadCodeVariant → loadIsomorphicCodeVariant}/calculateMainFilePath.mjs +0 -0
  77. /package/pipeline/{loadCodeVariant → loadIsomorphicCodeVariant}/computeHastDeltas.d.mts +0 -0
  78. /package/pipeline/{loadCodeVariant → loadIsomorphicCodeVariant}/computeHastDeltas.mjs +0 -0
  79. /package/pipeline/{loadCodeVariant → loadIsomorphicCodeVariant}/diffHast.d.mts +0 -0
  80. /package/pipeline/{loadCodeVariant → loadIsomorphicCodeVariant}/diffHast.mjs +0 -0
  81. /package/pipeline/{loadCodeVariant → loadIsomorphicCodeVariant}/enhanceCode.d.mts +0 -0
  82. /package/pipeline/{loadCodeVariant → loadIsomorphicCodeVariant}/enhanceCode.mjs +0 -0
  83. /package/pipeline/{loadCodeVariant → loadIsomorphicCodeVariant}/examineCodeVariant.d.mts +0 -0
  84. /package/pipeline/{loadCodeVariant → loadIsomorphicCodeVariant}/examineCodeVariant.mjs +0 -0
  85. /package/pipeline/{loadCodeVariant → loadIsomorphicCodeVariant}/flattenCodeVariant.d.mts +0 -0
  86. /package/pipeline/{loadCodeVariant → loadIsomorphicCodeVariant}/flattenCodeVariant.mjs +0 -0
  87. /package/pipeline/{loadCodeVariant → loadIsomorphicCodeVariant}/hasAllCodeVariants.d.mts +0 -0
  88. /package/pipeline/{loadCodeVariant → loadIsomorphicCodeVariant}/hasAllCodeVariants.mjs +0 -0
  89. /package/pipeline/{loadCodeVariant → loadIsomorphicCodeVariant}/loadCodeFallback.d.mts +0 -0
  90. /package/pipeline/{loadCodeVariant → loadIsomorphicCodeVariant}/maybeCodeInitialData.d.mts +0 -0
  91. /package/pipeline/{loadCodeVariant → loadIsomorphicCodeVariant}/maybeCodeInitialData.mjs +0 -0
  92. /package/pipeline/{loadCodeVariant → loadIsomorphicCodeVariant}/mergeCodeMetadata.d.mts +0 -0
  93. /package/pipeline/{loadCodeVariant → loadIsomorphicCodeVariant}/mergeCodeMetadata.mjs +0 -0
  94. /package/pipeline/{loadCodeVariant → loadIsomorphicCodeVariant}/parseCode.d.mts +0 -0
  95. /package/pipeline/{loadCodeVariant → loadIsomorphicCodeVariant}/parseCode.mjs +0 -0
  96. /package/pipeline/{loadCodeVariant → loadIsomorphicCodeVariant}/pathUtils.d.mts +0 -0
  97. /package/pipeline/{loadCodeVariant → loadIsomorphicCodeVariant}/pathUtils.mjs +0 -0
  98. /package/pipeline/{loadCodeVariant → loadIsomorphicCodeVariant}/runSourceEnhancers.d.mts +0 -0
  99. /package/pipeline/{loadCodeVariant → loadIsomorphicCodeVariant}/runSourceEnhancers.mjs +0 -0
  100. /package/pipeline/{loadCodeVariant → loadIsomorphicCodeVariant}/transformSource.d.mts +0 -0
  101. /package/pipeline/{loadCodeVariant → loadIsomorphicCodeVariant}/transformSource.mjs +0 -0
  102. /package/pipeline/{loadPrecomputedCodeHighlighter → parseCreateFactoryCall}/parseFunctionArguments.d.mts +0 -0
  103. /package/pipeline/{loadPrecomputedCodeHighlighter → parseCreateFactoryCall}/parseFunctionArguments.mjs +0 -0
  104. /package/pipeline/{loadPrecomputedCodeHighlighter → parseCreateFactoryCall}/replacePrecomputeValue.d.mts +0 -0
  105. /package/pipeline/{loadPrecomputedCodeHighlighter → parseCreateFactoryCall}/replacePrecomputeValue.mjs +0 -0
  106. /package/pipeline/{loadPrecomputedCodeHighlighter → parseCreateFactoryCall}/serializeFunctionArguments.d.mts +0 -0
  107. /package/pipeline/{loadPrecomputedCodeHighlighter → parseCreateFactoryCall}/serializeFunctionArguments.mjs +0 -0
@@ -1,10 +1,11 @@
1
1
  import * as React from 'react';
2
- import { loadCodeVariant } from "../pipeline/loadCodeVariant/loadCodeVariant.mjs";
3
- import { loadCodeFallback } from "../pipeline/loadCodeVariant/loadCodeFallback.mjs";
2
+ import { loadIsomorphicCodeVariant } from "../pipeline/loadIsomorphicCodeVariant/loadIsomorphicCodeVariant.mjs";
3
+ import { loadCodeFallback } from "../pipeline/loadIsomorphicCodeVariant/loadCodeFallback.mjs";
4
4
  import { CodeHighlighterClient } from "./CodeHighlighterClient.mjs";
5
- import { maybeCodeInitialData } from "../pipeline/loadCodeVariant/maybeCodeInitialData.mjs";
6
- import { hasAllVariants } from "../pipeline/loadCodeVariant/hasAllCodeVariants.mjs";
5
+ import { maybeCodeInitialData } from "../pipeline/loadIsomorphicCodeVariant/maybeCodeInitialData.mjs";
6
+ import { hasAllVariants } from "../pipeline/loadIsomorphicCodeVariant/hasAllCodeVariants.mjs";
7
7
  import { getFileNameFromUrl, getLanguageFromExtension } from "../pipeline/loaderUtils/index.mjs";
8
+ import { replaceUrlPrefix } from "../pipeline/loaderUtils/applyUrlPrefix.mjs";
8
9
  import { codeToFallbackProps } from "./codeToFallbackProps.mjs";
9
10
  import * as Errors from "./errors.mjs";
10
11
  import { jsx as _jsx } from "react/jsx-runtime";
@@ -13,17 +14,25 @@ const DEBUG = false; // Set to true for debugging purposes
13
14
  function createClientProps(props) {
14
15
  const highlightAfter = props.highlightAfter === 'stream' ? 'init' : props.highlightAfter;
15
16
  const enhanceAfter = props.enhanceAfter === 'stream' ? 'init' : props.enhanceAfter;
17
+
18
+ // Rewrite the top-level URL before it leaves the server. The client never
19
+ // receives `urlPrefix` (and shouldn't deal with `file://` URLs), so any
20
+ // local URL must be translated to its hosted form here. Variant-level URLs
21
+ // inside `code`/`precompute` are already rewritten upstream (by
22
+ // `loadIsomorphicCodeVariant` on the server, or by the demo factory for precomputed
23
+ // input).
24
+ const url = props.urlPrefix && props.url ? replaceUrlPrefix(props.url, props.urlPrefix) : props.url;
16
25
  const contentProps = {
17
26
  code: props.code || props.precompute,
18
27
  components: props.components,
19
28
  name: props.name,
20
29
  slug: props.slug,
21
- url: props.url,
30
+ url,
22
31
  variantType: props.variantType,
23
32
  ...props.contentProps
24
33
  };
25
34
  return {
26
- url: props.url,
35
+ url,
27
36
  code: props.code,
28
37
  precompute: props.precompute,
29
38
  components: props.components,
@@ -115,14 +124,15 @@ async function CodeSourceLoader(props) {
115
124
  } else if (props.deferParsing === 'none') {
116
125
  output = 'hast';
117
126
  }
118
- return loadCodeVariant(variantUrl, variantName, variantCode, {
127
+ return loadIsomorphicCodeVariant(variantUrl, variantName, variantCode, {
119
128
  sourceParser: props.sourceParser,
120
129
  loadSource: props.loadSource,
121
130
  loadVariantMeta: props.loadVariantMeta,
122
131
  sourceTransformers: props.sourceTransformers,
123
132
  sourceEnhancers: props.sourceEnhancers,
124
133
  globalsCode: resolvedGlobalsCode,
125
- output
134
+ output,
135
+ urlPrefix: props.urlPrefix
126
136
  }).then(variant => ({
127
137
  name: variantName,
128
138
  variant
@@ -182,7 +192,6 @@ async function CodeHighlighterSuspense(props) {
182
192
  function renderWithInitialSource(props) {
183
193
  const ContentLoading = props.ContentLoading;
184
194
  const {
185
- url,
186
195
  slug,
187
196
  name,
188
197
  initialVariant,
@@ -191,6 +200,11 @@ function renderWithInitialSource(props) {
191
200
  fallbackUsesExtraFiles,
192
201
  fallbackUsesAllVariants
193
202
  } = props;
203
+
204
+ // Rewrite the top-level URL before it reaches the loading fallback so the
205
+ // browser never sees `file://` URLs. See `createClientProps` for the same
206
+ // rewrite on the regular client path.
207
+ const url = props.urlPrefix && props.url ? replaceUrlPrefix(props.url, props.urlPrefix) : props.url;
194
208
  const fallbackProps = codeToFallbackProps(initialVariant, code, initialFilename, fallbackUsesExtraFiles, fallbackUsesAllVariants);
195
209
 
196
210
  // Get the component for the selected variant
@@ -272,7 +286,8 @@ async function CodeInitialSourceLoader(props) {
272
286
  initialFilename: fileName,
273
287
  variants,
274
288
  globalsCode,
275
- output
289
+ output,
290
+ urlPrefix: props.urlPrefix
276
291
  });
277
292
  return renderWithInitialSource({
278
293
  ...props,
@@ -3,12 +3,12 @@
3
3
  import * as React from 'react';
4
4
  import { useCodeContext } from "../CodeProvider/CodeContext.mjs";
5
5
  import { CodeHighlighterContext } from "./CodeHighlighterContext.mjs";
6
- import { maybeCodeInitialData } from "../pipeline/loadCodeVariant/maybeCodeInitialData.mjs";
7
- import { hasAllVariants } from "../pipeline/loadCodeVariant/hasAllCodeVariants.mjs";
6
+ import { maybeCodeInitialData } from "../pipeline/loadIsomorphicCodeVariant/maybeCodeInitialData.mjs";
7
+ import { hasAllVariants } from "../pipeline/loadIsomorphicCodeVariant/hasAllCodeVariants.mjs";
8
8
  import { CodeHighlighterFallbackContext } from "./CodeHighlighterFallbackContext.mjs";
9
9
  import { useControlledCode } from "../CodeControllerContext/index.mjs";
10
10
  import { codeToFallbackProps } from "./codeToFallbackProps.mjs";
11
- import { mergeCodeMetadata } from "../pipeline/loadCodeVariant/mergeCodeMetadata.mjs";
11
+ import { mergeCodeMetadata } from "../pipeline/loadIsomorphicCodeVariant/mergeCodeMetadata.mjs";
12
12
  import * as Errors from "./errors.mjs";
13
13
  import { jsx as _jsx } from "react/jsx-runtime";
14
14
  const DEBUG = false; // Set to true for debugging purposes
@@ -50,6 +50,11 @@ function useInitialData({
50
50
  }
51
51
  }
52
52
 
53
+ // Signal to downstream loaders that a fallback fetch is pending. Used to gate
54
+ // `useAllVariants` so it can reuse the data populated by the fallback rather
55
+ // than racing it and re-fetching the same variant.
56
+ const fallbackPending = Boolean(needsFallback && url && loadCodeFallback);
57
+
53
58
  // TODO: fallbackInitialRenderOnly option? this would mean we can't fetch fallback data on the client side
54
59
  // Load initial data if not provided
55
60
  React.useEffect(() => {
@@ -90,6 +95,9 @@ function useInitialData({
90
95
  }
91
96
  })();
92
97
  }, [initialData, reason, needsFallback, variantName, code, setCode, highlightAfter, url, sourceParser, loadSource, loadVariantMeta, loadCodeMeta, sourceEnhancers, fallbackUsesExtraFiles, fallbackUsesAllVariants, fileName, variants, globalsCode, setProcessedGlobalsCode, loadCodeFallback]);
98
+ return {
99
+ fallbackPending
100
+ };
93
101
  }
94
102
  function useAllVariants({
95
103
  readyForContent,
@@ -100,16 +108,17 @@ function useAllVariants({
100
108
  setCode,
101
109
  processedGlobalsCode,
102
110
  globalsCode,
103
- setProcessedGlobalsCode
111
+ setProcessedGlobalsCode,
112
+ fallbackPending
104
113
  }) {
105
114
  const {
106
115
  loadCodeMeta,
107
116
  loadVariantMeta,
108
117
  loadSource,
109
- loadCodeVariant,
118
+ loadIsomorphicCodeVariant,
110
119
  sourceEnhancers
111
120
  } = useCodeContext();
112
- const needsData = !readyForContent && !isControlled;
121
+ const needsData = !readyForContent && !isControlled && !fallbackPending;
113
122
 
114
123
  // validation
115
124
  React.useMemo(() => {
@@ -117,7 +126,7 @@ function useAllVariants({
117
126
  if (!url) {
118
127
  throw new Errors.ErrorCodeHighlighterClientMissingUrlForVariants();
119
128
  }
120
- if (!loadCodeVariant) {
129
+ if (!loadIsomorphicCodeVariant) {
121
130
  throw new Errors.ErrorCodeHighlighterClientMissingLoadVariant(url);
122
131
  }
123
132
  if (!code && !loadCodeMeta) {
@@ -143,9 +152,9 @@ function useAllVariants({
143
152
  throw new Errors.ErrorCodeHighlighterClientMissingLoadSourceForUnloadedUrls();
144
153
  }
145
154
  }
146
- }, [code, globalsCode, loadCodeMeta, loadCodeVariant, loadSource, needsData, url]);
155
+ }, [code, globalsCode, loadCodeMeta, loadIsomorphicCodeVariant, loadSource, needsData, url]);
147
156
  React.useEffect(() => {
148
- if (!needsData || !url || !loadCodeVariant) {
157
+ if (!needsData || !url || !loadIsomorphicCodeVariant) {
149
158
  return;
150
159
  }
151
160
 
@@ -190,7 +199,7 @@ function useAllVariants({
190
199
  // Only include if this variant exists in the globalsCode
191
200
  return codeObj[name];
192
201
  }).filter(item => Boolean(item));
193
- return loadCodeVariant(url, name, loadedCode[name], {
202
+ return loadIsomorphicCodeVariant(url, name, loadedCode[name], {
194
203
  disableParsing: true,
195
204
  disableTransforms: true,
196
205
  loadSource,
@@ -222,7 +231,7 @@ function useAllVariants({
222
231
  console.error(new Errors.ErrorCodeHighlighterClientLoadAllVariantsFailure(url, error));
223
232
  }
224
233
  })();
225
- }, [needsData, variants, url, code, setCode, loadSource, loadVariantMeta, loadCodeMeta, sourceEnhancers, processedGlobalsCode, globalsCode, setProcessedGlobalsCode, loadCodeVariant]);
234
+ }, [needsData, variants, url, code, setCode, loadSource, loadVariantMeta, loadCodeMeta, sourceEnhancers, processedGlobalsCode, globalsCode, setProcessedGlobalsCode, loadIsomorphicCodeVariant]);
226
235
  return {
227
236
  readyForContent
228
237
  };
@@ -246,6 +255,7 @@ function useCodeParsing({
246
255
  url
247
256
  }) {
248
257
  const {
258
+ sourceParser,
249
259
  parseSource,
250
260
  parseCode
251
261
  } = useCodeContext();
@@ -285,6 +295,12 @@ function useCodeParsing({
285
295
  return undefined;
286
296
  }
287
297
  if (!parseSource) {
298
+ // A CodeProvider is present and its async `sourceParser` promise hasn't
299
+ // resolved yet — wait for it instead of erroring. The memo will re-run
300
+ // once `parseSource` is populated.
301
+ if (sourceParser) {
302
+ return undefined;
303
+ }
288
304
  if (forceClient) {
289
305
  console.error(new Errors.ErrorCodeHighlighterClientMissingParseSource(url, true));
290
306
  } else {
@@ -301,7 +317,7 @@ function useCodeParsing({
301
317
  return undefined;
302
318
  }
303
319
  return parseCode(code, parseSource);
304
- }, [code, shouldHighlight, parseSource, parseCode, forceClient, url]);
320
+ }, [code, shouldHighlight, sourceParser, parseSource, parseCode, forceClient, url]);
305
321
  const deferHighlight = !shouldHighlight;
306
322
  return {
307
323
  parsedCode,
@@ -404,7 +420,7 @@ function useGlobalsCodeMerging({
404
420
  loadCodeMeta,
405
421
  loadSource,
406
422
  loadVariantMeta,
407
- loadCodeVariant
423
+ loadIsomorphicCodeVariant
408
424
  } = useCodeContext();
409
425
 
410
426
  // Set processedGlobalsCode if we have ready Code objects but haven't stored them yet
@@ -424,7 +440,7 @@ function useGlobalsCodeMerging({
424
440
  }
425
441
  // If not all ready, fall through to loading logic below
426
442
  }
427
- if (!loadCodeVariant) {
443
+ if (!loadIsomorphicCodeVariant) {
428
444
  console.error(new Errors.ErrorCodeHighlighterClientMissingLoadVariantForGlobals());
429
445
  return;
430
446
  }
@@ -470,7 +486,7 @@ function useGlobalsCodeMerging({
470
486
 
471
487
  // Need to load this variant
472
488
  try {
473
- const result = await loadCodeVariant(originalUrl || '',
489
+ const result = await loadIsomorphicCodeVariant(originalUrl || '',
474
490
  // Use the original URL if available
475
491
  variantName, codeObj[variantName],
476
492
  // May be undefined or string
@@ -493,7 +509,7 @@ function useGlobalsCodeMerging({
493
509
  console.error(new Errors.ErrorCodeHighlighterClientLoadGlobalsCodeFailure(url || 'No URL', error));
494
510
  }
495
511
  })();
496
- }, [url, globalsCode, processedGlobalsCode, setProcessedGlobalsCode, loadCodeMeta, loadSource, loadVariantMeta, variants, loadCodeVariant]);
512
+ }, [url, globalsCode, processedGlobalsCode, setProcessedGlobalsCode, loadCodeMeta, loadSource, loadVariantMeta, variants, loadIsomorphicCodeVariant]);
497
513
 
498
514
  // Determine globalsCodeObjects to use (prefer processed, fallback to direct if ready)
499
515
  const globalsCodeObjects = React.useMemo(() => {
@@ -675,7 +691,9 @@ export function CodeHighlighterClient(props) {
675
691
  fallbackUsesExtraFiles,
676
692
  fallbackUsesAllVariants
677
693
  } = props;
678
- useInitialData({
694
+ const {
695
+ fallbackPending
696
+ } = useInitialData({
679
697
  variants,
680
698
  variantName,
681
699
  code,
@@ -748,7 +766,8 @@ export function CodeHighlighterClient(props) {
748
766
  setCode,
749
767
  processedGlobalsCode,
750
768
  globalsCode: props.globalsCode,
751
- setProcessedGlobalsCode
769
+ setProcessedGlobalsCode,
770
+ fallbackPending
752
771
  });
753
772
 
754
773
  // Merge globalsCode with internal state code (fetched data) - this should be stable once ready
@@ -156,7 +156,7 @@ export class ErrorCodeHighlighterClientMissingLoadFallbackCode extends ErrorCode
156
156
  }
157
157
  export class ErrorCodeHighlighterClientMissingLoadVariant extends ErrorCodeHighlighterClientProvider {
158
158
  constructor(url) {
159
- super(`Missing loadCodeVariant function - loadCodeVariant function is required when no initial code is provided (${url || 'No URL'})`);
159
+ super(`Missing loadIsomorphicCodeVariant function - loadIsomorphicCodeVariant function is required when no initial code is provided (${url || 'No URL'})`);
160
160
  }
161
161
  }
162
162
  export class ErrorCodeHighlighterClientMissingLoadCodeMeta extends ErrorCodeHighlighterClientProvider {
@@ -273,7 +273,7 @@ export class ErrorCodeHighlighterClientTransformProcessingFailure extends ErrorC
273
273
  }
274
274
  export class ErrorCodeHighlighterClientMissingLoadVariantForGlobals extends ErrorCodeHighlighterClientProvider {
275
275
  constructor() {
276
- super(`loadCodeVariant function is required for loading missing variants in globalsCode`);
276
+ super(`loadIsomorphicCodeVariant function is required for loading missing variants in globalsCode`);
277
277
  }
278
278
  }
279
279
  export class ErrorCodeHighlighterClientLoadVariantFailureForGlobals extends ErrorCodeHighlighterClientLoader {
@@ -52,6 +52,17 @@ export type VariantExtraFiles = {
52
52
  metadata?: boolean;
53
53
  /** File system path for this file */
54
54
  path?: string;
55
+ /**
56
+ * Path of this file relative to the variant's `url`. Set when the
57
+ * `extraFiles` key was rewritten (e.g., flattened) and no longer
58
+ * resolves to the file's URL on its own. Consumers derive the file
59
+ * URL via `new URL(relativeUrl, variant.url)`. When omitted, the
60
+ * `extraFiles` key itself resolves to the file URL against
61
+ * `variant.url`.
62
+ *
63
+ * Always normalized to start with `./` or `../`.
64
+ */
65
+ relativeUrl?: string;
55
66
  /** Comments extracted from source, stored when parsing is disabled for later use */
56
67
  comments?: SourceComments;
57
68
  };
@@ -212,9 +223,20 @@ export interface LoadFileOptions {
212
223
  * @default 'hast'
213
224
  */
214
225
  output?: 'hast' | 'hastJson' | 'hastCompressed';
226
+ /**
227
+ * Optional URL-prefix rewrite applied to the loaded variant's `url` and any
228
+ * string-form `extraFiles` entries. Useful for translating local `file://`
229
+ * URLs (e.g. those returned by `loadServerCodeSource`) into hosted URLs (e.g.
230
+ * `https://github.com/owner/repo/tree/<branch>/`) before they reach the
231
+ * client.
232
+ */
233
+ urlPrefix?: {
234
+ from: string;
235
+ to: string;
236
+ };
215
237
  }
216
238
  /**
217
- * Options for the loadCodeVariant function, extending LoadFileOptions with required function dependencies
239
+ * Options for the loadIsomorphicCodeVariant function, extending LoadFileOptions with required function dependencies
218
240
  */
219
241
  export interface LoadVariantOptions extends LoadFileOptions, Pick<CodeFunctionProps, 'sourceParser' | 'loadSource' | 'loadVariantMeta' | 'sourceTransformers' | 'sourceEnhancers'> {}
220
242
  /**
@@ -312,6 +334,15 @@ export interface CodeFunctionProps {
312
334
  sourceParser?: Promise<ParseSource>;
313
335
  /** Array of source enhancers that run after parsing to enhance the HAST tree */
314
336
  sourceEnhancers?: SourceEnhancers;
337
+ /**
338
+ * Optional URL-prefix rewrite forwarded to {@link LoadFileOptions.urlPrefix}.
339
+ * Lets the demo factory translate local `file://` URLs returned by
340
+ * `loadSource` into hosted URLs before they reach the client.
341
+ */
342
+ urlPrefix?: {
343
+ from: string;
344
+ to: string;
345
+ };
315
346
  }
316
347
  /**
317
348
  * Component and rendering props
@@ -43,7 +43,7 @@ export interface CodeContext {
43
43
  /** Heavy function: Loads fallback code with all variants and files */
44
44
  loadCodeFallback?: LoadFallbackCodeFn;
45
45
  /** Heavy function: Loads a specific code variant with its dependencies */
46
- loadCodeVariant?: LoadVariantFn;
46
+ loadIsomorphicCodeVariant?: LoadVariantFn;
47
47
  /** Heavy function: Parses code strings into HAST nodes */
48
48
  parseCode?: ParseCodeFn;
49
49
  /** Heavy function: Parses controlled code for editable demos */
@@ -5,11 +5,11 @@ import { CodeContext } from "./CodeContext.mjs";
5
5
  import { enhanceCodeEmphasis } from "../pipeline/enhanceCodeEmphasis/index.mjs";
6
6
  import { createParseSource } from "../pipeline/parseSource/parseSource.mjs";
7
7
  // Import the heavy functions
8
- import { loadCodeFallback } from "../pipeline/loadCodeVariant/loadCodeFallback.mjs";
9
- import { loadCodeVariant } from "../pipeline/loadCodeVariant/loadCodeVariant.mjs";
10
- import { parseCode } from "../pipeline/loadCodeVariant/parseCode.mjs";
8
+ import { loadCodeFallback } from "../pipeline/loadIsomorphicCodeVariant/loadCodeFallback.mjs";
9
+ import { loadIsomorphicCodeVariant } from "../pipeline/loadIsomorphicCodeVariant/loadIsomorphicCodeVariant.mjs";
10
+ import { parseCode } from "../pipeline/loadIsomorphicCodeVariant/parseCode.mjs";
11
11
  import { parseControlledCode } from "../CodeHighlighter/parseControlledCode.mjs";
12
- import { computeHastDeltas, getAvailableTransforms } from "../pipeline/loadCodeVariant/computeHastDeltas.mjs";
12
+ import { computeHastDeltas, getAvailableTransforms } from "../pipeline/loadIsomorphicCodeVariant/computeHastDeltas.mjs";
13
13
  import { jsx as _jsx } from "react/jsx-runtime";
14
14
  const DEFAULT_SOURCE_ENHANCERS = [enhanceCodeEmphasis];
15
15
 
@@ -116,7 +116,7 @@ export function CodeProvider({
116
116
  sourceEnhancers,
117
117
  // Provide the heavy functions
118
118
  loadCodeFallback,
119
- loadCodeVariant,
119
+ loadIsomorphicCodeVariant,
120
120
  parseCode,
121
121
  parseControlledCode,
122
122
  computeHastDeltas,
@@ -33,6 +33,24 @@ type AbstractCreateDemoOptions<T extends {}> = {
33
33
  loadSource?: LoadSource;
34
34
  sourceParser?: Promise<ParseSource>;
35
35
  sourceEnhancers?: SourceEnhancers;
36
+ /**
37
+ * Absolute filesystem path of the project root used to resolve `url`s
38
+ * gathered from `import.meta.url`. Combined with `projectUrl` to rewrite
39
+ * local `file://` URLs into hosted Git URLs (e.g.
40
+ * `https://github.com/owner/repo/tree/<branch>/`) before they reach the
41
+ * `CodeHighlighter`.
42
+ *
43
+ * Typically read from an environment variable populated by the build
44
+ * pipeline (e.g. Netlify's `REPOSITORY_URL`/`BRANCH` plus
45
+ * `git rev-parse --show-toplevel`). When either `projectPath` or
46
+ * `projectUrl` is missing, URLs are left untouched.
47
+ */
48
+ projectPath?: string;
49
+ /**
50
+ * Public URL prefix that maps to `projectPath`. See `projectPath` for
51
+ * details.
52
+ */
53
+ projectUrl?: string;
36
54
  };
37
55
  export declare function abstractCreateDemo<T extends {}>(options: AbstractCreateDemoOptions<T>, url: string, variants: {
38
56
  [key: string]: React.ComponentType;
@@ -1,5 +1,7 @@
1
1
  import * as React from 'react';
2
+ import { pathToFileURL } from 'node:url';
2
3
  import { CodeHighlighter } from "../CodeHighlighter/index.mjs";
4
+ import { applyUrlPrefixToCode, applyUrlPrefixToGlobalsCode, replaceUrlPrefix } from "../pipeline/loaderUtils/applyUrlPrefix.mjs";
3
5
  import { createDemoDataWithVariants } from "../createDemoData/index.mjs";
4
6
  import { jsx as _jsx } from "react/jsx-runtime";
5
7
  export function abstractCreateDemo(options, url, variants, meta) {
@@ -11,18 +13,35 @@ export function abstractCreateDemo(options, url, variants, meta) {
11
13
  globalCode.push(data.precompute || data.url);
12
14
  });
13
15
  }
16
+
17
+ // Apply urlPrefix once at factory build time so the rewritten values are
18
+ // captured by the closures below (and shared across renders) instead of
19
+ // being recomputed on every render inside `DemoComponent`.
20
+ //
21
+ // The top-level `url` is only rewritten when the variant is fully loaded
22
+ // (i.e. a `precompute` is present). Without a precompute, this `url` is
23
+ // forwarded to `loadSource` at runtime, which expects the original
24
+ // `file://` URL it can read from disk — rewriting here would turn it into
25
+ // a hosted `https://` URL and cause `loadSource` to fail. In that case
26
+ // the `urlPrefix` prop on `<CodeHighlighter>` (forwarded into
27
+ // `loadIsomorphicCodeVariant`) takes care of rewriting the loaded variant after the
28
+ // file is read.
29
+ const urlPrefix = resolveUrlPrefix(options.projectPath, options.projectUrl);
30
+ const resolvedUrl = urlPrefix && demoData.precompute ? replaceUrlPrefix(demoData.url, urlPrefix) ?? demoData.url : demoData.url;
31
+ const resolvedPrecompute = urlPrefix && demoData.precompute ? applyUrlPrefixToCode(demoData.precompute, urlPrefix) : demoData.precompute;
32
+ const resolvedGlobalCode = urlPrefix && globalCode.length > 0 ? applyUrlPrefixToGlobalsCode(globalCode, urlPrefix) : globalCode;
14
33
  function DemoComponent(props) {
15
34
  const renderedComponents = Object.entries(demoData.components).reduce((acc, [key, Component]) => {
16
35
  acc[key] = /*#__PURE__*/React.createElement(Component);
17
36
  return acc;
18
37
  }, {});
19
38
  const highlighter = /*#__PURE__*/_jsx(CodeHighlighter, {
20
- url: demoData.url,
39
+ url: resolvedUrl,
21
40
  name: demoData.name,
22
41
  slug: demoData.slug,
23
42
  variantType: meta?.variantType || variantType,
24
- precompute: demoData.precompute,
25
- globalsCode: globalCode,
43
+ precompute: resolvedPrecompute,
44
+ globalsCode: resolvedGlobalCode,
26
45
  components: renderedComponents,
27
46
  contentProps: props,
28
47
  Content: options.DemoContent,
@@ -32,6 +51,7 @@ export function abstractCreateDemo(options, url, variants, meta) {
32
51
  loadSource: options.loadSource,
33
52
  sourceParser: options.sourceParser,
34
53
  sourceEnhancers: options.sourceEnhancers,
54
+ urlPrefix: urlPrefix,
35
55
  highlightAfter: meta?.highlightAfter || options.highlightAfter,
36
56
  enhanceAfter: meta?.enhanceAfter || options.enhanceAfter,
37
57
  controlled: options.controlled,
@@ -67,6 +87,17 @@ export function abstractCreateDemo(options, url, variants, meta) {
67
87
  }
68
88
  return DemoComponent;
69
89
  }
90
+ function resolveUrlPrefix(projectPath, projectUrl) {
91
+ if (!projectPath || !projectUrl) {
92
+ return undefined;
93
+ }
94
+ const from = `${pathToFileURL(projectPath).href}/`;
95
+ const to = projectUrl.endsWith('/') ? projectUrl : `${projectUrl}/`;
96
+ return {
97
+ from,
98
+ to
99
+ };
100
+ }
70
101
  export function createDemoFactory(options) {
71
102
  /**
72
103
  * Creates a demo component for displaying code examples with syntax highlighting.
@@ -1,7 +1,7 @@
1
1
  import { readFile, writeFile, readdir, access } from 'node:fs/promises';
2
2
  import path from 'node:path';
3
- import { parseCreateFactoryCall } from "../pipeline/loadPrecomputedCodeHighlighter/parseCreateFactoryCall.mjs";
4
- import { serializeFunctionArguments } from "../pipeline/loadPrecomputedCodeHighlighter/serializeFunctionArguments.mjs";
3
+ import { parseCreateFactoryCall } from "../pipeline/parseCreateFactoryCall/parseCreateFactoryCall.mjs";
4
+ import { serializeFunctionArguments } from "../pipeline/parseCreateFactoryCall/serializeFunctionArguments.mjs";
5
5
  const CLIENT_FILE_NAME = 'client.ts';
6
6
  const INDEX_FILE_NAME = 'index.ts';
7
7
  const CLIENT_PROVIDER_IDENTIFIER = 'ClientProvider';
@@ -6,7 +6,7 @@ import { unified } from 'unified';
6
6
  import remarkParse from 'remark-parse';
7
7
  import remarkMdx from 'remark-mdx';
8
8
  import { transformMarkdownMetadata } from "../pipeline/transformMarkdownMetadata/transformMarkdownMetadata.mjs";
9
- import { parseCreateFactoryCall } from "../pipeline/loadPrecomputedCodeHighlighter/parseCreateFactoryCall.mjs";
9
+ import { parseCreateFactoryCall } from "../pipeline/parseCreateFactoryCall/parseCreateFactoryCall.mjs";
10
10
  import { syncTypes } from "../pipeline/syncTypes/syncTypes.mjs";
11
11
  function collectPerfEntries() {
12
12
  const entries = performance.getEntriesByType('measure').map(entry => ({