From eaae1dda2716fde920b8a616fd6e89106a3e3316 Mon Sep 17 00:00:00 2001 From: Gabriel Luiz Freitas Almeida Date: Mon, 12 Jun 2023 09:31:01 -0300 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20feat(chatComponent):=20add=20SSE=20?= =?UTF-8?q?context=20to=20update=20data=20in=20real-time=20The=20handleBui?= =?UTF-8?q?ld=20function=20has=20been=20refactored=20to=20process=20data?= =?UTF-8?q?=20in=20chunks=20instead=20of=20waiting=20for=20the=20entire=20?= =?UTF-8?q?response=20to=20be=20received.=20This=20improves=20the=20perfor?= =?UTF-8?q?mance=20of=20the=20function=20and=20allows=20for=20real-time=20?= =?UTF-8?q?updates.=20The=20SSE=20context=20has=20been=20added=20to=20upda?= =?UTF-8?q?te=20the=20data=20in=20real-time=20as=20it=20is=20received.=20?= =?UTF-8?q?=F0=9F=94=A8=20refactor(chatComponent):=20refactor=20handleBuil?= =?UTF-8?q?d=20function=20to=20process=20data=20in=20chunks?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../chatComponent/buildTrigger/index.tsx | 74 +++++++++++++------ 1 file changed, 53 insertions(+), 21 deletions(-) diff --git a/src/frontend/src/components/chatComponent/buildTrigger/index.tsx b/src/frontend/src/components/chatComponent/buildTrigger/index.tsx index 4cfe74980..6ce343280 100644 --- a/src/frontend/src/components/chatComponent/buildTrigger/index.tsx +++ b/src/frontend/src/components/chatComponent/buildTrigger/index.tsx @@ -8,6 +8,8 @@ import ChatModal from "../../../modals/chatModal"; import { FlowType } from "../../../types/flow"; import { postBuild } from "../../../controllers/API"; import Loading from "../../../components/ui/loading"; +import { useSSE } from "../../../contexts/SSEContext"; +import axios from "axios"; export default function BuildTrigger({ open, @@ -22,36 +24,66 @@ export default function BuildTrigger({ }) { const [isBuilding, setIsBuilding] = useState(false); - function handleBuild(flow: FlowType) { - const minimumLoadingTime = 500; // in milliseconds - const startTime = Date.now(); + const { updateSSEData } = useSSE(); + function handleBuild(flow) { setIsBuilding(true); - postBuild(flow) - .then((res) => { - console.log(res); - setIsBuilt(true); - }) + // State to keep track of validity status of all chunks + let allChunksValid = true; + + const apiUrl = `/build/${flow.id}`; + + // Post data to the server + axios({ + method: "post", + url: apiUrl, + data: { data: flow }, + headers: { "Content-Type": "application/json" }, + onDownloadProgress: (progressEvent) => { + const { currentTarget } = progressEvent.event; + const { responseText } = currentTarget; + // responseText is a string with \n\n delimiters + + // Get only the new data since the last read + // by splitting the string and getting the one before the last \n\n + + const chunks = responseText.split("\n\n"); + + // Process each chunk + chunks.forEach((chunk: string) => { + if (chunk !== "") { + let valid = processChunk(chunk); + console.log("Valid: ", valid); + allChunksValid = allChunksValid && valid; + } + }); + }, + }) .catch((err) => { - console.log(err); - setIsBuilt(false); + console.error("Error:", err); }) .finally(() => { - const endTime = Date.now(); - const elapsedTime = endTime - startTime; - - if (elapsedTime < minimumLoadingTime) { - const remainingTime = minimumLoadingTime - elapsedTime; - setTimeout(() => { - setIsBuilding(false); - }, remainingTime); - } else { - setIsBuilding(false); - } + // Set isBuilt to the value of allChunksValid + setIsBuilt(allChunksValid); + setIsBuilding(false); }); } + function processChunk(chunk: string) { + // Process each chunk of data here + // Parse the chunk and update the context + let parsedData = { valid: false, id: null }; + try { + parsedData = JSON.parse(chunk.slice(6)); // Remove the "data: " part + updateSSEData({ [parsedData.id]: parsedData }); + } catch (err) { + console.log("Chunk is not valid JSON: ", chunk); + console.log("Error parsing chunk: ", err); + } + return parsedData.valid; + } + return (