'use client'; /** * Block registry — maps a `MessageBlock['kind']` to a renderer. * * Mirrors `AttachmentRendererMap`, but keyed by a discriminant instead of * a predicate: cheaper, exhaustively typed, host-extensible. The built-in * registry (`BUILTIN_BLOCK_REGISTRY`) lives in `./builtin` so this module * stays free of any tool import. */ import type { ReactNode } from 'react'; import type { MessageBlock, MessageBlockKind, BlockAppearance } from '../../types/block'; import { BUILTIN_BLOCK_REGISTRY } from './builtin'; /** Context passed to every renderer alongside the block. */ export interface BlockRenderContext { appearance: BlockAppearance; isUser: boolean; } /** A renderer for one `kind`. The union is narrowed by the registry key. */ export type BlockRenderer = ( block: Extract, ctx: BlockRenderContext, ) => ReactNode; /** Partial map of `kind` → renderer. Missing kinds fall back to unknown. */ export type BlockRegistry = { [K in MessageBlockKind]?: BlockRenderer; }; /** * Merge host overrides over the built-in registry. Overrides win by key — * `{ map: myMapRenderer }` swaps only the map renderer. */ export function createBlockRegistry(overrides?: BlockRegistry): BlockRegistry { return { ...BUILTIN_BLOCK_REGISTRY, ...overrides }; } export { BUILTIN_BLOCK_REGISTRY };