@ai-react-markdown/engine 2.5.0 → 2.5.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
@@ -65,6 +65,8 @@ __export(src_exports, {
65
65
  hasLoneSurrogate: () => hasLoneSurrogate,
66
66
  highlight: () => highlight,
67
67
  isFootnoteSection: () => isFootnoteSection,
68
+ isWhitespaceText: () => isWhitespaceText,
69
+ lastMeaningfulIdx: () => lastMeaningfulIdx,
68
70
  measureStage: () => measureStage,
69
71
  mergeClassNameAllowlist: () => mergeClassNameAllowlist,
70
72
  normalizeForMatch: () => normalizeForMatch,
@@ -751,6 +753,7 @@ function processConfirmedLine(cp, ln, text) {
751
753
  cp.openTotal += 1;
752
754
  }
753
755
  };
756
+ const strayTablePart = (tag) => TABLE_PART_NAMES.has(tag) && (cp.tagBalance.get("table") ?? 0) === 0;
754
757
  const commentOpenAtLineStart = cp.commentOpen;
755
758
  const rawOpenAtLineStart = cp.commentOpen || cp.piOpen || cp.declOpen || cp.cdataOpen || cp.bogusOpen;
756
759
  if (cp.inFence) {
@@ -1079,7 +1082,7 @@ ${cont(scanText)}` };
1079
1082
  if (cp.commentOpen) continue;
1080
1083
  const closing = m[1] === "/";
1081
1084
  const tag = m[2].toLowerCase();
1082
- if (TABLE_PART_NAMES.has(tag)) cp.phasePoisonedAt = Math.min(cp.phasePoisonedAt, ln.start + m.index);
1085
+ if (strayTablePart(tag)) cp.phasePoisonedAt = Math.min(cp.phasePoisonedAt, ln.start + m.index);
1083
1086
  let attrs = m[3] ?? "";
1084
1087
  if (cp.htmlFlowReal && (cp.rawTextOpen === null || closing && tag === cp.rawTextOpen)) {
1085
1088
  const attrStart = m.index + 1 + (closing ? 1 : 0) + m[2].length;
@@ -1123,7 +1126,7 @@ ${cont(scanText)}` };
1123
1126
  if (startMasked || wholeVisible || inRaw(mr.index) || cp.commentOpen) continue;
1124
1127
  const closing = mr[1] === "/";
1125
1128
  const tag = mr[2].toLowerCase();
1126
- if (TABLE_PART_NAMES.has(tag)) cp.phasePoisonedAt = Math.min(cp.phasePoisonedAt, ln.start + mr.index);
1129
+ if (strayTablePart(tag)) cp.phasePoisonedAt = Math.min(cp.phasePoisonedAt, ln.start + mr.index);
1127
1130
  if (closing && mr[3] !== void 0 && !/^\s*$/.test(mr[3])) continue;
1128
1131
  const selfClosing = mr[3] !== void 0 && /\/\s*$/.test(mr[3]);
1129
1132
  if (VOID_TAGS.has(tag) || selfClosing && honoursSelfClosing(tag)) continue;
@@ -1131,7 +1134,7 @@ ${cont(scanText)}` };
1131
1134
  }
1132
1135
  }
1133
1136
  if (cp.pendingTruncatedTags.length > 0 && ln.text.includes(">")) {
1134
- if (cp.pendingTruncatedTags.some((t) => TABLE_PART_NAMES.has(t))) {
1137
+ if (cp.pendingTruncatedTags.some((t) => strayTablePart(t))) {
1135
1138
  cp.phasePoisonedAt = Math.min(cp.phasePoisonedAt, ln.start);
1136
1139
  }
1137
1140
  cp.pendingTruncatedTags = [];
@@ -1148,7 +1151,7 @@ ${cont(scanText)}` };
1148
1151
  if (m2) {
1149
1152
  const closing = m2[1] === "/";
1150
1153
  const tag = m2[2].toLowerCase();
1151
- if (TABLE_PART_NAMES.has(tag) && cp.htmlFlowReal) {
1154
+ if (strayTablePart(tag) && cp.htmlFlowReal) {
1152
1155
  cp.phasePoisonedAt = Math.min(cp.phasePoisonedAt, ln.start + lastLt);
1153
1156
  }
1154
1157
  if (cp.htmlFlowReal) {
@@ -1198,6 +1201,15 @@ function isFootnoteSection(node) {
1198
1201
  const props = node.properties;
1199
1202
  return props?.dataFootnotes !== void 0;
1200
1203
  }
1204
+ function isWhitespaceText(c) {
1205
+ return c.type === "text" && /^\s*$/.test(c.value);
1206
+ }
1207
+ function lastMeaningfulIdx(children) {
1208
+ for (let i = children.length - 1; i >= 0; i--) {
1209
+ if (!isWhitespaceText(children[i])) return i;
1210
+ }
1211
+ return -1;
1212
+ }
1201
1213
 
1202
1214
  // src/components/incrementalParse/attributeHastChildren.ts
1203
1215
  function attributeHastChildren(mdast, hast, stopAt = Infinity) {
@@ -1373,6 +1385,24 @@ function rebaseDualWalk(node, segments, maxEnd, offsetDelta, lineDelta) {
1373
1385
  }
1374
1386
  }
1375
1387
  var TABLE_PART_TAG_RE = /<(?:td|th|tr|tbody|thead|tfoot|caption|col|colgroup)\b/i;
1388
+ var TABLE_TOKEN_RE = /<(\/?)(table|td|th|tr|tbody|thead|tfoot|caption|col|colgroup)\b/gi;
1389
+ function hasStrayTablePart(values) {
1390
+ let depth = 0;
1391
+ for (const value of values) {
1392
+ TABLE_TOKEN_RE.lastIndex = 0;
1393
+ let m;
1394
+ while ((m = TABLE_TOKEN_RE.exec(value)) !== null) {
1395
+ const closing = m[1] === "/";
1396
+ const tag = m[2].toLowerCase();
1397
+ if (tag === "table") {
1398
+ depth = closing ? Math.max(0, depth - 1) : depth + 1;
1399
+ continue;
1400
+ }
1401
+ if (depth === 0) return true;
1402
+ }
1403
+ }
1404
+ return false;
1405
+ }
1376
1406
  var STRAY_SYNTHESIZED_END_TAG_RE = /<\/(?:br|p)\b/i;
1377
1407
  function spliceTrees(input) {
1378
1408
  const { prevMdast, prevHast, tailMdast, tailHast, content, boundary, injectionPrefix, injectedSegments } = input;
@@ -1430,7 +1460,7 @@ function spliceTrees(input) {
1430
1460
  return !(start !== void 0 && start < injectedLen);
1431
1461
  });
1432
1462
  const tailWrapVisible = tailMdastChildren.some((child) => !isWrapInvisible(child));
1433
- if (prefixMdast.some((c) => c.type === "html" && TABLE_PART_TAG_RE.test(c.value))) return null;
1463
+ if (hasStrayTablePart(prefixMdast.flatMap((c) => c.type === "html" ? [c.value] : []))) return null;
1434
1464
  for (const child of tailMdastChildren) {
1435
1465
  if (isWrapInvisible(child)) continue;
1436
1466
  if (child.type !== "html") break;
@@ -1962,16 +1992,6 @@ function isBackrefAnchor(c) {
1962
1992
  if (el.tagName !== "a") return false;
1963
1993
  return Boolean(el.properties && "dataFootnoteBackref" in el.properties);
1964
1994
  }
1965
- function isWhitespaceText(c) {
1966
- if (c.type !== "text") return false;
1967
- return /^\s*$/.test(c.value);
1968
- }
1969
- function lastMeaningfulIdx(children) {
1970
- for (let i = children.length - 1; i >= 0; i--) {
1971
- if (!isWhitespaceText(children[i])) return i;
1972
- }
1973
- return -1;
1974
- }
1975
1995
  function dropTrailingBackrefs(children) {
1976
1996
  let trailingWsStart = children.length;
1977
1997
  while (trailingWsStart > 0 && isWhitespaceText(children[trailingWsStart - 1])) {
@@ -4088,6 +4108,14 @@ var graphemeEnds = (text, base) => {
4088
4108
  }
4089
4109
  return ends;
4090
4110
  };
4111
+ var RESUME_LOOKBACK = 64;
4112
+ var isMidSurrogatePair = (text, at) => at > 0 && at < text.length && (text.charCodeAt(at - 1) & 64512) === 55296 && (text.charCodeAt(at) & 64512) === 56320;
4113
+ var RI_FIRST = 127462;
4114
+ var RI_LAST = 127487;
4115
+ var isRegionalIndicatorAt = (text, at) => {
4116
+ const cp = text.codePointAt(at);
4117
+ return cp !== void 0 && cp >= RI_FIRST && cp <= RI_LAST;
4118
+ };
4091
4119
  var createSmoothStreamController = (options = {}) => {
4092
4120
  const now = options.now ?? defaultNow;
4093
4121
  const schedule = options.schedule ?? defaultSchedule;
@@ -4096,6 +4124,7 @@ var createSmoothStreamController = (options = {}) => {
4096
4124
  let pending = [];
4097
4125
  let tentativeEnd = 0;
4098
4126
  let finished = false;
4127
+ let seam;
4099
4128
  let drainDeadlineAt;
4100
4129
  let initialized = false;
4101
4130
  let visibleCache = "";
@@ -4179,8 +4208,19 @@ var createSmoothStreamController = (options = {}) => {
4179
4208
  if (!disposed && !cancelFrame && pending.length > 0) cancelFrame = schedule(tick);
4180
4209
  };
4181
4210
  const resegmentTail = () => {
4211
+ if (seam !== void 0 && seam < source.length && pending[pending.length - 1] === seam) {
4212
+ pending.pop();
4213
+ }
4182
4214
  const from = pending.length > 0 ? pending[pending.length - 1] : visibleEnd;
4183
- const ends = graphemeEnds(source.slice(from), from);
4215
+ let anchor = from;
4216
+ if (seam !== void 0 && from <= seam) {
4217
+ anchor = Math.max(0, from - RESUME_LOOKBACK);
4218
+ if (isMidSurrogatePair(source, anchor)) anchor -= 1;
4219
+ while (anchor >= 2 && isRegionalIndicatorAt(source, anchor - 2)) anchor -= 2;
4220
+ } else {
4221
+ seam = void 0;
4222
+ }
4223
+ const ends = graphemeEnds(source.slice(anchor), anchor);
4184
4224
  if (ends.length === 0) {
4185
4225
  tentativeEnd = from;
4186
4226
  return;
@@ -4192,7 +4232,7 @@ var createSmoothStreamController = (options = {}) => {
4192
4232
  if (last >= 55296 && last <= 56319) hold = 2;
4193
4233
  }
4194
4234
  const confirmedEnds = finished ? ends : ends.slice(0, -hold);
4195
- for (const end of confirmedEnds) pending.push(end);
4235
+ for (const end of confirmedEnds) if (end > from) pending.push(end);
4196
4236
  };
4197
4237
  const snap = (next) => {
4198
4238
  disposed = false;
@@ -4206,6 +4246,7 @@ var createSmoothStreamController = (options = {}) => {
4206
4246
  visibleEnd = next.length;
4207
4247
  tentativeEnd = next.length;
4208
4248
  pending = [];
4249
+ seam = next.length;
4209
4250
  credit = 0;
4210
4251
  cancelScheduled();
4211
4252
  if (visibleCache !== next) notify();
@@ -4240,6 +4281,7 @@ var createSmoothStreamController = (options = {}) => {
4240
4281
  if (tentativeEnd > (pending.length > 0 ? pending[pending.length - 1] : visibleEnd)) {
4241
4282
  pending.push(tentativeEnd);
4242
4283
  }
4284
+ seam = source.length;
4243
4285
  ensureScheduled();
4244
4286
  },
4245
4287
  snap,
@@ -4616,21 +4658,7 @@ function convertSingleToDoubleDollar(text) {
4616
4658
  }
4617
4659
  function preprocessLaTeX(str) {
4618
4660
  if (!hasLatexTrigger(str)) return str;
4619
- const segments = splitByProtectedRegions(str);
4620
- const result = segments.map((segment) => {
4621
- if (segment.isCode) return segment.text;
4622
- let text = segment.text;
4623
- text = escapeMhchemCommands(text);
4624
- text = escapeCurrencyDollarSigns(text);
4625
- text = convertLatexDelimiters(text);
4626
- text = escapeLatexPipes(text);
4627
- text = escapeLatexPipesInUnclosed(text);
4628
- text = escapeTextUnderscores(text);
4629
- text = convertSingleToDoubleDollar(text);
4630
- text = truncateUnclosedLatexBlock(text);
4631
- return text;
4632
- });
4633
- return result.join("");
4661
+ return processSlice(str, false).out;
4634
4662
  }
4635
4663
  function hasLatexTrigger(str) {
4636
4664
  return str.includes("$") || str.includes("\\[") || str.includes("\\(");
@@ -4659,7 +4687,7 @@ function hasUnclosedTextCommand(text) {
4659
4687
  }
4660
4688
  var RESIDUAL_OPEN_BRACKET_RE = /(?<!!)\\\[/;
4661
4689
  var LEADING_DOUBLE_DOLLAR_RE = /^\s*\$\$/;
4662
- function processSliceInstrumented(slice, probe = true) {
4690
+ function processSlice(slice, probe = true) {
4663
4691
  const segments = splitByProtectedRegions(slice);
4664
4692
  const parts = [];
4665
4693
  let quiescent = true;
@@ -4783,13 +4811,13 @@ function createIncrementalLatexPreprocessor(options) {
4783
4811
  };
4784
4812
  const cut = findRawSafeCut(active);
4785
4813
  if (cut > 0) {
4786
- const candidate = processSliceInstrumented(active.slice(0, cut));
4814
+ const candidate = processSlice(active.slice(0, cut));
4787
4815
  if (candidate.quiescent) freeze(cut, candidate);
4788
4816
  }
4789
4817
  nextAttemptLen = advanced || !backoff ? 0 : active.length * 2;
4790
4818
  onAttempt?.({ activeLength, frozenBytes });
4791
4819
  }
4792
- const tail = processSliceInstrumented(active, false);
4820
+ const tail = processSlice(active, false);
4793
4821
  const head = tail.truncatedAtSeamStart ? frozenOut.replace(/\s+$/, "") : frozenOut;
4794
4822
  const out = head + tail.out;
4795
4823
  prevSource = source;
@@ -4854,6 +4882,8 @@ function createRemendPreprocessor(options) {
4854
4882
  hasLoneSurrogate,
4855
4883
  highlight,
4856
4884
  isFootnoteSection,
4885
+ isWhitespaceText,
4886
+ lastMeaningfulIdx,
4857
4887
  measureStage,
4858
4888
  mergeClassNameAllowlist,
4859
4889
  normalizeForMatch,