@donkeylabs/adapter-sveltekit 1.1.1 → 1.1.3
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/generator/index.ts +4 -4
- package/src/vite.ts +26 -7
package/package.json
CHANGED
package/src/generator/index.ts
CHANGED
|
@@ -197,16 +197,16 @@ function generateTypedSvelteKitClient(routes: RouteInfo[]): string {
|
|
|
197
197
|
const inputType = `Routes.${pascalNs}.${pascalRoute}.Input`;
|
|
198
198
|
const fullRouteName = commonPrefix ? `${commonPrefix}.${r.name}` : r.name;
|
|
199
199
|
// Stream routes provide three methods:
|
|
200
|
-
// - fetch(input): POST request (programmatic)
|
|
200
|
+
// - fetch(input, options?): POST request (programmatic)
|
|
201
201
|
// - url(input): GET URL for browser (video src, img src, download links)
|
|
202
|
-
// - get(input): GET fetch request
|
|
202
|
+
// - get(input, options?): GET fetch request
|
|
203
203
|
return ` ${methodName}: {
|
|
204
204
|
/** POST request with JSON body (programmatic) */
|
|
205
|
-
fetch: (input: ${inputType}): Promise<Response> => this.streamRequest("${fullRouteName}", input),
|
|
205
|
+
fetch: (input: ${inputType}, options?: RequestOptions): Promise<Response> => this.streamRequest("${fullRouteName}", input, options),
|
|
206
206
|
/** GET URL for browser src attributes (video, img, download links) */
|
|
207
207
|
url: (input: ${inputType}): string => this.streamUrl("${fullRouteName}", input),
|
|
208
208
|
/** GET request with query params */
|
|
209
|
-
get: (input: ${inputType}): Promise<Response> => this.streamGet("${fullRouteName}", input),
|
|
209
|
+
get: (input: ${inputType}, options?: RequestOptions): Promise<Response> => this.streamGet("${fullRouteName}", input, options),
|
|
210
210
|
}`;
|
|
211
211
|
});
|
|
212
212
|
|
package/src/vite.ts
CHANGED
|
@@ -218,24 +218,43 @@ export function donkeylabsDev(options: DevPluginOptions = {}): Plugin {
|
|
|
218
218
|
res.setHeader(key, value);
|
|
219
219
|
}
|
|
220
220
|
|
|
221
|
-
//
|
|
221
|
+
// Flush headers immediately for streaming responses
|
|
222
|
+
if (typeof res.flushHeaders === "function") {
|
|
223
|
+
res.flushHeaders();
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
// Handle body streaming (non-blocking for continuous streams like MJPEG)
|
|
222
227
|
if (response.body) {
|
|
223
228
|
const reader = response.body.getReader();
|
|
229
|
+
let closed = false;
|
|
230
|
+
|
|
231
|
+
// Handle client disconnect
|
|
232
|
+
req.on("close", () => {
|
|
233
|
+
closed = true;
|
|
234
|
+
reader.cancel().catch(() => {});
|
|
235
|
+
});
|
|
236
|
+
|
|
237
|
+
// Pump without awaiting - allows continuous streams
|
|
224
238
|
const pump = async () => {
|
|
225
239
|
try {
|
|
226
|
-
while (
|
|
240
|
+
while (!closed) {
|
|
227
241
|
const { done, value } = await reader.read();
|
|
228
|
-
if (done) {
|
|
229
|
-
res.end();
|
|
242
|
+
if (done || closed) {
|
|
243
|
+
if (!closed) res.end();
|
|
230
244
|
break;
|
|
231
245
|
}
|
|
232
|
-
|
|
246
|
+
// Write and check if client is still connected
|
|
247
|
+
const canContinue = res.write(value);
|
|
248
|
+
if (!canContinue && !closed) {
|
|
249
|
+
// Backpressure - wait for drain
|
|
250
|
+
await new Promise<void>(resolve => res.once("drain", resolve));
|
|
251
|
+
}
|
|
233
252
|
}
|
|
234
253
|
} catch {
|
|
235
|
-
res.end();
|
|
254
|
+
if (!closed) res.end();
|
|
236
255
|
}
|
|
237
256
|
};
|
|
238
|
-
|
|
257
|
+
pump(); // Don't await - let it run in background
|
|
239
258
|
} else {
|
|
240
259
|
res.end();
|
|
241
260
|
}
|