@ai-react-markdown/engine 2.11.0 → 2.12.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/dist/index.js CHANGED
@@ -2131,6 +2131,38 @@ function normalizeForMatch(s) {
2131
2131
  return normalizeIdentifier3(s);
2132
2132
  }
2133
2133
 
2134
+ // src/components/blankLineScanner.ts
2135
+ function createBlankLineScanner() {
2136
+ let end = 0;
2137
+ let newline = false;
2138
+ let cr = false;
2139
+ return (source, from = 0) => {
2140
+ if (from === 0) {
2141
+ end = 0;
2142
+ newline = false;
2143
+ cr = false;
2144
+ }
2145
+ for (let i = from; i < source.length; i++) {
2146
+ const c = source[i];
2147
+ if (c === "\n") {
2148
+ if (newline) {
2149
+ end = i + 1;
2150
+ newline = false;
2151
+ } else newline = true;
2152
+ cr = false;
2153
+ } else if (newline) {
2154
+ if ((c === " " || c === " ") && !cr) continue;
2155
+ if (c === "\r" && !cr) cr = true;
2156
+ else {
2157
+ newline = false;
2158
+ cr = false;
2159
+ }
2160
+ }
2161
+ }
2162
+ return end;
2163
+ };
2164
+ }
2165
+
2134
2166
  // src/components/collectDefLabels.ts
2135
2167
  var SCANNER_BOUNDARY_PROFILE = { defListEnabled: false, mathFlow: false, referenceTaint: false };
2136
2168
  function buildProcessor() {
@@ -2162,19 +2194,12 @@ var setsEqual = (a, b) => {
2162
2194
  for (const v of a) if (!b.has(v)) return false;
2163
2195
  return true;
2164
2196
  };
2165
- var BLANK_LINE_RE = /\r?\n[ \t]*\r?\n/g;
2166
- function lastRegionStart(source) {
2167
- BLANK_LINE_RE.lastIndex = 0;
2168
- let start = 0;
2169
- for (let m = BLANK_LINE_RE.exec(source); m !== null; m = BLANK_LINE_RE.exec(source)) {
2170
- start = m.index + m[0].length;
2171
- }
2172
- return start;
2173
- }
2174
2197
  var DEF_LINE_START_RE = /^[ \t>*+\d.)-]*\[(?:[^\]\\]|\\[\s\S])*\]:/m;
2175
2198
  function createDefLabelScanner(parse = collectDefLabels) {
2176
2199
  let prevSource = null;
2177
2200
  let prevLabels = null;
2201
+ const scanBlankLines = createBlankLineScanner();
2202
+ let regionStart = 0;
2178
2203
  let frozenEnd = 0;
2179
2204
  let frozenFootnotes = /* @__PURE__ */ new Set();
2180
2205
  let frozenLinks = /* @__PURE__ */ new Set();
@@ -2187,13 +2212,16 @@ function createDefLabelScanner(parse = collectDefLabels) {
2187
2212
  };
2188
2213
  return {
2189
2214
  scan(source) {
2215
+ if (source === prevSource && prevLabels !== null) return prevLabels;
2216
+ const previousRegionStart = regionStart;
2217
+ const appended = prevSource !== null && source.startsWith(prevSource);
2218
+ regionStart = scanBlankLines(source, appended ? prevSource.length : 0);
2190
2219
  let isAppend = false;
2191
2220
  if (prevSource !== null && prevLabels !== null) {
2192
2221
  if (source === prevSource) return prevLabels;
2193
2222
  if (source.startsWith(prevSource)) {
2194
2223
  isAppend = true;
2195
- const regionStart = lastRegionStart(prevSource);
2196
- const region = prevSource.slice(regionStart) + source.slice(prevSource.length);
2224
+ const region = source.slice(previousRegionStart);
2197
2225
  if (!DEF_LINE_START_RE.test(region)) {
2198
2226
  prevSource = source;
2199
2227
  return prevLabels;
@@ -2426,8 +2454,47 @@ function* extractContributions(mdast, options = {}) {
2426
2454
  for (const c of out) yield c;
2427
2455
  }
2428
2456
 
2457
+ // src/components/registryIndex.ts
2458
+ function buildRegistryIndex(registry) {
2459
+ const index = {
2460
+ footnotes: /* @__PURE__ */ new Map(),
2461
+ links: /* @__PURE__ */ new Map(),
2462
+ numbers: /* @__PURE__ */ new Map(),
2463
+ counts: /* @__PURE__ */ new Map(),
2464
+ occurrences: /* @__PURE__ */ new Map()
2465
+ };
2466
+ for (const sym of registry.chunkOrder) {
2467
+ const data = registry.chunkData.get(sym);
2468
+ if (!data) continue;
2469
+ for (const label of data.defs.keys()) if (!index.footnotes.has(label)) index.footnotes.set(label, sym);
2470
+ for (const label of data.linkDefs.keys()) if (!index.links.has(label)) index.links.set(label, sym);
2471
+ const local = /* @__PURE__ */ new Map();
2472
+ index.occurrences.set(sym, local);
2473
+ for (const ref of data.refs) {
2474
+ if (ref.kind !== "footnote") continue;
2475
+ const label = ref.label;
2476
+ if (!index.numbers.has(label)) index.numbers.set(label, index.numbers.size + 1);
2477
+ const total = (index.counts.get(label) ?? 0) + 1;
2478
+ index.counts.set(label, total);
2479
+ const prior = local.get(label);
2480
+ if (prior) prior.count++;
2481
+ else local.set(label, { start: total, count: 1 });
2482
+ }
2483
+ }
2484
+ return index;
2485
+ }
2486
+
2429
2487
  // src/components/documentRegistry.ts
2430
2488
  function createRegistry(onEmpty) {
2489
+ let index;
2490
+ let indexedVersion = -1;
2491
+ const getIndex = () => {
2492
+ if (!index || indexedVersion !== reg.version) {
2493
+ index = buildRegistryIndex(reg);
2494
+ indexedVersion = reg.version;
2495
+ }
2496
+ return index;
2497
+ };
2431
2498
  const reg = {
2432
2499
  chunkOrder: [],
2433
2500
  chunkData: /* @__PURE__ */ new Map(),
@@ -2579,72 +2646,25 @@ function createRegistry(onEmpty) {
2579
2646
  };
2580
2647
  },
2581
2648
  canonicalFootnoteFor(label) {
2582
- const id = normalizeId(label);
2583
- for (const sym of this.chunkOrder) {
2584
- const data = this.chunkData.get(sym);
2585
- if (data?.defs.has(id)) return sym;
2586
- }
2587
- return null;
2649
+ return getIndex().footnotes.get(normalizeId(label)) ?? null;
2588
2650
  },
2589
2651
  canonicalLinkFor(label) {
2590
- const id = normalizeId(label);
2591
- for (const sym of this.chunkOrder) {
2592
- const data = this.chunkData.get(sym);
2593
- if (data?.linkDefs.has(id)) return sym;
2594
- }
2595
- return null;
2652
+ return getIndex().links.get(normalizeId(label)) ?? null;
2596
2653
  },
2597
2654
  globalNumber(label) {
2598
- const id = normalizeId(label);
2599
- let n = 0;
2600
- const seen = /* @__PURE__ */ new Set();
2601
- for (const sym of this.chunkOrder) {
2602
- const data = this.chunkData.get(sym);
2603
- if (!data) continue;
2604
- for (const ref of data.refs) {
2605
- if (ref.kind !== "footnote") continue;
2606
- if (!seen.has(ref.label)) {
2607
- seen.add(ref.label);
2608
- n++;
2609
- if (ref.label === id) return n;
2610
- }
2611
- }
2612
- }
2613
- return null;
2655
+ return getIndex().numbers.get(normalizeId(label)) ?? null;
2614
2656
  },
2615
2657
  resolveLinkDef(label) {
2616
- const sym = this.canonicalLinkFor(label);
2617
- if (!sym) return null;
2618
- return this.chunkData.get(sym)?.linkDefs.get(normalizeId(label)) ?? null;
2658
+ const id = normalizeId(label);
2659
+ const sym = getIndex().links.get(id);
2660
+ return sym ? this.chunkData.get(sym)?.linkDefs.get(id) ?? null : null;
2619
2661
  },
2620
2662
  getRefsForLabel(label) {
2621
- const id = normalizeId(label);
2622
- let n = 0;
2623
- for (const sym of this.chunkOrder) {
2624
- const data = this.chunkData.get(sym);
2625
- if (!data) continue;
2626
- for (const ref of data.refs) {
2627
- if (ref.kind === "footnote" && ref.label === id) n++;
2628
- }
2629
- }
2630
- return n;
2663
+ return getIndex().counts.get(normalizeId(label)) ?? 0;
2631
2664
  },
2632
2665
  globalOccurrenceForRef(chunkSym, label, localOccurrence) {
2633
- const id = normalizeId(label);
2634
- let global2 = 0;
2635
- for (const sym of this.chunkOrder) {
2636
- const data = this.chunkData.get(sym);
2637
- if (!data) continue;
2638
- let localCount = 0;
2639
- for (const ref of data.refs) {
2640
- if (ref.kind !== "footnote") continue;
2641
- if (ref.label !== id) continue;
2642
- localCount++;
2643
- global2++;
2644
- if (sym === chunkSym && localCount === localOccurrence) return global2;
2645
- }
2646
- }
2647
- return null;
2666
+ const range = getIndex().occurrences.get(chunkSym)?.get(normalizeId(label));
2667
+ return range && Number.isInteger(localOccurrence) && localOccurrence > 0 && localOccurrence <= range.count ? range.start + localOccurrence - 1 : null;
2648
2668
  },
2649
2669
  _notify() {
2650
2670
  this.version++;
@@ -2709,7 +2729,7 @@ var ENGINE_PLACEHOLDER_TAGS = /* @__PURE__ */ new Set([
2709
2729
  "cross-chunk-image"
2710
2730
  ]);
2711
2731
  var ENGINE_PROVENANCE_PROPERTY = "engineProvenance";
2712
- function walk(parent, provenance) {
2732
+ function walk(parent, provenance, ancestors) {
2713
2733
  const children = parent.children;
2714
2734
  let i = 0;
2715
2735
  while (i < children.length) {
@@ -2720,21 +2740,32 @@ function walk(parent, provenance) {
2720
2740
  const genuine = provenance !== "" && typeof stamped === "string" && stamped === provenance;
2721
2741
  if (genuine) {
2722
2742
  delete props[ENGINE_PROVENANCE_PROPERTY];
2723
- walk(node, provenance);
2743
+ if (ancestors && (node.tagName === "cross-chunk-link" || node.tagName === "cross-chunk-image")) {
2744
+ (node.data ??= {}).referenceAncestors = ancestors.slice();
2745
+ }
2746
+ ancestors?.push(
2747
+ node.tagName === "cross-chunk-link" ? "a" : node.tagName === "cross-chunk-image" ? "img" : node.tagName
2748
+ );
2749
+ walk(node, provenance, ancestors);
2750
+ ancestors?.pop();
2724
2751
  i += 1;
2725
2752
  } else {
2726
2753
  children.splice(i, 1, ...node.children);
2727
2754
  }
2728
2755
  continue;
2729
2756
  }
2730
- if (node.type === "element") walk(node, provenance);
2757
+ if (node.type === "element") {
2758
+ ancestors?.push(node.tagName);
2759
+ walk(node, provenance, ancestors);
2760
+ ancestors?.pop();
2761
+ }
2731
2762
  i += 1;
2732
2763
  }
2733
2764
  }
2734
2765
  function rehypeVerifyEngineTags(options) {
2735
2766
  const provenance = options?.provenance ?? "";
2736
2767
  return function transformer(tree) {
2737
- walk(tree, provenance);
2768
+ walk(tree, provenance, options?.referenceAncestors ? [] : void 0);
2738
2769
  };
2739
2770
  }
2740
2771
 
@@ -2755,16 +2786,18 @@ import remarkRemoveComments from "remark-remove-comments";
2755
2786
  // src/components/rehypeRebaseHashLinks.ts
2756
2787
  import { visit as visit5 } from "unist-util-visit";
2757
2788
  var DEFAULT_PREFIX = "user-content-";
2789
+ function rebaseHashHref(href, prefix) {
2790
+ const hashPrefix = "#" + prefix;
2791
+ return href.startsWith("#") && !href.startsWith(hashPrefix) ? hashPrefix + href.slice(1) : href;
2792
+ }
2758
2793
  var rehypeRebaseHashLinks = (options) => {
2759
2794
  const prefix = options?.prefix ?? DEFAULT_PREFIX;
2760
- const hashPrefix = "#" + prefix;
2761
2795
  return (tree) => {
2762
2796
  visit5(tree, "element", (node) => {
2763
2797
  if (node.tagName !== "a") return;
2764
2798
  const href = node.properties?.href;
2765
2799
  if (typeof href !== "string" || !href.startsWith("#")) return;
2766
- if (href.startsWith(hashPrefix)) return;
2767
- node.properties.href = hashPrefix + href.slice(1);
2800
+ node.properties.href = rebaseHashHref(href, prefix);
2768
2801
  });
2769
2802
  };
2770
2803
  };
@@ -2850,7 +2883,15 @@ function buildCoreRehypePlugins(sanitizeSchema2, clobberPrefix, options) {
2850
2883
  [rehypeRaw, { passThrough: [] }],
2851
2884
  // Unwrap forged engine placeholders BEFORE sanitize admits their tag
2852
2885
  // names. Only when the caller holds a credential (see the option's doc).
2853
- ...options ? [[rehypeVerifyEngineTags, { provenance: options.provenance }]] : [],
2886
+ ...options ? [
2887
+ [
2888
+ rehypeVerifyEngineTags,
2889
+ {
2890
+ provenance: options.provenance,
2891
+ ...sanitizeSchema2.ancestors?.a || sanitizeSchema2.ancestors?.img ? { referenceAncestors: true } : {}
2892
+ }
2893
+ ]
2894
+ ] : [],
2854
2895
  // Sanitize HTML while allowing <mark> (highlight), KaTeX class names,
2855
2896
  // and any extra protocols the caller permitted via the `sanitizeSchema`
2856
2897
  // prop. Override `clobberPrefix` with the instance-scoped value — the
@@ -2924,11 +2965,9 @@ function buildCrossChunkHandlers() {
2924
2965
  type: "element",
2925
2966
  tagName: "cross-chunk-link",
2926
2967
  properties: {
2927
- // `label` is the ORIGINAL source text (mdast's `label` field), NOT
2928
- // the normalized `identifier`. The placeholder uses it to construct
2929
- // hrefs that line up with mdast-util-to-hast's default `<li id>`
2930
- // which also preserves source case. Registry lookups normalize
2931
- // internally, so cross-chunk case-insensitive matching still works.
2968
+ // Display labels decode escapes; registry identifiers must retain
2969
+ // those bytes. Never use the display label as the lookup key.
2970
+ identifier: node.identifier,
2932
2971
  label: node.label ?? node.identifier,
2933
2972
  referenceType: node.referenceType,
2934
2973
  documentId: s.options.documentId,
@@ -2947,6 +2986,7 @@ function buildCrossChunkHandlers() {
2947
2986
  type: "element",
2948
2987
  tagName: "cross-chunk-image",
2949
2988
  properties: {
2989
+ identifier: node.identifier,
2950
2990
  label: node.label ?? node.identifier,
2951
2991
  referenceType: node.referenceType,
2952
2992
  alt: node.alt ?? "",
@@ -4209,8 +4249,8 @@ var sanitizeSchema = deepFreeze(
4209
4249
  attributes: {
4210
4250
  ...defaultSchema.attributes,
4211
4251
  code: mergeClassNameAllowlist(defaultSchema.attributes?.code, ["math-inline", "math-display"]),
4212
- "cross-chunk-link": ["label", "referenceType", "documentId", "localUrl", "localTitle"],
4213
- "cross-chunk-image": ["label", "referenceType", "documentId", "alt", "localUrl", "localTitle"],
4252
+ "cross-chunk-link": ["identifier", "label", "referenceType", "documentId", "localUrl", "localTitle"],
4253
+ "cross-chunk-image": ["identifier", "label", "referenceType", "documentId", "alt", "localUrl", "localTitle"],
4214
4254
  "footnote-sup": ["label", "localOccurrence", "localNumber", "documentId"]
4215
4255
  },
4216
4256
  strip: [.../* @__PURE__ */ new Set([...defaultSchema.strip || [], ...STRIPPED_TAGS])]
@@ -4246,6 +4286,49 @@ function sanitizeCrossChunkUrl(rawUrl, key, tagName, urlTransform, schema) {
4246
4286
  return String(transformed);
4247
4287
  }
4248
4288
 
4289
+ // src/components/resolveCrossChunkReference.ts
4290
+ import rehypeSanitize2 from "rehype-sanitize";
4291
+ import { normalizeUri as normalizeUri3 } from "micromark-util-sanitize-uri";
4292
+ function resolveCrossChunkReference(input, schema, urlTransform, clobberPrefix) {
4293
+ const key = input.tagName === "a" ? "href" : "src";
4294
+ const element = {
4295
+ type: "element",
4296
+ tagName: input.tagName,
4297
+ properties: {
4298
+ [key]: normalizeUri3(input.url),
4299
+ ...input.tagName === "img" ? { alt: input.alt ?? "" } : {},
4300
+ ...input.title !== void 0 ? { title: input.title } : {}
4301
+ },
4302
+ children: input.tagName === "a" ? [{ type: "text", value: "__reference_children__" }] : []
4303
+ };
4304
+ const requiredAncestors = schema.ancestors?.[input.tagName];
4305
+ const recordedAncestors = input.node?.data?.referenceAncestors;
4306
+ let finalSchema = schema;
4307
+ if (requiredAncestors && Array.isArray(recordedAncestors) && requiredAncestors.some((tag) => recordedAncestors.includes(tag))) {
4308
+ const ancestors = { ...schema.ancestors };
4309
+ delete ancestors[input.tagName];
4310
+ finalSchema = { ...schema, ancestors };
4311
+ }
4312
+ const root2 = rehypeSanitize2({ ...finalSchema, clobberPrefix })({ type: "root", children: [element] });
4313
+ const node = root2.children[0];
4314
+ if (node?.type !== "element") return { element: null, keepChildren: node?.type === "text" };
4315
+ if (node.tagName === "a" && typeof node.properties.href === "string") {
4316
+ node.properties.href = rebaseHashHref(node.properties.href, clobberPrefix);
4317
+ }
4318
+ node.children = input.node?.children ?? [];
4319
+ if (input.node?.position) node.position = input.node.position;
4320
+ buildTransform({
4321
+ allowedElements: void 0,
4322
+ disallowedElements: void 0,
4323
+ allowElement: void 0,
4324
+ skipHtml: void 0,
4325
+ unwrapDisallowed: void 0,
4326
+ urlTransform
4327
+ })(node, 0, root2);
4328
+ node.children = [];
4329
+ return { element: node, keepChildren: false };
4330
+ }
4331
+
4249
4332
  // src/plugins/defs.ts
4250
4333
  function getEnginePluginInternals(plugin) {
4251
4334
  const candidate = plugin;
@@ -4450,6 +4533,8 @@ var createSmoothStreamController = (options = {}) => {
4450
4533
  let source = "";
4451
4534
  let visibleEnd = 0;
4452
4535
  let pending = [];
4536
+ let pendingHead = 0;
4537
+ const pendingCount = () => pending.length - pendingHead;
4453
4538
  let tentativeEnd = 0;
4454
4539
  let finished = false;
4455
4540
  let seam;
@@ -4494,7 +4579,7 @@ var createSmoothStreamController = (options = {}) => {
4494
4579
  cancelFrame = void 0;
4495
4580
  };
4496
4581
  const ensureScheduled = () => {
4497
- if (disposed || cancelFrame || pending.length === 0) return;
4582
+ if (disposed || cancelFrame || pendingCount() === 0) return;
4498
4583
  lastTickAt = now();
4499
4584
  credit = 0;
4500
4585
  cancelFrame = schedule(tick);
@@ -4508,31 +4593,38 @@ var createSmoothStreamController = (options = {}) => {
4508
4593
  const params = resolveParams();
4509
4594
  let rate;
4510
4595
  if (finished && drainDeadlineAt !== void 0) {
4511
- rate = Math.max(params.minCharsPerSecond, pending.length * 1e3 / Math.max(1, drainDeadlineAt - t));
4596
+ rate = Math.max(params.minCharsPerSecond, pendingCount() * 1e3 / Math.max(1, drainDeadlineAt - t));
4512
4597
  } else if (gapWindow.length > 0 && lastArrivalAt !== void 0) {
4513
4598
  const gaps = gapWindow.map((s) => s.gap).sort((a, b) => a - b);
4514
4599
  const intervalQ = gaps[Math.min(gaps.length - 1, Math.floor(gaps.length * INTERVAL_QUANTILE))];
4515
4600
  const horizon = Math.max(16, Math.min(params.bufferFactor * intervalQ + HORIZON_PAD_MS, params.maxLagMs));
4516
4601
  const deadline = Math.max(lastArrivalAt + horizon, t + DEADLINE_FLOOR_MS);
4517
- rate = Math.max(params.minCharsPerSecond, pending.length * 1e3 / Math.max(1, deadline - t));
4602
+ rate = Math.max(params.minCharsPerSecond, pendingCount() * 1e3 / Math.max(1, deadline - t));
4518
4603
  } else {
4519
- rate = Math.max(params.minCharsPerSecond, pending.length * 1e3 / Math.max(1, params.correctionTauMs));
4604
+ rate = Math.max(params.minCharsPerSecond, pendingCount() * 1e3 / Math.max(1, params.correctionTauMs));
4520
4605
  }
4521
4606
  credit += rate * dt / 1e3;
4522
- const reveal = Math.min(Math.floor(credit), pending.length);
4607
+ const reveal = Math.min(Math.floor(credit), pendingCount());
4523
4608
  if (reveal > 0) {
4524
- visibleEnd = pending[reveal - 1];
4525
- pending = pending.slice(reveal);
4526
- credit = pending.length > 0 ? credit - reveal : 0;
4609
+ visibleEnd = pending[pendingHead + reveal - 1];
4610
+ pendingHead += reveal;
4611
+ if (pendingHead === pending.length) {
4612
+ pending = [];
4613
+ pendingHead = 0;
4614
+ } else if (pendingHead >= 1024 && pendingHead * 2 >= pending.length) {
4615
+ pending = pending.slice(pendingHead);
4616
+ pendingHead = 0;
4617
+ }
4618
+ credit = pendingCount() > 0 ? credit - reveal : 0;
4527
4619
  notify();
4528
4620
  }
4529
- if (!disposed && !cancelFrame && pending.length > 0) cancelFrame = schedule(tick);
4621
+ if (!disposed && !cancelFrame && pendingCount() > 0) cancelFrame = schedule(tick);
4530
4622
  };
4531
4623
  const resegmentTail = () => {
4532
- if (seam !== void 0 && seam < source.length && pending[pending.length - 1] === seam) {
4624
+ if (pendingCount() > 0 && seam !== void 0 && seam < source.length && pending[pending.length - 1] === seam) {
4533
4625
  pending.pop();
4534
4626
  }
4535
- const from = pending.length > 0 ? pending[pending.length - 1] : visibleEnd;
4627
+ const from = pendingCount() > 0 ? pending[pending.length - 1] : visibleEnd;
4536
4628
  let anchor = from;
4537
4629
  if (seam !== void 0 && from <= seam) {
4538
4630
  anchor = Math.max(0, from - RESUME_LOOKBACK);
@@ -4566,6 +4658,7 @@ var createSmoothStreamController = (options = {}) => {
4566
4658
  visibleEnd = next.length;
4567
4659
  tentativeEnd = next.length;
4568
4660
  pending = [];
4661
+ pendingHead = 0;
4569
4662
  seam = next.length;
4570
4663
  credit = 0;
4571
4664
  cancelScheduled();
@@ -4597,7 +4690,7 @@ var createSmoothStreamController = (options = {}) => {
4597
4690
  if (finished) return;
4598
4691
  finished = true;
4599
4692
  lastArrivalAt = void 0;
4600
- if (tentativeEnd > (pending.length > 0 ? pending[pending.length - 1] : visibleEnd)) {
4693
+ if (tentativeEnd > (pendingCount() > 0 ? pending[pending.length - 1] : visibleEnd)) {
4601
4694
  pending.push(tentativeEnd);
4602
4695
  }
4603
4696
  const params = resolveParams();
@@ -4623,10 +4716,11 @@ var createSmoothStreamController = (options = {}) => {
4623
4716
  snap,
4624
4717
  flush() {
4625
4718
  disposed = false;
4626
- const target = finished ? source.length : pending.length > 0 ? pending[pending.length - 1] : visibleEnd;
4719
+ const target = finished ? source.length : pendingCount() > 0 ? pending[pending.length - 1] : visibleEnd;
4627
4720
  if (target <= visibleEnd) return;
4628
4721
  visibleEnd = target;
4629
4722
  pending = [];
4723
+ pendingHead = 0;
4630
4724
  credit = 0;
4631
4725
  cancelScheduled();
4632
4726
  notify();
@@ -5476,6 +5570,7 @@ export {
5476
5570
  rehypeRebaseHashLinks_default as rehypeRebaseHashLinks,
5477
5571
  rehypeVerifyEngineTags,
5478
5572
  removeComments,
5573
+ resolveCrossChunkReference,
5479
5574
  sanitizeCrossChunkUrl,
5480
5575
  sanitizeSchema,
5481
5576
  shortenDocumentId,