import { Suggestion } from '@/lib/db/schema'; import { UseChatHelpers } from 'ai/react'; import { ComponentType, Dispatch, ReactNode, SetStateAction } from 'react'; import { DataStreamDelta } from './data-stream-handler'; import { UIBlock } from './block'; export type BlockActionContext = { content: string; handleVersionChange: (type: 'next' | 'prev' | 'toggle' | 'latest') => void; currentVersionIndex: number; isCurrentVersion: boolean; mode: 'edit' | 'diff'; metadata: any; setMetadata: Dispatch>; }; type BlockAction = { icon: ReactNode; label?: string; description: string; onClick: (context: BlockActionContext) => void; isDisabled?: (context: BlockActionContext) => boolean; }; export type BlockToolbarContext = { appendMessage: UseChatHelpers['append']; }; export type BlockToolbarItem = { description: string; icon: ReactNode; onClick: (context: BlockToolbarContext) => void; }; type BlockContent = { title: string; content: string; mode: 'edit' | 'diff'; isCurrentVersion: boolean; currentVersionIndex: number; status: 'streaming' | 'idle'; suggestions: Array; onSaveContent: (updatedContent: string, debounce: boolean) => void; isInline: boolean; getDocumentContentById: (index: number) => string; isLoading: boolean; metadata: any; setMetadata: Dispatch>; }; interface InitializeParameters { documentId: string; setMetadata: Dispatch>; } type BlockConfig = { kind: T; description: string; content: ComponentType< Omit & { metadata: M; setMetadata: Dispatch>; } >; actions?: BlockAction[]; toolbar?: BlockToolbarItem[]; metadata?: M; initialize?: (parameters: InitializeParameters) => void; onStreamPart?: (args: { setMetadata: Dispatch>; setBlock: Dispatch>; streamPart: DataStreamDelta; }) => void; }; export class Block { readonly kind: T; readonly description: string; readonly content: ComponentType; readonly actions: BlockAction[]; readonly toolbar: BlockToolbarItem[]; readonly metadata: M; readonly initialize: (parameters: InitializeParameters) => void; readonly onStreamPart?: (args: { setMetadata: Dispatch>; setBlock: Dispatch>; streamPart: DataStreamDelta; }) => void; constructor(config: BlockConfig) { this.kind = config.kind; this.description = config.description; this.content = config.content; this.actions = config.actions || []; this.toolbar = config.toolbar || []; this.metadata = config.metadata as M; this.initialize = config.initialize || (async () => ({})); this.onStreamPart = config.onStreamPart; } }