@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.d.cts CHANGED
@@ -1460,6 +1460,28 @@ declare const defaultEnginePlugins: readonly AIMarkdownEnginePlugin[];
1460
1460
  * `tagName === 'section'` AND presence of the `dataFootnotes` property.
1461
1461
  */
1462
1462
  declare function isFootnoteSection(node: Element): boolean;
1463
+ /**
1464
+ * Whitespace-only text node. `mdast-util-to-hast`'s `state.wrap(content,
1465
+ * true)` interleaves `\n` text nodes between (and around) the block-level
1466
+ * children of an `<li>`, so any code reasoning about a list item's real
1467
+ * children has to look past them.
1468
+ */
1469
+ declare function isWhitespaceText(c: ElementContent): boolean;
1470
+ /**
1471
+ * Index of the last child that is not a whitespace-only text node, or -1 if
1472
+ * there is none.
1473
+ *
1474
+ * Both footnote-footer paths need exactly this and for the same reason.
1475
+ * Appending a backref follows mdast-util-to-hast's contract — "if the tail of
1476
+ * the `<li>`'s content is a `<p>`, push into it, else push onto the `<li>`" —
1477
+ * and stripping one has to find that tail again. Read the trailing
1478
+ * wrap-emitted `\n` as the tail and the `<p>` path is bypassed in one case
1479
+ * and the wrong node stripped in the other.
1480
+ *
1481
+ * Lived in two copies until 2.5.2 (core's aggregate footer and the engine's
1482
+ * body extractor), one on each side of the 2.3.0 package split.
1483
+ */
1484
+ declare function lastMeaningfulIdx(children: ElementContent[]): number;
1463
1485
 
1464
1486
  declare function normalizeId(s: string): string;
1465
1487
  /**
@@ -2021,4 +2043,4 @@ type RemendPreprocessorOptions = Omit<RemendOptions, 'katex' | 'inlineKatex'>;
2021
2043
  */
2022
2044
  declare function createRemendPreprocessor(options?: RemendPreprocessorOptions): AIMDContentPreprocessor;
2023
2045
 
2024
- export { type AIMDContentPreprocessor, type AIMarkdownEnginePlugin, type AIMarkdownEnginePluginName, type AdvanceOptions, type AdvanceResult, type AllowElement, type ChunkData, type Contribution, type CrossChunkHandlerOptions, DEFAULT_PAYLOAD, type DefLabelScanner, type DefLabels, type Deprecation, type EnginePluginInternals, type EnginePluginStage, type ExtractContributionsOptions, type FootnoteDef, type FreezeBoundaryOptions, type IncrementalParseState, type IncrementalStage, type LinkDef, PIPELINE_STAGES, type ParsedMarkdown, type PhantomLabels, type PipelineOptions, type PipelineStage, type RefKind, type RefRecord, type Registry, type RegistryInternal, type RehypePlugins, type RehypeRebaseHashLinksOptions, type RemarkPlugins, type RemarkRehypeOptions, type RemendPreprocessorOptions, SENTINEL_FN_CONTENT, SENTINEL_LINK_URL, SMOOTH_STREAM_PACING_PRESETS, STAGE_MEASURE_PREFIX, type SanitizeSchema, type SmoothStreamController, type SmoothStreamOptions, type SmoothStreamPacing, type SmoothStreamPacingParams, type TransformContext, type UrlAttrKey, type UrlAttrTag, type UrlTransform, advanceIncrementalParse, attributeHastChildren, buildCoreRehypePlugins, buildCoreRemarkPlugins, buildCoreRemarkRehypeOptions, buildCrossChunkHandlers, buildPhantomSuffix, buildTransform, codePointSnapshots, collectDefLabels, computeFreezeBoundary, createDefLabelScanner, createFile, createIncrementalLatexPreprocessor, createProcessor, createRegistry, createRemendPreprocessor, createSmoothStreamController, defaultEnginePlugins, defaultUrlTransform, definitionList, extendSanitizeSchema, extractContributions, extractDefBodiesFromHast, footnoteSafeId, getEnginePluginInternals, hasLoneSurrogate, highlight, isFootnoteSection, measureStage, mergeClassNameAllowlist, normalizeForMatch, normalizeId, pangu, parseStage, phantomSuffixCloser, preprocessAIMDContent, preprocessLaTeX, rehypeFooterAdorn, rehypeRebaseHashLinks, removeComments, sanitizeCrossChunkUrl, sanitizeSchema, shortenDocumentId, smartypants, sourceIdFromFootnoteLiId, splitByProtectedRegions, subscribeStageTimings, transformStage, withDefs };
2046
+ export { type AIMDContentPreprocessor, type AIMarkdownEnginePlugin, type AIMarkdownEnginePluginName, type AdvanceOptions, type AdvanceResult, type AllowElement, type ChunkData, type Contribution, type CrossChunkHandlerOptions, DEFAULT_PAYLOAD, type DefLabelScanner, type DefLabels, type Deprecation, type EnginePluginInternals, type EnginePluginStage, type ExtractContributionsOptions, type FootnoteDef, type FreezeBoundaryOptions, type IncrementalParseState, type IncrementalStage, type LinkDef, PIPELINE_STAGES, type ParsedMarkdown, type PhantomLabels, type PipelineOptions, type PipelineStage, type RefKind, type RefRecord, type Registry, type RegistryInternal, type RehypePlugins, type RehypeRebaseHashLinksOptions, type RemarkPlugins, type RemarkRehypeOptions, type RemendPreprocessorOptions, SENTINEL_FN_CONTENT, SENTINEL_LINK_URL, SMOOTH_STREAM_PACING_PRESETS, STAGE_MEASURE_PREFIX, type SanitizeSchema, type SmoothStreamController, type SmoothStreamOptions, type SmoothStreamPacing, type SmoothStreamPacingParams, type TransformContext, type UrlAttrKey, type UrlAttrTag, type UrlTransform, advanceIncrementalParse, attributeHastChildren, buildCoreRehypePlugins, buildCoreRemarkPlugins, buildCoreRemarkRehypeOptions, buildCrossChunkHandlers, buildPhantomSuffix, buildTransform, codePointSnapshots, collectDefLabels, computeFreezeBoundary, createDefLabelScanner, createFile, createIncrementalLatexPreprocessor, createProcessor, createRegistry, createRemendPreprocessor, createSmoothStreamController, defaultEnginePlugins, defaultUrlTransform, definitionList, extendSanitizeSchema, extractContributions, extractDefBodiesFromHast, footnoteSafeId, getEnginePluginInternals, hasLoneSurrogate, highlight, isFootnoteSection, isWhitespaceText, lastMeaningfulIdx, measureStage, mergeClassNameAllowlist, normalizeForMatch, normalizeId, pangu, parseStage, phantomSuffixCloser, preprocessAIMDContent, preprocessLaTeX, rehypeFooterAdorn, rehypeRebaseHashLinks, removeComments, sanitizeCrossChunkUrl, sanitizeSchema, shortenDocumentId, smartypants, sourceIdFromFootnoteLiId, splitByProtectedRegions, subscribeStageTimings, transformStage, withDefs };
package/dist/index.d.ts CHANGED
@@ -1460,6 +1460,28 @@ declare const defaultEnginePlugins: readonly AIMarkdownEnginePlugin[];
1460
1460
  * `tagName === 'section'` AND presence of the `dataFootnotes` property.
1461
1461
  */
1462
1462
  declare function isFootnoteSection(node: Element): boolean;
1463
+ /**
1464
+ * Whitespace-only text node. `mdast-util-to-hast`'s `state.wrap(content,
1465
+ * true)` interleaves `\n` text nodes between (and around) the block-level
1466
+ * children of an `<li>`, so any code reasoning about a list item's real
1467
+ * children has to look past them.
1468
+ */
1469
+ declare function isWhitespaceText(c: ElementContent): boolean;
1470
+ /**
1471
+ * Index of the last child that is not a whitespace-only text node, or -1 if
1472
+ * there is none.
1473
+ *
1474
+ * Both footnote-footer paths need exactly this and for the same reason.
1475
+ * Appending a backref follows mdast-util-to-hast's contract — "if the tail of
1476
+ * the `<li>`'s content is a `<p>`, push into it, else push onto the `<li>`" —
1477
+ * and stripping one has to find that tail again. Read the trailing
1478
+ * wrap-emitted `\n` as the tail and the `<p>` path is bypassed in one case
1479
+ * and the wrong node stripped in the other.
1480
+ *
1481
+ * Lived in two copies until 2.5.2 (core's aggregate footer and the engine's
1482
+ * body extractor), one on each side of the 2.3.0 package split.
1483
+ */
1484
+ declare function lastMeaningfulIdx(children: ElementContent[]): number;
1463
1485
 
1464
1486
  declare function normalizeId(s: string): string;
1465
1487
  /**
@@ -2021,4 +2043,4 @@ type RemendPreprocessorOptions = Omit<RemendOptions, 'katex' | 'inlineKatex'>;
2021
2043
  */
2022
2044
  declare function createRemendPreprocessor(options?: RemendPreprocessorOptions): AIMDContentPreprocessor;
2023
2045
 
2024
- export { type AIMDContentPreprocessor, type AIMarkdownEnginePlugin, type AIMarkdownEnginePluginName, type AdvanceOptions, type AdvanceResult, type AllowElement, type ChunkData, type Contribution, type CrossChunkHandlerOptions, DEFAULT_PAYLOAD, type DefLabelScanner, type DefLabels, type Deprecation, type EnginePluginInternals, type EnginePluginStage, type ExtractContributionsOptions, type FootnoteDef, type FreezeBoundaryOptions, type IncrementalParseState, type IncrementalStage, type LinkDef, PIPELINE_STAGES, type ParsedMarkdown, type PhantomLabels, type PipelineOptions, type PipelineStage, type RefKind, type RefRecord, type Registry, type RegistryInternal, type RehypePlugins, type RehypeRebaseHashLinksOptions, type RemarkPlugins, type RemarkRehypeOptions, type RemendPreprocessorOptions, SENTINEL_FN_CONTENT, SENTINEL_LINK_URL, SMOOTH_STREAM_PACING_PRESETS, STAGE_MEASURE_PREFIX, type SanitizeSchema, type SmoothStreamController, type SmoothStreamOptions, type SmoothStreamPacing, type SmoothStreamPacingParams, type TransformContext, type UrlAttrKey, type UrlAttrTag, type UrlTransform, advanceIncrementalParse, attributeHastChildren, buildCoreRehypePlugins, buildCoreRemarkPlugins, buildCoreRemarkRehypeOptions, buildCrossChunkHandlers, buildPhantomSuffix, buildTransform, codePointSnapshots, collectDefLabels, computeFreezeBoundary, createDefLabelScanner, createFile, createIncrementalLatexPreprocessor, createProcessor, createRegistry, createRemendPreprocessor, createSmoothStreamController, defaultEnginePlugins, defaultUrlTransform, definitionList, extendSanitizeSchema, extractContributions, extractDefBodiesFromHast, footnoteSafeId, getEnginePluginInternals, hasLoneSurrogate, highlight, isFootnoteSection, measureStage, mergeClassNameAllowlist, normalizeForMatch, normalizeId, pangu, parseStage, phantomSuffixCloser, preprocessAIMDContent, preprocessLaTeX, rehypeFooterAdorn, rehypeRebaseHashLinks, removeComments, sanitizeCrossChunkUrl, sanitizeSchema, shortenDocumentId, smartypants, sourceIdFromFootnoteLiId, splitByProtectedRegions, subscribeStageTimings, transformStage, withDefs };
2046
+ export { type AIMDContentPreprocessor, type AIMarkdownEnginePlugin, type AIMarkdownEnginePluginName, type AdvanceOptions, type AdvanceResult, type AllowElement, type ChunkData, type Contribution, type CrossChunkHandlerOptions, DEFAULT_PAYLOAD, type DefLabelScanner, type DefLabels, type Deprecation, type EnginePluginInternals, type EnginePluginStage, type ExtractContributionsOptions, type FootnoteDef, type FreezeBoundaryOptions, type IncrementalParseState, type IncrementalStage, type LinkDef, PIPELINE_STAGES, type ParsedMarkdown, type PhantomLabels, type PipelineOptions, type PipelineStage, type RefKind, type RefRecord, type Registry, type RegistryInternal, type RehypePlugins, type RehypeRebaseHashLinksOptions, type RemarkPlugins, type RemarkRehypeOptions, type RemendPreprocessorOptions, SENTINEL_FN_CONTENT, SENTINEL_LINK_URL, SMOOTH_STREAM_PACING_PRESETS, STAGE_MEASURE_PREFIX, type SanitizeSchema, type SmoothStreamController, type SmoothStreamOptions, type SmoothStreamPacing, type SmoothStreamPacingParams, type TransformContext, type UrlAttrKey, type UrlAttrTag, type UrlTransform, advanceIncrementalParse, attributeHastChildren, buildCoreRehypePlugins, buildCoreRemarkPlugins, buildCoreRemarkRehypeOptions, buildCrossChunkHandlers, buildPhantomSuffix, buildTransform, codePointSnapshots, collectDefLabels, computeFreezeBoundary, createDefLabelScanner, createFile, createIncrementalLatexPreprocessor, createProcessor, createRegistry, createRemendPreprocessor, createSmoothStreamController, defaultEnginePlugins, defaultUrlTransform, definitionList, extendSanitizeSchema, extractContributions, extractDefBodiesFromHast, footnoteSafeId, getEnginePluginInternals, hasLoneSurrogate, highlight, isFootnoteSection, isWhitespaceText, lastMeaningfulIdx, measureStage, mergeClassNameAllowlist, normalizeForMatch, normalizeId, pangu, parseStage, phantomSuffixCloser, preprocessAIMDContent, preprocessLaTeX, rehypeFooterAdorn, rehypeRebaseHashLinks, removeComments, sanitizeCrossChunkUrl, sanitizeSchema, shortenDocumentId, smartypants, sourceIdFromFootnoteLiId, splitByProtectedRegions, subscribeStageTimings, transformStage, withDefs };
@@ -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])) {
@@ -4100,6 +4120,14 @@ var graphemeEnds = (text, base) => {
4100
4120
  }
4101
4121
  return ends;
4102
4122
  };
4123
+ var RESUME_LOOKBACK = 64;
4124
+ var isMidSurrogatePair = (text, at) => at > 0 && at < text.length && (text.charCodeAt(at - 1) & 64512) === 55296 && (text.charCodeAt(at) & 64512) === 56320;
4125
+ var RI_FIRST = 127462;
4126
+ var RI_LAST = 127487;
4127
+ var isRegionalIndicatorAt = (text, at) => {
4128
+ const cp = text.codePointAt(at);
4129
+ return cp !== void 0 && cp >= RI_FIRST && cp <= RI_LAST;
4130
+ };
4103
4131
  var createSmoothStreamController = (options = {}) => {
4104
4132
  const now = options.now ?? defaultNow;
4105
4133
  const schedule = options.schedule ?? defaultSchedule;
@@ -4108,6 +4136,7 @@ var createSmoothStreamController = (options = {}) => {
4108
4136
  let pending = [];
4109
4137
  let tentativeEnd = 0;
4110
4138
  let finished = false;
4139
+ let seam;
4111
4140
  let drainDeadlineAt;
4112
4141
  let initialized = false;
4113
4142
  let visibleCache = "";
@@ -4191,8 +4220,19 @@ var createSmoothStreamController = (options = {}) => {
4191
4220
  if (!disposed && !cancelFrame && pending.length > 0) cancelFrame = schedule(tick);
4192
4221
  };
4193
4222
  const resegmentTail = () => {
4223
+ if (seam !== void 0 && seam < source.length && pending[pending.length - 1] === seam) {
4224
+ pending.pop();
4225
+ }
4194
4226
  const from = pending.length > 0 ? pending[pending.length - 1] : visibleEnd;
4195
- const ends = graphemeEnds(source.slice(from), from);
4227
+ let anchor = from;
4228
+ if (seam !== void 0 && from <= seam) {
4229
+ anchor = Math.max(0, from - RESUME_LOOKBACK);
4230
+ if (isMidSurrogatePair(source, anchor)) anchor -= 1;
4231
+ while (anchor >= 2 && isRegionalIndicatorAt(source, anchor - 2)) anchor -= 2;
4232
+ } else {
4233
+ seam = void 0;
4234
+ }
4235
+ const ends = graphemeEnds(source.slice(anchor), anchor);
4196
4236
  if (ends.length === 0) {
4197
4237
  tentativeEnd = from;
4198
4238
  return;
@@ -4204,7 +4244,7 @@ var createSmoothStreamController = (options = {}) => {
4204
4244
  if (last >= 55296 && last <= 56319) hold = 2;
4205
4245
  }
4206
4246
  const confirmedEnds = finished ? ends : ends.slice(0, -hold);
4207
- for (const end of confirmedEnds) pending.push(end);
4247
+ for (const end of confirmedEnds) if (end > from) pending.push(end);
4208
4248
  };
4209
4249
  const snap = (next) => {
4210
4250
  disposed = false;
@@ -4218,6 +4258,7 @@ var createSmoothStreamController = (options = {}) => {
4218
4258
  visibleEnd = next.length;
4219
4259
  tentativeEnd = next.length;
4220
4260
  pending = [];
4261
+ seam = next.length;
4221
4262
  credit = 0;
4222
4263
  cancelScheduled();
4223
4264
  if (visibleCache !== next) notify();
@@ -4252,6 +4293,7 @@ var createSmoothStreamController = (options = {}) => {
4252
4293
  if (tentativeEnd > (pending.length > 0 ? pending[pending.length - 1] : visibleEnd)) {
4253
4294
  pending.push(tentativeEnd);
4254
4295
  }
4296
+ seam = source.length;
4255
4297
  ensureScheduled();
4256
4298
  },
4257
4299
  snap,
@@ -4628,21 +4670,7 @@ function convertSingleToDoubleDollar(text) {
4628
4670
  }
4629
4671
  function preprocessLaTeX(str) {
4630
4672
  if (!hasLatexTrigger(str)) return str;
4631
- const segments = splitByProtectedRegions(str);
4632
- const result = segments.map((segment) => {
4633
- if (segment.isCode) return segment.text;
4634
- let text = segment.text;
4635
- text = escapeMhchemCommands(text);
4636
- text = escapeCurrencyDollarSigns(text);
4637
- text = convertLatexDelimiters(text);
4638
- text = escapeLatexPipes(text);
4639
- text = escapeLatexPipesInUnclosed(text);
4640
- text = escapeTextUnderscores(text);
4641
- text = convertSingleToDoubleDollar(text);
4642
- text = truncateUnclosedLatexBlock(text);
4643
- return text;
4644
- });
4645
- return result.join("");
4673
+ return processSlice(str, false).out;
4646
4674
  }
4647
4675
  function hasLatexTrigger(str) {
4648
4676
  return str.includes("$") || str.includes("\\[") || str.includes("\\(");
@@ -4671,7 +4699,7 @@ function hasUnclosedTextCommand(text) {
4671
4699
  }
4672
4700
  var RESIDUAL_OPEN_BRACKET_RE = /(?<!!)\\\[/;
4673
4701
  var LEADING_DOUBLE_DOLLAR_RE = /^\s*\$\$/;
4674
- function processSliceInstrumented(slice, probe = true) {
4702
+ function processSlice(slice, probe = true) {
4675
4703
  const segments = splitByProtectedRegions(slice);
4676
4704
  const parts = [];
4677
4705
  let quiescent = true;
@@ -4795,13 +4823,13 @@ function createIncrementalLatexPreprocessor(options) {
4795
4823
  };
4796
4824
  const cut = findRawSafeCut(active);
4797
4825
  if (cut > 0) {
4798
- const candidate = processSliceInstrumented(active.slice(0, cut));
4826
+ const candidate = processSlice(active.slice(0, cut));
4799
4827
  if (candidate.quiescent) freeze(cut, candidate);
4800
4828
  }
4801
4829
  nextAttemptLen = advanced || !backoff ? 0 : active.length * 2;
4802
4830
  onAttempt?.({ activeLength, frozenBytes });
4803
4831
  }
4804
- const tail = processSliceInstrumented(active, false);
4832
+ const tail = processSlice(active, false);
4805
4833
  const head = tail.truncatedAtSeamStart ? frozenOut.replace(/\s+$/, "") : frozenOut;
4806
4834
  const out = head + tail.out;
4807
4835
  prevSource = source;
@@ -4866,6 +4894,8 @@ function createRemendPreprocessor(options) {
4866
4894
  hasLoneSurrogate,
4867
4895
  highlight,
4868
4896
  isFootnoteSection,
4897
+ isWhitespaceText,
4898
+ lastMeaningfulIdx,
4869
4899
  measureStage,
4870
4900
  mergeClassNameAllowlist,
4871
4901
  normalizeForMatch,