markstream-react 0.0.48 → 0.0.50-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/tailwind.ts CHANGED
@@ -1,3 +1,3 @@
1
- export const safeList = `use client react string cannot delete global call clearGlobalCustomComponents dependency is not install it to enable checkbox-node checkbox checkbox-input note is-dark data-index-key headerId admonition-header admonition-icon admonition-title admonition-toggle aria-expanded aria-controls collapsed admonition-content aria-labelledby stream-markdown-parser typeof window.requestIdleCallback [data-node-index] node-spacer dark virtualized data-custom-id code_block node-slot data-node-index data-node-type typewriter-node node-placeholder performance [markstream-react][perf] mermaid theme object name markdown-renderer boolean safe clsx href xlink:href markstream-d2-root-svg number window.requestAnimationFrame instance.render instance missing render returned empty top d2-block my-4 rounded-lg border overflow-hidden shadow-sm border-gray-700/30 bg-gray-900 text-gray-100 border-gray-200 bg-white text-gray-900 d2-block-header flex justify-between items-center px-4 py-2.5 border-b border-gray-400/5 gap-x-2 text-sm font-medium font-mono gap-x-1 rounded-md p-0.5 bg-gray-700 bg-gray-100 mode-btn px-2 py-1 text-xs rounded !showSource is-active showSource d2-action-btn p-2 transition-colors hover:bg-[var(--vscode-editor-selectionBackground)] copying w-3 h-3 none currentColor round aria-pressed m9 bodyRef d2-block-body bodyStyle !hasPreview d2-source py-4 d2-code d2-error mt-2 d2-render d2-svg pb-3 line-info diffUnchangedRegionStyle line-info-basic metadata legacy off never background auto night moon black dracula mocha frappe macchiato palenight ocean poimandres monokai laserwave tokyo slack-dark rose-pine github-dark material-theme one-dark catppuccin-mocha catppuccin-frappe catppuccin-macchiato light latte dawn lotus plaintext diff visible view.getModifiedEditor ?? explicit on same helpers.cleanupEditor canonicalLanguage single window.cancelAnimationFrame clientX navigator.clipboard navigator.clipboard.writeText code-block-container is-rendering is-diff is-plain-text code-block-header space-x-2 flex-1 icon-slot h-4 w-4 flex-shrink-0 truncate code-action-btn copied m14 evenodd code-block-body--collapsed code-block-body--expanded code-editor-layer code-height-placeholder hidden aria-hidden code-editor-fallback-surface code-fallback-plain m-0 aria-busy aria-label no code-loading-placeholder loading-skeleton skeleton-line short sr-only polite status emoji-node emphasis-node smooth footnote-reference handleScroll footnote-link cursor-pointer footnote-node leading-relaxed border-t border-[var(--footnote-border,#eaecef)] pt-2 insert-node mark highlight-node blockquote-node heading-node font-semibold inline-code inline text-[85%] px-1 py-0.5 bg-[hsl(var(--secondary))] whitespace-normal break-words max-w-full text-node-stream-delta text-node-stream-delta--a text-node-stream-delta--b dl definition-list indexKey mb-4 dt definition-term ctx renderNode definition dd definition-desc ml-4 hard-break footnote-anchor hover:underline ↩︎ react-dom library failed text-red-500 p-4">Failed instanceof error.message error keydown transform ease center fullscreen touches text-gray-400 hover:bg-gray-700 hover:text-gray-200 text-gray-600 hover:bg-gray-200 hover:text-gray-700 source hasPreview preview pending bg-gray-800 bg-gray-50 px-2.5 bg-gray-600 text-gray-200 text-gray-700 text-gray-500 m16 isCollapsed opacity-50 cursor-not-allowed m7 whitespace-pre-wrap text-gray-300 baseCode relative absolute top-2 right-2 z-10 gap-2 backdrop-blur infographic-preview min-h-[360px] transition-all duration-100 block inset-0 cursor-grab isDragging containerRef w-full text-center justify-center min-h-full fixed z-50 bg-black/70 p-4 closeModal dialog h-full max-h-full shadow-lg top-6 right-6 !isDragging cursor-grabbing list-item pl-1.5 my-2 valueAttr children is-loaded lazy eager async image image-node__placeholder image-node__spinner image-node__placeholder-text image… placeholder image-node__error load ease-in-out infinite node.title link-loading inline-flex items-baseline gap-1.5 link-text-wrapper leading-[normal] link-text text link-loading-indicator link-node noopener noreferrer html-block-node escape html-block html-block-node__placeholder html-block-node__placeholder-bar w-4/5 w-2/3 setHostEl shouldRender useDynamic reactNodes list-node my-5 pl-[calc(13/8*1em)] list-decimal list-disc max-lg:my-[calc(4/3*1em)] max-lg:pl-[calc(14/9*1em)] list vitesse-dark vitesse-light shiki shiki-fallback stream-markdown code-block-content rendererTargetRef code-block-render paragraph-node paragraph strong-node reference-node bg-[hsl(var(--muted))] px-1.5 mx-0.5 hover:bg-[hsl(var(--secondary))] event.key unknown-node italic node strikethrough-node subscript-node superscript-node in out zoom hr-node thematic-break containerClass vmr-container javascript typescript python ruby shell d2 plain cpp markdown right text-right text-left pointermove pointerup pointercancel table-node-wrapper my-8 table-node table-node--loading colgroup border-[var(--table-border,#cbd5e1)] p-[calc(4/7*1em)] table-node__resize-handle table-node__loading table-node__spinner window.matchMedia ms-tooltip z-[9999] inline-block text-base py-2 px-3 shadow-md whitespace-nowrap pointer-events-none tooltip-element text-white border-gray-700 tooltip text-node text-node-center afterbegin viewBox loose strict gantt open-modal [data-mermaid-wrapper] mermaid-action-btn toggle-mode common.zoomIn common.zoomOut common.resetZoom transition-[height] duration-150 ease-out data-mermaid-wrapper mermaid-loading mermaid-spinner diagram… mermaid-block-header space-x-1 common.preview common.source common.export mermaid-error hasRenderedOnce mermaid-block modeContainerRef mermaid-modal-overlay mermaid-modal-panel mermaid-modal-header mermaid-modal-title mermaid-modal-close mermaid-modal-body modalContentRef mermaid-modal-content available default abort timed [mermaidWorkerClient] messageerror cleared worker inject via busy canParse findPrefix infographic language d2lang html_block node.type html_inline text_special node.content heading list_item definition_list footnote footnote_reference footnote_anchor admonition hardbreak inline_code emphasis strikethrough highlight insert subscript superscript checkbox_input emoji thematic_break math_inline math_block reference vmr_container label_open label_close stream-monaco document data-language thinking htmlFor class className role aria-describedby self_closing tag_open tag_close parse dynamic template html-inline-node html-inline-node--loading [markstream-react] htmlPreviewSandbox contains both allow-scripts and this only fully trusted content served an isolated en utf-8 viewport content="width=device-width initial-scale=1 html-preview-frame__backdrop--dark html-preview-frame--dark html-preview-frame__header html-preview-frame__title html-preview-frame__dot html-preview-frame__label html-preview-frame__close--dark html-preview-frame__iframe no-referrer about:blank data-ssr-fallback normalizedLanguage renderNodeProp classAttr node.cite value void rowIdx bodyRows.length isOpen thematic-break-node cssVars image-node__img code-block-node code-block markdown-code-block-node markdown-code-block mermaid-block-node d2-block-node infographic-block-node math-block overflow-x-auto min-h-[40px] $$ math-inline-wrapper math-inline data-reference-id customComponents server-renderer node-content mathRef math-inline--hidden math-inline__loading math-inline__spinner rendering math-rendering normalizedType globalThis.requestAnimationFrame globalThis.cancelAnimationFrame sequencediagram classdiagram kind statediagram erdiagram flowchart graph module did expected [katexWorkerClient] init cache-hit timeout waiting slot existingEnv.getWorkerUrl °C process katex`
1
+ export const safeList = `use client react string cannot delete global call clearGlobalCustomComponents blockquote-node auto note is-dark data-index-key headerId admonition-header admonition-icon admonition-title admonition-toggle aria-expanded aria-controls collapsed admonition-content aria-labelledby stream-markdown-parser code_block next.type typeof window.requestIdleCallback [data-node-index] node-spacer dark virtualized data-custom-id node-slot data-node-index data-node-type fade-node typewriter-node node-placeholder typewriterCursorRef typewriter-cursor admonition math_block html_block image object [data-node-type="code_block"] [data-node-type="admonition"] [data-node-type="table"] [data-node-type="math_block"] [data-node-type="html_block"] [data-node-type="image"] performance [markstream-react][perf] mermaid theme name markdown-renderer boolean safe mark highlight-node emphasis-node hard-break dependency is not install it to enable smooth footnote-anchor text-sm hover:underline cursor-pointer ↩︎ clsx heading-node font-semibold footnote-reference handleScroll footnote-link emoji-node number ?? ease-in-out infinite node.title top link-loading inline-flex items-baseline gap-1.5 link-text-wrapper relative leading-[normal] link-text text link-loading-indicator link-node aria-label noopener noreferrer dl definition-list indexKey mb-4 dt definition-term ctx renderNode definition dd definition-desc ml-4 html-block-node escape html-block html-block-node__placeholder html-block-node__placeholder-bar w-4/5 w-2/3 setHostEl shouldRender useDynamic reactNodes insert-node checkbox-node checkbox checkbox-input footnote-node flex leading-relaxed border-t border-[var(--footnote-border,#eaecef)] pt-2 flex-1 line-info diffUnchangedRegionStyle line-info-basic metadata legacy none off never background night moon black dracula mocha frappe macchiato palenight ocean poimandres monokai laserwave tokyo slack-dark rose-pine github-dark material-theme one-dark catppuccin-mocha catppuccin-frappe catppuccin-macchiato light latte dawn lotus plaintext diff visible view.getModifiedEditor explicit on same helpers.cleanupEditor canonicalLanguage window.requestAnimationFrame single window.cancelAnimationFrame clientX navigator.clipboard navigator.clipboard.writeText code-block-container my-4 rounded-lg border overflow-hidden shadow-sm border-gray-700/30 bg-gray-900 border-gray-200 bg-white is-rendering is-diff is-plain-text code-block-header justify-between items-center px-4 py-2.5 border-b border-gray-400/5 space-x-2 icon-slot h-4 w-4 flex-shrink-0 font-medium font-mono truncate code-action-btn p-2 text-xs rounded-md transition-colors hover:bg-[var(--vscode-editor-selectionBackground)] aria-pressed w-3 h-3 currentColor round m9 copied m14 evenodd code-block-body--collapsed code-block-body--expanded code-editor-layer code-height-placeholder hidden aria-hidden code-editor-fallback-surface code-fallback-plain m-0 aria-busy no code-loading-placeholder loading-skeleton skeleton-line short sr-only polite status href xlink:href markstream-d2-root-svg instance.render instance missing render returned empty d2-block text-gray-100 text-gray-900 d2-block-header gap-x-2 gap-x-1 p-0.5 bg-gray-700 bg-gray-100 mode-btn px-2 py-1 rounded !showSource is-active showSource d2-action-btn copying bodyRef d2-block-body bodyStyle !hasPreview d2-source py-4 d2-code d2-error mt-2 d2-render d2-svg pb-3 react-dom library failed text-red-500 p-4">Failed instanceof error.message error keydown transform ease center fullscreen touches text-gray-400 hover:bg-gray-700 hover:text-gray-200 text-gray-600 hover:bg-gray-200 hover:text-gray-700 source hasPreview preview pending bg-gray-800 bg-gray-50 px-2.5 bg-gray-600 text-gray-200 text-gray-700 text-gray-500 m16 isCollapsed opacity-50 cursor-not-allowed m7 whitespace-pre-wrap text-gray-300 baseCode absolute top-2 right-2 z-10 gap-2 backdrop-blur infographic-preview min-h-[360px] transition-all duration-100 block inset-0 cursor-grab isDragging containerRef w-full text-center justify-center min-h-full fixed z-50 bg-black/70 p-4 closeModal dialog h-full max-w-full max-h-full shadow-lg top-6 right-6 !isDragging cursor-grabbing unknown-node italic node list-item pl-1.5 my-2 valueAttr children list-node my-5 pl-[calc(13/8*1em)] list-decimal list-disc max-lg:my-[calc(4/3*1em)] max-lg:pl-[calc(14/9*1em)] list markstream-core inline-code inline text-[85%] px-1 py-0.5 bg-[hsl(var(--secondary))] whitespace-normal break-words text-node-stream-delta text-node-stream-delta--a text-node-stream-delta--b primary fallback is-loaded lazy eager async image-node__placeholder image-node__spinner image-node__placeholder-text image… placeholder image-node__error load superscript-node paragraph-node paragraph right text-right text-left pointermove pointerup pointercancel table-node-wrapper my-8 table-node table-node--loading colgroup border-[var(--table-border,#cbd5e1)] p-[calc(4/7*1em)] table-node__resize-handle table-node__loading table-node__spinner strong-node strikethrough-node window.matchMedia ms-tooltip z-[9999] inline-block text-base py-2 px-3 shadow-md whitespace-nowrap pointer-events-none tooltip-element text-white border-gray-700 tooltip [mermaidWorkerClient] messageerror cleared worker inject via busy timed out canParse findPrefix hr-node thematic-break reference-node bg-[hsl(var(--muted))] px-1.5 mx-0.5 hover:bg-[hsl(var(--secondary))] event.key subscript-node text-node text-node-center in zoom loose strict viewBox gantt open-modal [data-mermaid-wrapper] mermaid-action-btn toggle-mode common.zoomIn common.zoomOut common.resetZoom transition-[height] duration-150 ease-out data-mermaid-wrapper mermaid-loading mermaid-spinner diagram… mermaid-block-header space-x-1 common.preview common.source common.export mermaid-error hasRenderedOnce mermaid-block modeContainerRef mermaid-modal-overlay mermaid-modal-panel mermaid-modal-header mermaid-modal-title mermaid-modal-close mermaid-modal-body modalContentRef mermaid-modal-content available default abort vitesse-dark vitesse-light shiki shiki-fallback [MarkdownCodeBlockNode] dispose stream-markdown stream-markdown.createShikiStreamRenderer stale ready requires with ignoring and using language register configured retrying without code-block-content rendererTargetRef code-block-render infographic d2 d2lang node.type html_inline text_special node.content heading list_item definition_list footnote footnote_reference footnote_anchor hardbreak inline_code emphasis strikethrough highlight insert subscript superscript checkbox_input emoji thematic_break math_inline reference vmr_container label_open label_close containerClass vmr-container javascript typescript go python ruby shell powershell plain cpp csharp objectivec objectivecpp yaml markdown rust kotlin stream-monaco thinking htmlFor class className [markstream-react] htmlPreviewSandbox contains both allow-scripts this only fully trusted content served an isolated en utf-8 viewport content="width=device-width initial-scale=1 html-preview-frame__backdrop--dark html-preview-frame--dark html-preview-frame__header html-preview-frame__title html-preview-frame__dot html-preview-frame__label html-preview-frame__close--dark html-preview-frame__iframe no-referrer about:blank data-ssr-fallback normalizedLanguage data-language renderNodeProp classAttr node.cite value void rowIdx bodyRows.length isOpen thematic-break-node cssVars image-node__img code-block-node code-block markdown-code-block-node markdown-code-block mermaid-block-node d2-block-node infographic-block-node math-block overflow-x-auto min-h-[40px] $$ math-inline-wrapper math-inline data-reference-id customComponents server-renderer node-content document role aria-describedby self_closing tag_open tag_close parse dynamic template html-inline-node html-inline-node--loading mathRef rendering math-rendering math-inline--hidden math-inline__loading math-inline__spinner normalizedType [katexWorkerClient] init cache-hit startTime normalizedContent.length timeout waiting slot globalThis.requestAnimationFrame globalThis.cancelAnimationFrame sequencediagram classdiagram kind statediagram erdiagram flowchart graph module did expected key ref prototype constructor existingEnv.getWorkerUrl npm development process katex °C`
2
2
  module.exports = safeList;
3
3
  export default safeList;
@@ -1,5 +1,5 @@
1
- import { NodeComponentProps } from '../../types/node-component';
2
1
  import { DefinitionItemNode } from 'stream-markdown-parser';
2
+ import { NodeComponentProps } from '../../types/node-component';
3
3
  export declare function DefinitionListNode(props: NodeComponentProps<{
4
4
  type: 'definition_list';
5
5
  items?: DefinitionItemNode[];
@@ -1,5 +1,5 @@
1
- import { NodeComponentProps } from '../../types/node-component';
2
1
  import { ListItemNode as ParsedListItemNode } from 'stream-markdown-parser';
2
+ import { NodeComponentProps } from '../../types/node-component';
3
3
  export declare function ListNode(props: NodeComponentProps<{
4
4
  type: 'list';
5
5
  ordered?: boolean;
@@ -1,4 +1,5 @@
1
- export interface MarkdownCodeBlockNodeProps {
1
+ import { ShikiCodeBlockProps } from '../../types/component-props';
2
+ export interface MarkdownCodeBlockNodeProps extends ShikiCodeBlockProps {
2
3
  node: {
3
4
  type: 'code_block';
4
5
  language: string;
@@ -17,10 +18,6 @@ export interface MarkdownCodeBlockNodeProps {
17
18
  enableFontSizeControl?: boolean;
18
19
  minWidth?: string | number;
19
20
  maxWidth?: string | number;
20
- themes?: string[];
21
- showHeader?: boolean;
22
- showCopyButton?: boolean;
23
- showExpandButton?: boolean;
24
21
  showPreviewButton?: boolean;
25
22
  showCollapseButton?: boolean;
26
23
  showFontSizeButtons?: boolean;
@@ -1,5 +1,5 @@
1
- import { NodeComponentProps } from '../../types/node-component';
2
1
  import { TableRowNode } from 'stream-markdown-parser';
2
+ import { NodeComponentProps } from '../../types/node-component';
3
3
  export declare function TableNode(props: NodeComponentProps<{
4
4
  type: 'table';
5
5
  header?: TableRowNode;
@@ -0,0 +1 @@
1
+ export declare const SmoothStreamingContext: import('react').Context<boolean>;
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Holds mutable streaming state that updates on every streaming chunk
3
+ * without triggering React re-renders. TextNode and InlineCodeNode read
4
+ * from this ref inside effects / callbacks rather than from renderCtx props,
5
+ * so that the renderCtx object can stay referentially stable during streaming.
6
+ */
7
+ export interface StreamStateRef {
8
+ /** Map from node key to last-settled text content (shared across renders). */
9
+ textStreamState: Map<string, string>;
10
+ /** Returns the current stream render version counter. */
11
+ getStreamRenderVersion: () => number;
12
+ }
13
+ /**
14
+ * React Context that carries a stable StreamStateRef.
15
+ * The context value itself never changes (same ref object for the lifetime
16
+ * of the NodeRenderer), so subscribing components do NOT re-render when
17
+ * the stream version increments. Consumers read the latest value inside
18
+ * effects or callbacks via `ref.getStreamRenderVersion()`.
19
+ */
20
+ export declare const StreamStateRefContext: import('react').Context<StreamStateRef>;
21
+ /**
22
+ * Hook that returns the nearest StreamStateRef, or null if none is provided.
23
+ */
24
+ export declare function useStreamStateRef(): StreamStateRef | null;
@@ -0,0 +1,20 @@
1
+ import { SmoothMarkdownStreamOptions, SmoothMarkdownStreamSnapshot } from 'markstream-core';
2
+ export type { SmoothMarkdownStreamOptions, SmoothMarkdownStreamSnapshot };
3
+ export declare function useSmoothMarkdownStream(options?: SmoothMarkdownStreamOptions): {
4
+ enqueue: (chunk: string) => void;
5
+ finish: (options?: {
6
+ flush?: boolean;
7
+ }) => void;
8
+ flush: () => void;
9
+ reset: (initialMarkdown?: string) => void;
10
+ pause: () => void;
11
+ resume: () => void;
12
+ getSnapshot: () => SmoothMarkdownStreamSnapshot;
13
+ source: string;
14
+ visible: string;
15
+ done: boolean;
16
+ paused: boolean;
17
+ pendingChars: number;
18
+ caughtUp: boolean;
19
+ final: boolean;
20
+ };
@@ -53,10 +53,12 @@ export type { TooltipPlacement, TooltipProps } from './components/Tooltip/Toolti
53
53
  export { VmrContainerNode } from './components/VmrContainerNode/VmrContainerNode';
54
54
  export { clearGlobalCustomComponents, getCustomComponentDisplay, getCustomNodeComponents, removeCustomComponents, setCustomComponents, withMarkstreamComponentDisplay, } from './customComponents';
55
55
  export type { CustomComponentDisplayMode, MarkstreamCustomComponent, } from './customComponents';
56
+ export { useSmoothMarkdownStream } from './hooks/useSmoothMarkdownStream';
57
+ export type { SmoothMarkdownStreamOptions, SmoothMarkdownStreamSnapshot, } from './hooks/useSmoothMarkdownStream';
56
58
  export * from './i18n/useSafeI18n';
57
59
  export * from './renderers/renderNode';
58
60
  export type { NodeRendererCodeBlockProps, NodeRendererProps } from './types';
59
- export type { CodeBlockDiffAppearance, CodeBlockDiffHideUnchangedRegions, CodeBlockDiffHideUnchangedRegionsOptions, CodeBlockDiffHunkActionContext, CodeBlockDiffHunkActionKind, CodeBlockDiffHunkSide, CodeBlockDiffLineStyle, CodeBlockDiffUnchangedRegionStyle, CodeBlockMonacoLanguage, CodeBlockMonacoOptions, CodeBlockMonacoTheme, CodeBlockMonacoThemeObject, CodeBlockNodeProps, CodeBlockPreviewPayload, D2BlockNodeProps, ImageNodeProps, InfographicBlockNodeProps, LinkNodeProps, MathBlockNodeProps, MathInlineNodeProps, MermaidBlockEvent, MermaidBlockNodeProps, PreCodeNodeProps, } from './types/component-props';
61
+ export type { CodeBlockDiffAppearance, CodeBlockDiffHideUnchangedRegions, CodeBlockDiffHideUnchangedRegionsOptions, CodeBlockDiffHunkActionContext, CodeBlockDiffHunkActionKind, CodeBlockDiffHunkSide, CodeBlockDiffLineStyle, CodeBlockDiffUnchangedRegionStyle, CodeBlockMonacoLanguage, CodeBlockMonacoOptions, CodeBlockMonacoTheme, CodeBlockMonacoThemeObject, CodeBlockNodeProps, CodeBlockPreviewPayload, D2BlockNodeProps, ImageNodeProps, InfographicBlockNodeProps, LinkNodeProps, MathBlockNodeProps, MathInlineNodeProps, MermaidBlockEvent, MermaidBlockNodeProps, PreCodeNodeProps, ShikiCodeBlockProps, } from './types/component-props';
60
62
  export type { NodeComponentProps } from './types/node-component';
61
63
  export * from './utils/languageIcon';
62
64
  export * from './workers/katexWorkerClient';
@@ -0,0 +1 @@
1
+ export declare function getCodeBlockExtraProps(source: unknown): Record<string, unknown>;
@@ -9,6 +9,19 @@ export interface CodeBlockMonacoThemeObject {
9
9
  }
10
10
  export type CodeBlockMonacoTheme = string | CodeBlockMonacoThemeObject;
11
11
  export type CodeBlockMonacoLanguage = string | ((...args: unknown[]) => unknown);
12
+ export interface CommonCodeBlockProps {
13
+ showHeader?: boolean;
14
+ showCopyButton?: boolean;
15
+ showExpandButton?: boolean;
16
+ }
17
+ export interface ShikiCodeBlockProps extends CommonCodeBlockProps {
18
+ themes?: readonly string[];
19
+ /**
20
+ * Shiki language preload request forwarded to stream-markdown's registerHighlight().
21
+ * This is not a rendering allow-list; already available Shiki languages may still highlight.
22
+ */
23
+ langs?: readonly string[];
24
+ }
12
25
  export interface CodeBlockDiffHideUnchangedRegionsOptions {
13
26
  enabled?: boolean;
14
27
  contextLineCount?: number;
@@ -64,7 +77,7 @@ export interface CodeBlockMonacoOptions {
64
77
  scrollbar?: Record<string, unknown>;
65
78
  [key: string]: unknown;
66
79
  }
67
- export interface CodeBlockNodeProps {
80
+ export interface CodeBlockNodeProps extends CommonCodeBlockProps {
68
81
  node: CodeBlockNode;
69
82
  isDark?: boolean;
70
83
  loading?: boolean;
@@ -77,9 +90,6 @@ export interface CodeBlockNodeProps {
77
90
  minWidth?: string | number;
78
91
  maxWidth?: string | number;
79
92
  themes?: CodeBlockMonacoTheme[];
80
- showHeader?: boolean;
81
- showCopyButton?: boolean;
82
- showExpandButton?: boolean;
83
93
  showPreviewButton?: boolean;
84
94
  showCollapseButton?: boolean;
85
95
  showFontSizeButtons?: boolean;
@@ -153,6 +163,7 @@ export interface MermaidBlockNodeProps {
153
163
  showZoomControls?: boolean;
154
164
  enableWheelZoom?: boolean;
155
165
  isStrict?: boolean;
166
+ enableMermaidInteractions?: boolean;
156
167
  showTooltips?: boolean;
157
168
  onRenderError?: (error: unknown, code: string, container: HTMLElement) => boolean | void;
158
169
  }
@@ -8,5 +8,7 @@ export interface NodeComponentProps<TNode = unknown> {
8
8
  customId?: string;
9
9
  isDark?: boolean;
10
10
  typewriter?: boolean;
11
+ /** Enable/disable fade animations. Default: true */
12
+ fade?: boolean;
11
13
  children?: React.ReactNode;
12
14
  }
@@ -1,8 +1,12 @@
1
1
  import { default as React } from 'react';
2
2
  import { BaseNode, HtmlPolicy, MarkdownIt, ParsedNode, ParseOptions } from 'stream-markdown-parser';
3
3
  import { CustomComponentMap } from './customComponents';
4
- import { CodeBlockPreviewPayload, CodeBlockMonacoOptions, CodeBlockMonacoTheme, CodeBlockNodeProps, D2BlockNodeProps, InfographicBlockNodeProps, MermaidBlockNodeProps } from './types/component-props';
5
- export type NodeRendererCodeBlockProps = Partial<Omit<CodeBlockNodeProps, 'node'>> & Record<string, unknown>;
4
+ import { SmoothMarkdownStreamOptions } from './hooks/useSmoothMarkdownStream';
5
+ import { CodeBlockMonacoOptions, CodeBlockMonacoTheme, CodeBlockNodeProps, CodeBlockPreviewPayload, D2BlockNodeProps, InfographicBlockNodeProps, MermaidBlockNodeProps, ShikiCodeBlockProps } from './types/component-props';
6
+ type NodeRendererCodeBlockThemes = CodeBlockNodeProps['themes'] | ShikiCodeBlockProps['themes'];
7
+ export type NodeRendererCodeBlockProps = Partial<Omit<CodeBlockNodeProps, 'node' | 'themes'>> & Partial<Omit<ShikiCodeBlockProps, 'themes'>> & {
8
+ themes?: NodeRendererCodeBlockThemes;
9
+ } & Record<string, unknown>;
6
10
  export interface NodeRendererProps {
7
11
  content?: string;
8
12
  nodes?: readonly BaseNode[] | null;
@@ -34,11 +38,36 @@ export interface NodeRendererProps {
34
38
  d2Props?: Partial<Omit<D2BlockNodeProps, 'node' | 'loading' | 'isDark'>>;
35
39
  infographicProps?: Partial<Omit<InfographicBlockNodeProps, 'node' | 'loading' | 'isDark'>>;
36
40
  showTooltips?: boolean;
41
+ /**
42
+ * Theme names or theme objects preloaded for Monaco-backed code blocks.
43
+ * When Shiki code blocks are used, only string theme names are forwarded to
44
+ * MarkdownCodeBlockNode / stream-markdown; theme objects are ignored.
45
+ */
37
46
  themes?: CodeBlockMonacoTheme[];
47
+ /**
48
+ * Shiki language preload list forwarded to MarkdownCodeBlockNode.
49
+ *
50
+ * The default React code block renderer is Monaco-backed. This prop is used
51
+ * when a custom `code_block` or language renderer uses MarkdownCodeBlockNode.
52
+ */
53
+ langs?: readonly string[];
38
54
  isDark?: boolean;
39
55
  customId?: string;
40
56
  indexKey?: number | string;
57
+ /** Show a blinking typewriter cursor while streamed content grows. Default: false */
41
58
  typewriter?: boolean;
59
+ /** Enable/disable non-code-node enter and streamed-text fade animations. Default: true */
60
+ fade?: boolean;
61
+ /**
62
+ * Enable built-in smooth pacing for streaming `content` updates.
63
+ * - `true`: force-enable smooth streaming (content mode only)
64
+ * - `false`: force-disable smooth streaming
65
+ * - `'auto'` (default): enable only when typewriter/incremental mode is active
66
+ * Applies when rendering from `content` (not `nodes`).
67
+ */
68
+ smoothStreaming?: boolean | 'auto';
69
+ /** Options forwarded to the built-in smooth streaming controller. Read once when the renderer is created. */
70
+ smoothStreamingOptions?: SmoothMarkdownStreamOptions;
42
71
  batchRendering?: boolean;
43
72
  initialRenderBatchSize?: number;
44
73
  renderBatchSize?: number;
@@ -59,6 +88,8 @@ export interface RenderContext {
59
88
  isDark?: boolean;
60
89
  indexKey?: string;
61
90
  typewriter?: boolean;
91
+ /** Enable/disable fade animations. Default: true */
92
+ fade?: boolean;
62
93
  textStreamState?: Map<string, string>;
63
94
  streamRenderVersion?: number;
64
95
  customComponents?: CustomComponentMap;
@@ -78,6 +109,7 @@ export interface RenderContext {
78
109
  monacoOptions?: CodeBlockMonacoOptions;
79
110
  minWidth?: string | number;
80
111
  maxWidth?: string | number;
112
+ langs?: readonly string[];
81
113
  };
82
114
  events: {
83
115
  onCopy?: (code: string) => void;
@@ -85,3 +117,4 @@ export interface RenderContext {
85
117
  };
86
118
  }
87
119
  export type RenderNodeFn = (node: ParsedNode, key: React.Key, ctx: RenderContext) => React.ReactNode;
120
+ export {};
@@ -0,0 +1 @@
1
+ export declare function isDevEnvironment(): boolean;
@@ -1,23 +1,2 @@
1
- export interface ResolveStreamingTextStateOptions {
2
- nextContent: string;
3
- previousContent: string;
4
- typewriterEnabled: boolean;
5
- }
6
- export interface StreamingTextStateResult {
7
- settledContent: string;
8
- streamedDelta: string;
9
- appended: boolean;
10
- }
11
- export interface StreamingRenderState {
12
- settledContent: string;
13
- streamedDelta: string;
14
- }
15
- export interface ResolveStreamingTextUpdateOptions {
16
- nextContent: string;
17
- persistedContent?: string;
18
- currentState: StreamingRenderState;
19
- typewriterEnabled: boolean;
20
- streamRenderVersionChanged?: boolean;
21
- }
22
- export declare function resolveStreamingTextState({ nextContent, previousContent, typewriterEnabled, }: ResolveStreamingTextStateOptions): StreamingTextStateResult;
23
- export declare function resolveStreamingTextUpdate({ nextContent, persistedContent, currentState, typewriterEnabled, streamRenderVersionChanged, }: ResolveStreamingTextUpdateOptions): StreamingTextStateResult;
1
+ export { resolveStreamingTextState, resolveStreamingTextUpdate } from 'markstream-core';
2
+ export type { ResolveStreamingTextStateOptions, ResolveStreamingTextUpdateOptions, StreamingRenderState, StreamingTextStateResult } from 'markstream-core';
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "markstream-react",
3
3
  "type": "module",
4
- "version": "0.0.48",
4
+ "version": "0.0.50-beta.1",
5
5
  "description": "React Markdown renderer optimized for large documents with progressive Mermaid rendering, streaming diff code blocks, and fast real-time preview. Built on stream-markdown AST for consistent rendering across frameworks. Perfect for documentation sites, AI chat interfaces, and content management systems.",
6
6
  "author": "Simon He",
7
7
  "license": "MIT",
@@ -90,8 +90,8 @@
90
90
  "mermaid": ">=11",
91
91
  "react": ">=18",
92
92
  "react-dom": ">=18",
93
- "stream-markdown": ">=0.0.15",
94
- "stream-monaco": ">=0.0.40"
93
+ "stream-markdown": ">=0.0.16",
94
+ "stream-monaco": ">=0.0.41"
95
95
  },
96
96
  "peerDependenciesMeta": {
97
97
  "@antv/infographic": {
@@ -116,29 +116,32 @@
116
116
  "dependencies": {
117
117
  "@floating-ui/dom": "^1.7.6",
118
118
  "clsx": "^2.1.1",
119
- "stream-markdown-parser": "0.0.93"
119
+ "markstream-core": "1.0.3",
120
+ "stream-markdown-parser": "1.0.5"
120
121
  },
121
122
  "devDependencies": {
122
123
  "@types/react": "^18.3.28",
123
124
  "@types/react-dom": "^18.3.7",
124
125
  "@vitejs/plugin-react-swc": "^3.11.0",
125
- "autoprefixer": "^10.4.27",
126
+ "autoprefixer": "^10.5.0",
126
127
  "rollup": "^3.30.0",
127
128
  "rollup-plugin-dts": "^5.3.1",
128
129
  "rollup-plugin-visualizer": "^6.0.11",
129
130
  "tailwindcss": "^3.4.19",
130
131
  "typescript": "^5.9.3",
131
- "vite": "^7.3.1",
132
+ "vite": "^7.3.3",
132
133
  "vite-plugin-dts": "^4.5.4"
133
134
  },
134
135
  "scripts": {
135
136
  "dev": "vite dev",
136
- "build": "vite build --mode npm && vite build -c vite.config.tailwind.ts --mode npm && node ./scripts/copy-tailwind-css.mjs && node ../../scripts/generate-px-css.mjs && pnpm run build:dts && node ./scripts/ensure-next-client-directive.mjs",
137
+ "build": "pnpm --dir ../markstream-core build && vite build --mode npm && vite build -c vite.config.tailwind.ts --mode npm && node ./scripts/copy-tailwind-css.mjs && node ../../scripts/generate-px-css.mjs && pnpm run build:dts && node ./scripts/ensure-next-client-directive.mjs",
137
138
  "build:analyze": "ANALYZE=true pnpm build",
138
139
  "build:dts": "rollup -c ./scripts/rollup.dts.config.mjs && node ./scripts/clean-dts.cjs",
139
140
  "preview": "vite preview",
140
141
  "typecheck": "tsc --noEmit",
141
142
  "size:check": "node ../../scripts/check-package-size.mjs",
142
- "release": "bumpp --commit --no-tag --no-push && pnpm publish --access public && node ../../scripts/tag-package.mjs --package-json package.json --push"
143
+ "check:core-published": "node ../../scripts/check-core-published.mjs --package-json package.json --core-package-json ../markstream-core/package.json",
144
+ "check:workspace-deps-published": "node ../../scripts/check-workspace-deps-published.mjs --package-json package.json",
145
+ "release": "pnpm run check:workspace-deps-published && bumpp --commit --no-tag --no-push && pnpm publish --access public && node ../../scripts/tag-package.mjs --package-json package.json --push"
143
146
  }
144
147
  }