@stream-mdx/react 0.1.0 → 0.2.0

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 (47) hide show
  1. package/CHANGELOG.md +9 -0
  2. package/README.md +4 -0
  3. package/dist/components/index.cjs +497 -163
  4. package/dist/components/index.d.cts +1 -1
  5. package/dist/components/index.d.ts +1 -1
  6. package/dist/components/index.mjs +496 -163
  7. package/dist/{index-Bt1opGCs.d.cts → index-D0akq48G.d.cts} +24 -2
  8. package/dist/{index-Bt1opGCs.d.ts → index-D0akq48G.d.ts} +24 -2
  9. package/dist/index.cjs +3797 -2048
  10. package/dist/index.d.cts +43 -5
  11. package/dist/index.d.ts +43 -5
  12. package/dist/index.mjs +3741 -1990
  13. package/dist/mdx-client.cjs +60 -18
  14. package/dist/mdx-client.d.cts +11 -0
  15. package/dist/mdx-client.d.ts +11 -0
  16. package/dist/mdx-client.mjs +60 -18
  17. package/dist/mdx-coordinator.cjs +60 -18
  18. package/dist/mdx-coordinator.mjs +60 -18
  19. package/dist/renderer/node-views.cjs +481 -130
  20. package/dist/renderer/node-views.d.cts +1 -1
  21. package/dist/renderer/node-views.d.ts +1 -1
  22. package/dist/renderer/node-views.mjs +424 -65
  23. package/dist/renderer/patch-commit-scheduler.cjs +68 -7
  24. package/dist/renderer/patch-commit-scheduler.d.cts +6 -5
  25. package/dist/renderer/patch-commit-scheduler.d.ts +6 -5
  26. package/dist/renderer/patch-commit-scheduler.mjs +68 -7
  27. package/dist/renderer/store.cjs +481 -56
  28. package/dist/renderer/store.d.cts +2 -1
  29. package/dist/renderer/store.d.ts +2 -1
  30. package/dist/renderer/store.mjs +479 -47
  31. package/dist/renderer/virtualized-code.cjs +8 -2
  32. package/dist/renderer/virtualized-code.d.cts +4 -0
  33. package/dist/renderer/virtualized-code.d.ts +4 -0
  34. package/dist/renderer/virtualized-code.mjs +8 -2
  35. package/dist/renderer.cjs +3188 -2172
  36. package/dist/renderer.d.cts +4 -2
  37. package/dist/renderer.d.ts +4 -2
  38. package/dist/renderer.mjs +3009 -1985
  39. package/dist/streaming-markdown-Ch6PwjAa.d.cts +154 -0
  40. package/dist/streaming-markdown-tca-Mf8D.d.ts +154 -0
  41. package/dist/streaming-markdown.cjs +3929 -2202
  42. package/dist/streaming-markdown.d.cts +6 -95
  43. package/dist/streaming-markdown.d.ts +6 -95
  44. package/dist/streaming-markdown.mjs +3943 -2208
  45. package/dist/utils/inline-html.d.cts +1 -1
  46. package/dist/utils/inline-html.d.ts +1 -1
  47. package/package.json +3 -3
@@ -70,6 +70,8 @@ var init_mdx_client = __esm({
70
70
  constructor(compileEndpoint = "/api/mdx-compile-v2") {
71
71
  this.cache = /* @__PURE__ */ new Map();
72
72
  this.inlineModules = /* @__PURE__ */ new Map();
73
+ this.compiledCache = /* @__PURE__ */ new Map();
74
+ this.compiledInflight = /* @__PURE__ */ new Map();
73
75
  this.compileEndpoint = compileEndpoint;
74
76
  }
75
77
  /**
@@ -94,34 +96,53 @@ var init_mdx_client = __esm({
94
96
  throw error;
95
97
  }
96
98
  }
97
- /**
98
- * Get compiled MDX by reference
99
- */
100
- async getCompiled(ref) {
99
+ async getCompiledInternal(ref) {
101
100
  const inline = this.inlineModules.get(ref.id);
102
101
  if (inline) {
103
- return {
104
- ...inline,
105
- dependencies: Array.isArray(inline.dependencies) ? [...inline.dependencies] : []
106
- };
102
+ return this.cloneCompiled(inline);
107
103
  }
108
- const response = await fetch(`${this.compileEndpoint}?id=${ref.id}`);
109
- if (!response.ok) {
110
- throw new Error(`Failed to get compiled MDX: ${response.statusText}`);
104
+ const cached = this.compiledCache.get(ref.id);
105
+ if (cached) {
106
+ return this.cloneCompiled(cached);
111
107
  }
112
- const data = await response.json();
113
- return {
114
- id: data.id,
115
- code: data.code,
116
- dependencies: data.dependencies || [],
117
- timestamp: data.timestamp
118
- };
108
+ const inflight = this.compiledInflight.get(ref.id);
109
+ if (inflight) {
110
+ const resolved = await inflight;
111
+ return this.cloneCompiled(resolved);
112
+ }
113
+ const fetchPromise = this.fetchCompiled(ref);
114
+ this.compiledInflight.set(ref.id, fetchPromise);
115
+ try {
116
+ const data = await fetchPromise;
117
+ this.compiledCache.set(ref.id, data);
118
+ return this.cloneCompiled(data);
119
+ } finally {
120
+ this.compiledInflight.delete(ref.id);
121
+ }
122
+ }
123
+ async getCompiled(ref, options) {
124
+ if (options?.signal) {
125
+ const inline = this.inlineModules.get(ref.id);
126
+ if (inline) {
127
+ return this.cloneCompiled(inline);
128
+ }
129
+ const cached = this.compiledCache.get(ref.id);
130
+ if (cached) {
131
+ return this.cloneCompiled(cached);
132
+ }
133
+ const data = await this.fetchCompiled(ref, options);
134
+ this.compiledCache.set(ref.id, data);
135
+ return this.cloneCompiled(data);
136
+ }
137
+ return this.getCompiledInternal(ref);
119
138
  }
120
139
  /**
121
140
  * Clear compilation cache
122
141
  */
123
142
  clearCache() {
124
143
  this.cache.clear();
144
+ this.compiledCache.clear();
145
+ this.compiledInflight.clear();
125
146
  }
126
147
  registerInlineModule(compiled) {
127
148
  this.inlineModules.set(compiled.id, {
@@ -158,6 +179,27 @@ var init_mdx_client = __esm({
158
179
  cached: data.cached || false
159
180
  };
160
181
  }
182
+ async fetchCompiled(ref, options) {
183
+ const response = await fetch(`${this.compileEndpoint}?id=${ref.id}`, {
184
+ signal: options?.signal
185
+ });
186
+ if (!response.ok) {
187
+ throw new Error(`Failed to get compiled MDX: ${response.statusText}`);
188
+ }
189
+ const data = await response.json();
190
+ return {
191
+ id: data.id,
192
+ code: data.code,
193
+ dependencies: data.dependencies || [],
194
+ timestamp: data.timestamp
195
+ };
196
+ }
197
+ cloneCompiled(compiled) {
198
+ return {
199
+ ...compiled,
200
+ dependencies: Array.isArray(compiled.dependencies) ? [...compiled.dependencies] : []
201
+ };
202
+ }
161
203
  };
162
204
  MDXComponentFactory = class {
163
205
  constructor(mdxClient) {
@@ -344,11 +386,118 @@ var init_mdx_client = __esm({
344
386
 
345
387
  // src/components/index.ts
346
388
  import { createTrustedHTML, sanitizeHTML } from "@stream-mdx/core";
389
+
390
+ // src/mdx-hydration-metrics.ts
391
+ var entries = /* @__PURE__ */ new Map();
392
+ var lastHydrationMs = null;
393
+ function now() {
394
+ if (typeof performance !== "undefined" && typeof performance.now === "function") {
395
+ return performance.now();
396
+ }
397
+ return Date.now();
398
+ }
399
+ function markMdxHydrationStart(id) {
400
+ if (!id) return;
401
+ const entry = entries.get(id) ?? { status: "compiled" };
402
+ if (entry.startedAt === void 0) {
403
+ entry.startedAt = now();
404
+ }
405
+ entry.status = "compiled";
406
+ entries.set(id, entry);
407
+ }
408
+ function markMdxHydrated(id) {
409
+ if (!id) return;
410
+ const entry = entries.get(id) ?? { status: "hydrated" };
411
+ if (entry.startedAt === void 0) {
412
+ entry.startedAt = now();
413
+ }
414
+ entry.hydratedAt = now();
415
+ entry.status = "hydrated";
416
+ entries.set(id, entry);
417
+ lastHydrationMs = entry.startedAt ? entry.hydratedAt - entry.startedAt : null;
418
+ }
419
+ function markMdxHydrationError(id) {
420
+ if (!id) return;
421
+ const entry = entries.get(id) ?? { status: "error" };
422
+ entry.status = "error";
423
+ entries.set(id, entry);
424
+ }
425
+
426
+ // src/mdx-hydration-context.ts
427
+ import React from "react";
428
+ var MdxHydrationContext = React.createContext({ controller: null });
429
+
430
+ // src/mdx-runtime.ts
431
+ var mdxRuntimePromise = null;
432
+ function loadMdxRuntime() {
433
+ if (!mdxRuntimePromise) {
434
+ mdxRuntimePromise = Promise.resolve().then(() => (init_mdx_client(), mdx_client_exports));
435
+ }
436
+ return mdxRuntimePromise;
437
+ }
438
+
439
+ // src/renderer/use-deferred-render.ts
440
+ import { useEffect, useState } from "react";
441
+ function useDeferredRender(ref, options) {
442
+ const enabled = options?.enabled ?? true;
443
+ const [shouldRender, setShouldRender] = useState(!enabled);
444
+ useEffect(() => {
445
+ if (!enabled) {
446
+ setShouldRender(true);
447
+ return;
448
+ }
449
+ const target = ref.current;
450
+ if (!target) {
451
+ return;
452
+ }
453
+ let cancelled = false;
454
+ let idleId = null;
455
+ let timerId = null;
456
+ const scheduleRender = () => {
457
+ if (cancelled) return;
458
+ setShouldRender(true);
459
+ };
460
+ const runWithIdle = () => {
461
+ if (typeof globalThis.requestIdleCallback === "function") {
462
+ idleId = globalThis.requestIdleCallback(scheduleRender, { timeout: options?.idleTimeoutMs ?? 200 });
463
+ } else {
464
+ timerId = window.setTimeout(scheduleRender, options?.idleTimeoutMs ?? 200);
465
+ }
466
+ };
467
+ const observer = new IntersectionObserver(
468
+ (entries2) => {
469
+ for (const entry of entries2) {
470
+ if (entry.isIntersecting || entry.intersectionRatio > 0) {
471
+ observer.disconnect();
472
+ const debounceMs = options?.debounceMs ?? 80;
473
+ timerId = window.setTimeout(runWithIdle, debounceMs);
474
+ return;
475
+ }
476
+ }
477
+ },
478
+ { rootMargin: options?.rootMargin ?? "200px 0px" }
479
+ );
480
+ observer.observe(target);
481
+ return () => {
482
+ cancelled = true;
483
+ observer.disconnect();
484
+ if (idleId !== null && typeof globalThis.cancelIdleCallback === "function") {
485
+ globalThis.cancelIdleCallback(idleId);
486
+ }
487
+ if (timerId !== null) {
488
+ window.clearTimeout(timerId);
489
+ }
490
+ };
491
+ }, [enabled, options?.debounceMs, options?.idleTimeoutMs, options?.rootMargin, ref]);
492
+ return shouldRender;
493
+ }
494
+
495
+ // src/components/index.ts
347
496
  import { removeHeadingMarkers } from "@stream-mdx/core";
348
- import React3 from "react";
497
+ import React4 from "react";
349
498
 
350
499
  // src/utils/inline-html.ts
351
- import React from "react";
500
+ import React3 from "react";
352
501
  var BACKTICK_CONTENT = /^`([\s\S]+)`$/;
353
502
  var DEFAULT_INLINE_HTML_RENDERERS = {
354
503
  kbd: (descriptor, ctx) => {
@@ -360,7 +509,7 @@ var DEFAULT_INLINE_HTML_RENDERERS = {
360
509
  if (ctx.key !== void 0 && ctx.key !== null) {
361
510
  props.key = ctx.key;
362
511
  }
363
- return React.createElement("kbd", props, React.createElement("code", { className: "inline-code" }, codeText));
512
+ return React3.createElement("kbd", props, React3.createElement("code", { className: "inline-code" }, codeText));
364
513
  }
365
514
  return ctx.defaultRender();
366
515
  }
@@ -378,9 +527,9 @@ function renderInlineHtmlSegment(raw, sanitized, options = {}) {
378
527
  return null;
379
528
  }
380
529
  if (options.key !== void 0 && options.key !== null) {
381
- return React.createElement(React.Fragment, { key: options.key }, descriptor.text);
530
+ return React3.createElement(React3.Fragment, { key: options.key }, descriptor.text);
382
531
  }
383
- return React.createElement(React.Fragment, {}, descriptor.text);
532
+ return React3.createElement(React3.Fragment, {}, descriptor.text);
384
533
  }
385
534
  if (isInlineTag) {
386
535
  const parsedElement = renderSanitizedHtmlTree(descriptor.sanitized, options.key);
@@ -395,15 +544,15 @@ function renderInlineHtmlSegment(raw, sanitized, options = {}) {
395
544
  if (options.key !== void 0 && options.key !== null) {
396
545
  props.key = options.key;
397
546
  }
398
- return React.createElement("span", props);
547
+ return React3.createElement("span", props);
399
548
  };
400
549
  const allRenderers = options.renderers ? { ...DEFAULT_INLINE_HTML_RENDERERS, ...options.renderers } : DEFAULT_INLINE_HTML_RENDERERS;
401
550
  const renderer = allRenderers[descriptor.tagName];
402
551
  if (renderer) {
403
552
  const rendered = renderer(descriptor, { key: options.key, defaultRender });
404
553
  if (rendered) {
405
- if (options.key !== void 0 && options.key !== null && React.isValidElement(rendered) && rendered.key === null) {
406
- return React.cloneElement(rendered, { key: options.key });
554
+ if (options.key !== void 0 && options.key !== null && React3.isValidElement(rendered) && rendered.key === null) {
555
+ return React3.cloneElement(rendered, { key: options.key });
407
556
  }
408
557
  return rendered;
409
558
  }
@@ -515,21 +664,21 @@ function renderSanitizedHtmlTree(html, key) {
515
664
  }
516
665
  if (children.length === 1) {
517
666
  const [child] = children;
518
- if (React.isValidElement(child)) {
667
+ if (React3.isValidElement(child)) {
519
668
  if (key !== void 0 && key !== null) {
520
- return React.cloneElement(child, { key });
669
+ return React3.cloneElement(child, { key });
521
670
  }
522
671
  return child;
523
672
  }
524
673
  if (typeof child === "string" || typeof child === "number") {
525
674
  if (key !== void 0 && key !== null) {
526
- return React.createElement(React.Fragment, { key }, child);
675
+ return React3.createElement(React3.Fragment, { key }, child);
527
676
  }
528
- return React.createElement(React.Fragment, {}, child);
677
+ return React3.createElement(React3.Fragment, {}, child);
529
678
  }
530
- return React.createElement(React.Fragment, { key }, child);
679
+ return React3.createElement(React3.Fragment, { key }, child);
531
680
  }
532
- return React.createElement(React.Fragment, { key }, ...children);
681
+ return React3.createElement(React3.Fragment, { key }, ...children);
533
682
  } catch {
534
683
  return null;
535
684
  }
@@ -554,9 +703,9 @@ function convertDomNode(node, key) {
554
703
  }
555
704
  });
556
705
  if (children.length === 0) {
557
- return React.createElement(tagName, props);
706
+ return React3.createElement(tagName, props);
558
707
  }
559
- return React.createElement(tagName, props, ...children);
708
+ return React3.createElement(tagName, props, ...children);
560
709
  }
561
710
  function getElementAttributes(element) {
562
711
  const attrs = {};
@@ -616,7 +765,97 @@ var INLINE_ELEMENTS = /* @__PURE__ */ new Set([
616
765
  "mtd"
617
766
  ]);
618
767
 
768
+ // src/components/link-safety-modal.tsx
769
+ import { jsx, jsxs } from "react/jsx-runtime";
770
+ var DefaultLinkSafetyModal = ({ url, isOpen, isChecking, onClose, onConfirm, onCopy }) => {
771
+ if (!isOpen) {
772
+ return null;
773
+ }
774
+ return /* @__PURE__ */ jsx(
775
+ "div",
776
+ {
777
+ className: "stream-mdx-link-modal-backdrop",
778
+ role: "dialog",
779
+ "aria-modal": "true",
780
+ "aria-label": "Link safety confirmation",
781
+ style: {
782
+ position: "fixed",
783
+ inset: 0,
784
+ display: "flex",
785
+ alignItems: "center",
786
+ justifyContent: "center",
787
+ background: "rgba(0, 0, 0, 0.4)",
788
+ zIndex: 9999,
789
+ padding: "24px"
790
+ },
791
+ onClick: onClose,
792
+ children: /* @__PURE__ */ jsxs(
793
+ "div",
794
+ {
795
+ className: "stream-mdx-link-modal",
796
+ style: {
797
+ width: "min(520px, 100%)",
798
+ borderRadius: 12,
799
+ background: "var(--background, #fff)",
800
+ color: "var(--foreground, #111)",
801
+ border: "1px solid var(--border, rgba(0, 0, 0, 0.1))",
802
+ boxShadow: "0 20px 60px rgba(0, 0, 0, 0.25)",
803
+ padding: 20
804
+ },
805
+ onClick: (event) => event.stopPropagation(),
806
+ children: [
807
+ /* @__PURE__ */ jsx("div", { style: { fontWeight: 600, marginBottom: 8 }, children: "Open external link?" }),
808
+ /* @__PURE__ */ jsx("div", { style: { fontSize: 13, opacity: 0.8, wordBreak: "break-all", marginBottom: 16 }, children: url }),
809
+ /* @__PURE__ */ jsxs("div", { style: { display: "flex", gap: 8, justifyContent: "flex-end" }, children: [
810
+ /* @__PURE__ */ jsx("button", { type: "button", onClick: onCopy, disabled: isChecking, style: buttonStyle, children: "Copy link" }),
811
+ /* @__PURE__ */ jsx("button", { type: "button", onClick: onConfirm, disabled: isChecking, style: primaryButtonStyle, children: "Open link" }),
812
+ /* @__PURE__ */ jsx("button", { type: "button", onClick: onClose, style: buttonStyle, children: "Cancel" })
813
+ ] })
814
+ ]
815
+ }
816
+ )
817
+ }
818
+ );
819
+ };
820
+ var buttonStyle = {
821
+ borderRadius: 8,
822
+ border: "1px solid var(--border, rgba(0, 0, 0, 0.1))",
823
+ padding: "6px 12px",
824
+ background: "var(--background, #fff)",
825
+ color: "inherit",
826
+ fontSize: 13
827
+ };
828
+ var primaryButtonStyle = {
829
+ ...buttonStyle,
830
+ background: "var(--foreground, #111)",
831
+ color: "var(--background, #fff)",
832
+ borderColor: "var(--foreground, #111)"
833
+ };
834
+
619
835
  // src/components/index.ts
836
+ var MdxRuntimeBoundary = class extends React4.Component {
837
+ constructor() {
838
+ super(...arguments);
839
+ this.state = { hasError: false };
840
+ }
841
+ static getDerivedStateFromError() {
842
+ return { hasError: true };
843
+ }
844
+ componentDidCatch(error) {
845
+ this.props.onError(error);
846
+ }
847
+ componentDidUpdate(prevProps) {
848
+ if (prevProps.resetKey !== this.props.resetKey && this.state.hasError) {
849
+ this.setState({ hasError: false });
850
+ }
851
+ }
852
+ render() {
853
+ if (this.state.hasError) {
854
+ return null;
855
+ }
856
+ return this.props.children;
857
+ }
858
+ };
620
859
  function renderInlineNodes(nodes, components) {
621
860
  return nodes.map((node, index) => {
622
861
  const key = `${node.kind}-${index}`;
@@ -624,31 +863,31 @@ function renderInlineNodes(nodes, components) {
624
863
  case "text": {
625
864
  const textComponent = components.text;
626
865
  if (textComponent && textComponent !== defaultInlineComponents.text) {
627
- return React3.createElement(textComponent, { key, text: node.text });
866
+ return React4.createElement(textComponent, { key, text: node.text });
628
867
  }
629
- return React3.createElement(React3.Fragment, { key, children: node.text });
868
+ return React4.createElement(React4.Fragment, { key, children: node.text });
630
869
  }
631
870
  case "strong":
632
- return React3.createElement(components.strong, {
871
+ return React4.createElement(components.strong, {
633
872
  key,
634
873
  children: renderInlineNodes(node.children, components)
635
874
  });
636
875
  case "em":
637
- return React3.createElement(components.em, {
876
+ return React4.createElement(components.em, {
638
877
  key,
639
878
  children: renderInlineNodes(node.children, components)
640
879
  });
641
880
  case "strike": {
642
- const StrikeComponent = components.strike ?? ((props) => React3.createElement("del", {}, props.children));
643
- return React3.createElement(StrikeComponent, {
881
+ const StrikeComponent = components.strike ?? ((props) => React4.createElement("del", {}, props.children));
882
+ return React4.createElement(StrikeComponent, {
644
883
  key,
645
884
  children: renderInlineNodes(node.children, components)
646
885
  });
647
886
  }
648
887
  case "code":
649
- return React3.createElement(components.code, { key, text: node.text });
888
+ return React4.createElement(components.code, { key, text: node.text });
650
889
  case "link":
651
- return React3.createElement(
890
+ return React4.createElement(
652
891
  components.link,
653
892
  {
654
893
  key,
@@ -658,18 +897,18 @@ function renderInlineNodes(nodes, components) {
658
897
  }
659
898
  );
660
899
  case "image":
661
- return React3.createElement(components.image, {
900
+ return React4.createElement(components.image, {
662
901
  key,
663
902
  src: node.src,
664
903
  alt: node.alt,
665
904
  title: node.title
666
905
  });
667
906
  case "br":
668
- return React3.createElement(React3.Fragment, { key }, React3.createElement(components.br, {}));
907
+ return React4.createElement(React4.Fragment, { key }, React4.createElement(components.br, {}));
669
908
  default: {
670
909
  const component = components[node.kind];
671
910
  if (component) {
672
- return React3.createElement(component, { key, ...node });
911
+ return React4.createElement(component, { key, ...node });
673
912
  }
674
913
  return null;
675
914
  }
@@ -677,18 +916,18 @@ function renderInlineNodes(nodes, components) {
677
916
  });
678
917
  }
679
918
  var defaultInlineComponents = {
680
- text: ({ text }) => React3.createElement(React3.Fragment, {}, text),
681
- strong: ({ children }) => React3.createElement("strong", {}, children),
682
- em: ({ children }) => React3.createElement("em", {}, children),
683
- strike: ({ children }) => React3.createElement("del", {}, children),
684
- code: ({ text }) => React3.createElement(
919
+ text: ({ text }) => React4.createElement(React4.Fragment, {}, text),
920
+ strong: ({ children }) => React4.createElement("strong", {}, children),
921
+ em: ({ children }) => React4.createElement("em", {}, children),
922
+ strike: ({ children }) => React4.createElement("del", {}, children),
923
+ code: ({ text }) => React4.createElement(
685
924
  "code",
686
925
  {
687
926
  className: "inline-code"
688
927
  },
689
928
  text
690
929
  ),
691
- link: ({ href, title, children }) => React3.createElement(
930
+ link: ({ href, title, children }) => React4.createElement(
692
931
  "a",
693
932
  {
694
933
  href,
@@ -699,15 +938,15 @@ var defaultInlineComponents = {
699
938
  },
700
939
  children
701
940
  ),
702
- image: ({ src, alt, title }) => React3.createElement("img", {
941
+ image: ({ src, alt, title }) => React4.createElement("img", {
703
942
  src,
704
943
  alt,
705
944
  title,
706
945
  className: "markdown-image"
707
946
  }),
708
- br: () => React3.createElement("br"),
947
+ br: () => React4.createElement("br"),
709
948
  // Custom extensible components
710
- mention: ({ handle }) => React3.createElement(
949
+ mention: ({ handle }) => React4.createElement(
711
950
  "span",
712
951
  {
713
952
  className: "mention",
@@ -715,7 +954,7 @@ var defaultInlineComponents = {
715
954
  },
716
955
  `@${handle}`
717
956
  ),
718
- citation: ({ id }) => React3.createElement(
957
+ citation: ({ id }) => React4.createElement(
719
958
  "span",
720
959
  {
721
960
  className: "citation",
@@ -723,7 +962,7 @@ var defaultInlineComponents = {
723
962
  },
724
963
  `[${id}]`
725
964
  ),
726
- "math-inline": ({ tex }) => React3.createElement(
965
+ "math-inline": ({ tex }) => React4.createElement(
727
966
  "span",
728
967
  {
729
968
  className: "math-inline",
@@ -731,27 +970,27 @@ var defaultInlineComponents = {
731
970
  },
732
971
  `$${tex}$`
733
972
  ),
734
- "math-display": ({ tex }) => React3.createElement(
973
+ "math-display": ({ tex }) => React4.createElement(
735
974
  "div",
736
975
  {
737
976
  className: "math-display markdown-math-display",
738
977
  "data-tex": tex,
739
978
  style: { overflowX: "auto" }
740
979
  },
741
- React3.createElement("span", { className: "math-display-content" }, `$$${tex}$$`)
980
+ React4.createElement("span", { className: "math-display-content" }, `$$${tex}$$`)
742
981
  ),
743
982
  // Footnote inline reference (superscript anchor)
744
983
  "footnote-ref": ({ label, number }) => {
745
984
  const n = number ?? "?";
746
985
  const href = number ? `#fn:${n}` : void 0;
747
986
  const id = number ? `fnref:${n}` : void 0;
748
- return React3.createElement("sup", { className: "footnote-ref" }, React3.createElement("a", { href, id, "data-label": label }, String(n)));
987
+ return React4.createElement("sup", { className: "footnote-ref" }, React4.createElement("a", { href, id, "data-label": label }, String(n)));
749
988
  }
750
989
  };
751
990
  var defaultBlockComponents = {
752
991
  paragraph: ({ inlines, raw, meta, children }) => {
753
992
  if (children !== void 0) {
754
- return React3.createElement(
993
+ return React4.createElement(
755
994
  "p",
756
995
  {
757
996
  className: "markdown-paragraph"
@@ -765,7 +1004,7 @@ var defaultBlockComponents = {
765
1004
  if (structured.length === 1) {
766
1005
  return structured[0];
767
1006
  }
768
- return React3.createElement(React3.Fragment, {}, ...structured);
1007
+ return React4.createElement(React4.Fragment, {}, ...structured);
769
1008
  }
770
1009
  const filteredInlines = inlines && raw && inlines.length > 0 ? inlines.filter((node) => !(node.kind === "text" && node.text === raw)) : inlines ?? [];
771
1010
  const effectiveInlines = filteredInlines.length > 0 ? filteredInlines : raw ? [
@@ -774,7 +1013,7 @@ var defaultBlockComponents = {
774
1013
  text: raw
775
1014
  }
776
1015
  ] : [];
777
- return React3.createElement(
1016
+ return React4.createElement(
778
1017
  "p",
779
1018
  {
780
1019
  className: "markdown-paragraph"
@@ -786,7 +1025,7 @@ var defaultBlockComponents = {
786
1025
  const tag = `h${level}`;
787
1026
  const onlyPlainText = Array.isArray(inlines) && inlines.length > 0 && inlines.every((node) => node.kind === "text");
788
1027
  const children = onlyPlainText ? inlines.map((node) => node.kind === "text" ? node.text : "").join("") : renderInlineNodes(inlines, defaultInlineComponents);
789
- return React3.createElement(
1028
+ return React4.createElement(
790
1029
  tag,
791
1030
  {
792
1031
  className: `markdown-heading markdown-h${level}`,
@@ -798,7 +1037,7 @@ var defaultBlockComponents = {
798
1037
  code: ({ html, meta, lines, lang, preAttrs, codeAttrs }) => {
799
1038
  const language = typeof lang === "string" ? lang : typeof meta?.lang === "string" ? String(meta.lang) : "text";
800
1039
  if (html) {
801
- return React3.createElement("div", {
1040
+ return React4.createElement("div", {
802
1041
  className: `markdown-code-block language-${language || "text"}`,
803
1042
  /* biome-ignore lint/security/noDangerouslySetInnerHtml: highlighted HTML is generated by our sanitizer */
804
1043
  dangerouslySetInnerHTML: { __html: html }
@@ -808,20 +1047,20 @@ var defaultBlockComponents = {
808
1047
  if (lines && lines.length > 0) {
809
1048
  const preAttributes = attrsToProps(preAttrs);
810
1049
  const codeAttributes = attrsToProps(codeAttrs);
811
- return React3.createElement(
1050
+ return React4.createElement(
812
1051
  "pre",
813
1052
  {
814
1053
  ...preAttributes,
815
1054
  className: preAttributes.className ? `${preAttributes.className} markdown-code-block language-${language || "text"}` : `markdown-code-block language-${language || "text"}`
816
1055
  },
817
- React3.createElement(
1056
+ React4.createElement(
818
1057
  "code",
819
1058
  {
820
1059
  ...codeAttributes,
821
1060
  className: codeAttributes.className ? `${codeAttributes.className} language-${language || "text"}` : `language-${language || "text"}`
822
1061
  },
823
1062
  lines.map(
824
- (line) => React3.createElement("span", {
1063
+ (line) => React4.createElement("span", {
825
1064
  key: line.id,
826
1065
  className: "line",
827
1066
  /* biome-ignore lint/security/noDangerouslySetInnerHtml: line HTML is sanitized server-side */
@@ -831,34 +1070,44 @@ var defaultBlockComponents = {
831
1070
  )
832
1071
  );
833
1072
  }
834
- return React3.createElement("pre", {
1073
+ return React4.createElement("pre", {
835
1074
  className: `markdown-code-block language-${language || "text"}`,
836
1075
  children: code
837
1076
  });
838
1077
  },
839
- blockquote: ({ inlines, renderedContent }) => React3.createElement(
1078
+ blockquote: ({ inlines, renderedContent }) => React4.createElement(
840
1079
  "blockquote",
841
1080
  {
842
1081
  className: "markdown-blockquote"
843
1082
  },
844
1083
  renderedContent ?? renderInlineNodes(inlines, defaultInlineComponents)
845
1084
  ),
1085
+ hr: (props) => React4.createElement("hr", props),
846
1086
  list: ({ ordered, items }) => {
1087
+ if (items.length === 0) {
1088
+ return null;
1089
+ }
847
1090
  const tag = ordered ? "ol" : "ul";
1091
+ const listStyle = ordered ? {
1092
+ ["--list-indent"]: `calc(2.5rem + ${String(items.length).length}ch)`
1093
+ } : void 0;
848
1094
  const listItems = items.map(
849
- (item, index) => React3.createElement(
1095
+ (item, index) => React4.createElement(
850
1096
  "li",
851
1097
  {
852
1098
  key: index,
853
- className: "markdown-list-item"
1099
+ className: "markdown-list-item",
1100
+ "data-counter-text": ordered ? `${index + 1}.` : void 0,
1101
+ "data-list-depth": 0
854
1102
  },
855
1103
  renderInlineNodes(item, defaultInlineComponents)
856
1104
  )
857
1105
  );
858
- return React3.createElement(
1106
+ return React4.createElement(
859
1107
  tag,
860
1108
  {
861
- className: `markdown-list ${ordered ? "ordered" : "unordered"}`
1109
+ className: `markdown-list ${ordered ? "ordered" : "unordered"}`,
1110
+ style: listStyle
862
1111
  },
863
1112
  listItems
864
1113
  );
@@ -868,29 +1117,62 @@ var defaultBlockComponents = {
868
1117
  const htmlString = sanitizeHTML(raw);
869
1118
  if (typeof window !== "undefined" && elements) {
870
1119
  const content = mapHtmlToReact(htmlString, elements);
871
- return React3.createElement("div", { className: "markdown-html" }, content);
1120
+ return React4.createElement("div", { className: "markdown-html" }, content);
872
1121
  }
873
- return React3.createElement("div", {
1122
+ return React4.createElement("div", {
874
1123
  className: "markdown-html",
875
1124
  /* biome-ignore lint/security/noDangerouslySetInnerHtml: htmlString is sanitized before injection */
876
1125
  dangerouslySetInnerHTML: { __html: htmlString }
877
1126
  });
878
1127
  },
879
- mdx: ({ compiledRef, compiledModule, status, errorMessage }) => {
880
- const [Comp, setComp] = React3.useState(null);
881
- const [internalError, setInternalError] = React3.useState(null);
1128
+ mdx: ({ compiledRef, compiledModule, status, errorMessage, raw }) => {
1129
+ const [Comp, setComp] = React4.useState(null);
1130
+ const [internalError, setInternalError] = React4.useState(null);
1131
+ const [renderError, setRenderError] = React4.useState(null);
1132
+ const [retryKey, setRetryKey] = React4.useState(0);
1133
+ const hydrationContext = React4.useContext(MdxHydrationContext);
1134
+ const hydrationController = hydrationContext?.controller ?? null;
1135
+ const hydrationOptions = hydrationContext?.options;
1136
+ const containerRef = React4.useRef(null);
1137
+ const deferHydration = hydrationOptions?.strategy === "visible";
1138
+ const shouldHydrate = useDeferredRender(
1139
+ containerRef,
1140
+ deferHydration ? {
1141
+ enabled: true,
1142
+ rootMargin: hydrationOptions?.rootMargin,
1143
+ idleTimeoutMs: hydrationOptions?.idleTimeoutMs,
1144
+ debounceMs: hydrationOptions?.debounceMs
1145
+ } : { enabled: false }
1146
+ );
882
1147
  const resolvedId = compiledModule?.id ?? (compiledRef?.id && compiledRef.id !== "pending" ? compiledRef.id : void 0);
1148
+ const handleRetry = React4.useCallback(() => {
1149
+ setInternalError(null);
1150
+ setRenderError(null);
1151
+ setComp(null);
1152
+ setRetryKey((prev) => prev + 1);
1153
+ }, []);
1154
+ const handleRuntimeError = React4.useCallback(
1155
+ (error) => {
1156
+ const message2 = error instanceof Error ? error.message : String(error);
1157
+ setRenderError(message2);
1158
+ markMdxHydrationError(resolvedId ?? compiledRef?.id);
1159
+ },
1160
+ [resolvedId, compiledRef?.id]
1161
+ );
883
1162
  const effectiveStatus = status ? status : resolvedId ? "compiled" : "pending";
884
- const failureMessage = errorMessage ?? internalError ?? null;
1163
+ const failureMessage = errorMessage ?? internalError ?? renderError ?? null;
885
1164
  const moduleDependencies = compiledModule?.dependencies;
886
- React3.useEffect(() => {
1165
+ React4.useEffect(() => {
1166
+ if (!shouldHydrate) {
1167
+ return;
1168
+ }
887
1169
  if (status === "error") {
888
- setComp(null);
889
- setInternalError(null);
1170
+ markMdxHydrationError(resolvedId ?? compiledRef?.id);
890
1171
  return;
891
1172
  }
892
1173
  let cancelled = false;
893
1174
  async function ensure() {
1175
+ let permit = null;
894
1176
  try {
895
1177
  if (status === "error" || !resolvedId || resolvedId === "pending") {
896
1178
  if (!cancelled) {
@@ -899,7 +1181,17 @@ var defaultBlockComponents = {
899
1181
  }
900
1182
  return;
901
1183
  }
902
- const { getMDXComponentFactory: getMDXComponentFactory2, registerInlineMdxModule: registerInlineMdxModule2 } = await Promise.resolve().then(() => (init_mdx_client(), mdx_client_exports));
1184
+ if (hydrationController) {
1185
+ permit = await hydrationController.acquire();
1186
+ if (cancelled) {
1187
+ permit.release();
1188
+ return;
1189
+ }
1190
+ }
1191
+ setInternalError(null);
1192
+ setRenderError(null);
1193
+ markMdxHydrationStart(resolvedId);
1194
+ const { getMDXComponentFactory: getMDXComponentFactory2, registerInlineMdxModule: registerInlineMdxModule2 } = await loadMdxRuntime();
903
1195
  if (compiledModule?.code) {
904
1196
  registerInlineMdxModule2({
905
1197
  id: compiledModule.id,
@@ -912,41 +1204,82 @@ var defaultBlockComponents = {
912
1204
  if (!cancelled) {
913
1205
  setComp(() => C);
914
1206
  setInternalError(null);
1207
+ markMdxHydrated(resolvedId);
915
1208
  }
916
1209
  } catch (error) {
917
1210
  if (!cancelled) {
918
- const message = error instanceof Error ? error.message : String(error);
919
- setComp(null);
920
- setInternalError(message);
1211
+ const message2 = error instanceof Error ? error.message : String(error);
1212
+ setInternalError(message2);
1213
+ markMdxHydrationError(resolvedId);
921
1214
  }
1215
+ } finally {
1216
+ permit?.release();
922
1217
  }
923
1218
  }
924
1219
  ensure();
925
1220
  return () => {
926
1221
  cancelled = true;
927
1222
  };
928
- }, [compiledModule?.id, compiledModule?.code, moduleDependencies, resolvedId, status]);
1223
+ }, [compiledModule?.id, compiledModule?.code, moduleDependencies, resolvedId, status, shouldHydrate, retryKey]);
929
1224
  const compileMode = compiledModule?.source === "worker" || compiledRef?.id?.startsWith("worker:") ? "worker" : "server";
930
- if (effectiveStatus === "error" || failureMessage) {
931
- const message = failureMessage ?? (compileMode === "worker" ? "MDX compilation failed in client mode. Try switching back to server rendering or restarting the stream." : "MDX compilation failed. Try restarting the stream.");
932
- return React3.createElement(
1225
+ const pendingId = resolvedId && resolvedId !== "pending" ? resolvedId : compiledRef?.id ?? "pending";
1226
+ const waitingForVisibility = deferHydration && !shouldHydrate && Boolean(resolvedId);
1227
+ const pendingLabel = waitingForVisibility ? "MDX ready (hydrate on view)\u2026" : compileMode === "worker" ? "Compiling MDX (client)\u2026" : "Compiling MDX (server)\u2026";
1228
+ const message = failureMessage ?? (compileMode === "worker" ? "MDX compilation failed in client mode. Try switching back to server rendering or restarting the stream." : "MDX compilation failed. Try restarting the stream.");
1229
+ const rawFallback = typeof raw === "string" && raw.trim().length > 0 ? React4.createElement("pre", { className: "markdown-mdx-fallback" }, raw) : null;
1230
+ const allowRetry = Boolean(internalError || renderError);
1231
+ const retryButton = allowRetry ? React4.createElement(
1232
+ "button",
1233
+ {
1234
+ type: "button",
1235
+ className: "markdown-mdx-retry",
1236
+ onClick: handleRetry
1237
+ },
1238
+ "Retry hydration"
1239
+ ) : null;
1240
+ const errorPanel = React4.createElement(
1241
+ "div",
1242
+ { className: "markdown-mdx-error" },
1243
+ React4.createElement(React4.Fragment, null, React4.createElement("strong", null, "MDX failed"), React4.createElement("div", null, message))
1244
+ );
1245
+ if (Comp && !failureMessage) {
1246
+ return React4.createElement(
1247
+ "div",
1248
+ {
1249
+ className: "markdown-mdx",
1250
+ ref: containerRef,
1251
+ "data-mdx-ref": resolvedId ?? compiledRef?.id ?? "compiled",
1252
+ "data-mdx-status": failureMessage ? "error" : "compiled",
1253
+ "data-mdx-mode": compileMode
1254
+ },
1255
+ React4.createElement(
1256
+ MdxRuntimeBoundary,
1257
+ { resetKey: retryKey, onError: handleRuntimeError },
1258
+ React4.createElement(Comp, {})
1259
+ )
1260
+ );
1261
+ }
1262
+ if (failureMessage) {
1263
+ return React4.createElement(
933
1264
  "div",
934
1265
  {
935
- className: "markdown-mdx error",
936
- "data-mdx-ref": resolvedId ?? compiledRef?.id ?? "error",
1266
+ className: "markdown-mdx",
1267
+ ref: containerRef,
1268
+ "data-mdx-ref": pendingId,
937
1269
  "data-mdx-status": "error",
938
1270
  "data-mdx-mode": compileMode
939
1271
  },
940
- React3.createElement(React3.Fragment, null, React3.createElement("strong", null, "MDX failed"), React3.createElement("div", null, message))
1272
+ errorPanel,
1273
+ rawFallback,
1274
+ retryButton
941
1275
  );
942
1276
  }
943
1277
  if (!Comp) {
944
- const pendingId = resolvedId && resolvedId !== "pending" ? resolvedId : compiledRef?.id ?? "pending";
945
- const pendingLabel = compileMode === "worker" ? "Compiling MDX (client)\u2026" : "Compiling MDX (server)\u2026";
946
- return React3.createElement(
1278
+ return React4.createElement(
947
1279
  "div",
948
1280
  {
949
1281
  className: "markdown-mdx",
1282
+ ref: containerRef,
950
1283
  "data-mdx-ref": pendingId,
951
1284
  "data-mdx-status": "pending",
952
1285
  "data-mdx-mode": compileMode
@@ -954,41 +1287,31 @@ var defaultBlockComponents = {
954
1287
  pendingLabel
955
1288
  );
956
1289
  }
957
- return React3.createElement(
958
- "div",
959
- {
960
- className: "markdown-mdx",
961
- "data-mdx-ref": resolvedId ?? compiledRef?.id ?? "compiled",
962
- "data-mdx-status": "compiled",
963
- "data-mdx-mode": compileMode
964
- },
965
- React3.createElement(Comp, {})
966
- );
967
1290
  },
968
1291
  // Footnotes block rendered at page end
969
1292
  footnotes: ({ items }) => {
970
- if (!items || items.length === 0) return React3.createElement(React3.Fragment, null);
1293
+ if (!items || items.length === 0) return React4.createElement(React4.Fragment, null);
971
1294
  const listItems = items.map(
972
- (item) => React3.createElement(
1295
+ (item) => React4.createElement(
973
1296
  "li",
974
1297
  { key: item.number, id: `fn:${item.number}` },
975
1298
  renderInlineNodes(item.inlines, defaultInlineComponents),
976
1299
  " ",
977
- React3.createElement("a", { href: `#fnref:${item.number}`, className: "footnote-backref", "aria-label": "Back to content" }, "\u21A9")
1300
+ React4.createElement("a", { href: `#fnref:${item.number}`, className: "footnote-backref", "aria-label": "Back to content" }, "\u21A9")
978
1301
  )
979
1302
  );
980
- return React3.createElement("section", { className: "footnotes" }, React3.createElement("hr", {}), React3.createElement("ol", {}, listItems));
1303
+ return React4.createElement("section", { className: "footnotes" }, React4.createElement("hr", {}), React4.createElement("ol", {}, listItems));
981
1304
  },
982
1305
  // Footnote definition placeholders (render nothing)
983
- "footnote-def": () => React3.createElement(React3.Fragment, null),
1306
+ "footnote-def": () => React4.createElement(React4.Fragment, null),
984
1307
  // Callouts block
985
1308
  callout: ({ kind, inlines = [] }) => {
986
1309
  const tone = (kind || "NOTE").toUpperCase();
987
1310
  const title = tone.charAt(0) + tone.slice(1).toLowerCase();
988
- return React3.createElement(
1311
+ return React4.createElement(
989
1312
  "div",
990
1313
  { className: `markdown-callout markdown-callout-${tone.toLowerCase()} border rounded p-3 my-3` },
991
- React3.createElement("div", { className: "font-semibold mb-1" }, title),
1314
+ React4.createElement("div", { className: "font-semibold mb-1" }, title),
992
1315
  inlines.length > 0 ? renderInlineNodes(inlines, defaultInlineComponents) : null
993
1316
  );
994
1317
  },
@@ -1003,7 +1326,7 @@ var defaultBlockComponents = {
1003
1326
  const renderCells = (cells, tag, rowIdx) => cells.map((cell, i) => {
1004
1327
  const columnAlign = align?.[i] ?? void 0;
1005
1328
  const cellStyle = columnAlign ? { textAlign: columnAlign } : void 0;
1006
- return React3.createElement(
1329
+ return React4.createElement(
1007
1330
  tag === "th" ? El.Th : El.Td,
1008
1331
  {
1009
1332
  key: `${rowIdx}-${i}`,
@@ -1014,14 +1337,14 @@ var defaultBlockComponents = {
1014
1337
  renderInlineNodes(cell, defaultInlineComponents)
1015
1338
  );
1016
1339
  });
1017
- return React3.createElement(
1340
+ return React4.createElement(
1018
1341
  El.Table,
1019
1342
  { className: "markdown-table" },
1020
- header && header.length > 0 ? React3.createElement(El.Thead, {}, React3.createElement(El.Tr, {}, renderCells(header, "th", -1))) : null,
1021
- React3.createElement(
1343
+ header && header.length > 0 ? React4.createElement(El.Thead, {}, React4.createElement(El.Tr, {}, renderCells(header, "th", -1))) : null,
1344
+ React4.createElement(
1022
1345
  El.Tbody,
1023
1346
  {},
1024
- rows.map((row, r) => React3.createElement(El.Tr, { key: r }, renderCells(row, "td", r)))
1347
+ rows.map((row, r) => React4.createElement(El.Tr, { key: r }, renderCells(row, "td", r)))
1025
1348
  )
1026
1349
  );
1027
1350
  }
@@ -1090,7 +1413,7 @@ var ComponentRegistry = class {
1090
1413
  renderBlock(block) {
1091
1414
  const Component = this.getBlockComponent(block.type);
1092
1415
  const props = this.getBlockProps(block);
1093
- return React3.createElement(Component, {
1416
+ return React4.createElement(Component, {
1094
1417
  key: block.id,
1095
1418
  ...props
1096
1419
  });
@@ -1125,6 +1448,14 @@ var ComponentRegistry = class {
1125
1448
  return {
1126
1449
  inlines: block.payload.inline || []
1127
1450
  };
1451
+ case "hr": {
1452
+ const range = block.payload.range;
1453
+ return {
1454
+ className: "markdown-hr",
1455
+ "data-start": typeof range?.from === "number" ? range.from : void 0,
1456
+ "data-end": typeof range?.to === "number" ? range.to : void 0
1457
+ };
1458
+ }
1128
1459
  case "code":
1129
1460
  return {
1130
1461
  html: block.payload.highlightedHtml,
@@ -1157,7 +1488,8 @@ var ComponentRegistry = class {
1157
1488
  compiledRef: compiledRef ?? { id: "pending" },
1158
1489
  compiledModule,
1159
1490
  status,
1160
- errorMessage
1491
+ errorMessage,
1492
+ raw: typeof block.payload.raw === "string" ? block.payload.raw : void 0
1161
1493
  };
1162
1494
  })();
1163
1495
  case "table": {
@@ -1208,42 +1540,42 @@ var ComponentRegistry = class {
1208
1540
  function getDefaultHtmlElements() {
1209
1541
  return {
1210
1542
  // Text semantics
1211
- p: (props) => React3.createElement("p", props),
1212
- strong: (props) => React3.createElement("strong", props),
1213
- em: (props) => React3.createElement("em", props),
1214
- code: (props) => React3.createElement("code", props),
1215
- pre: (props) => React3.createElement("pre", props),
1216
- span: (props) => React3.createElement("span", props),
1217
- br: (props) => React3.createElement("br", props),
1218
- hr: (props) => React3.createElement("hr", props),
1543
+ p: (props) => React4.createElement("p", props),
1544
+ strong: (props) => React4.createElement("strong", props),
1545
+ em: (props) => React4.createElement("em", props),
1546
+ code: (props) => React4.createElement("code", props),
1547
+ pre: (props) => React4.createElement("pre", props),
1548
+ span: (props) => React4.createElement("span", props),
1549
+ br: (props) => React4.createElement("br", props),
1550
+ hr: (props) => React4.createElement("hr", props),
1219
1551
  // Lists
1220
- ul: (props) => React3.createElement("ul", props),
1221
- ol: (props) => React3.createElement("ol", props),
1222
- li: (props) => React3.createElement("li", props),
1552
+ ul: (props) => React4.createElement("ul", props),
1553
+ ol: (props) => React4.createElement("ol", props),
1554
+ li: (props) => React4.createElement("li", props),
1223
1555
  // Links & media
1224
- a: (props) => React3.createElement("a", props),
1225
- img: (props) => React3.createElement("img", props),
1556
+ a: (props) => React4.createElement("a", props),
1557
+ img: (props) => React4.createElement("img", props),
1226
1558
  // Blockquotes
1227
- blockquote: (props) => React3.createElement("blockquote", props),
1559
+ blockquote: (props) => React4.createElement("blockquote", props),
1228
1560
  // Tables
1229
- table: (props) => React3.createElement("table", props),
1230
- thead: (props) => React3.createElement("thead", props),
1231
- tbody: (props) => React3.createElement("tbody", props),
1232
- tr: (props) => React3.createElement("tr", props),
1233
- th: (props) => React3.createElement("th", props),
1234
- td: (props) => React3.createElement("td", props),
1561
+ table: (props) => React4.createElement("table", props),
1562
+ thead: (props) => React4.createElement("thead", props),
1563
+ tbody: (props) => React4.createElement("tbody", props),
1564
+ tr: (props) => React4.createElement("tr", props),
1565
+ th: (props) => React4.createElement("th", props),
1566
+ td: (props) => React4.createElement("td", props),
1235
1567
  // Generic
1236
- div: (props) => React3.createElement("div", props)
1568
+ div: (props) => React4.createElement("div", props)
1237
1569
  };
1238
1570
  }
1239
1571
  function getDefaultTableElements(overrides) {
1240
1572
  const base = {
1241
- Table: (props) => React3.createElement("table", props),
1242
- Thead: (props) => React3.createElement("thead", props),
1243
- Tbody: (props) => React3.createElement("tbody", props),
1244
- Tr: (props) => React3.createElement("tr", props),
1245
- Th: (props) => React3.createElement("th", props),
1246
- Td: (props) => React3.createElement("td", props)
1573
+ Table: (props) => React4.createElement("table", props),
1574
+ Thead: (props) => React4.createElement("thead", props),
1575
+ Tbody: (props) => React4.createElement("tbody", props),
1576
+ Tr: (props) => React4.createElement("tr", props),
1577
+ Th: (props) => React4.createElement("th", props),
1578
+ Td: (props) => React4.createElement("td", props)
1247
1579
  };
1248
1580
  return { ...base, ...overrides || {} };
1249
1581
  }
@@ -1257,12 +1589,12 @@ function mapHtmlToReact(html, elements) {
1257
1589
  children.push(element);
1258
1590
  }
1259
1591
  });
1260
- return React3.createElement(React3.Fragment, {}, ...children);
1592
+ return React4.createElement(React4.Fragment, {}, ...children);
1261
1593
  }
1262
1594
  function toReact(node, elements, key) {
1263
1595
  if (node.nodeType === Node.TEXT_NODE) {
1264
1596
  const text = node.textContent ?? "";
1265
- return React3.createElement(React3.Fragment, { key }, text);
1597
+ return React4.createElement(React4.Fragment, { key }, text);
1266
1598
  }
1267
1599
  if (node.nodeType !== Node.ELEMENT_NODE) {
1268
1600
  return null;
@@ -1284,9 +1616,9 @@ function toReact(node, elements, key) {
1284
1616
  const component = elements[tag];
1285
1617
  const elementChildren = children.length > 0 ? children : void 0;
1286
1618
  if (component) {
1287
- return React3.createElement(component, { ...props, key }, elementChildren);
1619
+ return React4.createElement(component, { ...props, key }, elementChildren);
1288
1620
  }
1289
- return React3.createElement(tag, { ...props, key }, elementChildren);
1621
+ return React4.createElement(tag, { ...props, key }, elementChildren);
1290
1622
  }
1291
1623
  function attrsToProps(attrs) {
1292
1624
  if (!attrs) return {};
@@ -1331,12 +1663,12 @@ function renderParagraphMixedSegments(segments, inlineComponents, inlineHtmlRend
1331
1663
  nodes.forEach((node, idx) => {
1332
1664
  if (node === null || node === void 0) return;
1333
1665
  const key = `${baseKey}-${idx}`;
1334
- if (React3.isValidElement(node)) {
1335
- target.push(node.key === key ? node : React3.cloneElement(node, { key }));
1666
+ if (React4.isValidElement(node)) {
1667
+ target.push(node.key === key ? node : React4.cloneElement(node, { key }));
1336
1668
  } else if (typeof node === "string" || typeof node === "number") {
1337
- target.push(React3.createElement(React3.Fragment, { key }, node));
1669
+ target.push(React4.createElement(React4.Fragment, { key }, node));
1338
1670
  } else {
1339
- target.push(React3.createElement(React3.Fragment, { key }, node));
1671
+ target.push(React4.createElement(React4.Fragment, { key }, node));
1340
1672
  }
1341
1673
  });
1342
1674
  };
@@ -1352,7 +1684,7 @@ function renderParagraphMixedSegments(segments, inlineComponents, inlineHtmlRend
1352
1684
  }
1353
1685
  const key = `paragraph-inline-group-${inlineGroupIndex++}`;
1354
1686
  result.push(
1355
- React3.createElement(
1687
+ React4.createElement(
1356
1688
  "p",
1357
1689
  {
1358
1690
  key,
@@ -1370,7 +1702,7 @@ function renderParagraphMixedSegments(segments, inlineComponents, inlineHtmlRend
1370
1702
  const inlineNodes = Array.isArray(segment.inline) ? segment.inline : [];
1371
1703
  if (inlineNodes.length === 0) {
1372
1704
  if (segment.value) {
1373
- inlineBuffer.push(React3.createElement(React3.Fragment, { key }, segment.value));
1705
+ inlineBuffer.push(React4.createElement(React4.Fragment, { key }, segment.value));
1374
1706
  }
1375
1707
  break;
1376
1708
  }
@@ -1398,14 +1730,14 @@ function renderParagraphMixedSegments(segments, inlineComponents, inlineHtmlRend
1398
1730
  const status = segment.status ?? "pending";
1399
1731
  let element;
1400
1732
  if (status === "compiled") {
1401
- element = React3.createElement("span", { className: "markdown-mdx-inline", "data-mdx-status": "compiled" });
1733
+ element = React4.createElement("span", { className: "markdown-mdx-inline", "data-mdx-status": "compiled" });
1402
1734
  } else if (status === "error") {
1403
1735
  const message = segment.value || "MDX error";
1404
- element = React3.createElement("span", { className: "markdown-mdx-inline text-destructive", "data-mdx-status": "error" }, message);
1736
+ element = React4.createElement("span", { className: "markdown-mdx-inline text-destructive", "data-mdx-status": "error" }, message);
1405
1737
  } else {
1406
- element = React3.createElement("span", { className: "markdown-mdx-inline", "data-mdx-status": status }, segment.value);
1738
+ element = React4.createElement("span", { className: "markdown-mdx-inline", "data-mdx-status": status }, segment.value);
1407
1739
  }
1408
- inlineBuffer.push(React3.createElement(React3.Fragment, { key }, element));
1740
+ inlineBuffer.push(React4.createElement(React4.Fragment, { key }, element));
1409
1741
  break;
1410
1742
  }
1411
1743
  case "html": {
@@ -1421,7 +1753,7 @@ function renderParagraphMixedSegments(segments, inlineComponents, inlineHtmlRend
1421
1753
  result.push(element);
1422
1754
  } else if (html) {
1423
1755
  result.push(
1424
- React3.createElement("div", {
1756
+ React4.createElement("div", {
1425
1757
  key,
1426
1758
  className: "markdown-inline-html-block",
1427
1759
  dangerouslySetInnerHTML: { __html: html }
@@ -1440,7 +1772,7 @@ function renderParagraphMixedSegments(segments, inlineComponents, inlineHtmlRend
1440
1772
  flushInline();
1441
1773
  if (result.length === 0) {
1442
1774
  return [
1443
- React3.createElement(
1775
+ React4.createElement(
1444
1776
  "p",
1445
1777
  {
1446
1778
  key: "paragraph-inline-group-0",
@@ -1499,6 +1831,7 @@ var BLOCK_LEVEL_TAGS = /* @__PURE__ */ new Set([
1499
1831
  ]);
1500
1832
  export {
1501
1833
  ComponentRegistry,
1834
+ DefaultLinkSafetyModal,
1502
1835
  defaultBlockComponents,
1503
1836
  defaultInlineComponents,
1504
1837
  mapHtmlToReact,