Skip to content

Commit 1b8a03d

Browse files
committed
chore: use custom WritableStream to support Edge on Windows.
1 parent dad1696 commit 1b8a03d

File tree

2 files changed

+43
-26
lines changed

2 files changed

+43
-26
lines changed

api/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
"description": "The API for a personal finance assistant designed to help you with financial tasks and queries.",
55
"main": "src/functions/assistant.js",
66
"scripts": {
7-
"start": "func start --cors \"*\"",
7+
"start": "func start --cors \"*\" --verbose",
88
"test": "echo \"No tests yet...\""
99
},
1010
"dependencies": {

src/script.js

Lines changed: 42 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
let aborter = new AbortController();
2+
let autoAbortTimeout = null;
23

34
const outputRef = document.querySelector("#outputRef");
45
const loadingRef = document.querySelector("#loadingRef");
@@ -27,47 +28,63 @@ submitQueryRef
2728
cancelQueryRef.classList.remove("hidden");
2829
submitQueryRef.classList.add("hidden");
2930

30-
const stream = await submitQuery(value);
31-
loadingRef.classList.add("hidden");
31+
autoTimeout();
32+
submitQuery(value, insertText);
33+
}
34+
});
3235

33-
outputRef.innerHTML = "";
34-
outputRef.classList.remove("hidden");
36+
function autoTimeout() {
37+
autoAbortTimeout = setTimeout(() => {
38+
cancelQueryRef.click();
3539

36-
for await (const chunk of stream) {
37-
if (aborter.signal.aborted) throw signal.reason;
38-
insertText(chunk)();
39-
}
40+
if (outputRef.innerHTML === "") {
41+
outputRef.innerHTML = "Your Assistant could not fetch data. Please try again!"
42+
}
4043

41-
cancelQueryRef.classList.add("hidden");
42-
submitQueryRef.classList.remove("hidden");
43-
loadingRef.classList.add("hidden");
44+
}, 30_000); // in case, cancel request after 30 of timeout
4445

45-
if (outputRef.innerHTML === "") {
46-
outputRef.innerHTML = "Your Assistant could not fetch data. Please try again!"
47-
}
48-
}
49-
});
46+
}
5047

51-
const insertText = chunk => () => {
48+
function insertText(chunk) {
5249
const delta = new TextDecoder().decode(chunk);
5350
outputRef.innerHTML += delta;
5451
outputRef.scrollTop = outputRef.scrollHeight; // scroll to bottom
5552
};
5653

5754

58-
async function submitQuery(userQuery) {
55+
function submitQuery(userQuery, cb) {
5956

6057
const { API_URL = 'http://localhost:7071' } = import.meta.env;
6158

62-
const response = await fetch(`${API_URL}/api/assistant`, {
59+
fetch(`${API_URL}/api/assistant`, {
6360
method: "POST",
6461
body: userQuery,
6562
signal: aborter.signal
66-
});
63+
}).then(response => response.body)
64+
.then(rs => processReadableStream(rs, cb));
65+
}
6766

68-
if (!response.ok) {
69-
console.log(response.statusText);
70-
}
67+
function processReadableStream(rs, cb) {
7168

72-
return response.body;
73-
}
69+
rs.pipeTo(new WritableStream({
70+
write(chunk, controller) {
71+
cb(chunk);
72+
},
73+
start(controller) {
74+
outputRef.innerHTML = "";
75+
loadingRef.classList.add("hidden");
76+
outputRef.classList.remove("hidden");
77+
clearTimeout(autoAbortTimeout); // cancel
78+
},
79+
close(controller) {
80+
cancelQueryRef.classList.add("hidden");
81+
submitQueryRef.classList.remove("hidden");
82+
loadingRef.classList.add("hidden");
83+
},
84+
abort(reason) {
85+
console.log(reason);
86+
},
87+
})).catch(console.error);
88+
89+
return rs;
90+
}

0 commit comments

Comments
 (0)