@stream-mdx/core 0.3.0 → 0.5.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 +10 -3
- package/README.md +47 -32
- package/dist/code-highlighting.cjs +6 -0
- package/dist/code-highlighting.mjs +6 -0
- package/dist/index.cjs +150 -29
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.mjs +150 -29
- package/dist/inline-parser.cjs +6 -6
- package/dist/inline-parser.mjs +6 -6
- package/dist/mixed-content.cjs +25 -5
- package/dist/mixed-content.mjs +25 -5
- package/dist/perf/patch-batching.cjs +38 -0
- package/dist/perf/patch-batching.d.cts +3 -2
- package/dist/perf/patch-batching.d.ts +3 -2
- package/dist/perf/patch-batching.mjs +37 -0
- package/dist/perf/patch-coalescing.cjs +10 -5
- package/dist/perf/patch-coalescing.mjs +10 -5
- package/dist/streaming/inline-streaming.cjs +16 -3
- package/dist/streaming/inline-streaming.mjs +16 -3
- package/dist/types.d.cts +46 -1
- package/dist/types.d.ts +46 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -24,6 +24,9 @@ function normalizeNewlines(input) {
|
|
|
24
24
|
function isFenceLine(line) {
|
|
25
25
|
return /^```/.test(line.trim());
|
|
26
26
|
}
|
|
27
|
+
function isTrailingPartialFenceLine(line) {
|
|
28
|
+
return /^[\t ]*`{1,2}[\t ]*$/.test(line);
|
|
29
|
+
}
|
|
27
30
|
function stripCodeFence(raw) {
|
|
28
31
|
if (!raw) {
|
|
29
32
|
return { code: "", info: "", hadFence: false };
|
|
@@ -47,6 +50,9 @@ function stripCodeFence(raw) {
|
|
|
47
50
|
return { code: codeLines2.join("\n"), info, hadFence: true };
|
|
48
51
|
}
|
|
49
52
|
const codeLines = lines.slice(1);
|
|
53
|
+
if (!normalized.endsWith("\n") && codeLines.length > 0 && isTrailingPartialFenceLine(codeLines[codeLines.length - 1] ?? "")) {
|
|
54
|
+
codeLines.pop();
|
|
55
|
+
}
|
|
50
56
|
return { code: codeLines.join("\n"), info, hadFence: true };
|
|
51
57
|
}
|
|
52
58
|
function getDomParser() {
|
|
@@ -429,12 +435,12 @@ var InlineParser = class {
|
|
|
429
435
|
this.registerPlugin({
|
|
430
436
|
id: "strong-emphasis",
|
|
431
437
|
priority: 6,
|
|
432
|
-
re: /\*\*\*([^*\n]+?)\*\*\*|\*\*([^*\n]+?)
|
|
438
|
+
re: /\*\*\*([^*\n]+?)\*\*\*|\*\*([^*\n]+?)\*\*|(?<![\w\\])__([^_\n]+?)__(?!\w)/g,
|
|
433
439
|
toNode: (match) => ({
|
|
434
440
|
kind: "strong",
|
|
435
|
-
children: [{ kind: "text", text: match[1] || match[2] }]
|
|
441
|
+
children: [{ kind: "text", text: match[1] || match[2] || match[3] }]
|
|
436
442
|
}),
|
|
437
|
-
fastCheck: (text) => text.indexOf("**") !== -1
|
|
443
|
+
fastCheck: (text) => text.indexOf("**") !== -1 || text.indexOf("__") !== -1
|
|
438
444
|
});
|
|
439
445
|
this.registerPlugin({
|
|
440
446
|
id: "strikethrough",
|
|
@@ -449,12 +455,12 @@ var InlineParser = class {
|
|
|
449
455
|
this.registerPlugin({
|
|
450
456
|
id: "emphasis",
|
|
451
457
|
priority: 8,
|
|
452
|
-
re: /\*([^*\n]+?)
|
|
458
|
+
re: /\*([^*\n]+?)\*|(?<![\w\\])_([^_\n]+?)_(?!\w)/g,
|
|
453
459
|
toNode: (match) => ({
|
|
454
460
|
kind: "em",
|
|
455
|
-
children: [{ kind: "text", text: match[1] }]
|
|
461
|
+
children: [{ kind: "text", text: match[1] || match[2] }]
|
|
456
462
|
}),
|
|
457
|
-
fastCheck: (text) => text.indexOf("*") !== -1
|
|
463
|
+
fastCheck: (text) => text.indexOf("*") !== -1 || text.indexOf("_") !== -1
|
|
458
464
|
});
|
|
459
465
|
this.registerPlugin({
|
|
460
466
|
id: "citations",
|
|
@@ -605,6 +611,13 @@ function prepareInlineStreamingContent(content, options) {
|
|
|
605
611
|
};
|
|
606
612
|
let mathDisplayOpen = false;
|
|
607
613
|
let mathDisplayCrossedNewline = false;
|
|
614
|
+
const shouldOpenInlineMath = (index) => {
|
|
615
|
+
const next = content[index + 1] ?? "";
|
|
616
|
+
if (/\d/.test(next)) {
|
|
617
|
+
return false;
|
|
618
|
+
}
|
|
619
|
+
return true;
|
|
620
|
+
};
|
|
608
621
|
for (let i = 0; i < content.length; i++) {
|
|
609
622
|
const code = content.charCodeAt(i);
|
|
610
623
|
if (code === 10 || code === 13) {
|
|
@@ -643,7 +656,10 @@ function prepareInlineStreamingContent(content, options) {
|
|
|
643
656
|
}
|
|
644
657
|
i += 1;
|
|
645
658
|
} else {
|
|
646
|
-
|
|
659
|
+
const mathInlineOpen = stack.includes("math-inline");
|
|
660
|
+
if (mathInlineOpen || shouldOpenInlineMath(i)) {
|
|
661
|
+
toggleToken("math-inline");
|
|
662
|
+
}
|
|
647
663
|
}
|
|
648
664
|
}
|
|
649
665
|
}
|
|
@@ -655,7 +671,7 @@ function prepareInlineStreamingContent(content, options) {
|
|
|
655
671
|
if (hasIncompleteMathInline && !enableMathInlineAnticipation) {
|
|
656
672
|
return { kind: "raw", status: "raw", reason: "incomplete-math" };
|
|
657
673
|
}
|
|
658
|
-
if (hasIncompleteMathDisplay &&
|
|
674
|
+
if (hasIncompleteMathDisplay && !enableMathBlockAnticipation) {
|
|
659
675
|
return { kind: "raw", status: "raw", reason: "incomplete-math" };
|
|
660
676
|
}
|
|
661
677
|
}
|
|
@@ -678,7 +694,10 @@ function prepareInlineStreamingContent(content, options) {
|
|
|
678
694
|
case "math-inline":
|
|
679
695
|
return "$";
|
|
680
696
|
case "math-display":
|
|
681
|
-
|
|
697
|
+
if (!mathDisplayCrossedNewline) {
|
|
698
|
+
return "$$";
|
|
699
|
+
}
|
|
700
|
+
return content.endsWith("\n") || content.endsWith("\r") ? "$$" : "\n$$";
|
|
682
701
|
default:
|
|
683
702
|
return "";
|
|
684
703
|
}
|
|
@@ -896,9 +915,25 @@ function splitByTagSegments(source, baseOffset, parseInline, options) {
|
|
|
896
915
|
continue;
|
|
897
916
|
}
|
|
898
917
|
}
|
|
899
|
-
if (!isSelfClosing
|
|
900
|
-
const closingIndex = findClosingHtmlTag(lowerSource,
|
|
901
|
-
if (closingIndex
|
|
918
|
+
if (!isSelfClosing) {
|
|
919
|
+
const closingIndex = findClosingHtmlTag(lowerSource, tagNameLower, end);
|
|
920
|
+
if (closingIndex !== -1) {
|
|
921
|
+
end = closingIndex;
|
|
922
|
+
} else if (mdxAllowed) {
|
|
923
|
+
if (mdxAutoClose) {
|
|
924
|
+
const tail = source.slice(end);
|
|
925
|
+
const newlineCount = countNewlines(tail, mdxMaxNewlines + 1);
|
|
926
|
+
if (newlineCount > mdxMaxNewlines) {
|
|
927
|
+
tagPattern.lastIndex = start + 1;
|
|
928
|
+
match = tagPattern.exec(source);
|
|
929
|
+
continue;
|
|
930
|
+
}
|
|
931
|
+
} else {
|
|
932
|
+
tagPattern.lastIndex = start + 1;
|
|
933
|
+
match = tagPattern.exec(source);
|
|
934
|
+
continue;
|
|
935
|
+
}
|
|
936
|
+
} else {
|
|
902
937
|
if (htmlAutoClose && htmlAllowTags.has(tagNameLower)) {
|
|
903
938
|
const tail = source.slice(end);
|
|
904
939
|
const newlineCount = countNewlines(tail, htmlMaxNewlines + 1);
|
|
@@ -925,7 +960,6 @@ function splitByTagSegments(source, baseOffset, parseInline, options) {
|
|
|
925
960
|
match = tagPattern.exec(source);
|
|
926
961
|
continue;
|
|
927
962
|
}
|
|
928
|
-
end = closingIndex;
|
|
929
963
|
}
|
|
930
964
|
if (start > cursor) {
|
|
931
965
|
const absoluteFrom = baseIsFinite ? baseOffset + cursor : void 0;
|
|
@@ -949,7 +983,9 @@ function splitByTagSegments(source, baseOffset, parseInline, options) {
|
|
|
949
983
|
match = tagPattern.exec(source);
|
|
950
984
|
continue;
|
|
951
985
|
}
|
|
952
|
-
|
|
986
|
+
const closingTagPattern = new RegExp(`</\\s*${escapeRegExp(tagName)}\\s*>\\s*$`, "i");
|
|
987
|
+
const hasExplicitClose = closingTagPattern.test(rawSegment);
|
|
988
|
+
if (mdxAutoClose && !hasExplicitClose && !rawSegment.endsWith("/>")) {
|
|
953
989
|
rawSegment = selfCloseTag(rawSegment);
|
|
954
990
|
segment.value = rawSegment;
|
|
955
991
|
}
|
|
@@ -1119,6 +1155,9 @@ function selfCloseTag(rawTag) {
|
|
|
1119
1155
|
if (closeIndex === -1) return rawTag;
|
|
1120
1156
|
return `${rawTag.slice(0, closeIndex)}/>`;
|
|
1121
1157
|
}
|
|
1158
|
+
function escapeRegExp(value) {
|
|
1159
|
+
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
1160
|
+
}
|
|
1122
1161
|
function isLikelyMdxComponent(tagName) {
|
|
1123
1162
|
const first = tagName.charAt(0);
|
|
1124
1163
|
return first.toUpperCase() === first && first.toLowerCase() !== first;
|
|
@@ -1399,6 +1438,12 @@ function createBlockSnapshot(block) {
|
|
|
1399
1438
|
}
|
|
1400
1439
|
}
|
|
1401
1440
|
var listInlineParser = new InlineParser();
|
|
1441
|
+
var LIST_STREAMING_ANTICIPATION = {
|
|
1442
|
+
inline: true,
|
|
1443
|
+
mathInline: true,
|
|
1444
|
+
mathBlock: true,
|
|
1445
|
+
regex: true
|
|
1446
|
+
};
|
|
1402
1447
|
function enrichListSnapshot(block, snapshot) {
|
|
1403
1448
|
const raw = block.payload.raw ?? "";
|
|
1404
1449
|
const baseOffset = block.payload.range?.from ?? 0;
|
|
@@ -1505,7 +1550,7 @@ function buildListItemSnapshot(block, listItemNode, ordered, index, id, baseOffs
|
|
|
1505
1550
|
const nestedId = `${id}::list:${subListIndex++}`;
|
|
1506
1551
|
const nestedOrdered = name === "OrderedList";
|
|
1507
1552
|
const nestedSnapshot = buildListNodeSnapshot(block, cursor.node, nestedOrdered, nestedId, baseOffset, raw);
|
|
1508
|
-
if (Array.isArray(nestedSnapshot.children) && nestedSnapshot.children.length > 0) {
|
|
1553
|
+
if (nestedSnapshot && Array.isArray(nestedSnapshot.children) && nestedSnapshot.children.length > 0) {
|
|
1509
1554
|
childSnapshots.push(nestedSnapshot);
|
|
1510
1555
|
}
|
|
1511
1556
|
} else if (name === "Blockquote") {
|
|
@@ -1544,21 +1589,20 @@ function buildListItemSnapshot(block, listItemNode, ordered, index, id, baseOffs
|
|
|
1544
1589
|
return itemSnapshot;
|
|
1545
1590
|
}
|
|
1546
1591
|
function parseListInline(raw, options) {
|
|
1547
|
-
if (!options?.streaming
|
|
1592
|
+
if (!options?.streaming) {
|
|
1548
1593
|
return listInlineParser.parse(raw);
|
|
1549
1594
|
}
|
|
1550
|
-
const
|
|
1595
|
+
const effectiveFormatAnticipation = options.formatAnticipation ?? LIST_STREAMING_ANTICIPATION;
|
|
1596
|
+
const prepared = prepareInlineStreamingContent(raw, { formatAnticipation: effectiveFormatAnticipation, math: options.math ?? true });
|
|
1551
1597
|
if (prepared.kind === "raw") {
|
|
1552
1598
|
return [{ kind: "text", text: raw }];
|
|
1553
1599
|
}
|
|
1554
1600
|
let preparedContent = prepared.content;
|
|
1555
|
-
|
|
1556
|
-
const normalized = normalizeFormatAnticipation(options.formatAnticipation);
|
|
1601
|
+
const normalized = normalizeFormatAnticipation(effectiveFormatAnticipation);
|
|
1557
1602
|
if (normalized.regex) {
|
|
1558
1603
|
const regexAppend = listInlineParser.getRegexAnticipationAppend(raw);
|
|
1559
1604
|
if (regexAppend) {
|
|
1560
1605
|
preparedContent += regexAppend;
|
|
1561
|
-
appended += regexAppend;
|
|
1562
1606
|
}
|
|
1563
1607
|
}
|
|
1564
1608
|
return listInlineParser.parse(preparedContent, { cache: false });
|
|
@@ -1611,7 +1655,7 @@ function buildCodeBlockSnapshot(block, codeNode, id, baseOffset, raw, _isFenced)
|
|
|
1611
1655
|
const segment = raw.slice(codeNode.from, codeNode.to);
|
|
1612
1656
|
const normalized = stripListIndentation(segment);
|
|
1613
1657
|
const { code, info: infoString, hadFence } = stripCodeFence(normalized);
|
|
1614
|
-
const body = hadFence ? code : dedentIndentedCode2(normalized);
|
|
1658
|
+
const body = hadFence ? dedentFencedCodeByClosingIndent(normalized, code) : dedentIndentedCode2(normalized);
|
|
1615
1659
|
const { lang, meta } = parseCodeFenceInfo(infoString);
|
|
1616
1660
|
const codeBlock = {
|
|
1617
1661
|
id,
|
|
@@ -1656,6 +1700,10 @@ function buildHeadingSnapshot(block, headingNode, id, baseOffset, raw) {
|
|
|
1656
1700
|
return createBlockSnapshot(headingBlock);
|
|
1657
1701
|
}
|
|
1658
1702
|
function buildListNodeSnapshot(block, listNode, ordered, id, baseOffset, raw) {
|
|
1703
|
+
const children = buildListItemSnapshots(block, listNode, ordered, id, baseOffset, raw);
|
|
1704
|
+
if (children.length === 0) {
|
|
1705
|
+
return null;
|
|
1706
|
+
}
|
|
1659
1707
|
return {
|
|
1660
1708
|
id,
|
|
1661
1709
|
type: "list",
|
|
@@ -1663,7 +1711,7 @@ function buildListNodeSnapshot(block, listNode, ordered, id, baseOffset, raw) {
|
|
|
1663
1711
|
ordered
|
|
1664
1712
|
},
|
|
1665
1713
|
range: createRange(baseOffset + listNode.from, baseOffset + listNode.to),
|
|
1666
|
-
children
|
|
1714
|
+
children
|
|
1667
1715
|
};
|
|
1668
1716
|
}
|
|
1669
1717
|
function enrichParagraphSnapshot(block, snapshot) {
|
|
@@ -1790,6 +1838,73 @@ function dedentIndentedCode2(input) {
|
|
|
1790
1838
|
}
|
|
1791
1839
|
return lines.map((line) => line.length >= minIndent ? line.slice(minIndent) : "").join("\n").trimEnd();
|
|
1792
1840
|
}
|
|
1841
|
+
function dedentFencedCodeByClosingIndent(fencedRaw, extractedCode) {
|
|
1842
|
+
if (!fencedRaw || !extractedCode) {
|
|
1843
|
+
return extractedCode;
|
|
1844
|
+
}
|
|
1845
|
+
const lines = fencedRaw.replace(/\r\n?/g, "\n").split("\n");
|
|
1846
|
+
if (lines.length < 2) {
|
|
1847
|
+
return extractedCode;
|
|
1848
|
+
}
|
|
1849
|
+
let closingIndex = lines.length - 1;
|
|
1850
|
+
while (closingIndex > 0 && lines[closingIndex].trim().length === 0) {
|
|
1851
|
+
closingIndex -= 1;
|
|
1852
|
+
}
|
|
1853
|
+
if (closingIndex <= 0) {
|
|
1854
|
+
return extractedCode;
|
|
1855
|
+
}
|
|
1856
|
+
const closingMatch = lines[closingIndex].match(/^([ \t]*)```/);
|
|
1857
|
+
const closingIndent = closingMatch?.[1] ?? "";
|
|
1858
|
+
if (closingIndent.length === 0) {
|
|
1859
|
+
return extractedCode;
|
|
1860
|
+
}
|
|
1861
|
+
return extractedCode.split("\n").map((line) => stripIndentPrefix(line, closingIndent)).join("\n");
|
|
1862
|
+
}
|
|
1863
|
+
function stripIndentPrefix(line, prefix) {
|
|
1864
|
+
if (!line || !prefix) {
|
|
1865
|
+
return line;
|
|
1866
|
+
}
|
|
1867
|
+
if (line.startsWith(prefix)) {
|
|
1868
|
+
return line.slice(prefix.length);
|
|
1869
|
+
}
|
|
1870
|
+
const targetColumns = measureIndentColumns(prefix);
|
|
1871
|
+
if (targetColumns <= 0) {
|
|
1872
|
+
return line;
|
|
1873
|
+
}
|
|
1874
|
+
let index = 0;
|
|
1875
|
+
let columns = 0;
|
|
1876
|
+
while (index < line.length && columns < targetColumns) {
|
|
1877
|
+
const ch = line[index];
|
|
1878
|
+
if (ch === " ") {
|
|
1879
|
+
columns += 1;
|
|
1880
|
+
index += 1;
|
|
1881
|
+
continue;
|
|
1882
|
+
}
|
|
1883
|
+
if (ch === " ") {
|
|
1884
|
+
columns += 4;
|
|
1885
|
+
index += 1;
|
|
1886
|
+
continue;
|
|
1887
|
+
}
|
|
1888
|
+
break;
|
|
1889
|
+
}
|
|
1890
|
+
return columns >= targetColumns ? line.slice(index) : line;
|
|
1891
|
+
}
|
|
1892
|
+
function measureIndentColumns(value) {
|
|
1893
|
+
let columns = 0;
|
|
1894
|
+
for (let i = 0; i < value.length; i += 1) {
|
|
1895
|
+
const ch = value[i];
|
|
1896
|
+
if (ch === " ") {
|
|
1897
|
+
columns += 1;
|
|
1898
|
+
continue;
|
|
1899
|
+
}
|
|
1900
|
+
if (ch === " ") {
|
|
1901
|
+
columns += 4;
|
|
1902
|
+
continue;
|
|
1903
|
+
}
|
|
1904
|
+
break;
|
|
1905
|
+
}
|
|
1906
|
+
return columns;
|
|
1907
|
+
}
|
|
1793
1908
|
function removeHeadingMarkers2(input) {
|
|
1794
1909
|
return input.replace(/^#{1,6}\s+/, "").replace(/\s+={2,}\s*$|\s+-{2,}\s*$/m, "").trim();
|
|
1795
1910
|
}
|
|
@@ -1850,8 +1965,9 @@ function enrichTableSnapshot(block, snapshot) {
|
|
|
1850
1965
|
return snapshot;
|
|
1851
1966
|
}
|
|
1852
1967
|
function enrichCodeSnapshot(block, snapshot) {
|
|
1853
|
-
const
|
|
1854
|
-
const
|
|
1968
|
+
const metaCode = typeof block.payload.meta?.code === "string" ? block.payload.meta?.code : null;
|
|
1969
|
+
const source = metaCode ?? (block.payload.raw ?? "");
|
|
1970
|
+
const lines = metaCode !== null ? source.length > 0 ? source.replace(/\r\n?/g, "\n").split("\n") : [] : extractCodeLines(source);
|
|
1855
1971
|
const meta = block.payload.meta;
|
|
1856
1972
|
const highlightedHtml = block.payload.highlightedHtml ?? "";
|
|
1857
1973
|
const hasBlockHighlight = typeof block.payload.highlightedHtml === "string" && block.payload.highlightedHtml.length > 0;
|
|
@@ -2962,7 +3078,8 @@ function collectSetProps(window2, startIndex) {
|
|
|
2962
3078
|
}
|
|
2963
3079
|
entries.push({
|
|
2964
3080
|
at: cloneNodePath(current.at),
|
|
2965
|
-
props: mergedProps
|
|
3081
|
+
props: mergedProps,
|
|
3082
|
+
meta: current.meta ? { ...current.meta } : void 0
|
|
2966
3083
|
});
|
|
2967
3084
|
j = k;
|
|
2968
3085
|
}
|
|
@@ -2980,7 +3097,8 @@ function collectSetProps(window2, startIndex) {
|
|
|
2980
3097
|
}
|
|
2981
3098
|
const batchPatch = {
|
|
2982
3099
|
op: "setPropsBatch",
|
|
2983
|
-
entries
|
|
3100
|
+
entries,
|
|
3101
|
+
meta: first.meta ? { ...first.meta } : void 0
|
|
2984
3102
|
};
|
|
2985
3103
|
return { patches: [batchPatch], nextIndex: j };
|
|
2986
3104
|
}
|
|
@@ -3075,7 +3193,8 @@ function coalescePatchesQuadratic(patches, config = DEFAULT_COALESCE_CONFIG) {
|
|
|
3075
3193
|
const batchEntries = [
|
|
3076
3194
|
{
|
|
3077
3195
|
at: cloneNodePath(current.at),
|
|
3078
|
-
props: mergedProps
|
|
3196
|
+
props: mergedProps,
|
|
3197
|
+
meta: current.meta ? { ...current.meta } : void 0
|
|
3079
3198
|
}
|
|
3080
3199
|
];
|
|
3081
3200
|
let k = j;
|
|
@@ -3099,14 +3218,16 @@ function coalescePatchesQuadratic(patches, config = DEFAULT_COALESCE_CONFIG) {
|
|
|
3099
3218
|
}
|
|
3100
3219
|
batchEntries.push({
|
|
3101
3220
|
at: cloneNodePath(candidate.at),
|
|
3102
|
-
props: candidateMergedProps
|
|
3221
|
+
props: candidateMergedProps,
|
|
3222
|
+
meta: candidate.meta ? { ...candidate.meta } : void 0
|
|
3103
3223
|
});
|
|
3104
3224
|
k = m;
|
|
3105
3225
|
}
|
|
3106
3226
|
if (batchEntries.length > 1) {
|
|
3107
3227
|
coalesced.push({
|
|
3108
3228
|
op: "setPropsBatch",
|
|
3109
|
-
entries: batchEntries
|
|
3229
|
+
entries: batchEntries,
|
|
3230
|
+
meta: current.meta ? { ...current.meta } : void 0
|
|
3110
3231
|
});
|
|
3111
3232
|
i = k;
|
|
3112
3233
|
continue;
|
package/dist/inline-parser.cjs
CHANGED
|
@@ -236,12 +236,12 @@ var InlineParser = class {
|
|
|
236
236
|
this.registerPlugin({
|
|
237
237
|
id: "strong-emphasis",
|
|
238
238
|
priority: 6,
|
|
239
|
-
re: /\*\*\*([^*\n]+?)\*\*\*|\*\*([^*\n]+?)
|
|
239
|
+
re: /\*\*\*([^*\n]+?)\*\*\*|\*\*([^*\n]+?)\*\*|(?<![\w\\])__([^_\n]+?)__(?!\w)/g,
|
|
240
240
|
toNode: (match) => ({
|
|
241
241
|
kind: "strong",
|
|
242
|
-
children: [{ kind: "text", text: match[1] || match[2] }]
|
|
242
|
+
children: [{ kind: "text", text: match[1] || match[2] || match[3] }]
|
|
243
243
|
}),
|
|
244
|
-
fastCheck: (text) => text.indexOf("**") !== -1
|
|
244
|
+
fastCheck: (text) => text.indexOf("**") !== -1 || text.indexOf("__") !== -1
|
|
245
245
|
});
|
|
246
246
|
this.registerPlugin({
|
|
247
247
|
id: "strikethrough",
|
|
@@ -256,12 +256,12 @@ var InlineParser = class {
|
|
|
256
256
|
this.registerPlugin({
|
|
257
257
|
id: "emphasis",
|
|
258
258
|
priority: 8,
|
|
259
|
-
re: /\*([^*\n]+?)
|
|
259
|
+
re: /\*([^*\n]+?)\*|(?<![\w\\])_([^_\n]+?)_(?!\w)/g,
|
|
260
260
|
toNode: (match) => ({
|
|
261
261
|
kind: "em",
|
|
262
|
-
children: [{ kind: "text", text: match[1] }]
|
|
262
|
+
children: [{ kind: "text", text: match[1] || match[2] }]
|
|
263
263
|
}),
|
|
264
|
-
fastCheck: (text) => text.indexOf("*") !== -1
|
|
264
|
+
fastCheck: (text) => text.indexOf("*") !== -1 || text.indexOf("_") !== -1
|
|
265
265
|
});
|
|
266
266
|
this.registerPlugin({
|
|
267
267
|
id: "citations",
|
package/dist/inline-parser.mjs
CHANGED
|
@@ -210,12 +210,12 @@ var InlineParser = class {
|
|
|
210
210
|
this.registerPlugin({
|
|
211
211
|
id: "strong-emphasis",
|
|
212
212
|
priority: 6,
|
|
213
|
-
re: /\*\*\*([^*\n]+?)\*\*\*|\*\*([^*\n]+?)
|
|
213
|
+
re: /\*\*\*([^*\n]+?)\*\*\*|\*\*([^*\n]+?)\*\*|(?<![\w\\])__([^_\n]+?)__(?!\w)/g,
|
|
214
214
|
toNode: (match) => ({
|
|
215
215
|
kind: "strong",
|
|
216
|
-
children: [{ kind: "text", text: match[1] || match[2] }]
|
|
216
|
+
children: [{ kind: "text", text: match[1] || match[2] || match[3] }]
|
|
217
217
|
}),
|
|
218
|
-
fastCheck: (text) => text.indexOf("**") !== -1
|
|
218
|
+
fastCheck: (text) => text.indexOf("**") !== -1 || text.indexOf("__") !== -1
|
|
219
219
|
});
|
|
220
220
|
this.registerPlugin({
|
|
221
221
|
id: "strikethrough",
|
|
@@ -230,12 +230,12 @@ var InlineParser = class {
|
|
|
230
230
|
this.registerPlugin({
|
|
231
231
|
id: "emphasis",
|
|
232
232
|
priority: 8,
|
|
233
|
-
re: /\*([^*\n]+?)
|
|
233
|
+
re: /\*([^*\n]+?)\*|(?<![\w\\])_([^_\n]+?)_(?!\w)/g,
|
|
234
234
|
toNode: (match) => ({
|
|
235
235
|
kind: "em",
|
|
236
|
-
children: [{ kind: "text", text: match[1] }]
|
|
236
|
+
children: [{ kind: "text", text: match[1] || match[2] }]
|
|
237
237
|
}),
|
|
238
|
-
fastCheck: (text) => text.indexOf("*") !== -1
|
|
238
|
+
fastCheck: (text) => text.indexOf("*") !== -1 || text.indexOf("_") !== -1
|
|
239
239
|
});
|
|
240
240
|
this.registerPlugin({
|
|
241
241
|
id: "citations",
|
package/dist/mixed-content.cjs
CHANGED
|
@@ -245,9 +245,25 @@ function splitByTagSegments(source, baseOffset, parseInline, options) {
|
|
|
245
245
|
continue;
|
|
246
246
|
}
|
|
247
247
|
}
|
|
248
|
-
if (!isSelfClosing
|
|
249
|
-
const closingIndex = findClosingHtmlTag(lowerSource,
|
|
250
|
-
if (closingIndex
|
|
248
|
+
if (!isSelfClosing) {
|
|
249
|
+
const closingIndex = findClosingHtmlTag(lowerSource, tagNameLower, end);
|
|
250
|
+
if (closingIndex !== -1) {
|
|
251
|
+
end = closingIndex;
|
|
252
|
+
} else if (mdxAllowed) {
|
|
253
|
+
if (mdxAutoClose) {
|
|
254
|
+
const tail = source.slice(end);
|
|
255
|
+
const newlineCount = countNewlines(tail, mdxMaxNewlines + 1);
|
|
256
|
+
if (newlineCount > mdxMaxNewlines) {
|
|
257
|
+
tagPattern.lastIndex = start + 1;
|
|
258
|
+
match = tagPattern.exec(source);
|
|
259
|
+
continue;
|
|
260
|
+
}
|
|
261
|
+
} else {
|
|
262
|
+
tagPattern.lastIndex = start + 1;
|
|
263
|
+
match = tagPattern.exec(source);
|
|
264
|
+
continue;
|
|
265
|
+
}
|
|
266
|
+
} else {
|
|
251
267
|
if (htmlAutoClose && htmlAllowTags.has(tagNameLower)) {
|
|
252
268
|
const tail = source.slice(end);
|
|
253
269
|
const newlineCount = countNewlines(tail, htmlMaxNewlines + 1);
|
|
@@ -274,7 +290,6 @@ function splitByTagSegments(source, baseOffset, parseInline, options) {
|
|
|
274
290
|
match = tagPattern.exec(source);
|
|
275
291
|
continue;
|
|
276
292
|
}
|
|
277
|
-
end = closingIndex;
|
|
278
293
|
}
|
|
279
294
|
if (start > cursor) {
|
|
280
295
|
const absoluteFrom = baseIsFinite ? baseOffset + cursor : void 0;
|
|
@@ -298,7 +313,9 @@ function splitByTagSegments(source, baseOffset, parseInline, options) {
|
|
|
298
313
|
match = tagPattern.exec(source);
|
|
299
314
|
continue;
|
|
300
315
|
}
|
|
301
|
-
|
|
316
|
+
const closingTagPattern = new RegExp(`</\\s*${escapeRegExp(tagName)}\\s*>\\s*$`, "i");
|
|
317
|
+
const hasExplicitClose = closingTagPattern.test(rawSegment);
|
|
318
|
+
if (mdxAutoClose && !hasExplicitClose && !rawSegment.endsWith("/>")) {
|
|
302
319
|
rawSegment = selfCloseTag(rawSegment);
|
|
303
320
|
segment.value = rawSegment;
|
|
304
321
|
}
|
|
@@ -468,6 +485,9 @@ function selfCloseTag(rawTag) {
|
|
|
468
485
|
if (closeIndex === -1) return rawTag;
|
|
469
486
|
return `${rawTag.slice(0, closeIndex)}/>`;
|
|
470
487
|
}
|
|
488
|
+
function escapeRegExp(value) {
|
|
489
|
+
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
490
|
+
}
|
|
471
491
|
function isLikelyMdxComponent(tagName) {
|
|
472
492
|
const first = tagName.charAt(0);
|
|
473
493
|
return first.toUpperCase() === first && first.toLowerCase() !== first;
|
package/dist/mixed-content.mjs
CHANGED
|
@@ -207,9 +207,25 @@ function splitByTagSegments(source, baseOffset, parseInline, options) {
|
|
|
207
207
|
continue;
|
|
208
208
|
}
|
|
209
209
|
}
|
|
210
|
-
if (!isSelfClosing
|
|
211
|
-
const closingIndex = findClosingHtmlTag(lowerSource,
|
|
212
|
-
if (closingIndex
|
|
210
|
+
if (!isSelfClosing) {
|
|
211
|
+
const closingIndex = findClosingHtmlTag(lowerSource, tagNameLower, end);
|
|
212
|
+
if (closingIndex !== -1) {
|
|
213
|
+
end = closingIndex;
|
|
214
|
+
} else if (mdxAllowed) {
|
|
215
|
+
if (mdxAutoClose) {
|
|
216
|
+
const tail = source.slice(end);
|
|
217
|
+
const newlineCount = countNewlines(tail, mdxMaxNewlines + 1);
|
|
218
|
+
if (newlineCount > mdxMaxNewlines) {
|
|
219
|
+
tagPattern.lastIndex = start + 1;
|
|
220
|
+
match = tagPattern.exec(source);
|
|
221
|
+
continue;
|
|
222
|
+
}
|
|
223
|
+
} else {
|
|
224
|
+
tagPattern.lastIndex = start + 1;
|
|
225
|
+
match = tagPattern.exec(source);
|
|
226
|
+
continue;
|
|
227
|
+
}
|
|
228
|
+
} else {
|
|
213
229
|
if (htmlAutoClose && htmlAllowTags.has(tagNameLower)) {
|
|
214
230
|
const tail = source.slice(end);
|
|
215
231
|
const newlineCount = countNewlines(tail, htmlMaxNewlines + 1);
|
|
@@ -236,7 +252,6 @@ function splitByTagSegments(source, baseOffset, parseInline, options) {
|
|
|
236
252
|
match = tagPattern.exec(source);
|
|
237
253
|
continue;
|
|
238
254
|
}
|
|
239
|
-
end = closingIndex;
|
|
240
255
|
}
|
|
241
256
|
if (start > cursor) {
|
|
242
257
|
const absoluteFrom = baseIsFinite ? baseOffset + cursor : void 0;
|
|
@@ -260,7 +275,9 @@ function splitByTagSegments(source, baseOffset, parseInline, options) {
|
|
|
260
275
|
match = tagPattern.exec(source);
|
|
261
276
|
continue;
|
|
262
277
|
}
|
|
263
|
-
|
|
278
|
+
const closingTagPattern = new RegExp(`</\\s*${escapeRegExp(tagName)}\\s*>\\s*$`, "i");
|
|
279
|
+
const hasExplicitClose = closingTagPattern.test(rawSegment);
|
|
280
|
+
if (mdxAutoClose && !hasExplicitClose && !rawSegment.endsWith("/>")) {
|
|
264
281
|
rawSegment = selfCloseTag(rawSegment);
|
|
265
282
|
segment.value = rawSegment;
|
|
266
283
|
}
|
|
@@ -430,6 +447,9 @@ function selfCloseTag(rawTag) {
|
|
|
430
447
|
if (closeIndex === -1) return rawTag;
|
|
431
448
|
return `${rawTag.slice(0, closeIndex)}/>`;
|
|
432
449
|
}
|
|
450
|
+
function escapeRegExp(value) {
|
|
451
|
+
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
452
|
+
}
|
|
433
453
|
function isLikelyMdxComponent(tagName) {
|
|
434
454
|
const first = tagName.charAt(0);
|
|
435
455
|
return first.toUpperCase() === first && first.toLowerCase() !== first;
|
|
@@ -20,6 +20,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
20
20
|
// src/perf/patch-batching.ts
|
|
21
21
|
var patch_batching_exports = {};
|
|
22
22
|
__export(patch_batching_exports, {
|
|
23
|
+
getPatchKind: () => getPatchKind,
|
|
23
24
|
isHeavyPatch: () => isHeavyPatch,
|
|
24
25
|
splitPatchBatch: () => splitPatchBatch
|
|
25
26
|
});
|
|
@@ -105,23 +106,59 @@ function isHeavyPatch(patch) {
|
|
|
105
106
|
return false;
|
|
106
107
|
}
|
|
107
108
|
}
|
|
109
|
+
function getPatchKind(patch) {
|
|
110
|
+
const explicitKind = patch.op === "setHTML" ? patch.patchMeta?.kind : patch.meta?.kind;
|
|
111
|
+
if (explicitKind === "semantic" || explicitKind === "enrichment") {
|
|
112
|
+
return explicitKind;
|
|
113
|
+
}
|
|
114
|
+
switch (patch.op) {
|
|
115
|
+
case "insertChild":
|
|
116
|
+
case "deleteChild":
|
|
117
|
+
case "replaceChild":
|
|
118
|
+
case "finalize":
|
|
119
|
+
case "reorder":
|
|
120
|
+
case "appendLines":
|
|
121
|
+
case "setHTML":
|
|
122
|
+
return "semantic";
|
|
123
|
+
case "setProps":
|
|
124
|
+
case "setPropsBatch":
|
|
125
|
+
return "semantic";
|
|
126
|
+
default:
|
|
127
|
+
return "semantic";
|
|
128
|
+
}
|
|
129
|
+
}
|
|
108
130
|
function splitPatchBatch(patches, maxLightChunk = DEFAULT_MAX_LIGHT_PATCHES_PER_CHUNK) {
|
|
109
131
|
if (patches.length === 0) return [];
|
|
110
132
|
const groups = [];
|
|
111
133
|
let current = [];
|
|
134
|
+
let currentMode = null;
|
|
112
135
|
const flush = () => {
|
|
113
136
|
if (current.length > 0) {
|
|
114
137
|
groups.push(current);
|
|
115
138
|
current = [];
|
|
139
|
+
currentMode = null;
|
|
116
140
|
}
|
|
117
141
|
};
|
|
118
142
|
for (const patch of patches) {
|
|
143
|
+
const kind = getPatchKind(patch);
|
|
119
144
|
const heavy = isHeavyPatch(patch);
|
|
145
|
+
if (kind === "semantic") {
|
|
146
|
+
if (currentMode !== "semantic") {
|
|
147
|
+
flush();
|
|
148
|
+
currentMode = "semantic";
|
|
149
|
+
}
|
|
150
|
+
current.push(patch);
|
|
151
|
+
continue;
|
|
152
|
+
}
|
|
120
153
|
if (heavy) {
|
|
121
154
|
flush();
|
|
122
155
|
groups.push([patch]);
|
|
123
156
|
continue;
|
|
124
157
|
}
|
|
158
|
+
if (currentMode !== "enrichment") {
|
|
159
|
+
flush();
|
|
160
|
+
currentMode = "enrichment";
|
|
161
|
+
}
|
|
125
162
|
current.push(patch);
|
|
126
163
|
if (current.length >= maxLightChunk) {
|
|
127
164
|
flush();
|
|
@@ -132,6 +169,7 @@ function splitPatchBatch(patches, maxLightChunk = DEFAULT_MAX_LIGHT_PATCHES_PER_
|
|
|
132
169
|
}
|
|
133
170
|
// Annotate the CommonJS export names for ESM import in node:
|
|
134
171
|
0 && (module.exports = {
|
|
172
|
+
getPatchKind,
|
|
135
173
|
isHeavyPatch,
|
|
136
174
|
splitPatchBatch
|
|
137
175
|
});
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { Patch } from '../types.cjs';
|
|
1
|
+
import { Patch, PatchKind } from '../types.cjs';
|
|
2
2
|
|
|
3
3
|
declare function isHeavyPatch(patch: Patch): boolean;
|
|
4
|
+
declare function getPatchKind(patch: Patch): PatchKind;
|
|
4
5
|
declare function splitPatchBatch(patches: Patch[], maxLightChunk?: number): Patch[][];
|
|
5
6
|
|
|
6
|
-
export { isHeavyPatch, splitPatchBatch };
|
|
7
|
+
export { getPatchKind, isHeavyPatch, splitPatchBatch };
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { Patch } from '../types.js';
|
|
1
|
+
import { Patch, PatchKind } from '../types.js';
|
|
2
2
|
|
|
3
3
|
declare function isHeavyPatch(patch: Patch): boolean;
|
|
4
|
+
declare function getPatchKind(patch: Patch): PatchKind;
|
|
4
5
|
declare function splitPatchBatch(patches: Patch[], maxLightChunk?: number): Patch[][];
|
|
5
6
|
|
|
6
|
-
export { isHeavyPatch, splitPatchBatch };
|
|
7
|
+
export { getPatchKind, isHeavyPatch, splitPatchBatch };
|