next-chat / components /data-stream-handler.tsx
NeoPy's picture
Upload folder using huggingface_hub
867b17d verified
'use client';
import { useEffect, useRef } from 'react';
import { artifactDefinitions } from './artifact';
import { initialArtifactData, useArtifact } from '@/hooks/use-artifact';
import { useDataStream } from './data-stream-provider';
export function DataStreamHandler() {
const { dataStream } = useDataStream();
const { artifact, setArtifact, setMetadata } = useArtifact();
const lastProcessedIndex = useRef(-1);
useEffect(() => {
if (!dataStream?.length) return;
const newDeltas = dataStream.slice(lastProcessedIndex.current + 1);
lastProcessedIndex.current = dataStream.length - 1;
newDeltas.forEach((delta) => {
const artifactDefinition = artifactDefinitions.find(
(artifactDefinition) => artifactDefinition.kind === artifact.kind,
);
if (artifactDefinition?.onStreamPart) {
artifactDefinition.onStreamPart({
streamPart: delta,
setArtifact,
setMetadata,
});
}
setArtifact((draftArtifact) => {
if (!draftArtifact) {
return { ...initialArtifactData, status: 'streaming' };
}
switch (delta.type) {
case 'data-id':
return {
...draftArtifact,
documentId: delta.data,
status: 'streaming',
};
case 'data-title':
return {
...draftArtifact,
title: delta.data,
status: 'streaming',
};
case 'data-kind':
return {
...draftArtifact,
kind: delta.data,
status: 'streaming',
};
case 'data-clear':
return {
...draftArtifact,
content: '',
status: 'streaming',
};
case 'data-finish':
return {
...draftArtifact,
status: 'idle',
};
default:
return draftArtifact;
}
});
});
}, [dataStream, setArtifact, setMetadata, artifact]);
return null;
}