@stream-mdx/react 0.4.0 → 1.0.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 (106) hide show
  1. package/CHANGELOG.md +385 -4
  2. package/README.md +141 -16
  3. package/dist/blocks-renderer-DAOBFBfi.d.ts +29 -0
  4. package/dist/blocks-renderer-DQEL1kJW.d.cts +29 -0
  5. package/dist/components/bottom-stick-scroll-area.cjs +268 -0
  6. package/dist/components/bottom-stick-scroll-area.d.cts +36 -0
  7. package/dist/components/bottom-stick-scroll-area.d.ts +36 -0
  8. package/dist/components/bottom-stick-scroll-area.mjs +249 -0
  9. package/dist/components/diff-renderer.cjs +86 -0
  10. package/dist/components/diff-renderer.d.cts +11 -0
  11. package/dist/components/diff-renderer.d.ts +11 -0
  12. package/dist/components/diff-renderer.mjs +66 -0
  13. package/dist/components/index.cjs +2879 -1295
  14. package/dist/components/index.d.cts +9 -2
  15. package/dist/components/index.d.ts +9 -2
  16. package/dist/components/index.mjs +2842 -1277
  17. package/dist/components/katex-math.cjs +220 -0
  18. package/dist/components/katex-math.d.cts +10 -0
  19. package/dist/components/katex-math.d.ts +10 -0
  20. package/dist/components/katex-math.mjs +188 -0
  21. package/dist/contexts/math-tracker.cjs +240 -521
  22. package/dist/contexts/math-tracker.mjs +235 -513
  23. package/dist/index-Cmne1yUK.d.cts +723 -0
  24. package/dist/index-D7dyyu3q.d.ts +723 -0
  25. package/dist/index.cjs +13180 -5640
  26. package/dist/index.d.cts +72 -40
  27. package/dist/index.d.ts +72 -40
  28. package/dist/index.mjs +12587 -5038
  29. package/dist/math/display-wrapper.cjs +7 -15
  30. package/dist/math/display-wrapper.d.cts +2 -2
  31. package/dist/math/display-wrapper.d.ts +2 -2
  32. package/dist/math/display-wrapper.mjs +2 -6
  33. package/dist/node-views-Bpc6Gkgl.d.cts +13 -0
  34. package/dist/node-views-DpnYdaAS.d.ts +13 -0
  35. package/dist/renderer/hooks.cjs +35 -20
  36. package/dist/renderer/hooks.d.cts +22 -1
  37. package/dist/renderer/hooks.d.ts +22 -1
  38. package/dist/renderer/hooks.mjs +27 -12
  39. package/dist/renderer/patch-batching.cjs +7 -8
  40. package/dist/renderer/patch-batching.d.cts +1 -1
  41. package/dist/renderer/patch-batching.d.ts +1 -1
  42. package/dist/renderer/patch-batching.mjs +2 -1
  43. package/dist/renderer/patch-coalescing.cjs +5 -8
  44. package/dist/renderer/patch-commit-scheduler.cjs +160 -326
  45. package/dist/renderer/patch-commit-scheduler.d.cts +28 -4
  46. package/dist/renderer/patch-commit-scheduler.d.ts +28 -4
  47. package/dist/renderer/patch-commit-scheduler.mjs +157 -318
  48. package/dist/renderer/store.cjs +3847 -1099
  49. package/dist/renderer/store.d.cts +111 -3
  50. package/dist/renderer/store.d.ts +111 -3
  51. package/dist/renderer/store.mjs +3847 -1085
  52. package/dist/renderer/virtualized-code.cjs +415 -71
  53. package/dist/renderer/virtualized-code.d.cts +24 -23
  54. package/dist/renderer/virtualized-code.d.ts +24 -23
  55. package/dist/renderer/virtualized-code.mjs +409 -62
  56. package/dist/renderer.cjs +10939 -3974
  57. package/dist/renderer.d.cts +100 -29
  58. package/dist/renderer.d.ts +100 -29
  59. package/dist/renderer.mjs +10711 -3697
  60. package/dist/server-regions-CPLHGli0.d.cts +32 -0
  61. package/dist/server-regions-mUhyoKi7.d.ts +32 -0
  62. package/dist/server.cjs +10286 -3365
  63. package/dist/server.d.cts +17 -247
  64. package/dist/server.d.ts +17 -247
  65. package/dist/server.mjs +10565 -3619
  66. package/dist/{streaming-markdown-DOc2uLiP.d.ts → streaming-markdown-yELbJxyH.d.ts} +51 -55
  67. package/dist/{streaming-markdown-D-JcByd9.d.cts → streaming-markdown-zVwFuaJG.d.cts} +51 -55
  68. package/dist/streaming-markdown.cjs +11828 -4879
  69. package/dist/streaming-markdown.d.cts +9 -2
  70. package/dist/streaming-markdown.d.ts +9 -2
  71. package/dist/streaming-markdown.mjs +11820 -4821
  72. package/dist/trusted-mdx/index.cjs +833 -0
  73. package/dist/trusted-mdx/index.d.cts +11 -0
  74. package/dist/trusted-mdx/index.d.ts +11 -0
  75. package/dist/trusted-mdx/index.mjs +807 -0
  76. package/dist/trusted-mdx/native-children-slot.cjs +45 -0
  77. package/dist/trusted-mdx/native-children-slot.d.cts +11 -0
  78. package/dist/trusted-mdx/native-children-slot.d.ts +11 -0
  79. package/dist/trusted-mdx/native-children-slot.mjs +24 -0
  80. package/dist/trusted-mdx/server.cjs +752 -0
  81. package/dist/trusted-mdx/server.d.cts +24 -0
  82. package/dist/trusted-mdx/server.d.ts +24 -0
  83. package/dist/trusted-mdx/server.mjs +724 -0
  84. package/dist/trusted-mdx-contract-ElKpkDI5.d.cts +113 -0
  85. package/dist/trusted-mdx-contract-ElKpkDI5.d.ts +113 -0
  86. package/dist/utils/inline-html.cjs +246 -147
  87. package/dist/utils/inline-html.d.cts +39 -6
  88. package/dist/utils/inline-html.d.ts +39 -6
  89. package/dist/utils/inline-html.mjs +237 -134
  90. package/package.json +52 -18
  91. package/shadcn/README.md +28 -0
  92. package/shadcn/bottom-stick-scroll-area.tsx +358 -0
  93. package/dist/index-D2MYusAM.d.cts +0 -248
  94. package/dist/index-D2MYusAM.d.ts +0 -248
  95. package/dist/mdx-client.cjs +0 -408
  96. package/dist/mdx-client.d.cts +0 -113
  97. package/dist/mdx-client.d.ts +0 -113
  98. package/dist/mdx-client.mjs +0 -369
  99. package/dist/mdx-coordinator.cjs +0 -563
  100. package/dist/mdx-coordinator.d.cts +0 -21
  101. package/dist/mdx-coordinator.d.ts +0 -21
  102. package/dist/mdx-coordinator.mjs +0 -529
  103. package/dist/renderer/node-views.cjs +0 -1642
  104. package/dist/renderer/node-views.d.cts +0 -12
  105. package/dist/renderer/node-views.d.ts +0 -12
  106. package/dist/renderer/node-views.mjs +0 -1616
@@ -4,18 +4,14 @@ var __create = Object.create;
4
4
  var __defProp = Object.defineProperty;
5
5
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
6
6
  var __getOwnPropNames = Object.getOwnPropertyNames;
7
- var __getProtoOf = Object.getPrototypeOf;
8
- var __hasOwnProp = Object.prototype.hasOwnProperty;
7
+ var __getProtoOf = Object.getPrototypeOf, __hasOwnProp = Object.prototype.hasOwnProperty;
9
8
  var __export = (target, all) => {
10
9
  for (var name in all)
11
- __defProp(target, name, { get: all[name], enumerable: true });
12
- };
13
- var __copyProps = (to, from, except, desc) => {
14
- if (from && typeof from === "object" || typeof from === "function") {
10
+ __defProp(target, name, { get: all[name], enumerable: !0 });
11
+ }, __copyProps = (to, from, except, desc) => {
12
+ if (from && typeof from == "object" || typeof from == "function")
15
13
  for (let key of __getOwnPropNames(from))
16
- if (!__hasOwnProp.call(to, key) && key !== except)
17
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
18
- }
14
+ !__hasOwnProp.call(to, key) && key !== except && __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
19
15
  return to;
20
16
  };
21
17
  var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
@@ -23,99 +19,182 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
23
19
  // file that has been converted to a CommonJS file using a Babel-
24
20
  // compatible transform (i.e. "__esModule" has not been set), then set
25
21
  // "default" to the CommonJS "module.exports" for node compatibility.
26
- isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
22
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: !0 }) : target,
27
23
  mod
28
- ));
29
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
24
+ )), __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: !0 }), mod);
30
25
 
31
26
  // src/utils/inline-html.ts
32
27
  var inline_html_exports = {};
33
28
  __export(inline_html_exports, {
34
29
  DEFAULT_INLINE_HTML_RENDERERS: () => DEFAULT_INLINE_HTML_RENDERERS,
30
+ renderHtmlInlineNode: () => renderHtmlInlineNode,
31
+ renderHtmlOwnershipTree: () => renderHtmlOwnershipTree,
35
32
  renderInlineHtmlSegment: () => renderInlineHtmlSegment
36
33
  });
37
34
  module.exports = __toCommonJS(inline_html_exports);
38
- var import_react = __toESM(require("react"), 1);
39
- var BACKTICK_CONTENT = /^`([\s\S]+)`$/;
40
- var DEFAULT_INLINE_HTML_RENDERERS = {
35
+ var import_react = __toESM(require("react"), 1), import_core = require("@stream-mdx/core");
36
+ function renderHtmlInlineNode(node, children, elements, key, textValue, urlTransform, filterElement, parentTagName, renderPresentation, renderNativeElement) {
37
+ if (node.isClose || node.tagName === "script" || node.tagName === "style") return null;
38
+ if (!node.tagName || node.sanitized === "")
39
+ return import_react.default.createElement(import_react.default.Fragment, { key }, children);
40
+ let tag = node.tagName.toLowerCase(), props = mapAttributesToProps(node.attributes ?? {}, urlTransform);
41
+ props.key = key;
42
+ let renderElement = () => {
43
+ let nativeView;
44
+ return renderNativeElement ? nativeView = renderNativeElement(
45
+ tag,
46
+ props,
47
+ node.isSelfClosing ? void 0 : children,
48
+ key ?? tag
49
+ ) : tag === "textarea" ? (props.defaultValue = textValue ?? "", nativeView = import_react.default.createElement(elements?.[tag] ?? tag, props)) : nativeView = import_react.default.createElement(elements?.[tag] ?? tag, props, node.isSelfClosing ? void 0 : children), renderPresentation ? renderPresentation(tag, props, nativeView, children, key ?? tag) : nativeView;
50
+ };
51
+ return filterElement ? filterElement(
52
+ { tagName: tag, properties: props },
53
+ { source: "html", parentTagName },
54
+ renderElement,
55
+ () => children
56
+ ) : renderElement();
57
+ }
58
+ function renderHtmlOwnershipTree(nodes, elements, renderBlock, renderInline, renderInlineElement, renderParagraph, urlTransform, filterElement, parentTagName, contentComponents, renderPresentation, parentPath = "html", renderComponentPresentation) {
59
+ return nodes.map((node, index) => {
60
+ let nodeKey = `${parentPath}:${index}`;
61
+ if (node.kind === "text") return node.inline && renderInline ? renderInline(node.inline, parentTagName) : node.rawSource ?? node.text;
62
+ if (node.kind === "block") return renderBlock(node.block, parentTagName);
63
+ if (node.kind === "component") {
64
+ let reg = contentComponents?.[node.name];
65
+ if (!reg)
66
+ return import_react.default.createElement(import_react.default.Fragment, { key: nodeKey }, node.rawSource ?? `<${node.name} />`);
67
+ let result = reg.render({
68
+ props: node.props,
69
+ key: index,
70
+ hasChildren: node.children.length > 0,
71
+ renderChildren: () => renderHtmlOwnershipTree(
72
+ node.children,
73
+ elements,
74
+ renderBlock,
75
+ renderInline,
76
+ renderInlineElement,
77
+ renderParagraph,
78
+ urlTransform,
79
+ filterElement,
80
+ node.name,
81
+ contentComponents,
82
+ renderPresentation,
83
+ nodeKey,
84
+ renderComponentPresentation
85
+ ),
86
+ status: node.status,
87
+ diagnostic: node.diagnostic
88
+ });
89
+ return result.kind === "invalid" ? import_react.default.createElement(import_react.default.Fragment, { key: nodeKey }, node.rawSource ?? `<${node.name} />`) : result.kind === "suppressed" ? null : renderComponentPresentation ? renderComponentPresentation(
90
+ node.name,
91
+ result.element,
92
+ import_react.default.isValidElement(result.element) ? result.element.props.children : void 0,
93
+ nodeKey,
94
+ node.status,
95
+ node.rawSource
96
+ ) : result.element;
97
+ }
98
+ let tag = node.tagName.toLowerCase(), props = mapAttributesToProps(node.attributes, urlTransform);
99
+ props.key = nodeKey;
100
+ let children = renderHtmlOwnershipTree(node.children, elements, renderBlock, renderInline, renderInlineElement, renderParagraph, urlTransform, filterElement, tag, contentComponents, renderPresentation, nodeKey, renderComponentPresentation);
101
+ if (node.paragraphRoot && renderParagraph) {
102
+ let paragraph = filterElement ? filterElement(
103
+ { tagName: "p", properties: props, blockType: "paragraph" },
104
+ { source: "markdown", parentTagName },
105
+ () => renderParagraph(children),
106
+ () => children
107
+ ) : renderParagraph(children);
108
+ return import_react.default.createElement(import_react.default.Fragment, { key: nodeKey }, paragraph);
109
+ }
110
+ if (node.inlineNode && renderInlineElement)
111
+ return import_react.default.createElement(import_react.default.Fragment, { key: nodeKey }, renderInlineElement(node.inlineNode, children, parentTagName, nodeKey));
112
+ let renderElement = () => {
113
+ let nativeView;
114
+ if (tag === "textarea")
115
+ props.defaultValue = node.children.map((child) => child.kind === "text" ? child.text : "").join(""), nativeView = import_react.default.createElement(elements[tag] ?? tag, props);
116
+ else {
117
+ let content = tag === "pre" && node.children.every((child) => child.kind === "text" && !child.inline) ? node.children.map((child) => child.kind === "text" ? child.text : "").join("") : children;
118
+ nativeView = import_react.default.createElement(elements[tag] ?? tag, props, node.children.length ? content : void 0);
119
+ }
120
+ return renderPresentation ? renderPresentation(tag, props, nativeView, children, nodeKey) : nativeView;
121
+ };
122
+ return filterElement ? filterElement(
123
+ { tagName: tag, properties: props },
124
+ { source: "html", parentTagName },
125
+ renderElement,
126
+ () => children
127
+ ) : renderElement();
128
+ });
129
+ }
130
+ var BACKTICK_CONTENT = /^`([\s\S]+)`$/, DEFAULT_INLINE_HTML_RENDERERS = {
41
131
  kbd: (descriptor, ctx) => {
42
- const trimmed = descriptor.rawInner.trim();
43
- const match = BACKTICK_CONTENT.exec(trimmed);
132
+ let trimmed = descriptor.rawInner.trim(), match = BACKTICK_CONTENT.exec(trimmed);
44
133
  if (match) {
45
- const codeText = decodeHtmlEntities(match[1]);
46
- const props = mapAttributesToProps(descriptor.attributes);
47
- if (ctx.key !== void 0 && ctx.key !== null) {
48
- props.key = ctx.key;
49
- }
50
- return import_react.default.createElement("kbd", props, import_react.default.createElement("code", { className: "inline-code" }, codeText));
134
+ let codeText = decodeHtmlEntities(match[1]), props = mapAttributesToProps(descriptor.attributes);
135
+ return ctx.key !== void 0 && ctx.key !== null && (props.key = ctx.key), import_react.default.createElement("kbd", props, import_react.default.createElement("code", { className: "inline-code" }, codeText));
51
136
  }
52
137
  return ctx.defaultRender();
53
138
  }
54
139
  };
55
140
  function renderInlineHtmlSegment(raw, sanitized, options = {}) {
56
- const descriptor = parseInlineHtmlDescriptor(raw, sanitized);
57
- if (!descriptor) {
141
+ let descriptor = parseInlineHtmlDescriptor(raw, sanitized);
142
+ if (!descriptor)
58
143
  return null;
59
- }
60
- const className = options.className ?? "markdown-inline-html";
61
- const isInlineTag = INLINE_ELEMENTS.has(descriptor.tagName);
62
- const defaultRender = () => {
63
- if (!descriptor.sanitized || descriptor.sanitized.length === 0) {
64
- if (!descriptor.text) {
65
- return null;
66
- }
67
- if (options.key !== void 0 && options.key !== null) {
68
- return import_react.default.createElement(import_react.default.Fragment, { key: options.key }, descriptor.text);
69
- }
70
- return import_react.default.createElement(import_react.default.Fragment, {}, descriptor.text);
71
- }
144
+ let className = options.className ?? "markdown-inline-html", hasCustomElement = !!options.htmlElements?.[descriptor.tagName], isInlineTag = INLINE_ELEMENTS.has(descriptor.tagName) || hasCustomElement, defaultRender = () => {
145
+ if (!descriptor.sanitized || descriptor.sanitized.length === 0)
146
+ return descriptor.text ? options.key !== void 0 && options.key !== null ? import_react.default.createElement(import_react.default.Fragment, { key: options.key }, descriptor.text) : import_react.default.createElement(import_react.default.Fragment, {}, descriptor.text) : null;
72
147
  if (isInlineTag) {
73
- const parsedElement = renderSanitizedHtmlTree(descriptor.sanitized, options.key);
74
- if (parsedElement) {
148
+ let parsedElement = renderSanitizedHtmlTree(
149
+ descriptor.sanitized,
150
+ options.key,
151
+ options.htmlElements,
152
+ options.literalTagContent,
153
+ options.parseMarkdown
154
+ );
155
+ if (parsedElement)
75
156
  return parsedElement;
76
- }
77
157
  }
78
- const props = {
158
+ let customElementComp = options.htmlElements?.[descriptor.tagName];
159
+ if (customElementComp) {
160
+ let props2 = mapAttributesToProps(descriptor.attributes, options.urlTransform);
161
+ return options.key !== void 0 && options.key !== null && (props2.key = options.key), import_react.default.createElement(customElementComp, props2, descriptor.text || descriptor.sanitizedInner || void 0);
162
+ }
163
+ let props = {
79
164
  className,
80
165
  dangerouslySetInnerHTML: { __html: descriptor.sanitized }
81
166
  };
82
- if (options.key !== void 0 && options.key !== null) {
83
- props.key = options.key;
84
- }
85
- return import_react.default.createElement("span", props);
167
+ return options.key !== void 0 && options.key !== null && (props.key = options.key), import_react.default.createElement("span", props);
86
168
  };
87
- const allRenderers = options.renderers ? { ...DEFAULT_INLINE_HTML_RENDERERS, ...options.renderers } : DEFAULT_INLINE_HTML_RENDERERS;
88
- const renderer = allRenderers[descriptor.tagName];
89
- if (renderer) {
90
- const rendered = renderer(descriptor, { key: options.key, defaultRender });
91
- if (rendered) {
92
- if (options.key !== void 0 && options.key !== null && import_react.default.isValidElement(rendered) && rendered.key === null) {
93
- return import_react.default.cloneElement(rendered, { key: options.key });
94
- }
95
- return rendered;
169
+ if (!hasCustomElement) {
170
+ let renderer = (options.renderers ? { ...DEFAULT_INLINE_HTML_RENDERERS, ...options.renderers } : DEFAULT_INLINE_HTML_RENDERERS)[descriptor.tagName];
171
+ if (renderer) {
172
+ let rendered = renderer(descriptor, { key: options.key, defaultRender });
173
+ if (rendered)
174
+ return options.key !== void 0 && options.key !== null && import_react.default.isValidElement(rendered) && rendered.key === null ? import_react.default.cloneElement(rendered, { key: options.key }) : rendered;
96
175
  }
97
176
  }
98
177
  return defaultRender();
99
178
  }
100
179
  function parseInlineHtmlDescriptor(raw, sanitized) {
101
- const normalizedRaw = typeof raw === "string" ? raw.trim() : "";
102
- const normalizedSanitized = typeof sanitized === "string" && sanitized.length > 0 ? sanitized.trim() : normalizedRaw;
103
- if (!normalizedSanitized) {
104
- return null;
105
- }
106
- const match = normalizedSanitized.match(/^<([A-Za-z][\w:-]*)(\s[^>]*)?>([\s\S]*)<\/\1>$/);
107
- if (!match) {
180
+ let normalizedRaw = typeof raw == "string" ? raw.trim() : "", normalizedSanitized = typeof sanitized == "string" && sanitized.length > 0 ? sanitized.trim() : normalizedRaw;
181
+ if (!normalizedSanitized)
108
182
  return null;
183
+ let pairedMatch = normalizedSanitized.match(/^<([A-Za-z][\w:-]*)((?:\s+[^>]*)?)>([\s\S]*)<\/\1>$/), tagNameRaw, attrString = "", sanitizedInner = "";
184
+ if (pairedMatch)
185
+ tagNameRaw = pairedMatch[1], attrString = pairedMatch[2] ?? "", sanitizedInner = pairedMatch[3] ?? "";
186
+ else {
187
+ let selfClosingMatch = normalizedSanitized.match(/^<([A-Za-z][\w:-]*)((?:\s+[^>]*)?)\s*(?:\/?>|>)$/) || normalizedRaw.match(/^<([A-Za-z][\w:-]*)((?:\s+[^>]*)?)\s*(?:\/?>|>)$/);
188
+ if (!selfClosingMatch)
189
+ return null;
190
+ tagNameRaw = selfClosingMatch[1], attrString = selfClosingMatch[2] ?? "", sanitizedInner = "";
109
191
  }
110
- const [, tagNameRaw, attrString = "", sanitizedInner = ""] = match;
111
- const tagName = tagNameRaw.toLowerCase();
112
- const attributes = parseAttributes(attrString);
113
- let rawInner = "";
192
+ let tagName = tagNameRaw.toLowerCase(), attributes = parseAttributes(attrString), rawInner = "";
114
193
  if (normalizedRaw) {
115
- const rawMatch = normalizedRaw.match(/^<([A-Za-z][\w:-]*)(\s[^>]*)?>([\s\S]*)<\/\1>$/);
194
+ let rawMatch = normalizedRaw.match(/^<([A-Za-z][\w:-]*)(\s[^>]*)?>([\s\S]*)<\/\1>$/);
116
195
  rawInner = rawMatch ? rawMatch[3] ?? "" : normalizedRaw;
117
196
  }
118
- const text = extractPlainText(rawInner || sanitizedInner);
197
+ let text = extractPlainText(rawInner || sanitizedInner);
119
198
  return {
120
199
  tagName,
121
200
  attributes,
@@ -127,52 +206,91 @@ function parseInlineHtmlDescriptor(raw, sanitized) {
127
206
  };
128
207
  }
129
208
  function parseAttributes(input) {
130
- const attrs = {};
209
+ let attrs = {};
131
210
  if (!input) return attrs;
132
- const attrPattern = /([A-Za-z_:][\w:.\-]*)(?:\s*=\s*(?:"([^"]*)"|'([^']*)'|([^\s"'=<>`]+)))?/g;
133
- let match = attrPattern.exec(input);
134
- while (match !== null) {
135
- const name = match[1];
211
+ let attrPattern = /([A-Za-z_:][\w:.\-]*)(?:\s*=\s*(?:"([^"]*)"|'([^']*)'|([^\s"'=<>`]+)))?/g, match = attrPattern.exec(input);
212
+ for (; match !== null; ) {
213
+ let name = match[1];
136
214
  if (!name) continue;
137
- const value = match[2] ?? match[3] ?? match[4] ?? "";
138
- attrs[name] = value;
139
- match = attrPattern.exec(input);
215
+ let value = match[2] ?? match[3] ?? match[4] ?? "";
216
+ attrs[name] = value, match = attrPattern.exec(input);
140
217
  }
141
218
  return attrs;
142
219
  }
143
- function mapAttributesToProps(attrs) {
144
- const props = {};
145
- for (const [key, value] of Object.entries(attrs)) {
146
- if (key === "class") {
147
- props.className = value;
148
- } else if (key === "style") {
149
- props.style = parseStyleAttribute(value);
150
- } else if (key === "tabindex" || key === "tabIndex") {
151
- const normalized = normalizeTabIndex(value);
152
- if (normalized !== void 0) {
153
- props.tabIndex = normalized;
154
- }
155
- } else {
156
- props[key] = value;
157
- }
220
+ var BOOLEAN_HTML_PROPS = {
221
+ allowFullScreen: !0,
222
+ async: !0,
223
+ autoFocus: !0,
224
+ autoPlay: !0,
225
+ checked: !0,
226
+ controls: !0,
227
+ default: !0,
228
+ defer: !0,
229
+ disabled: !0,
230
+ formNoValidate: !0,
231
+ hidden: !0,
232
+ inert: !0,
233
+ loop: !0,
234
+ multiple: !0,
235
+ muted: !0,
236
+ noModule: !0,
237
+ noValidate: !0,
238
+ open: !0,
239
+ playsInline: !0,
240
+ readOnly: !0,
241
+ required: !0,
242
+ reversed: !0,
243
+ selected: !0,
244
+ itemScope: !0
245
+ };
246
+ function mapAttributesToProps(attrs, urlTransform) {
247
+ let props = {}, transform = urlTransform ?? import_core.defaultUrlTransform;
248
+ for (let [key, value] of Object.entries(attrs)) {
249
+ let lower = key.toLowerCase();
250
+ if (!(0, import_core.isForbiddenAttribute)(lower))
251
+ if (key === "class")
252
+ props.className = value;
253
+ else if (key === "style")
254
+ props.style = parseStyleAttribute(value);
255
+ else if (key === "tabindex" || key === "tabIndex") {
256
+ let normalized = normalizeTabIndex(value);
257
+ normalized !== void 0 && (props.tabIndex = normalized);
258
+ } else if (lower === "href") {
259
+ let safe = transform(value, "href", { source: "html" });
260
+ safe != null && (props.href = safe);
261
+ } else if (lower === "src") {
262
+ let safe = transform(value, "src", { source: "html" });
263
+ safe != null && (props.src = safe);
264
+ } else if (lower === "action") {
265
+ let safe = transform(value, "href", { source: "html" });
266
+ safe != null && (props.action = safe);
267
+ } else if (lower === "formaction") {
268
+ let safe = transform(value, "href", { source: "html" });
269
+ safe != null && (props.formAction = safe);
270
+ } else if (lower === "xlink:href" || lower === "xlinkhref") {
271
+ let safe = transform(value, "href", { source: "html" });
272
+ safe != null && (props.xlinkHref = safe);
273
+ } else /^(?:data|aria)[A-Z]/.test(key) ? props[key.replace(/[A-Z]/g, (letter) => `-${letter.toLowerCase()}`)] = value : BOOLEAN_HTML_PROPS[key] ? props[key] = !0 : props[key] = value;
158
274
  }
159
275
  return props;
160
276
  }
161
277
  function parseStyleAttribute(value) {
162
- const style = {};
278
+ let style = {};
163
279
  if (!value) return style;
164
- const pairs = value.split(";");
165
- for (const pair of pairs) {
280
+ let pairs = value.split(";");
281
+ for (let pair of pairs) {
166
282
  if (!pair.trim()) continue;
167
- const [property, rawVal] = pair.split(":");
168
- if (!property || rawVal === void 0) continue;
169
- const camelProp = property.trim().replace(/-([a-z])/g, (_, char) => char.toUpperCase());
170
- style[camelProp] = rawVal.trim();
283
+ let separator = pair.indexOf(":");
284
+ if (separator <= 0) continue;
285
+ let property = pair.slice(0, separator).trim(), rawVal = pair.slice(separator + 1).trim();
286
+ if (!(0, import_core.isSafeStyleDeclaration)(property, rawVal)) continue;
287
+ let camelProp = property.replace(/-([a-z])/g, (_, char) => char.toUpperCase());
288
+ style[camelProp] = rawVal;
171
289
  }
172
290
  return style;
173
291
  }
174
292
  function normalizeTabIndex(value) {
175
- const numeric = Number(value);
293
+ let numeric = Number(value);
176
294
  return Number.isNaN(numeric) ? void 0 : numeric;
177
295
  }
178
296
  function decodeHtmlEntities(value) {
@@ -180,76 +298,50 @@ function decodeHtmlEntities(value) {
180
298
  }
181
299
  function extractPlainText(value) {
182
300
  if (!value) return "";
183
- const withoutTags = value.replace(/<\/?[^>]+>/g, "");
301
+ let withoutTags = value.replace(/<\/?[^>]+>/g, "");
184
302
  return decodeHtmlEntities(withoutTags);
185
303
  }
186
- function renderSanitizedHtmlTree(html, key) {
187
- if (typeof DOMParser === "undefined") {
304
+ var DEFAULT_LITERAL_TAGS = /* @__PURE__ */ new Set(["code", "pre", "script", "style", "textarea"]);
305
+ function renderSanitizedHtmlTree(html, key, htmlElements, literalTagContent, parseMarkdown) {
306
+ if (typeof DOMParser > "u")
188
307
  return null;
189
- }
190
308
  try {
191
- const parser = new DOMParser();
192
- const doc = parser.parseFromString(html, "text/html");
193
- const body = doc.body;
194
- const nodes = Array.from(body.childNodes);
195
- if (nodes.length === 0) {
309
+ let body = new DOMParser().parseFromString(html, "text/html").body, nodes = Array.from(body.childNodes);
310
+ if (nodes.length === 0)
196
311
  return null;
197
- }
198
- const baseKey = typeof key === "string" || typeof key === "number" ? String(key) : "inline-html";
199
- const children = nodes.map((node, index) => convertDomNode(node, `${baseKey}-${index}`)).filter((child) => child !== null && child !== void 0);
200
- if (children.length === 0) {
312
+ let literalTags = literalTagContent ? /* @__PURE__ */ new Set([...DEFAULT_LITERAL_TAGS, ...literalTagContent.map((t) => t.toLowerCase())]) : DEFAULT_LITERAL_TAGS, baseKey = typeof key == "string" || typeof key == "number" ? String(key) : "inline-html", children = nodes.map((node, index) => convertDomNode(node, `${baseKey}-${index}`, htmlElements, literalTags, !1, parseMarkdown)).filter((child) => child != null);
313
+ if (children.length === 0)
201
314
  return null;
202
- }
203
315
  if (children.length === 1) {
204
- const [child] = children;
205
- if (import_react.default.isValidElement(child)) {
206
- if (key !== void 0 && key !== null) {
207
- return import_react.default.cloneElement(child, { key });
208
- }
209
- return child;
210
- }
211
- if (typeof child === "string" || typeof child === "number") {
212
- if (key !== void 0 && key !== null) {
213
- return import_react.default.createElement(import_react.default.Fragment, { key }, child);
214
- }
215
- return import_react.default.createElement(import_react.default.Fragment, {}, child);
216
- }
217
- return import_react.default.createElement(import_react.default.Fragment, { key }, child);
316
+ let [child] = children;
317
+ return import_react.default.isValidElement(child) ? key != null ? import_react.default.cloneElement(child, { key }) : child : typeof child == "string" || typeof child == "number" ? key != null ? import_react.default.createElement(import_react.default.Fragment, { key }, child) : import_react.default.createElement(import_react.default.Fragment, {}, child) : import_react.default.createElement(import_react.default.Fragment, { key }, child);
218
318
  }
219
319
  return import_react.default.createElement(import_react.default.Fragment, { key }, ...children);
220
320
  } catch {
221
321
  return null;
222
322
  }
223
323
  }
224
- function convertDomNode(node, key) {
324
+ function convertDomNode(node, key, htmlElements, literalTags, parentIsLiteral, parseMarkdown) {
225
325
  if (node.nodeType === Node.TEXT_NODE) {
226
- return node.textContent ?? "";
326
+ let rawText = node.textContent ?? "";
327
+ return parentIsLiteral || !parseMarkdown ? rawText : parseMarkdown(rawText);
227
328
  }
228
- if (node.nodeType !== Node.ELEMENT_NODE) {
329
+ if (node.nodeType !== Node.ELEMENT_NODE)
229
330
  return null;
230
- }
231
- const element = node;
232
- const tagName = element.tagName.toLowerCase();
233
- const attrs = getElementAttributes(element);
234
- const props = mapAttributesToProps(attrs);
331
+ let element = node, tagName = element.tagName.toLowerCase(), attrs = getElementAttributes(element), props = mapAttributesToProps(attrs);
235
332
  props.key = key;
236
- const children = [];
333
+ let isLiteral = parentIsLiteral || (literalTags ? literalTags.has(tagName) : !1), children = [];
237
334
  element.childNodes.forEach((child, index) => {
238
- const converted = convertDomNode(child, `${key}-${index}`);
239
- if (converted !== null && converted !== void 0) {
240
- children.push(converted);
241
- }
335
+ let converted = convertDomNode(child, `${key}-${index}`, htmlElements, literalTags, isLiteral, parseMarkdown);
336
+ converted != null && children.push(converted);
242
337
  });
243
- if (children.length === 0) {
244
- return import_react.default.createElement(tagName, props);
245
- }
246
- return import_react.default.createElement(tagName, props, ...children);
338
+ let customComponent = htmlElements?.[tagName];
339
+ return customComponent ? children.length === 0 ? import_react.default.createElement(customComponent, props) : import_react.default.createElement(customComponent, props, ...children) : children.length === 0 ? import_react.default.createElement(tagName, props) : import_react.default.createElement(tagName, props, ...children);
247
340
  }
248
341
  function getElementAttributes(element) {
249
- const attrs = {};
250
- for (const attr of Array.from(element.attributes)) {
342
+ let attrs = {};
343
+ for (let attr of Array.from(element.attributes))
251
344
  attrs[attr.name] = attr.value;
252
- }
253
345
  return attrs;
254
346
  }
255
347
  var INLINE_ELEMENTS = /* @__PURE__ */ new Set([
@@ -259,6 +351,11 @@ var INLINE_ELEMENTS = /* @__PURE__ */ new Set([
259
351
  "bdi",
260
352
  "bdo",
261
353
  "br",
354
+ "img",
355
+ "input",
356
+ "picture",
357
+ "del",
358
+ "ins",
262
359
  "cite",
263
360
  "code",
264
361
  "data",
@@ -305,5 +402,7 @@ var INLINE_ELEMENTS = /* @__PURE__ */ new Set([
305
402
  // Annotate the CommonJS export names for ESM import in node:
306
403
  0 && (module.exports = {
307
404
  DEFAULT_INLINE_HTML_RENDERERS,
405
+ renderHtmlInlineNode,
406
+ renderHtmlOwnershipTree,
308
407
  renderInlineHtmlSegment
309
408
  });
@@ -1,13 +1,46 @@
1
- import React from 'react';
2
- import { I as InlineHtmlRendererMap } from '../index-D2MYusAM.cjs';
3
- import '@stream-mdx/core';
1
+ import React__default from 'react';
2
+ import { UrlTransform, InlineNode, HtmlTreeNode } from '@stream-mdx/core';
3
+ import { I as InlineHtmlRendererMap, H as HtmlElements, C as ContentComponentsMap } from '../index-Cmne1yUK.cjs';
4
+ import '../components/bottom-stick-scroll-area.cjs';
5
+ import 'react/jsx-runtime';
6
+ import '../components/diff-renderer.cjs';
7
+ import '@stream-mdx/protocol';
8
+ import '../trusted-mdx-contract-ElKpkDI5.cjs';
9
+ import '@stream-mdx/worker/engine';
10
+ import '../renderer/virtualized-code.cjs';
4
11
 
5
12
  interface RenderInlineHtmlOptions {
6
- key?: React.Key;
13
+ key?: React__default.Key;
7
14
  renderers?: InlineHtmlRendererMap;
8
15
  className?: string;
16
+ htmlElements?: HtmlElements;
17
+ literalTagContent?: string[];
18
+ parseMarkdown?: (text: string) => React__default.ReactNode;
19
+ urlTransform?: UrlTransform;
9
20
  }
21
+ /** Render only the sanitized attributes supplied by the engine, with parsed children intact. */
22
+ declare function renderHtmlInlineNode(node: Omit<Extract<InlineNode, {
23
+ kind: "html";
24
+ }>, "children">, children: React__default.ReactNode, elements?: HtmlElements, key?: React__default.Key, textValue?: string, urlTransform?: UrlTransform, filterElement?: (element: {
25
+ tagName: string;
26
+ properties: Record<string, unknown>;
27
+ blockType?: string;
28
+ }, context: {
29
+ source: "markdown" | "html";
30
+ parentTagName?: string;
31
+ }, renderElement: () => React__default.ReactNode, renderChildren?: () => React__default.ReactNode) => React__default.ReactNode, parentTagName?: string, renderPresentation?: (tagName: string, properties: Readonly<Record<string, unknown>>, nativeView: React__default.ReactNode, children: React__default.ReactNode, key: React__default.Key) => React__default.ReactNode, renderNativeElement?: (tagName: string, properties: Readonly<Record<string, unknown>>, children: React__default.ReactNode, key: React__default.Key) => React__default.ReactNode): React__default.ReactNode;
32
+ type RenderComponentPresentation = (name: string, nativeView: React__default.ReactElement, children: React__default.ReactNode, key: React__default.Key, status: "open" | "closed" | "incomplete", rawSource?: string) => React__default.ReactNode;
33
+ declare function renderHtmlOwnershipTree(nodes: HtmlTreeNode[], elements: HtmlElements, renderBlock: (block: Extract<HtmlTreeNode, {
34
+ kind: "block";
35
+ }>["block"], parentTagName?: string) => React__default.ReactNode, renderInline?: (nodes: InlineNode[], parentTagName?: string) => React__default.ReactNode, renderInlineElement?: (node: InlineNode, children: React__default.ReactNode, parentTagName: string | undefined, key: React__default.Key) => React__default.ReactNode, renderParagraph?: (children: React__default.ReactNode) => React__default.ReactNode, urlTransform?: UrlTransform, filterElement?: (element: {
36
+ tagName: string;
37
+ properties: Record<string, unknown>;
38
+ blockType?: string;
39
+ }, context: {
40
+ source: "markdown" | "html";
41
+ parentTagName?: string;
42
+ }, renderElement: () => React__default.ReactNode, renderChildren?: () => React__default.ReactNode) => React__default.ReactNode, parentTagName?: string, contentComponents?: ContentComponentsMap, renderPresentation?: (tagName: string, properties: Readonly<Record<string, unknown>>, nativeView: React__default.ReactNode, children: React__default.ReactNode, key: React__default.Key) => React__default.ReactNode, parentPath?: string, renderComponentPresentation?: RenderComponentPresentation): React__default.ReactNode;
10
43
  declare const DEFAULT_INLINE_HTML_RENDERERS: InlineHtmlRendererMap;
11
- declare function renderInlineHtmlSegment(raw: string | undefined, sanitized: string | undefined, options?: RenderInlineHtmlOptions): React.ReactElement | null;
44
+ declare function renderInlineHtmlSegment(raw: string | undefined, sanitized: string | undefined, options?: RenderInlineHtmlOptions): React__default.ReactElement | null;
12
45
 
13
- export { DEFAULT_INLINE_HTML_RENDERERS, type RenderInlineHtmlOptions, renderInlineHtmlSegment };
46
+ export { DEFAULT_INLINE_HTML_RENDERERS, type RenderComponentPresentation, type RenderInlineHtmlOptions, renderHtmlInlineNode, renderHtmlOwnershipTree, renderInlineHtmlSegment };
@@ -1,13 +1,46 @@
1
- import React from 'react';
2
- import { I as InlineHtmlRendererMap } from '../index-D2MYusAM.js';
3
- import '@stream-mdx/core';
1
+ import React__default from 'react';
2
+ import { UrlTransform, InlineNode, HtmlTreeNode } from '@stream-mdx/core';
3
+ import { I as InlineHtmlRendererMap, H as HtmlElements, C as ContentComponentsMap } from '../index-D7dyyu3q.js';
4
+ import '../components/bottom-stick-scroll-area.js';
5
+ import 'react/jsx-runtime';
6
+ import '../components/diff-renderer.js';
7
+ import '@stream-mdx/protocol';
8
+ import '../trusted-mdx-contract-ElKpkDI5.js';
9
+ import '@stream-mdx/worker/engine';
10
+ import '../renderer/virtualized-code.js';
4
11
 
5
12
  interface RenderInlineHtmlOptions {
6
- key?: React.Key;
13
+ key?: React__default.Key;
7
14
  renderers?: InlineHtmlRendererMap;
8
15
  className?: string;
16
+ htmlElements?: HtmlElements;
17
+ literalTagContent?: string[];
18
+ parseMarkdown?: (text: string) => React__default.ReactNode;
19
+ urlTransform?: UrlTransform;
9
20
  }
21
+ /** Render only the sanitized attributes supplied by the engine, with parsed children intact. */
22
+ declare function renderHtmlInlineNode(node: Omit<Extract<InlineNode, {
23
+ kind: "html";
24
+ }>, "children">, children: React__default.ReactNode, elements?: HtmlElements, key?: React__default.Key, textValue?: string, urlTransform?: UrlTransform, filterElement?: (element: {
25
+ tagName: string;
26
+ properties: Record<string, unknown>;
27
+ blockType?: string;
28
+ }, context: {
29
+ source: "markdown" | "html";
30
+ parentTagName?: string;
31
+ }, renderElement: () => React__default.ReactNode, renderChildren?: () => React__default.ReactNode) => React__default.ReactNode, parentTagName?: string, renderPresentation?: (tagName: string, properties: Readonly<Record<string, unknown>>, nativeView: React__default.ReactNode, children: React__default.ReactNode, key: React__default.Key) => React__default.ReactNode, renderNativeElement?: (tagName: string, properties: Readonly<Record<string, unknown>>, children: React__default.ReactNode, key: React__default.Key) => React__default.ReactNode): React__default.ReactNode;
32
+ type RenderComponentPresentation = (name: string, nativeView: React__default.ReactElement, children: React__default.ReactNode, key: React__default.Key, status: "open" | "closed" | "incomplete", rawSource?: string) => React__default.ReactNode;
33
+ declare function renderHtmlOwnershipTree(nodes: HtmlTreeNode[], elements: HtmlElements, renderBlock: (block: Extract<HtmlTreeNode, {
34
+ kind: "block";
35
+ }>["block"], parentTagName?: string) => React__default.ReactNode, renderInline?: (nodes: InlineNode[], parentTagName?: string) => React__default.ReactNode, renderInlineElement?: (node: InlineNode, children: React__default.ReactNode, parentTagName: string | undefined, key: React__default.Key) => React__default.ReactNode, renderParagraph?: (children: React__default.ReactNode) => React__default.ReactNode, urlTransform?: UrlTransform, filterElement?: (element: {
36
+ tagName: string;
37
+ properties: Record<string, unknown>;
38
+ blockType?: string;
39
+ }, context: {
40
+ source: "markdown" | "html";
41
+ parentTagName?: string;
42
+ }, renderElement: () => React__default.ReactNode, renderChildren?: () => React__default.ReactNode) => React__default.ReactNode, parentTagName?: string, contentComponents?: ContentComponentsMap, renderPresentation?: (tagName: string, properties: Readonly<Record<string, unknown>>, nativeView: React__default.ReactNode, children: React__default.ReactNode, key: React__default.Key) => React__default.ReactNode, parentPath?: string, renderComponentPresentation?: RenderComponentPresentation): React__default.ReactNode;
10
43
  declare const DEFAULT_INLINE_HTML_RENDERERS: InlineHtmlRendererMap;
11
- declare function renderInlineHtmlSegment(raw: string | undefined, sanitized: string | undefined, options?: RenderInlineHtmlOptions): React.ReactElement | null;
44
+ declare function renderInlineHtmlSegment(raw: string | undefined, sanitized: string | undefined, options?: RenderInlineHtmlOptions): React__default.ReactElement | null;
12
45
 
13
- export { DEFAULT_INLINE_HTML_RENDERERS, type RenderInlineHtmlOptions, renderInlineHtmlSegment };
46
+ export { DEFAULT_INLINE_HTML_RENDERERS, type RenderComponentPresentation, type RenderInlineHtmlOptions, renderHtmlInlineNode, renderHtmlOwnershipTree, renderInlineHtmlSegment };