elysia 2.0.0-beta.2 → 2.0.0-beta.21

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 (339) hide show
  1. package/dist/adapter/bun/index.d.ts +18 -2
  2. package/dist/adapter/bun/index.js +467 -110
  3. package/dist/adapter/bun/index.mjs +467 -112
  4. package/dist/adapter/types.d.ts +2 -21
  5. package/dist/adapter/utils.d.ts +14 -3
  6. package/dist/adapter/utils.js +146 -87
  7. package/dist/adapter/utils.mjs +148 -90
  8. package/dist/adapter/web-standard/handler.d.ts +1 -1
  9. package/dist/adapter/web-standard/handler.js +47 -36
  10. package/dist/adapter/web-standard/handler.mjs +48 -37
  11. package/dist/adapter/web-standard/index.js +2 -30
  12. package/dist/adapter/web-standard/index.mjs +2 -30
  13. package/dist/adapter/web-standard/utils.js +5 -18
  14. package/dist/adapter/web-standard/utils.mjs +5 -18
  15. package/dist/base.d.ts +99 -67
  16. package/dist/base.js +678 -510
  17. package/dist/base.mjs +682 -514
  18. package/dist/compile/aot-capture.d.ts +2 -13
  19. package/dist/compile/aot-capture.js +26 -69
  20. package/dist/compile/aot-capture.mjs +28 -67
  21. package/dist/compile/aot-emit.d.ts +9 -7
  22. package/dist/compile/aot-emit.js +42 -19
  23. package/dist/compile/aot-emit.mjs +42 -20
  24. package/dist/compile/aot.d.ts +17 -19
  25. package/dist/compile/aot.js +41 -51
  26. package/dist/compile/aot.mjs +39 -49
  27. package/dist/compile/handler/descriptor.d.ts +9 -12
  28. package/dist/compile/handler/descriptor.js +19 -44
  29. package/dist/compile/handler/descriptor.mjs +20 -42
  30. package/dist/compile/handler/frozen-validator.d.ts +5 -10
  31. package/dist/compile/handler/frozen-validator.js +55 -105
  32. package/dist/compile/handler/frozen-validator.mjs +53 -105
  33. package/dist/compile/handler/index.d.ts +7 -5
  34. package/dist/compile/handler/index.js +270 -111
  35. package/dist/compile/handler/index.mjs +270 -113
  36. package/dist/compile/handler/jit.d.ts +19 -17
  37. package/dist/compile/handler/jit.js +222 -149
  38. package/dist/compile/handler/jit.mjs +224 -152
  39. package/dist/compile/handler/params.d.ts +1 -4
  40. package/dist/compile/handler/params.js +10 -5
  41. package/dist/compile/handler/params.mjs +14 -8
  42. package/dist/compile/handler/reconstruct.d.ts +2 -2
  43. package/dist/compile/handler/reconstruct.js +6 -4
  44. package/dist/compile/handler/reconstruct.mjs +6 -4
  45. package/dist/compile/handler/static-clone-resolver.d.ts +6 -0
  46. package/dist/compile/handler/static-clone-resolver.js +8 -0
  47. package/dist/compile/handler/static-clone-resolver.mjs +7 -0
  48. package/dist/compile/handler/utils.d.ts +22 -11
  49. package/dist/compile/handler/utils.js +159 -253
  50. package/dist/compile/handler/utils.mjs +155 -252
  51. package/dist/compile/jit-probe.d.ts +2 -2
  52. package/dist/compile/jit-probe.js +2 -3
  53. package/dist/compile/jit-probe.mjs +2 -3
  54. package/dist/compile/lexer.d.ts +7 -4
  55. package/dist/compile/lexer.js +268 -6
  56. package/dist/compile/lexer.mjs +268 -4
  57. package/dist/compile/utils.js +7 -4
  58. package/dist/compile/utils.mjs +7 -4
  59. package/dist/compiled.d.ts +0 -1
  60. package/dist/compiled.js +0 -1
  61. package/dist/compiled.mjs +0 -1
  62. package/dist/context.d.ts +14 -4
  63. package/dist/context.js +17 -32
  64. package/dist/context.mjs +19 -34
  65. package/dist/cookie/config.d.ts +7 -2
  66. package/dist/cookie/config.js +76 -16
  67. package/dist/cookie/config.mjs +77 -18
  68. package/dist/cookie/cookie.d.ts +1 -1
  69. package/dist/cookie/cookie.js +8 -10
  70. package/dist/cookie/cookie.mjs +8 -10
  71. package/dist/cookie/crypto.d.ts +8 -7
  72. package/dist/cookie/crypto.js +51 -40
  73. package/dist/cookie/crypto.mjs +51 -41
  74. package/dist/cookie/error.d.ts +1 -2
  75. package/dist/cookie/error.js +6 -4
  76. package/dist/cookie/error.mjs +6 -4
  77. package/dist/cookie/lib.js +7 -2
  78. package/dist/cookie/lib.mjs +7 -2
  79. package/dist/cookie/serialize.js +1 -1
  80. package/dist/cookie/serialize.mjs +1 -1
  81. package/dist/cookie/types.d.ts +10 -0
  82. package/dist/cookie/utils.d.ts +4 -8
  83. package/dist/cookie/utils.js +86 -52
  84. package/dist/cookie/utils.mjs +89 -54
  85. package/dist/error.d.ts +113 -103
  86. package/dist/error.js +181 -117
  87. package/dist/error.mjs +179 -118
  88. package/dist/generation.d.ts +2 -2
  89. package/dist/handler/error.d.ts +26 -15
  90. package/dist/handler/error.js +77 -96
  91. package/dist/handler/error.mjs +74 -97
  92. package/dist/handler/fetch.js +87 -108
  93. package/dist/handler/fetch.mjs +89 -110
  94. package/dist/handler/utils.d.ts +12 -6
  95. package/dist/handler/utils.js +84 -28
  96. package/dist/handler/utils.mjs +80 -28
  97. package/dist/index.d.ts +12 -12
  98. package/dist/index.js +2 -9
  99. package/dist/index.mjs +1 -1
  100. package/dist/memory.js +1 -1
  101. package/dist/memory.mjs +1 -1
  102. package/dist/package.js +1 -1
  103. package/dist/package.mjs +1 -1
  104. package/dist/plugin/aot/bun.d.ts +8 -1
  105. package/dist/plugin/aot/bun.js +16 -9
  106. package/dist/plugin/aot/bun.mjs +17 -10
  107. package/dist/plugin/aot/core.d.ts +52 -60
  108. package/dist/plugin/aot/core.js +208 -109
  109. package/dist/plugin/aot/core.mjs +205 -111
  110. package/dist/plugin/aot/esbuild.js +8 -5
  111. package/dist/plugin/aot/esbuild.mjs +9 -6
  112. package/dist/plugin/aot/hooks.d.ts +6 -17
  113. package/dist/plugin/aot/hooks.js +36 -14
  114. package/dist/plugin/aot/hooks.mjs +37 -16
  115. package/dist/plugin/aot/rspack-loader.d.ts +1 -5
  116. package/dist/plugin/aot/rspack-loader.js +1 -10
  117. package/dist/plugin/aot/rspack-loader.mjs +1 -10
  118. package/dist/plugin/aot/rspack.js +2 -5
  119. package/dist/plugin/aot/rspack.mjs +3 -6
  120. package/dist/plugin/aot/source.d.ts +6 -42
  121. package/dist/plugin/aot/source.js +71 -71
  122. package/dist/plugin/aot/source.mjs +72 -72
  123. package/dist/plugin/aot/treeshake.js +2 -6
  124. package/dist/plugin/aot/treeshake.mjs +2 -6
  125. package/dist/plugin/aot/unplugin.d.ts +1 -4
  126. package/dist/plugin/aot/unplugin.js +4 -13
  127. package/dist/plugin/aot/unplugin.mjs +4 -13
  128. package/dist/plugin/aot/vite.d.ts +2 -6
  129. package/dist/plugin/aot/worker.js +2 -2
  130. package/dist/plugin/aot/worker.mjs +2 -2
  131. package/dist/plugin/auto-head.js +1 -10
  132. package/dist/plugin/auto-head.mjs +1 -10
  133. package/dist/plugin/trace.d.ts +2 -1
  134. package/dist/route-table.d.ts +3 -0
  135. package/dist/route-table.js +16 -11
  136. package/dist/route-table.mjs +16 -11
  137. package/dist/schema-snapshot.d.ts +0 -4
  138. package/dist/schema-snapshot.js +32 -49
  139. package/dist/schema-snapshot.mjs +32 -49
  140. package/dist/sucrose.d.ts +6 -55
  141. package/dist/sucrose.js +103 -731
  142. package/dist/sucrose.mjs +102 -724
  143. package/dist/trace.d.ts +5 -8
  144. package/dist/trace.js +23 -134
  145. package/dist/trace.mjs +24 -135
  146. package/dist/type/bridge-live.d.ts +4 -2
  147. package/dist/type/bridge-live.js +6 -3
  148. package/dist/type/bridge-live.mjs +4 -2
  149. package/dist/type/bridge.d.ts +6 -4
  150. package/dist/type/bridge.js +17 -9
  151. package/dist/type/bridge.mjs +5 -3
  152. package/dist/type/coerce-plan.d.ts +5 -5
  153. package/dist/type/coerce-plan.js +41 -39
  154. package/dist/type/coerce-plan.mjs +43 -39
  155. package/dist/type/coerce.d.ts +3 -7
  156. package/dist/type/coerce.js +18 -75
  157. package/dist/type/coerce.mjs +19 -76
  158. package/dist/type/compat.d.ts +3 -0
  159. package/dist/type/compat.js +23 -14
  160. package/dist/type/compat.mjs +20 -10
  161. package/dist/type/elysia/array-buffer.d.ts +4 -1
  162. package/dist/type/elysia/array-buffer.js +17 -17
  163. package/dist/type/elysia/array-buffer.mjs +17 -17
  164. package/dist/type/elysia/array-string.js +2 -40
  165. package/dist/type/elysia/array-string.mjs +2 -39
  166. package/dist/type/elysia/array.js +5 -9
  167. package/dist/type/elysia/array.mjs +5 -9
  168. package/dist/type/elysia/boolean-string.js +2 -3
  169. package/dist/type/elysia/boolean-string.mjs +1 -1
  170. package/dist/type/elysia/boolean.js +3 -12
  171. package/dist/type/elysia/boolean.mjs +3 -11
  172. package/dist/type/elysia/cookie.d.ts +3 -4
  173. package/dist/type/elysia/cookie.js +5 -15
  174. package/dist/type/elysia/cookie.mjs +5 -15
  175. package/dist/type/elysia/date.js +13 -20
  176. package/dist/type/elysia/date.mjs +10 -16
  177. package/dist/type/elysia/file-type.d.ts +11 -4
  178. package/dist/type/elysia/file-type.js +17 -2
  179. package/dist/type/elysia/file-type.mjs +17 -3
  180. package/dist/type/elysia/file.d.ts +1 -3
  181. package/dist/type/elysia/file.js +11 -27
  182. package/dist/type/elysia/file.mjs +11 -12
  183. package/dist/type/elysia/files.js +7 -11
  184. package/dist/type/elysia/files.mjs +7 -10
  185. package/dist/type/elysia/form.js +2 -3
  186. package/dist/type/elysia/form.mjs +3 -3
  187. package/dist/type/elysia/integer-string.d.ts +1 -1
  188. package/dist/type/elysia/integer-string.js +4 -30
  189. package/dist/type/elysia/integer-string.mjs +5 -30
  190. package/dist/type/elysia/integer.js +3 -12
  191. package/dist/type/elysia/integer.mjs +3 -11
  192. package/dist/type/elysia/intersect.js +0 -5
  193. package/dist/type/elysia/intersect.mjs +0 -5
  194. package/dist/type/elysia/json-string.d.ts +7 -0
  195. package/dist/type/elysia/json-string.js +47 -0
  196. package/dist/type/elysia/json-string.mjs +46 -0
  197. package/dist/type/elysia/keep-config.d.ts +14 -0
  198. package/dist/type/elysia/keep-config.js +62 -0
  199. package/dist/type/elysia/keep-config.mjs +53 -0
  200. package/dist/type/elysia/maybe-empty.js +3 -4
  201. package/dist/type/elysia/maybe-empty.mjs +1 -1
  202. package/dist/type/elysia/nullable.js +2 -3
  203. package/dist/type/elysia/nullable.mjs +1 -1
  204. package/dist/type/elysia/number.d.ts +2 -1
  205. package/dist/type/elysia/number.js +19 -11
  206. package/dist/type/elysia/number.mjs +18 -10
  207. package/dist/type/elysia/numeric-enum.d.ts +1 -1
  208. package/dist/type/elysia/numeric-enum.js +4 -5
  209. package/dist/type/elysia/numeric-enum.mjs +3 -3
  210. package/dist/type/elysia/numeric.d.ts +4 -2
  211. package/dist/type/elysia/numeric.js +20 -17
  212. package/dist/type/elysia/numeric.mjs +19 -16
  213. package/dist/type/elysia/object-string.js +2 -37
  214. package/dist/type/elysia/object-string.mjs +2 -36
  215. package/dist/type/elysia/object.js +5 -9
  216. package/dist/type/elysia/object.mjs +5 -9
  217. package/dist/type/elysia/optional.js +8 -8
  218. package/dist/type/elysia/optional.mjs +7 -7
  219. package/dist/type/elysia/problem.d.ts +20 -0
  220. package/dist/type/elysia/problem.js +25 -0
  221. package/dist/type/elysia/problem.mjs +24 -0
  222. package/dist/type/elysia/string.js +4 -3
  223. package/dist/type/elysia/string.mjs +4 -2
  224. package/dist/type/elysia/uint8-array.d.ts +1 -1
  225. package/dist/type/elysia/uint8-array.js +5 -20
  226. package/dist/type/elysia/uint8-array.mjs +5 -19
  227. package/dist/type/elysia/union-enum.js +7 -8
  228. package/dist/type/elysia/union-enum.mjs +6 -6
  229. package/dist/type/elysia/union.js +0 -5
  230. package/dist/type/elysia/union.mjs +0 -5
  231. package/dist/type/elysia/utils.d.ts +2 -4
  232. package/dist/type/elysia/utils.js +10 -21
  233. package/dist/type/elysia/utils.mjs +7 -15
  234. package/dist/type/exports.d.ts +4 -2
  235. package/dist/type/exports.js +23 -2
  236. package/dist/type/exports.mjs +11 -2
  237. package/dist/type/index.d.ts +10 -2
  238. package/dist/type/index.js +62 -15
  239. package/dist/type/index.mjs +65 -11
  240. package/dist/type/shared.d.ts +3 -9
  241. package/dist/type/shared.js +44 -97
  242. package/dist/type/shared.mjs +43 -97
  243. package/dist/type/sync-require.d.ts +11 -0
  244. package/dist/type/sync-require.js +14 -0
  245. package/dist/type/sync-require.mjs +12 -0
  246. package/dist/type/typebox-system-lite.d.ts +2 -0
  247. package/dist/type/typebox-system-lite.js +34 -0
  248. package/dist/type/typebox-system-lite.mjs +3 -0
  249. package/dist/type/typebox-system-require.d.ts +7 -0
  250. package/dist/type/typebox-system-require.js +24 -0
  251. package/dist/type/typebox-system-require.mjs +23 -0
  252. package/dist/type/typebox-type-live.d.ts +11 -0
  253. package/dist/type/typebox-type-live.js +45 -0
  254. package/dist/type/typebox-type-live.mjs +20 -0
  255. package/dist/type/typebox-type.d.ts +34 -0
  256. package/dist/type/typebox-type.js +199 -0
  257. package/dist/type/typebox-type.mjs +86 -0
  258. package/dist/type/typebox-value-live.d.ts +11 -0
  259. package/dist/type/typebox-value-live.js +31 -0
  260. package/dist/type/typebox-value-live.mjs +13 -0
  261. package/dist/type/typebox-value-ops.d.ts +4 -0
  262. package/dist/type/typebox-value-ops.js +90 -0
  263. package/dist/type/typebox-value-ops.mjs +5 -0
  264. package/dist/type/typebox-value-require.d.ts +8 -0
  265. package/dist/type/typebox-value-require.js +28 -0
  266. package/dist/type/typebox-value-require.mjs +25 -0
  267. package/dist/type/typebox-value.d.ts +35 -0
  268. package/dist/type/typebox-value.js +161 -0
  269. package/dist/type/typebox-value.mjs +74 -0
  270. package/dist/type/utils.js +1 -10
  271. package/dist/type/utils.mjs +1 -10
  272. package/dist/type/validator/clean-safe.d.ts +2 -4
  273. package/dist/type/validator/clean-safe.js +15 -11
  274. package/dist/type/validator/clean-safe.mjs +16 -10
  275. package/dist/type/validator/custom-error.js +12 -16
  276. package/dist/type/validator/custom-error.mjs +11 -14
  277. package/dist/type/validator/default-precompute.d.ts +9 -1
  278. package/dist/type/validator/default-precompute.js +40 -77
  279. package/dist/type/validator/default-precompute.mjs +37 -74
  280. package/dist/type/validator/exact-mirror-live.d.ts +8 -0
  281. package/dist/type/validator/exact-mirror-live.js +22 -0
  282. package/dist/type/validator/exact-mirror-live.mjs +17 -0
  283. package/dist/type/validator/exact-mirror-require.d.ts +4 -0
  284. package/dist/type/validator/exact-mirror-require.js +11 -0
  285. package/dist/type/validator/exact-mirror-require.mjs +9 -0
  286. package/dist/type/validator/exact-mirror.js +8 -8
  287. package/dist/type/validator/exact-mirror.mjs +9 -8
  288. package/dist/type/validator/frozen-check.js +5 -6
  289. package/dist/type/validator/frozen-check.mjs +6 -7
  290. package/dist/type/validator/index.d.ts +1 -0
  291. package/dist/type/validator/index.js +169 -166
  292. package/dist/type/validator/index.mjs +162 -158
  293. package/dist/type/validator/string-codec-aot.d.ts +2 -1
  294. package/dist/type/validator/string-codec-aot.js +8 -2
  295. package/dist/type/validator/string-codec-aot.mjs +7 -2
  296. package/dist/type/validator/validator-cache.d.ts +5 -4
  297. package/dist/type/validator/validator-cache.js +41 -24
  298. package/dist/type/validator/validator-cache.mjs +40 -22
  299. package/dist/types.d.ts +263 -95
  300. package/dist/universal/constants.d.ts +2 -1
  301. package/dist/universal/constants.js +3 -1
  302. package/dist/universal/constants.mjs +2 -1
  303. package/dist/universal/env.js +2 -3
  304. package/dist/universal/env.mjs +2 -3
  305. package/dist/universal/file.d.ts +6 -4
  306. package/dist/universal/file.js +11 -16
  307. package/dist/universal/file.mjs +12 -16
  308. package/dist/universal/index.d.ts +2 -2
  309. package/dist/universal/is-production.d.ts +1 -2
  310. package/dist/universal/is-production.js +1 -3
  311. package/dist/universal/is-production.mjs +2 -3
  312. package/dist/universal/server.d.ts +0 -272
  313. package/dist/utils.d.ts +43 -7
  314. package/dist/utils.js +181 -126
  315. package/dist/utils.mjs +168 -126
  316. package/dist/validator/index.d.ts +1 -1
  317. package/dist/validator/index.js +17 -30
  318. package/dist/validator/index.mjs +18 -31
  319. package/dist/validator/route.js +2 -1
  320. package/dist/validator/route.mjs +2 -1
  321. package/dist/ws/context.d.ts +8 -1
  322. package/dist/ws/context.js +68 -44
  323. package/dist/ws/context.mjs +67 -44
  324. package/dist/ws/parser.js +10 -20
  325. package/dist/ws/parser.mjs +10 -20
  326. package/dist/ws/route.d.ts +2 -2
  327. package/dist/ws/route.js +249 -141
  328. package/dist/ws/route.mjs +254 -146
  329. package/dist/ws/types.d.ts +2 -2
  330. package/package.json +23 -49
  331. package/dist/compile/analysis-cache.d.ts +0 -6
  332. package/dist/compile/analysis-cache.js +0 -12
  333. package/dist/compile/analysis-cache.mjs +0 -11
  334. package/dist/cookie/index.d.ts +0 -7
  335. package/dist/cookie/index.js +0 -13
  336. package/dist/cookie/index.mjs +0 -7
  337. package/dist/handler/index.d.ts +0 -2
  338. package/dist/handler/index.js +0 -5
  339. package/dist/handler/index.mjs +0 -3
package/dist/sucrose.mjs CHANGED
@@ -1,406 +1,26 @@
1
1
  import { evictOldestHalf, fnv1a } from "./utils.mjs";
2
2
  import { getCompilerSession } from "./compile/aot.mjs";
3
+ import { scanTokens } from "./compile/lexer.mjs";
3
4
 
4
5
  //#region src/sucrose.ts
5
- /**
6
- * Separate stringified function body and parameter
7
- *
8
- * @example
9
- * ```typescript
10
- * separateFunction('async ({ hello }) => { return hello }') // => ['({ hello })', '{ return hello }']
11
- * ```
12
- */
13
- function separateFunction(code) {
14
- if (code.startsWith("async")) code = code.slice(5);
15
- code = code.trimStart();
16
- let index;
17
- if (code.charCodeAt(0) === 40) {
18
- const parameterEnd = findClosingParenthesis(code, 0);
19
- index = code.indexOf("=>", parameterEnd);
20
- if (index !== -1) {
21
- let body = code.slice(index + 2);
22
- if (body.charCodeAt(0) === 32) body = body.trimStart();
23
- return [code.slice(1, parameterEnd), body];
24
- }
25
- }
26
- if (/^([\w$]+)=>/g.test(code)) {
27
- index = code.indexOf("=>");
28
- if (index !== -1) {
29
- let body = code.slice(index + 2);
30
- if (body.charCodeAt(0) === 32) body = body.trimStart();
31
- return [code.slice(0, index), body];
32
- }
33
- }
34
- if (code.startsWith("function")) {
35
- index = code.indexOf("(");
36
- const end = findClosingParenthesis(code, index);
37
- return [code.slice(index + 1, end), code.slice(end + 2)];
38
- }
39
- const start = code.indexOf("(");
40
- if (start !== -1) {
41
- const sep = code.indexOf("\n", 2);
42
- const parameter = code.slice(0, sep);
43
- const end = parameter.lastIndexOf(")") + 1;
44
- const body = code.slice(sep + 1);
45
- return [parameter.slice(start, end), "{" + body];
46
- }
47
- const x = code.split("\n", 2);
48
- return [x[0], x[1]];
49
- }
50
- function findClosingParenthesis(code, start) {
51
- let deep = 1;
52
- for (let index = start + 1; index < code.length; index++) {
53
- const char = code.charCodeAt(index);
54
- if (char === 40) deep++;
55
- else if (char === 41 && --deep === 0) return index;
56
- }
57
- return start;
58
- }
59
- /**
60
- * Get range between bracket pair
61
- *
62
- * @example
63
- * ```typescript
64
- * bracketPairRange('hello: { world: { a } }, elysia') // [6, 20]
65
- * ```
66
- */
67
- function bracketPairRange(parameter) {
68
- const start = parameter.indexOf("{");
69
- if (start === -1) return [-1, 0];
70
- let end = start + 1;
71
- let deep = 1;
72
- for (; end < parameter.length; end++) {
73
- const char = parameter.charCodeAt(end);
74
- if (char === 123) deep++;
75
- else if (char === 125) deep--;
76
- if (deep === 0) break;
77
- }
78
- if (deep !== 0) return [0, parameter.length];
79
- return [start, end + 1];
80
- }
81
- /**
82
- * Similar to `bracketPairRange` but in reverse order
83
- * Get range between bracket pair from end to beginning
84
- *
85
- * @example
86
- * ```typescript
87
- * bracketPairRange('hello: { world: { a } }, elysia') // [6, 20]
88
- * ```
89
- */
90
- function bracketPairRangeReverse(parameter) {
91
- const end = parameter.lastIndexOf("}");
92
- if (end === -1) return [-1, 0];
93
- let start = end - 1;
94
- let deep = 1;
95
- for (; start >= 0; start--) {
96
- const char = parameter.charCodeAt(start);
97
- if (char === 125) deep++;
98
- else if (char === 123) deep--;
99
- if (deep === 0) break;
100
- }
101
- if (deep !== 0) return [-1, 0];
102
- return [start, end + 1];
103
- }
104
- function removeColonAlias(parameter) {
105
- while (true) {
106
- const start = parameter.indexOf(":");
107
- if (start === -1) break;
108
- let end = start + 1;
109
- while (end < parameter.length) {
110
- const char = parameter.charCodeAt(end);
111
- if (char !== 32 && char !== 9 && char !== 10) break;
112
- end++;
113
- }
114
- while (end < parameter.length) {
115
- const char = parameter.charCodeAt(end);
116
- if (char === 44 || char === 125 || char === 32 || char === 9 || char === 10) break;
117
- end++;
118
- }
119
- parameter = parameter.slice(0, start) + parameter.slice(end);
120
- }
121
- return parameter;
122
- }
123
- /**
124
- * Retrieve only root parameters of a function
125
- *
126
- * @example
127
- * ```typescript
128
- * retrieveRootParameters('({ hello: { world: { a } }, elysia })') // => {
129
- * parameters: ['hello', 'elysia'],
130
- * hasParenthesis: true
131
- * }
132
- * ```
133
- */
134
- function retrieveRootparameters(parameter) {
135
- let hasParenthesis = false;
136
- if (parameter.charCodeAt(0) === 40) parameter = parameter.slice(1, -1);
137
- parameter = parameter.trim();
138
- if (parameter.indexOf("=") !== -1) parameter = removeDefaultParameter(parameter);
139
- if (parameter.charCodeAt(0) === 123) {
140
- hasParenthesis = true;
141
- const [, end] = bracketPairRange(parameter);
142
- parameter = parameter.slice(1, end - 1);
143
- }
144
- parameter = parameter.replace(/\s+/g, "");
145
- const parameters = [];
146
- while (true) {
147
- let [start, end] = bracketPairRange(parameter);
148
- if (start === -1) break;
149
- parameters.push(removeColonAlias(parameter.slice(0, start - 1)));
150
- if (parameter.charCodeAt(end) === 44) end++;
151
- parameter = parameter.slice(end);
152
- }
153
- parameter = removeColonAlias(parameter);
154
- if (parameter) parameters.push(parameter);
155
- const parameterMap = Object.create(null);
156
- for (const p of parameters) {
157
- if (p.indexOf(",") === -1) {
158
- parameterMap[p] = true;
159
- continue;
160
- }
161
- for (const q of p.split(",")) parameterMap[q] = true;
162
- }
163
- return {
164
- hasParenthesis,
165
- parameters: parameterMap
166
- };
167
- }
168
- function findEndIndex(type, content, index) {
169
- let search = index ?? 0;
170
- while (true) {
171
- const found = content.indexOf(type, search);
172
- if (found === -1) return -1;
173
- switch (content.charCodeAt(found + type.length)) {
174
- case 10:
175
- case 9:
176
- case 44:
177
- case 59:
178
- case 32:
179
- case 41:
180
- case 125: return found;
181
- }
182
- search = found + 1;
183
- }
184
- }
185
- /**
186
- * Find alias of variable from function body
187
- *
188
- * @example
189
- * ```typescript
190
- * findAlias('body', '{ const a = body, b = body }') // => ['a', 'b']
191
- * ```
192
- */
193
- function findAlias(type, body, seen = /* @__PURE__ */ new Set()) {
194
- const aliases = [];
195
- let content = body;
196
- const spaced = " = " + type;
197
- const minified = "=" + type;
198
- while (true) {
199
- let matchedLength = spaced.length;
200
- let index = findEndIndex(spaced, content);
201
- if (index === -1) {
202
- index = findEndIndex(minified, content);
203
- matchedLength = minified.length;
204
- }
205
- if (index === -1) {
206
- /**
207
- * Check if pattern is at the end of the string
208
- *
209
- * @example
210
- * ```typescript
211
- * 'const a = body' // true
212
- * ```
213
- **/
214
- let lastIndex = content.indexOf(spaced);
215
- matchedLength = spaced.length;
216
- if (lastIndex === -1) {
217
- lastIndex = content.indexOf(minified);
218
- matchedLength = minified.length;
219
- }
220
- if (lastIndex === -1) break;
221
- if (lastIndex + matchedLength !== content.length) break;
222
- index = lastIndex;
223
- }
224
- const part = content.slice(0, index);
225
- let boundary = -1;
226
- for (let i = part.length - 1; i >= 0; i--) {
227
- const char = part.charCodeAt(i);
228
- if (char === 32 || char === 44 || char === 40 || char === 59 || char === 41 || char === 9 || char === 10) {
229
- boundary = i;
230
- break;
231
- }
232
- }
233
- /**
234
- * aliased variable last character
235
- *
236
- * @example
237
- * ```typescript
238
- * const { hello } = body // } is the last character
239
- * ```
240
- **/
241
- const variable = part.slice(boundary + 1);
242
- if (variable.charCodeAt(variable.length - 1) === 125) {
243
- const [start, end] = bracketPairRangeReverse(part);
244
- aliases.push(removeColonAlias(content.slice(start, end)));
245
- content = content.slice(index + matchedLength);
246
- continue;
247
- }
248
- if (variable && !variable.includes("(")) aliases.push(variable);
249
- content = content.slice(index + matchedLength);
250
- }
251
- for (let i = 0; i < aliases.length; i++) {
252
- const alias = aliases[i];
253
- if (alias.charCodeAt(0) === 123 || seen.has(alias)) continue;
254
- seen.add(alias);
255
- aliases.push(...findAlias(alias, body, seen));
256
- }
257
- return aliases;
258
- }
259
- /**
260
- * Whitespace as JavaScript defines it, which is what `\s` matches: everything
261
- * `String.prototype.trim` removes, not just the three characters that happen to
262
- * appear in LF-formatted source.
263
- */
264
- const isWhitespace = (char) => char === 32 || char >= 9 && char <= 13 || char === 160 || char === 5760 || char >= 8192 && char <= 8202 || char === 8232 || char === 8233 || char === 8239 || char === 8287 || char === 12288 || char === 65279;
265
- /**
266
- * Words that lex as an identifier but are operators, so a `/` after one opens a
267
- * regex instead of dividing. Padded so a lookup cannot match a substring.
268
- */
269
- const operatorKeyword = " typeof void delete in of instanceof new return case do else yield await throw ";
270
- /**
271
- * Skip a regular expression literal, so a `,`, `}` or quote inside it is not
272
- * mistaken for structure.
273
- */
274
- function skipRegexLiteral(parameter, start, regexEnd) {
275
- let previous = start - 1;
276
- while (previous >= 0 && isWhitespace(parameter.charCodeAt(previous))) previous--;
277
- if (previous >= 0) {
278
- const char = parameter.charCodeAt(previous);
279
- if (isIdentifierPart(char)) {
280
- let identifier = previous;
281
- while (identifier >= 0 && isIdentifierPart(parameter.charCodeAt(identifier))) identifier--;
282
- if (parameter.charCodeAt(identifier) === 46 || !operatorKeyword.includes(" " + parameter.slice(identifier + 1, previous + 1) + " ")) return start;
283
- } else if (char === 41 || char === 93 || char === 125 || char === 39 || char === 34 || char === 96 || char === 47 && previous === regexEnd) return start;
284
- }
285
- let inCharacterClass = false;
286
- for (let index = start + 1; index < parameter.length; index++) {
287
- const char = parameter.charCodeAt(index);
288
- if (char === 92) index++;
289
- else if (char === 91) inCharacterClass = true;
290
- else if (char === 93) inCharacterClass = false;
291
- else if (char === 47 && !inCharacterClass) return index;
292
- }
293
- return start;
294
- }
295
- /**
296
- * Find where a default parameter value ends: the first `,` or `}` that is
297
- * outside a string or regex literal and not nested inside `()`, `[]`, or `{}`
298
- *
299
- * Returns -1 when the value runs until the end of the string
300
- */
301
- function findDefaultValueEnd(parameter, start) {
302
- let deep = 0;
303
- let quote = 0;
304
- let regexEnd = -1;
305
- let template;
306
- for (let index = start; index < parameter.length; index++) {
307
- const char = parameter.charCodeAt(index);
308
- if (quote !== 0) {
309
- if (char === 92) index++;
310
- else if (char === quote) quote = 0;
311
- else if (quote === 96 && char === 36 && parameter.charCodeAt(index + 1) === 123) {
312
- (template ??= []).push(deep);
313
- quote = 0;
314
- deep++;
315
- index++;
316
- }
317
- continue;
318
- }
319
- switch (char) {
320
- case 39:
321
- case 34:
322
- case 96:
323
- quote = char;
324
- break;
325
- case 47: {
326
- const closing = skipRegexLiteral(parameter, index, regexEnd);
327
- if (closing !== index) regexEnd = closing;
328
- index = closing;
329
- break;
330
- }
331
- case 40:
332
- case 91:
333
- case 123:
334
- deep++;
335
- break;
336
- case 41:
337
- case 93:
338
- if (deep !== 0) deep--;
339
- break;
340
- case 125:
341
- if (deep === 0) return index;
342
- deep--;
343
- if (template !== void 0 && template[template.length - 1] === deep) {
344
- template.pop();
345
- quote = 96;
346
- }
347
- break;
348
- case 44:
349
- if (deep === 0) return index;
350
- break;
351
- }
352
- }
353
- return -1;
354
- }
355
- function removeDefaultParameter(parameter) {
356
- let index = parameter.indexOf("=");
357
- if (index !== -1) {
358
- let kept = "";
359
- let copyFrom = 0;
360
- for (; index < parameter.length; index++) {
361
- if (parameter.charCodeAt(index) !== 61) continue;
362
- kept += parameter.slice(copyFrom, index);
363
- const end = findDefaultValueEnd(parameter, index + 1);
364
- if (end === -1) {
365
- copyFrom = parameter.length;
366
- break;
367
- }
368
- copyFrom = index = end;
369
- }
370
- parameter = kept + parameter.slice(copyFrom);
371
- }
372
- return parameter.split(",").map((i) => i.trim()).join(", ");
373
- }
374
- function markAllAccessed(i) {
375
- i.query = i.headers = i.body = i.cookie = i.set = i.route = true;
376
- i.afterResponse = true;
377
- }
6
+ const allAccessed = Object.freeze({
7
+ query: true,
8
+ headers: true,
9
+ body: true,
10
+ cookie: true,
11
+ set: true,
12
+ route: true,
13
+ afterResponse: true
14
+ });
15
+ const isAllAccessed = (i) => i.query && i.headers && i.body && i.cookie && i.set && i.route && i.afterResponse;
378
16
  const DEFAULT_CACHE_LIMIT = 1024;
379
17
  const globalSourceCache = /* @__PURE__ */ new Map();
380
- function sourceCache() {
381
- const session = getCompilerSession();
382
- return session?.external ? session.sucroseCache : globalSourceCache;
383
- }
384
18
  let functionCaches = /* @__PURE__ */ new WeakMap();
385
- function rememberInference(caches, key, cached, content, event, inference) {
386
- if (!cached || cached.content !== content) {
387
- if (caches.size >= DEFAULT_CACHE_LIMIT) evictOldestHalf(caches);
388
- caches.set(key, {
389
- content,
390
- inference
391
- });
392
- }
393
- if (typeof event === "function") functionCaches.set(event, inference);
394
- }
395
- function clearCache() {
19
+ function clearSucroseCache() {
396
20
  globalSourceCache.clear();
397
21
  getCompilerSession()?.sucroseCache.clear();
398
22
  functionCaches = /* @__PURE__ */ new WeakMap();
399
23
  }
400
- function clearSucroseCache(delay) {
401
- if (delay === null) return;
402
- clearCache();
403
- }
404
24
  const mergeInference = (a, b) => ({
405
25
  body: a.body || b.body,
406
26
  cookie: a.cookie || b.cookie,
@@ -419,245 +39,6 @@ const defaultSucrose = () => ({
419
39
  route: false
420
40
  });
421
41
  const emptyInference = Object.freeze(defaultSucrose());
422
- function push(target, array) {
423
- for (let i = 0; i < array.length; i++) target.push(array[i]);
424
- }
425
- function pushParse(target, array) {
426
- for (let i = 0; i < array.length; i++) if (typeof array[i] === "function") target.push(array[i]);
427
- }
428
- const prefixKeywords = new Set([
429
- "await",
430
- "case",
431
- "delete",
432
- "do",
433
- "else",
434
- "in",
435
- "instanceof",
436
- "new",
437
- "of",
438
- "return",
439
- "throw",
440
- "typeof",
441
- "void",
442
- "yield"
443
- ]);
444
- const isIdentifierStart = (char) => char >= 65 && char <= 90 || char >= 97 && char <= 122 || char === 36 || char === 95 || char >= 128;
445
- const isIdentifierPart = (char) => isIdentifierStart(char) || char >= 48 && char <= 57;
446
- function decodeIdentifier(value) {
447
- if (!value.includes("\\u")) return value;
448
- let decoded = "";
449
- for (let i = 0; i < value.length; i++) {
450
- if (value.charCodeAt(i) !== 92 || value.charCodeAt(i + 1) !== 117) {
451
- decoded += value[i];
452
- continue;
453
- }
454
- i += 2;
455
- let hex;
456
- if (value.charCodeAt(i) === 123) {
457
- const end = value.indexOf("}", i + 1);
458
- if (end === -1) return;
459
- hex = value.slice(i + 1, end);
460
- i = end;
461
- } else {
462
- hex = value.slice(i, i + 4);
463
- if (hex.length !== 4) return;
464
- i += 3;
465
- }
466
- const codePoint = Number.parseInt(hex, 16);
467
- if (!Number.isFinite(codePoint) || codePoint > 1114111) return;
468
- decoded += String.fromCodePoint(codePoint);
469
- }
470
- return decoded;
471
- }
472
- function scanTokens(source) {
473
- const tokens = [];
474
- let index = 0;
475
- let canEndExpression = false;
476
- const scanCode = (templateExpression = false) => {
477
- let templateDepth = 0;
478
- while (index < source.length) {
479
- const char = source.charCodeAt(index);
480
- if (char === 32 || char === 9 || char === 10 || char === 13) {
481
- index++;
482
- continue;
483
- }
484
- if (char === 92 && source.charCodeAt(index + 1) !== 117) return false;
485
- if (char === 47) {
486
- const next = source.charCodeAt(index + 1);
487
- if (next === 47) {
488
- index += 2;
489
- while (index < source.length && source.charCodeAt(index) !== 10 && source.charCodeAt(index) !== 13) index++;
490
- continue;
491
- }
492
- if (next === 42) {
493
- index += 2;
494
- while (index + 1 < source.length && !(source.charCodeAt(index) === 42 && source.charCodeAt(index + 1) === 47)) index++;
495
- if (index + 1 >= source.length) return false;
496
- index += 2;
497
- continue;
498
- }
499
- if (!canEndExpression) {
500
- index++;
501
- let escaped = false;
502
- let characterClass = false;
503
- let closed = false;
504
- while (index < source.length) {
505
- const regexChar = source.charCodeAt(index++);
506
- if (escaped) {
507
- escaped = false;
508
- continue;
509
- }
510
- if (regexChar === 92) {
511
- escaped = true;
512
- continue;
513
- }
514
- if (regexChar === 91) characterClass = true;
515
- else if (regexChar === 93) characterClass = false;
516
- else if (regexChar === 47 && !characterClass) {
517
- closed = true;
518
- break;
519
- } else if (regexChar === 10 || regexChar === 13) return false;
520
- }
521
- if (!closed) return false;
522
- while (isIdentifierPart(source.charCodeAt(index))) index++;
523
- canEndExpression = true;
524
- continue;
525
- }
526
- tokens.push({
527
- k: "p",
528
- value: "/"
529
- });
530
- index++;
531
- canEndExpression = false;
532
- continue;
533
- }
534
- if (char === 34 || char === 39) {
535
- const quote = char;
536
- const start = ++index;
537
- let escaped = false;
538
- while (index < source.length) {
539
- const stringChar = source.charCodeAt(index);
540
- if (escaped) escaped = false;
541
- else if (stringChar === 92) escaped = true;
542
- else if (stringChar === quote) break;
543
- else if (stringChar === 10 || stringChar === 13) return false;
544
- index++;
545
- }
546
- if (index >= source.length) return false;
547
- tokens.push({
548
- k: "s",
549
- value: source.slice(start, index)
550
- });
551
- index++;
552
- canEndExpression = true;
553
- continue;
554
- }
555
- if (char === 96) {
556
- index++;
557
- let closed = false;
558
- while (index < source.length) {
559
- const templateChar = source.charCodeAt(index);
560
- if (templateChar === 92) {
561
- index += 2;
562
- continue;
563
- }
564
- if (templateChar === 96) {
565
- index++;
566
- closed = true;
567
- break;
568
- }
569
- if (templateChar === 36 && source.charCodeAt(index + 1) === 123) {
570
- index += 2;
571
- canEndExpression = false;
572
- if (!scanCode(true)) return false;
573
- continue;
574
- }
575
- index++;
576
- }
577
- if (!closed) return false;
578
- canEndExpression = true;
579
- continue;
580
- }
581
- if (isIdentifierStart(char) || char === 92 && source.charCodeAt(index + 1) === 117) {
582
- const start = index;
583
- if (char === 92) {
584
- index += 2;
585
- if (source.charCodeAt(index) === 123) {
586
- const end = source.indexOf("}", index + 1);
587
- if (end === -1) return false;
588
- index = end + 1;
589
- } else {
590
- for (let digit = 0; digit < 4; digit++) {
591
- const hex = source.charCodeAt(index + digit);
592
- if (!(hex >= 48 && hex <= 57 || hex >= 65 && hex <= 70 || hex >= 97 && hex <= 102)) return false;
593
- }
594
- index += 4;
595
- }
596
- } else index++;
597
- while (index < source.length) {
598
- const identifierChar = source.charCodeAt(index);
599
- if (isIdentifierPart(identifierChar)) {
600
- index++;
601
- continue;
602
- }
603
- if (identifierChar === 92 && source.charCodeAt(index + 1) === 117) {
604
- index += 2;
605
- if (source.charCodeAt(index) === 123) {
606
- const end = source.indexOf("}", index + 1);
607
- if (end === -1) return false;
608
- index = end + 1;
609
- } else {
610
- for (let digit = 0; digit < 4; digit++) {
611
- const hex = source.charCodeAt(index + digit);
612
- if (!(hex >= 48 && hex <= 57 || hex >= 65 && hex <= 70 || hex >= 97 && hex <= 102)) return false;
613
- }
614
- index += 4;
615
- }
616
- continue;
617
- }
618
- break;
619
- }
620
- const value = decodeIdentifier(source.slice(start, index));
621
- if (value === void 0) return false;
622
- tokens.push({
623
- k: "i",
624
- value
625
- });
626
- canEndExpression = !prefixKeywords.has(value);
627
- continue;
628
- }
629
- if (char >= 48 && char <= 57) {
630
- index++;
631
- while (isIdentifierPart(source.charCodeAt(index))) index++;
632
- canEndExpression = true;
633
- continue;
634
- }
635
- if (templateExpression) {
636
- if (char === 123) templateDepth++;
637
- else if (char === 125) {
638
- if (templateDepth === 0) {
639
- index++;
640
- return true;
641
- }
642
- templateDepth--;
643
- }
644
- }
645
- let value = source[index];
646
- const pair = source.slice(index, index + 2);
647
- const triple = source.slice(index, index + 3);
648
- if (triple === "...") value = triple;
649
- else if (pair === "?." || pair === "=>" || pair === "++" || pair === "--") value = pair;
650
- tokens.push({
651
- k: "p",
652
- value
653
- });
654
- index += value.length;
655
- if (value !== "++" && value !== "--") canEndExpression = value === ")" || value === "]" || value === "}";
656
- }
657
- return !templateExpression;
658
- };
659
- return scanCode() ? tokens : void 0;
660
- }
661
42
  const channel = (value) => {
662
43
  switch (value) {
663
44
  case "query":
@@ -669,27 +50,24 @@ const channel = (value) => {
669
50
  case "defer": return "afterResponse";
670
51
  }
671
52
  };
672
- function computedDestructuringChannel(tokens, index) {
53
+ function computedDestructuringChannel(tokens, index, channelOf) {
673
54
  const property = tokens[index + 1];
674
- return property?.k === "s" && !property.value.includes("\\") && tokens[index + 2]?.value === "]" && channel(property.value) || false;
55
+ return property?.k === "s" && !property.value.includes("\\") && tokens[index + 2]?.value === "]" && channelOf(property.value) || false;
675
56
  }
676
- function inferFunction(source) {
677
- const inference = defaultSucrose();
678
- if (!source || source.includes("[native code]") || source.trimStart().startsWith("class")) {
679
- markAllAccessed(inference);
680
- return inference;
681
- }
57
+ /**
58
+ * @internal Which `channelOf`-mapped members of a function's first parameter
59
+ * the function may read, or `null` when any member may be read
60
+ */
61
+ function inferFunction(source, channelOf, strict = false) {
62
+ if (!source || source.includes("[native code]") || source.trimStart().startsWith("class")) return null;
682
63
  let tokens;
683
64
  try {
684
65
  tokens = scanTokens(source);
685
66
  } catch {
686
- markAllAccessed(inference);
687
- return inference;
688
- }
689
- if (!tokens?.length) {
690
- markAllAccessed(inference);
691
- return inference;
67
+ return null;
692
68
  }
69
+ if (!tokens?.length) return null;
70
+ const keys = /* @__PURE__ */ new Set();
693
71
  let arrow = -1;
694
72
  const callableStart = tokens[0].value === "async" ? 1 : 0;
695
73
  if (tokens[callableStart]?.value !== "function") {
@@ -740,10 +118,7 @@ function inferFunction(source) {
740
118
  }
741
119
  break;
742
120
  }
743
- if (parameterStart < 0 || parameterEnd < parameterStart || bodyStart < 0) {
744
- markAllAccessed(inference);
745
- return inference;
746
- }
121
+ if (parameterStart < 0 || parameterEnd < parameterStart || bodyStart < 0) return null;
747
122
  const aliases = /* @__PURE__ */ new Set();
748
123
  const first = tokens[parameterStart];
749
124
  if (parameterStart === parameterEnd) {} else if (first?.k === "i") aliases.add(first.value);
@@ -753,25 +128,25 @@ function inferFunction(source) {
753
128
  const token = tokens[i];
754
129
  if (token.value === "{") depth++;
755
130
  else if (token.value === "}") depth--;
131
+ else if (token.value === "," && depth === 0) break;
756
132
  else if (token.value === "[" && depth === 1 && (tokens[i - 1]?.value === "{" || tokens[i - 1]?.value === ",")) {
757
- const computed = computedDestructuringChannel(tokens, i);
758
- if (computed === false) {
759
- markAllAccessed(inference);
760
- return inference;
761
- }
762
- if (computed) inference[computed] = true;
133
+ const computed = computedDestructuringChannel(tokens, i, channelOf);
134
+ if (computed === false) return null;
135
+ keys.add(computed);
763
136
  } else if (token.value === "..." && depth === 1) {
764
137
  const rest = tokens[i + 1];
765
138
  if (rest?.k === "i") aliases.add(rest.value);
766
139
  } else if (token.k === "i" && depth === 1) {
767
- const key = channel(token.value);
768
- if (key) inference[key] = true;
140
+ if (token.value === "ws" && (tokens[i - 1]?.value === "{" || tokens[i - 1]?.value === ",")) {
141
+ const renamed = tokens[i + 1]?.value === ":" && tokens[i + 2]?.k === "i" ? tokens[i + 2].value : token.value;
142
+ aliases.add(renamed);
143
+ continue;
144
+ }
145
+ const key = channelOf(token.value);
146
+ if (key) keys.add(key);
769
147
  }
770
148
  }
771
- } else {
772
- markAllAccessed(inference);
773
- return inference;
774
- }
149
+ } else return null;
775
150
  const patterns = [];
776
151
  let closedPattern;
777
152
  for (let i = bodyStart; i < tokens.length; i++) {
@@ -788,28 +163,28 @@ function inferFunction(source) {
788
163
  if (patterns.length) {
789
164
  const current = patterns[patterns.length - 1];
790
165
  if (token.value === "[" && (tokens[i - 1]?.value === "{" || tokens[i - 1]?.value === ",")) {
791
- const computed = computedDestructuringChannel(tokens, i);
166
+ const computed = computedDestructuringChannel(tokens, i, channelOf);
792
167
  current[0].add(computed);
793
168
  } else if (token.value === "..." && tokens[i + 1]?.k === "i") current[1] = tokens[i + 1].value;
794
169
  else if (token.k === "i") {
795
- const key = channel(token.value);
170
+ const key = channelOf(token.value);
796
171
  if (key) current[0].add(key);
797
172
  }
798
173
  }
799
174
  if (token.value === "=") {
800
175
  const right = tokens[i + 1];
801
176
  let member = i + 2;
802
- if (tokens[member]?.value === "?.") member++;
803
- if (right?.k === "i" && aliases.has(right.value) && tokens[member]?.value !== "." && tokens[member]?.value !== "[" && tokens[member]?.k !== "i") {
177
+ const optional = tokens[member]?.value === "?.";
178
+ if (optional) member++;
179
+ if (right?.k === "i" && aliases.has(right.value) && tokens[member]?.value !== "." && tokens[member]?.value !== "[" && (tokens[member]?.k !== "i" || strict && !optional)) {
804
180
  const left = tokens[i - 1];
805
- if (left?.k === "i") aliases.add(left.value);
806
- else if (left?.value === "}" && closedPattern) {
181
+ if (left?.k === "i") {
182
+ if (strict) return null;
183
+ aliases.add(left.value);
184
+ } else if (left?.value === "}" && closedPattern) {
807
185
  for (const key of closedPattern[0]) {
808
- if (key === false) {
809
- markAllAccessed(inference);
810
- return inference;
811
- }
812
- inference[key] = true;
186
+ if (key === false) return null;
187
+ keys.add(key);
813
188
  }
814
189
  if (closedPattern[1]) aliases.add(closedPattern[1]);
815
190
  }
@@ -817,64 +192,61 @@ function inferFunction(source) {
817
192
  continue;
818
193
  }
819
194
  if (token.k !== "i") continue;
820
- if (token.value === "arguments" || token.value === "eval") {
821
- markAllAccessed(inference);
822
- break;
823
- }
195
+ if (token.value === "arguments" || token.value === "eval") return null;
824
196
  if (!aliases.has(token.value)) continue;
197
+ if (i + 1 < tokens.length) {
198
+ for (let j = token.at + 1; j < tokens[i + 1].at; j++) if (source.charCodeAt(j) === 96) return null;
199
+ }
825
200
  let next = i + 1;
826
201
  if (tokens[next]?.value === "?.") next++;
827
202
  if (tokens[next]?.value === ".") next++;
828
203
  if (tokens[next]?.k === "i" && next > i + 1) {
829
- const key = channel(tokens[next].value);
830
- if (key) inference[key] = true;
204
+ const key = channelOf(tokens[next].value);
205
+ if (key) keys.add(key);
831
206
  continue;
832
207
  }
833
208
  if (tokens[next]?.value === "[") {
834
209
  const property = tokens[next + 1];
835
- const key = property?.k === "s" && channel(property.value);
836
- if (key && tokens[next + 2]?.value === "]") inference[key] = true;
837
- else markAllAccessed(inference);
838
- if (inference.query && inference.headers && inference.body && inference.cookie && inference.set && inference.route && inference.afterResponse) break;
210
+ const key = property?.k === "s" && channelOf(property.value);
211
+ if (!key || tokens[next + 2]?.value !== "]") return null;
212
+ keys.add(key);
839
213
  continue;
840
214
  }
841
215
  if (tokens[i - 1]?.value === "=" && (tokens[i - 2]?.k === "i" || tokens[i - 2]?.value === "}")) continue;
842
- markAllAccessed(inference);
843
- break;
216
+ return null;
844
217
  }
845
- return inference;
218
+ return keys;
846
219
  }
847
- const eventsBuffer = [];
848
- let eventsBufferInUse = false;
220
+ const lifeCycleEvents = [
221
+ "request",
222
+ "beforeHandle",
223
+ "parse",
224
+ "error",
225
+ "transform",
226
+ "afterHandle",
227
+ "mapResponse",
228
+ "afterResponse"
229
+ ];
849
230
  function sucrose(handler, lifeCycle) {
850
231
  let inference;
851
232
  let merged = false;
852
- const reentrant = eventsBufferInUse;
853
- const events = reentrant ? [] : eventsBuffer;
854
- eventsBufferInUse = true;
855
- try {
856
- if (handler && typeof handler === "function") events.push(handler);
857
- if (lifeCycle) {
858
- if (lifeCycle.request?.length) push(events, lifeCycle.request);
859
- if (lifeCycle.beforeHandle?.length) push(events, lifeCycle.beforeHandle);
860
- if (lifeCycle.parse?.length) pushParse(events, lifeCycle.parse);
861
- if (lifeCycle.error?.length) push(events, lifeCycle.error);
862
- if (lifeCycle.transform?.length) push(events, lifeCycle.transform);
863
- if (lifeCycle.afterHandle?.length) push(events, lifeCycle.afterHandle);
864
- if (lifeCycle.mapResponse?.length) push(events, lifeCycle.mapResponse);
865
- if (lifeCycle.afterResponse?.length) push(events, lifeCycle.afterResponse);
233
+ const events = [];
234
+ if (handler && typeof handler === "function") events.push(handler);
235
+ if (lifeCycle) for (const name of lifeCycleEvents) {
236
+ const array = lifeCycle[name];
237
+ if (array) {
238
+ for (let i = 0; i < array.length; i++) if (name !== "parse" || typeof array[i] === "function") events.push(array[i]);
866
239
  }
867
- const caches = sourceCache();
868
- for (let i = 0; i < events.length; i++) {
869
- const event = events[i];
870
- if (!event) continue;
871
- let inferred = functionCaches.get(event);
872
- if (!inferred) if (typeof event === "function" && Object.hasOwn(event, "toString")) {
873
- const forged = defaultSucrose();
874
- markAllAccessed(forged);
875
- inferred = Object.freeze(forged);
876
- functionCaches.set(event, inferred);
877
- } else {
240
+ }
241
+ const session = getCompilerSession();
242
+ const caches = session?.external ? session.sucroseCache : globalSourceCache;
243
+ for (let i = 0; i < events.length; i++) {
244
+ const event = events[i];
245
+ if (!event) continue;
246
+ let inferred = functionCaches.get(event);
247
+ if (!inferred) {
248
+ if (typeof event === "function" && Object.hasOwn(event, "toString")) inferred = allAccessed;
249
+ else {
878
250
  const content = event.toString();
879
251
  const key = fnv1a(content);
880
252
  const cached = caches.get(key);
@@ -884,25 +256,31 @@ function sucrose(handler, lifeCycle) {
884
256
  caches.delete(key);
885
257
  caches.set(key, cached);
886
258
  }
887
- if (typeof event === "function") functionCaches.set(event, inferred);
888
259
  } else {
889
- inferred = Object.freeze(inferFunction(content));
890
- rememberInference(caches, key, cached, content, event, inferred);
260
+ const channels = inferFunction(content, channel);
261
+ if (channels) {
262
+ const fresh = defaultSucrose();
263
+ for (const c of channels) fresh[c] = true;
264
+ inferred = Object.freeze(fresh);
265
+ } else inferred = allAccessed;
266
+ if (caches.size >= DEFAULT_CACHE_LIMIT) evictOldestHalf(caches);
267
+ caches.set(key, {
268
+ content,
269
+ inference: inferred
270
+ });
891
271
  }
892
272
  }
893
- if (inference) {
894
- inference = mergeInference(inference, inferred);
895
- merged = true;
896
- } else inference = inferred;
897
- if (inference.query && inference.headers && inference.body && inference.cookie && inference.set && inference.route && inference.afterResponse) break;
273
+ if (typeof event === "function") functionCaches.set(event, inferred);
898
274
  }
899
- } finally {
900
- events.length = 0;
901
- eventsBufferInUse = reentrant;
275
+ if (inference) {
276
+ inference = mergeInference(inference, inferred);
277
+ merged = true;
278
+ } else inference = inferred;
279
+ if (isAllAccessed(inference)) break;
902
280
  }
903
281
  if (!inference) return emptyInference;
904
282
  return merged ? Object.freeze(inference) : inference;
905
283
  }
906
284
 
907
285
  //#endregion
908
- export { bracketPairRange, bracketPairRangeReverse, clearSucroseCache, findAlias, mergeInference, removeColonAlias, removeDefaultParameter, retrieveRootparameters, separateFunction, sucrose };
286
+ export { clearSucroseCache, inferFunction, mergeInference, sucrose };