@stream-mdx/core 0.0.3 → 0.1.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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # @stream-mdx/core
2
2
 
3
+ ## 0.1.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 294e557: Release StreamMDX 0.1.0 across all published packages.
8
+
3
9
  ## 0.0.3
4
10
 
5
11
  ### Patch Changes
package/dist/index.cjs CHANGED
@@ -72,6 +72,7 @@ __export(index_exports, {
72
72
  inlineNodesToPlainText: () => inlineNodesToPlainText,
73
73
  isLikelyMdxComponent: () => isLikelyMdxComponent,
74
74
  normalizeBlockquoteText: () => normalizeBlockquoteText,
75
+ normalizeFormatAnticipation: () => normalizeFormatAnticipation,
75
76
  normalizeLang: () => normalizeLang,
76
77
  parseCodeFenceInfo: () => parseCodeFenceInfo,
77
78
  prepareInlineStreamingContent: () => prepareInlineStreamingContent,
@@ -290,6 +291,36 @@ function filterAllowedAttributes(attrs) {
290
291
  }
291
292
 
292
293
  // src/inline-parser.ts
294
+ function ensureGlobal(pattern) {
295
+ if (pattern.global) return pattern;
296
+ const flags = pattern.flags.includes("g") ? pattern.flags : `${pattern.flags}g`;
297
+ return new RegExp(pattern.source, flags);
298
+ }
299
+ function findLastMatch(pattern, value) {
300
+ const re = ensureGlobal(pattern);
301
+ let match = null;
302
+ let next;
303
+ while ((next = re.exec(value)) !== null) {
304
+ match = next;
305
+ }
306
+ return match;
307
+ }
308
+ function findMatchAfter(pattern, value, startIndex) {
309
+ const re = ensureGlobal(pattern);
310
+ re.lastIndex = Math.max(0, startIndex);
311
+ return re.exec(value);
312
+ }
313
+ function isSamePattern(a, b) {
314
+ return a.source === b.source && a.flags === b.flags;
315
+ }
316
+ function countMatches(pattern, value) {
317
+ const re = ensureGlobal(pattern);
318
+ let count = 0;
319
+ while (re.exec(value)) {
320
+ count += 1;
321
+ }
322
+ return count;
323
+ }
293
324
  var InlineParser = class {
294
325
  constructor(options = {}) {
295
326
  this.plugins = [];
@@ -337,6 +368,42 @@ var InlineParser = class {
337
368
  }
338
369
  return result;
339
370
  }
371
+ /**
372
+ * Streaming regex anticipation helper. Returns an append string if a plugin
373
+ * declares an incomplete match at the end of the buffer.
374
+ */
375
+ getRegexAnticipationAppend(content) {
376
+ if (!content || this.plugins.length === 0) {
377
+ return null;
378
+ }
379
+ for (const plugin of this.plugins) {
380
+ if (!("re" in plugin)) continue;
381
+ const regexPlugin = plugin;
382
+ const anticipation = regexPlugin.anticipation;
383
+ if (!anticipation) continue;
384
+ const maxScanChars = Number.isFinite(anticipation.maxScanChars ?? Number.NaN) ? Math.max(1, anticipation.maxScanChars ?? 0) : 240;
385
+ const scan = content.slice(Math.max(0, content.length - maxScanChars));
386
+ if (regexPlugin.fastCheck && !regexPlugin.fastCheck(scan)) {
387
+ continue;
388
+ }
389
+ const lastStart = findLastMatch(anticipation.start, scan);
390
+ if (!lastStart) continue;
391
+ if (isSamePattern(anticipation.start, anticipation.end)) {
392
+ const occurrences = countMatches(anticipation.start, scan);
393
+ if (occurrences % 2 === 0) {
394
+ continue;
395
+ }
396
+ } else {
397
+ const startIndex = lastStart.index + lastStart[0].length;
398
+ const hasEnd = Boolean(findMatchAfter(anticipation.end, scan, startIndex));
399
+ if (hasEnd) continue;
400
+ }
401
+ const appendValue = typeof anticipation.append === "function" ? anticipation.append(lastStart, content) : anticipation.append;
402
+ if (!appendValue) continue;
403
+ return appendValue;
404
+ }
405
+ return null;
406
+ }
340
407
  /**
341
408
  * Clear the memoization cache
342
409
  */
@@ -465,9 +532,16 @@ var InlineParser = class {
465
532
  this.registerPlugin({
466
533
  id: "citations",
467
534
  priority: 10,
468
- re: /\[\^([^\]]+)\]|@cite\{([^}]+)\}/g,
469
- toNode: (match) => ({ kind: "citation", id: match[1] || match[2] }),
470
- fastCheck: (text) => text.indexOf("@") !== -1 || text.indexOf("[^") !== -1
535
+ re: /\[\^([^\]\n]+)\]|@cite\{([^}\n]+)\}|\{cite:([^}\n]+)\}/g,
536
+ toNode: (match) => ({ kind: "citation", id: match[1] || match[2] || match[3] }),
537
+ fastCheck: (text) => text.indexOf("@cite") !== -1 || text.indexOf("[^") !== -1 || text.indexOf("{cite:") !== -1,
538
+ anticipation: {
539
+ start: /@cite\{|\{cite:/g,
540
+ end: /\}/g,
541
+ full: /@cite\{[^}\n]+?\}|\{cite:[^}\n]+?\}/g,
542
+ append: "}",
543
+ maxScanChars: 120
544
+ }
471
545
  });
472
546
  this.registerPlugin({
473
547
  id: "mentions",
@@ -567,9 +641,23 @@ var rehypeParse = __toESM(require("rehype-parse"), 1);
567
641
  var rehypeSanitize = __toESM(require("rehype-sanitize"), 1);
568
642
  var rehypeStringify = __toESM(require("rehype-stringify"), 1);
569
643
  var import_unified = require("unified");
570
- var { defaultSchema } = rehypeSanitize;
644
+ var rehypeSanitizeModule = rehypeSanitize;
645
+ var defaultSchema = rehypeSanitizeModule.defaultSchema;
646
+ var resolvePlugin = (mod) => {
647
+ if (typeof mod === "function") return mod;
648
+ if (mod && typeof mod.default === "function") {
649
+ return mod.default;
650
+ }
651
+ if (mod && typeof mod.default?.default === "function") {
652
+ return mod.default?.default;
653
+ }
654
+ return mod;
655
+ };
656
+ var rehypeParsePlugin = resolvePlugin(rehypeParse);
657
+ var rehypeSanitizePlugin = resolvePlugin(rehypeSanitizeModule);
658
+ var rehypeStringifyPlugin = resolvePlugin(rehypeStringify);
571
659
  var SANITIZED_SCHEMA = createSchema();
572
- var sanitizeProcessor = (0, import_unified.unified)().use(rehypeParse.default, { fragment: true }).use(rehypeSanitize.default, SANITIZED_SCHEMA).use(rehypeStringify.default).freeze();
660
+ var sanitizeProcessor = (0, import_unified.unified)().use(rehypeParsePlugin, { fragment: true }).use(rehypeSanitizePlugin, SANITIZED_SCHEMA).use(rehypeStringifyPlugin).freeze();
573
661
  function sanitizeHtmlInWorker(html) {
574
662
  if (!html) return "";
575
663
  try {
@@ -685,9 +773,27 @@ function mergeAttributes(existing, additions) {
685
773
  }
686
774
 
687
775
  // src/mixed-content.ts
688
- function extractMixedContentSegments(raw, baseOffset, parseInline) {
776
+ var DEFAULT_INLINE_HTML_AUTOCLOSE_TAGS = /* @__PURE__ */ new Set([
777
+ "span",
778
+ "em",
779
+ "strong",
780
+ "code",
781
+ "kbd",
782
+ "del",
783
+ "s",
784
+ "mark",
785
+ "sub",
786
+ "sup",
787
+ "i",
788
+ "b",
789
+ "u",
790
+ "small",
791
+ "abbr",
792
+ "a"
793
+ ]);
794
+ function extractMixedContentSegments(raw, baseOffset, parseInline, options) {
689
795
  if (!raw) return [];
690
- const initial = splitByTagSegments(raw, baseOffset, parseInline);
796
+ const initial = splitByTagSegments(raw, baseOffset, parseInline, options);
691
797
  const expanded = [];
692
798
  for (const segment of initial) {
693
799
  if (segment.kind === "text") {
@@ -698,22 +804,58 @@ function extractMixedContentSegments(raw, baseOffset, parseInline) {
698
804
  }
699
805
  return mergeAdjacentTextSegments(expanded, parseInline);
700
806
  }
701
- function splitByTagSegments(source, baseOffset, parseInline) {
807
+ function splitByTagSegments(source, baseOffset, parseInline, options) {
702
808
  const segments = [];
703
809
  const lowerSource = source.toLowerCase();
704
810
  const tagPattern = /<([A-Za-z][\w:-]*)([^<>]*?)\/?>/g;
705
811
  let cursor = 0;
706
812
  let match = tagPattern.exec(source);
707
813
  const baseIsFinite = typeof baseOffset === "number" && Number.isFinite(baseOffset);
814
+ const htmlAllowTags = normalizeHtmlAllowlist(options?.html?.allowTags);
815
+ const htmlAutoClose = options?.html?.autoClose === true;
816
+ const htmlMaxNewlines = normalizeNewlineLimit(options?.html?.maxNewlines);
817
+ const mdxAutoClose = options?.mdx?.autoClose === true;
818
+ const mdxMaxNewlines = normalizeNewlineLimit(options?.mdx?.maxNewlines);
819
+ const mdxAllowlist = normalizeComponentAllowlist(options?.mdx?.componentAllowlist);
708
820
  while (match !== null) {
709
821
  const start = match.index;
710
822
  const tagName = match[1];
711
823
  const matchText = match[0];
712
- const isSelfClosing = matchText.endsWith("/>") || isVoidHtmlTag(tagName);
824
+ const tagNameLower = tagName.toLowerCase();
825
+ const isSelfClosing = matchText.endsWith("/>") || isVoidHtmlTag(tagNameLower);
826
+ const mdxCandidate = isLikelyMdxComponent(tagName);
827
+ const mdxAllowed = mdxCandidate && (!mdxAllowlist || mdxAllowlist.has(tagName));
828
+ if (mdxCandidate && mdxAllowlist && !mdxAllowed) {
829
+ tagPattern.lastIndex = start + 1;
830
+ match = tagPattern.exec(source);
831
+ continue;
832
+ }
713
833
  let end = tagPattern.lastIndex;
714
- if (!isSelfClosing && !isLikelyMdxComponent(tagName)) {
834
+ if (!isSelfClosing && !mdxAllowed) {
715
835
  const closingIndex = findClosingHtmlTag(lowerSource, tagName.toLowerCase(), end);
716
836
  if (closingIndex === -1) {
837
+ if (htmlAutoClose && htmlAllowTags.has(tagNameLower)) {
838
+ const tail = source.slice(end);
839
+ const newlineCount = countNewlines(tail, htmlMaxNewlines + 1);
840
+ if (newlineCount <= htmlMaxNewlines) {
841
+ if (start > cursor) {
842
+ const absoluteFrom = baseIsFinite ? baseOffset + cursor : void 0;
843
+ const absoluteTo = baseIsFinite ? baseOffset + start : void 0;
844
+ pushTextSegment(segments, source.slice(cursor, start), absoluteFrom, absoluteTo, parseInline);
845
+ }
846
+ const rawSegment2 = source.slice(start);
847
+ const closedValue = `${rawSegment2}</${tagName}>`;
848
+ const segment2 = {
849
+ kind: "html",
850
+ value: closedValue,
851
+ range: createSegmentRange(baseOffset, start, source.length),
852
+ sanitized: sanitizeHtmlInWorker(closedValue)
853
+ };
854
+ segments.push(segment2);
855
+ cursor = source.length;
856
+ break;
857
+ }
858
+ }
717
859
  tagPattern.lastIndex = start + 1;
718
860
  match = tagPattern.exec(source);
719
861
  continue;
@@ -725,8 +867,8 @@ function splitByTagSegments(source, baseOffset, parseInline) {
725
867
  const absoluteTo = baseIsFinite ? baseOffset + start : void 0;
726
868
  pushTextSegment(segments, source.slice(cursor, start), absoluteFrom, absoluteTo, parseInline);
727
869
  }
728
- const rawSegment = source.slice(start, end);
729
- const kind = isLikelyMdxComponent(tagName) ? "mdx" : "html";
870
+ let rawSegment = source.slice(start, end);
871
+ const kind = mdxAllowed ? "mdx" : "html";
730
872
  const segment = {
731
873
  kind,
732
874
  value: rawSegment,
@@ -735,6 +877,17 @@ function splitByTagSegments(source, baseOffset, parseInline) {
735
877
  if (kind === "html") {
736
878
  segment.sanitized = sanitizeHtmlInWorker(rawSegment);
737
879
  } else {
880
+ const tail = source.slice(end);
881
+ const newlineCount = countNewlines(tail, mdxMaxNewlines + 1);
882
+ if (mdxAutoClose && newlineCount > mdxMaxNewlines) {
883
+ tagPattern.lastIndex = start + 1;
884
+ match = tagPattern.exec(source);
885
+ continue;
886
+ }
887
+ if (mdxAutoClose && !rawSegment.endsWith("/>")) {
888
+ rawSegment = selfCloseTag(rawSegment);
889
+ segment.value = rawSegment;
890
+ }
738
891
  segment.status = "pending";
739
892
  }
740
893
  segments.push(segment);
@@ -859,6 +1012,48 @@ var VOID_HTML_TAGS = /* @__PURE__ */ new Set(["br", "hr", "img", "meta", "input"
859
1012
  function isVoidHtmlTag(tagName) {
860
1013
  return VOID_HTML_TAGS.has(tagName.toLowerCase());
861
1014
  }
1015
+ function normalizeNewlineLimit(value) {
1016
+ if (!Number.isFinite(value ?? Number.NaN)) {
1017
+ return 2;
1018
+ }
1019
+ return Math.max(0, value ?? 0);
1020
+ }
1021
+ function normalizeHtmlAllowlist(value) {
1022
+ if (!value) return DEFAULT_INLINE_HTML_AUTOCLOSE_TAGS;
1023
+ const tags = /* @__PURE__ */ new Set();
1024
+ for (const tag of value) {
1025
+ if (tag) {
1026
+ tags.add(tag.toLowerCase());
1027
+ }
1028
+ }
1029
+ return tags.size > 0 ? tags : DEFAULT_INLINE_HTML_AUTOCLOSE_TAGS;
1030
+ }
1031
+ function normalizeComponentAllowlist(value) {
1032
+ if (!value) return null;
1033
+ const tags = /* @__PURE__ */ new Set();
1034
+ for (const tag of value) {
1035
+ if (tag) tags.add(tag);
1036
+ }
1037
+ return tags.size > 0 ? tags : null;
1038
+ }
1039
+ function countNewlines(value, limit) {
1040
+ let count = 0;
1041
+ for (let i = 0; i < value.length; i++) {
1042
+ if (value.charCodeAt(i) === 10) {
1043
+ count += 1;
1044
+ if (limit !== void 0 && count >= limit) {
1045
+ return count;
1046
+ }
1047
+ }
1048
+ }
1049
+ return count;
1050
+ }
1051
+ function selfCloseTag(rawTag) {
1052
+ if (rawTag.endsWith("/>")) return rawTag;
1053
+ const closeIndex = rawTag.lastIndexOf(">");
1054
+ if (closeIndex === -1) return rawTag;
1055
+ return `${rawTag.slice(0, closeIndex)}/>`;
1056
+ }
862
1057
  function isLikelyMdxComponent(tagName) {
863
1058
  const first = tagName.charAt(0);
864
1059
  return first.toUpperCase() === first && first.toLowerCase() !== first;
@@ -2811,63 +3006,126 @@ var CustomStreamingMatcher = class {
2811
3006
  };
2812
3007
 
2813
3008
  // src/streaming/inline-streaming.ts
3009
+ var DEFAULT_FORMAT_ANTICIPATION = {
3010
+ inline: false,
3011
+ mathInline: false,
3012
+ mathBlock: false,
3013
+ html: false,
3014
+ mdx: false,
3015
+ regex: false
3016
+ };
3017
+ function normalizeFormatAnticipation(input) {
3018
+ if (input === true) {
3019
+ return { ...DEFAULT_FORMAT_ANTICIPATION, inline: true };
3020
+ }
3021
+ if (!input) {
3022
+ return { ...DEFAULT_FORMAT_ANTICIPATION };
3023
+ }
3024
+ return {
3025
+ inline: input.inline ?? false,
3026
+ mathInline: input.mathInline ?? false,
3027
+ mathBlock: input.mathBlock ?? false,
3028
+ html: input.html ?? false,
3029
+ mdx: input.mdx ?? false,
3030
+ regex: input.regex ?? false
3031
+ };
3032
+ }
2814
3033
  function prepareInlineStreamingContent(content, options) {
2815
- const enableAnticipation = Boolean(options?.formatAnticipation);
2816
3034
  const enableMath = options?.math !== false;
2817
- let dollarCount = 0;
2818
- let backtickCount = 0;
2819
- let starCount = 0;
2820
- let doubleStarCount = 0;
2821
- let tildePairCount = 0;
3035
+ const anticipation = normalizeFormatAnticipation(options?.formatAnticipation);
3036
+ const enableInlineAnticipation = anticipation.inline;
3037
+ const enableMathInlineAnticipation = anticipation.mathInline;
3038
+ const enableMathBlockAnticipation = anticipation.mathBlock;
3039
+ const stack = [];
3040
+ const toggleToken = (token) => {
3041
+ const last = stack[stack.length - 1];
3042
+ if (last === token) {
3043
+ stack.pop();
3044
+ } else {
3045
+ stack.push(token);
3046
+ }
3047
+ };
3048
+ let mathDisplayOpen = false;
3049
+ let mathDisplayCrossedNewline = false;
2822
3050
  for (let i = 0; i < content.length; i++) {
2823
3051
  const code = content.charCodeAt(i);
2824
- if (code === 36) {
2825
- dollarCount += 1;
3052
+ if (code === 10 || code === 13) {
3053
+ if (mathDisplayOpen) {
3054
+ mathDisplayCrossedNewline = true;
3055
+ }
2826
3056
  continue;
2827
3057
  }
2828
3058
  if (code === 96) {
2829
- backtickCount += 1;
3059
+ toggleToken("code");
3060
+ continue;
3061
+ }
3062
+ if (code === 126 && i + 1 < content.length && content.charCodeAt(i + 1) === 126) {
3063
+ toggleToken("strike");
3064
+ i += 1;
2830
3065
  continue;
2831
3066
  }
2832
3067
  if (code === 42) {
2833
3068
  if (i + 1 < content.length && content.charCodeAt(i + 1) === 42) {
2834
- doubleStarCount += 1;
2835
- starCount += 2;
3069
+ toggleToken("strong");
2836
3070
  i += 1;
2837
3071
  } else {
2838
- starCount += 1;
3072
+ toggleToken("em");
2839
3073
  }
2840
3074
  continue;
2841
3075
  }
2842
- if (code === 126) {
2843
- if (i + 1 < content.length && content.charCodeAt(i + 1) === 126) {
2844
- tildePairCount += 1;
3076
+ if (enableMath && code === 36) {
3077
+ if (i + 1 < content.length && content.charCodeAt(i + 1) === 36) {
3078
+ toggleToken("math-display");
3079
+ if (mathDisplayOpen) {
3080
+ mathDisplayOpen = false;
3081
+ mathDisplayCrossedNewline = false;
3082
+ } else {
3083
+ mathDisplayOpen = true;
3084
+ mathDisplayCrossedNewline = false;
3085
+ }
2845
3086
  i += 1;
3087
+ } else {
3088
+ toggleToken("math-inline");
2846
3089
  }
2847
3090
  }
2848
3091
  }
2849
- const hasIncompleteMath = enableMath && dollarCount % 2 !== 0;
2850
- if (hasIncompleteMath) {
2851
- return { kind: "raw", status: "raw", reason: "incomplete-math" };
2852
- }
2853
- const hasIncompleteCode = backtickCount % 2 !== 0;
2854
- const hasIncompleteStrong = doubleStarCount % 2 !== 0;
2855
- const singleStarCount = starCount - doubleStarCount * 2;
2856
- const hasIncompleteEmphasis = singleStarCount % 2 !== 0;
2857
- const hasIncompleteStrike = tildePairCount % 2 !== 0;
2858
- const hasAnyIncomplete = hasIncompleteCode || hasIncompleteStrong || hasIncompleteEmphasis || hasIncompleteStrike;
2859
- if (!hasAnyIncomplete) {
2860
- return { kind: "parse", status: "complete", content, appended: "" };
3092
+ const hasIncompleteFormatting = stack.some((token) => token === "code" || token === "strike" || token === "strong" || token === "em");
3093
+ const hasIncompleteMathInline = stack.includes("math-inline");
3094
+ const hasIncompleteMathDisplay = stack.includes("math-display");
3095
+ const hasIncompleteMath = hasIncompleteMathInline || hasIncompleteMathDisplay;
3096
+ if (enableMath && hasIncompleteMath) {
3097
+ if (hasIncompleteMathInline && !enableMathInlineAnticipation) {
3098
+ return { kind: "raw", status: "raw", reason: "incomplete-math" };
3099
+ }
3100
+ if (hasIncompleteMathDisplay && (!enableMathBlockAnticipation || mathDisplayCrossedNewline)) {
3101
+ return { kind: "raw", status: "raw", reason: "incomplete-math" };
3102
+ }
2861
3103
  }
2862
- if (!enableAnticipation) {
3104
+ if (hasIncompleteFormatting && !enableInlineAnticipation) {
2863
3105
  return { kind: "raw", status: "raw", reason: "incomplete-formatting" };
2864
3106
  }
2865
- let appended = "";
2866
- if (hasIncompleteCode) appended += "`";
2867
- if (hasIncompleteStrike) appended += "~~";
2868
- if (hasIncompleteStrong && hasIncompleteEmphasis) appended += "***";
2869
- else if (hasIncompleteStrong) appended += "**";
2870
- else if (hasIncompleteEmphasis) appended += "*";
3107
+ if (!hasIncompleteFormatting && !hasIncompleteMath) {
3108
+ return { kind: "parse", status: "complete", content, appended: "" };
3109
+ }
3110
+ const appendForToken = (token) => {
3111
+ switch (token) {
3112
+ case "code":
3113
+ return "`";
3114
+ case "strike":
3115
+ return "~~";
3116
+ case "strong":
3117
+ return "**";
3118
+ case "em":
3119
+ return "*";
3120
+ case "math-inline":
3121
+ return "$";
3122
+ case "math-display":
3123
+ return "$$";
3124
+ default:
3125
+ return "";
3126
+ }
3127
+ };
3128
+ const appended = stack.slice().reverse().map((token) => appendForToken(token)).join("");
2871
3129
  return { kind: "parse", status: "anticipated", content: content + appended, appended };
2872
3130
  }
2873
3131
  // Annotate the CommonJS export names for ESM import in node:
@@ -2914,6 +3172,7 @@ function prepareInlineStreamingContent(content, options) {
2914
3172
  inlineNodesToPlainText,
2915
3173
  isLikelyMdxComponent,
2916
3174
  normalizeBlockquoteText,
3175
+ normalizeFormatAnticipation,
2917
3176
  normalizeLang,
2918
3177
  parseCodeFenceInfo,
2919
3178
  prepareInlineStreamingContent,
package/dist/index.d.cts CHANGED
@@ -1,15 +1,15 @@
1
1
  import { Block, NodeSnapshot, InlineNode, Patch } from './types.cjs';
2
- export { ASTInlinePlugin, CoalescingMetrics, CompiledMdxModule, InlineHtmlDescriptor, InlinePlugin, LANGUAGE_ALIASES, MixedContentSegment, NodePath, PATCH_ROOT_ID, PatchMetrics, PerformanceMetrics, ProtectedRange, ProtectedRangeKind, RegexInlinePlugin, SetPropsBatchEntry, WorkerErrorPayload, WorkerIn, WorkerOut, WorkerPhase } from './types.cjs';
2
+ export { ASTInlinePlugin, CoalescingMetrics, CompiledMdxModule, FormatAnticipationConfig, InlineHtmlDescriptor, InlinePlugin, LANGUAGE_ALIASES, MixedContentSegment, NodePath, PATCH_ROOT_ID, PatchMetrics, PerformanceMetrics, ProtectedRange, ProtectedRangeKind, RegexAnticipationPattern, RegexInlinePlugin, SetPropsBatchEntry, WorkerErrorPayload, WorkerIn, WorkerOut, WorkerPhase } from './types.cjs';
3
3
  export { HighlightedLine, dedentIndentedCode, extractCodeLines, extractCodeWrapperAttributes, extractHighlightedLines, stripCodeFence } from './code-highlighting.cjs';
4
4
  export { PerformanceTimer, StringBuffer, applyUpdate, debounce, detectMDX, generateBlockId, getBlockKey, normalizeBlockquoteText, normalizeLang, parseCodeFenceInfo, removeHeadingMarkers } from './utils.cjs';
5
- export { extractMixedContentSegments, findClosingHtmlTag, isLikelyMdxComponent } from './mixed-content.cjs';
5
+ export { MixedContentAutoCloseHtmlOptions, MixedContentAutoCloseMdxOptions, MixedContentOptions, extractMixedContentSegments, findClosingHtmlTag, isLikelyMdxComponent } from './mixed-content.cjs';
6
6
  export { CSP_HEADERS, SanitizationPolicy, createSanitizationConfig, createTrustedHTML, initializeSecurity, initializeTrustedTypesPolicy, sanitizeCodeHTML, sanitizeHTML, sanitizeMathHTML, sanitizeURL } from './security.cjs';
7
7
  export { InlineParseOptions, InlineParser, InlineParserOptions, applyASTPlugin, applyRegexPlugin } from './inline-parser.cjs';
8
8
  export { sanitizeHtmlInWorker } from './worker-html-sanitizer.cjs';
9
9
  export { BackpressureConfig, DEFAULT_BACKPRESSURE_CONFIG, calculateRawCredit, calculateSmoothedCredit, clampCredit, computeHeavyPatchBudget, smoothCredit } from './perf/backpressure.cjs';
10
10
  export { CoalesceConfig, DEFAULT_COALESCE_CONFIG, coalescePatches, coalescePatchesLinear, coalescePatchesQuadratic, coalescePatchesWithMetrics } from './perf/patch-coalescing.cjs';
11
11
  export { CustomStreamingMatcher, MatchResult } from './streaming/custom-matcher.cjs';
12
- export { InlineStreamingInlineStatus, InlineStreamingPrepareResult, prepareInlineStreamingContent } from './streaming/inline-streaming.cjs';
12
+ export { InlineStreamingInlineStatus, InlineStreamingPrepareResult, NormalizedFormatAnticipation, normalizeFormatAnticipation, prepareInlineStreamingContent } from './streaming/inline-streaming.cjs';
13
13
  import 'dompurify';
14
14
 
15
15
  declare function cloneBlock(block: Block): Block;
package/dist/index.d.ts CHANGED
@@ -1,15 +1,15 @@
1
1
  import { Block, NodeSnapshot, InlineNode, Patch } from './types.js';
2
- export { ASTInlinePlugin, CoalescingMetrics, CompiledMdxModule, InlineHtmlDescriptor, InlinePlugin, LANGUAGE_ALIASES, MixedContentSegment, NodePath, PATCH_ROOT_ID, PatchMetrics, PerformanceMetrics, ProtectedRange, ProtectedRangeKind, RegexInlinePlugin, SetPropsBatchEntry, WorkerErrorPayload, WorkerIn, WorkerOut, WorkerPhase } from './types.js';
2
+ export { ASTInlinePlugin, CoalescingMetrics, CompiledMdxModule, FormatAnticipationConfig, InlineHtmlDescriptor, InlinePlugin, LANGUAGE_ALIASES, MixedContentSegment, NodePath, PATCH_ROOT_ID, PatchMetrics, PerformanceMetrics, ProtectedRange, ProtectedRangeKind, RegexAnticipationPattern, RegexInlinePlugin, SetPropsBatchEntry, WorkerErrorPayload, WorkerIn, WorkerOut, WorkerPhase } from './types.js';
3
3
  export { HighlightedLine, dedentIndentedCode, extractCodeLines, extractCodeWrapperAttributes, extractHighlightedLines, stripCodeFence } from './code-highlighting.js';
4
4
  export { PerformanceTimer, StringBuffer, applyUpdate, debounce, detectMDX, generateBlockId, getBlockKey, normalizeBlockquoteText, normalizeLang, parseCodeFenceInfo, removeHeadingMarkers } from './utils.js';
5
- export { extractMixedContentSegments, findClosingHtmlTag, isLikelyMdxComponent } from './mixed-content.js';
5
+ export { MixedContentAutoCloseHtmlOptions, MixedContentAutoCloseMdxOptions, MixedContentOptions, extractMixedContentSegments, findClosingHtmlTag, isLikelyMdxComponent } from './mixed-content.js';
6
6
  export { CSP_HEADERS, SanitizationPolicy, createSanitizationConfig, createTrustedHTML, initializeSecurity, initializeTrustedTypesPolicy, sanitizeCodeHTML, sanitizeHTML, sanitizeMathHTML, sanitizeURL } from './security.js';
7
7
  export { InlineParseOptions, InlineParser, InlineParserOptions, applyASTPlugin, applyRegexPlugin } from './inline-parser.js';
8
8
  export { sanitizeHtmlInWorker } from './worker-html-sanitizer.js';
9
9
  export { BackpressureConfig, DEFAULT_BACKPRESSURE_CONFIG, calculateRawCredit, calculateSmoothedCredit, clampCredit, computeHeavyPatchBudget, smoothCredit } from './perf/backpressure.js';
10
10
  export { CoalesceConfig, DEFAULT_COALESCE_CONFIG, coalescePatches, coalescePatchesLinear, coalescePatchesQuadratic, coalescePatchesWithMetrics } from './perf/patch-coalescing.js';
11
11
  export { CustomStreamingMatcher, MatchResult } from './streaming/custom-matcher.js';
12
- export { InlineStreamingInlineStatus, InlineStreamingPrepareResult, prepareInlineStreamingContent } from './streaming/inline-streaming.js';
12
+ export { InlineStreamingInlineStatus, InlineStreamingPrepareResult, NormalizedFormatAnticipation, normalizeFormatAnticipation, prepareInlineStreamingContent } from './streaming/inline-streaming.js';
13
13
  import 'dompurify';
14
14
 
15
15
  declare function cloneBlock(block: Block): Block;