@donkeylabs/adapter-sveltekit 1.1.3 → 1.1.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/vite.ts +34 -6
package/package.json
CHANGED
package/src/vite.ts
CHANGED
|
@@ -138,12 +138,20 @@ export function donkeylabsDev(options: DevPluginOptions = {}): Plugin {
|
|
|
138
138
|
|
|
139
139
|
// Stream SSE data
|
|
140
140
|
const reader = response.body?.getReader();
|
|
141
|
+
let sseClosed = false;
|
|
142
|
+
|
|
143
|
+
req.on("close", () => {
|
|
144
|
+
sseClosed = true;
|
|
145
|
+
reader?.cancel().catch(() => {});
|
|
146
|
+
appServer.getCore().sse.removeClient(client.id);
|
|
147
|
+
});
|
|
148
|
+
|
|
141
149
|
if (reader) {
|
|
142
150
|
const pump = async () => {
|
|
143
151
|
try {
|
|
144
|
-
while (
|
|
152
|
+
while (!sseClosed) {
|
|
145
153
|
const { done, value } = await reader.read();
|
|
146
|
-
if (done) break;
|
|
154
|
+
if (done || sseClosed) break;
|
|
147
155
|
res.write(value);
|
|
148
156
|
}
|
|
149
157
|
} catch {
|
|
@@ -153,10 +161,6 @@ export function donkeylabsDev(options: DevPluginOptions = {}): Plugin {
|
|
|
153
161
|
pump();
|
|
154
162
|
}
|
|
155
163
|
|
|
156
|
-
req.on("close", () => {
|
|
157
|
-
appServer.getCore().sse.removeClient(client.id);
|
|
158
|
-
});
|
|
159
|
-
|
|
160
164
|
return; // Don't call next()
|
|
161
165
|
}
|
|
162
166
|
|
|
@@ -376,6 +380,8 @@ export function donkeylabsDev(options: DevPluginOptions = {}): Plugin {
|
|
|
376
380
|
if (!isApiRoute) return next();
|
|
377
381
|
|
|
378
382
|
waitForBackend.then(() => {
|
|
383
|
+
let proxyAborted = false;
|
|
384
|
+
|
|
379
385
|
const proxyReq = http.request(
|
|
380
386
|
{
|
|
381
387
|
hostname: "localhost",
|
|
@@ -385,17 +391,39 @@ export function donkeylabsDev(options: DevPluginOptions = {}): Plugin {
|
|
|
385
391
|
headers: { ...req.headers, host: `localhost:${backendPort}` },
|
|
386
392
|
},
|
|
387
393
|
(proxyRes) => {
|
|
394
|
+
if (proxyAborted) return;
|
|
395
|
+
|
|
388
396
|
res.setHeader("Access-Control-Allow-Origin", "*");
|
|
389
397
|
res.statusCode = proxyRes.statusCode || 200;
|
|
390
398
|
for (const [k, v] of Object.entries(proxyRes.headers)) {
|
|
391
399
|
if (v) res.setHeader(k, v);
|
|
392
400
|
}
|
|
401
|
+
|
|
402
|
+
// Flush headers for streaming responses
|
|
403
|
+
if (typeof res.flushHeaders === "function") {
|
|
404
|
+
res.flushHeaders();
|
|
405
|
+
}
|
|
406
|
+
|
|
393
407
|
// Stream response back (works for binary/streaming responses)
|
|
394
408
|
proxyRes.pipe(res);
|
|
409
|
+
|
|
410
|
+
// Clean up on proxy response end
|
|
411
|
+
proxyRes.on("end", () => {
|
|
412
|
+
if (!proxyAborted) res.end();
|
|
413
|
+
});
|
|
395
414
|
}
|
|
396
415
|
);
|
|
397
416
|
|
|
417
|
+
// Handle client disconnect - abort proxy request
|
|
418
|
+
req.on("close", () => {
|
|
419
|
+
if (!proxyAborted) {
|
|
420
|
+
proxyAborted = true;
|
|
421
|
+
proxyReq.destroy();
|
|
422
|
+
}
|
|
423
|
+
});
|
|
424
|
+
|
|
398
425
|
proxyReq.on("error", (err) => {
|
|
426
|
+
if (proxyAborted) return; // Ignore errors after abort
|
|
399
427
|
console.error(`[donkeylabs-dev] Proxy error:`, err.message);
|
|
400
428
|
res.statusCode = 502;
|
|
401
429
|
res.end(JSON.stringify({ error: "Backend unavailable" }));
|