'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. };