@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.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/src/vite.ts +34 -6
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@donkeylabs/adapter-sveltekit",
3
- "version": "1.1.3",
3
+ "version": "1.1.7",
4
4
  "type": "module",
5
5
  "description": "SvelteKit adapter for @donkeylabs/server - seamless SSR/browser API integration",
6
6
  "main": "./src/index.ts",
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 (true) {
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" }));