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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (221) hide show
  1. package/ChunkProvider/PreloadProvider.mjs +1 -2
  2. package/ChunkProvider/usePreload.d.mts +1 -1
  3. package/ChunkProvider/usePreload.mjs +0 -1
  4. package/CodeControllerContext/CodeControllerContext.d.mts +45 -10
  5. package/CodeControllerContext/CodeControllerContext.mjs +15 -1
  6. package/CodeHighlighter/CodeHighlighterClient.d.mts +3 -2
  7. package/CodeHighlighter/CodeHighlighterClient.mjs +113 -18
  8. package/CodeHighlighter/CodeHighlighterContext.d.mts +9 -3
  9. package/CodeHighlighter/buildStringFallback.d.mts +1 -1
  10. package/CodeHighlighter/codeToFallbackProps.d.mts +1 -1
  11. package/CodeHighlighter/createClientProps.mjs +3 -0
  12. package/CodeHighlighter/fallbackCompression.d.mts +1 -1
  13. package/CodeHighlighter/parseControlledCode.d.mts +13 -4
  14. package/CodeHighlighter/parseControlledCode.mjs +41 -49
  15. package/CodeHighlighter/types.d.mts +21 -0
  16. package/CodeHighlighter/useGrammarsReady.mjs +44 -9
  17. package/CodeProvider/CodeProvider.d.mts +1 -1
  18. package/CodeProvider/CodeProviderLazy.d.mts +1 -1
  19. package/CodeProvider/createParseSourceWorkerClient.d.mts +6 -0
  20. package/CodeProvider/createParseSourceWorkerClient.mjs +83 -15
  21. package/CodeProvider/useCodeProviderValue.mjs +50 -4
  22. package/abstractCreateDemo/abstractCreateDemo.d.mts +15 -1
  23. package/abstractCreateDemo/abstractCreateDemo.mjs +8 -0
  24. package/abstractCreateDemoClient/abstractCreateDemoClient.mjs +4 -0
  25. package/abstractCreateTypes/abstractCreateTypes.d.mts +12 -1
  26. package/abstractCreateTypes/abstractCreateTypes.mjs +4 -0
  27. package/abstractCreateTypes/typesToJsx.d.mts +8 -0
  28. package/abstractCreateTypes/typesToJsx.mjs +2 -1
  29. package/cli/loadNextConfig.d.mts +9 -0
  30. package/cli/loadNextConfig.mjs +11 -2
  31. package/cli/runValidate.mjs +15 -7
  32. package/cli/validateWorker.d.mts +1 -0
  33. package/cli/validateWorker.mjs +2 -1
  34. package/createDemoData/createDemoData.d.mts +1 -1
  35. package/package.json +34 -5
  36. package/pipeline/cacheUtils/constants.d.mts +5 -0
  37. package/pipeline/cacheUtils/constants.mjs +5 -0
  38. package/pipeline/cacheUtils/hashCacheContent.d.mts +5 -0
  39. package/pipeline/cacheUtils/hashCacheContent.mjs +9 -0
  40. package/pipeline/cacheUtils/index.d.mts +9 -0
  41. package/pipeline/cacheUtils/index.mjs +7 -0
  42. package/pipeline/cacheUtils/loadFileCache.d.mts +13 -0
  43. package/pipeline/cacheUtils/loadFileCache.mjs +20 -0
  44. package/pipeline/cacheUtils/loadFileCacheEntry.d.mts +13 -0
  45. package/pipeline/cacheUtils/loadFileCacheEntry.mjs +47 -0
  46. package/pipeline/cacheUtils/resolveCachePath.d.mts +16 -0
  47. package/pipeline/cacheUtils/resolveCachePath.mjs +24 -0
  48. package/pipeline/cacheUtils/saveFileCache.d.mts +17 -0
  49. package/pipeline/cacheUtils/saveFileCache.mjs +54 -0
  50. package/pipeline/cacheUtils/types.d.mts +23 -0
  51. package/pipeline/cacheUtils/types.mjs +1 -0
  52. package/pipeline/cacheUtils/withFileCache.d.mts +40 -0
  53. package/pipeline/cacheUtils/withFileCache.mjs +81 -0
  54. package/pipeline/hastUtils/hastUtils.d.mts +1 -1
  55. package/pipeline/hastUtils/hastUtils.mjs +0 -1
  56. package/pipeline/loadIsomorphicCodeSource/loadIsomorphicCodeSource.d.mts +1 -1
  57. package/pipeline/loadIsomorphicCodeSource/loadIsomorphicCodeSource.mjs +1 -1
  58. package/pipeline/loadIsomorphicCodeVariant/applyCodeTransform.mjs +0 -1
  59. package/pipeline/loadIsomorphicCodeVariant/diffHast.d.mts +1 -1
  60. package/pipeline/loadIsomorphicCodeVariant/hasAllCodeVariants.d.mts +1 -1
  61. package/pipeline/loadIsomorphicCodeVariant/maybeCodeInitialData.d.mts +1 -1
  62. package/pipeline/loadPrecomputedSitemap/loadPrecomputedSitemap.d.mts +6 -0
  63. package/pipeline/loadPrecomputedSitemap/loadPrecomputedSitemap.mjs +2 -1
  64. package/pipeline/loadPrecomputedTypes/loadPrecomputedTypes.d.mts +6 -0
  65. package/pipeline/loadPrecomputedTypes/loadPrecomputedTypes.mjs +5 -1
  66. package/pipeline/loadServerCodeMeta/resolveModulePathWithFs.d.mts +1 -1
  67. package/pipeline/loadServerCodeMeta/resolveModulePathWithFs.mjs +0 -1
  68. package/pipeline/loadServerPageIndex/enrichPageIndex.d.mts +15 -0
  69. package/pipeline/loadServerPageIndex/enrichPageIndex.mjs +50 -0
  70. package/pipeline/loadServerPageIndex/extractPrefixAndTitle.d.mts +19 -0
  71. package/pipeline/loadServerPageIndex/extractPrefixAndTitle.mjs +80 -0
  72. package/pipeline/loadServerPageIndex/index.d.mts +5 -2
  73. package/pipeline/loadServerPageIndex/index.mjs +4 -1
  74. package/pipeline/loadServerPageIndex/loadServerPageIndex.d.mts +13 -22
  75. package/pipeline/loadServerPageIndex/loadServerPageIndex.mjs +32 -124
  76. package/pipeline/loadServerPageIndex/resolvePageIndexCacheKey.d.mts +13 -0
  77. package/pipeline/loadServerPageIndex/resolvePageIndexCacheKey.mjs +23 -0
  78. package/pipeline/loadServerTypes/highlightTypes.d.mts +3 -3
  79. package/pipeline/loadServerTypes/highlightTypesMeta.d.mts +4 -4
  80. package/pipeline/loadServerTypes/loadServerTypes.d.mts +2 -2
  81. package/pipeline/loadServerTypes/loadServerTypes.mjs +67 -7
  82. package/pipeline/loadServerTypesMeta/createOptimizedProgram.d.mts +2 -1
  83. package/pipeline/loadServerTypesMeta/formatClass.d.mts +2 -2
  84. package/pipeline/loadServerTypesMeta/formatComponent.d.mts +2 -2
  85. package/pipeline/loadServerTypesMeta/formatFunction.d.mts +2 -2
  86. package/pipeline/loadServerTypesMeta/formatHook.d.mts +2 -2
  87. package/pipeline/loadServerTypesMeta/formatRaw.d.mts +2 -2
  88. package/pipeline/loadServerTypesMeta/formatType.d.mts +1 -1
  89. package/pipeline/loadServerTypesMeta/loadServerTypesMeta.d.mts +7 -7
  90. package/pipeline/loadServerTypesMeta/loadServerTypesMeta.mjs +1 -1
  91. package/pipeline/loadServerTypesMeta/processTypes.d.mts +2 -2
  92. package/pipeline/loadServerTypesMeta/worker.d.mts +1 -1
  93. package/pipeline/loadServerTypesText/loadServerTypesText.d.mts +16 -2
  94. package/pipeline/loadServerTypesText/loadServerTypesText.mjs +30 -8
  95. package/pipeline/loadServerTypesText/normalizeTypesSourceDataForCache.d.mts +2 -0
  96. package/pipeline/loadServerTypesText/normalizeTypesSourceDataForCache.mjs +144 -0
  97. package/pipeline/loadServerTypesText/resolveTypesCacheKey.d.mts +19 -0
  98. package/pipeline/loadServerTypesText/resolveTypesCacheKey.mjs +29 -0
  99. package/pipeline/loaderUtils/parseImportsAndComments.d.mts +5 -3
  100. package/pipeline/loaderUtils/parseImportsAndComments.mjs +284 -40
  101. package/pipeline/parseCreateFactoryCall/parseCreateFactoryCall.d.mts +2 -2
  102. package/pipeline/parseCreateFactoryCall/parseCreateFactoryCall.mjs +2 -3
  103. package/pipeline/parseSource/detectFileTypes.d.mts +16 -0
  104. package/pipeline/parseSource/detectFileTypes.mjs +44 -0
  105. package/pipeline/syncPageIndex/mergeMetadataMarkdown.d.mts +25 -1
  106. package/pipeline/syncPageIndex/mergeMetadataMarkdown.mjs +79 -49
  107. package/pipeline/syncPageIndex/metadataToMarkdown.d.mts +15 -1
  108. package/pipeline/syncPageIndex/metadataToMarkdown.mjs +32 -10
  109. package/pipeline/syncPageIndex/syncPageIndex.d.mts +12 -0
  110. package/pipeline/syncPageIndex/syncPageIndex.mjs +154 -40
  111. package/pipeline/syncTypes/generateTypesMarkdown.d.mts +2 -2
  112. package/pipeline/syncTypes/syncTypes.d.mts +7 -0
  113. package/pipeline/syncTypes/syncTypes.mjs +31 -1
  114. package/pipeline/transformHtmlCodeBlock/transformHtmlCodeBlock.mjs +1 -1
  115. package/pipeline/transformMarkdownCode/transformMarkdownCode.mjs +25 -15
  116. package/pipeline/transformMarkdownMetadata/transformMarkdownMetadata.mjs +3 -0
  117. package/pipeline/transformMarkdownMetadata/types.d.mts +8 -1
  118. package/useCode/EditableEngine.d.mts +1 -1
  119. package/useCode/Pre.d.mts +9 -2
  120. package/useCode/Pre.mjs +4 -3
  121. package/useCode/TransformEngine.d.mts +1 -1
  122. package/useCode/useCode.d.mts +17 -1
  123. package/useCode/useCode.mjs +22 -1
  124. package/useCode/useCopyFunctionality.d.mts +2 -2
  125. package/useCode/useEditable.browser.mjs +0 -1
  126. package/useCode/useFileNavigation.d.mts +3 -0
  127. package/useCode/useFileNavigation.mjs +3 -1
  128. package/useCode/useSourceEditing.mjs +45 -10
  129. package/useCode/useSourceEnhancing.mjs +41 -9
  130. package/useCode/useTransformManagement.d.mts +2 -2
  131. package/useCode/useTransformManagement.mjs +19 -3
  132. package/useCode/useUIState.d.mts +4 -0
  133. package/useCode/useUIState.mjs +8 -1
  134. package/useCode/useVariantSelection.d.mts +1 -1
  135. package/useCoordinated/useCoordinated.d.mts +1 -1
  136. package/useCoordinated/useCoordinatedLocalStorage.d.mts +1 -1
  137. package/useCoordinated/useCoordinatedLocalStorage.mjs +0 -1
  138. package/useCoordinated/useCoordinatedPreference.d.mts +1 -1
  139. package/useCoordinated/useCoordinatedPreference.mjs +0 -1
  140. package/useCrossTabState/index.d.mts +2 -0
  141. package/useCrossTabState/index.mjs +2 -0
  142. package/useCrossTabState/useCrossTabMirror.d.mts +26 -0
  143. package/useCrossTabState/useCrossTabMirror.mjs +108 -0
  144. package/useCrossTabState/useCrossTabState.d.mts +21 -0
  145. package/useCrossTabState/useCrossTabState.mjs +31 -0
  146. package/useDemo/exportVariant.mjs +2 -4
  147. package/useDemo/exportVariantAsCra.d.mts +1 -1
  148. package/useDemo/exportVariantAsCra.mjs +0 -1
  149. package/useDemo/useDemo.d.mts +4 -1
  150. package/useDemo/useDemo.mjs +5 -0
  151. package/useDemoController/BuildEngine.d.mts +2 -0
  152. package/useDemoController/BuildEngine.mjs +10 -0
  153. package/useDemoController/DemoRunner.d.mts +34 -0
  154. package/useDemoController/DemoRunner.mjs +83 -0
  155. package/useDemoController/ErrorBoundary.d.mts +34 -0
  156. package/useDemoController/ErrorBoundary.mjs +49 -0
  157. package/useDemoController/Runner.d.mts +44 -0
  158. package/useDemoController/Runner.mjs +71 -0
  159. package/useDemoController/absolutizeImports.d.mts +13 -0
  160. package/useDemoController/absolutizeImports.mjs +73 -0
  161. package/useDemoController/buildScope.d.mts +48 -0
  162. package/useDemoController/buildScope.mjs +270 -0
  163. package/useDemoController/collectSources.d.mts +67 -0
  164. package/useDemoController/collectSources.mjs +92 -0
  165. package/useDemoController/compileCssModule.d.mts +64 -0
  166. package/useDemoController/compileCssModule.mjs +40 -0
  167. package/useDemoController/compileCssWithPostcss.d.mts +17 -0
  168. package/useDemoController/compileCssWithPostcss.mjs +89 -0
  169. package/useDemoController/compileModule.d.mts +14 -0
  170. package/useDemoController/compileModule.mjs +17 -0
  171. package/useDemoController/constants.d.mts +13 -0
  172. package/useDemoController/constants.mjs +13 -0
  173. package/useDemoController/createRequire.d.mts +10 -0
  174. package/useDemoController/createRequire.mjs +17 -0
  175. package/useDemoController/createTranspileWorkerClient.d.mts +27 -0
  176. package/useDemoController/createTranspileWorkerClient.mjs +139 -0
  177. package/useDemoController/cssModules.d.mts +47 -0
  178. package/useDemoController/currentBrowserTarget.d.mts +16 -0
  179. package/useDemoController/currentBrowserTarget.mjs +36 -0
  180. package/useDemoController/evalCode.d.mts +12 -0
  181. package/useDemoController/evalCode.mjs +35 -0
  182. package/useDemoController/generateCssModuleSource.d.mts +11 -0
  183. package/useDemoController/generateCssModuleSource.mjs +55 -0
  184. package/useDemoController/generateElement.d.mts +21 -0
  185. package/useDemoController/generateElement.mjs +26 -0
  186. package/useDemoController/hashString.d.mts +11 -0
  187. package/useDemoController/hashString.mjs +20 -0
  188. package/useDemoController/importCode.d.mts +11 -0
  189. package/useDemoController/importCode.mjs +15 -0
  190. package/useDemoController/index.d.mts +1 -0
  191. package/useDemoController/index.mjs +1 -0
  192. package/useDemoController/instantiateElement.d.mts +24 -0
  193. package/useDemoController/instantiateElement.mjs +57 -0
  194. package/useDemoController/instantiateModule.d.mts +17 -0
  195. package/useDemoController/instantiateModule.mjs +24 -0
  196. package/useDemoController/resolveCssImports.d.mts +27 -0
  197. package/useDemoController/resolveCssImports.mjs +79 -0
  198. package/useDemoController/transformCode.d.mts +14 -0
  199. package/useDemoController/transformCode.mjs +42 -0
  200. package/useDemoController/transpileClientSingleton.d.mts +10 -0
  201. package/useDemoController/transpileClientSingleton.mjs +83 -0
  202. package/useDemoController/transpileSource.d.mts +29 -0
  203. package/useDemoController/transpileSource.mjs +36 -0
  204. package/useDemoController/transpileWorker.d.mts +14 -0
  205. package/useDemoController/transpileWorker.mjs +41 -0
  206. package/useDemoController/types.d.mts +30 -0
  207. package/useDemoController/types.mjs +1 -0
  208. package/useDemoController/useDemoController.d.mts +54 -0
  209. package/useDemoController/useDemoController.mjs +186 -0
  210. package/useDemoController/useRunner.d.mts +53 -0
  211. package/useDemoController/useRunner.mjs +118 -0
  212. package/useDemoController/useVariantBuilds.d.mts +31 -0
  213. package/useDemoController/useVariantBuilds.mjs +188 -0
  214. package/useSearch/types.d.mts +1 -1
  215. package/useType/TypesDataProvider.d.mts +1 -1
  216. package/useType/TypesDataProvider.mjs +1 -2
  217. package/useType/useType.d.mts +1 -1
  218. package/useType/useTypeProp.d.mts +1 -1
  219. package/withDocsInfra/withDeploymentConfig.mjs +57 -0
  220. package/withDocsInfra/withDocsInfra.d.mts +14 -0
  221. package/withDocsInfra/withDocsInfra.mjs +25 -11
@@ -3,6 +3,12 @@
3
3
  import * as React from 'react';
4
4
  import { areGrammarsRegistered, ensureGrammars } from "../pipeline/parseSource/grammarCache.mjs";
5
5
 
6
+ // Safety-net deadline (ms) for the grammar load. A load that HANGS (a stalled dynamic
7
+ // import that never settles) — rather than rejecting — would otherwise leave `ready`
8
+ // false forever, wedging the block un-highlighted until a reload. After the deadline we
9
+ // fail open (plain text) just like a hard rejection.
10
+ const GRAMMAR_LOAD_TIMEOUT_MS = 10_000;
11
+
6
12
  /**
7
13
  * Gates client-side highlighting on grammar readiness. Under `CodeProviderLazy`,
8
14
  * grammars load per-language and on demand, so a block must wait until the
@@ -22,24 +28,53 @@ import { areGrammarsRegistered, ensureGrammars } from "../pipeline/parseSource/g
22
28
  */
23
29
  export function useGrammarsReady(scopes, enabled) {
24
30
  const [, forceUpdate] = React.useReducer(count => count + 1, 0);
31
+ // The scopes whose grammar load has definitively FAILED (a hard chunk-fetch error,
32
+ // not a partial register). Tracked so the block can fail OPEN — render plain text for
33
+ // those scopes — instead of wedging on `ready === false` forever (which would leave
34
+ // the code permanently un-highlighted until a reload). Stored as a CONTENT key (the
35
+ // joined scopes), not a reference, so it stays matched if the caller passes a fresh
36
+ // array — and a different set of scopes (a new language) still retries.
37
+ const [failedScopesKey, setFailedScopesKey] = React.useState(null);
25
38
 
26
- // Nothing to wait for when disabled or when every scope is already registered.
27
- const ready = !enabled || areGrammarsRegistered(scopes);
39
+ // Nothing to wait for when disabled or when every scope is already registered. The
40
+ // content key (joined scopes) drives both the fail-open match AND the effect dep, so
41
+ // the load runs once per scope-CONTENT set — not on every render when a caller passes
42
+ // a fresh `scopes` array (which would otherwise re-trigger `ensureGrammars`/timeouts).
43
+ const registered = areGrammarsRegistered(scopes);
44
+ const scopesKey = scopes.join('\n');
45
+ const ready = !enabled || registered || failedScopesKey === scopesKey;
28
46
  React.useEffect(() => {
29
- if (ready) {
47
+ if (!enabled || registered) {
30
48
  return undefined;
31
49
  }
32
50
  let cancelled = false;
33
- // Fails open: a load error still flips ready so the block highlights what it
34
- // can (and renders plain text for any scope that failed to register).
35
- ensureGrammars(scopes).finally(() => {
51
+ // Fail open on a hard rejection (catch) OR a hang (the timer): a grammar load that
52
+ // never settles would otherwise leave `ready` false forever the same wedge.
53
+ const failOpen = () => {
36
54
  if (!cancelled) {
37
- forceUpdate();
55
+ setFailedScopesKey(scopesKey);
56
+ }
57
+ };
58
+ const timer = setTimeout(failOpen, GRAMMAR_LOAD_TIMEOUT_MS);
59
+ (async () => {
60
+ try {
61
+ // Reconstruct from the content key so this effect depends only on the joined
62
+ // content (`scopesKey`), never the array reference.
63
+ await ensureGrammars(scopesKey.split('\n'));
64
+ // Registered now — re-render so `ready` recomputes to true.
65
+ if (!cancelled) {
66
+ forceUpdate();
67
+ }
68
+ } catch {
69
+ failOpen();
70
+ } finally {
71
+ clearTimeout(timer);
38
72
  }
39
- });
73
+ })();
40
74
  return () => {
41
75
  cancelled = true;
76
+ clearTimeout(timer);
42
77
  };
43
- }, [ready, scopes]);
78
+ }, [enabled, registered, scopesKey]);
44
79
  return ready;
45
80
  }
@@ -26,4 +26,4 @@ export declare function CodeProvider({
26
26
  /** Function to load raw source code and dependencies */
27
27
  loadSource?: LoadSource;
28
28
  sourceEnhancers?: SourceEnhancers;
29
- }): import("react/jsx-runtime").JSX.Element;
29
+ }): React.JSX.Element;
@@ -36,5 +36,5 @@ interface CodeProviderLazyProps {
36
36
  export declare function CodeProviderLazy({
37
37
  children,
38
38
  ...rest
39
- }: CodeProviderLazyProps): import("react/jsx-runtime").JSX.Element;
39
+ }: CodeProviderLazyProps): React.JSX.Element;
40
40
  export {};
@@ -42,6 +42,12 @@ export interface ParseSourceWorkerClient {
42
42
  *
43
43
  * Each client owns exactly one underlying `Worker`. Concurrent in-flight
44
44
  * requests are demuxed by a monotonically increasing `id`.
45
+ *
46
+ * If the worker dies unexpectedly (a load/parse failure, or a message that fails
47
+ * to deserialize), every in-flight parse request and pending `init`/`register`
48
+ * handshake is rejected and the client latches `dead`, so a crash surfaces as a
49
+ * rejected promise (which the consumer already handles like an abort, falling back
50
+ * to the synchronous highlighter) rather than a request that hangs forever.
45
51
  */
46
52
  export declare function createParseSourceWorkerClient(): ParseSourceWorkerClient;
47
53
  export {};
@@ -16,6 +16,12 @@
16
16
  *
17
17
  * Each client owns exactly one underlying `Worker`. Concurrent in-flight
18
18
  * requests are demuxed by a monotonically increasing `id`.
19
+ *
20
+ * If the worker dies unexpectedly (a load/parse failure, or a message that fails
21
+ * to deserialize), every in-flight parse request and pending `init`/`register`
22
+ * handshake is rejected and the client latches `dead`, so a crash surfaces as a
23
+ * rejected promise (which the consumer already handles like an abort, falling back
24
+ * to the synchronous highlighter) rather than a request that hangs forever.
19
25
  */
20
26
  export function createParseSourceWorkerClient() {
21
27
  // Module workers are required (the worker uses `import` statements). On
@@ -36,6 +42,45 @@ export function createParseSourceWorkerClient() {
36
42
  const pending = new Map();
37
43
  let nextId = 1;
38
44
  let initPromise = null;
45
+ // Latched once the worker dies or is terminated, so later calls reject immediately
46
+ // rather than hanging on a worker that will never respond.
47
+ let dead = false;
48
+ // Reject callbacks for in-flight `init()`/`register()` handshakes, so a worker
49
+ // crash can fail them too (they listen on their own one-shot listeners, not
50
+ // `pending`). Each clears itself on settle.
51
+ const handshakeRejecters = new Set();
52
+
53
+ // Reject + forget every in-flight parse request with `reason`, detaching abort
54
+ // listeners first. Shared by `terminate()` (intentional) and the fatal-error path.
55
+ const rejectAllPending = reason => {
56
+ for (const entry of pending.values()) {
57
+ if (entry.signal && entry.onAbort) {
58
+ entry.signal.removeEventListener('abort', entry.onAbort);
59
+ }
60
+ entry.reject(reason);
61
+ }
62
+ pending.clear();
63
+ };
64
+
65
+ // The worker died unexpectedly — a load/parse failure, or a message that could not
66
+ // be deserialized. (A parse that merely fails is reported as an `ok: false`
67
+ // response, so it never reaches here.) Reject everything in flight — parse requests
68
+ // AND pending `init`/`register` handshakes — and latch `dead`; the consumer treats
69
+ // the rejection like an abort and falls back to the synchronous highlighter.
70
+ // Idempotent. (Unlike a crash, a deliberate `terminate()` leaves handshakes alone:
71
+ // the component is unmounting, so a still-pending `init` is simply abandoned.)
72
+ const handleFatal = error => {
73
+ if (dead) {
74
+ return;
75
+ }
76
+ dead = true;
77
+ worker.terminate();
78
+ rejectAllPending(error);
79
+ for (const reject of [...handshakeRejecters]) {
80
+ reject(error);
81
+ }
82
+ handshakeRejecters.clear();
83
+ };
39
84
  worker.addEventListener('message', event => {
40
85
  const data = event.data;
41
86
  if (data.type === 'init-ack' || data.type === 'init-error' || data.type === 'register-ack' || data.type === 'register-error') {
@@ -60,20 +105,34 @@ export function createParseSourceWorkerClient() {
60
105
  }
61
106
  }
62
107
  });
108
+ worker.addEventListener('error', event => {
109
+ handleFatal(new Error(event.message || 'Parse worker errored'));
110
+ });
111
+ worker.addEventListener('messageerror', () => {
112
+ handleFatal(new Error('Parse worker received an undeserializable message'));
113
+ });
63
114
  function init(grammars) {
64
115
  if (initPromise) {
65
116
  return initPromise;
66
117
  }
118
+ if (dead) {
119
+ return Promise.reject(new Error('Parse worker is no longer available'));
120
+ }
67
121
  initPromise = new Promise((resolve, reject) => {
68
- const onMessage = event => {
122
+ const settle = () => {
123
+ handshakeRejecters.delete(reject);
124
+ worker.removeEventListener('message', onMessage);
125
+ };
126
+ function onMessage(event) {
69
127
  if (event.data.type === 'init-ack') {
70
- worker.removeEventListener('message', onMessage);
128
+ settle();
71
129
  resolve();
72
130
  } else if (event.data.type === 'init-error') {
73
- worker.removeEventListener('message', onMessage);
131
+ settle();
74
132
  reject(new Error(event.data.error));
75
133
  }
76
- };
134
+ }
135
+ handshakeRejecters.add(reject);
77
136
  worker.addEventListener('message', onMessage);
78
137
  worker.postMessage({
79
138
  type: 'init',
@@ -83,16 +142,24 @@ export function createParseSourceWorkerClient() {
83
142
  return initPromise;
84
143
  }
85
144
  function register(grammars) {
145
+ if (dead) {
146
+ return Promise.reject(new Error('Parse worker is no longer available'));
147
+ }
86
148
  return new Promise((resolve, reject) => {
87
- const onMessage = event => {
149
+ const settle = () => {
150
+ handshakeRejecters.delete(reject);
151
+ worker.removeEventListener('message', onMessage);
152
+ };
153
+ function onMessage(event) {
88
154
  if (event.data.type === 'register-ack') {
89
- worker.removeEventListener('message', onMessage);
155
+ settle();
90
156
  resolve();
91
157
  } else if (event.data.type === 'register-error') {
92
- worker.removeEventListener('message', onMessage);
158
+ settle();
93
159
  reject(new Error(event.data.error));
94
160
  }
95
- };
161
+ }
162
+ handshakeRejecters.add(reject);
96
163
  worker.addEventListener('message', onMessage);
97
164
  worker.postMessage({
98
165
  type: 'register',
@@ -104,10 +171,16 @@ export function createParseSourceWorkerClient() {
104
171
  if (!initPromise) {
105
172
  throw new Error('parseSourceAsync called before init(). Call client.init(grammars) first.');
106
173
  }
174
+ if (dead) {
175
+ throw new Error('Parse worker is no longer available');
176
+ }
107
177
  if (signal?.aborted) {
108
178
  throw signal.reason;
109
179
  }
110
180
  await initPromise;
181
+ if (dead) {
182
+ throw new Error('Parse worker is no longer available');
183
+ }
111
184
  if (signal?.aborted) {
112
185
  throw signal.reason;
113
186
  }
@@ -146,14 +219,9 @@ export function createParseSourceWorkerClient() {
146
219
  });
147
220
  };
148
221
  function terminate() {
222
+ dead = true;
149
223
  worker.terminate();
150
- for (const entry of pending.values()) {
151
- if (entry.signal && entry.onAbort) {
152
- entry.signal.removeEventListener('abort', entry.onAbort);
153
- }
154
- entry.reject(new Error('Worker terminated'));
155
- }
156
- pending.clear();
224
+ rejectAllPending(new Error('Worker terminated'));
157
225
  }
158
226
  return {
159
227
  init,
@@ -17,6 +17,15 @@ import { parseControlledCode } from "../CodeHighlighter/parseControlledCode.mjs"
17
17
  * the heavy modules out of the lazy provider's chunk.
18
18
  */
19
19
 
20
+ // The source parser (Starry Night's regex engine + grammar chunks) is created from a
21
+ // dynamically-imported, memoized promise. A transient load failure (a CDN/network
22
+ // blip) would otherwise reject that promise ONCE and never retry — leaving
23
+ // `parseSource` undefined forever, which strands every client-highlighted block as
24
+ // plain text until a FULL PAGE RELOAD. Retry a bounded number of times, with a short
25
+ // backoff, so a transient blip self-heals without a reload.
26
+ const MAX_PARSER_ATTEMPTS = 3;
27
+ const PARSER_RETRY_DELAY_MS = 500;
28
+
20
29
  /**
21
30
  * Builds the {@link CodeContext} value shared by `CodeProvider` and
22
31
  * `CodeProviderLazy`: the (browser-only, lazily-initialized) source parser, the
@@ -36,6 +45,9 @@ export function useCodeProviderValue(props, heavy,
36
45
  createSourceParser) {
37
46
  const [parseSource, setParseSource] = React.useState(undefined);
38
47
  const [parseSourceAsync, setParseSourceAsync] = React.useState(undefined);
48
+ // Bumped to re-create the (memoized) source parser after a failed load, so a
49
+ // transient failure can recover instead of wedging highlighting (see below).
50
+ const [parserAttempt, setParserAttempt] = React.useState(0);
39
51
  const sourceParser = React.useMemo(() => {
40
52
  // Only initialize Starry Night in the browser, not during SSR
41
53
  if (typeof window === 'undefined') {
@@ -43,12 +55,46 @@ createSourceParser) {
43
55
  throw new Error('parseSource not available during SSR');
44
56
  });
45
57
  }
58
+
59
+ // `parserAttempt` is a dep so a retry creates a FRESH parser promise (the previous
60
+ // one stays rejected); see the effect below. The value isn't read in the body — it's
61
+ // a deliberate cache-bust — so exhaustive-deps flags it as "unnecessary".
46
62
  return createSourceParser();
47
- }, [createSourceParser]);
63
+ // eslint-disable-next-line react-hooks/exhaustive-deps -- parserAttempt is a deliberate retry cache-bust
64
+ }, [createSourceParser, parserAttempt]);
48
65
  React.useEffect(() => {
49
- // Update the sync version when available
50
- sourceParser.then(parseSourceFn => setParseSource(() => parseSourceFn));
51
- }, [sourceParser]);
66
+ // Resolve the parser and publish the sync version. On failure, retry with backoff
67
+ // rather than leaving the rejection unhandled and `parseSource` undefined forever
68
+ // (which strands every client-highlighted block as plain text until a reload).
69
+ let cancelled = false;
70
+ let retryTimer;
71
+ (async () => {
72
+ try {
73
+ const parseSourceFn = await sourceParser;
74
+ if (!cancelled) {
75
+ setParseSource(() => parseSourceFn);
76
+ }
77
+ } catch (error) {
78
+ if (cancelled) {
79
+ return;
80
+ }
81
+ console.error('Failed to initialize the source parser.', error);
82
+ if (parserAttempt < MAX_PARSER_ATTEMPTS) {
83
+ retryTimer = setTimeout(() => {
84
+ if (!cancelled) {
85
+ setParserAttempt(attempt => attempt + 1);
86
+ }
87
+ }, PARSER_RETRY_DELAY_MS * (parserAttempt + 1));
88
+ }
89
+ }
90
+ })();
91
+ return () => {
92
+ cancelled = true;
93
+ if (retryTimer !== undefined) {
94
+ clearTimeout(retryTimer);
95
+ }
96
+ };
97
+ }, [sourceParser, parserAttempt]);
52
98
 
53
99
  // Worker for off-main-thread parsing during live editing. Created LAZILY on the
54
100
  // first editable block (via `ensureParseSourceWorker`), not on mount, and
@@ -1,6 +1,6 @@
1
1
  import * as React from 'react';
2
2
  import type { Code, CodeHighlighterProps, ContentLoadingProps, ContentProps, LoadCodeMeta, LoadSource, LoadVariantMeta, ParseSource, SourceEnhancers } from "../CodeHighlighter/types.mjs";
3
- import { type DemoGlobalData } from "../createDemoData/types.mjs";
3
+ import type { DemoGlobalData } from "../createDemoData/types.mjs";
4
4
  type CreateDemoMeta = {
5
5
  name?: string;
6
6
  slug?: string;
@@ -36,6 +36,14 @@ type CreateDemoMeta = {
36
36
  * collapsed instead. Mirrors the demo component's `initialCollapsed` prop.
37
37
  */
38
38
  initialCollapsed?: boolean;
39
+ /**
40
+ * Start this demo's editable code read-only (a truthy value), leaving it to a
41
+ * `setEditable` toggle to turn editing on. Overrides a factory `initialDisabled`
42
+ * default (set in the `createDemoFactory` call). Distinct from `editActivation` (which
43
+ * only defers *when* the engine loads) and from the hard `disabled` opt (which forbids
44
+ * editing entirely).
45
+ */
46
+ initialDisabled?: boolean;
39
47
  };
40
48
  type AbstractCreateDemoOptions<T extends {}> = {
41
49
  DemoContent: React.ComponentType<ContentProps<T>>;
@@ -69,6 +77,12 @@ type AbstractCreateDemoOptions<T extends {}> = {
69
77
  * override with `meta.initialExpanded: false` or `<Demo initialExpanded={false} />`.
70
78
  */
71
79
  initialExpanded?: boolean;
80
+ /**
81
+ * Default every demo from this factory to start its editable code read-only — a
82
+ * reader toggles it on per demo with `setEditable`. Individual demos override with
83
+ * `meta.initialDisabled: false` or `<Demo initialDisabled={false} />`.
84
+ */
85
+ initialDisabled?: boolean;
72
86
  /**
73
87
  * `file://` URL of the project root used to resolve `url`s gathered from
74
88
  * `import.meta.url`. Combined with `projectUrl` to rewrite local `file://`
@@ -50,6 +50,7 @@ export function abstractCreateDemo(options, url, variants, meta) {
50
50
  showCollapsedFocus: instanceShowCollapsedFocus,
51
51
  initialExpanded: instanceInitialExpanded,
52
52
  initialCollapsed: instanceInitialCollapsed,
53
+ initialDisabled: instanceInitialDisabled,
53
54
  ...restProps
54
55
  } = props;
55
56
  const collapseToEmpty = resolveDemoFlag([{
@@ -66,6 +67,12 @@ export function abstractCreateDemo(options, url, variants, meta) {
66
67
  on: meta?.initialExpanded,
67
68
  off: meta?.initialCollapsed
68
69
  }], options.initialExpanded);
70
+ // Single flag (no off-cascade): instance prop → demo `meta` → factory default.
71
+ const initialDisabled = resolveDemoFlag([{
72
+ on: instanceInitialDisabled
73
+ }, {
74
+ on: meta?.initialDisabled
75
+ }], options.initialDisabled);
69
76
  const highlighter = /*#__PURE__*/_jsx(CodeHighlighter, {
70
77
  url: resolvedUrl,
71
78
  name: demoData.name,
@@ -77,6 +84,7 @@ export function abstractCreateDemo(options, url, variants, meta) {
77
84
  contentProps: restProps,
78
85
  collapseToEmpty: collapseToEmpty,
79
86
  initialExpanded: initialExpanded,
87
+ initialDisabled: initialDisabled,
80
88
  Content: options.DemoContent,
81
89
  ContentLoading: options.DemoContentLoading,
82
90
  loadCodeMeta: options.loadCodeMeta,
@@ -38,10 +38,13 @@ export function abstractCreateDemoClient(options, url, meta) {
38
38
  function ClientProvider({
39
39
  children
40
40
  }) {
41
+ // Pass the demo's own `url` so a controller can use it as a stable per-demo key
42
+ // (e.g. for cross-tab sync); the demo url wins over any `controllerProps.url`.
41
43
  if (controllerProps != null) {
42
44
  return /*#__PURE__*/_jsx(CodeExternalsContext.Provider, {
43
45
  value: context,
44
46
  children: /*#__PURE__*/React.createElement(DemoController, Object.assign({}, controllerProps, {
47
+ url,
45
48
  children
46
49
  }))
47
50
  });
@@ -49,6 +52,7 @@ export function abstractCreateDemoClient(options, url, meta) {
49
52
  return /*#__PURE__*/_jsx(CodeExternalsContext.Provider, {
50
53
  value: context,
51
54
  children: /*#__PURE__*/React.createElement(DemoController, Object.assign({}, {
55
+ url,
52
56
  children
53
57
  }))
54
58
  });
@@ -2,7 +2,7 @@ import * as React from 'react';
2
2
  import type { PluggableList } from 'unified';
3
3
  import type { HighlightedTypesMeta } from '@mui/internal-docs-infra/pipeline/loadServerTypes';
4
4
  import type { ModuleLinkMapEntry } from "../pipeline/enhanceCodeTypes/scanState.mjs";
5
- import { type TypesJsxOptions } from "./typesToJsx.mjs";
5
+ import type { TypesJsxOptions } from "./typesToJsx.mjs";
6
6
  import type { TypesTableProps } from "../useTypes/useTypes.mjs";
7
7
  /**
8
8
  * Export data structure containing a main type and its related additional types.
@@ -63,6 +63,11 @@ export type TypesTableMeta = {
63
63
  * When set, overrides the factory-level TypePre.
64
64
  */
65
65
  TypePre?: TypesJsxOptions['TypePre'];
66
+ /**
67
+ * Override pre component for shortType code blocks.
68
+ * When set, overrides the factory-level ShortTypePre.
69
+ */
70
+ ShortTypePre?: TypesJsxOptions['ShortTypePre'];
66
71
  /**
67
72
  * Override pre component for detailed type blocks.
68
73
  * When set, overrides the factory-level DetailedTypePre.
@@ -166,6 +171,12 @@ export type AbstractCreateTypesOptions<T extends {} = {}> = {
166
171
  * Can be overridden by TypesTableMeta.TypePre.
167
172
  */
168
173
  TypePre: TypesJsxOptions['TypePre'];
174
+ /**
175
+ * Optional pre component for shortType code blocks.
176
+ * Falls back to `TypePre` when not provided.
177
+ * Can be overridden by TypesTableMeta.ShortTypePre.
178
+ */
179
+ ShortTypePre?: TypesJsxOptions['ShortTypePre'];
169
180
  /**
170
181
  * Optional pre component for detailed type blocks.
171
182
  * Falls back to `TypePre` when not provided.
@@ -38,6 +38,7 @@ export function abstractCreateTypes(options, url, meta, exportName) {
38
38
 
39
39
  // Resolve named component slots (meta overrides options)
40
40
  const TypePre = meta.TypePre ?? options.TypePre;
41
+ const ShortTypePre = meta.ShortTypePre ?? options.ShortTypePre;
41
42
  const DetailedTypePre = meta.DetailedTypePre ?? options.DetailedTypePre;
42
43
  const ShortTypeCode = meta.ShortTypeCode ?? options.ShortTypeCode;
43
44
  const DefaultCode = meta.DefaultCode ?? options.DefaultCode;
@@ -122,6 +123,7 @@ export function abstractCreateTypes(options, url, meta, exportName) {
122
123
  } = React.useMemo(() => typeToJsx(precompute.exports[targetExportName], filteredAdditionalTypes, {
123
124
  components,
124
125
  TypePre,
126
+ ShortTypePre,
125
127
  DetailedTypePre,
126
128
  ShortTypeCode,
127
129
  DefaultCode,
@@ -211,6 +213,7 @@ function createAdditionalTypesComponent(options, url, meta) {
211
213
 
212
214
  // Resolve named component slots (meta overrides options)
213
215
  const TypePre = meta.TypePre ?? options.TypePre;
216
+ const ShortTypePre = meta.ShortTypePre ?? options.ShortTypePre;
214
217
  const DetailedTypePre = meta.DetailedTypePre ?? options.DetailedTypePre;
215
218
  const ShortTypeCode = meta.ShortTypeCode ?? options.ShortTypeCode;
216
219
  const DefaultCode = meta.DefaultCode ?? options.DefaultCode;
@@ -271,6 +274,7 @@ function createAdditionalTypesComponent(options, url, meta) {
271
274
  const additionalTypes = React.useMemo(() => additionalTypesToJsx(allAdditionalTypes, {
272
275
  components,
273
276
  TypePre,
277
+ ShortTypePre,
274
278
  DetailedTypePre,
275
279
  ShortTypeCode,
276
280
  DefaultCode,
@@ -24,6 +24,14 @@ export type TypesJsxOptions = {
24
24
  DetailedTypePre?: React.ComponentType<{
25
25
  children: React.ReactNode;
26
26
  }>;
27
+ /**
28
+ * Optional pre component for shortType code blocks.
29
+ * Rendered inside phrasing content (e.g. a table trigger), so it should emit
30
+ * inline markup. Falls back to `TypePre` when not provided.
31
+ */
32
+ ShortTypePre?: React.ComponentType<{
33
+ children: React.ReactNode;
34
+ }>;
27
35
  /**
28
36
  * Optional code component for shortType fields.
29
37
  * Falls back to `components.code` when not provided.
@@ -109,6 +109,7 @@ function resolveFieldMaps(options) {
109
109
  type: typeMap,
110
110
  shortType: options.ShortTypeCode ? {
111
111
  ...typeMap,
112
+ pre: options.ShortTypePre ?? options.TypePre,
112
113
  code: options.ShortTypeCode
113
114
  } : typeMap,
114
115
  default: options.DefaultCode ? {
@@ -878,7 +879,7 @@ function enhanceClassType(classData, components, fieldMaps, enhancers, enhancers
878
879
  ...method,
879
880
  description: method.description && hastToJsx(method.description, components, enhancers),
880
881
  parameters: enhancedMethodParams,
881
- returnValue: hastToJsx(method.returnValue, fieldMaps.type, enhancers),
882
+ returnValue: hastToJsx(method.returnValue, fieldMaps.shortType, enhancersInline),
882
883
  returnValueDescription: method.returnValueDescription && hastToJsx(method.returnValueDescription, components, enhancers)
883
884
  };
884
885
  return [methodName, enhancedMethod];
@@ -23,11 +23,20 @@ export type ExtractedNextConfigOptions = {
23
23
  descriptionReplacements?: DescriptionReplacement[];
24
24
  useVisibleDescription?: boolean;
25
25
  socketDir?: string;
26
+ /** Page-index cache directory configured on the sitemap loader. */
27
+ cacheDir?: string;
26
28
  /** Demo index patterns that opted into automatic `client.ts` generation. */
27
29
  demoClientRequirements?: DemoClientRequirement[];
28
30
  /** Demo index patterns that opted into automatic `page.tsx` generation. */
29
31
  demoPageRequirements?: DemoPageRequirement[];
30
32
  };
33
+ /**
34
+ * Searches turbopack rules for docs-infra options (ordering,
35
+ * descriptionReplacements, socketDir, useVisibleDescription, cacheDir).
36
+ *
37
+ * Exported for tests.
38
+ */
39
+ export declare function extractOptionsFromTurbopack(config: any): ExtractedNextConfigOptions;
31
40
  /**
32
41
  * Walks Turbopack rules to collect demo patterns that opted into automatic
33
42
  * `page.tsx` generation via the `requirePage` option.
@@ -3,6 +3,7 @@ import path from 'node:path';
3
3
  import { pathToFileURL } from 'node:url';
4
4
  import { createJiti } from 'jiti';
5
5
  const TYPES_LOADER = '@mui/internal-docs-infra/pipeline/loadPrecomputedTypes';
6
+ const SITEMAP_LOADER = '@mui/internal-docs-infra/pipeline/loadPrecomputedSitemap';
6
7
  const CODE_HIGHLIGHTER_LOADER = '@mui/internal-docs-infra/pipeline/loadPrecomputedCodeHighlighter';
7
8
  const TRANSFORM_METADATA_PLUGIN = '@mui/internal-docs-infra/pipeline/transformMarkdownMetadata';
8
9
  const TRANSFORM_METADATA_PLUGIN_FUNCTION_NAME = 'transformMarkdownMetadata';
@@ -49,6 +50,9 @@ function extractOptionsFromLoaderEntries(loaders) {
49
50
  if (!result.socketDir && loader.loader === TYPES_LOADER && typeof loader.options?.socketDir === 'string') {
50
51
  result.socketDir = loader.options.socketDir;
51
52
  }
53
+ if (!result.cacheDir && loader.loader === SITEMAP_LOADER && typeof loader.options?.cacheDir === 'string') {
54
+ result.cacheDir = loader.options.cacheDir;
55
+ }
52
56
  if (result.useVisibleDescription === undefined && loader.options?.remarkPlugins) {
53
57
  const extracted = extractUseVisibleDescriptionFromRemarkPlugins(loader.options.remarkPlugins);
54
58
  if (typeof extracted === 'boolean') {
@@ -61,9 +65,11 @@ function extractOptionsFromLoaderEntries(loaders) {
61
65
 
62
66
  /**
63
67
  * Searches turbopack rules for docs-infra options (ordering,
64
- * descriptionReplacements, socketDir, useVisibleDescription).
68
+ * descriptionReplacements, socketDir, useVisibleDescription, cacheDir).
69
+ *
70
+ * Exported for tests.
65
71
  */
66
- function extractOptionsFromTurbopack(config) {
72
+ export function extractOptionsFromTurbopack(config) {
67
73
  const rules = config?.turbopack?.rules;
68
74
  if (!rules) {
69
75
  return {};
@@ -79,6 +85,7 @@ function extractOptionsFromTurbopack(config) {
79
85
  merged.descriptionReplacements ??= extracted.descriptionReplacements;
80
86
  merged.useVisibleDescription ??= extracted.useVisibleDescription;
81
87
  merged.socketDir ??= extracted.socketDir;
88
+ merged.cacheDir ??= extracted.cacheDir;
82
89
  }
83
90
  return merged;
84
91
  }
@@ -166,6 +173,7 @@ function extractOptionsFromWebpackResult(result) {
166
173
  merged.descriptionReplacements ??= extracted.descriptionReplacements;
167
174
  merged.useVisibleDescription ??= extracted.useVisibleDescription;
168
175
  merged.socketDir ??= extracted.socketDir;
176
+ merged.cacheDir ??= extracted.cacheDir;
169
177
  }
170
178
  return merged;
171
179
  }
@@ -323,6 +331,7 @@ export async function extractDocsInfraOptionsFromNextConfig(dir) {
323
331
  descriptionReplacements: turbopack.descriptionReplacements ?? webpack.descriptionReplacements,
324
332
  useVisibleDescription: turbopack.useVisibleDescription ?? webpack.useVisibleDescription,
325
333
  socketDir: turbopack.socketDir ?? webpack.socketDir,
334
+ cacheDir: turbopack.cacheDir ?? webpack.cacheDir,
326
335
  demoClientRequirements: demoClientRequirements.length > 0 ? demoClientRequirements : undefined,
327
336
  demoPageRequirements: demoPageRequirements.length > 0 ? demoPageRequirements : undefined
328
337
  };