@stream-mdx/react 0.4.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 +14 -4
- package/README.md +65 -15
- package/dist/components/bottom-stick-scroll-area.cjs +344 -0
- package/dist/components/bottom-stick-scroll-area.d.cts +36 -0
- package/dist/components/bottom-stick-scroll-area.d.ts +36 -0
- package/dist/components/bottom-stick-scroll-area.mjs +320 -0
- package/dist/components/index.cjs +503 -172
- package/dist/components/index.d.cts +3 -1
- package/dist/components/index.d.ts +3 -1
- package/dist/components/index.mjs +350 -22
- package/dist/{index-D2MYusAM.d.cts → index-BVhp_pcF.d.ts} +3 -0
- package/dist/{index-D2MYusAM.d.ts → index-EaeouYp2.d.cts} +3 -0
- package/dist/index.cjs +1472 -486
- package/dist/index.d.cts +6 -4
- package/dist/index.d.ts +6 -4
- package/dist/index.mjs +1256 -272
- package/dist/mdx-client.cjs +1 -1
- package/dist/mdx-client.mjs +1 -1
- package/dist/mdx-coordinator.cjs +28 -7
- package/dist/mdx-coordinator.d.cts +2 -2
- package/dist/mdx-coordinator.d.ts +2 -2
- package/dist/mdx-coordinator.mjs +28 -7
- package/dist/renderer/node-views.cjs +271 -26
- package/dist/renderer/node-views.d.cts +3 -1
- package/dist/renderer/node-views.d.ts +3 -1
- package/dist/renderer/node-views.mjs +272 -27
- package/dist/renderer/patch-batching.cjs +2 -0
- package/dist/renderer/patch-batching.d.cts +1 -1
- package/dist/renderer/patch-batching.d.ts +1 -1
- package/dist/renderer/patch-batching.mjs +2 -1
- package/dist/renderer/patch-commit-scheduler.cjs +82 -30
- package/dist/renderer/patch-commit-scheduler.d.cts +15 -3
- package/dist/renderer/patch-commit-scheduler.d.ts +15 -3
- package/dist/renderer/patch-commit-scheduler.mjs +84 -30
- package/dist/renderer/store.cjs +382 -36
- package/dist/renderer/store.d.cts +3 -0
- package/dist/renderer/store.d.ts +3 -0
- package/dist/renderer/store.mjs +382 -36
- package/dist/renderer.cjs +758 -114
- package/dist/renderer.d.cts +3 -1
- package/dist/renderer.d.ts +3 -1
- package/dist/renderer.mjs +760 -116
- package/dist/server.cjs +669 -71
- package/dist/server.d.cts +5 -0
- package/dist/server.d.ts +5 -0
- package/dist/server.mjs +670 -72
- package/dist/{streaming-markdown-DOc2uLiP.d.ts → streaming-markdown-CEI9eDZm.d.ts} +3 -1
- package/dist/{streaming-markdown-D-JcByd9.d.cts → streaming-markdown-DRisClXb.d.cts} +3 -1
- package/dist/streaming-markdown.cjs +788 -121
- package/dist/streaming-markdown.d.cts +4 -2
- package/dist/streaming-markdown.d.ts +4 -2
- package/dist/streaming-markdown.mjs +790 -123
- package/dist/utils/inline-html.d.cts +3 -1
- package/dist/utils/inline-html.d.ts +3 -1
- package/package.json +14 -3
- package/shadcn/README.md +28 -0
- package/shadcn/bottom-stick-scroll-area.tsx +358 -0
package/dist/mdx-client.cjs
CHANGED
|
@@ -72,7 +72,7 @@ var MDXClient = class {
|
|
|
72
72
|
if (block.type !== "mdx") {
|
|
73
73
|
throw new Error("Block is not MDX type");
|
|
74
74
|
}
|
|
75
|
-
const cacheKey = block.id
|
|
75
|
+
const cacheKey = `${block.id}\0${block.payload.raw ?? ""}`;
|
|
76
76
|
const cachedPromise = this.cache.get(cacheKey);
|
|
77
77
|
if (cachedPromise) {
|
|
78
78
|
return cachedPromise;
|
package/dist/mdx-client.mjs
CHANGED
|
@@ -34,7 +34,7 @@ var MDXClient = class {
|
|
|
34
34
|
if (block.type !== "mdx") {
|
|
35
35
|
throw new Error("Block is not MDX type");
|
|
36
36
|
}
|
|
37
|
-
const cacheKey = block.id
|
|
37
|
+
const cacheKey = `${block.id}\0${block.payload.raw ?? ""}`;
|
|
38
38
|
const cachedPromise = this.cache.get(cacheKey);
|
|
39
39
|
if (cachedPromise) {
|
|
40
40
|
return cachedPromise;
|
package/dist/mdx-coordinator.cjs
CHANGED
|
@@ -71,7 +71,7 @@ var MDXClient = class {
|
|
|
71
71
|
if (block.type !== "mdx") {
|
|
72
72
|
throw new Error("Block is not MDX type");
|
|
73
73
|
}
|
|
74
|
-
const cacheKey = block.id
|
|
74
|
+
const cacheKey = `${block.id}\0${block.payload.raw ?? ""}`;
|
|
75
75
|
const cachedPromise = this.cache.get(cacheKey);
|
|
76
76
|
if (cachedPromise) {
|
|
77
77
|
return cachedPromise;
|
|
@@ -399,13 +399,14 @@ function useMdxCoordinator(blocks, compileEndpoint, options) {
|
|
|
399
399
|
const mode = options?.mode ?? "server";
|
|
400
400
|
const [compiledMap, setCompiledMap] = (0, import_react2.useState)(/* @__PURE__ */ new Map());
|
|
401
401
|
const blockSignatureRef = (0, import_react2.useRef)(/* @__PURE__ */ new Map());
|
|
402
|
+
const failedSignatureRef = (0, import_react2.useRef)(/* @__PURE__ */ new Map());
|
|
402
403
|
const applyCompiledRef = (0, import_react2.useCallback)(
|
|
403
404
|
(block, compiledId) => {
|
|
404
405
|
if (mode === "worker") {
|
|
405
406
|
return;
|
|
406
407
|
}
|
|
407
408
|
if (options?.workerClient) {
|
|
408
|
-
options.workerClient.setMdxCompiled(block.id, compiledId);
|
|
409
|
+
options.workerClient.setMdxCompiled(block.id, compiledId, block.payload.raw ?? "");
|
|
409
410
|
return;
|
|
410
411
|
}
|
|
411
412
|
const store = options?.store;
|
|
@@ -416,6 +417,9 @@ function useMdxCoordinator(blocks, compileEndpoint, options) {
|
|
|
416
417
|
const index = currentBlocks.findIndex((candidate) => candidate.id === block.id);
|
|
417
418
|
if (index === -1) return;
|
|
418
419
|
const current = currentBlocks[index];
|
|
420
|
+
if ((current.payload.raw ?? "") !== (block.payload.raw ?? "")) {
|
|
421
|
+
return;
|
|
422
|
+
}
|
|
419
423
|
if (current.payload.compiledMdxRef?.id === compiledId) {
|
|
420
424
|
return;
|
|
421
425
|
}
|
|
@@ -445,7 +449,13 @@ function useMdxCoordinator(blocks, compileEndpoint, options) {
|
|
|
445
449
|
if (mode === "worker") {
|
|
446
450
|
return;
|
|
447
451
|
}
|
|
448
|
-
const targets = blocks.filter((b) =>
|
|
452
|
+
const targets = blocks.filter((b) => {
|
|
453
|
+
if (b.type !== "mdx" || !b.isFinalized || b.payload.compiledMdxRef || compiledMap.has(b.id)) {
|
|
454
|
+
return false;
|
|
455
|
+
}
|
|
456
|
+
const raw = b.payload.raw ?? "";
|
|
457
|
+
return failedSignatureRef.current.get(b.id) !== raw;
|
|
458
|
+
});
|
|
449
459
|
if (targets.length === 0) return;
|
|
450
460
|
let cancelled = false;
|
|
451
461
|
(async () => {
|
|
@@ -464,22 +474,29 @@ function useMdxCoordinator(blocks, compileEndpoint, options) {
|
|
|
464
474
|
next.set(block.id, compiled.id);
|
|
465
475
|
return next;
|
|
466
476
|
});
|
|
477
|
+
failedSignatureRef.current.delete(block.id);
|
|
467
478
|
applyCompiledRef(block, compiled.id);
|
|
468
479
|
} catch (e) {
|
|
469
480
|
console.warn("MDX compile failed for block", block.id, e);
|
|
481
|
+
failedSignatureRef.current.set(block.id, block.payload.raw ?? "");
|
|
470
482
|
if (options?.workerClient) {
|
|
471
|
-
options.workerClient.setMdxError(block.id, e instanceof Error ? e.message : String(e));
|
|
483
|
+
options.workerClient.setMdxError(block.id, e instanceof Error ? e.message : String(e), block.payload.raw ?? "");
|
|
472
484
|
} else if (options?.store) {
|
|
485
|
+
const currentBlocks = options.store.getBlocks();
|
|
486
|
+
const current = currentBlocks.find((candidate) => candidate.id === block.id);
|
|
487
|
+
if (!current || (current.payload.raw ?? "") !== (block.payload.raw ?? "")) {
|
|
488
|
+
continue;
|
|
489
|
+
}
|
|
473
490
|
options.store.applyPatches([
|
|
474
491
|
{
|
|
475
492
|
op: "setProps",
|
|
476
493
|
at: { blockId: block.id, nodeId: block.id },
|
|
477
494
|
props: {
|
|
478
495
|
block: {
|
|
479
|
-
...
|
|
496
|
+
...current,
|
|
480
497
|
payload: {
|
|
481
|
-
...
|
|
482
|
-
meta: { ...
|
|
498
|
+
...current.payload,
|
|
499
|
+
meta: { ...current.payload.meta ?? {}, mdxStatus: "error", mdxError: e instanceof Error ? e.message : String(e) }
|
|
483
500
|
}
|
|
484
501
|
}
|
|
485
502
|
}
|
|
@@ -512,6 +529,7 @@ function useMdxCoordinator(blocks, compileEndpoint, options) {
|
|
|
512
529
|
const currentSignature = candidate.payload.raw ?? "";
|
|
513
530
|
if (previousSignature !== void 0 && previousSignature !== currentSignature) {
|
|
514
531
|
next.delete(blockId);
|
|
532
|
+
failedSignatureRef.current.delete(blockId);
|
|
515
533
|
mutated = true;
|
|
516
534
|
}
|
|
517
535
|
}
|
|
@@ -521,6 +539,9 @@ function useMdxCoordinator(blocks, compileEndpoint, options) {
|
|
|
521
539
|
for (const block of blocks) {
|
|
522
540
|
if (block.type === "mdx") {
|
|
523
541
|
signatureMap.set(block.id, block.payload.raw ?? "");
|
|
542
|
+
if (!block.isFinalized || block.payload.compiledMdxRef) {
|
|
543
|
+
failedSignatureRef.current.delete(block.id);
|
|
544
|
+
}
|
|
524
545
|
}
|
|
525
546
|
}
|
|
526
547
|
blockSignatureRef.current = signatureMap;
|
|
@@ -8,8 +8,8 @@ import { RendererStore } from './renderer/store.cjs';
|
|
|
8
8
|
* - Returns a derived blocks array with `compiledMdxRef` populated
|
|
9
9
|
*/
|
|
10
10
|
interface MdxWorkerClientLike {
|
|
11
|
-
setMdxCompiled(blockId: string, compiledId: string): void;
|
|
12
|
-
setMdxError(blockId: string, message: string): void;
|
|
11
|
+
setMdxCompiled(blockId: string, compiledId: string, rawSignature: string): void;
|
|
12
|
+
setMdxError(blockId: string, message: string, rawSignature: string): void;
|
|
13
13
|
}
|
|
14
14
|
interface MdxCoordinatorOptions {
|
|
15
15
|
workerClient?: MdxWorkerClientLike;
|
|
@@ -8,8 +8,8 @@ import { RendererStore } from './renderer/store.js';
|
|
|
8
8
|
* - Returns a derived blocks array with `compiledMdxRef` populated
|
|
9
9
|
*/
|
|
10
10
|
interface MdxWorkerClientLike {
|
|
11
|
-
setMdxCompiled(blockId: string, compiledId: string): void;
|
|
12
|
-
setMdxError(blockId: string, message: string): void;
|
|
11
|
+
setMdxCompiled(blockId: string, compiledId: string, rawSignature: string): void;
|
|
12
|
+
setMdxError(blockId: string, message: string, rawSignature: string): void;
|
|
13
13
|
}
|
|
14
14
|
interface MdxCoordinatorOptions {
|
|
15
15
|
workerClient?: MdxWorkerClientLike;
|
package/dist/mdx-coordinator.mjs
CHANGED
|
@@ -38,7 +38,7 @@ var MDXClient = class {
|
|
|
38
38
|
if (block.type !== "mdx") {
|
|
39
39
|
throw new Error("Block is not MDX type");
|
|
40
40
|
}
|
|
41
|
-
const cacheKey = block.id
|
|
41
|
+
const cacheKey = `${block.id}\0${block.payload.raw ?? ""}`;
|
|
42
42
|
const cachedPromise = this.cache.get(cacheKey);
|
|
43
43
|
if (cachedPromise) {
|
|
44
44
|
return cachedPromise;
|
|
@@ -366,13 +366,14 @@ function useMdxCoordinator(blocks, compileEndpoint, options) {
|
|
|
366
366
|
const mode = options?.mode ?? "server";
|
|
367
367
|
const [compiledMap, setCompiledMap] = useState(/* @__PURE__ */ new Map());
|
|
368
368
|
const blockSignatureRef = useRef(/* @__PURE__ */ new Map());
|
|
369
|
+
const failedSignatureRef = useRef(/* @__PURE__ */ new Map());
|
|
369
370
|
const applyCompiledRef = useCallback(
|
|
370
371
|
(block, compiledId) => {
|
|
371
372
|
if (mode === "worker") {
|
|
372
373
|
return;
|
|
373
374
|
}
|
|
374
375
|
if (options?.workerClient) {
|
|
375
|
-
options.workerClient.setMdxCompiled(block.id, compiledId);
|
|
376
|
+
options.workerClient.setMdxCompiled(block.id, compiledId, block.payload.raw ?? "");
|
|
376
377
|
return;
|
|
377
378
|
}
|
|
378
379
|
const store = options?.store;
|
|
@@ -383,6 +384,9 @@ function useMdxCoordinator(blocks, compileEndpoint, options) {
|
|
|
383
384
|
const index = currentBlocks.findIndex((candidate) => candidate.id === block.id);
|
|
384
385
|
if (index === -1) return;
|
|
385
386
|
const current = currentBlocks[index];
|
|
387
|
+
if ((current.payload.raw ?? "") !== (block.payload.raw ?? "")) {
|
|
388
|
+
return;
|
|
389
|
+
}
|
|
386
390
|
if (current.payload.compiledMdxRef?.id === compiledId) {
|
|
387
391
|
return;
|
|
388
392
|
}
|
|
@@ -412,7 +416,13 @@ function useMdxCoordinator(blocks, compileEndpoint, options) {
|
|
|
412
416
|
if (mode === "worker") {
|
|
413
417
|
return;
|
|
414
418
|
}
|
|
415
|
-
const targets = blocks.filter((b) =>
|
|
419
|
+
const targets = blocks.filter((b) => {
|
|
420
|
+
if (b.type !== "mdx" || !b.isFinalized || b.payload.compiledMdxRef || compiledMap.has(b.id)) {
|
|
421
|
+
return false;
|
|
422
|
+
}
|
|
423
|
+
const raw = b.payload.raw ?? "";
|
|
424
|
+
return failedSignatureRef.current.get(b.id) !== raw;
|
|
425
|
+
});
|
|
416
426
|
if (targets.length === 0) return;
|
|
417
427
|
let cancelled = false;
|
|
418
428
|
(async () => {
|
|
@@ -431,22 +441,29 @@ function useMdxCoordinator(blocks, compileEndpoint, options) {
|
|
|
431
441
|
next.set(block.id, compiled.id);
|
|
432
442
|
return next;
|
|
433
443
|
});
|
|
444
|
+
failedSignatureRef.current.delete(block.id);
|
|
434
445
|
applyCompiledRef(block, compiled.id);
|
|
435
446
|
} catch (e) {
|
|
436
447
|
console.warn("MDX compile failed for block", block.id, e);
|
|
448
|
+
failedSignatureRef.current.set(block.id, block.payload.raw ?? "");
|
|
437
449
|
if (options?.workerClient) {
|
|
438
|
-
options.workerClient.setMdxError(block.id, e instanceof Error ? e.message : String(e));
|
|
450
|
+
options.workerClient.setMdxError(block.id, e instanceof Error ? e.message : String(e), block.payload.raw ?? "");
|
|
439
451
|
} else if (options?.store) {
|
|
452
|
+
const currentBlocks = options.store.getBlocks();
|
|
453
|
+
const current = currentBlocks.find((candidate) => candidate.id === block.id);
|
|
454
|
+
if (!current || (current.payload.raw ?? "") !== (block.payload.raw ?? "")) {
|
|
455
|
+
continue;
|
|
456
|
+
}
|
|
440
457
|
options.store.applyPatches([
|
|
441
458
|
{
|
|
442
459
|
op: "setProps",
|
|
443
460
|
at: { blockId: block.id, nodeId: block.id },
|
|
444
461
|
props: {
|
|
445
462
|
block: {
|
|
446
|
-
...
|
|
463
|
+
...current,
|
|
447
464
|
payload: {
|
|
448
|
-
...
|
|
449
|
-
meta: { ...
|
|
465
|
+
...current.payload,
|
|
466
|
+
meta: { ...current.payload.meta ?? {}, mdxStatus: "error", mdxError: e instanceof Error ? e.message : String(e) }
|
|
450
467
|
}
|
|
451
468
|
}
|
|
452
469
|
}
|
|
@@ -479,6 +496,7 @@ function useMdxCoordinator(blocks, compileEndpoint, options) {
|
|
|
479
496
|
const currentSignature = candidate.payload.raw ?? "";
|
|
480
497
|
if (previousSignature !== void 0 && previousSignature !== currentSignature) {
|
|
481
498
|
next.delete(blockId);
|
|
499
|
+
failedSignatureRef.current.delete(blockId);
|
|
482
500
|
mutated = true;
|
|
483
501
|
}
|
|
484
502
|
}
|
|
@@ -488,6 +506,9 @@ function useMdxCoordinator(blocks, compileEndpoint, options) {
|
|
|
488
506
|
for (const block of blocks) {
|
|
489
507
|
if (block.type === "mdx") {
|
|
490
508
|
signatureMap.set(block.id, block.payload.raw ?? "");
|
|
509
|
+
if (!block.isFinalized || block.payload.compiledMdxRef) {
|
|
510
|
+
failedSignatureRef.current.delete(block.id);
|
|
511
|
+
}
|
|
491
512
|
}
|
|
492
513
|
}
|
|
493
514
|
blockSignatureRef.current = signatureMap;
|
|
@@ -521,7 +521,11 @@ var defaultInlineComponents = {
|
|
|
521
521
|
const n = number ?? "?";
|
|
522
522
|
const href = number ? `#fn:${n}` : void 0;
|
|
523
523
|
const id = number ? `fnref:${n}` : void 0;
|
|
524
|
-
return import_react3.default.createElement(
|
|
524
|
+
return import_react3.default.createElement(
|
|
525
|
+
"sup",
|
|
526
|
+
{ className: "footnote-ref" },
|
|
527
|
+
import_react3.default.createElement("a", { href, id, "data-label": label, style: { color: "var(--foreground)", textDecoration: "underline" } }, String(n))
|
|
528
|
+
);
|
|
525
529
|
}
|
|
526
530
|
};
|
|
527
531
|
function renderParagraphMixedSegments(segments, inlineComponents, inlineHtmlRenderers) {
|
|
@@ -729,6 +733,7 @@ var DeferredRenderContext = import_react6.default.createContext(null);
|
|
|
729
733
|
|
|
730
734
|
// src/renderer/store.ts
|
|
731
735
|
var import_core3 = require("@stream-mdx/core");
|
|
736
|
+
var import_patch_batching = require("@stream-mdx/core/perf/patch-batching");
|
|
732
737
|
var NODE_SNAPSHOT_CACHE_LIMIT = 5e4;
|
|
733
738
|
var CHILDREN_SNAPSHOT_CACHE_LIMIT = 5e4;
|
|
734
739
|
var NODE_SNAPSHOT_CACHE_BUFFER = Math.max(200, Math.floor(NODE_SNAPSHOT_CACHE_LIMIT * 0.1));
|
|
@@ -1207,8 +1212,10 @@ var ListBlockView = import_react8.default.memo(
|
|
|
1207
1212
|
isFinalized: block?.isFinalized ?? false
|
|
1208
1213
|
});
|
|
1209
1214
|
}, [listDebugEnabled, blockId, depth, ordered, childIds, listItemIds, store, block?.isFinalized]);
|
|
1210
|
-
const listStyle = import_react8.default.useMemo(() => {
|
|
1211
|
-
if (!ordered || listItemIds.length === 0)
|
|
1215
|
+
const { listStyle, markerDigits } = import_react8.default.useMemo(() => {
|
|
1216
|
+
if (!ordered || listItemIds.length === 0) {
|
|
1217
|
+
return { listStyle: void 0, markerDigits: 1 };
|
|
1218
|
+
}
|
|
1212
1219
|
let maxDigits = 1;
|
|
1213
1220
|
listItemIds.forEach((childId, index) => {
|
|
1214
1221
|
const childNode = store.getNode(childId);
|
|
@@ -1220,9 +1227,14 @@ var ListBlockView = import_react8.default.memo(
|
|
|
1220
1227
|
const digits = digitMatch ? digitMatch.length : text.length;
|
|
1221
1228
|
if (digits > maxDigits) maxDigits = digits;
|
|
1222
1229
|
});
|
|
1223
|
-
const baseIndent = depth === 0 ? "
|
|
1230
|
+
const baseIndent = depth === 0 ? "2rem" : depth === 1 ? "1.75rem" : "1.5rem";
|
|
1231
|
+
const extraDigits = Math.max(0, maxDigits - 1);
|
|
1224
1232
|
return {
|
|
1225
|
-
|
|
1233
|
+
markerDigits: maxDigits,
|
|
1234
|
+
listStyle: {
|
|
1235
|
+
["--list-indent"]: extraDigits > 0 ? `calc(${baseIndent} + ${extraDigits}ch)` : baseIndent,
|
|
1236
|
+
["--list-marker-digits"]: String(maxDigits)
|
|
1237
|
+
}
|
|
1226
1238
|
};
|
|
1227
1239
|
}, [ordered, listItemIds, store, depth]);
|
|
1228
1240
|
if (listItemIds.length === 0) return null;
|
|
@@ -1231,6 +1243,7 @@ var ListBlockView = import_react8.default.memo(
|
|
|
1231
1243
|
{
|
|
1232
1244
|
className: `markdown-list ${ordered ? "ordered" : "unordered"}`,
|
|
1233
1245
|
"data-list-depth": depth,
|
|
1246
|
+
"data-marker-digits": ordered ? markerDigits : void 0,
|
|
1234
1247
|
"data-list-id": listDebugEnabled ? blockId : void 0,
|
|
1235
1248
|
style: listStyle,
|
|
1236
1249
|
children: listItemIds.map((childId, index) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
@@ -1412,6 +1425,7 @@ var CodeBlockView = import_react8.default.memo(({ store, blockId, registry }) =>
|
|
|
1412
1425
|
deferredConfig ? { ...deferredConfig, enabled: true } : { enabled: false }
|
|
1413
1426
|
);
|
|
1414
1427
|
if (!node || !node.block) return null;
|
|
1428
|
+
const blockIsFinalized = node.block.isFinalized;
|
|
1415
1429
|
const nodeVersion = node.version;
|
|
1416
1430
|
const lines = import_react8.default.useMemo(() => {
|
|
1417
1431
|
const seenIds = /* @__PURE__ */ new Set();
|
|
@@ -1442,13 +1456,25 @@ var CodeBlockView = import_react8.default.memo(({ store, blockId, registry }) =>
|
|
|
1442
1456
|
const lang = typeof node.props?.lang === "string" ? node.props?.lang : node.block.payload.meta?.lang;
|
|
1443
1457
|
const preAttrs = node.props?.preAttrs ?? void 0;
|
|
1444
1458
|
const codeAttrs = node.props?.codeAttrs ?? void 0;
|
|
1459
|
+
const blockMeta = node.block.payload.meta ?? void 0;
|
|
1460
|
+
const lazyEnabled = Boolean(blockMeta?.lazyTokenization);
|
|
1461
|
+
const lazyTokenizedUntil = typeof blockMeta?.lazyTokenizedUntil === "number" ? blockMeta.lazyTokenizedUntil : 0;
|
|
1462
|
+
const lazyHighlightedLines = Array.isArray(blockMeta?.highlightedLines) ? blockMeta.highlightedLines.length : 0;
|
|
1463
|
+
const lazyTokenLines = Array.isArray(blockMeta?.tokenLines) ? blockMeta.tokenLines.length : 0;
|
|
1464
|
+
const lazySourceTextLineCount = import_react8.default.useMemo(() => {
|
|
1465
|
+
const raw = typeof node.block?.payload.raw === "string" ? node.block.payload.raw : "";
|
|
1466
|
+
const metaCode = typeof blockMeta?.code === "string" ? blockMeta.code : null;
|
|
1467
|
+
const sourceText = resolveCodeSourceText(raw, metaCode);
|
|
1468
|
+
if (sourceText.length === 0) return 0;
|
|
1469
|
+
return sourceText.split("\n").length;
|
|
1470
|
+
}, [blockMeta, node.block?.payload.raw]);
|
|
1471
|
+
const totalLazyLineCount = Math.max(lines.length, lazyHighlightedLines, lazyTokenLines, lazySourceTextLineCount);
|
|
1445
1472
|
const virtualizationConfig = DEFAULT_VIRTUALIZED_CODE_CONFIG;
|
|
1446
1473
|
const virtualizationDisabled = typeof process !== "undefined" && typeof process.env === "object" && process.env.STREAM_MDX_DISABLE_VIRTUALIZED_CODE === "true";
|
|
1447
|
-
const
|
|
1474
|
+
const canVirtualize = node.block.isFinalized && !lazyEnabled;
|
|
1475
|
+
const shouldVirtualize = canVirtualize && !virtualizationDisabled && virtualizationConfig.enabled && lines.length >= virtualizationConfig.virtualizeThreshold;
|
|
1448
1476
|
const virtualization = useVirtualizedCode(lines, shouldVirtualize ? virtualizationConfig : { ...virtualizationConfig, enabled: false });
|
|
1449
1477
|
const highlightRequester = useCodeHighlightRequester();
|
|
1450
|
-
const lazyEnabled = Boolean(node.block.payload.meta?.lazyTokenization);
|
|
1451
|
-
const lazyTokenizedUntil = typeof node.block.payload.meta?.lazyTokenizedUntil === "number" ? node.block.payload.meta.lazyTokenizedUntil : 0;
|
|
1452
1478
|
const lastRangeRef = import_react8.default.useRef(null);
|
|
1453
1479
|
const rafRef = import_react8.default.useRef(null);
|
|
1454
1480
|
const idleRef = import_react8.default.useRef(null);
|
|
@@ -1529,29 +1555,111 @@ var CodeBlockView = import_react8.default.memo(({ store, blockId, registry }) =>
|
|
|
1529
1555
|
virtualization.window.startIndex,
|
|
1530
1556
|
virtualization.window.endIndex
|
|
1531
1557
|
]);
|
|
1532
|
-
|
|
1533
|
-
if (
|
|
1534
|
-
|
|
1558
|
+
import_react8.default.useEffect(() => {
|
|
1559
|
+
if (shouldVirtualize || !blockIsFinalized || !lazyEnabled || !highlightRequester) return;
|
|
1560
|
+
if (totalLazyLineCount <= 0 || lazyTokenizedUntil >= totalLazyLineCount) return;
|
|
1561
|
+
const nextRange = {
|
|
1562
|
+
visibleStart: 0,
|
|
1563
|
+
visibleEnd: totalLazyLineCount,
|
|
1564
|
+
prefetchStart: 0,
|
|
1565
|
+
prefetchEnd: totalLazyLineCount,
|
|
1566
|
+
tokenizedUntil: lazyTokenizedUntil
|
|
1567
|
+
};
|
|
1568
|
+
const last = lastRangeRef.current;
|
|
1569
|
+
if (last && last.visibleStart === nextRange.visibleStart && last.visibleEnd === nextRange.visibleEnd && last.prefetchStart === nextRange.prefetchStart && last.prefetchEnd === nextRange.prefetchEnd && last.tokenizedUntil === nextRange.tokenizedUntil) {
|
|
1570
|
+
return;
|
|
1571
|
+
}
|
|
1572
|
+
lastRangeRef.current = nextRange;
|
|
1573
|
+
if (rafRef.current !== null && typeof cancelAnimationFrame === "function") {
|
|
1574
|
+
cancelAnimationFrame(rafRef.current);
|
|
1575
|
+
}
|
|
1576
|
+
const requestFullHighlight = () => {
|
|
1577
|
+
highlightRequester({
|
|
1578
|
+
blockId,
|
|
1579
|
+
startLine: 0,
|
|
1580
|
+
endLine: totalLazyLineCount,
|
|
1581
|
+
priority: "visible",
|
|
1582
|
+
reason: "finalize-full"
|
|
1583
|
+
});
|
|
1584
|
+
rafRef.current = null;
|
|
1585
|
+
};
|
|
1586
|
+
if (typeof requestAnimationFrame === "function") {
|
|
1587
|
+
rafRef.current = requestAnimationFrame(requestFullHighlight);
|
|
1588
|
+
} else {
|
|
1589
|
+
requestFullHighlight();
|
|
1535
1590
|
}
|
|
1591
|
+
}, [blockId, blockIsFinalized, highlightRequester, lazyEnabled, lazyTokenizedUntil, shouldVirtualize, totalLazyLineCount]);
|
|
1592
|
+
const highlightedHtml = import_react8.default.useMemo(() => {
|
|
1593
|
+
const blockHtml = node.block?.payload.highlightedHtml ?? "";
|
|
1594
|
+
const raw = typeof node.block?.payload.raw === "string" ? node.block.payload.raw : "";
|
|
1595
|
+
const metaCode = typeof node.block?.payload.meta?.code === "string" ? (node.block?.payload.meta).code : null;
|
|
1596
|
+
const sourceText = resolveCodeSourceText(raw, metaCode);
|
|
1597
|
+
const sourceEndsWithNewline = sourceText.endsWith("\n");
|
|
1598
|
+
const sourceLines = sourceText.length > 0 ? sourceText.split("\n") : [];
|
|
1599
|
+
const rawFallbackLines = buildCodeFallbackLines(raw);
|
|
1600
|
+
const deterministicWrapperAttrs = (0, import_core4.getDefaultCodeWrapperAttributes)(lang);
|
|
1601
|
+
const composedPreAttrs = deterministicWrapperAttrs.preAttrs;
|
|
1602
|
+
const composedCodeAttrs = deterministicWrapperAttrs.codeAttrs;
|
|
1603
|
+
const shouldAppendTerminalNewline = (renderedLines) => {
|
|
1604
|
+
if (!sourceEndsWithNewline || renderedLines.length === 0 || lines.length === 0) {
|
|
1605
|
+
return false;
|
|
1606
|
+
}
|
|
1607
|
+
const lastRendered = renderedLines[renderedLines.length - 1];
|
|
1608
|
+
const lastKnown = lines[lines.length - 1];
|
|
1609
|
+
if (!lastRendered || !lastKnown || lastRendered.index !== lastKnown.index || lastRendered.text === "") {
|
|
1610
|
+
return false;
|
|
1611
|
+
}
|
|
1612
|
+
const expectedRenderedLineCount = Math.max(0, sourceLines.length - 1);
|
|
1613
|
+
const expectedLastRenderedLine = sourceLines.length >= 2 ? sourceLines[sourceLines.length - 2] ?? "" : "";
|
|
1614
|
+
return renderedLines.length === expectedRenderedLineCount && lastRendered.text === expectedLastRenderedLine;
|
|
1615
|
+
};
|
|
1536
1616
|
if (lines.length > 0) {
|
|
1537
1617
|
const hasLineHtml = lines.some((line) => typeof line.html === "string" && line.html.length > 0);
|
|
1538
|
-
if (!hasLineHtml &&
|
|
1539
|
-
return
|
|
1618
|
+
if (!hasLineHtml && blockHtml) {
|
|
1619
|
+
return blockHtml;
|
|
1540
1620
|
}
|
|
1541
1621
|
if (shouldVirtualize) {
|
|
1542
|
-
return composeHighlightedHtml(
|
|
1622
|
+
return composeHighlightedHtml(
|
|
1623
|
+
virtualization.window.visibleLines,
|
|
1624
|
+
composedPreAttrs,
|
|
1625
|
+
composedCodeAttrs,
|
|
1626
|
+
shouldAppendTerminalNewline(virtualization.window.visibleLines)
|
|
1627
|
+
);
|
|
1543
1628
|
}
|
|
1544
|
-
return composeHighlightedHtml(lines,
|
|
1629
|
+
return composeHighlightedHtml(lines, composedPreAttrs, composedCodeAttrs, shouldAppendTerminalNewline(lines));
|
|
1630
|
+
}
|
|
1631
|
+
if (!shouldVirtualize && blockHtml) {
|
|
1632
|
+
const hasHighlightedLines = blockHtml.includes('class="line"');
|
|
1633
|
+
if (!hasHighlightedLines && rawFallbackLines.length > 0) {
|
|
1634
|
+
return composeHighlightedHtml(
|
|
1635
|
+
rawFallbackLines,
|
|
1636
|
+
composedPreAttrs,
|
|
1637
|
+
composedCodeAttrs,
|
|
1638
|
+
sourceEndsWithNewline && rawFallbackLines[rawFallbackLines.length - 1]?.text !== ""
|
|
1639
|
+
);
|
|
1640
|
+
}
|
|
1641
|
+
return blockHtml;
|
|
1545
1642
|
}
|
|
1546
|
-
const blockHtml = node.block?.payload.highlightedHtml ?? "";
|
|
1547
1643
|
if (blockHtml?.trim().match(/^```[\w-]*\s*$/)) {
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
|
|
1644
|
+
if (rawFallbackLines.length > 0) {
|
|
1645
|
+
return composeHighlightedHtml(
|
|
1646
|
+
rawFallbackLines,
|
|
1647
|
+
composedPreAttrs,
|
|
1648
|
+
composedCodeAttrs,
|
|
1649
|
+
sourceEndsWithNewline && rawFallbackLines[rawFallbackLines.length - 1]?.text !== ""
|
|
1650
|
+
);
|
|
1551
1651
|
}
|
|
1552
1652
|
}
|
|
1653
|
+
if (!blockHtml && rawFallbackLines.length > 0) {
|
|
1654
|
+
return composeHighlightedHtml(
|
|
1655
|
+
rawFallbackLines,
|
|
1656
|
+
composedPreAttrs,
|
|
1657
|
+
composedCodeAttrs,
|
|
1658
|
+
sourceEndsWithNewline && rawFallbackLines[rawFallbackLines.length - 1]?.text !== ""
|
|
1659
|
+
);
|
|
1660
|
+
}
|
|
1553
1661
|
return blockHtml;
|
|
1554
|
-
}, [shouldVirtualize, node.block?.payload.highlightedHtml,
|
|
1662
|
+
}, [blockIsFinalized, shouldVirtualize, node.block?.payload.highlightedHtml, node.block?.payload.meta, lines, lang, virtualization.window.visibleLines, node.block?.payload.raw]);
|
|
1555
1663
|
const rendered = /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
1556
1664
|
CodeComponent,
|
|
1557
1665
|
{
|
|
@@ -1563,13 +1671,19 @@ var CodeBlockView = import_react8.default.memo(({ store, blockId, registry }) =>
|
|
|
1563
1671
|
codeAttrs
|
|
1564
1672
|
}
|
|
1565
1673
|
);
|
|
1674
|
+
const effectiveLineCount = import_react8.default.useMemo(() => {
|
|
1675
|
+
if (lines.length > 0) {
|
|
1676
|
+
return lines.length;
|
|
1677
|
+
}
|
|
1678
|
+
return 1;
|
|
1679
|
+
}, [lines.length]);
|
|
1566
1680
|
const codeFrameClass = "not-prose flex flex-col rounded-lg border border-input pt-1 font-mono text-sm";
|
|
1567
1681
|
const codeMetricsAttrs = {
|
|
1568
1682
|
"data-code-block": "true",
|
|
1569
1683
|
"data-block-id": blockId,
|
|
1570
1684
|
"data-code-virtualized": shouldVirtualize ? "true" : "false",
|
|
1571
|
-
"data-code-total-lines": String(
|
|
1572
|
-
"data-code-mounted-lines": String(shouldVirtualize ? virtualization.window.mountedLines :
|
|
1685
|
+
"data-code-total-lines": String(effectiveLineCount),
|
|
1686
|
+
"data-code-mounted-lines": String(shouldVirtualize ? virtualization.window.mountedLines : effectiveLineCount),
|
|
1573
1687
|
"data-code-window-size": String(virtualization.config.windowSize)
|
|
1574
1688
|
};
|
|
1575
1689
|
const codeView = shouldVirtualize ? (() => {
|
|
@@ -1615,21 +1729,152 @@ var CodeBlockView = import_react8.default.memo(({ store, blockId, registry }) =>
|
|
|
1615
1729
|
return codeView;
|
|
1616
1730
|
});
|
|
1617
1731
|
CodeBlockView.displayName = "CodeBlockView";
|
|
1618
|
-
function composeHighlightedHtml(lines, preAttrs, codeAttrs) {
|
|
1732
|
+
function composeHighlightedHtml(lines, preAttrs, codeAttrs, appendTerminalNewline = false) {
|
|
1619
1733
|
const lineMarkup = lines.map((line) => {
|
|
1620
|
-
const content = line.html ?? escapeHtml(line.text);
|
|
1734
|
+
const content = line.html ?? renderTokenLineHtml(line.tokens) ?? escapeHtml(line.text);
|
|
1621
1735
|
const dataLine = Number.isFinite(line.index) ? ` data-line="${line.index + 1}"` : "";
|
|
1622
1736
|
return `<span class="line"${dataLine}>${content}</span>`;
|
|
1623
1737
|
}).join("\n");
|
|
1624
1738
|
const preAttr = attrsToString(preAttrs);
|
|
1625
1739
|
const codeAttr = attrsToString(codeAttrs);
|
|
1626
|
-
return `<pre${preAttr}><code${codeAttr}>${lineMarkup}
|
|
1627
|
-
|
|
1740
|
+
return `<pre${preAttr}><code${codeAttr}>${lineMarkup}${appendTerminalNewline ? "\n" : ""}</code></pre>`;
|
|
1741
|
+
}
|
|
1742
|
+
var TOKEN_FONT_STYLE_ITALIC = 1;
|
|
1743
|
+
var TOKEN_FONT_STYLE_BOLD = 2;
|
|
1744
|
+
var TOKEN_FONT_STYLE_UNDERLINE = 4;
|
|
1745
|
+
var TOKEN_FONT_STYLE_STRIKETHROUGH = 8;
|
|
1746
|
+
function renderTokenLineHtml(tokens) {
|
|
1747
|
+
if (!tokens || !Array.isArray(tokens.spans)) {
|
|
1748
|
+
return null;
|
|
1749
|
+
}
|
|
1750
|
+
return mergeRenderableTokenSpans(tokens.spans).map((span) => renderTokenSpanHtml(span)).join("");
|
|
1751
|
+
}
|
|
1752
|
+
function renderTokenSpanHtml(span) {
|
|
1753
|
+
const dark = span.v?.dark;
|
|
1754
|
+
const light = span.v?.light;
|
|
1755
|
+
const single = span.s;
|
|
1756
|
+
const styles = [];
|
|
1757
|
+
if (dark?.fg) {
|
|
1758
|
+
styles.push(`--shiki-dark:${dark.fg}`);
|
|
1759
|
+
}
|
|
1760
|
+
if (light?.fg) {
|
|
1761
|
+
styles.push(`--shiki-light:${light.fg}`);
|
|
1762
|
+
}
|
|
1763
|
+
if (!light?.fg && !dark?.fg && single?.fg) {
|
|
1764
|
+
styles.push(`color:${single.fg}`);
|
|
1765
|
+
}
|
|
1766
|
+
const fontStyle = light?.fs ?? dark?.fs ?? single?.fs;
|
|
1767
|
+
if (typeof fontStyle === "number" && fontStyle > 0) {
|
|
1768
|
+
if (fontStyle & TOKEN_FONT_STYLE_ITALIC) {
|
|
1769
|
+
styles.push("font-style: italic");
|
|
1770
|
+
}
|
|
1771
|
+
if (fontStyle & TOKEN_FONT_STYLE_BOLD) {
|
|
1772
|
+
styles.push("font-weight: bold");
|
|
1773
|
+
}
|
|
1774
|
+
const decorations = [];
|
|
1775
|
+
if (fontStyle & TOKEN_FONT_STYLE_UNDERLINE) {
|
|
1776
|
+
decorations.push("underline");
|
|
1777
|
+
}
|
|
1778
|
+
if (fontStyle & TOKEN_FONT_STYLE_STRIKETHROUGH) {
|
|
1779
|
+
decorations.push("line-through");
|
|
1780
|
+
}
|
|
1781
|
+
if (decorations.length > 0) {
|
|
1782
|
+
styles.push(`text-decoration: ${decorations.join(" ")}`);
|
|
1783
|
+
}
|
|
1784
|
+
}
|
|
1785
|
+
const content = escapeHtml(span.t ?? "");
|
|
1786
|
+
if (styles.length === 0) {
|
|
1787
|
+
return content;
|
|
1788
|
+
}
|
|
1789
|
+
return `<span style="${styles.join(";")}">${content}</span>`;
|
|
1790
|
+
}
|
|
1791
|
+
function mergeRenderableTokenSpans(spans) {
|
|
1792
|
+
if (spans.length <= 1) {
|
|
1793
|
+
return spans.slice();
|
|
1794
|
+
}
|
|
1795
|
+
const merged = [];
|
|
1796
|
+
let pendingWhitespace = "";
|
|
1797
|
+
for (const span of spans) {
|
|
1798
|
+
const text = typeof span.t === "string" ? span.t : "";
|
|
1799
|
+
if (/^[\t ]+$/.test(text)) {
|
|
1800
|
+
pendingWhitespace += text;
|
|
1801
|
+
continue;
|
|
1802
|
+
}
|
|
1803
|
+
const nextSpan = pendingWhitespace ? { ...span, t: `${pendingWhitespace}${text}` } : span;
|
|
1804
|
+
pendingWhitespace = "";
|
|
1805
|
+
const previous = merged[merged.length - 1];
|
|
1806
|
+
if (previous && sameTokenSpanStyle(previous, nextSpan)) {
|
|
1807
|
+
previous.t += nextSpan.t;
|
|
1808
|
+
} else {
|
|
1809
|
+
merged.push({ ...nextSpan });
|
|
1810
|
+
}
|
|
1811
|
+
}
|
|
1812
|
+
if (pendingWhitespace) {
|
|
1813
|
+
const previous = merged[merged.length - 1];
|
|
1814
|
+
if (previous) {
|
|
1815
|
+
previous.t += pendingWhitespace;
|
|
1816
|
+
} else {
|
|
1817
|
+
merged.push({ t: pendingWhitespace });
|
|
1818
|
+
}
|
|
1819
|
+
}
|
|
1820
|
+
return merged;
|
|
1821
|
+
}
|
|
1822
|
+
function sameTokenSpanStyle(a, b) {
|
|
1823
|
+
const variantKeys = /* @__PURE__ */ new Set([
|
|
1824
|
+
...Object.keys(a.v ?? {}),
|
|
1825
|
+
...Object.keys(b.v ?? {})
|
|
1826
|
+
]);
|
|
1827
|
+
for (const key of variantKeys) {
|
|
1828
|
+
const aStyle = a.v?.[key];
|
|
1829
|
+
const bStyle = b.v?.[key];
|
|
1830
|
+
if ((aStyle?.fg ?? null) !== (bStyle?.fg ?? null)) return false;
|
|
1831
|
+
if ((aStyle?.bg ?? null) !== (bStyle?.bg ?? null)) return false;
|
|
1832
|
+
if ((aStyle?.fs ?? null) !== (bStyle?.fs ?? null)) return false;
|
|
1833
|
+
}
|
|
1834
|
+
if ((a.s?.fg ?? null) !== (b.s?.fg ?? null)) return false;
|
|
1835
|
+
if ((a.s?.bg ?? null) !== (b.s?.bg ?? null)) return false;
|
|
1836
|
+
if ((a.s?.fs ?? null) !== (b.s?.fs ?? null)) return false;
|
|
1837
|
+
return true;
|
|
1838
|
+
}
|
|
1839
|
+
function resolveCodeSourceText(raw, metaCode) {
|
|
1840
|
+
if (metaCode !== null) {
|
|
1841
|
+
return metaCode.replace(/\r\n?/g, "\n");
|
|
1842
|
+
}
|
|
1843
|
+
if (!raw) return "";
|
|
1844
|
+
const normalized = raw.replace(/\r\n?/g, "\n");
|
|
1845
|
+
const fenced = (0, import_core4.stripCodeFence)(normalized);
|
|
1846
|
+
return fenced.hadFence ? fenced.code : normalized;
|
|
1628
1847
|
}
|
|
1629
1848
|
function attrsToString(attrs) {
|
|
1630
1849
|
if (!attrs) return "";
|
|
1631
1850
|
return Object.entries(attrs).map(([key, value]) => ` ${key}="${escapeAttribute(value)}"`).join("");
|
|
1632
1851
|
}
|
|
1852
|
+
function buildCodeFallbackLines(raw) {
|
|
1853
|
+
const normalized = normalizeCodeFallbackRaw(raw);
|
|
1854
|
+
if (normalized.length === 0) {
|
|
1855
|
+
if (/^\s*```[^\n]*\n?\s*$/.test(raw)) {
|
|
1856
|
+
return [{ id: "temp-0", index: 0, text: "", html: null }];
|
|
1857
|
+
}
|
|
1858
|
+
return [];
|
|
1859
|
+
}
|
|
1860
|
+
return normalized.split("\n").map((line, index) => ({
|
|
1861
|
+
id: `temp-${index}`,
|
|
1862
|
+
index,
|
|
1863
|
+
text: line,
|
|
1864
|
+
html: null
|
|
1865
|
+
}));
|
|
1866
|
+
}
|
|
1867
|
+
function normalizeCodeFallbackRaw(raw) {
|
|
1868
|
+
if (!raw) return "";
|
|
1869
|
+
const normalized = raw.replace(/\r\n?/g, "\n");
|
|
1870
|
+
const fenced = (0, import_core4.stripCodeFence)(normalized);
|
|
1871
|
+
if (!fenced.hadFence) {
|
|
1872
|
+
return normalized.replace(/\n+$/, "");
|
|
1873
|
+
}
|
|
1874
|
+
let code = fenced.code;
|
|
1875
|
+
code = code.replace(/\n+$/, "");
|
|
1876
|
+
return code;
|
|
1877
|
+
}
|
|
1633
1878
|
function escapeHtml(value) {
|
|
1634
1879
|
return value.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
|
1635
1880
|
}
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import { C as ComponentRegistry } from '../index-
|
|
2
|
+
import { C as ComponentRegistry } from '../index-EaeouYp2.cjs';
|
|
3
3
|
import { RendererStore } from './store.cjs';
|
|
4
|
+
import '../components/bottom-stick-scroll-area.cjs';
|
|
5
|
+
import 'react/jsx-runtime';
|
|
4
6
|
import '@stream-mdx/core';
|
|
5
7
|
|
|
6
8
|
declare const BlockNodeRenderer: React.FC<{
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import { C as ComponentRegistry } from '../index-
|
|
2
|
+
import { C as ComponentRegistry } from '../index-BVhp_pcF.js';
|
|
3
3
|
import { RendererStore } from './store.js';
|
|
4
|
+
import '../components/bottom-stick-scroll-area.js';
|
|
5
|
+
import 'react/jsx-runtime';
|
|
4
6
|
import '@stream-mdx/core';
|
|
5
7
|
|
|
6
8
|
declare const BlockNodeRenderer: React.FC<{
|