elysia 2.0.0-beta.13 → 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 +28 -0
  7. package/dist/base.js +109 -59
  8. package/dist/base.mjs +110 -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 +4 -3
  77. package/dist/universal/file.js +2 -6
  78. package/dist/universal/file.mjs +2 -6
  79. package/dist/utils.d.ts +11 -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
@@ -10,7 +10,6 @@ const require_adapter_origin = require('../../adapter/origin.js');
10
10
  const require_compile_lexer = require('../lexer.js');
11
11
 
12
12
  //#region src/compile/handler/utils.ts
13
- const childName = (fn) => fn?.name && typeof fn.name === "string" ? fn.name : "anonymous";
14
13
  const noTrace = {
15
14
  begin: "",
16
15
  end: () => ""
@@ -51,7 +50,7 @@ function armEntryAbort(context) {
51
50
  if (context.request === require_adapter_origin.origin.request) return false;
52
51
  return (context["~sig"] = context.request.signal).aborted;
53
52
  }
54
- const trace = (report, fn) => report?.resolveChild(childName(fn)) ?? noTrace;
53
+ const trace = (report, fn) => report?.resolveChild(fn?.name && typeof fn.name === "string" ? fn.name : "anonymous") ?? noTrace;
55
54
  const toArray = (v) => Array.isArray(v) ? v : [v];
56
55
  const mapTransform = /* @__PURE__ */ map((i, fn, [isAsync, report, arm]) => {
57
56
  const t = trace(report, fn);
@@ -62,7 +61,20 @@ const deriveKeyCache = /* @__PURE__ */ new WeakMap();
62
61
  function extractDeriveKeys(fn) {
63
62
  const cached = deriveKeyCache.get(fn);
64
63
  if (cached !== void 0) return cached;
65
- const result = scanDeriveKeys(fn);
64
+ let src;
65
+ try {
66
+ src = Function.prototype.toString.call(fn);
67
+ } catch {
68
+ src = void 0;
69
+ }
70
+ let result;
71
+ if (src === void 0) result = null;
72
+ else if (src.includes("[native code]")) result = null;
73
+ else if (src.includes("...")) result = null;
74
+ else {
75
+ const objStart = findReturnedObjectStart(src);
76
+ result = objStart === -1 ? null : scanObjectLiteralKeys(src, objStart);
77
+ }
66
78
  deriveKeyCache.set(fn, result);
67
79
  return result;
68
80
  }
@@ -72,6 +84,7 @@ function replaceDeriveContext(context, derivative) {
72
84
  next.request = context.request;
73
85
  next["~sig"] = context["~sig"];
74
86
  next["~afterResponse"] = context["~afterResponse"];
87
+ next["~dispose"] = context["~dispose"];
75
88
  next.store = context.store;
76
89
  next.set = context.set;
77
90
  next.body = context.body;
@@ -91,21 +104,19 @@ function replaceDeriveContext(context, derivative) {
91
104
  next.redirect = context.redirect;
92
105
  return next;
93
106
  }
94
- function deriveModeQueues(entries) {
95
- if (!entries?.length) return;
96
- const queues = /* @__PURE__ */ new Map();
97
- for (let i = 0; i < entries.length; i++) {
98
- const entry = entries[i];
99
- const fn = require_utils.deriveEntryFn(entry);
100
- const queue = queues.get(fn);
101
- const mode = require_utils.isMapDeriveEntry(entry);
102
- if (queue) queue.push(mode);
103
- else queues.set(fn, [mode]);
104
- }
105
- return queues;
106
- }
107
107
  function deriveModes(hooks, entries) {
108
- const queues = deriveModeQueues(entries);
108
+ let queues;
109
+ if (entries?.length) {
110
+ queues = /* @__PURE__ */ new Map();
111
+ for (let i = 0; i < entries.length; i++) {
112
+ const entry = entries[i];
113
+ const fn = require_utils.deriveEntryFn(entry);
114
+ const queue = queues.get(fn);
115
+ const mode = require_utils.isMapDeriveEntry(entry);
116
+ if (queue) queue.push(mode);
117
+ else queues.set(fn, [mode]);
118
+ }
119
+ }
109
120
  if (!queues) return;
110
121
  let found = false;
111
122
  const modes = Array(hooks.length);
@@ -118,44 +129,8 @@ function deriveModes(hooks, entries) {
118
129
  }
119
130
  return found ? modes : void 0;
120
131
  }
121
- function scanDeriveKeys(fn) {
122
- let src;
123
- try {
124
- src = Function.prototype.toString.call(fn);
125
- } catch {
126
- return null;
127
- }
128
- if (src.includes("[native code]")) return null;
129
- if (src.includes("...")) return null;
130
- const objStart = findReturnedObjectStart(src);
131
- if (objStart === -1) return null;
132
- return scanObjectLiteralKeys(src, objStart);
133
- }
134
132
  function findReturnedObjectStart(src) {
135
- const arrow = topLevelArrowIndex(src);
136
- if (arrow !== -1) {
137
- let i = arrow + 2;
138
- while (i < src.length && require_compile_lexer.isSpace(src[i])) i++;
139
- if (src[i] === "(") {
140
- let j = i + 1;
141
- while (j < src.length && require_compile_lexer.isSpace(src[j])) j++;
142
- if (src[j] === "{") return j;
143
- return -1;
144
- }
145
- if (src[i] !== "{") return -1;
146
- }
147
- const { count: returns, firstIndex: idx } = scanReturns(src);
148
- if (returns !== 1) return -1;
149
- if (idx === -1) return -1;
150
- let i = idx + 6;
151
- while (i < src.length && require_compile_lexer.isSpace(src[i])) i++;
152
- while (i < src.length && src[i] === "(") {
153
- i++;
154
- while (i < src.length && require_compile_lexer.isSpace(src[i])) i++;
155
- }
156
- return src[i] === "{" ? i : -1;
157
- }
158
- function topLevelArrowIndex(src) {
133
+ let arrow = -1;
159
134
  let depth = 0;
160
135
  for (let i = 0; i < src.length;) {
161
136
  const ch = src[i];
@@ -165,17 +140,17 @@ function topLevelArrowIndex(src) {
165
140
  }
166
141
  if (ch === "/" && src[i + 1] === "/") {
167
142
  const nl = src.indexOf("\n", i);
168
- if (nl === -1) return -1;
143
+ if (nl === -1) break;
169
144
  i = nl + 1;
170
145
  continue;
171
146
  }
172
147
  if (ch === "/" && src[i + 1] === "*") {
173
148
  const end = src.indexOf("*/", i);
174
- if (end === -1) return -1;
149
+ if (end === -1) break;
175
150
  i = end + 2;
176
151
  continue;
177
152
  }
178
- if (depth === 0 && ch === "f" && src.startsWith("function", i) && !require_compile_lexer.isIdentChar(src[i - 1] ?? " ") && !require_compile_lexer.isIdentChar(src[i + 8] ?? " ")) return -1;
153
+ if (depth === 0 && ch === "f" && src.startsWith("function", i) && !require_compile_lexer.isIdentChar(src[i - 1] ?? " ") && !require_compile_lexer.isIdentChar(src[i + 8] ?? " ")) break;
179
154
  if (ch === "(" || ch === "[" || ch === "{") {
180
155
  depth++;
181
156
  i++;
@@ -186,14 +161,25 @@ function topLevelArrowIndex(src) {
186
161
  i++;
187
162
  continue;
188
163
  }
189
- if (depth === 0 && ch === "=" && src[i + 1] === ">") return i;
164
+ if (depth === 0 && ch === "=" && src[i + 1] === ">") {
165
+ arrow = i;
166
+ break;
167
+ }
190
168
  i++;
191
169
  }
192
- return -1;
193
- }
194
- function scanReturns(src) {
195
- let count = 0;
196
- let firstIndex = -1;
170
+ if (arrow !== -1) {
171
+ let i = arrow + 2;
172
+ while (i < src.length && require_compile_lexer.isSpace(src[i])) i++;
173
+ if (src[i] === "(") {
174
+ let j = i + 1;
175
+ while (j < src.length && require_compile_lexer.isSpace(src[j])) j++;
176
+ if (src[j] === "{") return j;
177
+ return -1;
178
+ }
179
+ if (src[i] !== "{") return -1;
180
+ }
181
+ let returns = 0;
182
+ let idx = -1;
197
183
  for (let i = 0; i < src.length;) {
198
184
  const ch = src[i];
199
185
  if (ch === "\"" || ch === "'" || ch === "`") {
@@ -213,17 +199,22 @@ function scanReturns(src) {
213
199
  continue;
214
200
  }
215
201
  if (ch === "r" && src.startsWith("return", i) && !require_compile_lexer.isIdentChar(src[i - 1] ?? " ") && !require_compile_lexer.isIdentChar(src[i + 6] ?? " ")) {
216
- if (firstIndex === -1) firstIndex = i;
217
- count++;
202
+ if (idx === -1) idx = i;
203
+ returns++;
218
204
  i += 6;
219
205
  continue;
220
206
  }
221
207
  i++;
222
208
  }
223
- return {
224
- count,
225
- firstIndex
226
- };
209
+ if (returns !== 1) return -1;
210
+ if (idx === -1) return -1;
211
+ let i = idx + 6;
212
+ while (i < src.length && require_compile_lexer.isSpace(src[i])) i++;
213
+ while (i < src.length && src[i] === "(") {
214
+ i++;
215
+ while (i < src.length && require_compile_lexer.isSpace(src[i])) i++;
216
+ }
217
+ return src[i] === "{" ? i : -1;
227
218
  }
228
219
  function scanObjectLiteralKeys(src, open) {
229
220
  const keys = [];
@@ -266,7 +257,56 @@ function scanObjectLiteralKeys(src, open) {
266
257
  if (src[j] !== ":") return null;
267
258
  keys.push(key);
268
259
  i = j + 1;
269
- i = skipValue(src, i);
260
+ let depth = 0;
261
+ let found = false;
262
+ while (i < src.length) {
263
+ const ch = src[i];
264
+ if (ch === "\"" || ch === "'" || ch === "`") {
265
+ i = require_compile_lexer.skipString(src, i);
266
+ continue;
267
+ }
268
+ if (ch === "/" && src[i + 1] === "/") {
269
+ const nl = src.indexOf("\n", i);
270
+ if (nl === -1) {
271
+ i = -1;
272
+ found = true;
273
+ break;
274
+ }
275
+ i = nl + 1;
276
+ continue;
277
+ }
278
+ if (ch === "/" && src[i + 1] === "*") {
279
+ const end = src.indexOf("*/", i);
280
+ if (end === -1) {
281
+ i = -1;
282
+ found = true;
283
+ break;
284
+ }
285
+ i = end + 2;
286
+ continue;
287
+ }
288
+ if (ch === "{" || ch === "(" || ch === "[") {
289
+ depth++;
290
+ i++;
291
+ continue;
292
+ }
293
+ if (ch === "}" || ch === ")" || ch === "]") {
294
+ if (depth === 0) {
295
+ if (ch !== "}") i = -1;
296
+ found = true;
297
+ break;
298
+ }
299
+ depth--;
300
+ i++;
301
+ continue;
302
+ }
303
+ if (ch === "," && depth === 0) {
304
+ found = true;
305
+ break;
306
+ }
307
+ i++;
308
+ }
309
+ if (!found) i = -1;
270
310
  if (i === -1) return null;
271
311
  expectKey = false;
272
312
  continue;
@@ -280,45 +320,6 @@ function scanObjectLiteralKeys(src, open) {
280
320
  }
281
321
  return null;
282
322
  }
283
- function skipValue(src, i) {
284
- let depth = 0;
285
- while (i < src.length) {
286
- const ch = src[i];
287
- if (ch === "\"" || ch === "'" || ch === "`") {
288
- i = require_compile_lexer.skipString(src, i);
289
- continue;
290
- }
291
- if (ch === "/" && src[i + 1] === "/") {
292
- const nl = src.indexOf("\n", i);
293
- if (nl === -1) return -1;
294
- i = nl + 1;
295
- continue;
296
- }
297
- if (ch === "/" && src[i + 1] === "*") {
298
- const end = src.indexOf("*/", i);
299
- if (end === -1) return -1;
300
- i = end + 2;
301
- continue;
302
- }
303
- if (ch === "{" || ch === "(" || ch === "[") {
304
- depth++;
305
- i++;
306
- continue;
307
- }
308
- if (ch === "}" || ch === ")" || ch === "]") {
309
- if (depth === 0) {
310
- if (ch === "}") return i;
311
- return -1;
312
- }
313
- depth--;
314
- i++;
315
- continue;
316
- }
317
- if (ch === "," && depth === 0) return i;
318
- i++;
319
- }
320
- return -1;
321
- }
322
323
  function mapBeforeHandle(_hooks, derive, link, isAsync, report, abortGuard, arm) {
323
324
  const hooks = toArray(_hooks);
324
325
  const modes = deriveModes(hooks, derive);
@@ -337,12 +338,13 @@ function mapBeforeHandle(_hooks, derive, link, isAsync, report, abortGuard, arm)
337
338
  code += awaitGuard(fn, isAsync, "tmp", arm);
338
339
  if (modes?.[i] !== void 0) {
339
340
  needsEs = true;
341
+ link(require_handler_utils.registerDeriveDisposable, "dsp");
340
342
  if (modes[i]) {
341
343
  link(replaceDeriveContext, "rdc");
342
- code += "if(tmp instanceof es)_r=tmp\nelse if(tmp){if(typeof tmp==='object'||typeof tmp==='function')c=rdc(c,tmp);tmp=undefined}\n";
344
+ code += "if(tmp instanceof es)_r=tmp\nelse if(tmp){if(typeof tmp==='object'||typeof tmp==='function'){const _pc=c;c=rdc(c,tmp);for(const _k of Object.keys(tmp))dsp(c,c[_k],_pc)}tmp=undefined}\n";
343
345
  } else {
344
346
  const keys = extractDeriveKeys(fn);
345
- const merge = keys && keys.length && !keys.includes("__proto__") ? keys.map((k) => `c[${JSON.stringify(k)}]=tmp[${JSON.stringify(k)}]`).join(";") : "Object.hasOwn(tmp,'__proto__')?Object.defineProperties(c,Object.getOwnPropertyDescriptors(tmp)):Object.assign(c,tmp)";
347
+ const merge = !!keys && !!keys.length && !keys.includes("__proto__") ? keys.map((k) => `_v=tmp[${JSON.stringify(k)}];dsp(c,_v);c[${JSON.stringify(k)}]=_v`).join(";") : "if(Object.hasOwn(tmp,'__proto__')){for(const _k of Object.keys(tmp))dsp(c,tmp[_k]);Object.defineProperties(c,Object.getOwnPropertyDescriptors(tmp))}else{_v=Object.assign({},tmp);for(const _k of Reflect.ownKeys(_v)){dsp(c,_v[_k]);c[_k]=_v[_k]}}";
346
348
  code += `if(tmp instanceof es)_r=tmp
347
349
  else if(tmp){${merge};tmp=undefined}\n`;
348
350
  }
@@ -515,6 +517,7 @@ exports.awaitGuard = awaitGuard;
515
517
  exports.cloneResponse = cloneResponse;
516
518
  exports.cloneStaticValue = cloneStaticValue;
517
519
  exports.deriveModes = deriveModes;
520
+ exports.drainDisposables = require_handler_utils.drainDisposables;
518
521
  exports.emptyResponse = require_handler_utils.emptyResponse;
519
522
  exports.getQueryParseChannels = getQueryParseChannels;
520
523
  exports.hasRequestBody = hasRequestBody;
@@ -524,6 +527,7 @@ exports.mapBeforeHandle = mapBeforeHandle;
524
527
  exports.mapError = mapError;
525
528
  exports.mapMapResponse = mapMapResponse;
526
529
  exports.mapTransform = mapTransform;
530
+ exports.registerDeriveDisposable = require_handler_utils.registerDeriveDisposable;
527
531
  exports.replaceDeriveContext = replaceDeriveContext;
528
532
  exports.runBeforeHandlePrefix = runBeforeHandlePrefix;
529
533
  exports.runBeforeHandlePrefixAsync = runBeforeHandlePrefixAsync;
@@ -3,13 +3,12 @@ import { ELYSIA_TYPES } from "../../type/constants.mjs";
3
3
  import { skipClone } from "../../adapter/skip-clone.mjs";
4
4
  import { ElysiaStatus } from "../../error.mjs";
5
5
  import { isAsyncFunction } from "../utils.mjs";
6
- import { emptyResponse } from "../../handler/utils.mjs";
6
+ import { drainDisposables, emptyResponse, registerDeriveDisposable } from "../../handler/utils.mjs";
7
7
  import { adoptErrorType } from "../../handler/error.mjs";
8
8
  import { origin } from "../../adapter/origin.mjs";
9
9
  import { isIdentChar, isSpace, skipString } from "../lexer.mjs";
10
10
 
11
11
  //#region src/compile/handler/utils.ts
12
- const childName = (fn) => fn?.name && typeof fn.name === "string" ? fn.name : "anonymous";
13
12
  const noTrace = {
14
13
  begin: "",
15
14
  end: () => ""
@@ -50,7 +49,7 @@ function armEntryAbort(context) {
50
49
  if (context.request === origin.request) return false;
51
50
  return (context["~sig"] = context.request.signal).aborted;
52
51
  }
53
- const trace = (report, fn) => report?.resolveChild(childName(fn)) ?? noTrace;
52
+ const trace = (report, fn) => report?.resolveChild(fn?.name && typeof fn.name === "string" ? fn.name : "anonymous") ?? noTrace;
54
53
  const toArray = (v) => Array.isArray(v) ? v : [v];
55
54
  const mapTransform = /* @__PURE__ */ map((i, fn, [isAsync, report, arm]) => {
56
55
  const t = trace(report, fn);
@@ -61,7 +60,20 @@ const deriveKeyCache = /* @__PURE__ */ new WeakMap();
61
60
  function extractDeriveKeys(fn) {
62
61
  const cached = deriveKeyCache.get(fn);
63
62
  if (cached !== void 0) return cached;
64
- const result = scanDeriveKeys(fn);
63
+ let src;
64
+ try {
65
+ src = Function.prototype.toString.call(fn);
66
+ } catch {
67
+ src = void 0;
68
+ }
69
+ let result;
70
+ if (src === void 0) result = null;
71
+ else if (src.includes("[native code]")) result = null;
72
+ else if (src.includes("...")) result = null;
73
+ else {
74
+ const objStart = findReturnedObjectStart(src);
75
+ result = objStart === -1 ? null : scanObjectLiteralKeys(src, objStart);
76
+ }
65
77
  deriveKeyCache.set(fn, result);
66
78
  return result;
67
79
  }
@@ -71,6 +83,7 @@ function replaceDeriveContext(context, derivative) {
71
83
  next.request = context.request;
72
84
  next["~sig"] = context["~sig"];
73
85
  next["~afterResponse"] = context["~afterResponse"];
86
+ next["~dispose"] = context["~dispose"];
74
87
  next.store = context.store;
75
88
  next.set = context.set;
76
89
  next.body = context.body;
@@ -90,21 +103,19 @@ function replaceDeriveContext(context, derivative) {
90
103
  next.redirect = context.redirect;
91
104
  return next;
92
105
  }
93
- function deriveModeQueues(entries) {
94
- if (!entries?.length) return;
95
- const queues = /* @__PURE__ */ new Map();
96
- for (let i = 0; i < entries.length; i++) {
97
- const entry = entries[i];
98
- const fn = deriveEntryFn(entry);
99
- const queue = queues.get(fn);
100
- const mode = isMapDeriveEntry(entry);
101
- if (queue) queue.push(mode);
102
- else queues.set(fn, [mode]);
103
- }
104
- return queues;
105
- }
106
106
  function deriveModes(hooks, entries) {
107
- const queues = deriveModeQueues(entries);
107
+ let queues;
108
+ if (entries?.length) {
109
+ queues = /* @__PURE__ */ new Map();
110
+ for (let i = 0; i < entries.length; i++) {
111
+ const entry = entries[i];
112
+ const fn = deriveEntryFn(entry);
113
+ const queue = queues.get(fn);
114
+ const mode = isMapDeriveEntry(entry);
115
+ if (queue) queue.push(mode);
116
+ else queues.set(fn, [mode]);
117
+ }
118
+ }
108
119
  if (!queues) return;
109
120
  let found = false;
110
121
  const modes = Array(hooks.length);
@@ -117,44 +128,8 @@ function deriveModes(hooks, entries) {
117
128
  }
118
129
  return found ? modes : void 0;
119
130
  }
120
- function scanDeriveKeys(fn) {
121
- let src;
122
- try {
123
- src = Function.prototype.toString.call(fn);
124
- } catch {
125
- return null;
126
- }
127
- if (src.includes("[native code]")) return null;
128
- if (src.includes("...")) return null;
129
- const objStart = findReturnedObjectStart(src);
130
- if (objStart === -1) return null;
131
- return scanObjectLiteralKeys(src, objStart);
132
- }
133
131
  function findReturnedObjectStart(src) {
134
- const arrow = topLevelArrowIndex(src);
135
- if (arrow !== -1) {
136
- let i = arrow + 2;
137
- while (i < src.length && isSpace(src[i])) i++;
138
- if (src[i] === "(") {
139
- let j = i + 1;
140
- while (j < src.length && isSpace(src[j])) j++;
141
- if (src[j] === "{") return j;
142
- return -1;
143
- }
144
- if (src[i] !== "{") return -1;
145
- }
146
- const { count: returns, firstIndex: idx } = scanReturns(src);
147
- if (returns !== 1) return -1;
148
- if (idx === -1) return -1;
149
- let i = idx + 6;
150
- while (i < src.length && isSpace(src[i])) i++;
151
- while (i < src.length && src[i] === "(") {
152
- i++;
153
- while (i < src.length && isSpace(src[i])) i++;
154
- }
155
- return src[i] === "{" ? i : -1;
156
- }
157
- function topLevelArrowIndex(src) {
132
+ let arrow = -1;
158
133
  let depth = 0;
159
134
  for (let i = 0; i < src.length;) {
160
135
  const ch = src[i];
@@ -164,17 +139,17 @@ function topLevelArrowIndex(src) {
164
139
  }
165
140
  if (ch === "/" && src[i + 1] === "/") {
166
141
  const nl = src.indexOf("\n", i);
167
- if (nl === -1) return -1;
142
+ if (nl === -1) break;
168
143
  i = nl + 1;
169
144
  continue;
170
145
  }
171
146
  if (ch === "/" && src[i + 1] === "*") {
172
147
  const end = src.indexOf("*/", i);
173
- if (end === -1) return -1;
148
+ if (end === -1) break;
174
149
  i = end + 2;
175
150
  continue;
176
151
  }
177
- if (depth === 0 && ch === "f" && src.startsWith("function", i) && !isIdentChar(src[i - 1] ?? " ") && !isIdentChar(src[i + 8] ?? " ")) return -1;
152
+ if (depth === 0 && ch === "f" && src.startsWith("function", i) && !isIdentChar(src[i - 1] ?? " ") && !isIdentChar(src[i + 8] ?? " ")) break;
178
153
  if (ch === "(" || ch === "[" || ch === "{") {
179
154
  depth++;
180
155
  i++;
@@ -185,14 +160,25 @@ function topLevelArrowIndex(src) {
185
160
  i++;
186
161
  continue;
187
162
  }
188
- if (depth === 0 && ch === "=" && src[i + 1] === ">") return i;
163
+ if (depth === 0 && ch === "=" && src[i + 1] === ">") {
164
+ arrow = i;
165
+ break;
166
+ }
189
167
  i++;
190
168
  }
191
- return -1;
192
- }
193
- function scanReturns(src) {
194
- let count = 0;
195
- let firstIndex = -1;
169
+ if (arrow !== -1) {
170
+ let i = arrow + 2;
171
+ while (i < src.length && isSpace(src[i])) i++;
172
+ if (src[i] === "(") {
173
+ let j = i + 1;
174
+ while (j < src.length && isSpace(src[j])) j++;
175
+ if (src[j] === "{") return j;
176
+ return -1;
177
+ }
178
+ if (src[i] !== "{") return -1;
179
+ }
180
+ let returns = 0;
181
+ let idx = -1;
196
182
  for (let i = 0; i < src.length;) {
197
183
  const ch = src[i];
198
184
  if (ch === "\"" || ch === "'" || ch === "`") {
@@ -212,17 +198,22 @@ function scanReturns(src) {
212
198
  continue;
213
199
  }
214
200
  if (ch === "r" && src.startsWith("return", i) && !isIdentChar(src[i - 1] ?? " ") && !isIdentChar(src[i + 6] ?? " ")) {
215
- if (firstIndex === -1) firstIndex = i;
216
- count++;
201
+ if (idx === -1) idx = i;
202
+ returns++;
217
203
  i += 6;
218
204
  continue;
219
205
  }
220
206
  i++;
221
207
  }
222
- return {
223
- count,
224
- firstIndex
225
- };
208
+ if (returns !== 1) return -1;
209
+ if (idx === -1) return -1;
210
+ let i = idx + 6;
211
+ while (i < src.length && isSpace(src[i])) i++;
212
+ while (i < src.length && src[i] === "(") {
213
+ i++;
214
+ while (i < src.length && isSpace(src[i])) i++;
215
+ }
216
+ return src[i] === "{" ? i : -1;
226
217
  }
227
218
  function scanObjectLiteralKeys(src, open) {
228
219
  const keys = [];
@@ -265,7 +256,56 @@ function scanObjectLiteralKeys(src, open) {
265
256
  if (src[j] !== ":") return null;
266
257
  keys.push(key);
267
258
  i = j + 1;
268
- i = skipValue(src, i);
259
+ let depth = 0;
260
+ let found = false;
261
+ while (i < src.length) {
262
+ const ch = src[i];
263
+ if (ch === "\"" || ch === "'" || ch === "`") {
264
+ i = skipString(src, i);
265
+ continue;
266
+ }
267
+ if (ch === "/" && src[i + 1] === "/") {
268
+ const nl = src.indexOf("\n", i);
269
+ if (nl === -1) {
270
+ i = -1;
271
+ found = true;
272
+ break;
273
+ }
274
+ i = nl + 1;
275
+ continue;
276
+ }
277
+ if (ch === "/" && src[i + 1] === "*") {
278
+ const end = src.indexOf("*/", i);
279
+ if (end === -1) {
280
+ i = -1;
281
+ found = true;
282
+ break;
283
+ }
284
+ i = end + 2;
285
+ continue;
286
+ }
287
+ if (ch === "{" || ch === "(" || ch === "[") {
288
+ depth++;
289
+ i++;
290
+ continue;
291
+ }
292
+ if (ch === "}" || ch === ")" || ch === "]") {
293
+ if (depth === 0) {
294
+ if (ch !== "}") i = -1;
295
+ found = true;
296
+ break;
297
+ }
298
+ depth--;
299
+ i++;
300
+ continue;
301
+ }
302
+ if (ch === "," && depth === 0) {
303
+ found = true;
304
+ break;
305
+ }
306
+ i++;
307
+ }
308
+ if (!found) i = -1;
269
309
  if (i === -1) return null;
270
310
  expectKey = false;
271
311
  continue;
@@ -279,45 +319,6 @@ function scanObjectLiteralKeys(src, open) {
279
319
  }
280
320
  return null;
281
321
  }
282
- function skipValue(src, i) {
283
- let depth = 0;
284
- while (i < src.length) {
285
- const ch = src[i];
286
- if (ch === "\"" || ch === "'" || ch === "`") {
287
- i = skipString(src, i);
288
- continue;
289
- }
290
- if (ch === "/" && src[i + 1] === "/") {
291
- const nl = src.indexOf("\n", i);
292
- if (nl === -1) return -1;
293
- i = nl + 1;
294
- continue;
295
- }
296
- if (ch === "/" && src[i + 1] === "*") {
297
- const end = src.indexOf("*/", i);
298
- if (end === -1) return -1;
299
- i = end + 2;
300
- continue;
301
- }
302
- if (ch === "{" || ch === "(" || ch === "[") {
303
- depth++;
304
- i++;
305
- continue;
306
- }
307
- if (ch === "}" || ch === ")" || ch === "]") {
308
- if (depth === 0) {
309
- if (ch === "}") return i;
310
- return -1;
311
- }
312
- depth--;
313
- i++;
314
- continue;
315
- }
316
- if (ch === "," && depth === 0) return i;
317
- i++;
318
- }
319
- return -1;
320
- }
321
322
  function mapBeforeHandle(_hooks, derive, link, isAsync, report, abortGuard, arm) {
322
323
  const hooks = toArray(_hooks);
323
324
  const modes = deriveModes(hooks, derive);
@@ -336,12 +337,13 @@ function mapBeforeHandle(_hooks, derive, link, isAsync, report, abortGuard, arm)
336
337
  code += awaitGuard(fn, isAsync, "tmp", arm);
337
338
  if (modes?.[i] !== void 0) {
338
339
  needsEs = true;
340
+ link(registerDeriveDisposable, "dsp");
339
341
  if (modes[i]) {
340
342
  link(replaceDeriveContext, "rdc");
341
- code += "if(tmp instanceof es)_r=tmp\nelse if(tmp){if(typeof tmp==='object'||typeof tmp==='function')c=rdc(c,tmp);tmp=undefined}\n";
343
+ code += "if(tmp instanceof es)_r=tmp\nelse if(tmp){if(typeof tmp==='object'||typeof tmp==='function'){const _pc=c;c=rdc(c,tmp);for(const _k of Object.keys(tmp))dsp(c,c[_k],_pc)}tmp=undefined}\n";
342
344
  } else {
343
345
  const keys = extractDeriveKeys(fn);
344
- const merge = keys && keys.length && !keys.includes("__proto__") ? keys.map((k) => `c[${JSON.stringify(k)}]=tmp[${JSON.stringify(k)}]`).join(";") : "Object.hasOwn(tmp,'__proto__')?Object.defineProperties(c,Object.getOwnPropertyDescriptors(tmp)):Object.assign(c,tmp)";
346
+ const merge = !!keys && !!keys.length && !keys.includes("__proto__") ? keys.map((k) => `_v=tmp[${JSON.stringify(k)}];dsp(c,_v);c[${JSON.stringify(k)}]=_v`).join(";") : "if(Object.hasOwn(tmp,'__proto__')){for(const _k of Object.keys(tmp))dsp(c,tmp[_k]);Object.defineProperties(c,Object.getOwnPropertyDescriptors(tmp))}else{_v=Object.assign({},tmp);for(const _k of Reflect.ownKeys(_v)){dsp(c,_v[_k]);c[_k]=_v[_k]}}";
345
347
  code += `if(tmp instanceof es)_r=tmp
346
348
  else if(tmp){${merge};tmp=undefined}\n`;
347
349
  }
@@ -509,4 +511,4 @@ function awaitGuard(fn, isAsync, target, arm = "") {
509
511
  }
510
512
 
511
513
  //#endregion
512
- export { armEntryAbort, awaitGuard, cloneResponse, cloneStaticValue, deriveModes, emptyResponse, getQueryParseChannels, hasRequestBody, mapAfterHandle, mapAfterResponse, mapBeforeHandle, mapError, mapMapResponse, mapTransform, replaceDeriveContext, runBeforeHandlePrefix, runBeforeHandlePrefixAsync };
514
+ export { armEntryAbort, awaitGuard, cloneResponse, cloneStaticValue, deriveModes, drainDisposables, emptyResponse, getQueryParseChannels, hasRequestBody, mapAfterHandle, mapAfterResponse, mapBeforeHandle, mapError, mapMapResponse, mapTransform, registerDeriveDisposable, replaceDeriveContext, runBeforeHandlePrefix, runBeforeHandlePrefixAsync };