'use client';
/**
* Built-in block registry.
*
* Each media renderer is reached through a `React.lazy` indirection, so a
* chat that never shows (say) a map block never downloads MapLibre. This
* module must NOT statically import any tool — only `React.lazy(() =>
* import('./renderers/…'))` thunks. The `text`/`markdown` kinds are the
* sole exception: `MarkdownMessage` is already a Chat dependency.
*/
import { lazy, Suspense, type ComponentType } from 'react';
import { MarkdownMessage } from '../../../dev/code/MarkdownMessage';
import type {
AudioBlock,
CodeBlock,
DiffBlock,
GalleryBlock,
ImageBlock,
JsonBlock,
LinkBlock,
MapBlock,
MarkdownBlock,
MermaidBlock,
MessageBlock,
TextBlock,
VideoBlock,
} from '../../types/block';
import type { BlockRegistry } from './registry';
import type { BlockRendererProps } from './renderers/types';
/** Minimal inline placeholder while a renderer chunk streams in. */
function BlockFallback() {
return (
);
}
/** Wrap a lazily-loaded renderer in a Suspense boundary. */
function lazyBlock(
loader: () => Promise<{ default: ComponentType> }>,
) {
const Lazy = lazy(loader);
return function LazyBlockRenderer(props: BlockRendererProps) {
return (
}>
);
};
}
const AudioBlockRenderer = lazyBlock(() => import('./renderers/AudioBlock'));
const VideoBlockRenderer = lazyBlock(() => import('./renderers/VideoBlock'));
const ImageBlockRenderer = lazyBlock(() => import('./renderers/ImageBlock'));
const GalleryBlockRenderer = lazyBlock(() => import('./renderers/GalleryBlock'));
const MapBlockRenderer = lazyBlock(() => import('./renderers/MapBlock'));
const JsonBlockRenderer = lazyBlock(() => import('./renderers/JsonBlock'));
const MermaidBlockRenderer = lazyBlock(() => import('./renderers/MermaidBlock'));
const CodeBlockRenderer = lazyBlock(() => import('./renderers/CodeBlock'));
const DiffBlockRenderer = lazyBlock(() => import('./renderers/DiffBlock'));
const LinkBlockRenderer = lazyBlock(() => import('./renderers/LinkBlock'));
/** Render a `text` / `markdown` block as bubble-styled prose. */
function renderProse(content: string, isUser: boolean) {
return ;
}
/**
* The default registry. Host registries are merged over this via
* `createBlockRegistry(overrides)`.
*/
export const BUILTIN_BLOCK_REGISTRY: BlockRegistry = {
text: (block: TextBlock, ctx) => renderProse(block.text, ctx.isUser),
markdown: (block: MarkdownBlock, ctx) => renderProse(block.markdown, ctx.isUser),
audio: (block, ctx) => ,
video: (block, ctx) => ,
image: (block, ctx) => ,
gallery: (block, ctx) => ,
map: (block, ctx) => ,
json: (block, ctx) => ,
mermaid: (block, ctx) => ,
code: (block, ctx) => ,
diff: (block, ctx) => ,
link: (block, ctx) => ,
// `custom` has no built-in renderer — it falls through to the
// unknown-kind fallback unless the host registers one.
};