elysia 2.0.0-beta.14 → 2.0.0-beta.15

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 (90) hide show
  1. package/dist/adapter/bun/index.d.ts +4 -2
  2. package/dist/adapter/bun/index.js +35 -38
  3. package/dist/adapter/bun/index.mjs +35 -39
  4. package/dist/adapter/utils.js +16 -21
  5. package/dist/adapter/utils.mjs +16 -21
  6. package/dist/base.d.ts +8 -0
  7. package/dist/base.js +106 -59
  8. package/dist/base.mjs +107 -60
  9. package/dist/compile/aot.js +14 -21
  10. package/dist/compile/aot.mjs +14 -21
  11. package/dist/compile/handler/frozen-validator.js +51 -42
  12. package/dist/compile/handler/frozen-validator.mjs +51 -42
  13. package/dist/compile/handler/index.js +57 -50
  14. package/dist/compile/handler/index.mjs +57 -50
  15. package/dist/compile/handler/jit.js +36 -26
  16. package/dist/compile/handler/jit.mjs +37 -27
  17. package/dist/compile/handler/params.js +2 -0
  18. package/dist/compile/handler/params.mjs +3 -1
  19. package/dist/compile/handler/utils.d.ts +2 -2
  20. package/dist/compile/handler/utils.js +115 -111
  21. package/dist/compile/handler/utils.mjs +115 -113
  22. package/dist/context.d.ts +3 -1
  23. package/dist/context.js +2 -0
  24. package/dist/context.mjs +3 -1
  25. package/dist/cookie/config.js +6 -7
  26. package/dist/cookie/config.mjs +6 -7
  27. package/dist/error.d.ts +6 -3
  28. package/dist/error.js +26 -28
  29. package/dist/error.mjs +26 -28
  30. package/dist/handler/fetch.js +2 -1
  31. package/dist/handler/fetch.mjs +3 -2
  32. package/dist/handler/utils.d.ts +3 -1
  33. package/dist/handler/utils.js +19 -1
  34. package/dist/handler/utils.mjs +17 -1
  35. package/dist/index.d.ts +3 -3
  36. package/dist/package.js +1 -1
  37. package/dist/package.mjs +1 -1
  38. package/dist/plugin/aot/core.js +4 -0
  39. package/dist/plugin/aot/core.mjs +4 -0
  40. package/dist/sucrose.js +60 -59
  41. package/dist/sucrose.mjs +60 -59
  42. package/dist/trace.js +6 -9
  43. package/dist/trace.mjs +6 -9
  44. package/dist/type/coerce-plan.js +41 -36
  45. package/dist/type/coerce-plan.mjs +41 -36
  46. package/dist/type/coerce.d.ts +1 -1
  47. package/dist/type/constants.d.ts +1 -1
  48. package/dist/type/elysia/cookie.js +8 -17
  49. package/dist/type/elysia/cookie.mjs +8 -17
  50. package/dist/type/elysia/date.js +6 -7
  51. package/dist/type/elysia/date.mjs +6 -7
  52. package/dist/type/elysia/numeric.js +8 -9
  53. package/dist/type/elysia/numeric.mjs +8 -9
  54. package/dist/type/elysia/problem.d.ts +20 -0
  55. package/dist/type/elysia/problem.js +25 -0
  56. package/dist/type/elysia/problem.mjs +24 -0
  57. package/dist/type/exports.d.ts +3 -2
  58. package/dist/type/exports.js +2 -0
  59. package/dist/type/exports.mjs +2 -1
  60. package/dist/type/index.js +2 -0
  61. package/dist/type/index.mjs +2 -0
  62. package/dist/type/validator/clean-safe.d.ts +1 -2
  63. package/dist/type/validator/clean-safe.js +0 -2
  64. package/dist/type/validator/clean-safe.mjs +1 -2
  65. package/dist/type/validator/custom-error.js +37 -26
  66. package/dist/type/validator/custom-error.mjs +37 -26
  67. package/dist/type/validator/default-precompute.js +24 -26
  68. package/dist/type/validator/default-precompute.mjs +24 -26
  69. package/dist/type/validator/exact-mirror.js +6 -8
  70. package/dist/type/validator/exact-mirror.mjs +6 -8
  71. package/dist/type/validator/index.js +64 -66
  72. package/dist/type/validator/index.mjs +65 -67
  73. package/dist/type/validator/validator-cache.d.ts +2 -2
  74. package/dist/type/validator/validator-cache.js +7 -10
  75. package/dist/type/validator/validator-cache.mjs +6 -9
  76. package/dist/types.d.ts +2 -1
  77. package/dist/universal/file.js +2 -6
  78. package/dist/universal/file.mjs +2 -6
  79. package/dist/utils.d.ts +10 -2
  80. package/dist/utils.js +85 -47
  81. package/dist/utils.mjs +82 -48
  82. package/dist/validator/index.js +14 -18
  83. package/dist/validator/index.mjs +14 -18
  84. package/dist/ws/context.js +9 -11
  85. package/dist/ws/context.mjs +9 -11
  86. package/dist/ws/parser.js +23 -20
  87. package/dist/ws/parser.mjs +23 -20
  88. package/dist/ws/route.js +76 -87
  89. package/dist/ws/route.mjs +76 -87
  90. package/package.json +5 -2
@@ -1,7 +1,9 @@
1
+ import { BunHTMLBundlelike } from "../../types.js";
1
2
  import { AnyElysia } from "../../base.js";
2
3
  import { ElysiaAdapterOptions } from "../types.js";
3
4
  //#region src/adapter/bun/index.d.ts
4
- declare function collectStaticRoutes(app: AnyElysia): Record<string, Record<string, Response>> | undefined;
5
+ declare const isHTMLBundle: (value: unknown) => value is BunHTMLBundlelike;
6
+ declare function collectStaticRoutes(app: AnyElysia): Record<string, Record<string, Response | BunHTMLBundlelike>> | undefined;
5
7
  declare const BunAdapter: ElysiaAdapterOptions<void>;
6
8
  //#endregion
7
- export { BunAdapter, collectStaticRoutes };
9
+ export { BunAdapter, collectStaticRoutes, isHTMLBundle };
@@ -21,29 +21,11 @@ const unavailableFetch = () => new Response(null, {
21
21
  headers: { connection: "close" },
22
22
  status: 503
23
23
  });
24
- function reloadServer(server, serve) {
25
- try {
26
- server.reload(serve);
27
- } catch (error) {
28
- if (!serve.routes) throw error;
29
- delete serve.routes;
30
- console.warn("[Elysia] Native static promotion was skipped:", error);
31
- try {
32
- server.reload(serve);
33
- } catch (fallbackError) {
34
- console.error("[Elysia] Failed to reload Bun server:", fallbackError);
35
- throw fallbackError;
36
- }
37
- }
38
- }
39
24
  function releaseLifecycle(app, ext, createdExt, stop, registerCleanup) {
40
25
  if (ext.stop === stop) delete ext.stop;
41
26
  if (ext.cleanupEpoch === registerCleanup) delete ext.cleanupEpoch;
42
27
  if (createdExt && app["~ext"] === ext && !Object.keys(ext).length) app["~ext"] = void 0;
43
28
  }
44
- function clearAppServer(app, server) {
45
- if (app.server === server) app.server = void 0;
46
- }
47
29
  async function waitForServerRequests(server, abandoned) {
48
30
  while (server.pendingRequests && !abandoned()) await Bun.sleep(1);
49
31
  }
@@ -68,17 +50,6 @@ async function settleServerWebSockets(lifecycle, errors) {
68
50
  } while (lifecycle.sockets.size);
69
51
  return true;
70
52
  }
71
- const closeServerIdle = (server, errors) => {
72
- const close = server.closeIdleConnections;
73
- if (!close) return true;
74
- try {
75
- close.call(server);
76
- return true;
77
- } catch (error) {
78
- errors.push(error);
79
- return false;
80
- }
81
- };
82
53
  /**
83
54
  * ! This may looks like it would cause race condition, but it is not
84
55
  * Bun is single-threaded and synchronous, so the `finally` block will
@@ -97,12 +68,12 @@ const withOrigin = (fetch) => (request, server) => {
97
68
  }
98
69
  };
99
70
  const isNativeStaticMethod = (method) => method === "GET" || method === "POST" || method === "PUT" || method === "DELETE" || method === "PATCH" || method === "HEAD" || method === "OPTIONS";
71
+ const isHTMLBundle = (value) => typeof value === "object" && value !== null && typeof value.index === "string";
100
72
  function collectStaticRoutes(app) {
101
- if (app["~config"]?.nativeStaticResponse === false) return;
102
73
  app.fetch;
103
74
  const frozenRoot = require_generation.frozenRootOf(app);
104
75
  const fetchLevelHook = require_utils.flattenChain(frozenRoot["~hookChain"]);
105
- if (fetchLevelHook?.request?.length || fetchLevelHook?.trace?.length || frozenRoot["~ext"]?.hoc?.length) return;
76
+ const promoteResponses = app["~config"]?.nativeStaticResponse !== false && !fetchLevelHook?.request?.length && !fetchLevelHook?.trace?.length && !frozenRoot["~ext"]?.hoc?.length;
106
77
  const table = app["~generation"]?.routeTable ?? app["~routeTable"];
107
78
  const length = table?.length ?? 0;
108
79
  if (!table || !length) return;
@@ -111,7 +82,7 @@ function collectStaticRoutes(app) {
111
82
  for (let i = 0; i < length; i++) {
112
83
  if (!isNativeStaticMethod(methods[i]) || (flags[i] & require_route_table.RouteFlag.Dynamic) !== 0) continue;
113
84
  const h = handlers[i];
114
- if (typeof h !== "function" && !(h instanceof Error) && !(h instanceof Promise)) {
85
+ if (isHTMLBundle(h) || promoteResponses && typeof h !== "function" && !(h instanceof Error) && !(h instanceof Promise)) {
115
86
  hasCandidate = true;
116
87
  break;
117
88
  }
@@ -146,8 +117,10 @@ function collectStaticRoutes(app) {
146
117
  const path = paths[i];
147
118
  if (pathsByMethod.get(path) !== i) continue;
148
119
  const h = handlers[i];
149
- if (typeof h === "function" || h instanceof Error || h instanceof Promise) continue;
150
- const value = require_compile_handler_index.buildNativeStaticResponse(require_route_table.routeRow(table, i), app);
120
+ let value;
121
+ if (isHTMLBundle(h)) value = h;
122
+ else if (!promoteResponses || typeof h === "function" || h instanceof Error || h instanceof Promise) continue;
123
+ else value = require_compile_handler_index.buildNativeStaticResponse(require_route_table.routeRow(table, i), app);
151
124
  if (!value) continue;
152
125
  const needsEncode = (routeFlags & require_route_table.RouteFlag.Encode) !== 0;
153
126
  add(method, path, value, needsEncode);
@@ -329,7 +302,13 @@ const BunAdapter = require_adapter_index.createAdapter({
329
302
  }
330
303
  let idleClosed = true;
331
304
  if (idleRequired) {
332
- idleClosed = closeServerIdle(server, errors);
305
+ const closeIdle = server.closeIdleConnections;
306
+ if (closeIdle) try {
307
+ closeIdle.call(server);
308
+ } catch (error) {
309
+ errors.push(error);
310
+ idleClosed = false;
311
+ }
333
312
  if (idleClosed && !gateFailure) idleRequired = false;
334
313
  }
335
314
  const safe = socketsSettled && stopped && idleClosed && (!gateFailure || forceDone);
@@ -368,7 +347,7 @@ const BunAdapter = require_adapter_index.createAdapter({
368
347
  }
369
348
  cancelled = true;
370
349
  requestReady.resolve();
371
- clearAppServer(app, server);
350
+ if (app.server === server) app.server = void 0;
372
351
  let outcome;
373
352
  if (shutdownAttempt) {
374
353
  if (closeActiveConnections === true && !forceDone) {
@@ -423,6 +402,11 @@ const BunAdapter = require_adapter_index.createAdapter({
423
402
  (cleanupFailures ??= []).push(error);
424
403
  }
425
404
  }
405
+ try {
406
+ await require_utils.disposeDecorators(app);
407
+ } catch (error) {
408
+ (cleanupFailures ??= []).push(error);
409
+ }
426
410
  }
427
411
  cleanupCompleted = true;
428
412
  epochCleanup.length = 0;
@@ -457,7 +441,19 @@ const BunAdapter = require_adapter_index.createAdapter({
457
441
  published = true;
458
442
  if (built.websocket) serve.websocket = built.websocket;
459
443
  if (built.routes) serve.routes = built.routes;
460
- reloadServer(server, serve);
444
+ try {
445
+ server.reload(serve);
446
+ } catch (error) {
447
+ if (!serve.routes) throw error;
448
+ delete serve.routes;
449
+ console.warn("[Elysia] Native static promotion was skipped:", error);
450
+ try {
451
+ server.reload(serve);
452
+ } catch (fallbackError) {
453
+ console.error("[Elysia] Failed to reload Bun server:", fallbackError);
454
+ throw fallbackError;
455
+ }
456
+ }
461
457
  if (callback) callback(server);
462
458
  } catch (error) {
463
459
  startupFailure ??= { error };
@@ -490,4 +486,5 @@ const BunAdapter = require_adapter_index.createAdapter({
490
486
 
491
487
  //#endregion
492
488
  exports.BunAdapter = BunAdapter;
493
- exports.collectStaticRoutes = collectStaticRoutes;
489
+ exports.collectStaticRoutes = collectStaticRoutes;
490
+ exports.isHTMLBundle = isHTMLBundle;
@@ -1,5 +1,5 @@
1
1
  import { createAdapter } from "../index.mjs";
2
- import { flattenChain, getLoosePath, isSocketQuiet, nullObject, throwLifecycleErrors } from "../../utils.mjs";
2
+ import { disposeDecorators, flattenChain, getLoosePath, isSocketQuiet, nullObject, throwLifecycleErrors } from "../../utils.mjs";
3
3
  import { WebStandardAdapter } from "../web-standard/index.mjs";
4
4
  import { frozenRootOf, resolvedWsOf } from "../../generation.mjs";
5
5
  import { origin } from "../origin.mjs";
@@ -20,29 +20,11 @@ const unavailableFetch = () => new Response(null, {
20
20
  headers: { connection: "close" },
21
21
  status: 503
22
22
  });
23
- function reloadServer(server, serve) {
24
- try {
25
- server.reload(serve);
26
- } catch (error) {
27
- if (!serve.routes) throw error;
28
- delete serve.routes;
29
- console.warn("[Elysia] Native static promotion was skipped:", error);
30
- try {
31
- server.reload(serve);
32
- } catch (fallbackError) {
33
- console.error("[Elysia] Failed to reload Bun server:", fallbackError);
34
- throw fallbackError;
35
- }
36
- }
37
- }
38
23
  function releaseLifecycle(app, ext, createdExt, stop, registerCleanup) {
39
24
  if (ext.stop === stop) delete ext.stop;
40
25
  if (ext.cleanupEpoch === registerCleanup) delete ext.cleanupEpoch;
41
26
  if (createdExt && app["~ext"] === ext && !Object.keys(ext).length) app["~ext"] = void 0;
42
27
  }
43
- function clearAppServer(app, server) {
44
- if (app.server === server) app.server = void 0;
45
- }
46
28
  async function waitForServerRequests(server, abandoned) {
47
29
  while (server.pendingRequests && !abandoned()) await Bun.sleep(1);
48
30
  }
@@ -67,17 +49,6 @@ async function settleServerWebSockets(lifecycle, errors) {
67
49
  } while (lifecycle.sockets.size);
68
50
  return true;
69
51
  }
70
- const closeServerIdle = (server, errors) => {
71
- const close = server.closeIdleConnections;
72
- if (!close) return true;
73
- try {
74
- close.call(server);
75
- return true;
76
- } catch (error) {
77
- errors.push(error);
78
- return false;
79
- }
80
- };
81
52
  /**
82
53
  * ! This may looks like it would cause race condition, but it is not
83
54
  * Bun is single-threaded and synchronous, so the `finally` block will
@@ -96,12 +67,12 @@ const withOrigin = (fetch) => (request, server) => {
96
67
  }
97
68
  };
98
69
  const isNativeStaticMethod = (method) => method === "GET" || method === "POST" || method === "PUT" || method === "DELETE" || method === "PATCH" || method === "HEAD" || method === "OPTIONS";
70
+ const isHTMLBundle = (value) => typeof value === "object" && value !== null && typeof value.index === "string";
99
71
  function collectStaticRoutes(app) {
100
- if (app["~config"]?.nativeStaticResponse === false) return;
101
72
  app.fetch;
102
73
  const frozenRoot = frozenRootOf(app);
103
74
  const fetchLevelHook = flattenChain(frozenRoot["~hookChain"]);
104
- if (fetchLevelHook?.request?.length || fetchLevelHook?.trace?.length || frozenRoot["~ext"]?.hoc?.length) return;
75
+ const promoteResponses = app["~config"]?.nativeStaticResponse !== false && !fetchLevelHook?.request?.length && !fetchLevelHook?.trace?.length && !frozenRoot["~ext"]?.hoc?.length;
105
76
  const table = app["~generation"]?.routeTable ?? app["~routeTable"];
106
77
  const length = table?.length ?? 0;
107
78
  if (!table || !length) return;
@@ -110,7 +81,7 @@ function collectStaticRoutes(app) {
110
81
  for (let i = 0; i < length; i++) {
111
82
  if (!isNativeStaticMethod(methods[i]) || (flags[i] & RouteFlag.Dynamic) !== 0) continue;
112
83
  const h = handlers[i];
113
- if (typeof h !== "function" && !(h instanceof Error) && !(h instanceof Promise)) {
84
+ if (isHTMLBundle(h) || promoteResponses && typeof h !== "function" && !(h instanceof Error) && !(h instanceof Promise)) {
114
85
  hasCandidate = true;
115
86
  break;
116
87
  }
@@ -145,8 +116,10 @@ function collectStaticRoutes(app) {
145
116
  const path = paths[i];
146
117
  if (pathsByMethod.get(path) !== i) continue;
147
118
  const h = handlers[i];
148
- if (typeof h === "function" || h instanceof Error || h instanceof Promise) continue;
149
- const value = buildNativeStaticResponse(routeRow(table, i), app);
119
+ let value;
120
+ if (isHTMLBundle(h)) value = h;
121
+ else if (!promoteResponses || typeof h === "function" || h instanceof Error || h instanceof Promise) continue;
122
+ else value = buildNativeStaticResponse(routeRow(table, i), app);
150
123
  if (!value) continue;
151
124
  const needsEncode = (routeFlags & RouteFlag.Encode) !== 0;
152
125
  add(method, path, value, needsEncode);
@@ -328,7 +301,13 @@ const BunAdapter = createAdapter({
328
301
  }
329
302
  let idleClosed = true;
330
303
  if (idleRequired) {
331
- idleClosed = closeServerIdle(server, errors);
304
+ const closeIdle = server.closeIdleConnections;
305
+ if (closeIdle) try {
306
+ closeIdle.call(server);
307
+ } catch (error) {
308
+ errors.push(error);
309
+ idleClosed = false;
310
+ }
332
311
  if (idleClosed && !gateFailure) idleRequired = false;
333
312
  }
334
313
  const safe = socketsSettled && stopped && idleClosed && (!gateFailure || forceDone);
@@ -367,7 +346,7 @@ const BunAdapter = createAdapter({
367
346
  }
368
347
  cancelled = true;
369
348
  requestReady.resolve();
370
- clearAppServer(app, server);
349
+ if (app.server === server) app.server = void 0;
371
350
  let outcome;
372
351
  if (shutdownAttempt) {
373
352
  if (closeActiveConnections === true && !forceDone) {
@@ -422,6 +401,11 @@ const BunAdapter = createAdapter({
422
401
  (cleanupFailures ??= []).push(error);
423
402
  }
424
403
  }
404
+ try {
405
+ await disposeDecorators(app);
406
+ } catch (error) {
407
+ (cleanupFailures ??= []).push(error);
408
+ }
425
409
  }
426
410
  cleanupCompleted = true;
427
411
  epochCleanup.length = 0;
@@ -456,7 +440,19 @@ const BunAdapter = createAdapter({
456
440
  published = true;
457
441
  if (built.websocket) serve.websocket = built.websocket;
458
442
  if (built.routes) serve.routes = built.routes;
459
- reloadServer(server, serve);
443
+ try {
444
+ server.reload(serve);
445
+ } catch (error) {
446
+ if (!serve.routes) throw error;
447
+ delete serve.routes;
448
+ console.warn("[Elysia] Native static promotion was skipped:", error);
449
+ try {
450
+ server.reload(serve);
451
+ } catch (fallbackError) {
452
+ console.error("[Elysia] Failed to reload Bun server:", fallbackError);
453
+ throw fallbackError;
454
+ }
455
+ }
460
456
  if (callback) callback(server);
461
457
  } catch (error) {
462
458
  startupFailure ??= { error };
@@ -488,4 +484,4 @@ const BunAdapter = createAdapter({
488
484
  });
489
485
 
490
486
  //#endregion
491
- export { BunAdapter, collectStaticRoutes };
487
+ export { BunAdapter, collectStaticRoutes, isHTMLBundle };
@@ -124,25 +124,6 @@ function responseToSetHeaders(response, set) {
124
124
  if (set.headers["content-encoding"]) delete set.headers["content-encoding"];
125
125
  return set;
126
126
  }
127
- function enqueueBinaryChunk(controller, chunk) {
128
- if (chunk instanceof Blob) return chunk.arrayBuffer().then((buffer) => {
129
- controller.enqueue(new Uint8Array(buffer));
130
- return true;
131
- });
132
- if (chunk instanceof Uint8Array) {
133
- controller.enqueue(chunk);
134
- return true;
135
- }
136
- if (chunk instanceof ArrayBuffer) {
137
- controller.enqueue(new Uint8Array(chunk));
138
- return true;
139
- }
140
- if (ArrayBuffer.isView(chunk)) {
141
- controller.enqueue(new Uint8Array(chunk.buffer, chunk.byteOffset, chunk.byteLength));
142
- return true;
143
- }
144
- return false;
145
- }
146
127
  function createStreamHandler({ mapResponse, mapCompactResponse }) {
147
128
  return async (generator, set, request, skipFormat, owned = false) => {
148
129
  if (request === null) return void 0;
@@ -253,7 +234,21 @@ function createStreamHandler({ mapResponse, mapCompactResponse }) {
253
234
  controller.enqueue(encodeChunk(value.toSSE()));
254
235
  return;
255
236
  }
256
- const p = enqueueBinaryChunk(controller, value);
237
+ let p;
238
+ if (value instanceof Blob) p = value.arrayBuffer().then((buffer) => {
239
+ controller.enqueue(new Uint8Array(buffer));
240
+ return true;
241
+ });
242
+ else if (value instanceof Uint8Array) {
243
+ controller.enqueue(value);
244
+ p = true;
245
+ } else if (value instanceof ArrayBuffer) {
246
+ controller.enqueue(new Uint8Array(value));
247
+ p = true;
248
+ } else if (ArrayBuffer.isView(value)) {
249
+ controller.enqueue(new Uint8Array(value.buffer, value.byteOffset, value.byteLength));
250
+ p = true;
251
+ } else p = false;
257
252
  if (p !== false) return void await p;
258
253
  if (typeof value === "object") try {
259
254
  controller.enqueue(encodeChunk(format(JSON.stringify(value))));
@@ -540,7 +535,7 @@ function tee(source, branches = 2, cap = 64, capBytes = 1 << 22) {
540
535
  wakeAll();
541
536
  }
542
537
  })();
543
- const makeBranch = (me) => ({
538
+ const makeBranch = (me) => Object.assign(Object.create(null), {
544
539
  [Symbol.asyncIterator]() {
545
540
  return this;
546
541
  },
@@ -123,25 +123,6 @@ function responseToSetHeaders(response, set) {
123
123
  if (set.headers["content-encoding"]) delete set.headers["content-encoding"];
124
124
  return set;
125
125
  }
126
- function enqueueBinaryChunk(controller, chunk) {
127
- if (chunk instanceof Blob) return chunk.arrayBuffer().then((buffer) => {
128
- controller.enqueue(new Uint8Array(buffer));
129
- return true;
130
- });
131
- if (chunk instanceof Uint8Array) {
132
- controller.enqueue(chunk);
133
- return true;
134
- }
135
- if (chunk instanceof ArrayBuffer) {
136
- controller.enqueue(new Uint8Array(chunk));
137
- return true;
138
- }
139
- if (ArrayBuffer.isView(chunk)) {
140
- controller.enqueue(new Uint8Array(chunk.buffer, chunk.byteOffset, chunk.byteLength));
141
- return true;
142
- }
143
- return false;
144
- }
145
126
  function createStreamHandler({ mapResponse, mapCompactResponse }) {
146
127
  return async (generator, set, request, skipFormat, owned = false) => {
147
128
  if (request === null) return void 0;
@@ -252,7 +233,21 @@ function createStreamHandler({ mapResponse, mapCompactResponse }) {
252
233
  controller.enqueue(encodeChunk(value.toSSE()));
253
234
  return;
254
235
  }
255
- const p = enqueueBinaryChunk(controller, value);
236
+ let p;
237
+ if (value instanceof Blob) p = value.arrayBuffer().then((buffer) => {
238
+ controller.enqueue(new Uint8Array(buffer));
239
+ return true;
240
+ });
241
+ else if (value instanceof Uint8Array) {
242
+ controller.enqueue(value);
243
+ p = true;
244
+ } else if (value instanceof ArrayBuffer) {
245
+ controller.enqueue(new Uint8Array(value));
246
+ p = true;
247
+ } else if (ArrayBuffer.isView(value)) {
248
+ controller.enqueue(new Uint8Array(value.buffer, value.byteOffset, value.byteLength));
249
+ p = true;
250
+ } else p = false;
256
251
  if (p !== false) return void await p;
257
252
  if (typeof value === "object") try {
258
253
  controller.enqueue(encodeChunk(format(JSON.stringify(value))));
@@ -539,7 +534,7 @@ function tee(source, branches = 2, cap = 64, capBytes = 1 << 22) {
539
534
  wakeAll();
540
535
  }
541
536
  })();
542
- const makeBranch = (me) => ({
537
+ const makeBranch = (me) => Object.assign(Object.create(null), {
543
538
  [Symbol.asyncIterator]() {
544
539
  return this;
545
540
  },
package/dist/base.d.ts CHANGED
@@ -50,6 +50,14 @@ declare class Elysia<const in out BasePath extends string = '', const in out Sco
50
50
  hoc?: WrapFn<any>[];
51
51
  setup?: GracefulHandler<any>[];
52
52
  cleanup?: GracefulHandler<any>[];
53
+ /**
54
+ * Accepted `.decorate()` values implementing an explicit disposer, in
55
+ * registration order.
56
+ *
57
+ * Recorded at registration so the original reference survives a
58
+ * `.use()` clone, a same-name merge and a later override
59
+ */
60
+ disposable?: unknown[];
53
61
  cleanupEpoch?: (handler: GracefulHandler<any> | GracefulHandler<any>[]) => boolean;
54
62
  stop?: (closeActiveConnections?: boolean, failure?: {
55
63
  error: unknown;