@ai-react-markdown/core 1.0.0 → 1.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -34,15 +34,18 @@ __export(index_exports, {
34
34
  AIMarkdownRenderDisplayOptimizeAbility: () => AIMarkdownRenderDisplayOptimizeAbility,
35
35
  AIMarkdownRenderExtraSyntax: () => AIMarkdownRenderExtraSyntax,
36
36
  default: () => index_default,
37
- useAIMarkdownRenderState: () => useAIMarkdownRenderState
37
+ defaultAIMarkdownRenderConfig: () => defaultAIMarkdownRenderConfig,
38
+ useAIMarkdownMetadata: () => useAIMarkdownMetadata,
39
+ useAIMarkdownRenderState: () => useAIMarkdownRenderState,
40
+ useStableValue: () => useStableValue
38
41
  });
39
42
  module.exports = __toCommonJS(index_exports);
40
43
  var import_react5 = require("react");
41
44
 
42
45
  // src/context.tsx
43
46
  var import_react = require("react");
44
- var import_cloneDeep = __toESM(require("lodash/cloneDeep"), 1);
45
- var import_mergeWith = __toESM(require("lodash/mergeWith"), 1);
47
+ var import_cloneDeep = __toESM(require("lodash-es/cloneDeep"), 1);
48
+ var import_mergeWith = __toESM(require("lodash-es/mergeWith"), 1);
46
49
 
47
50
  // src/defs.ts
48
51
  var AIMarkdownRenderExtraSyntax = /* @__PURE__ */ ((AIMarkdownRenderExtraSyntax2) => {
@@ -57,22 +60,23 @@ var AIMarkdownRenderDisplayOptimizeAbility = /* @__PURE__ */ ((AIMarkdownRenderD
57
60
  AIMarkdownRenderDisplayOptimizeAbility2["PANGU"] = "PANGU";
58
61
  return AIMarkdownRenderDisplayOptimizeAbility2;
59
62
  })(AIMarkdownRenderDisplayOptimizeAbility || {});
60
- var defaultMRMarkdownRenderConfig = {
61
- extraSyntaxSupported: [
63
+ var defaultAIMarkdownRenderConfig = Object.freeze({
64
+ extraSyntaxSupported: Object.freeze([
62
65
  "HIGHLIGHT" /* HIGHLIGHT */,
63
66
  "DEFINITION_LIST" /* DEFINITION_LIST */,
64
67
  "SUBSCRIPT" /* SUBSCRIPT */
65
- ],
66
- displayOptimizeAbilities: [
68
+ ]),
69
+ displayOptimizeAbilities: Object.freeze([
67
70
  "REMOVE_COMMENTS" /* REMOVE_COMMENTS */,
68
71
  "SMARTYPANTS" /* SMARTYPANTS */,
69
72
  "PANGU" /* PANGU */
70
- ]
71
- };
73
+ ])
74
+ });
72
75
 
73
76
  // src/context.tsx
74
77
  var import_jsx_runtime = require("react/jsx-runtime");
75
78
  var AIMarkdownRenderStateContext = (0, import_react.createContext)(null);
79
+ var AIMarkdownMetadataContext = (0, import_react.createContext)(void 0);
76
80
  function useAIMarkdownRenderState() {
77
81
  const context = (0, import_react.useContext)(AIMarkdownRenderStateContext);
78
82
  if (!context) {
@@ -80,51 +84,70 @@ function useAIMarkdownRenderState() {
80
84
  }
81
85
  return context;
82
86
  }
87
+ function useAIMarkdownMetadata() {
88
+ return (0, import_react.useContext)(AIMarkdownMetadataContext);
89
+ }
83
90
  var configMergeCustomizer = (_objValue, srcValue, _key, _object, _source, _stack) => {
84
91
  if (Array.isArray(srcValue)) {
85
92
  return srcValue;
86
93
  }
87
94
  };
95
+ var AIMarkdownMetadataProvider = ({
96
+ metadata,
97
+ children
98
+ }) => {
99
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(AIMarkdownMetadataContext.Provider, { value: metadata, children });
100
+ };
88
101
  var AIMarkdownRenderStateProvider = ({
89
102
  streaming,
90
103
  fontSize,
104
+ variant,
105
+ colorScheme,
106
+ defaultConfig,
91
107
  config,
92
- metadata,
93
108
  children
94
109
  }) => {
110
+ const baseConfig = defaultConfig ?? defaultAIMarkdownRenderConfig;
95
111
  const mergedConfig = (0, import_react.useMemo)(
96
- () => config ? (0, import_mergeWith.default)((0, import_cloneDeep.default)(defaultMRMarkdownRenderConfig), config, configMergeCustomizer) : defaultMRMarkdownRenderConfig,
97
- [config]
112
+ () => config ? (0, import_mergeWith.default)((0, import_cloneDeep.default)(baseConfig), config, configMergeCustomizer) : baseConfig,
113
+ [baseConfig, config]
98
114
  );
99
115
  const state = (0, import_react.useMemo)(
100
- () => ({
116
+ () => Object.freeze({
101
117
  streaming,
102
118
  fontSize,
103
- config: mergedConfig,
104
- metadata
119
+ variant,
120
+ colorScheme,
121
+ config: mergedConfig
105
122
  }),
106
- [streaming, fontSize, mergedConfig, metadata]
123
+ [streaming, fontSize, variant, colorScheme, mergedConfig]
107
124
  );
108
125
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(AIMarkdownRenderStateContext.Provider, { value: state, children });
109
126
  };
110
127
  var context_default = AIMarkdownRenderStateProvider;
111
128
 
112
129
  // src/preprocessors/latex.ts
113
- function escapeMhchemCommands(text) {
114
- return text.replaceAll("$\\ce{", "$\\\\ce{").replaceAll("$\\pu{", "$\\\\pu{");
115
- }
116
- function findCodeBlockRegions(content) {
117
- const regions = [];
130
+ function splitByProtectedRegions(content) {
131
+ const segments = [];
132
+ let lastIndex = 0;
118
133
  let inlineStart = -1;
119
134
  let multilineStart = -1;
135
+ function pushProtected(start, end) {
136
+ if (start > lastIndex) {
137
+ segments.push({ text: content.substring(lastIndex, start), isCode: false });
138
+ }
139
+ segments.push({ text: content.substring(start, end), isCode: true });
140
+ lastIndex = end;
141
+ }
120
142
  for (let i = 0; i < content.length; i++) {
121
143
  const char = content[i];
122
144
  if (char === "`" && i + 2 < content.length && content[i + 1] === "`" && content[i + 2] === "`") {
123
145
  if (multilineStart === -1) {
146
+ inlineStart = -1;
124
147
  multilineStart = i;
125
148
  i += 2;
126
149
  } else {
127
- regions.push([multilineStart, i + 2]);
150
+ pushProtected(multilineStart, i + 3);
128
151
  multilineStart = -1;
129
152
  i += 2;
130
153
  }
@@ -132,43 +155,71 @@ function findCodeBlockRegions(content) {
132
155
  if (inlineStart === -1) {
133
156
  inlineStart = i;
134
157
  } else {
135
- regions.push([inlineStart, i]);
158
+ pushProtected(inlineStart, i + 1);
136
159
  inlineStart = -1;
137
160
  }
161
+ } else if (char === "<" && multilineStart === -1 && inlineStart === -1) {
162
+ const rest = content.substring(i);
163
+ const tagMatch = rest.match(
164
+ /^<\/?(span|div|p|br|hr|img|a|em|strong|b|i|u|s|sub|sup|code|pre|table|tr|td|th|thead|tbody|tfoot|ul|ol|li|dl|dt|dd|h[1-6]|blockquote|details|summary|figure|figcaption|section|article|aside|nav|header|footer|main|mark|del|ins|small|abbr|cite|dfn|kbd|samp|var|ruby|rt|rp|bdo|wbr|input|button|select|textarea|label|fieldset|legend|output|iframe|video|audio|source|canvas|svg|math|time)(?:\s[^>]*)?\/?>/i
165
+ );
166
+ if (tagMatch) {
167
+ pushProtected(i, i + tagMatch[0].length);
168
+ i += tagMatch[0].length - 1;
169
+ }
138
170
  }
139
171
  }
140
- return regions;
141
- }
142
- function isInCodeBlock(position, codeRegions) {
143
- let left = 0;
144
- let right = codeRegions.length - 1;
145
- while (left <= right) {
146
- const mid = Math.floor((left + right) / 2);
147
- const [start, end] = codeRegions[mid];
148
- if (position >= start && position <= end) {
149
- return true;
150
- } else if (position < start) {
151
- right = mid - 1;
152
- } else {
153
- left = mid + 1;
154
- }
172
+ if (lastIndex < content.length) {
173
+ segments.push({ text: content.substring(lastIndex), isCode: false });
155
174
  }
156
- return false;
175
+ return segments;
176
+ }
177
+ function escapeMhchemCommands(text) {
178
+ return text.replaceAll("$\\ce{", "$\\\\ce{").replaceAll("$\\pu{", "$\\\\pu{");
157
179
  }
158
180
  var CURRENCY_REGEX = /(?<![\\$])\$(?!\$)(?=\d+(?:,\d{3})*(?:\.\d+)?(?:[KMBkmb])?(?:\s|$|[^a-zA-Z\d]))/g;
159
181
  var NO_ESCAPED_DOLLAR_REGEX = /(?<![\\$])\$(?!\$)/g;
160
- var DELIMITERS_REGEX = /\\\[([\S\s]*?[^\\])\\]|\\\((.*?)\\\)/g;
161
- var UNESCAPED_PIPES_REGEX = /(?<!\\)\|/g;
162
- var LATEX_BLOCK_REGEX = /\$\$([\S\s]*?)\$\$|(?<![\\$])\$(?!\$)((?:.|\n)*?)(?<![\\`])\$(?!\$)/g;
182
+ var DELIMITERS_REGEX = /(?<!!)\\\[([\S\s]*?[^\\])\\](?!\()|\\\((.*?)\\\)/g;
183
+ var ARRAY_COL_SPEC_OR_PIPE_REGEX = /(\\begin\{(?:array|tabular[x*]?)\}\{[^}]*\})|(?<!\\)\|/g;
184
+ var LATEX_BLOCK_REGEX = /\$\$([\S\s]*?)\$\$|(?<![\\$])\$(?!\$)((?:[^$\n]|\\\$)*?)(?<![\\`])\$(?!\$)/g;
163
185
  var ESCAPE_TEXT_UNDERSCORES_REGEX = /\\text{([^}]*)}/g;
164
186
  var SINGLE_DOLLAR_REGEX = /(?<![\\$])\$(?!\$)((?:[^$\n]|\\[$])+?)(?<!\\)(?<!`)\$(?!\$)/g;
165
- function convertLatexDelimiters(text, codeRegions) {
187
+ function escapeCurrencyDollarSigns(text) {
188
+ const parts = [];
189
+ let lastIndex = 0;
190
+ const currencyMatches = Array.from(text.matchAll(CURRENCY_REGEX));
191
+ for (let i = 0; i < currencyMatches.length; i++) {
192
+ const match = currencyMatches[i];
193
+ parts.push(text.substring(lastIndex, match.index));
194
+ let needEscape = true;
195
+ let restBeforeNextMatchOrEnd = "";
196
+ if (i < currencyMatches.length - 1) {
197
+ const nextMatch = currencyMatches[i + 1];
198
+ if (nextMatch.index - match.index > 1) {
199
+ restBeforeNextMatchOrEnd = text.substring(match.index + 1, nextMatch.index);
200
+ }
201
+ } else {
202
+ restBeforeNextMatchOrEnd = text.substring(match.index + 1);
203
+ }
204
+ const firstLineBeforeNextMatch = restBeforeNextMatchOrEnd.split(/\r\n|\r|\n/g)[0];
205
+ if (Array.from(firstLineBeforeNextMatch.matchAll(NO_ESCAPED_DOLLAR_REGEX)).length % 2 !== 0) {
206
+ const previousNewContent = parts.join("");
207
+ const previousLastLineContent = previousNewContent.split(/\r\n|\r|\n/g).pop();
208
+ const wholeLineBeforeNextMatchWithoutCurrentDollar = previousLastLineContent + firstLineBeforeNextMatch;
209
+ if (Array.from(wholeLineBeforeNextMatchWithoutCurrentDollar.matchAll(NO_ESCAPED_DOLLAR_REGEX)).length % 2 !== 0) {
210
+ needEscape = false;
211
+ }
212
+ }
213
+ parts.push(needEscape ? "\\$" : "$");
214
+ lastIndex = match.index + 1;
215
+ }
216
+ parts.push(text.substring(lastIndex));
217
+ return parts.join("");
218
+ }
219
+ function convertLatexDelimiters(text) {
166
220
  return text.replaceAll(
167
221
  DELIMITERS_REGEX,
168
- (match, squareBracket, roundBracket, index) => {
169
- if (isInCodeBlock(index, codeRegions)) {
170
- return match;
171
- }
222
+ (match, squareBracket, roundBracket) => {
172
223
  if (squareBracket !== void 0) {
173
224
  return `$$${squareBracket}$$`;
174
225
  } else if (roundBracket !== void 0) {
@@ -179,83 +230,43 @@ function convertLatexDelimiters(text, codeRegions) {
179
230
  );
180
231
  }
181
232
  var replaceUnescapedPipes = (formula) => (
182
- // Use \vert{} so the control sequence terminates before the next token
183
- formula.replaceAll(UNESCAPED_PIPES_REGEX, "\\vert{}")
233
+ // Use \vert{} so the control sequence terminates before the next token.
234
+ // Preserve `|` inside \begin{array}{...} / \begin{tabular}{...} column specifiers.
235
+ formula.replaceAll(
236
+ ARRAY_COL_SPEC_OR_PIPE_REGEX,
237
+ (match, colSpec) => colSpec !== void 0 ? match : "\\vert{}"
238
+ )
184
239
  );
185
- function escapeLatexPipes(text, codeRegions) {
186
- return text.replaceAll(LATEX_BLOCK_REGEX, (match, display, inline, index) => {
187
- if (isInCodeBlock(index, codeRegions)) {
188
- return match;
189
- }
240
+ function escapeLatexPipes(text) {
241
+ return text.replaceAll(LATEX_BLOCK_REGEX, (match, display, inline) => {
190
242
  if (display !== void 0) return `$$${replaceUnescapedPipes(display)}$$`;
191
243
  if (inline !== void 0) return `$${replaceUnescapedPipes(inline)}$`;
192
244
  return match;
193
245
  });
194
246
  }
195
- function escapeTextUnderscores(text, codeRegions) {
196
- return text.replaceAll(ESCAPE_TEXT_UNDERSCORES_REGEX, (match, textContent, index) => {
197
- if (isInCodeBlock(index, codeRegions)) {
198
- return match;
199
- }
247
+ function escapeTextUnderscores(text) {
248
+ return text.replaceAll(ESCAPE_TEXT_UNDERSCORES_REGEX, (_match, textContent) => {
200
249
  const escapedTextContent = textContent.replaceAll(/(?<!\\)_/g, "\\_");
201
250
  return `\\text{${escapedTextContent}}`;
202
251
  });
203
252
  }
253
+ function convertSingleToDoubleDollar(text) {
254
+ return text.replaceAll(SINGLE_DOLLAR_REGEX, (_match, content) => `$$${content}$$`);
255
+ }
204
256
  function preprocessLaTeX(str) {
205
257
  if (!str.includes("$") && !str.includes("\\[") && !str.includes("\\(")) return str;
206
- let processed = str;
207
- processed = escapeMhchemCommands(processed);
208
- const codeRegions = findCodeBlockRegions(processed);
209
- const parts = [];
210
- let lastIndex = 0;
211
- const currencyMatchesIterator = processed.matchAll(CURRENCY_REGEX);
212
- const currencyMatches = Array.from(currencyMatchesIterator);
213
- for (let i = 0; i < currencyMatches.length; i++) {
214
- const match = currencyMatches[i];
215
- parts.push(processed.substring(lastIndex, match.index));
216
- let needEscape = true;
217
- if (!isInCodeBlock(match.index, codeRegions)) {
218
- let restBeforeNextMatchOrEnd = "";
219
- if (i < currencyMatches.length - 1) {
220
- const nextMatch = currencyMatches[i + 1];
221
- if (nextMatch.index - match.index > 1) {
222
- restBeforeNextMatchOrEnd = processed.substring(match.index + 1, nextMatch.index);
223
- }
224
- } else {
225
- restBeforeNextMatchOrEnd = processed.substring(match.index + 1, processed.length);
226
- }
227
- const firstLineBeforeNextMatch = restBeforeNextMatchOrEnd.split(/\r\n|\r|\n/g)[0];
228
- if (Array.from(firstLineBeforeNextMatch.matchAll(NO_ESCAPED_DOLLAR_REGEX)).length % 2 !== 0) {
229
- const previousNewCotent = parts.join("");
230
- const previousLastLineContent = previousNewCotent.split(/\r\n|\r|\n/g).pop();
231
- const wholeLineBeforeNextMatchWithoutCurrentDollar = previousLastLineContent + firstLineBeforeNextMatch;
232
- if (Array.from(wholeLineBeforeNextMatchWithoutCurrentDollar.matchAll(NO_ESCAPED_DOLLAR_REGEX)).length % 2 !== 0) {
233
- needEscape = false;
234
- }
235
- }
236
- } else {
237
- needEscape = false;
238
- }
239
- parts.push(needEscape ? "\\$" : "$");
240
- lastIndex = match.index + 1;
241
- }
242
- parts.push(processed.substring(lastIndex));
243
- processed = parts.join("");
244
- console.log("processed", processed);
245
- processed = convertLatexDelimiters(processed, codeRegions);
246
- processed = escapeLatexPipes(processed, codeRegions);
247
- processed = escapeTextUnderscores(processed, codeRegions);
248
- const result = [];
249
- lastIndex = 0;
250
- const singleDollarMatchesIterator = processed.matchAll(SINGLE_DOLLAR_REGEX);
251
- for (const match of singleDollarMatchesIterator) {
252
- if (!isInCodeBlock(match.index, codeRegions)) {
253
- result.push(processed.substring(lastIndex, match.index));
254
- result.push(`$$${match[1]}$$`);
255
- lastIndex = match.index + match[0].length;
256
- }
257
- }
258
- result.push(processed.substring(lastIndex));
258
+ const segments = splitByProtectedRegions(str);
259
+ const result = segments.map((segment) => {
260
+ if (segment.isCode) return segment.text;
261
+ let text = segment.text;
262
+ text = escapeMhchemCommands(text);
263
+ text = escapeCurrencyDollarSigns(text);
264
+ text = convertLatexDelimiters(text);
265
+ text = escapeLatexPipes(text);
266
+ text = escapeTextUnderscores(text);
267
+ text = convertSingleToDoubleDollar(text);
268
+ return text;
269
+ });
259
270
  return result.join("");
260
271
  }
261
272
 
@@ -319,28 +330,36 @@ var AIMarkdownContent = (0, import_react2.memo)(({ content, customComponents })
319
330
  import_react_markdown.default,
320
331
  {
321
332
  remarkPlugins: [
333
+ // --- Core plugins (always active) ---
322
334
  import_remark_gfm.default,
323
335
  [
324
336
  import_remark_math.default,
325
337
  {
338
+ // Disable single-dollar inline math to avoid conflicts with currency
339
+ // signs and other dollar usages; the preprocessor converts $...$ to $$...$$.
326
340
  singleDollarTextMath: false
327
341
  }
328
342
  ],
343
+ // --- Configurable extra syntax plugins ---
329
344
  ...extraSyntaxRemarkPlugins,
345
+ // --- Formatting & normalization ---
330
346
  import_remark_breaks.default,
331
347
  import_remark_emoji.default,
332
348
  import_remark_squeeze_paragraphs.default,
333
349
  import_remark_cjk_friendly.default,
334
350
  import_remark_cjk_friendly_gfm_strikethrough.default,
351
+ // --- Configurable display optimizations ---
335
352
  ...displayOptimizeRemarkPlugins
336
353
  ],
337
354
  rehypePlugins: [
355
+ // Allow raw HTML through so rehype-sanitize can handle it.
338
356
  [
339
357
  import_rehype_raw.default,
340
358
  {
341
359
  passThrough: []
342
360
  }
343
361
  ],
362
+ // Sanitize HTML while allowing <mark> (highlight) and KaTeX class names.
344
363
  [
345
364
  import_rehype_sanitize.default,
346
365
  {
@@ -359,6 +378,7 @@ var AIMarkdownContent = (0, import_react2.memo)(({ content, customComponents })
359
378
  remarkRehypeOptions: {
360
379
  allowDangerousHtml: true,
361
380
  handlers: {
381
+ // Inject definition-list HAST handlers when the extension is active.
362
382
  ...enableDefinitionList ? import_remark_definition_list.defListHastHandlers : {}
363
383
  }
364
384
  },
@@ -372,7 +392,7 @@ var MarkdownContent_default = AIMarkdownContent;
372
392
 
373
393
  // src/hooks/useStableValue.ts
374
394
  var import_react3 = require("react");
375
- var import_isEqual = __toESM(require("lodash/isEqual"), 1);
395
+ var import_isEqual = __toESM(require("lodash-es/isEqual"), 1);
376
396
  function useStableValue(value) {
377
397
  const ref = (0, import_react3.useRef)(value);
378
398
  const prev = ref.current;
@@ -405,14 +425,16 @@ var AIMarkdownComponent = ({
405
425
  fontSize,
406
426
  contentPreprocessors,
407
427
  customComponents,
428
+ defaultConfig,
408
429
  config,
409
430
  metadata,
410
- typography: Typography = Default_default,
411
- extraStyle: ExtraStyle,
431
+ Typography = Default_default,
432
+ ExtraStyles,
412
433
  variant = "default",
413
434
  colorScheme = "light"
414
435
  }) => {
415
436
  const usedFontSize = fontSize ? typeof fontSize === "number" ? `${fontSize}px` : fontSize : "0.875rem";
437
+ const stableDefaultConfig = useStableValue(defaultConfig);
416
438
  const stableConfig = useStableValue(config);
417
439
  const stablePreprocessors = useStableValue(contentPreprocessors);
418
440
  const stableCustomComponents = useStableValue(customComponents);
@@ -420,16 +442,18 @@ var AIMarkdownComponent = ({
420
442
  () => content ? preprocessAIMDContent(content, stablePreprocessors) : content,
421
443
  [content, stablePreprocessors]
422
444
  );
423
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
445
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(AIMarkdownMetadataProvider, { metadata, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
424
446
  context_default,
425
447
  {
426
448
  streaming,
427
449
  fontSize: usedFontSize,
450
+ variant,
451
+ colorScheme,
452
+ defaultConfig: stableDefaultConfig,
428
453
  config: stableConfig,
429
- metadata,
430
- children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Typography, { fontSize: usedFontSize, variant, colorScheme, children: ExtraStyle ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(ExtraStyle, { children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(MarkdownContent_default, { content: usedContent, customComponents: stableCustomComponents }) }) : /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(MarkdownContent_default, { content: usedContent, customComponents: stableCustomComponents }) })
454
+ children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Typography, { fontSize: usedFontSize, variant, colorScheme, children: ExtraStyles ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(ExtraStyles, { children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(MarkdownContent_default, { content: usedContent, customComponents: stableCustomComponents }) }) : /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(MarkdownContent_default, { content: usedContent, customComponents: stableCustomComponents }) })
431
455
  }
432
- );
456
+ ) });
433
457
  };
434
458
  var AIMarkdown = (0, import_react5.memo)(AIMarkdownComponent);
435
459
  AIMarkdown.displayName = "AIMarkdown";
@@ -438,6 +462,9 @@ var index_default = AIMarkdown;
438
462
  0 && (module.exports = {
439
463
  AIMarkdownRenderDisplayOptimizeAbility,
440
464
  AIMarkdownRenderExtraSyntax,
441
- useAIMarkdownRenderState
465
+ defaultAIMarkdownRenderConfig,
466
+ useAIMarkdownMetadata,
467
+ useAIMarkdownRenderState,
468
+ useStableValue
442
469
  });
443
470
  //# sourceMappingURL=index.cjs.map