markstream-react 0.0.48 → 0.0.49

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.
@@ -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,6 +53,8 @@ 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';
@@ -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,7 +1,8 @@
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';
4
+ import { SmoothMarkdownStreamOptions } from './hooks/useSmoothMarkdownStream';
5
+ import { CodeBlockMonacoOptions, CodeBlockMonacoTheme, CodeBlockNodeProps, CodeBlockPreviewPayload, D2BlockNodeProps, InfographicBlockNodeProps, MermaidBlockNodeProps } from './types/component-props';
5
6
  export type NodeRendererCodeBlockProps = Partial<Omit<CodeBlockNodeProps, 'node'>> & Record<string, unknown>;
6
7
  export interface NodeRendererProps {
7
8
  content?: string;
@@ -38,7 +39,20 @@ export interface NodeRendererProps {
38
39
  isDark?: boolean;
39
40
  customId?: string;
40
41
  indexKey?: number | string;
42
+ /** Show a blinking typewriter cursor while streamed content grows. Default: false */
41
43
  typewriter?: boolean;
44
+ /** Enable/disable non-code-node enter and streamed-text fade animations. Default: true */
45
+ fade?: boolean;
46
+ /**
47
+ * Enable built-in smooth pacing for streaming `content` updates.
48
+ * - `true`: force-enable smooth streaming (content mode only)
49
+ * - `false`: force-disable smooth streaming
50
+ * - `'auto'` (default): enable only when typewriter/incremental mode is active
51
+ * Applies when rendering from `content` (not `nodes`).
52
+ */
53
+ smoothStreaming?: boolean | 'auto';
54
+ /** Options forwarded to the built-in smooth streaming controller. Read once when the renderer is created. */
55
+ smoothStreamingOptions?: SmoothMarkdownStreamOptions;
42
56
  batchRendering?: boolean;
43
57
  initialRenderBatchSize?: number;
44
58
  renderBatchSize?: number;
@@ -59,6 +73,8 @@ export interface RenderContext {
59
73
  isDark?: boolean;
60
74
  indexKey?: string;
61
75
  typewriter?: boolean;
76
+ /** Enable/disable fade animations. Default: true */
77
+ fade?: boolean;
62
78
  textStreamState?: Map<string, string>;
63
79
  streamRenderVersion?: number;
64
80
  customComponents?: CustomComponentMap;
@@ -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.49",
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",
@@ -116,7 +116,8 @@
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": "0.0.1",
120
+ "stream-markdown-parser": "0.0.95"
120
121
  },
121
122
  "devDependencies": {
122
123
  "@types/react": "^18.3.28",
@@ -133,12 +134,13 @@
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
+ "release": "pnpm run check:core-published && bumpp --commit --no-tag --no-push && pnpm publish --access public && node ../../scripts/tag-package.mjs --package-json package.json --push"
143
145
  }
144
146
  }