2024-12-19 17:05:04 +05:30
|
|
|
'use client';
|
|
|
|
|
|
2025-03-04 18:00:14 -08:00
|
|
|
import { useChat } from '@ai-sdk/react';
|
2025-01-27 14:19:47 +05:30
|
|
|
import { useEffect, useRef } from 'react';
|
2025-02-13 08:25:57 -08:00
|
|
|
import { artifactDefinitions, ArtifactKind } from './artifact';
|
2024-12-19 17:05:04 +05:30
|
|
|
import { Suggestion } from '@/lib/db/schema';
|
2025-02-13 08:25:57 -08:00
|
|
|
import { initialArtifactData, useArtifact } from '@/hooks/use-artifact';
|
2024-12-19 17:05:04 +05:30
|
|
|
|
2025-01-27 14:19:47 +05:30
|
|
|
export type DataStreamDelta = {
|
2024-12-19 17:05:04 +05:30
|
|
|
type:
|
|
|
|
|
| 'text-delta'
|
|
|
|
|
| 'code-delta'
|
2025-02-03 13:33:48 +05:30
|
|
|
| 'sheet-delta'
|
2025-01-15 19:59:29 +05:30
|
|
|
| 'image-delta'
|
2024-12-19 17:05:04 +05:30
|
|
|
| 'title'
|
|
|
|
|
| 'id'
|
|
|
|
|
| 'suggestion'
|
|
|
|
|
| 'clear'
|
|
|
|
|
| 'finish'
|
|
|
|
|
| 'kind';
|
|
|
|
|
content: string | Suggestion;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export function DataStreamHandler({ id }: { id: string }) {
|
|
|
|
|
const { data: dataStream } = useChat({ id });
|
2025-02-13 08:25:57 -08:00
|
|
|
const { artifact, setArtifact, setMetadata } = useArtifact();
|
2024-12-19 17:05:04 +05:30
|
|
|
const lastProcessedIndex = useRef(-1);
|
|
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
if (!dataStream?.length) return;
|
|
|
|
|
|
|
|
|
|
const newDeltas = dataStream.slice(lastProcessedIndex.current + 1);
|
|
|
|
|
lastProcessedIndex.current = dataStream.length - 1;
|
|
|
|
|
|
|
|
|
|
(newDeltas as DataStreamDelta[]).forEach((delta: DataStreamDelta) => {
|
2025-02-13 08:25:57 -08:00
|
|
|
const artifactDefinition = artifactDefinitions.find(
|
|
|
|
|
(artifactDefinition) => artifactDefinition.kind === artifact.kind,
|
2025-01-27 14:19:47 +05:30
|
|
|
);
|
|
|
|
|
|
2025-02-13 08:25:57 -08:00
|
|
|
if (artifactDefinition?.onStreamPart) {
|
|
|
|
|
artifactDefinition.onStreamPart({
|
2025-01-27 14:19:47 +05:30
|
|
|
streamPart: delta,
|
2025-02-13 08:25:57 -08:00
|
|
|
setArtifact,
|
2025-01-27 14:19:47 +05:30
|
|
|
setMetadata,
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
2025-02-13 08:25:57 -08:00
|
|
|
setArtifact((draftArtifact) => {
|
|
|
|
|
if (!draftArtifact) {
|
|
|
|
|
return { ...initialArtifactData, status: 'streaming' };
|
2024-12-19 17:05:04 +05:30
|
|
|
}
|
|
|
|
|
|
|
|
|
|
switch (delta.type) {
|
|
|
|
|
case 'id':
|
|
|
|
|
return {
|
2025-02-13 08:25:57 -08:00
|
|
|
...draftArtifact,
|
2024-12-19 17:05:04 +05:30
|
|
|
documentId: delta.content as string,
|
|
|
|
|
status: 'streaming',
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
case 'title':
|
|
|
|
|
return {
|
2025-02-13 08:25:57 -08:00
|
|
|
...draftArtifact,
|
2024-12-19 17:05:04 +05:30
|
|
|
title: delta.content as string,
|
|
|
|
|
status: 'streaming',
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
case 'kind':
|
|
|
|
|
return {
|
2025-02-13 08:25:57 -08:00
|
|
|
...draftArtifact,
|
|
|
|
|
kind: delta.content as ArtifactKind,
|
2024-12-19 17:05:04 +05:30
|
|
|
status: 'streaming',
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
case 'clear':
|
|
|
|
|
return {
|
2025-02-13 08:25:57 -08:00
|
|
|
...draftArtifact,
|
2024-12-19 17:05:04 +05:30
|
|
|
content: '',
|
|
|
|
|
status: 'streaming',
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
case 'finish':
|
|
|
|
|
return {
|
2025-02-13 08:25:57 -08:00
|
|
|
...draftArtifact,
|
2024-12-19 17:05:04 +05:30
|
|
|
status: 'idle',
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
default:
|
2025-02-13 08:25:57 -08:00
|
|
|
return draftArtifact;
|
2024-12-19 17:05:04 +05:30
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
});
|
2025-02-13 08:25:57 -08:00
|
|
|
}, [dataStream, setArtifact, setMetadata, artifact]);
|
2024-12-19 17:05:04 +05:30
|
|
|
|
|
|
|
|
return null;
|
|
|
|
|
}
|