import type { Suggestion } from '@/lib/db/schema'; import type { UseChatHelpers } from '@ai-sdk/react'; import type { ComponentType, Dispatch, ReactNode, SetStateAction } from 'react'; import type { UIArtifact } from './artifact'; import type { ChatMessage, CustomUIDataTypes } from '@/lib/types'; import type { DataUIPart } from 'ai'; export type ArtifactActionContext = { content: string; handleVersionChange: (type: 'next' | 'prev' | 'toggle' | 'latest') => void; currentVersionIndex: number; isCurrentVersion: boolean; mode: 'edit' | 'diff'; metadata: M; setMetadata: Dispatch>; }; type ArtifactAction = { icon: ReactNode; label?: string; description: string; onClick: (context: ArtifactActionContext) => Promise | void; isDisabled?: (context: ArtifactActionContext) => boolean; }; export type ArtifactToolbarContext = { sendMessage: UseChatHelpers['sendMessage']; }; export type ArtifactToolbarItem = { description: string; icon: ReactNode; onClick: (context: ArtifactToolbarContext) => void; }; interface ArtifactContent { 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: M; setMetadata: Dispatch>; } interface InitializeParameters { documentId: string; setMetadata: Dispatch>; } type ArtifactConfig = { kind: T; description: string; content: ComponentType>; actions: Array>; toolbar: ArtifactToolbarItem[]; initialize?: (parameters: InitializeParameters) => void; onStreamPart: (args: { setMetadata: Dispatch>; setArtifact: Dispatch>; streamPart: DataUIPart; }) => void; }; export class Artifact { readonly kind: T; readonly description: string; readonly content: ComponentType>; readonly actions: Array>; readonly toolbar: ArtifactToolbarItem[]; readonly initialize?: (parameters: InitializeParameters) => void; readonly onStreamPart: (args: { setMetadata: Dispatch>; setArtifact: Dispatch>; streamPart: DataUIPart; }) => void; constructor(config: ArtifactConfig) { this.kind = config.kind; this.description = config.description; this.content = config.content; this.actions = config.actions || []; this.toolbar = config.toolbar || []; this.initialize = config.initialize || (async () => ({})); this.onStreamPart = config.onStreamPart; } }