quivr/frontend/app/chat/[chatId]/hooks/useHandleStream.ts
Antoine Dewez 2baa405991
feat(frontend): search modal - remove parameters and explore buttons (#2094)
# Description

Please include a summary of the changes and the related issue. Please
also include relevant motivation and context.

## Checklist before requesting a review

Please delete options that are not relevant.

- [ ] My code follows the style guidelines of this project
- [ ] I have performed a self-review of my code
- [ ] I have commented hard-to-understand areas
- [ ] I have ideally added tests that prove my fix is effective or that
my feature works
- [ ] New and existing unit tests pass locally with my changes
- [ ] Any dependent changes have been merged

## Screenshots (if appropriate):
2024-01-26 16:06:01 -08:00

71 lines
1.8 KiB
TypeScript

import { useChatContext } from "@/lib/context";
import { ChatMessage } from "../types";
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
export const useHandleStream = () => {
const { updateStreamingHistory } = useChatContext();
const handleStream = async (
reader: ReadableStreamDefaultReader<Uint8Array>,
onFirstChunk: () => void
): Promise<void> => {
const decoder = new TextDecoder("utf-8");
let isFirstChunk = true;
let incompleteData = "";
const handleStreamRecursively = async () => {
const { done, value } = await reader.read();
if (done) {
if (incompleteData !== "") {
// Try to parse any remaining incomplete data
try {
const parsedData = JSON.parse(incompleteData) as ChatMessage;
updateStreamingHistory(parsedData);
} catch (e) {
console.error("Error parsing incomplete data", e);
}
}
return;
}
if (isFirstChunk) {
isFirstChunk = false;
onFirstChunk();
}
// Concatenate incomplete data with new chunk
const rawData = incompleteData + decoder.decode(value, { stream: true });
const dataStrings = rawData.trim().split("data: ").filter(Boolean);
dataStrings.forEach((data, index, array) => {
if (index === array.length - 1 && !data.endsWith("\n")) {
// Last item and does not end with a newline, save as incomplete
incompleteData = data;
return;
}
try {
const parsedData = JSON.parse(data) as ChatMessage;
updateStreamingHistory(parsedData);
} catch (e) {
console.error("Error parsing data string", e);
}
});
await handleStreamRecursively();
};
await handleStreamRecursively();
};
return {
handleStream,
};
};