@stream-mdx/react 0.5.0 → 1.0.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 +371 -0
- package/README.md +79 -4
- package/dist/blocks-renderer-DAOBFBfi.d.ts +29 -0
- package/dist/blocks-renderer-DQEL1kJW.d.cts +29 -0
- package/dist/components/bottom-stick-scroll-area.cjs +117 -193
- package/dist/components/bottom-stick-scroll-area.mjs +112 -183
- package/dist/components/diff-renderer.cjs +86 -0
- package/dist/components/diff-renderer.d.cts +11 -0
- package/dist/components/diff-renderer.d.ts +11 -0
- package/dist/components/diff-renderer.mjs +66 -0
- package/dist/components/index.cjs +2761 -1508
- package/dist/components/index.d.cts +7 -2
- package/dist/components/index.d.ts +7 -2
- package/dist/components/index.mjs +2730 -1493
- package/dist/components/katex-math.cjs +220 -0
- package/dist/components/katex-math.d.cts +10 -0
- package/dist/components/katex-math.d.ts +10 -0
- package/dist/components/katex-math.mjs +188 -0
- package/dist/contexts/math-tracker.cjs +240 -521
- package/dist/contexts/math-tracker.mjs +235 -513
- package/dist/index-Cmne1yUK.d.cts +723 -0
- package/dist/index-D7dyyu3q.d.ts +723 -0
- package/dist/index.cjs +13029 -6475
- package/dist/index.d.cts +69 -39
- package/dist/index.d.ts +69 -39
- package/dist/index.mjs +13007 -6442
- package/dist/math/display-wrapper.cjs +7 -15
- package/dist/math/display-wrapper.d.cts +2 -2
- package/dist/math/display-wrapper.d.ts +2 -2
- package/dist/math/display-wrapper.mjs +2 -6
- package/dist/node-views-Bpc6Gkgl.d.cts +13 -0
- package/dist/node-views-DpnYdaAS.d.ts +13 -0
- package/dist/renderer/hooks.cjs +35 -20
- package/dist/renderer/hooks.d.cts +22 -1
- package/dist/renderer/hooks.d.ts +22 -1
- package/dist/renderer/hooks.mjs +27 -12
- package/dist/renderer/patch-batching.cjs +5 -8
- package/dist/renderer/patch-coalescing.cjs +5 -8
- package/dist/renderer/patch-commit-scheduler.cjs +138 -356
- package/dist/renderer/patch-commit-scheduler.d.cts +13 -1
- package/dist/renderer/patch-commit-scheduler.d.ts +13 -1
- package/dist/renderer/patch-commit-scheduler.mjs +133 -348
- package/dist/renderer/store.cjs +3775 -1373
- package/dist/renderer/store.d.cts +108 -3
- package/dist/renderer/store.d.ts +108 -3
- package/dist/renderer/store.mjs +3778 -1362
- package/dist/renderer/virtualized-code.cjs +415 -71
- package/dist/renderer/virtualized-code.d.cts +24 -23
- package/dist/renderer/virtualized-code.d.ts +24 -23
- package/dist/renderer/virtualized-code.mjs +409 -62
- package/dist/renderer.cjs +10655 -4334
- package/dist/renderer.d.cts +98 -29
- package/dist/renderer.d.ts +98 -29
- package/dist/renderer.mjs +10582 -4212
- package/dist/server-regions-CPLHGli0.d.cts +32 -0
- package/dist/server-regions-mUhyoKi7.d.ts +32 -0
- package/dist/server.cjs +10195 -3872
- package/dist/server.d.cts +17 -252
- package/dist/server.d.ts +17 -252
- package/dist/server.mjs +9997 -3649
- package/dist/{streaming-markdown-CEI9eDZm.d.ts → streaming-markdown-yELbJxyH.d.ts} +49 -55
- package/dist/{streaming-markdown-DRisClXb.d.cts → streaming-markdown-zVwFuaJG.d.cts} +49 -55
- package/dist/streaming-markdown.cjs +11660 -5378
- package/dist/streaming-markdown.d.cts +7 -2
- package/dist/streaming-markdown.d.ts +7 -2
- package/dist/streaming-markdown.mjs +11679 -5347
- package/dist/trusted-mdx/index.cjs +833 -0
- package/dist/trusted-mdx/index.d.cts +11 -0
- package/dist/trusted-mdx/index.d.ts +11 -0
- package/dist/trusted-mdx/index.mjs +807 -0
- package/dist/trusted-mdx/native-children-slot.cjs +45 -0
- package/dist/trusted-mdx/native-children-slot.d.cts +11 -0
- package/dist/trusted-mdx/native-children-slot.d.ts +11 -0
- package/dist/trusted-mdx/native-children-slot.mjs +24 -0
- package/dist/trusted-mdx/server.cjs +752 -0
- package/dist/trusted-mdx/server.d.cts +24 -0
- package/dist/trusted-mdx/server.d.ts +24 -0
- package/dist/trusted-mdx/server.mjs +724 -0
- package/dist/trusted-mdx-contract-ElKpkDI5.d.cts +113 -0
- package/dist/trusted-mdx-contract-ElKpkDI5.d.ts +113 -0
- package/dist/utils/inline-html.cjs +246 -147
- package/dist/utils/inline-html.d.cts +37 -6
- package/dist/utils/inline-html.d.ts +37 -6
- package/dist/utils/inline-html.mjs +237 -134
- package/package.json +41 -18
- package/dist/index-BVhp_pcF.d.ts +0 -251
- package/dist/index-EaeouYp2.d.cts +0 -251
- package/dist/mdx-client.cjs +0 -408
- package/dist/mdx-client.d.cts +0 -113
- package/dist/mdx-client.d.ts +0 -113
- package/dist/mdx-client.mjs +0 -369
- package/dist/mdx-coordinator.cjs +0 -584
- package/dist/mdx-coordinator.d.cts +0 -21
- package/dist/mdx-coordinator.d.ts +0 -21
- package/dist/mdx-coordinator.mjs +0 -550
- package/dist/renderer/node-views.cjs +0 -1887
- package/dist/renderer/node-views.d.cts +0 -14
- package/dist/renderer/node-views.d.ts +0 -14
- package/dist/renderer/node-views.mjs +0 -1861
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,376 @@
|
|
|
1
1
|
# @stream-mdx/react
|
|
2
2
|
|
|
3
|
+
## 1.0.0
|
|
4
|
+
|
|
5
|
+
### Major Changes
|
|
6
|
+
|
|
7
|
+
- f28e605: Presentation wrappers receive prepared children, bounded metadata, and source-bound actions; the unbounded full Block prop is removed.
|
|
8
|
+
- 2c019b9: Report whether a diff document's declared hunk row counts hold. `CodeBlockMetadata.diffStatus` is `"incomplete"` while an open hunk still owes rows, `"malformed"` once the document is finalized with rows still owed or a new hunk or file starts before the previous hunk's rows arrive, and `"complete"` otherwise. Token exactness is reported separately and is unaffected. Ordinary code carries no diff status.
|
|
9
|
+
|
|
10
|
+
Native root and nested code blocks report the same `diffStatus` through `CodeNodeHandle.readMetadata()` and the React store's code metadata. One pure owner (`abandonsOwedRows`/`codeDiffStatus`) computes it for standalone, root and nested code.
|
|
11
|
+
|
|
12
|
+
Migration: `CodeLineDecoration` and `HighlightResult` can report `{ exactness: "unavailable", tokens: null, reason }`, for example when lazy tokenization reaches an unbased diff hunk without the prefix context needed to reconstruct diff-side state. Narrow on `exactness` before reading `tokens`. The default React renderer shows unavailable rows as unhighlighted authored source text while preserving diff markers.
|
|
13
|
+
|
|
14
|
+
- 45b29fb: Native list and blockquote streaming preserves current nested children in open dumps and Core cold exports. Nested code, table, and paragraph leaves update through existing owner patch families and generic child operations; authored ranges remain physical UTF-16 coordinates in the canonical input document.
|
|
15
|
+
|
|
16
|
+
Primary list paragraphs use native paragraph deltas while cold exports preserve the existing item representation. Empty tasks retain their authored markers without rendering duplicate marker text, including after finalization.
|
|
17
|
+
|
|
18
|
+
Keep provisional inline HTML and allowlisted MDX repair separate from authored source. Rejected HTML stays literal even inside formatted inline content; unclosed previews become literal at finalization without consuming later paragraphs.
|
|
19
|
+
|
|
20
|
+
Preserve the canonical nested hierarchy during late link and footnote resolution. Publish targeted meaning updates with stable authored ranges and historical values, including generic heading metadata and links. Footnote numbering and occurrence anchors follow document reference order across nested paragraphs and table cells.
|
|
21
|
+
|
|
22
|
+
Preserve table headers and alignments when CRLF arrives one UTF-16 unit at a time. Parse lone CR as a line ending without changing physical source offsets, invalidate affected incremental fragments when LF follows, and advance retired root paragraph generations across source-kind changes.
|
|
23
|
+
|
|
24
|
+
Carry canonical generic ranges and metadata through existing property patches. Core and React apply metadata replacement, omission and explicit clearing consistently, without resurrecting stale block metadata or mutating historical exports. Preserve a list item's canonical source extent when retained marker context is shorter than its managed primary paragraph.
|
|
25
|
+
|
|
26
|
+
Preserve completed paragraph leases when retained native marker context omits their body. Publish current HTML source ranges alongside sanitized content, and keep type-1 HTML, comments and processing instructions outside type-6/7 continuation recovery.
|
|
27
|
+
|
|
28
|
+
Remove invalidated suffix reference definitions as titles arrive, and retire paragraph ownership when a footnote definition becomes complete. Native list child identity carries its canonical ordinal so ordered markers remain correct across bounded windows.
|
|
29
|
+
|
|
30
|
+
Native code rows remain in their owned code index rather than a duplicate generic child tree. Native line ranges subscribe only to changed aligned ranges, including late decoration and provisional boundary completion.
|
|
31
|
+
|
|
32
|
+
Keep completed list-item DOM mounted when list looseness changes; inherited presentation updates through the parent layout context. Current ancestor ordering epochs remain observable without restamping unchanged descendants, while stale updates are still rejected.
|
|
33
|
+
|
|
34
|
+
Reuse typed container markers and list looseness in bounded native windows without reading completed item gaps. Preserve quote markers inside the changing paragraph and refresh marker-only opening lines before deriving their retained context.
|
|
35
|
+
|
|
36
|
+
Explicit renderer resets and worker replacement start a fresh document baseline. Keep retired owner generations within that baseline, and invalidate native code-range demand and source actions across resets even when worker-local IDs and generations repeat. Ordinary appends retain their bounded range subscriptions.
|
|
37
|
+
|
|
38
|
+
Normalize CRLF and lone CR for explicit cold container parsing and native fallback semantic extraction from canonical source. Retain untouched authored source, legitimate spaces, and physical UTF-16 child ranges, including nonzero source origins and astral characters.
|
|
39
|
+
|
|
40
|
+
Apply sparse paragraph meaning updates only to affected index branches, preserving earlier snapshots and unchanged authored source. Plaintext projection accepts read-only prepared inline nodes without copying them.
|
|
41
|
+
|
|
42
|
+
Keep MDX components finalized over their complete authored source. Retire absorbed paragraph and container leases before emitting further native updates, preserving unrelated batched changes.
|
|
43
|
+
|
|
44
|
+
Honor configured lazy tokenization for native nested code. Advance grammar state through skipped source without coloring unrequested rows, and retain requested tokens through append, finalize and cold JSON reset.
|
|
45
|
+
|
|
46
|
+
Do not republish a canonical root snapshot containing an already-published live nested code lease after its semantic owner updates. Preserve native lifetime guards and the unmanaged replacement path.
|
|
47
|
+
|
|
48
|
+
Retire the `appendLines` wire operation, generic code-line producers and reducers, and obsolete coalescing telemetry. Native source and decoration changes use their typed code owner. Static version-1 cold artifacts remain unchanged.
|
|
49
|
+
|
|
50
|
+
- 4b66f9c: Replace the legacy `components` component map with `components?: NodePresentations`. Each semantic key maps to an entry containing constrained `props` and optionally either `wrapper: React.ComponentType<NodeViewProps>` or a headless `view: React.ComponentType<HeadlessNodeViewProps<K>>` (never both); `slots.actions` is supported for code and table presentations. Migrate `components={{ table: TableView }}` to `components={{ table: { wrapper: TableView } }}`, or register a headless code view as `components={{ code: { view: CodeView } }}`. New public types include `NativeNodeKey`, `NodePresentationKey`, `NodePresentation`, `NodePresentations`, `NodeViewProps`, `HeadlessNodeViewProps`, `NodeHandle`, `NodeHandleMetadata`, `NodeChildRange`, `NodeViewMetadata`, `NodeViewActions`, `PresentationProps`, and `NativeActionSlot`.
|
|
51
|
+
- 4ba8928: Retire `engine="main-thread"` in favor of `engine="main"` and reject the removed value with an actionable runtime migration error.
|
|
52
|
+
- 28f8a1e: Remove `blockRenderer` and the `BlockComponents` registry. Use `components: NodePresentations` for native block wrappers and views, including unified rendering.
|
|
53
|
+
- 71f76b2: Remove the legacy `CodeNodeViewProps` export; use `HeadlessNodeViewProps<"code">` instead.
|
|
54
|
+
- e6fff1e: Remove the fragmented renderer override props in favor of `components: NodePresentations`:
|
|
55
|
+
|
|
56
|
+
- `inlineComponents` → `components["inline:<kind>"]` (for example `inline:link`, `inline:strong`).
|
|
57
|
+
- `htmlElements` → `components["html:<tag>"]`, applied after HTML admission and sanitization.
|
|
58
|
+
- `tableElements` → `components.table` and the table part keys.
|
|
59
|
+
- `codeRenderers` → `components.code`; route by `metadata.language` and return the prepared `children` for other languages.
|
|
60
|
+
- `mathRenderer` → `components["inline:math"]` / `components.math` for presentation.
|
|
61
|
+
- `mdxComponents` → `contentComponents` for restricted source components, and the explicit trusted MDX engine provider for trusted MDX.
|
|
62
|
+
|
|
63
|
+
`ComponentRegistry` now takes a single options object.
|
|
64
|
+
|
|
65
|
+
- 4173aec: `syntax` is now a versioned `SyntaxExtensionDescriptor` with `inline` rules and registered colon `containers` that share restricted-component admission.
|
|
66
|
+
- de107fe: Replace per-block MDX compilation and status messages with native source blocks and an explicit whole-document trusted lane. Restricted source components must be registered through `defineContentComponent`; only serializable descriptors cross the worker boundary, while validators, components, and native children remain host-side. Remove the retired MDX compile-mode and hydration props and default artifact execution. Full MDX now requires `createTrustedMdxEngine`, an explicit host import map, trusted content, and CSP permission for `unsafe-eval`. Worker `FINALIZED` reports native semantic completion, not trusted preparation or render readiness.
|
|
67
|
+
|
|
68
|
+
Preserve literal quoted attribute text, including trailing backslashes, while retaining strict-JSON escape semantics and native HTML entity decoding. Freeze admitted JSON recursively after worker transport and freeze the host React props envelope in production. Generate client and server declarations with one output owner so the explicit trusted server entry remains importable.
|
|
69
|
+
|
|
70
|
+
Keep trusted flow and fragment children on their native heading, paragraph, code and table owners. Classify module declarations by exact compiler source ranges so successful imports/exports do not leak into Markdown output. Preserve strict native child ownership and independent document leases; source-span parsing remains outside the trusted compiler/evaluator graph.
|
|
71
|
+
|
|
72
|
+
Admit nested restricted components through native paragraphs, headings, quotes, lists and sanitized HTML. Preserve emphasis and links around component leaves; keep code, destinations, titles, image alt text, comments and HTML attributes inert. Use opaque native leaves rather than decoded text markers, and remove private marker data before retaining inline metadata.
|
|
73
|
+
|
|
74
|
+
Separate validated registered opening headers from the following native Markdown body, including multiline headers whose closing delimiter resembles a blockquote marker. Preserve same-line suffixes and native child source ranges without changing ordinary CommonMark HTML, protected code/comments or invalid-header admission.
|
|
75
|
+
|
|
76
|
+
Keep list formatting, configured HTML attributes, parent-sensitive element filters and disabled autolinks intact around registered components. Number only the active prepared ownership tree, including props-owned list segments, so finalized footnote occurrences and their backlinks agree. Carry the producer's existing block epoch in initialization metadata so valid updates to later roots are not rejected as stale.
|
|
77
|
+
|
|
78
|
+
Associate nested whole-flow JSX with its explicit trusted inline owner when the native paragraph and compiler region cover the same authored span. Preserve native wrapper children without duplicate rendering or invalid paragraph wrappers. Bundle the source-span parser's ESM-only dependencies in the advertised CommonJS compiler entry instead of passing module namespaces to unified as plugins.
|
|
79
|
+
|
|
80
|
+
Match the compiler's standalone JSX/expression paragraph promotion in parse-only ownership scans. Distinguish native inline children from Markdown block children in `TrustedMdxFlowChildSpan`, preserve their exact whitespace and rich inline preparation, and render them without synthetic paragraph wrappers. Exact JSX frames own their descendant regions rather than treating those regions as additional roots. Advance the trusted compiler identity to `native-flow-children-v5` so earlier child metadata is not reused.
|
|
81
|
+
|
|
82
|
+
Preserve one canonical prepared ownership tree, including empty trees. When document-wide footnote definitions split compiler inline spans differently from a local native parse, render an exact contiguous run through its single prepared native paragraph and typed continuation slots. Keep strict range/duplicate checks, native reference numbering and backlinks, without per-token owners or whole-document Worker reparsing.
|
|
83
|
+
|
|
84
|
+
Trusted replacements retain a detached native store captured once after a successful complete-module host commit. During a pending or failed replacement it remains labelled with its original source generation and document revision, keeps commit-time decorations, and sends no code jobs to the replacement worker. Reset, engine/cache invalidation or disposal, lease or policy changes, or a later successful commit release it. A retained React render error shows the captured source but does not roll back arbitrary trusted host effects.
|
|
85
|
+
|
|
86
|
+
Under the explicit `trusted-mdx` content policy, seal APPEND admission at the FINALIZE request while draining input already accepted before the barrier; reject later host or worker appends without source or native-frame mutation until reset or replacement. The `markdown` and `restricted` policies retain their existing append-after-FINALIZE behavior. After restart, automatically owned workers accept imperative APPEND and FINALIZE requests into the fresh-generation FIFO before readiness; after INIT has been posted to the matching fresh worker, they replay in order. A later restart discards requests pending for the earlier generation, and a queued trusted FINALIZE seals admission against later queued appends.
|
|
87
|
+
|
|
88
|
+
Prepare packages before rebuilding the hosted worker for doc snapshots and screenshots, so package cleanup cannot remove the selected worker before compilation.
|
|
89
|
+
|
|
90
|
+
Prepare canonical trusted children after native owner grouping and before the single ordered document-plugin pass. Preserve exact direct-child source boundaries and reuse completed trees across later footnote definitions, with numbered links, backlinks and reset isolation. Update the MDX transition regression baseline to its native paragraph, list, table and quote views instead of retired per-block compiler wrappers.
|
|
91
|
+
|
|
92
|
+
Treat a nested MDX block and its own generated inline owner as one claim only when both match the exact compiler-authored region. Preserve repeated identical JSX siblings by source identity; unrelated duplicate and crossing owners still fail closed.
|
|
93
|
+
|
|
94
|
+
Keep the default code-view frame as a `<div>` around the original highlighted `<pre>`, preserving Shiki themes and code metadata without nested `<pre>` markup. Keep the Preview/code seam on the native outer code frame, with preserved inner padding and no duplicated inset border. Reject complete trusted-MDX HTML baseline updates that still contain render diagnostics.
|
|
95
|
+
|
|
96
|
+
Honor an explicit `mdx: false` feature setting for restricted registered JSX descriptors at root and nested native container boundaries, without changing ordinary HTML policy.
|
|
97
|
+
|
|
98
|
+
When an APPEND ends inside a tag name, attribute, or closing token, keep that fragment out of HTML ownership balancing until a complete token arrives. Treat backslashes inside quoted HTML attributes as literal characters, not quote escapes. Preserve canonical native paragraph, list, table, and quote owners inside completed trusted-MDX flow roots without duplicate ownership.
|
|
99
|
+
|
|
100
|
+
- 159a237: Use source-owned records for root code fences, tables, and paragraphs, with bounded line, row, and span updates and on-demand full-source reads. Patch consumers must accept wire protocol 2.0, replace `appendLines` with `appendCode`, adopt `appendParagraph` and `updateParagraphSpans`, and handle native table operations; the retired operation has no compatibility alias. Plugins must use the source snapshot and on-demand `readBlocks` document context instead of a retained `blocks` array.
|
|
101
|
+
|
|
102
|
+
Live consumers now initialize one canonical root input document from the
|
|
103
|
+
`INITIALIZED` snapshot baseline and retain later admitted bytes with ordered
|
|
104
|
+
semantic `appendInputSource` root patches. Missing live baselines are
|
|
105
|
+
incompatible; cold `Block[]` and standalone snapshots keep only their honest
|
|
106
|
+
per-block source slices. Native code, table, and paragraph windows share the
|
|
107
|
+
consumer input document while retaining independent owner generations and
|
|
108
|
+
exact newly owned `sourceAppend` suffixes. Empty baselines are valid, and static
|
|
109
|
+
artifact version 1 is unchanged.
|
|
110
|
+
|
|
111
|
+
Preserve owner identity and retirement guards when replacing active snapshots. Reject regressing revisions and source frontiers, while allowing valid source-stable table and paragraph dependency meaning updates after finalization. Same-generation finalized source cannot grow or reopen. Keep final code highlighting and fallback presentation intact without retransmitting source in presentation-only patches.
|
|
112
|
+
|
|
113
|
+
For paragraph owners after raw Markdown EOF, reopen only the actual trailing paragraph under a fresh owner generation. Do not fuse intervening definition or root source into an earlier paragraph. Keep genuinely unowned provisional following roots eligible for continuation.
|
|
114
|
+
|
|
115
|
+
Do not re-finalize completed paragraph owners when later roots extend the shared input. Preserve their original parser frontier and captured source while still publishing valid late dependency changes.
|
|
116
|
+
|
|
117
|
+
Queue imperative append and finalize calls behind their matching initialization acknowledgement. Ignore errors from detached or superseded initializations without changing public worker attachment readiness, and keep detached snapshot callbacks callable.
|
|
118
|
+
|
|
119
|
+
Render managed paragraph children through the native span view while preserving registered source props and finalized block overrides. Default appends avoid global block/MDX scans; legacy full-source custom props use an explicit cold projection. Cold Block exports also retain admitted open native tables.
|
|
120
|
+
|
|
121
|
+
Blocks whose rendering depends on HTML stay on the base HTML grouping path. Genuine inline-HTML paragraphs and HTML-bearing containers retire native owners instead of adopting or rehoming them; tail-local auto-close and native ownership for non-HTML blocks remain.
|
|
122
|
+
|
|
123
|
+
- Release the coordinated 1.0.0 package line. Upgrade all installed StreamMDX packages together and recopy the hosted worker from the matching version. Internal runtime dependencies remain exact versions; the optional unified adapter's StreamMDX peers require the 1.x line.
|
|
124
|
+
|
|
125
|
+
Migration from 0.5.0:
|
|
126
|
+
|
|
127
|
+
- Remove imports of `@stream-mdx/plugins/registry`, `/base`, and `/math`, their `stream-mdx/plugins/*` convenience re-exports, and `@stream-mdx/worker/streaming/custom-matcher`. `PluginRegistry`, `globalPluginRegistry`, legacy match handlers, and legacy math plugin factories are no longer public. Use native Lezer extensions, serializable `SyntaxRuleSpec` rules, and per-engine `DocumentPluginRegistry` document plugins. Native extension functions belong in the engine or custom worker bundle, not in structured-clone `INIT` messages.
|
|
128
|
+
- `MarkdownEngine` owns its parser, queue, document state, plugins, and caches. Construct it with `{ post, extensions? }`, send configuration and document resets through `handle({ type: "INIT", ... })`, and call terminal `dispose()` when finished. Use public `serveMarkdownWorker` and `createInlineEngineWorker` factories instead of old global runtime plumbing. Worker URLs and actual Worker factories create renderer-owned workers that terminate on detach; an existing Worker is caller-owned. Caller-created inline adapters also need caller-owned termination. See `docs/PUBLIC_API.md` and `docs/PLUGIN_ABI.md` for supported wiring.
|
|
129
|
+
`managedWorker={true}` requires a supplied Worker instance or caller-accessible factory and caller-owned initialization/document commands. URL/default workers and `engine="main-thread"` are rejected, even with a supplied worker source. Managed auto cannot silently fall back inline. Borrowed instances remain caller-owned; factory-created workers remain component-owned and terminate on detach.
|
|
130
|
+
- Provisional lookahead inputs over 512 characters now return raw text before completeness scanning, including closed strings. Oversized finalized/nonprovisional complete content is preserved; within-budget finalized projection retains its behavior. Internal defaults are `maxScanChars: 512`, `maxNewlines: 2`, `maxSyntheticOps: 6`, `maxNestingDepth: 8`, `maxValidationFailures: 1`, and `maxProviderMs: 5`. Provider timers start before scanning; these caps are not React props or latency guarantees.
|
|
131
|
+
- Core root exports no longer expose Lezer converter, math extension factory, link-label normalization, entity decoder, or default/regex plugin adapter internals. Use retained parser/preparation APIs and public worker/compiler entries. Owning parser settings remain authoritative, including disabled math in nested snapshot fallbacks.
|
|
132
|
+
- `ComponentRegistry` treats a block component as custom only when it differs from the built-in default. Custom paragraph and quote wrappers must render the supplied `children` projection to retain native inline, HTML, and nested-block ownership. Do not reconstruct those children from raw source.
|
|
133
|
+
- `CodeFenceRendererProps.renderCode` is a React node, not a callback. Return it directly as a fallback. `language`, fence metadata, and emitted `language-*` classes preserve the authored info word, such as `js`, rather than the canonical Shiki grammar name. Renderer lookups still fall back to canonical names and accept aliases. Unlabeled and indented code has no language class or `data-language` attribute.
|
|
134
|
+
- `restart()` cancels the current async iterator generation; it does not replay a consumed iterator. Supply a fresh iterator for a new stream. Renderer-owned text replacements reset the engine document, while caller-initialized managed workers retain their document ownership.
|
|
135
|
+
- URL transformation and HTML/style sanitization now apply across native client rendering, SSR, and the optional unified adapter. Rejected URLs are omitted; custom components must honor the supplied sanitized attributes and children. `allowedElements` and `disallowedElements` are mutually exclusive.
|
|
136
|
+
|
|
137
|
+
- **P9 Security & Architecture Cutover (Strict Restricted Components & Trusted MDX Lane)**:
|
|
138
|
+
- The default reachable React package graph removes compiler/evaluator imports, dynamic imports, and root re-exports (`mdx-client`, `mdx-coordinator`, `mdx-prefetch`, `mdx-runtime`). The main root keeps pure Trusted-MDX contract types; the implementation is available only from `@stream-mdx/react/trusted-mdx`.
|
|
139
|
+
- Removed per-block MDX compilation/evaluation machinery and obsolete props `mdxComponents`, `mdxCompileMode`, `mdxHydration`, and `artifactHtml`.
|
|
140
|
+
- Introduced `contentPolicy` (`"markdown" | "restricted" | "trusted-mdx"`, default `"restricted"`) and `contentComponents` host registrations with strict prop validation.
|
|
141
|
+
- Only serializable descriptors (`name`, `renderWhen`) cross the Web Worker boundary in `WorkerIn` `INIT`; host callbacks (`validateProps`, `component`) remain on the main thread.
|
|
142
|
+
- Full MDX authoring requires caller-supplied `engines.mdx` from an explicitly configured trusted engine.
|
|
143
|
+
- Removed automatic artifact-fence execution and the `ArtifactFrame` default renderer; `artifact` and `html-artifact` fences stay inert code unless the host explicitly supplies a code renderer.
|
|
144
|
+
The remaining consumed changesets describe the new opt-in renderers, controls, animation, table virtualization, themes, native extension APIs, and correctness/security fixes. These features do not enable themselves when upgrading. See the root README migration section and the generated package changelogs before upgrading custom integrations.
|
|
145
|
+
|
|
146
|
+
### Minor Changes
|
|
147
|
+
|
|
148
|
+
- 79560b9: Add `mathOptions={{ macroScope: "document" }}`, an explicit KaTeX macro scope owned by one document generation. Complete expressions apply `\gdef` definitions in document order, provisional expressions commit nothing, and replacing or restarting the document clears the scope. Expressions stay isolated by default. KaTeX now always renders with `trust: false`, `maxExpand: 1000` and non-throwing error output.
|
|
149
|
+
- 049f2e5: Add the `engines.math` capability for synchronous custom TeX rendering while keeping KaTeX as the default. Math presentations remain view-only wrappers around the selected engine output.
|
|
150
|
+
- 67b9728: Add a bounded viewport for large native code blocks with an opt-in full-content reader mode. `codeVirtualization` configures native code viewport presentation, including optional tail following; updates preserve the existing viewport and reader anchor. Eligible virtualized code blocks mount full source before printing and restore the previous viewport, anchor, and native selection afterward.
|
|
151
|
+
|
|
152
|
+
Native whole-code copy and download use cold authored source, preserving CR/LF and trailing blank lines instead of normalized display text. The test DOM exercises copy with an active selection and a Clipboard API stub; it does not prove physical browser or OS clipboard behavior. Direct Blob download browser proof remains pending. Copied-status feedback cleanup prevents delayed updates after unmount.
|
|
153
|
+
|
|
154
|
+
- 3101916: Export `NativeNodeView` from `@stream-mdx/react/server` so headless views rendered by the server `MarkdownBlocksRenderer` can fall back to native output. `table-row`, `table-cell` and `component:<Name>` presentations accept only `wrapper` and `props`, both in the types and at `ComponentRegistry` construction; customize tables headlessly through `components.table.view` with `useTableBlock` and `useTableRows`.
|
|
155
|
+
- 31c997f: Add the native root theme policy, isolate native output styles and custom properties, and map Shiki light/dark foreground, background, font-style, font-weight, and text-decoration tokens to the selected color scheme.
|
|
156
|
+
- afcce56: Render up to 4,096 accepted UTF-16 source units through the existing inline engine during `auto` startup, without waiting for worker or grammar readiness; defer further source beyond the bootstrap budget.
|
|
157
|
+
- 736c767: Export `EngineCompatibilityError` for automatic takeover failures when workers are unavailable.
|
|
158
|
+
- 61aa9d1: Take over the 4,096-unit auto bootstrap with a cold worker reconstruction, preserving the visible projection and accepted source order until the worker commits the matching source frontier.
|
|
159
|
+
- 1d6026c: Add an optional coarse-grained polite status region and preserve exact authored code selection and download bytes.
|
|
160
|
+
- fceb3e5: Expose code-engine adapters across the main and custom worker realms, preserve worker adapter tokens in emitted code-line output, and document their compatibility requirements.
|
|
161
|
+
- 925ca3e: Expose finalized state in inline and HTML node presentation metadata.
|
|
162
|
+
- 49efd0e: Add inline and allowed-HTML node presentation wrappers and headless views through the `components` registry. Preserve safe URL transformation, attribute normalization, sanitization, and element filtering before presentation dispatch.
|
|
163
|
+
- aca45df: Allow `components["inline:math"]` wrappers and headless views to present inline and display math while retaining the existing math engine output as prepared children.
|
|
164
|
+
- 59622ba: Add `components: NodePresentations` to static/server and unified rendering, using the same native-node wrapper/view dispatch as streaming. Unified's HAST element mapping moves to `hastComponents`.
|
|
165
|
+
- 7f65556: Add an inert preview slot and generation-bound node revision feeds for explicitly installed host runtimes.
|
|
166
|
+
- 3fca012: Add owner-local table handles and bounded React hooks for stable table metadata and ranged body-row subscriptions.
|
|
167
|
+
- bc8bb58: Export `useNode`, `useNodeChildren`, and `NativeNodeView`. Node hooks read generation-bound metadata and explicit half-open child ranges; native fallback bypasses the current presentation entry so headless views can render prepared native children without recursion.
|
|
168
|
+
- bbfb021: Export `useCodeDiff` for observing diff status and prepared code rows within an explicit half-open range. The hook reuses code-line records and avoids rerendering when metadata changes without changing the selected diff status or rows.
|
|
169
|
+
- 072e0f1: Expose generation-bound source reading and resolved link-reference metadata to node presentations, and report unified failures with block ID, type, and finalized state.
|
|
170
|
+
|
|
171
|
+
- 1669abb: Code fences keep the authored info word as their language. ` ```js ` now renders `language-js` / `data-language="js"` (CommonMark), and `meta.lang`, `CodeFenceRendererProps.language` and `parseCodeFenceInfo().lang` report `"js"` instead of the alias target `"javascript"`. Aliases (`js`, `ts`, `py`, `sh`, ...) still select the same Shiki grammar through `normalizeLang`, so highlighting is unchanged. `codeRenderers` lookups fall back to the canonical name, so a renderer registered as `javascript` still receives ` ```js ` fences.
|
|
172
|
+
- 0e96940: Make code themes configurable end-to-end:
|
|
173
|
+
- Core: add optional `{ light, dark }` theme pair to the WorkerIn INIT protocol and code highlighting configuration, with default code wrapper attribute support for configured themes.
|
|
174
|
+
- Worker: validate themes against Shiki bundledThemes, load themes on demand into the shared singleton highlighter, isolate caches by theme to prevent cross-contamination, use configured themes across all highlight strategies (static, incremental, lazy, diff), and report unknown themes via the INIT error pipeline while falling back to default themes. Direct compilation accepts themes in init options.
|
|
175
|
+
- React: expose `themes` on StreamingMarkdown and RendererConfig, forwarding themes to the INIT message, re-initializing the engine when themes change, and applying theme classes in the client store and code view wrappers.
|
|
176
|
+
- 4ed0ed3: Add element filtering, code renderer aliases, and autolink protocol disabling:
|
|
177
|
+
- `allowedElements` and `disallowedElements` to filter HTML tag names at render time across markdown and raw HTML (mutually exclusive; supplying both throws).
|
|
178
|
+
- `allowElement` callback predicate `(element, context) => boolean` receiving `{ tagName, properties, blockType? }` and `{ source: "markdown" | "html", parentTagName? }`.
|
|
179
|
+
- `unwrapDisallowed` boolean to unwrap and render children of disallowed elements in place instead of dropping the subtree.
|
|
180
|
+
- Unified element decision function in `ComponentRegistry` applied across client node views, SSR, and raw HTML rendering.
|
|
181
|
+
- `codeRenderers` entries accept `aliases?: string[]` (`{ component, aliases: ["js", "mjs"] }`); languages and aliases resolve case-insensitively.
|
|
182
|
+
- `disableAutolinkProtocols` to render autolink literals and angle autolinks with specific protocols (e.g. `["mailto"]`) as plain text while preserving explicit markdown links.
|
|
183
|
+
- 7879ed5: Add isolated MarkdownEngine instances, the public worker/engine entry, custom bundled worker serving, and a main-thread Worker adapter. React supports explicit worker, main-thread, and auto execution modes with a dynamically imported creation-time fallback. Updating onError no longer restarts streamed content.
|
|
184
|
+
|
|
185
|
+
Add serializable inline syntax rules with capture attributes, recursively parsed content, lookahead, streaming anticipation, and invalid-INIT recovery. Native worker entries accept Lezer markdown/inline extensions and instance document plugins. HTML supports per-tag attribute lists, mapped components, and opt-in markdown children while retaining literal raw-block defaults and respecting disabled math. Preserve whitespace beyond the required four columns on internal indented-code blank lines, including nested containers. Include invisible reference definitions when determining loose lists. Recognize bare FTP links with native GFM URL punctuation and parenthesis handling.
|
|
186
|
+
|
|
187
|
+
Add code fence renderer registration, React-node code fallbacks, math renderer overrides, structured diff views, and sandboxed HTML artifacts with CSP and host link routing. Mermaid accepts the code fence renderer contract and confines invalid-diagram output to its block.
|
|
188
|
+
|
|
189
|
+
Add the optional unified adapter for finalized-block remark/rehype transforms, explicit block routing, container replacement, synchronous SSR, asynchronous native fallback, error callbacks, and bounded per-renderer caches. Restore finalized heading levels from engine metadata before running remark and rehype plugins, preserving multiline Setext content and soft breaks. Cover compiler output and real inline-transport updates through the store-backed DOM renderer, including provisional rendering and terminal finalization. Document public exports and replace obsolete plugin factory examples.
|
|
190
|
+
|
|
191
|
+
React's minor version change covers public props (engine, codeRenderers, mathRenderer, blockRenderer) and renderer extension modes. Table virtualization is recorded separately in measured-table-rows, and nested block snapshot fixes are recorded in prepared-nested-blocks.
|
|
192
|
+
|
|
193
|
+
- 38273db: Add opt-in virtualization for large finalized tables in inactive streaming sessions. Preserve natural column widths with measured columns and a full-table sizing pass on viewport resize. Mounted rows use ResizeObserver measurements, stable row IDs, opaque sticky headers, and bounded overscan. Existing overflow-wrapped Table adapters use one managed scroll viewport with scoped style cleanup. Server rendering and active async/imperative sessions retain every row. Updating or removing the tableVirtualization prop updates the mounted view.
|
|
194
|
+
|
|
195
|
+
Finalize async iterator tails on normal EOF and track iterator ownership independently of stream prop presence. Refresh table observers and measurements when adapters change or virtualization is re-enabled; ignore detached generation callbacks.
|
|
196
|
+
|
|
197
|
+
Reset renderer-owned engine documents on text or iterator replacement using the existing initialization protocol and options. Caller-initialized managed workers keep their engine document when the renderer restarts.
|
|
198
|
+
|
|
199
|
+
Claim actual async iterator identities once per mounted component, including across restart and renderer/readiness changes. Restart cancels the current generation rather than re-entering a single-use iterator; fresh iterators remain supported. Removing an open stream releases only its iterator-owned activity and preserves independent imperative activity.
|
|
200
|
+
|
|
201
|
+
Initialize owned static text with the complete document rather than repeatedly parsing growing append chunks. Share all existing initialization options, match FIFO acknowledgements, reject pending static renders on worker detach, and leave incremental streams and caller-managed workers unchanged.
|
|
202
|
+
|
|
203
|
+
Preserve pending initialization acknowledgement ownership when a borrowed worker outlives its renderer. Detached calls reject without allowing late responses to resolve or repopulate a new attachment.
|
|
204
|
+
|
|
205
|
+
Disable showcase table navigation while its source is pending or its virtualized viewport is not ready, so an early click cannot silently target a missing or transient full-table view.
|
|
206
|
+
|
|
207
|
+
- 032136c: Add `animated` prop to `StreamingMarkdown` and `MarkdownBlocksRenderer` (+ ComponentRegistry) for opt-in streaming text animation.
|
|
208
|
+
- Applies only while blocks are streaming (non-finalized); finalized blocks and static or SSR renders output plain un-animated text.
|
|
209
|
+
- Inline text segments render as stable keyed `<span>` elements (keyed by segment index) preserving DOM node identity across streaming updates.
|
|
210
|
+
- Spans receive class `stream-mdx-anim` and CSS variables `--sm-anim-duration`, `--sm-anim-easing`, and `--sm-anim-delay`.
|
|
211
|
+
- Per-flush delay staggering tracked per renderer and capped by `maxBacklogMs`.
|
|
212
|
+
- Export `STREAM_MDX_ANIMATION_CSS` keyframes with `@media (prefers-reduced-motion: reduce)` support.
|
|
213
|
+
- e2c13e5: Add `controls` prop to `StreamingMarkdown` and `MarkdownBlocksRenderer` (+ RendererConfig/registry) for code block, table, and Mermaid diagram copy and download actions.
|
|
214
|
+
- Code blocks: copy raw authored code text (not highlighted HTML), download snippet with language-derived extension. Works for virtualized code.
|
|
215
|
+
- Tables: copy as TSV or Markdown, download CSV, TSV, or Markdown built from finalized cell text with strict RFC 4180 escaping (quotes, commas, newlines). Disabled during streaming; enabled upon table finalization.
|
|
216
|
+
- Mermaid & code-fence renderers: expose controls flags and `copy()` helper via `CodeFenceRendererProps`; `MermaidBlock` opts in to diagram source copying in its toolbar and code view.
|
|
217
|
+
- Buttons: real `<button type="button">` with `aria-label`, `data-stream-mdx-control`, and styling classnames. SSR-safe with no window access during render.
|
|
218
|
+
- Customization: support full replacement slot via `controlsComponent` prop / registry, and i18n label overrides via `controls.labels`.
|
|
219
|
+
|
|
220
|
+
### Patch Changes
|
|
221
|
+
|
|
222
|
+
- 721313b: Reject patches that would make a node its own ancestor, and record an invariant diagnostic instead of looping.
|
|
223
|
+
- e4c905f: Finish background tokenization of finalized lazy code blocks shown in the bounded code viewport. Visible rows are still served first, and `lazyTokenizedUntil` now reaches the full line count.
|
|
224
|
+
- 521be6f: Count code decorations computed for a superseded owner generation as stale work instead of invariant violations. They are still dropped. Decorations for an unknown owner or a newer generation are still diagnosed.
|
|
225
|
+
- a9052cb: Honor reduced-motion preferences for bottom jumps and let wheel, touch, and scroll-key input interrupt smooth returns.
|
|
226
|
+
- 3f24715: Bound host-accepted and in-flight source with generation-tagged worker admission acknowledgements. Imperative append accepts a whole UTF-16 chunk or refuses it without partial admission; automatic iterators losslessly split larger chunks and wait for capacity.
|
|
227
|
+
|
|
228
|
+
Finalization seals the host generation immediately and resolves one shared promise after all earlier accepted source reaches the matching native finalization and semantic store barrier. Reset invalidates pending capacity/finalization waits, including automatic source replacement on a reused renderer. The barrier does not imply a React commit or optional enrichment readiness.
|
|
229
|
+
|
|
230
|
+
Cache inline regex eligibility per immutable parser context, rather than rescanning the whole context at each token position. A later marker-bearing context still performs its own check, and weak keys do not retain completed contexts.
|
|
231
|
+
|
|
232
|
+
Demo automation now observes synchronous source and completion state immediately after fast-forward or finalization, and restart opens a fresh wrapper session before replacing its worker.
|
|
233
|
+
|
|
234
|
+
- e7b4a0c: Reject reads from a code-node handle after its owning code document is replaced or removed; retained immutable range snapshots remain valid independently.
|
|
235
|
+
- ccfd10b: Preserve authored line endings when copying selections that end at rendered code separators.
|
|
236
|
+
- 7cd811e: Preserve incomplete code-line provisional state in cold exports only while the block is still open.
|
|
237
|
+
- 831a29d: Preserve authored Markdown source when copying or downloading cold table views.
|
|
238
|
+
- a0a3bd2: Restore all rows and unclipped viewport styles while printing cold table views.
|
|
239
|
+
- 78753b7: Preserve authored leading plus characters when projecting diff line tokens into presentation metadata.
|
|
240
|
+
- e2303e9: Render default KaTeX math from inert authored source during SSR and the initial client render, then prepare KaTeX after commit. Keep prepared output and errors tied to the TeX and display mode that produced them.
|
|
241
|
+
- 072e0f1: Add an optional Mermaid engine capability that routes Mermaid fences through the native code owner while Markdown parsing remains in the selected worker or main-thread engine.
|
|
242
|
+
- 7767c9e: Apply constrained node presentation props to the native element across block render paths, including headings.
|
|
243
|
+
- 68b4b27: Apply presentation props to registered restricted components and reject unsupported headless component views.
|
|
244
|
+
- 4a8509d: Unescape `\|` in table cells on every table path, including streamed root and nested tables.
|
|
245
|
+
|
|
246
|
+
Stream the body rows of a table nested in a quote or list item from the container's own parse, and seal an unterminated last row at finalize instead of dropping it. A container window keeps the separating lines before a nested table's context lines.
|
|
247
|
+
|
|
248
|
+
A container replacement in the renderer store keeps the table and paragraph owners it carries forward, so a quote holding a table and a following block no longer loses its content when it finalizes.
|
|
249
|
+
|
|
250
|
+
Retract a provisional empty list item once its line completes as a thematic break.
|
|
251
|
+
|
|
252
|
+
- 7c47cf1: Reject an automatic takeover append before accepting its source when worker creation fails.
|
|
253
|
+
- 355c068: Start automatic worker takeover when code highlighting is requested so short code blocks receive worker decorations on finalization.
|
|
254
|
+
- fd6f456: Render complete static input in auto mode and report its full accepted-source frontier.
|
|
255
|
+
- 1e18f9e: Schedule presentation work through animation frames by default and limit semantic commits to cooperative 4 ms slices before lower-priority enrichment.
|
|
256
|
+
- 7f00a2c: Settle waiting source-capacity requests when automatic bootstrap takeover initialization admits the existing source frontier.
|
|
257
|
+
- c1666b8: Bind automatic bootstrap takeover failures to their initiating request so an obsolete worker lease cannot fail a replacement source session.
|
|
258
|
+
- df89989: Prioritize visible and rendered overscan code ranges ahead of full-block background tokenization.
|
|
259
|
+
- 8a081d5: Skip block presentations when element filters drop or unwrap their native host element.
|
|
260
|
+
- 2e71146: Avoid emitting managed table shells and controls when element filtering removes the table.
|
|
261
|
+
- 1a85e7a: Allow code and table headless views to select the matching native node projection with `NativeNodeView`.
|
|
262
|
+
- f394b1e: Dispatch table-row and table-cell presentations across managed, static, and virtualized table rendering.
|
|
263
|
+
- 1e8f261: Bind node metadata subscriptions to the captured record and generation, rejecting stale registration and suppressing notifications after replacement.
|
|
264
|
+
- 127dd84: Reject saved table-wrapper actions after their table owner is replaced or reset.
|
|
265
|
+
- 9d1ef66: Apply registered component presentations to validated restricted content elements.
|
|
266
|
+
- c6fb34f: Dispatch headless code presentations from unified rendering.
|
|
267
|
+
- 9616242: Keep code-line consumers subscribed to their selected line range rather than unrelated owner metadata.
|
|
268
|
+
- 3f24715: Reuse completed root block records during native tail parsing and clone only unfinished or affected container snapshots at EOF. Custom document plugins retain isolated previous snapshots. This reduces snapshot copying while preserving authored content and semantic lifecycle ordering.
|
|
269
|
+
|
|
270
|
+
Keep generic roots and native code, table, and paragraph owners in source order when emitting absolute root child indexes. A later generic heading no longer precedes an earlier native paragraph or displaces retained footnote/HTML roots.
|
|
271
|
+
|
|
272
|
+
Admit newly reached native code fences even when earlier code owners already exist. Seek admission from the changed root suffix and skip existing source starts before allocating owners. Mixed CR/LF input invalidates the adjacent unfinished parse fragment, while derived indented-code text uses normalized newlines without changing authored raw source.
|
|
273
|
+
|
|
274
|
+
Reopened native lists and blockquotes publish a bounded semantic finality transition. EOF emits the matching finalize operation for reparsed native suffix roots even when earlier completed records are retained. Core snapshots and the React store keep this finality in canonical block state rather than presentation props. During EOF finalization, retained-prefix indices are operation-local and are reused only after source-boundary validation against the current array; stale indices fall back to binary search.
|
|
275
|
+
|
|
276
|
+
Keep semantic and enrichment `setProps` deliveries separate when merging or batching. Discarding late code enrichment no longer discards an adjacent canonical container-finality transition.
|
|
277
|
+
|
|
278
|
+
Reject semantic output from an older parse epoch even when its stream sequence is higher. Direct document-plugin registry registration receives the same previous-snapshot isolation as constructor-installed plugins, including finalized prefix blocks reused by the generic append path.
|
|
279
|
+
|
|
280
|
+
- 3f24715: Require each live worker PATCH and every schema-2 protocol event to carry its native root document generation. Renderers and TUI event stores reject stale-generation work against the current validated INITIALIZED baseline, including after queueing; TUI replacement also clears old transaction/status metadata. Caller-managed worker attachment stays pending until an observed baseline, then drains accepted input once. Node and direct snapshot compilers bind patch/finalization handling to that baseline. Static snapshot artifacts remain version 1.
|
|
281
|
+
|
|
282
|
+
Explicit cold TUI replacement retires the old native lease, so delayed snapshots and lifecycle events cannot reclaim the replacement. A validated newer same-stream baseline can resume delivery.
|
|
283
|
+
|
|
284
|
+
Bind same-turn restart capacity waits to the new session's admitting renderer, retaining their requested capacity and cancellation options without dropping accepted source.
|
|
285
|
+
|
|
286
|
+
Use the task-packed protocol dependency in installed Node, Next, and Vite smoke consumers instead of allowing a registry fallback.
|
|
287
|
+
|
|
288
|
+
Generate JavaScript for both installed runtime loaders and replay a replacement root's actual finalization patches before checking completed source.
|
|
289
|
+
|
|
290
|
+
Render the terminal example from authored cold block source without adding duplicate heading, quote, or code-fence markers.
|
|
291
|
+
|
|
292
|
+
- 246c834: Bind retained streaming handles to their session generation and reject stale or disposed operations with `StreamSessionError`.
|
|
293
|
+
- de787ea: Initialize code follow-tail attachment from the viewport's physical bottom distance on mount.
|
|
294
|
+
- 8c889df: Make `waitForIdle()` wait for the current source session's worker admission and patch commits before returning.
|
|
295
|
+
- 6d9792e: Reject source reads from retained node presentations after their owner is reset, removed, or updated.
|
|
296
|
+
- 4af3faa: Normalize scrollable table presentation wrappers during virtualization, then restore their authored overflow styles when virtualization ends.
|
|
297
|
+
- 7ba4a6b: Preserve the detached visible table row and its pixel offset when measured row heights change, including rows partly covered by the sticky header. Keep bottom-following behavior for attached viewports. Reset the viewport and discard its geometry when the root source document is replaced, while retaining anchors across same-document appends.
|
|
298
|
+
|
|
299
|
+
Add an accessible per-table "Show full content" toggle for virtualized tables. It mounts all rows only on request and restores bounded windowing while retaining the native viewport, table, selection endpoints, measured columns, and scroll position.
|
|
300
|
+
|
|
301
|
+
Native table Markdown copy and download use the owned authored source slice, preserving spacing, escapes, inline Markdown, and original line endings while excluding the final row's line ending and following document content. TSV and CSV remain cell-value transforms. The public consumer regression clicks the copy button in JSDOM with a stubbed Clipboard API; it does not verify a physical browser or OS clipboard. Markdown download shares the source-selection path, but its Blob/browser handoff, PDF, and speech output were not exercised.
|
|
302
|
+
|
|
303
|
+
- Ensure finalized native and custom lazy code blocks request fresh full-range tokenization after document or code-epoch replacement, including identical source with reused block IDs and progress counts. Keep progress deduplication within the current lifetime.
|
|
304
|
+
|
|
305
|
+
- Verify coalesced patches through raw, linear, and quadratic consumer replays. Keep the 10% minimum on the controlled 60-update redundant-title case with exact final value `value-59`; real-snippet reduction remains telemetry, with retained coalescing counters and duration validated against aggregate totals (capped retained windows may undershoot), alongside the existing 8 ms coalescing-duration p95 guard.
|
|
306
|
+
|
|
307
|
+
- 5833985: Sanitize finalized code-row HTML without a DOM. `sanitizeCodeHTML` now reuses the shared DOM-free rehype pipeline (`CODE_ROW_ALLOWED_TAGS`/`CODE_ROW_ALLOWED_ATTRS`) when `window` is unavailable, so Node/SSR prerender (Next static export, snapshot stores, `MarkdownBlocksRenderer`) renders Shiki line markup and theme CSS variables instead of throwing, and malformed/untrusted row markup still loses scripts, event handlers, `javascript:` URLs, and unsafe style declarations. The browser DOM path applies the same allowlist and the same allowlisted-property/ASCII-charset style policy (rejecting CSS backslash escapes, comment-splitting, and function values such as `url(...)`), so browser and Node code-row DOM semantics match.
|
|
308
|
+
|
|
309
|
+
`ComponentRegistry.hasCustomBlockComponent` now reports a block type as custom only when the registered component differs from the built-in default. Re-passing the built-in component map (`components={registry.getBlockComponentMap()}`, the docs harness shape) keeps native block views enabled, so nested list children and nested code fences render instead of flattening through the default list component. Mid-stream fallback code lines are joined with newlines, so streamed `pre code` text stays a strict logical prefix of the finalized fence source.
|
|
310
|
+
|
|
311
|
+
- 9c482bd: Keep long documents streaming at high input rates. On a 1 MB document fed at 20,000 characters per second, the worker previously needed about 127 seconds of parse time for a stream that lasts about 50 seconds, so it fell further behind with every append.
|
|
312
|
+
|
|
313
|
+
Worker:
|
|
314
|
+
|
|
315
|
+
- Checks HTML ownership markers only inside the changed region.
|
|
316
|
+
- Reuses the source slice for each extracted block.
|
|
317
|
+
- Takes change ranges straight from the parser.
|
|
318
|
+
- Caches the tree sanitizer.
|
|
319
|
+
- Skips footnote and link-reference scans for blocks that cannot contain them.
|
|
320
|
+
|
|
321
|
+
React renderer:
|
|
322
|
+
|
|
323
|
+
- Wakes only the node subscribers whose records changed, not every mounted node.
|
|
324
|
+
- Keeps a code line's props when its text, tokens and HTML are unchanged, so the line is not re-sanitized.
|
|
325
|
+
- When the final canonical snapshot replaces a block, records whose content is unchanged keep their identity, so finalization re-renders only the blocks that changed.
|
|
326
|
+
|
|
327
|
+
Theme: the blockquote closing-quote rule now checks `p:is(blockquote *)` before `:last-of-type`. Selected elements and computed styles are unchanged. Chrome no longer restyles every sibling of an appended paragraph, which removed most style-recalculation time on long documents.
|
|
328
|
+
|
|
329
|
+
- 150a0ac: Omit `language-*` and `data-language` attributes on `<code>` and `pre` for info-less code blocks and indented code blocks in accordance with CommonMark specification §4.4/§4.5, reserving `language-*` classes exclusively for code blocks with explicit info strings. Syntax highlighting fallback to plain text continues to operate internally.
|
|
330
|
+
- 73bdb36: Cut main-thread cost while streaming. The renderer store reuses one public block clone per unchanged block instead of re-cloning every block on each read. Structural invariants are scanned when `getInvariantViolations()` is read, not after every patch batch. Browser code-row sanitizing uses a preconfigured DOMPurify instance that applies the style policy during sanitizing, with no second parse. Task-list checkboxes no longer set the redundant `aria-checked` attribute; native checkboxes already expose their checked state.
|
|
331
|
+
- fdaa309: Prepare nested list and quote snapshots with the owning engine's parsers, plugin callbacks, and references. Preserve source order and streaming finalization, and serialize normal nested code highlights and code-line children for core and React consumers. Correct tab headings, empty list item continuation, fence info decoding, and disabled table parsing.
|
|
332
|
+
|
|
333
|
+
Keep nested lazy tokenization isolated across document replacements and preserve equivalent code through owner reparses. Use compact public token styles, and give every defined footnote occurrence a distinct reference target and footer backlink while rendering missing references literally.
|
|
334
|
+
|
|
335
|
+
Honor explicit null code-line HTML in React lazy highlight patches, so token-only descendant enrichment clears stale fallback HTML instead of hiding token colors. Keep existing HTML when patches omit it, retain both-mode highlights, and preserve unchanged row props.
|
|
336
|
+
|
|
337
|
+
Keep native HTML paragraph ownership separate from block MDX compilation. Preserve surrounding prose and literal disallowed component tags, retain pending inline JSX projections at finalization, and compile standalone self-closing components through the existing module evaluator rather than the prose renderer.
|
|
338
|
+
|
|
339
|
+
Project mixed paragraph content through registered paragraph wrappers and prepared quote children through registered quote wrappers. Preserve the existing `children` extension contract, registry inline/URL/filter context, and coordinator-mode standalone MDX pending-segment metadata while keeping complete components on the module-evaluation path.
|
|
340
|
+
|
|
341
|
+
Carry sanitized mixed HTML ownership into native segment snapshots so registered URL transforms and descendant element filters apply after streaming and serialization. Keep registered quote wrappers for provisional and empty quotes as well as finalized content.
|
|
342
|
+
|
|
343
|
+
- 95be0bf: Fix React renderer and worker lifecycle defects: terminate factory-created workers on unmount, ensure blockRenderer override resets cleanly when the prop is removed, clear the patch scheduler upon worker detachment to prevent post-detach commits, listen for Worker error events to transition stream status and notify onError, and export HtmlOptions and SyntaxRuleSpec types.
|
|
344
|
+
- - Omit rejected Markdown link URLs, including HTML-owned paragraphs and custom link components.
|
|
345
|
+
- Apply paragraph element filters and `unwrapDisallowed` to HTML-normalized paragraphs.
|
|
346
|
+
- Bound dense streaming animation delays by `maxBacklogMs` without dropping or reordering text.
|
|
347
|
+
- Preserve themes, syntax rules, and HTML policy in fresh and cached Node snapshot initialization metadata.
|
|
348
|
+
- Keep paragraphs and lists outside unfinished HTML containers at native block boundaries while preserving balanced HTML and MDX region ownership.
|
|
349
|
+
- Forward registered uppercase-initial MDX component names through caller-owned demo worker initialization, retaining them across MDX toggles and restarts.
|
|
350
|
+
- e02e7cf: Security hardening: render-time URL transformation across client and SSR, raw HTML attribute and style sanitization, unified HAST URL sanitization, and ArtifactFrame height validation.
|
|
351
|
+
|
|
352
|
+
- `@stream-mdx/core`: Replaced dead URL sanitization code with `defaultUrlTransform(url, attribute, context)` which sanitizes URLs for `href` and `src` attributes. Rejects `javascript:`, `vbscript:`, `file:`, and unapproved `data:` URLs (allowing only `data:image/(png|gif|jpeg|webp|avif)` on `src`), while permitting relative paths, fragments, and custom schemes so CommonMark conformance stays at 675/675. In HTML schemas, `on*` event handlers and `srcdoc` attributes are strictly forbidden regardless of user `allowedTags` configuration, and `script` tags are never permitted. Exported `sanitizeStyle` for DOM-free CSS style sanitization.
|
|
353
|
+
- `@stream-mdx/react`: Added `urlTransform` prop to `<StreamingMarkdown />`, `ComponentRegistry`, and `MarkdownBlocksRenderer`. Applied at render time across link and image node views, raw HTML attributes (`href`, `src`, `action`, `formaction`, `xlink:href`), SSR rendering, and `openLink`/`linkSafety` navigation (preventing unsafe scheme execution). Raw HTML `style` attributes now enforce the DOM-free CSS property allowlist (dropping `position`, `url()`, backslash escapes, and expressions while retaining colors and fonts). `ArtifactFrame` strictly verifies `Number.isFinite(data.height)` and clamps between 50 and 10000 px, ignoring `NaN` and `Infinity`.
|
|
354
|
+
- `@stream-mdx/unified`: Added `urlTransform` option to `createUnifiedRenderer` that applies URL sanitization via a final HAST transformation pass after user rehype plugins without stripping user classes.
|
|
355
|
+
|
|
356
|
+
- Updated dependencies [1669abb]
|
|
357
|
+
- Updated dependencies [0e96940]
|
|
358
|
+
- Updated dependencies [a73209b]
|
|
359
|
+
- Updated dependencies [5833985]
|
|
360
|
+
- Updated dependencies [9c482bd]
|
|
361
|
+
- Updated dependencies [150a0ac]
|
|
362
|
+
- Updated dependencies [7879ed5]
|
|
363
|
+
- Updated dependencies [73bdb36]
|
|
364
|
+
- Updated dependencies [22fc3c9]
|
|
365
|
+
- Updated dependencies [fdaa309]
|
|
366
|
+
- Updated dependencies [1842544]
|
|
367
|
+
- Updated dependencies
|
|
368
|
+
- Updated dependencies [e02e7cf]
|
|
369
|
+
- Updated dependencies
|
|
370
|
+
- Updated dependencies [c9adde8]
|
|
371
|
+
- @stream-mdx/core@1.0.0
|
|
372
|
+
- @stream-mdx/worker@1.0.0
|
|
373
|
+
|
|
3
374
|
## 0.5.0
|
|
4
375
|
|
|
5
376
|
### Minor Changes
|
package/README.md
CHANGED
|
@@ -28,8 +28,7 @@ Peer dependencies:
|
|
|
28
28
|
| `@stream-mdx/react/renderer` | Lower-level renderer exports |
|
|
29
29
|
| `@stream-mdx/react/renderer/patch-commit-scheduler` | Scheduler implementation surface |
|
|
30
30
|
| `@stream-mdx/react/renderer/store` | Renderer store surface |
|
|
31
|
-
| `@stream-mdx/react/mdx
|
|
32
|
-
| `@stream-mdx/react/mdx-coordinator` | MDX coordination helpers |
|
|
31
|
+
| `@stream-mdx/react/trusted-mdx` | Explicit trusted-MDX engine factory and pure contract types |
|
|
33
32
|
|
|
34
33
|
## Quickstart
|
|
35
34
|
|
|
@@ -48,13 +47,29 @@ export function Demo({ text }: { text: string }) {
|
|
|
48
47
|
<StreamingMarkdown
|
|
49
48
|
text={text}
|
|
50
49
|
worker="/workers/markdown-worker.js"
|
|
51
|
-
features={{ html: true, tables: true, math: true,
|
|
52
|
-
mdxCompileMode="worker"
|
|
50
|
+
features={{ html: true, tables: true, math: true, footnotes: true }}
|
|
53
51
|
/>
|
|
54
52
|
);
|
|
55
53
|
}
|
|
56
54
|
```
|
|
57
55
|
|
|
56
|
+
`engine` defaults to `"auto"` and bootstraps up to 4,096 accepted UTF-16 source units with the existing inline engine while worker setup and grammar prewarm are pending. Further source is deferred beyond that limit. `"worker"` requires a Worker; `"main"` runs parsing on the browser thread without a bootstrap cap. Engine setup runs after mounting, not during SSR. Use compiled snapshots and the server entry for server markup.
|
|
57
|
+
|
|
58
|
+
### Rendering customization
|
|
59
|
+
|
|
60
|
+
`components` replaces the removed renderer maps:
|
|
61
|
+
|
|
62
|
+
- `inlineComponents` → `components["inline:<kind>"]` or `components["extension:<name>"]`
|
|
63
|
+
- `htmlElements` → `components["html:<tag>"]`
|
|
64
|
+
- `tableElements` → `components.table` wrappers or headless table views with `useTableBlock` / `useTableRows`
|
|
65
|
+
- `codeRenderers` → `components.code` wrappers or headless code views; wrappers receive `metadata.language`, and `slots.actions` replaces native code actions. Mermaid diagrams use `engines.mermaid` from `createMermaidEngine()`
|
|
66
|
+
- `mathRenderer` → presentation becomes a math wrapper/view in `components["inline:math"]`; TeX rendering uses `engines.math` (KaTeX remains the default)
|
|
67
|
+
- `mdxComponents` → restricted `contentComponents` registrations, or trusted `contentPolicy="trusted-mdx"` with `engines.mdx`
|
|
68
|
+
|
|
69
|
+
`features.math: false` disables math parsing. See the [public API](../../docs/PUBLIC_API.md) for HTML policy, restricted/trusted MDX, inert artifact fences, and optional finalized-block unified routing.
|
|
70
|
+
|
|
71
|
+
`colorScheme` accepts `"light"`, `"dark"`, or `"system"` and sets the native root's `data-color-scheme`. System mode follows `prefers-color-scheme` with CSS only; when unset, a `.dark` ancestor keeps the existing class-based behavior. Native roots carry `data-stream-mdx` and `not-prose`, so enclosing typography-plugin selectors do not restyle native output and the optional Tailwind theme scopes native styles to that root.
|
|
72
|
+
|
|
58
73
|
## Typical Uses
|
|
59
74
|
|
|
60
75
|
| Use case | API |
|
|
@@ -72,6 +87,8 @@ import { ComponentRegistry, MarkdownBlocksRenderer } from "@stream-mdx/react/ser
|
|
|
72
87
|
return <MarkdownBlocksRenderer blocks={blocks} componentRegistry={new ComponentRegistry()} />;
|
|
73
88
|
```
|
|
74
89
|
|
|
90
|
+
Default math stays as authored TeX source on the server and on the client's first render. KaTeX loads after commit and replaces that source after mount, so cold and preloaded clients hydrate from the same markup.
|
|
91
|
+
|
|
75
92
|
### Bottom-stick scroll area
|
|
76
93
|
|
|
77
94
|
```tsx
|
|
@@ -85,8 +102,66 @@ Behavior notes:
|
|
|
85
102
|
- sticks to bottom while content appends
|
|
86
103
|
- detaches on upward user scroll
|
|
87
104
|
- supports smooth return-to-bottom behavior
|
|
105
|
+
- honors `prefers-reduced-motion: reduce` with instant jumps and no jump-chrome transition
|
|
106
|
+
- interrupts an active smooth return on wheel, touch, or scroll-key input without preventing native behavior
|
|
88
107
|
- exposes debug hooks used by deterministic checks in the repo
|
|
89
108
|
|
|
109
|
+
### Table row virtualization
|
|
110
|
+
|
|
111
|
+
```tsx
|
|
112
|
+
import { StreamingMarkdown } from "@stream-mdx/react";
|
|
113
|
+
|
|
114
|
+
<StreamingMarkdown
|
|
115
|
+
text={content}
|
|
116
|
+
tableVirtualization={{
|
|
117
|
+
enabled: true,
|
|
118
|
+
minRows: 40,
|
|
119
|
+
estimatedRowHeight: 44,
|
|
120
|
+
overscan: 8,
|
|
121
|
+
maxHeight: "600px",
|
|
122
|
+
}}
|
|
123
|
+
/>
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
Table virtualization is disabled by default. Only finalized tables meeting `minRows` virtualize after mounting in a browser and after the surrounding stream ends. SSR, unfinished tables, and active streams render every row.
|
|
127
|
+
|
|
128
|
+
Virtualized tables retain native table elements, a sticky header, measured variable row heights, and `aria-hidden` spacer rows. The last row remains reachable by scrolling.
|
|
129
|
+
When detached from the bottom, row measurements preserve the visible row and its pixel offset, including content partly covered by the sticky header. Scrolling chooses a new anchor; bottom attachment still follows measured tail growth.
|
|
130
|
+
|
|
131
|
+
### Code viewport and printing
|
|
132
|
+
|
|
133
|
+
Large native code blocks use a bounded reader viewport. The **Show full content** control mounts all authored lines while retaining the existing code wrapper and mounted native rows; toggling back restores the bounded window and reader anchor.
|
|
134
|
+
|
|
135
|
+
`StreamingMarkdown` accepts `codeVirtualization?: Partial<VirtualizedCodeConfig>` to configure native code viewport presentation:
|
|
136
|
+
|
|
137
|
+
```tsx
|
|
138
|
+
<StreamingMarkdown text={content} codeVirtualization={{ followTail: true }} />
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
`followTail` defaults to `false`, preserving the reader position when code is appended. Set it to `true` to opt in to following appended rows while attached at the physical bottom (within 2px). An upward scroll of more than 1px detaches; returning within 2px reattaches. Changing this presentation config does not reset authored source or replace the native viewport; turning `followTail` off preserves the existing reader anchor and scroll position on a subsequent append.
|
|
142
|
+
|
|
143
|
+
When a browser dispatches `beforeprint`, an eligible virtualized native code block temporarily mounts its full source and removes viewport clipping and height limits. `afterprint` restores the prior reader mode, scroll anchor, and native text selection without changing the manual full-content control.
|
|
144
|
+
|
|
145
|
+
Print preparation mounts the whole block in the DOM, so print-time memory and layout work scale with the source length. Custom code renderers and server-rendered output control their own print behavior.
|
|
146
|
+
|
|
147
|
+
Native whole-code copy/download uses cold authored source, preserving CR/LF and trailing blank lines rather than normalized display text. The test DOM exercises copy with an active selection and a Clipboard API stub; no physical browser or OS clipboard proof is claimed. Download shares the source action, but direct Blob browser proof remains pending. Native copied-status feedback cleanup prevents delayed updates after unmount.
|
|
148
|
+
Each eligible virtualized table also exposes a "Show full content" toggle. It mounts every row only on request; toggling it again restores the bounded viewport without replacing the native table or changing the reader's scroll position.
|
|
149
|
+
|
|
150
|
+
|
|
151
|
+
### Table controls
|
|
152
|
+
|
|
153
|
+
Table controls are off by default. Enable Markdown copy or download for tables with `controls`:
|
|
154
|
+
|
|
155
|
+
```tsx
|
|
156
|
+
<StreamingMarkdown
|
|
157
|
+
text={content}
|
|
158
|
+
features={{ tables: true }}
|
|
159
|
+
controls={{ table: { copy: ["markdown"], download: ["markdown"] } }}
|
|
160
|
+
/>
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
For native tables, Markdown copy and download use the table's authored source slice. They preserve spacing, escaped pipes, inline Markdown, and original line endings, and exclude the final row's line ending and any following document content. TSV and CSV remain cell-value transforms, not source-preserving Markdown.
|
|
164
|
+
|
|
90
165
|
## When To Use This Package Directly
|
|
91
166
|
|
|
92
167
|
- You are shipping a library that wants `@stream-mdx/react` explicitly in `peerDependencies` or `dependencies`.
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { Block, UrlTransform } from '@stream-mdx/core';
|
|
2
|
+
import React__default from 'react';
|
|
3
|
+
import { l as ElementFilterOptions, d as ComponentRegistry, _ as NodePresentations, b as ControlsConfig, c as ControlsComponentProps, w as AnimatedProp, C as ContentComponentsMap, $ as MermaidEngine } from './index-D7dyyu3q.js';
|
|
4
|
+
import { RendererStore } from './renderer/store.js';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* React component for rendering markdown blocks
|
|
8
|
+
*/
|
|
9
|
+
interface MarkdownBlocksRendererProps extends ElementFilterOptions {
|
|
10
|
+
blocks: ReadonlyArray<Block>;
|
|
11
|
+
componentRegistry?: ComponentRegistry;
|
|
12
|
+
className?: string;
|
|
13
|
+
style?: React__default.CSSProperties;
|
|
14
|
+
colorScheme?: "light" | "dark" | "system";
|
|
15
|
+
store?: RendererStore;
|
|
16
|
+
components?: NodePresentations;
|
|
17
|
+
urlTransform?: UrlTransform;
|
|
18
|
+
controls?: ControlsConfig;
|
|
19
|
+
controlsComponent?: React__default.ComponentType<ControlsComponentProps>;
|
|
20
|
+
animated?: AnimatedProp;
|
|
21
|
+
statusMessage?: string;
|
|
22
|
+
contentComponents?: ContentComponentsMap;
|
|
23
|
+
engines?: {
|
|
24
|
+
mermaid?: MermaidEngine;
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
declare const MarkdownBlocksRenderer: React__default.NamedExoticComponent<MarkdownBlocksRendererProps>;
|
|
28
|
+
|
|
29
|
+
export { MarkdownBlocksRenderer as M, type MarkdownBlocksRendererProps as a };
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { Block, UrlTransform } from '@stream-mdx/core';
|
|
2
|
+
import React__default from 'react';
|
|
3
|
+
import { l as ElementFilterOptions, d as ComponentRegistry, _ as NodePresentations, b as ControlsConfig, c as ControlsComponentProps, w as AnimatedProp, C as ContentComponentsMap, $ as MermaidEngine } from './index-Cmne1yUK.cjs';
|
|
4
|
+
import { RendererStore } from './renderer/store.cjs';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* React component for rendering markdown blocks
|
|
8
|
+
*/
|
|
9
|
+
interface MarkdownBlocksRendererProps extends ElementFilterOptions {
|
|
10
|
+
blocks: ReadonlyArray<Block>;
|
|
11
|
+
componentRegistry?: ComponentRegistry;
|
|
12
|
+
className?: string;
|
|
13
|
+
style?: React__default.CSSProperties;
|
|
14
|
+
colorScheme?: "light" | "dark" | "system";
|
|
15
|
+
store?: RendererStore;
|
|
16
|
+
components?: NodePresentations;
|
|
17
|
+
urlTransform?: UrlTransform;
|
|
18
|
+
controls?: ControlsConfig;
|
|
19
|
+
controlsComponent?: React__default.ComponentType<ControlsComponentProps>;
|
|
20
|
+
animated?: AnimatedProp;
|
|
21
|
+
statusMessage?: string;
|
|
22
|
+
contentComponents?: ContentComponentsMap;
|
|
23
|
+
engines?: {
|
|
24
|
+
mermaid?: MermaidEngine;
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
declare const MarkdownBlocksRenderer: React__default.NamedExoticComponent<MarkdownBlocksRendererProps>;
|
|
28
|
+
|
|
29
|
+
export { MarkdownBlocksRenderer as M, type MarkdownBlocksRendererProps as a };
|