@stream-mdx/worker 0.2.0 → 0.4.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.
@@ -17946,7 +17946,7 @@ function getGroupContents(expression, contentsStartPos) {
17946
17946
  return expression.slice(contentsStartPos, contentsEndPos);
17947
17947
  }
17948
17948
 
17949
- // node_modules/regex/src/subclass.js
17949
+ // ../../node_modules/regex/src/subclass.js
17950
17950
  var emulationGroupMarker = "$E$";
17951
17951
  var RegExpSubclass = class _RegExpSubclass extends RegExp {
17952
17952
  /**
@@ -18059,13 +18059,13 @@ function unmarkEmulationGroups(expression) {
18059
18059
  };
18060
18060
  }
18061
18061
 
18062
- // node_modules/regex/src/utils-internals.js
18062
+ // ../../node_modules/regex/src/utils-internals.js
18063
18063
  var noncapturingDelim = String.raw`\(\?(?:[:=!>A-Za-z\-]|<[=!]|\(DEFINE\))`;
18064
18064
  function spliceStr(str, pos, oldValue, newValue) {
18065
18065
  return str.slice(0, pos) + newValue + str.slice(pos + oldValue.length);
18066
18066
  }
18067
18067
 
18068
- // node_modules/regex/src/atomic.js
18068
+ // ../../node_modules/regex/src/atomic.js
18069
18069
  var atomicPluginToken = new RegExp(String.raw`(?<noncapturingStart>${noncapturingDelim})|(?<capturingStart>\((?:\?<[^>]+>)?)|\\?.`, "gsu");
18070
18070
  function atomic(expression, data2) {
18071
18071
  if (!/\(\?>/.test(expression)) {
@@ -18206,7 +18206,7 @@ function possessive(expression) {
18206
18206
  return expression;
18207
18207
  }
18208
18208
 
18209
- // node_modules/regex-recursion/src/index.js
18209
+ // ../../node_modules/regex-recursion/src/index.js
18210
18210
  var r2 = String.raw;
18211
18211
  var gRToken = r2`\\g<(?<gRNameOrNum>[^>&]+)&R=(?<gRDepth>[^>]+)>`;
18212
18212
  var recursiveToken = r2`\(\?R=(?<rDepth>[^\)]+)\)|${gRToken}`;
@@ -18356,7 +18356,7 @@ function emulationGroupMarkerLength(expression, index2) {
18356
18356
  return match ? match[0].length : 0;
18357
18357
  }
18358
18358
 
18359
- // node_modules/oniguruma-to-es/dist/esm/index.js
18359
+ // ../../node_modules/oniguruma-to-es/dist/esm/index.js
18360
18360
  var cp = String.fromCodePoint;
18361
18361
  var r3 = String.raw;
18362
18362
  var envSupportsFlagGroups = (() => {
@@ -21379,7 +21379,7 @@ function toRegExp(pattern, options) {
21379
21379
  return new RegExp(result.pattern, result.flags);
21380
21380
  }
21381
21381
 
21382
- // node_modules/@shikijs/engine-javascript/dist/shared/engine-javascript.hzpS1_41.mjs
21382
+ // ../../node_modules/@shikijs/engine-javascript/dist/shared/engine-javascript.hzpS1_41.mjs
21383
21383
  var MAX = 4294967295;
21384
21384
  var JavaScriptScanner = class {
21385
21385
  constructor(patterns, options = {}) {
@@ -21472,7 +21472,7 @@ var JavaScriptScanner = class {
21472
21472
  }
21473
21473
  };
21474
21474
 
21475
- // node_modules/@shikijs/engine-javascript/dist/engine-compile.mjs
21475
+ // ../../node_modules/@shikijs/engine-javascript/dist/engine-compile.mjs
21476
21476
  function defaultJavaScriptRegexConstructor(pattern, options) {
21477
21477
  return toRegExp(
21478
21478
  pattern,
@@ -82144,6 +82144,9 @@ var lastStructuralDiffSummary = null;
82144
82144
  var maxEmittedBlockCount = 0;
82145
82145
  var maxDeferredQueueSize = 0;
82146
82146
  var maxStructuralBlockCount = 0;
82147
+ var tocHeadings = [];
82148
+ var tocSignature = "";
82149
+ var headingIdCounts = /* @__PURE__ */ new Map();
82147
82150
  var lastHighCountNoStructural = null;
82148
82151
  var MAX_DEFERRED_PATCHES = 400;
82149
82152
  var deferredPatchQueue = [];
@@ -82165,6 +82168,9 @@ var mdxCompileMode = "server";
82165
82168
  var formatAnticipationConfig = normalizeFormatAnticipation(false);
82166
82169
  var codeHighlightingMode = "final";
82167
82170
  var highlightOutputMode = "html";
82171
+ var emitHighlightTokens = true;
82172
+ var emitDiffBlocks = false;
82173
+ var liveTokenizationEnabled = true;
82168
82174
  var enableMath = true;
82169
82175
  var mdxComponentAllowlist = null;
82170
82176
  var WORKER_MDX_CACHE = /* @__PURE__ */ new Map();
@@ -82576,12 +82582,57 @@ function parseInlineStreaming(content4) {
82576
82582
  status
82577
82583
  };
82578
82584
  }
82585
+ function slugifyHeading(text12) {
82586
+ const normalized = text12.trim().toLowerCase().replace(/[\u0000-\u001f]/g, "").replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "").replace(/-{2,}/g, "-");
82587
+ return normalized;
82588
+ }
82589
+ function buildTocHeadings(blocksInput) {
82590
+ const headings = [];
82591
+ for (const block of blocksInput) {
82592
+ if (block.type !== "heading") continue;
82593
+ const meta2 = block.payload.meta ?? {};
82594
+ const rawHeading = typeof block.payload.raw === "string" ? block.payload.raw : "";
82595
+ const headingText = typeof meta2.headingText === "string" && meta2.headingText.trim().length > 0 ? meta2.headingText : removeHeadingMarkers(rawHeading).trim();
82596
+ const levelFromMeta = typeof meta2.headingLevel === "number" ? meta2.headingLevel : 1;
82597
+ const level = Math.min(Math.max(levelFromMeta, 1), 6);
82598
+ const id = typeof meta2.headingId === "string" && meta2.headingId.trim().length > 0 ? meta2.headingId : slugifyHeading(headingText) || "heading";
82599
+ headings.push({
82600
+ id,
82601
+ text: headingText,
82602
+ level,
82603
+ blockId: block.id
82604
+ });
82605
+ }
82606
+ return headings;
82607
+ }
82608
+ function tocSignatureFor(headings) {
82609
+ if (headings.length === 0) return "";
82610
+ return headings.map((heading4) => `${heading4.id}:${heading4.level}:${heading4.text}`).join("|");
82611
+ }
82612
+ function maybeBuildTocPatch(blocksInput) {
82613
+ const nextHeadings = buildTocHeadings(blocksInput);
82614
+ const nextSignature = tocSignatureFor(nextHeadings);
82615
+ tocHeadings = nextHeadings;
82616
+ if (nextSignature === tocSignature) {
82617
+ return null;
82618
+ }
82619
+ tocSignature = nextSignature;
82620
+ return {
82621
+ op: "setProps",
82622
+ at: { blockId: PATCH_ROOT_ID },
82623
+ props: {
82624
+ tocHeadings: nextHeadings
82625
+ }
82626
+ };
82627
+ }
82579
82628
  async function initialize(initialContent = "", prewarmLangs = [], docPlugins, mdxOptions) {
82580
82629
  performanceTimer = new PerformanceTimer();
82581
82630
  blocks = [];
82582
82631
  lastTree = null;
82583
82632
  currentContent = "";
82584
82633
  deferredPatchQueue = [];
82634
+ tocHeadings = [];
82635
+ tocSignature = "";
82585
82636
  resetIncrementalHighlightState();
82586
82637
  lazyTokenizationStates.clear();
82587
82638
  lazyTokenizationQueue.clear();
@@ -82604,7 +82655,10 @@ async function initialize(initialContent = "", prewarmLangs = [], docPlugins, md
82604
82655
  math: docPlugins?.math ?? true,
82605
82656
  formatAnticipation: docPlugins?.formatAnticipation ?? false,
82606
82657
  codeHighlighting: docPlugins?.codeHighlighting,
82607
- liveCodeHighlighting: docPlugins?.liveCodeHighlighting ?? false
82658
+ liveCodeHighlighting: docPlugins?.liveCodeHighlighting ?? false,
82659
+ liveTokenization: docPlugins?.liveTokenization ?? true,
82660
+ emitHighlightTokens: docPlugins?.emitHighlightTokens ?? true,
82661
+ emitDiffBlocks: docPlugins?.emitDiffBlocks ?? false
82608
82662
  };
82609
82663
  enableMath = enable.math;
82610
82664
  formatAnticipationConfig = normalizeFormatAnticipation(enable.formatAnticipation);
@@ -82618,6 +82672,9 @@ async function initialize(initialContent = "", prewarmLangs = [], docPlugins, md
82618
82672
  } else {
82619
82673
  highlightOutputMode = "html";
82620
82674
  }
82675
+ emitHighlightTokens = enable.emitHighlightTokens;
82676
+ emitDiffBlocks = enable.emitDiffBlocks;
82677
+ liveTokenizationEnabled = enable.liveTokenization;
82621
82678
  if (docPlugins?.lazyTokenization) {
82622
82679
  lazyTokenizationEnabled = docPlugins.lazyTokenization.enabled ?? true;
82623
82680
  const desiredThreshold = docPlugins.lazyTokenization.thresholdLines ?? DEFAULT_LAZY_TOKENIZATION_THRESHOLD;
@@ -82744,6 +82801,7 @@ async function appendAndReparse(appendedText, metrics) {
82744
82801
  }
82745
82802
  async function extractBlocks(tree, content4, options = {}) {
82746
82803
  try {
82804
+ headingIdCounts = /* @__PURE__ */ new Map();
82747
82805
  const blocks2 = [];
82748
82806
  const cursor = tree.cursor();
82749
82807
  if (cursor.firstChild()) {
@@ -82836,10 +82894,15 @@ async function enrichBlock(block) {
82836
82894
  const rawHeading = typeof block.payload.raw === "string" ? block.payload.raw : "";
82837
82895
  const normalizedHeading = removeHeadingMarkers(rawHeading);
82838
82896
  const headingLevel = Math.min(Math.max(rawHeading.match(/^#{1,6}/)?.[0].length ?? 1, 1), 6);
82897
+ const baseSlug = slugifyHeading(normalizedHeading) || "heading";
82898
+ const nextCount = (headingIdCounts.get(baseSlug) ?? 0) + 1;
82899
+ headingIdCounts.set(baseSlug, nextCount);
82900
+ const headingId = nextCount > 1 ? `${baseSlug}-${nextCount}` : baseSlug;
82839
82901
  block.payload.meta = {
82840
82902
  ...block.payload.meta ?? {},
82841
82903
  headingLevel,
82842
- headingText: normalizedHeading
82904
+ headingText: normalizedHeading,
82905
+ headingId
82843
82906
  };
82844
82907
  if (block.isFinalized) {
82845
82908
  block.payload.raw = normalizedHeading;
@@ -83302,6 +83365,154 @@ function parseUnifiedDiffLine(line, cursor) {
83302
83365
  }
83303
83366
  return { text: line, kind: "meta", prefix: "", content: line, oldNo: null, newNo: null };
83304
83367
  }
83368
+ function normalizeDiffPath(value) {
83369
+ if (!value) return null;
83370
+ let path3 = value.trim();
83371
+ if (!path3 || path3 === "/dev/null") return null;
83372
+ if (path3.startsWith('"') && path3.endsWith('"') || path3.startsWith("'") && path3.endsWith("'")) {
83373
+ path3 = path3.slice(1, -1);
83374
+ }
83375
+ if (path3.startsWith("a/") || path3.startsWith("b/")) {
83376
+ path3 = path3.slice(2);
83377
+ }
83378
+ return path3 || null;
83379
+ }
83380
+ function extractDiffFilePath(line) {
83381
+ if (line.startsWith("diff --git")) {
83382
+ const match = line.match(/^diff --git\\s+(\\S+)\\s+(\\S+)/);
83383
+ if (match) {
83384
+ return normalizeDiffPath(match[2] ?? match[1] ?? null);
83385
+ }
83386
+ }
83387
+ if (line.startsWith("+++ ") || line.startsWith("--- ")) {
83388
+ const path3 = normalizeDiffPath(line.slice(4));
83389
+ return path3;
83390
+ }
83391
+ if (line.startsWith("rename to ")) {
83392
+ return normalizeDiffPath(line.slice("rename to ".length));
83393
+ }
83394
+ return null;
83395
+ }
83396
+ function looksLikeUnifiedDiff(lines) {
83397
+ if (lines.length === 0) return false;
83398
+ for (const line of lines) {
83399
+ if (line.startsWith("diff --git") || line.startsWith("@@") || line.startsWith("+++ ") || line.startsWith("--- ")) {
83400
+ return true;
83401
+ }
83402
+ }
83403
+ return false;
83404
+ }
83405
+ function guessLanguageFromPath(filePath) {
83406
+ if (!filePath) return null;
83407
+ const parts = filePath.split(/[\\\\/]/);
83408
+ const file = parts[parts.length - 1] ?? "";
83409
+ const idx = file.lastIndexOf(".");
83410
+ if (idx <= 0 || idx >= file.length - 1) return null;
83411
+ const ext = file.slice(idx + 1);
83412
+ return normalizeLang(ext);
83413
+ }
83414
+ function guessLanguageFromDiffLines(lines) {
83415
+ for (const line of lines) {
83416
+ const filePath = extractDiffFilePath(line);
83417
+ if (filePath) {
83418
+ const guessed = guessLanguageFromPath(filePath);
83419
+ if (guessed) return guessed;
83420
+ }
83421
+ }
83422
+ return null;
83423
+ }
83424
+ function toDiffLineKind(kind) {
83425
+ if (kind === "remove") return "del";
83426
+ return kind;
83427
+ }
83428
+ function toThemedLine(tokenLine, theme) {
83429
+ if (!tokenLine) return null;
83430
+ return tokenLine.spans.map((span) => {
83431
+ const style2 = span.s ?? span.v?.[theme];
83432
+ const color3 = typeof style2?.fg === "string" ? style2.fg : null;
83433
+ const fontStyle = typeof style2?.fs === "number" ? style2.fs : null;
83434
+ return {
83435
+ content: span.t,
83436
+ color: color3,
83437
+ fontStyle
83438
+ };
83439
+ });
83440
+ }
83441
+ function stripPrefixFromThemedLine(tokens, prefix) {
83442
+ if (!tokens || !prefix) return tokens;
83443
+ if (tokens.length === 0) return tokens;
83444
+ const first = tokens[0];
83445
+ if (first.content === prefix) {
83446
+ return tokens.slice(1);
83447
+ }
83448
+ if (first.content.startsWith(prefix)) {
83449
+ const trimmed = first.content.slice(prefix.length);
83450
+ const next2 = trimmed ? [{ ...first, content: trimmed }, ...tokens.slice(1)] : tokens.slice(1);
83451
+ return next2;
83452
+ }
83453
+ return tokens;
83454
+ }
83455
+ function buildDiffBlocksFromLines(lines, rawLines, tokenLines, defaultLanguage) {
83456
+ const blocks2 = [];
83457
+ let current2 = null;
83458
+ let currentRaw = [];
83459
+ let additions = 0;
83460
+ let deletions = 0;
83461
+ const finalize = () => {
83462
+ if (!current2) return;
83463
+ current2.additions = additions;
83464
+ current2.deletions = deletions;
83465
+ if (currentRaw.length > 0) {
83466
+ current2.unified = currentRaw.join("\n");
83467
+ }
83468
+ blocks2.push(current2);
83469
+ current2 = null;
83470
+ currentRaw = [];
83471
+ additions = 0;
83472
+ deletions = 0;
83473
+ };
83474
+ for (let i = 0; i < lines.length; i++) {
83475
+ const line = lines[i];
83476
+ const raw2 = rawLines[i] ?? line.text;
83477
+ const filePath = extractDiffFilePath(raw2);
83478
+ if (raw2.startsWith("diff --git")) {
83479
+ finalize();
83480
+ }
83481
+ if (!current2) {
83482
+ current2 = {
83483
+ kind: "diff",
83484
+ filePath: filePath ?? null,
83485
+ language: filePath ? guessLanguageFromPath(filePath) ?? defaultLanguage : defaultLanguage,
83486
+ lines: [],
83487
+ additions: null,
83488
+ deletions: null,
83489
+ unified: null
83490
+ };
83491
+ } else if (filePath && !current2.filePath) {
83492
+ current2.filePath = filePath;
83493
+ if (!current2.language) {
83494
+ current2.language = guessLanguageFromPath(filePath) ?? defaultLanguage;
83495
+ }
83496
+ }
83497
+ if (line.kind === "add") additions += 1;
83498
+ if (line.kind === "remove") deletions += 1;
83499
+ let themed = tokenLines ? toThemedLine(tokenLines[i] ?? null, "dark") : null;
83500
+ if (line.kind === "add" || line.kind === "remove" || line.kind === "context") {
83501
+ themed = stripPrefixFromThemedLine(themed, line.prefix);
83502
+ }
83503
+ const entry = {
83504
+ kind: toDiffLineKind(line.kind),
83505
+ oldNo: line.oldNo ?? null,
83506
+ newNo: line.newNo ?? null,
83507
+ raw: raw2,
83508
+ tokens: themed ?? null
83509
+ };
83510
+ current2.lines.push(entry);
83511
+ currentRaw.push(raw2);
83512
+ }
83513
+ finalize();
83514
+ return blocks2;
83515
+ }
83305
83516
  function tokenizeDiffRun(lines, language, grammarState) {
83306
83517
  if (!highlighter) {
83307
83518
  return { tokens: [], nextGrammarState: grammarState };
@@ -83559,17 +83770,24 @@ async function handleLazyTokenizationRequest(request) {
83559
83770
  const raw2 = block.payload.raw ?? "";
83560
83771
  const { code: code4, info, hadFence } = stripCodeFence(raw2);
83561
83772
  const { lang: lang236, meta: meta2 } = parseCodeFenceInfo(info);
83562
- const diffInfo = detectDiffLanguage(lang236, meta2);
83563
- const requestedLanguage = diffInfo.isDiff ? diffInfo.diffLang : lang236 || "text";
83564
- const tokenLanguage = diffInfo.isDiff ? diffInfo.baseLang ?? "text" : requestedLanguage;
83565
83773
  const codeBody = hadFence ? code4 : dedentIndentedCode(raw2);
83566
83774
  const codeLines = extractCodeLines(raw2);
83775
+ let diffInfo = detectDiffLanguage(lang236, meta2);
83776
+ if (!diffInfo.isDiff && emitDiffBlocks && looksLikeUnifiedDiff(codeLines)) {
83777
+ diffInfo = {
83778
+ isDiff: true,
83779
+ diffLang: "diff",
83780
+ baseLang: guessLanguageFromDiffLines(codeLines)
83781
+ };
83782
+ }
83783
+ const requestedLanguage = diffInfo.isDiff ? diffInfo.diffLang : lang236 || "text";
83784
+ const tokenLanguage = diffInfo.isDiff ? diffInfo.baseLang ?? "text" : requestedLanguage;
83567
83785
  const hasHighlightableContent = codeBody.trim().length > 0;
83568
83786
  if (!shouldLazyTokenizeBlock(codeLines.length, Boolean(highlighter), hasHighlightableContent)) {
83569
83787
  return;
83570
83788
  }
83571
83789
  const wantsHtml = highlightOutputMode === "html" || highlightOutputMode === "both";
83572
- const wantsTokens = highlightOutputMode === "tokens" || highlightOutputMode === "both";
83790
+ const wantsTokens = (highlightOutputMode === "tokens" || highlightOutputMode === "both") && emitHighlightTokens;
83573
83791
  const diffEnabled = diffInfo.isDiff && wantsTokens;
83574
83792
  if (!wantsHtml && !wantsTokens) return;
83575
83793
  const { startLine, endLine } = clampLazyRange(request.startLine, request.endLine, codeLines.length);
@@ -83697,6 +83915,13 @@ async function handleLazyTokenizationRequest(request) {
83697
83915
  if ("oldNo" in nextMeta) delete nextMeta.oldNo;
83698
83916
  if ("newNo" in nextMeta) delete nextMeta.newNo;
83699
83917
  }
83918
+ if (emitDiffBlocks && diffInfo.isDiff) {
83919
+ const cursor = { oldLine: null, newLine: null };
83920
+ const diffLines = codeLines.map((line) => parseUnifiedDiffLine(line, cursor));
83921
+ nextMeta.diffBlocks = buildDiffBlocksFromLines(diffLines, codeLines, wantsTokens ? state.tokenLines : null, diffInfo.baseLang ?? null);
83922
+ } else if ("diffBlocks" in nextMeta) {
83923
+ delete nextMeta.diffBlocks;
83924
+ }
83700
83925
  updated.payload.meta = nextMeta;
83701
83926
  blocks[index2] = updated;
83702
83927
  const nextSnapshot = await blockToNodeSnapshot(updated);
@@ -83717,23 +83942,32 @@ async function enrichCodeBlock(block) {
83717
83942
  const raw2 = block.payload.raw ?? "";
83718
83943
  const { code: code4, info, hadFence } = stripCodeFence(raw2);
83719
83944
  const { lang: lang236, meta: meta2 } = parseCodeFenceInfo(info);
83720
- const diffInfo = detectDiffLanguage(lang236, meta2);
83721
- const requestedLanguage = diffInfo.isDiff ? diffInfo.diffLang : lang236 || "text";
83722
- const tokenLanguage = diffInfo.isDiff ? diffInfo.baseLang ?? "text" : requestedLanguage;
83945
+ let diffInfo = detectDiffLanguage(lang236, meta2);
83723
83946
  const codeBody = hadFence ? code4 : dedentIndentedCode(raw2);
83724
83947
  const codeLines = extractCodeLines(raw2);
83948
+ if (!diffInfo.isDiff && emitDiffBlocks && looksLikeUnifiedDiff(codeLines)) {
83949
+ diffInfo = {
83950
+ isDiff: true,
83951
+ diffLang: "diff",
83952
+ baseLang: guessLanguageFromDiffLines(codeLines)
83953
+ };
83954
+ }
83955
+ const requestedLanguage = diffInfo.isDiff ? diffInfo.diffLang : lang236 || "text";
83956
+ const tokenLanguage = diffInfo.isDiff ? diffInfo.baseLang ?? "text" : requestedLanguage;
83725
83957
  const baseMeta = block.payload.meta ?? {};
83726
83958
  let resolvedLanguage = requestedLanguage;
83727
83959
  let resolvedTokenLanguage = tokenLanguage;
83728
83960
  const hasHighlighter = Boolean(highlighter);
83729
83961
  const hasHighlightableContent = codeBody.trim().length > 0;
83730
83962
  const wantsHtml = highlightOutputMode === "html" || highlightOutputMode === "both";
83731
- const wantsTokens = highlightOutputMode === "tokens" || highlightOutputMode === "both";
83963
+ const wantsTokens = (highlightOutputMode === "tokens" || highlightOutputMode === "both") && emitHighlightTokens;
83964
+ const wantsTokensNow = wantsTokens && (block.isFinalized || liveTokenizationEnabled);
83732
83965
  if (!block.isFinalized) {
83733
83966
  if (codeHighlightingMode === "final" || !hasHighlighter || !hasHighlightableContent) {
83734
83967
  resetIncrementalHighlightState(block.id);
83735
83968
  block.payload.highlightedHtml = void 0;
83736
83969
  const nextMeta2 = { ...baseMeta, ...meta2, lang: resolvedLanguage };
83970
+ nextMeta2.code = codeBody;
83737
83971
  if ("highlightedLines" in nextMeta2) {
83738
83972
  delete nextMeta2.highlightedLines;
83739
83973
  }
@@ -83749,6 +83983,9 @@ async function enrichCodeBlock(block) {
83749
83983
  if ("newNo" in nextMeta2) {
83750
83984
  delete nextMeta2.newNo;
83751
83985
  }
83986
+ if ("diffBlocks" in nextMeta2) {
83987
+ delete nextMeta2.diffBlocks;
83988
+ }
83752
83989
  block.payload.meta = nextMeta2;
83753
83990
  return;
83754
83991
  }
@@ -83773,13 +84010,13 @@ async function enrichCodeBlock(block) {
83773
84010
  state.tokenLang = wantsTokens ? resolvedTokenLanguage : void 0;
83774
84011
  const appended = codeBody.slice(state.processedLength);
83775
84012
  const combined = state.pendingLine + appended;
83776
- const diffEnabled = diffInfo.isDiff && wantsTokens;
84013
+ const diffEnabled = diffInfo.isDiff && wantsTokensNow;
83777
84014
  if (combined.length > 0) {
83778
84015
  const parts = combined.split("\n");
83779
84016
  const completeLines = parts.slice(0, -1);
83780
84017
  const tail = parts.length > 0 ? parts[parts.length - 1] ?? "" : "";
83781
84018
  if (completeLines.length > 0) {
83782
- if (wantsHtml || wantsTokens && !diffEnabled) {
84019
+ if (wantsHtml || wantsTokensNow && !diffEnabled) {
83783
84020
  try {
83784
84021
  const sharedLanguage = wantsHtml ? resolvedLanguage : resolvedTokenLanguage;
83785
84022
  const tokens = highlighter?.codeToTokensWithThemes(completeLines.join("\n"), {
@@ -83791,7 +84028,7 @@ async function enrichCodeBlock(block) {
83791
84028
  const htmlLines = renderShikiLines(tokens);
83792
84029
  state.highlightedLines.push(...htmlLines);
83793
84030
  }
83794
- if (wantsTokens && !diffEnabled) {
84031
+ if (wantsTokensNow && !diffEnabled) {
83795
84032
  const tokenLines2 = renderTokenLines(tokens);
83796
84033
  state.tokenLines.push(...tokenLines2);
83797
84034
  }
@@ -83801,12 +84038,12 @@ async function enrichCodeBlock(block) {
83801
84038
  if (wantsHtml) {
83802
84039
  state.highlightedLines.push(...completeLines.map(() => null));
83803
84040
  }
83804
- if (wantsTokens && !diffEnabled) {
84041
+ if (wantsTokensNow && !diffEnabled) {
83805
84042
  state.tokenLines.push(...completeLines.map(() => null));
83806
84043
  }
83807
84044
  }
83808
84045
  }
83809
- if (wantsTokens && diffEnabled) {
84046
+ if (wantsTokensNow && diffEnabled) {
83810
84047
  const cursor = state.diffCursor ?? { oldLine: null, newLine: null };
83811
84048
  const diffLines = completeLines.map((line) => parseUnifiedDiffLine(line, cursor));
83812
84049
  state.diffCursor = cursor;
@@ -83832,12 +84069,13 @@ async function enrichCodeBlock(block) {
83832
84069
  block.payload.highlightedHtml = void 0;
83833
84070
  const effectiveLang2 = wantsHtml ? resolvedLanguage : resolvedTokenLanguage;
83834
84071
  const nextMeta2 = { ...baseMeta, ...meta2, lang: effectiveLang2 };
84072
+ nextMeta2.code = codeBody;
83835
84073
  if (wantsHtml) {
83836
84074
  nextMeta2.highlightedLines = state.highlightedLines;
83837
84075
  } else if ("highlightedLines" in nextMeta2) {
83838
84076
  delete nextMeta2.highlightedLines;
83839
84077
  }
83840
- if (wantsTokens) {
84078
+ if (wantsTokensNow) {
83841
84079
  nextMeta2.tokenLines = state.tokenLines;
83842
84080
  if (diffEnabled) {
83843
84081
  nextMeta2.diffKind = state.diffKind;
@@ -83854,6 +84092,13 @@ async function enrichCodeBlock(block) {
83854
84092
  if ("oldNo" in nextMeta2) delete nextMeta2.oldNo;
83855
84093
  if ("newNo" in nextMeta2) delete nextMeta2.newNo;
83856
84094
  }
84095
+ if (emitDiffBlocks && diffInfo.isDiff && liveTokenizationEnabled) {
84096
+ const cursor = { oldLine: null, newLine: null };
84097
+ const diffLines = codeLines.map((line) => parseUnifiedDiffLine(line, cursor));
84098
+ nextMeta2.diffBlocks = buildDiffBlocksFromLines(diffLines, codeLines, wantsTokensNow ? state.tokenLines : null, diffInfo.baseLang ?? null);
84099
+ } else if ("diffBlocks" in nextMeta2) {
84100
+ delete nextMeta2.diffBlocks;
84101
+ }
83857
84102
  block.payload.meta = nextMeta2;
83858
84103
  const highlightDuration2 = performanceTimer.measure("highlight-code");
83859
84104
  metrics?.recordShiki(highlightDuration2);
@@ -83876,6 +84121,7 @@ async function enrichCodeBlock(block) {
83876
84121
  const state = getOrInitLazyState(block.id, signature, codeLines.length, resolvedLanguage, resolvedTokenLanguage, diffEnabled);
83877
84122
  const effectiveLang2 = wantsHtml ? resolvedLanguage : resolvedTokenLanguage;
83878
84123
  const nextMeta2 = { ...baseMeta, ...meta2, lang: effectiveLang2 };
84124
+ nextMeta2.code = codeBody;
83879
84125
  nextMeta2.lazyTokenization = true;
83880
84126
  nextMeta2.lazyTokenizedUntil = state.processedLines;
83881
84127
  if (wantsHtml) {
@@ -83900,6 +84146,13 @@ async function enrichCodeBlock(block) {
83900
84146
  if ("oldNo" in nextMeta2) delete nextMeta2.oldNo;
83901
84147
  if ("newNo" in nextMeta2) delete nextMeta2.newNo;
83902
84148
  }
84149
+ if (emitDiffBlocks && diffInfo.isDiff) {
84150
+ const cursor = { oldLine: null, newLine: null };
84151
+ const diffLines = codeLines.map((line) => parseUnifiedDiffLine(line, cursor));
84152
+ nextMeta2.diffBlocks = buildDiffBlocksFromLines(diffLines, codeLines, wantsTokens ? state.tokenLines : null, diffInfo.baseLang ?? null);
84153
+ } else if ("diffBlocks" in nextMeta2) {
84154
+ delete nextMeta2.diffBlocks;
84155
+ }
83903
84156
  block.payload.highlightedHtml = void 0;
83904
84157
  block.payload.meta = nextMeta2;
83905
84158
  return;
@@ -83982,6 +84235,7 @@ async function enrichCodeBlock(block) {
83982
84235
  }
83983
84236
  const effectiveLang = wantsHtml ? resolvedLanguage : resolvedTokenLanguage;
83984
84237
  const nextMeta = { ...baseMeta, ...meta2, lang: effectiveLang };
84238
+ nextMeta.code = codeBody;
83985
84239
  if ("highlightedLines" in nextMeta) {
83986
84240
  delete nextMeta.highlightedLines;
83987
84241
  }
@@ -84002,6 +84256,13 @@ async function enrichCodeBlock(block) {
84002
84256
  if ("oldNo" in nextMeta) delete nextMeta.oldNo;
84003
84257
  if ("newNo" in nextMeta) delete nextMeta.newNo;
84004
84258
  }
84259
+ if (emitDiffBlocks && diffInfo.isDiff) {
84260
+ const cursor = { oldLine: null, newLine: null };
84261
+ const diffLines = codeLines.map((line) => parseUnifiedDiffLine(line, cursor));
84262
+ nextMeta.diffBlocks = buildDiffBlocksFromLines(diffLines, codeLines, wantsTokens ? tokenLines ?? null : null, diffInfo.baseLang ?? null);
84263
+ } else if ("diffBlocks" in nextMeta) {
84264
+ delete nextMeta.diffBlocks;
84265
+ }
84005
84266
  block.payload.meta = nextMeta;
84006
84267
  const highlightDuration = performanceTimer.measure("highlight-code");
84007
84268
  metrics?.recordShiki(highlightDuration);
@@ -84343,6 +84604,7 @@ async function blockToNodeSnapshot(block) {
84343
84604
  }
84344
84605
  async function emitDocumentPatch(currentBlocks) {
84345
84606
  const patches = [];
84607
+ const tocPatch = maybeBuildTocPatch(currentBlocks);
84346
84608
  for (let index2 = 0; index2 < currentBlocks.length; index2++) {
84347
84609
  const block = currentBlocks[index2];
84348
84610
  if (!block) continue;
@@ -84353,6 +84615,9 @@ async function emitDocumentPatch(currentBlocks) {
84353
84615
  node: await blockToNodeSnapshot(block)
84354
84616
  });
84355
84617
  }
84618
+ if (tocPatch) {
84619
+ patches.push(tocPatch);
84620
+ }
84356
84621
  if (patches.length > 0) {
84357
84622
  postMessage({
84358
84623
  type: "PATCH",
@@ -84363,6 +84628,7 @@ async function emitDocumentPatch(currentBlocks) {
84363
84628
  }
84364
84629
  async function emitBlockDiffPatches(previousBlocks, nextBlocks, changedRanges, metrics) {
84365
84630
  const patches = [];
84631
+ const tocPatch = maybeBuildTocPatch(nextBlocks);
84366
84632
  if (previousBlocks === nextBlocks) return;
84367
84633
  let prefix = 0;
84368
84634
  const maxPrefix = Math.min(previousBlocks.length, nextBlocks.length);
@@ -84410,6 +84676,9 @@ async function emitBlockDiffPatches(previousBlocks, nextBlocks, changedRanges, m
84410
84676
  const { patches: contentPatches, changedBlockCount } = await diffBlockContent(previousBlocks, nextBlocks, changedRanges, metrics);
84411
84677
  metrics?.markDiffEnd();
84412
84678
  const combined = patches.concat(contentPatches);
84679
+ if (tocPatch) {
84680
+ combined.push(tocPatch);
84681
+ }
84413
84682
  let paragraphLimit = null;
84414
84683
  if (workerCredits < 0.9) {
84415
84684
  const dynamicBase = workerCredits < 0.5 ? 48 : 96;
@@ -85009,6 +85278,9 @@ async function finalizeAllBlocks() {
85009
85278
  }
85010
85279
  workerCredits = previousCredits;
85011
85280
  }
85281
+ postMessage({
85282
+ type: "FINALIZED"
85283
+ });
85012
85284
  if (getActiveMetricsCollector() === metricsCollector) {
85013
85285
  setActiveMetricsCollector(null);
85014
85286
  }
@@ -85154,6 +85426,14 @@ async function processWorkerMessage(msg) {
85154
85426
  });
85155
85427
  return;
85156
85428
  }
85429
+ case "DUMP_BLOCKS": {
85430
+ postMessage({
85431
+ type: "DUMP_BLOCKS",
85432
+ blocks,
85433
+ tocHeadings
85434
+ });
85435
+ return;
85436
+ }
85157
85437
  case "TOKENIZE_RANGE": {
85158
85438
  const priority = msg.priority === "prefetch" ? "prefetch" : "visible";
85159
85439
  enqueueLazyTokenization({