mirror of
https://gitee.com/wanwujie/deer-flow
synced 2026-04-21 13:24:44 +08:00
chore: merge with web UI project
This commit is contained in:
4
web/src/core/sse/StreamEvent.ts
Normal file
4
web/src/core/sse/StreamEvent.ts
Normal file
@@ -0,0 +1,4 @@
|
||||
export interface StreamEvent {
|
||||
type: string;
|
||||
data: object;
|
||||
}
|
||||
70
web/src/core/sse/fetch-stream.ts
Normal file
70
web/src/core/sse/fetch-stream.ts
Normal file
@@ -0,0 +1,70 @@
|
||||
import { type StreamEvent } from "./StreamEvent";
|
||||
|
||||
export async function* fetchStream<T extends StreamEvent>(
|
||||
url: string,
|
||||
init: RequestInit,
|
||||
): AsyncIterable<T> {
|
||||
const response = await fetch(url, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
"Cache-Control": "no-cache",
|
||||
},
|
||||
...init,
|
||||
});
|
||||
if (response.status !== 200) {
|
||||
throw new Error(`Failed to fetch from ${url}: ${response.status}`);
|
||||
}
|
||||
// Read from response body, event by event. An event always ends with a '\n\n'.
|
||||
const reader = response.body
|
||||
?.pipeThrough(new TextDecoderStream())
|
||||
.getReader();
|
||||
if (!reader) {
|
||||
throw new Error("Response body is not readable");
|
||||
}
|
||||
let buffer = "";
|
||||
while (true) {
|
||||
const { done, value } = await reader.read();
|
||||
if (done) {
|
||||
break;
|
||||
}
|
||||
buffer += value;
|
||||
while (true) {
|
||||
const index = buffer.indexOf("\n\n");
|
||||
if (index === -1) {
|
||||
break;
|
||||
}
|
||||
const chunk = buffer.slice(0, index);
|
||||
buffer = buffer.slice(index + 2);
|
||||
const event = parseEvent<T>(chunk);
|
||||
if (event) {
|
||||
yield event;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function parseEvent<T extends StreamEvent>(chunk: string) {
|
||||
let resultType = "message";
|
||||
let resultData: object | null = null;
|
||||
for (const line of chunk.split("\n")) {
|
||||
const pos = line.indexOf(": ");
|
||||
if (pos === -1) {
|
||||
continue;
|
||||
}
|
||||
const key = line.slice(0, pos);
|
||||
const value = line.slice(pos + 2);
|
||||
if (key === "event") {
|
||||
resultType = value;
|
||||
} else if (key === "data") {
|
||||
resultData = JSON.parse(value);
|
||||
}
|
||||
}
|
||||
if (resultType === "message" && resultData === null) {
|
||||
return undefined;
|
||||
}
|
||||
return {
|
||||
type: resultType,
|
||||
data: resultData,
|
||||
} as T;
|
||||
}
|
||||
2
web/src/core/sse/index.ts
Normal file
2
web/src/core/sse/index.ts
Normal file
@@ -0,0 +1,2 @@
|
||||
export * from "./fetch-stream";
|
||||
export * from "./StreamEvent";
|
||||
Reference in New Issue
Block a user