elysia 2.0.0-beta.21 → 2.0.0-beta.23
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/_virtual/_rolldown/runtime.mjs +1 -0
- package/dist/adapter/bun/index.d.ts +6 -8
- package/dist/adapter/bun/index.js +6 -8
- package/dist/adapter/bun/index.mjs +7 -8
- package/dist/adapter/constants.mjs +1 -0
- package/dist/adapter/default-headers.mjs +1 -0
- package/dist/adapter/index.mjs +1 -0
- package/dist/adapter/origin.mjs +1 -0
- package/dist/adapter/response-ownership.mjs +1 -0
- package/dist/adapter/skip-clone.mjs +1 -0
- package/dist/adapter/types.mjs +1 -0
- package/dist/adapter/utils.d.ts +5 -8
- package/dist/adapter/utils.js +24 -18
- package/dist/adapter/utils.mjs +25 -18
- package/dist/adapter/web-standard/handler.mjs +2 -1
- package/dist/adapter/web-standard/index.mjs +1 -0
- package/dist/adapter/web-standard/utils.mjs +1 -0
- package/dist/base.d.ts +118 -69
- package/dist/base.js +214 -194
- package/dist/base.mjs +221 -200
- package/dist/compile/aot-capture.js +2 -2
- package/dist/compile/aot-capture.mjs +4 -3
- package/dist/compile/aot-emit.js +7 -8
- package/dist/compile/aot-emit.mjs +8 -8
- package/dist/compile/aot-reconstruct.mjs +3 -2
- package/dist/compile/aot.d.ts +3 -3
- package/dist/compile/aot.js +5 -5
- package/dist/compile/aot.mjs +6 -5
- package/dist/compile/handler/descriptor.d.ts +2 -5
- package/dist/compile/handler/descriptor.js +12 -17
- package/dist/compile/handler/descriptor.mjs +16 -21
- package/dist/compile/handler/frozen-validator.d.ts +2 -2
- package/dist/compile/handler/frozen-validator.js +3 -3
- package/dist/compile/handler/frozen-validator.mjs +4 -3
- package/dist/compile/handler/index.d.ts +3 -1
- package/dist/compile/handler/index.js +78 -118
- package/dist/compile/handler/index.mjs +84 -125
- package/dist/compile/handler/jit.d.ts +12 -12
- package/dist/compile/handler/jit.js +60 -43
- package/dist/compile/handler/jit.mjs +63 -47
- package/dist/compile/handler/params.d.ts +5 -1
- package/dist/compile/handler/params.js +14 -5
- package/dist/compile/handler/params.mjs +16 -7
- package/dist/compile/handler/reconstruct.d.ts +2 -2
- package/dist/compile/handler/reconstruct.js +2 -2
- package/dist/compile/handler/reconstruct.mjs +3 -2
- package/dist/compile/handler/static-clone-resolver.mjs +1 -0
- package/dist/compile/handler/utils.d.ts +13 -7
- package/dist/compile/handler/utils.js +75 -52
- package/dist/compile/handler/utils.mjs +77 -54
- package/dist/compile/jit-probe.mjs +1 -0
- package/dist/compile/lexer.js +4 -4
- package/dist/compile/lexer.mjs +5 -4
- package/dist/compile/utils.d.ts +2 -1
- package/dist/compile/utils.js +8 -3
- package/dist/compile/utils.mjs +8 -3
- package/dist/compiled.mjs +1 -0
- package/dist/constants.mjs +1 -0
- package/dist/context.d.ts +1 -1
- package/dist/context.js +1 -0
- package/dist/context.mjs +3 -1
- package/dist/cookie/config.d.ts +2 -2
- package/dist/cookie/config.js +21 -26
- package/dist/cookie/config.mjs +22 -26
- package/dist/cookie/cookie.mjs +1 -0
- package/dist/cookie/crypto.mjs +1 -0
- package/dist/cookie/error.mjs +1 -0
- package/dist/cookie/lib.mjs +1 -0
- package/dist/cookie/serialize.mjs +1 -0
- package/dist/cookie/types.mjs +1 -0
- package/dist/cookie/utils.d.ts +1 -1
- package/dist/cookie/utils.js +64 -45
- package/dist/cookie/utils.mjs +66 -46
- package/dist/error.d.ts +10 -6
- package/dist/error.js +22 -6
- package/dist/error.mjs +25 -9
- package/dist/generation.mjs +1 -0
- package/dist/handler/error.d.ts +12 -15
- package/dist/handler/error.js +43 -40
- package/dist/handler/error.mjs +45 -41
- package/dist/handler/fetch.js +59 -21
- package/dist/handler/fetch.mjs +61 -22
- package/dist/handler/utils.d.ts +16 -3
- package/dist/handler/utils.js +14 -13
- package/dist/handler/utils.mjs +16 -15
- package/dist/index.d.ts +9 -9
- package/dist/index.js +1 -0
- package/dist/index.mjs +3 -2
- package/dist/memory.mjs +1 -0
- package/dist/package.js +1 -1
- package/dist/package.mjs +2 -1
- package/dist/parse-query.js +76 -76
- package/dist/parse-query.mjs +77 -76
- package/dist/plugin/aot/bun.mjs +1 -0
- package/dist/plugin/aot/core.d.ts +1 -1
- package/dist/plugin/aot/core.js +7 -4
- package/dist/plugin/aot/core.mjs +8 -5
- package/dist/plugin/aot/esbuild.mjs +1 -0
- package/dist/plugin/aot/rspack-loader.mjs +1 -0
- package/dist/plugin/aot/rspack.mjs +1 -0
- package/dist/plugin/aot/treeshake.mjs +1 -0
- package/dist/plugin/aot/unplugin.mjs +4 -3
- package/dist/plugin/aot/vite.mjs +1 -0
- package/dist/plugin/aot/worker.mjs +1 -0
- package/dist/plugin/auto-head.mjs +1 -0
- package/dist/plugin/trace.mjs +1 -0
- package/dist/plugin/websocket.mjs +1 -0
- package/dist/route-table.mjs +1 -0
- package/dist/schema-snapshot.js +28 -3
- package/dist/schema-snapshot.mjs +29 -3
- package/dist/sucrose.d.ts +2 -2
- package/dist/sucrose.js +11 -11
- package/dist/sucrose.mjs +12 -11
- package/dist/trace.js +8 -10
- package/dist/trace.mjs +10 -11
- package/dist/type/bridge-live.d.ts +1 -1
- package/dist/type/bridge-live.mjs +1 -0
- package/dist/type/bridge.d.ts +1 -1
- package/dist/type/bridge.mjs +1 -0
- package/dist/type/coerce-plan.mjs +1 -0
- package/dist/type/coerce.d.ts +1 -1
- package/dist/type/coerce.mjs +1 -0
- package/dist/type/compat.mjs +1 -0
- package/dist/type/constants.d.ts +1 -1
- package/dist/type/constants.mjs +1 -0
- package/dist/type/elysia/accelerate.mjs +1 -0
- package/dist/type/elysia/array-buffer.d.ts +3 -2
- package/dist/type/elysia/array-buffer.js +5 -5
- package/dist/type/elysia/array-buffer.mjs +6 -5
- package/dist/type/elysia/array-string.mjs +1 -0
- package/dist/type/elysia/array.mjs +1 -0
- package/dist/type/elysia/boolean-string.mjs +1 -0
- package/dist/type/elysia/boolean.mjs +1 -0
- package/dist/type/elysia/cookie.mjs +1 -0
- package/dist/type/elysia/date.mjs +1 -0
- package/dist/type/elysia/file-type.mjs +1 -0
- package/dist/type/elysia/file.mjs +1 -0
- package/dist/type/elysia/files.mjs +1 -0
- package/dist/type/elysia/form.mjs +1 -0
- package/dist/type/elysia/integer-string.mjs +1 -0
- package/dist/type/elysia/integer.mjs +1 -0
- package/dist/type/elysia/intersect.mjs +1 -0
- package/dist/type/elysia/json-string.mjs +1 -0
- package/dist/type/elysia/keep-config.js +8 -8
- package/dist/type/elysia/keep-config.mjs +9 -8
- package/dist/type/elysia/maybe-empty.mjs +1 -0
- package/dist/type/elysia/no-validate.mjs +1 -0
- package/dist/type/elysia/nullable.mjs +1 -0
- package/dist/type/elysia/number.mjs +1 -0
- package/dist/type/elysia/numeric-enum.d.ts +4 -2
- package/dist/type/elysia/numeric-enum.mjs +1 -0
- package/dist/type/elysia/numeric.mjs +1 -0
- package/dist/type/elysia/object-string.mjs +1 -0
- package/dist/type/elysia/object.mjs +1 -0
- package/dist/type/elysia/optional.mjs +1 -0
- package/dist/type/elysia/problem.mjs +1 -0
- package/dist/type/elysia/string.mjs +1 -0
- package/dist/type/elysia/uint8-array.d.ts +2 -1
- package/dist/type/elysia/uint8-array.js +2 -2
- package/dist/type/elysia/uint8-array.mjs +3 -2
- package/dist/type/elysia/union-enum.mjs +1 -0
- package/dist/type/elysia/union.mjs +1 -0
- package/dist/type/elysia/utils.js +3 -3
- package/dist/type/elysia/utils.mjs +4 -3
- package/dist/type/exports.mjs +1 -0
- package/dist/type/index.mjs +2 -1
- package/dist/type/shared.mjs +1 -0
- package/dist/type/sync-require.mjs +1 -0
- package/dist/type/typebox-system-lite.mjs +1 -0
- package/dist/type/typebox-system-require.mjs +1 -0
- package/dist/type/typebox-type-live.mjs +1 -0
- package/dist/type/typebox-value-live.mjs +1 -0
- package/dist/type/typebox-value-ops.mjs +1 -0
- package/dist/type/typebox-value.mjs +1 -0
- package/dist/type/types.d.ts +1 -1
- package/dist/type/types.mjs +1 -0
- package/dist/type/utils.mjs +1 -0
- package/dist/type/validator/clean-safe.mjs +1 -0
- package/dist/type/validator/custom-error.js +41 -33
- package/dist/type/validator/custom-error.mjs +42 -33
- package/dist/type/validator/default-precompute.d.ts +2 -2
- package/dist/type/validator/default-precompute.js +10 -11
- package/dist/type/validator/default-precompute.mjs +13 -13
- package/dist/type/validator/exact-mirror.mjs +1 -0
- package/dist/type/validator/frozen-check.js +7 -7
- package/dist/type/validator/frozen-check.mjs +8 -7
- package/dist/type/validator/index.d.ts +2 -2
- package/dist/type/validator/index.js +4 -8
- package/dist/type/validator/index.mjs +5 -8
- package/dist/type/validator/string-codec-aot.d.ts +1 -1
- package/dist/type/validator/string-codec-aot.mjs +1 -0
- package/dist/type/validator/validator-cache.js +18 -18
- package/dist/type/validator/validator-cache.mjs +19 -18
- package/dist/types.d.ts +108 -70
- package/dist/types.mjs +1 -0
- package/dist/universal/constants.mjs +1 -0
- package/dist/universal/file.mjs +1 -0
- package/dist/universal/index.mjs +1 -0
- package/dist/universal/is-production.mjs +1 -0
- package/dist/universal/server.mjs +1 -0
- package/dist/utils.d.ts +49 -31
- package/dist/utils.js +221 -109
- package/dist/utils.mjs +215 -106
- package/dist/validator/index.d.ts +3 -3
- package/dist/validator/index.js +4 -4
- package/dist/validator/index.mjs +5 -4
- package/dist/validator/route.d.ts +2 -2
- package/dist/validator/route.mjs +1 -0
- package/dist/ws/context.js +1 -1
- package/dist/ws/context.mjs +2 -1
- package/dist/ws/index.mjs +1 -0
- package/dist/ws/parser.mjs +1 -0
- package/dist/ws/route.js +34 -25
- package/dist/ws/route.mjs +40 -30
- package/dist/ws/types.d.ts +2 -3
- package/dist/ws/types.mjs +1 -0
- package/package.json +2 -2
package/dist/base.mjs
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
|
+
// @bun
|
|
1
2
|
import { isBun } from "./universal/constants.mjs";
|
|
2
|
-
import { clearFlattenChainMemo, clonePlainDecorators, clonePlainDeep, coalesceSchemas, createErrorEventHandler, eventProperties,
|
|
3
|
+
import { clearFlattenChainMemo, clonePlainDecorators, clonePlainDeep, coalesceSchemas, createErrorEventHandler, eventProperties, getLoosePath, guardNonPlainLeaves, hookToGuard, invalidateMacroEpoch, isEmpty, isHTMLBundle, isNotEmpty, isPlainObject, isRecordNumber, joinPath, macroOrigin, mapDeriveEntry, markPropertySingletons, markSingletons, mergeDeep, mergeResponse, nullObject, pluginHash, pluginId, schemaProperties, serializeMacroSeed, throwLifecycleErrors } from "./utils.mjs";
|
|
3
4
|
import { Ref, warmTypebox } from "./type/bridge.mjs";
|
|
4
5
|
import { isProduction } from "./universal/is-production.mjs";
|
|
5
6
|
import { Capture, Compiled, beginCompilerSession, createAotFingerprint, endCompilerSession } from "./compile/aot.mjs";
|
|
6
7
|
import { traceCapabilityRequired, wsCapabilityRequired } from "./generation.mjs";
|
|
7
|
-
import {
|
|
8
|
+
import { releaseAnalysisCaches } from "./compile/handler/descriptor.mjs";
|
|
9
|
+
import { chainResolver, clearHandlerAnalysisCaches, compileHandler, composeRouteHook, localMacroRoot, resolveLocalHook, runIntrospect } from "./compile/handler/index.mjs";
|
|
8
10
|
import { RouteFlag, buildRouteTable, routeRow } from "./route-table.mjs";
|
|
9
11
|
import { BunAdapter } from "./adapter/bun/index.mjs";
|
|
10
12
|
import { clearContextCache } from "./context.mjs";
|
|
@@ -14,6 +16,9 @@ import Memoirist from "memoirist";
|
|
|
14
16
|
|
|
15
17
|
//#region src/base.ts
|
|
16
18
|
const useNodesBuffer = [];
|
|
19
|
+
const propagatedRegistrations = /* @__PURE__ */ new WeakMap();
|
|
20
|
+
const liftedRequests = /* @__PURE__ */ new WeakMap();
|
|
21
|
+
const hocOriginOf = (o) => typeof o === "object" ? o.origin : o;
|
|
17
22
|
const emptyHistory = Object.freeze([]);
|
|
18
23
|
let mutationEpoch = 0;
|
|
19
24
|
const extCallbackIndexes = /* @__PURE__ */ new WeakMap();
|
|
@@ -39,6 +44,13 @@ const markStoredSingletons = (table, source) => {
|
|
|
39
44
|
if (!table) return;
|
|
40
45
|
for (const key in source) markSingletons(table[key]);
|
|
41
46
|
};
|
|
47
|
+
const sharedTables = [
|
|
48
|
+
"decorator",
|
|
49
|
+
"store",
|
|
50
|
+
"headers",
|
|
51
|
+
"models",
|
|
52
|
+
"parser"
|
|
53
|
+
];
|
|
42
54
|
const canRegisterLoose = (path, isDynamic) => !isDynamic && (path.length === 0 || path.charCodeAt(path.length - 1) === 47);
|
|
43
55
|
const isSingleSchema = (value) => "~kind" in value || "~elyAcl" in value || "~standard" in value;
|
|
44
56
|
const isSchemaValue = (value) => {
|
|
@@ -78,7 +90,7 @@ function assertSchemaShape(hook, where) {
|
|
|
78
90
|
}
|
|
79
91
|
if (isStatusMap) continue;
|
|
80
92
|
}
|
|
81
|
-
throw new Error(`[Elysia] ${where}: "${key}" is not a schema
|
|
93
|
+
throw new Error(`[Elysia] ${where}: "${key}" is not a schema \u2014 use t.Object({ ... })`);
|
|
82
94
|
}
|
|
83
95
|
}
|
|
84
96
|
/**
|
|
@@ -105,6 +117,7 @@ function expandPaths(path, needsEncode, registerLoose, explicit) {
|
|
|
105
117
|
return paths;
|
|
106
118
|
}
|
|
107
119
|
var Elysia = class Elysia {
|
|
120
|
+
#pending = 0;
|
|
108
121
|
get history() {
|
|
109
122
|
const generation = this["~generation"];
|
|
110
123
|
if (this.#isCacheable && this.cachedGeneration === generation && this.cachedEpoch === mutationEpoch && this.cachedHistory !== void 0) return this.cachedHistory;
|
|
@@ -158,8 +171,6 @@ var Elysia = class Elysia {
|
|
|
158
171
|
return this;
|
|
159
172
|
}
|
|
160
173
|
constructor(config) {
|
|
161
|
-
this._pending = 0;
|
|
162
|
-
this.routerBuilt = false;
|
|
163
174
|
/**
|
|
164
175
|
* ! Don't tune
|
|
165
176
|
*
|
|
@@ -205,7 +216,7 @@ var Elysia = class Elysia {
|
|
|
205
216
|
if (config) {
|
|
206
217
|
const { prefix, name, seed, adapter } = config;
|
|
207
218
|
this["~Prefix"] = prefix ? prefix.charCodeAt(0) === 47 ? prefix : `/${prefix}` : void 0;
|
|
208
|
-
if (name) this.hash =
|
|
219
|
+
if (name) this.hash = pluginHash(JSON.stringify(seed === void 0 ? [name] : [name, seed], serializeMacroSeed));
|
|
209
220
|
if (adapter?.setup) this.#useFn(adapter.setup);
|
|
210
221
|
} else this["~Prefix"] = void 0;
|
|
211
222
|
}
|
|
@@ -221,11 +232,12 @@ var Elysia = class Elysia {
|
|
|
221
232
|
if (!this.declaredRoutes?.length) return [];
|
|
222
233
|
const routes = this["~routes"].map(([method, path, handler, instance, hook, appHook, inheritedChain, macroScope]) => {
|
|
223
234
|
const merged = composeRouteHook(instance, hook, appHook, inheritedChain, this, macroScope);
|
|
235
|
+
runIntrospect(merged);
|
|
224
236
|
if (merged?.schemas?.length) for (const entry of merged.schemas) {
|
|
225
237
|
if (!entry?.response) continue;
|
|
226
238
|
merged.response = mergeResponse(merged.response, entry.response);
|
|
227
239
|
}
|
|
228
|
-
if (merged?.response
|
|
240
|
+
if (merged?.response) merged.response = isRecordNumber(merged.response) ? { ...merged.response } : { 200: merged.response };
|
|
229
241
|
return {
|
|
230
242
|
method,
|
|
231
243
|
path,
|
|
@@ -243,10 +255,10 @@ var Elysia = class Elysia {
|
|
|
243
255
|
decorate(typeOrNameOrDecorators, nameOrDecorators, value) {
|
|
244
256
|
return this.#setField("decorator", arguments.length, typeOrNameOrDecorators, nameOrDecorators, value);
|
|
245
257
|
}
|
|
246
|
-
#setField(field,
|
|
258
|
+
#setField(field, argCount, typeOrName, nameOrValue, value) {
|
|
247
259
|
let as = "append";
|
|
248
260
|
let name = "";
|
|
249
|
-
switch (
|
|
261
|
+
switch (argCount) {
|
|
250
262
|
case 1:
|
|
251
263
|
value = typeOrName;
|
|
252
264
|
break;
|
|
@@ -261,10 +273,11 @@ var Elysia = class Elysia {
|
|
|
261
273
|
break;
|
|
262
274
|
default: return this;
|
|
263
275
|
}
|
|
264
|
-
this.#
|
|
265
|
-
const ext = this
|
|
266
|
-
|
|
267
|
-
|
|
276
|
+
this.#assertTableMutable(field === "store" ? "state" : "decorate");
|
|
277
|
+
const ext = this.#ext;
|
|
278
|
+
let fresh = true;
|
|
279
|
+
for (let app = this; fresh && app; app = app.scopeParent) fresh = !app["~ext"]?.[field];
|
|
280
|
+
const target = this.#table(field);
|
|
268
281
|
switch (typeof value) {
|
|
269
282
|
case "object":
|
|
270
283
|
if (!value) return this;
|
|
@@ -300,9 +313,8 @@ var Elysia = class Elysia {
|
|
|
300
313
|
return this.#setField("store", arguments.length, typeOrNameOrStore, nameOrStore, value);
|
|
301
314
|
}
|
|
302
315
|
headers(headers) {
|
|
303
|
-
this.#
|
|
304
|
-
|
|
305
|
-
ext.headers = Object.assign(ext.headers ?? nullObject(), headers);
|
|
316
|
+
this.#assertTableMutable("headers");
|
|
317
|
+
Object.assign(this.#table("headers"), headers);
|
|
306
318
|
return this;
|
|
307
319
|
}
|
|
308
320
|
#on(type, fn, scope = this["~config"]?.as) {
|
|
@@ -311,32 +323,30 @@ var Elysia = class Elysia {
|
|
|
311
323
|
const added = nullObject();
|
|
312
324
|
added[type] = fn;
|
|
313
325
|
if (type === "trace") this["~hasTrace"] = true;
|
|
314
|
-
this.#
|
|
315
|
-
this.#tagOrigin(fn);
|
|
326
|
+
this.#pushChainNode(added, scope);
|
|
316
327
|
return this;
|
|
317
328
|
}
|
|
318
|
-
#
|
|
329
|
+
#pushChainNode(added, scope, registration, origin, owner) {
|
|
319
330
|
const parent = this["~hookChain"];
|
|
320
|
-
const refs = parent !== void 0 && parent.refs ||
|
|
321
|
-
this["~hookChain"] =
|
|
331
|
+
const refs = parent !== void 0 && parent.refs || Elysia.#hookHasString(added);
|
|
332
|
+
this["~hookChain"] = registration ? {
|
|
322
333
|
added,
|
|
323
334
|
parent,
|
|
324
335
|
refs,
|
|
325
336
|
scope,
|
|
326
|
-
propagated,
|
|
327
|
-
owner
|
|
337
|
+
propagated: true,
|
|
338
|
+
owner,
|
|
339
|
+
origin,
|
|
340
|
+
registration
|
|
328
341
|
} : {
|
|
329
342
|
added,
|
|
330
343
|
parent,
|
|
331
344
|
refs,
|
|
332
345
|
scope,
|
|
333
|
-
owner
|
|
346
|
+
owner: this,
|
|
347
|
+
origin: this.hash
|
|
334
348
|
};
|
|
335
349
|
}
|
|
336
|
-
#tagOrigin(value) {
|
|
337
|
-
if (this.hash === void 0) return;
|
|
338
|
-
for (const fn of Array.isArray(value) ? value : [value]) if (typeof fn === "function" && !fnOrigin.has(fn)) fnOrigin.set(fn, this.hash);
|
|
339
|
-
}
|
|
340
350
|
#onBranch(type, scopeOrFn, fn) {
|
|
341
351
|
return fn ? this.#on(type, fn, scopeOrFn) : this.#on(type, scopeOrFn);
|
|
342
352
|
}
|
|
@@ -351,9 +361,8 @@ var Elysia = class Elysia {
|
|
|
351
361
|
return this.#onBranch("parse", scopeOrFnOrName, fn);
|
|
352
362
|
}
|
|
353
363
|
parser(name, fn) {
|
|
354
|
-
this.#
|
|
355
|
-
const
|
|
356
|
-
const parsers = ext.parser ??= nullObject();
|
|
364
|
+
this.#assertTableMutable("parser");
|
|
365
|
+
const parsers = this.#table("parser");
|
|
357
366
|
parsers[name] = fn;
|
|
358
367
|
return this;
|
|
359
368
|
}
|
|
@@ -373,7 +382,7 @@ var Elysia = class Elysia {
|
|
|
373
382
|
*/
|
|
374
383
|
setup(handler) {
|
|
375
384
|
this.#assertMutable("setup");
|
|
376
|
-
(this
|
|
385
|
+
(this.#ext.setup ??= []).push(...[].concat(handler));
|
|
377
386
|
return this;
|
|
378
387
|
}
|
|
379
388
|
transform(scopeOrFn, fn) {
|
|
@@ -412,13 +421,13 @@ var Elysia = class Elysia {
|
|
|
412
421
|
if (scopeOrFnOrError && typeof scopeOrFnOrError === "object") return this;
|
|
413
422
|
return this.#onBranch("error", scopeOrFnOrError);
|
|
414
423
|
case 2:
|
|
415
|
-
if (typeof scopeOrFnOrError === "function" && scopeOrFnOrError.prototype instanceof Object) return this.#
|
|
424
|
+
if (typeof scopeOrFnOrError === "function" && scopeOrFnOrError.prototype instanceof Object) return this.#onErrorClass(scopeOrFnOrError, fnOrError);
|
|
416
425
|
return this.#onBranch("error", scopeOrFnOrError, fnOrError);
|
|
417
|
-
case 3: return this.#
|
|
426
|
+
case 3: return this.#onErrorClass(fnOrError, fn, scopeOrFnOrError);
|
|
418
427
|
}
|
|
419
428
|
return this;
|
|
420
429
|
}
|
|
421
|
-
#
|
|
430
|
+
#onErrorClass(ErrorClass, fn, scope) {
|
|
422
431
|
const run = typeof fn === "function" ? fn : () => fn;
|
|
423
432
|
return this.#on("error", createErrorEventHandler(run, ErrorClass), scope);
|
|
424
433
|
}
|
|
@@ -437,9 +446,10 @@ var Elysia = class Elysia {
|
|
|
437
446
|
node = node.over;
|
|
438
447
|
continue;
|
|
439
448
|
}
|
|
440
|
-
if (node.scope !== "global") {
|
|
449
|
+
if (node.scope !== "global" && (node.scope !== scope || node.propagated)) {
|
|
441
450
|
node.scope = scope;
|
|
442
451
|
node.propagated = false;
|
|
452
|
+
invalidateMacroEpoch();
|
|
443
453
|
}
|
|
444
454
|
node = node.parent;
|
|
445
455
|
}
|
|
@@ -459,13 +469,11 @@ var Elysia = class Elysia {
|
|
|
459
469
|
if (hook) assertSchemaShape(hook, ".guard()");
|
|
460
470
|
hook = snapshotHookSchemas(hook);
|
|
461
471
|
hookToGuard(hook);
|
|
462
|
-
for (const key in hook) if (eventProperties.has(key)) this.#tagOrigin(hook[key]);
|
|
463
|
-
this.#tagOrigin(hook.derive);
|
|
464
472
|
this.#pushHook(hook, scope);
|
|
465
473
|
return this;
|
|
466
474
|
}
|
|
467
475
|
group() {
|
|
468
|
-
this.#
|
|
476
|
+
this.#assertTableMutable("group");
|
|
469
477
|
const prefix = arguments[0];
|
|
470
478
|
const schemaOrRun = arguments[1];
|
|
471
479
|
const run = arguments[2];
|
|
@@ -484,12 +492,8 @@ var Elysia = class Elysia {
|
|
|
484
492
|
const src = this["~ext"];
|
|
485
493
|
if (src) {
|
|
486
494
|
const ext = child["~ext"] ??= nullObject();
|
|
487
|
-
if (src
|
|
488
|
-
if (src.store) ext.store = Object.assign(nullObject(), src.store);
|
|
489
|
-
if (src.headers) ext.headers = Object.assign(nullObject(), src.headers);
|
|
490
|
-
if (src.models) ext.models = Object.assign(nullObject(), src.models);
|
|
495
|
+
for (const field of sharedTables) if (src[field]) ext[field] = src[field];
|
|
491
496
|
if (src.macro) ext.macro = Object.create(src.macro);
|
|
492
|
-
if (src.parser) ext.parser = Object.assign(nullObject(), src.parser);
|
|
493
497
|
if (src.capability) {
|
|
494
498
|
const cap = ext.capability = nullObject();
|
|
495
499
|
if (src.capability.trace) cap.trace = src.capability.trace;
|
|
@@ -502,9 +506,13 @@ var Elysia = class Elysia {
|
|
|
502
506
|
this.#use(child);
|
|
503
507
|
return this;
|
|
504
508
|
}
|
|
505
|
-
get ext() {
|
|
509
|
+
get #ext() {
|
|
506
510
|
return this["~ext"] ??= nullObject();
|
|
507
511
|
}
|
|
512
|
+
/** A group child starts or takes up its parent's table, see `group()` */
|
|
513
|
+
#table(field) {
|
|
514
|
+
return this.#ext[field] ??= this.scopeParent ? this.scopeParent.#table(field) : nullObject();
|
|
515
|
+
}
|
|
508
516
|
["~resolvedCapability"](kind) {
|
|
509
517
|
if (kind === "ws") {
|
|
510
518
|
const ws = this["~ext"]?.capability?.ws;
|
|
@@ -521,7 +529,7 @@ var Elysia = class Elysia {
|
|
|
521
529
|
return provider;
|
|
522
530
|
}
|
|
523
531
|
#ensureMacroTable() {
|
|
524
|
-
const ext = this
|
|
532
|
+
const ext = this.#ext;
|
|
525
533
|
if (ext.macro) return ext.macro;
|
|
526
534
|
const parent = this["~scopeChild"] ? this.scopeParent : void 0;
|
|
527
535
|
ext.macro = parent ? Object.create(parent.#ensureMacroTable()) : nullObject();
|
|
@@ -540,13 +548,13 @@ var Elysia = class Elysia {
|
|
|
540
548
|
}
|
|
541
549
|
}
|
|
542
550
|
if (hook.trace) this["~hasTrace"] = true;
|
|
543
|
-
this.#
|
|
551
|
+
this.#pushChainNode(hook, scope);
|
|
544
552
|
return this;
|
|
545
553
|
}
|
|
546
554
|
macro(macro, definition) {
|
|
547
555
|
this.#assertMutable("macro");
|
|
548
556
|
if (typeof macro === "function") throw new Error("use `.macro({ name: fn })` instead of `.macro(fn)`");
|
|
549
|
-
if (definition != null || typeof macro === "string") throw new Error("[Elysia] .macro(name, definition) was removed in 2.0
|
|
557
|
+
if (definition != null || typeof macro === "string") throw new Error("[Elysia] .macro(name, definition) was removed in 2.0 \u2014 use .macro({ [name]: definition })");
|
|
550
558
|
const m = this.#ensureMacroTable();
|
|
551
559
|
const baseline = this.macroBaseline;
|
|
552
560
|
for (const key in macro) {
|
|
@@ -577,7 +585,7 @@ var Elysia = class Elysia {
|
|
|
577
585
|
const seedSource = hook.seed ?? value;
|
|
578
586
|
const seedType = typeof seedSource;
|
|
579
587
|
let seedKey;
|
|
580
|
-
if (seedSource === null || seedType !== "object") seedKey = key
|
|
588
|
+
if (seedSource === null || seedType !== "object") seedKey = `${key}\0${seedType}\0${serializeMacroSeed("", seedSource)}`;
|
|
581
589
|
else try {
|
|
582
590
|
seedKey = key + "\0object\0" + JSON.stringify(seedSource, serializeMacroSeed);
|
|
583
591
|
} catch {
|
|
@@ -594,7 +602,7 @@ var Elysia = class Elysia {
|
|
|
594
602
|
const v = hook[k];
|
|
595
603
|
if (k === "seed" || k === "meta" || k === "$type") continue;
|
|
596
604
|
if (k === "introspect") {
|
|
597
|
-
v
|
|
605
|
+
if (v) (input["~introspect"] ??= []).push(v);
|
|
598
606
|
delete input[key];
|
|
599
607
|
continue;
|
|
600
608
|
}
|
|
@@ -630,15 +638,9 @@ var Elysia = class Elysia {
|
|
|
630
638
|
if (eventProperties.has(k) || k === "derive") {
|
|
631
639
|
const incoming = Array.isArray(v) ? v : [v];
|
|
632
640
|
const existing = k in input ? Array.isArray(input[k]) ? input[k] : [input[k]] : [];
|
|
633
|
-
const added = [];
|
|
634
|
-
for (const fn of incoming) if (!existing.includes(fn) && !added.includes(fn)) added.push(fn);
|
|
635
641
|
const at = insertions.get(k) ?? 0;
|
|
636
|
-
input[k] =
|
|
637
|
-
|
|
638
|
-
...added,
|
|
639
|
-
...existing.slice(at)
|
|
640
|
-
];
|
|
641
|
-
insertions.set(k, at + added.length);
|
|
642
|
+
input[k] = existing.toSpliced(at, 0, ...incoming);
|
|
643
|
+
insertions.set(k, at + incoming.length);
|
|
642
644
|
} else if (k in input) {
|
|
643
645
|
if (Array.isArray(input[k])) {
|
|
644
646
|
for (const item of Array.isArray(v) ? v : [v]) if (!input[k].includes(item)) input[k].unshift(item);
|
|
@@ -651,7 +653,7 @@ var Elysia = class Elysia {
|
|
|
651
653
|
}
|
|
652
654
|
use(app) {
|
|
653
655
|
if (!app) return this;
|
|
654
|
-
this.#
|
|
656
|
+
this.#assertTableMutable("use");
|
|
655
657
|
if (typeof app === "function") return this.#useFn(app);
|
|
656
658
|
if (typeof app.then === "function") return this.#useAsync(app);
|
|
657
659
|
if (Array.isArray(app)) {
|
|
@@ -664,6 +666,9 @@ var Elysia = class Elysia {
|
|
|
664
666
|
this.#use(app);
|
|
665
667
|
return this;
|
|
666
668
|
}
|
|
669
|
+
has(plugin) {
|
|
670
|
+
return this.childrenHash?.has(plugin.hash ?? pluginId(plugin)) ?? false;
|
|
671
|
+
}
|
|
667
672
|
#useFn(app) {
|
|
668
673
|
const prevBaseline = this.macroBaseline;
|
|
669
674
|
const baseline = /* @__PURE__ */ new Set();
|
|
@@ -705,14 +710,15 @@ var Elysia = class Elysia {
|
|
|
705
710
|
const config = app["~config"];
|
|
706
711
|
if (app["~introspect"] || config?.introspect) this["~introspect"] = true;
|
|
707
712
|
const name = config?.name;
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
713
|
+
const childKey = name ? app.hash : pluginId(app);
|
|
714
|
+
const exists = this.childrenHash?.has(childKey);
|
|
715
|
+
if (name && exists) return;
|
|
716
|
+
if (!exists) {
|
|
711
717
|
this.childrenHash ??= /* @__PURE__ */ new Set();
|
|
712
|
-
this.childrenHash.add(
|
|
713
|
-
(addedByThisCall ??= /* @__PURE__ */ new Set()).add(
|
|
718
|
+
this.childrenHash.add(childKey);
|
|
719
|
+
(addedByThisCall ??= /* @__PURE__ */ new Set()).add(childKey);
|
|
714
720
|
}
|
|
715
|
-
if (app.childrenHash) addedByThisCall = this.#absorbChildrenHash(app, addedByThisCall);
|
|
721
|
+
if (app.childrenHash && !app["~scopeChild"]) addedByThisCall = this.#absorbChildrenHash(app, addedByThisCall);
|
|
716
722
|
if (app["~ext"]) this.#assertMacroUnique(app, addedByThisCall);
|
|
717
723
|
if (app["~hasTrace"]) this["~hasTrace"] = true;
|
|
718
724
|
if (app.declaredRoutes === void 0 && app["~routeTable"]?.length) app.#materializeDeclaredRoutes();
|
|
@@ -725,20 +731,17 @@ var Elysia = class Elysia {
|
|
|
725
731
|
for (const child of app["~scopeChildren"]) children.push(child);
|
|
726
732
|
}
|
|
727
733
|
const hookChain = app["~hookChain"];
|
|
728
|
-
if (app["~ext"]) this.#absorbExt(app);
|
|
734
|
+
if (app["~ext"]) this.#absorbExt(app, addedByThisCall);
|
|
729
735
|
if (hookChain) this.#propagateHooks(app, hookChain, addedByThisCall);
|
|
730
736
|
}
|
|
731
737
|
#absorbChildrenHash(app, addedByThisCall) {
|
|
732
|
-
const
|
|
733
|
-
|
|
734
|
-
if (
|
|
735
|
-
|
|
738
|
+
const childrenHash = this.childrenHash;
|
|
739
|
+
for (let h of app.childrenHash) {
|
|
740
|
+
if (typeof h === "object") h = pluginId(h);
|
|
741
|
+
if (childrenHash.has(h)) continue;
|
|
742
|
+
childrenHash.add(h);
|
|
736
743
|
(addedByThisCall ??= /* @__PURE__ */ new Set()).add(h);
|
|
737
744
|
}
|
|
738
|
-
else {
|
|
739
|
-
this.childrenHash = new Set(incoming);
|
|
740
|
-
addedByThisCall = new Set(incoming);
|
|
741
|
-
}
|
|
742
745
|
return addedByThisCall;
|
|
743
746
|
}
|
|
744
747
|
/**
|
|
@@ -767,22 +770,26 @@ var Elysia = class Elysia {
|
|
|
767
770
|
*
|
|
768
771
|
* Keep the cold blocks in their own frames.
|
|
769
772
|
*/
|
|
770
|
-
#absorbExt(app) {
|
|
771
|
-
const
|
|
773
|
+
#absorbExt(app, addedByThisCall) {
|
|
774
|
+
const source = app["~ext"];
|
|
775
|
+
const { decorator, store, headers, models, parser, macro, hoc, setup, cleanup, capability } = source;
|
|
772
776
|
const ext = this["~ext"] ??= nullObject();
|
|
773
|
-
if (
|
|
777
|
+
if (app.scopeParent === this) {
|
|
778
|
+
for (const field of sharedTables) if (source[field]) ext[field] ??= source[field];
|
|
779
|
+
}
|
|
780
|
+
if (decorator && decorator !== ext.decorator) {
|
|
774
781
|
if (ext.decorator) mergeDeep(ext.decorator, decorator, void 0, true, false, void 0, { map: void 0 });
|
|
775
782
|
else ext.decorator = clonePlainDecorators(decorator);
|
|
776
783
|
markStoredSingletons(ext.decorator, decorator);
|
|
777
784
|
}
|
|
778
|
-
if (store) {
|
|
785
|
+
if (store && store !== ext.store) {
|
|
779
786
|
if (ext.store) mergeDeep(ext.store, store);
|
|
780
787
|
else ext.store = Object.assign(nullObject(), store);
|
|
781
788
|
markStoredSingletons(ext.store, store);
|
|
782
789
|
}
|
|
783
|
-
if (headers) ext.headers = Object.assign(ext.headers ?? nullObject(), headers);
|
|
784
|
-
if (models) ext.models = Object.assign(ext.models ?? nullObject(), models);
|
|
785
|
-
if (parser) ext.parser = Object.assign(ext.parser ?? nullObject(), parser);
|
|
790
|
+
if (headers && headers !== ext.headers) ext.headers = Object.assign(ext.headers ?? nullObject(), headers);
|
|
791
|
+
if (models && models !== ext.models) ext.models = Object.assign(ext.models ?? nullObject(), models);
|
|
792
|
+
if (parser && parser !== ext.parser) ext.parser = Object.assign(ext.parser ?? nullObject(), parser);
|
|
786
793
|
if (macro) if (app["~scopeChild"]) {
|
|
787
794
|
const pluginMacros = app.pluginMacros;
|
|
788
795
|
let changed = false;
|
|
@@ -803,7 +810,20 @@ var Elysia = class Elysia {
|
|
|
803
810
|
}
|
|
804
811
|
invalidateMacroEpoch();
|
|
805
812
|
}
|
|
806
|
-
if (hoc)
|
|
813
|
+
if (hoc) {
|
|
814
|
+
const childrenHash = this.childrenHash;
|
|
815
|
+
const target = ext.hoc ??= [];
|
|
816
|
+
const origins = ext.hocOrigin ??= [];
|
|
817
|
+
for (let i = 0; i < hoc.length; i++) {
|
|
818
|
+
const fn = hoc[i];
|
|
819
|
+
const registration = source.hocOrigin?.[i] ?? app.hash;
|
|
820
|
+
const origin = typeof registration === "object" ? registration.origin ??= app.hash : registration;
|
|
821
|
+
if (origin !== void 0 && childrenHash.has(origin) && !addedByThisCall?.has(origin)) continue;
|
|
822
|
+
if (target.some((f, j) => f === fn && hocOriginOf(origins[j]) === origin)) continue;
|
|
823
|
+
origins.push(registration);
|
|
824
|
+
target.push(fn);
|
|
825
|
+
}
|
|
826
|
+
}
|
|
807
827
|
if (setup) ext.setup = mergeExtCallbacks(ext.setup, setup);
|
|
808
828
|
if (cleanup) ext.cleanup = mergeExtCallbacks(ext.cleanup, cleanup);
|
|
809
829
|
if (capability) {
|
|
@@ -841,10 +861,6 @@ var Elysia = class Elysia {
|
|
|
841
861
|
* Split out from #use, see #absorbExt
|
|
842
862
|
*/
|
|
843
863
|
#propagateHooks(app, hookChain, addedByThisCall) {
|
|
844
|
-
let pluginEvents;
|
|
845
|
-
let globalEvents;
|
|
846
|
-
let pluginMayRef = false;
|
|
847
|
-
let globalMayRef = false;
|
|
848
864
|
const nodes = useNodesBuffer;
|
|
849
865
|
nodes.length = 0;
|
|
850
866
|
let current = hookChain;
|
|
@@ -856,96 +872,71 @@ var Elysia = class Elysia {
|
|
|
856
872
|
nodes.push(current);
|
|
857
873
|
current = current.parent;
|
|
858
874
|
}
|
|
875
|
+
const childrenHash = this.childrenHash;
|
|
876
|
+
const scopeChild = app["~scopeChild"];
|
|
877
|
+
let held = propagatedRegistrations.get(this);
|
|
878
|
+
const lifted = liftedRequests.get(this);
|
|
879
|
+
let lifting;
|
|
859
880
|
for (let i = nodes.length - 1; i >= 0; i--) {
|
|
860
881
|
const node = nodes[i];
|
|
861
|
-
const
|
|
862
|
-
if (
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
if (
|
|
879
|
-
|
|
880
|
-
const raw = added[key];
|
|
881
|
-
const many = Array.isArray(raw);
|
|
882
|
-
const count = many ? raw.length : 1;
|
|
883
|
-
for (let f = 0; f < count; f++) {
|
|
884
|
-
const fn = many ? raw[f] : raw;
|
|
885
|
-
const childrenHash = this.childrenHash;
|
|
886
|
-
if (childrenHash !== void 0) {
|
|
887
|
-
const origin = fnOrigin.get(fn);
|
|
888
|
-
if (origin !== void 0 && childrenHash.has(origin) && !addedByThisCall?.has(origin)) continue;
|
|
889
|
-
}
|
|
890
|
-
pushField(isGlobal ? globalEvents ??= nullObject() : pluginEvents ??= nullObject(), key, fn);
|
|
891
|
-
}
|
|
892
|
-
continue;
|
|
893
|
-
}
|
|
894
|
-
if (key === "~deriveEntries") {
|
|
895
|
-
const entries = added[key];
|
|
896
|
-
if (!entries) continue;
|
|
897
|
-
const target = isGlobal ? globalEvents ??= nullObject() : pluginEvents ??= nullObject();
|
|
898
|
-
const list = target[key] ??= [];
|
|
899
|
-
for (let j = 0; j < entries.length; j++) list.push(entries[j]);
|
|
900
|
-
continue;
|
|
901
|
-
}
|
|
902
|
-
const target = isGlobal ? globalEvents ??= nullObject() : pluginEvents ??= nullObject();
|
|
903
|
-
if (isGlobal) globalMayRef = true;
|
|
904
|
-
else pluginMayRef = true;
|
|
905
|
-
target[key] = added[key];
|
|
882
|
+
const scope = node.scope;
|
|
883
|
+
if (scope === "plugin" ? node.propagated : scope !== "global") continue;
|
|
884
|
+
let source = node.added;
|
|
885
|
+
if (scopeChild) {
|
|
886
|
+
const request = source.request;
|
|
887
|
+
if (!request) continue;
|
|
888
|
+
source = nullObject();
|
|
889
|
+
source.request = request;
|
|
890
|
+
}
|
|
891
|
+
const origin = node.origin ?? app.hash;
|
|
892
|
+
const registration = node.registration ?? node;
|
|
893
|
+
let added = source;
|
|
894
|
+
let repeated = false;
|
|
895
|
+
if (origin !== void 0) {
|
|
896
|
+
if (!held) propagatedRegistrations.set(this, held = /* @__PURE__ */ new WeakMap());
|
|
897
|
+
const through = held.get(registration);
|
|
898
|
+
if (!through) held.set(registration, [origin]);
|
|
899
|
+
else if (through.includes(origin)) repeated = true;
|
|
900
|
+
else through.push(origin);
|
|
906
901
|
}
|
|
902
|
+
const registrant = registration.origin;
|
|
903
|
+
if (repeated) {
|
|
904
|
+
const schemas = source.schemas;
|
|
905
|
+
if (!schemas) continue;
|
|
906
|
+
added = nullObject();
|
|
907
|
+
added.schemas = schemas;
|
|
908
|
+
} else if (registrant !== void 0 && childrenHash?.has(registrant) && !addedByThisCall?.has(registrant)) {
|
|
909
|
+
added = nullObject();
|
|
910
|
+
for (const key in source) if (key !== "~deriveEntries" && !eventProperties.has(key)) added[key] = source[key];
|
|
911
|
+
}
|
|
912
|
+
let dropRequest = false;
|
|
913
|
+
if (origin !== void 0 && "request" in added) {
|
|
914
|
+
if (lifted?.has(origin)) dropRequest = true;
|
|
915
|
+
else if (scopeChild) (lifting ??= new Set(lifted)).add(origin);
|
|
916
|
+
}
|
|
917
|
+
if ("schema" in added || dropRequest) {
|
|
918
|
+
if (added === source) added = Object.assign(nullObject(), source);
|
|
919
|
+
delete added.schema;
|
|
920
|
+
if (dropRequest) delete added.request;
|
|
921
|
+
}
|
|
922
|
+
if (isNotEmpty(added)) this.#pushChainNode(added, scope, registration, origin, app);
|
|
907
923
|
}
|
|
924
|
+
if (lifting) liftedRequests.set(this, lifting);
|
|
908
925
|
nodes.length = 0;
|
|
909
|
-
if (globalEvents) this.#link(globalEvents, "global", app, globalMayRef, true);
|
|
910
|
-
if (pluginEvents) this.#link(pluginEvents, "plugin", app, pluginMayRef, true);
|
|
911
926
|
}
|
|
912
927
|
#emitChildRoutes(app, preChain, name) {
|
|
913
928
|
const declared = app.declaredRoutes;
|
|
914
929
|
const limit = declared.length;
|
|
915
|
-
const
|
|
916
|
-
let recent;
|
|
917
|
-
let hasLocal = false;
|
|
930
|
+
const callback = app["~scopeChild"] ? app["~hookChain"] : void 0;
|
|
918
931
|
let lastChildChain;
|
|
919
932
|
let lastCombined;
|
|
920
|
-
let
|
|
921
|
-
let
|
|
933
|
+
let lastInner = null;
|
|
934
|
+
let lastCovered;
|
|
922
935
|
for (let i = 0; i < limit; i++) {
|
|
923
936
|
const route = declared[i];
|
|
924
937
|
const childChain = route[6];
|
|
925
|
-
const absorbed = tail !== void 0 && route[3] !== app;
|
|
926
|
-
if (absorbed && recent === void 0) {
|
|
927
|
-
recent = /* @__PURE__ */ new Set();
|
|
928
|
-
for (let node = tail; node && "added" in node; node = node.parent) {
|
|
929
|
-
recent.add(node);
|
|
930
|
-
if (isLocalScope(node.scope)) {
|
|
931
|
-
hasLocal = true;
|
|
932
|
-
break;
|
|
933
|
-
}
|
|
934
|
-
}
|
|
935
|
-
}
|
|
936
938
|
let inheritedChain;
|
|
937
|
-
if (
|
|
938
|
-
if (childChain !== lastTailChild) {
|
|
939
|
-
lastTailChild = childChain;
|
|
940
|
-
lastTailCombined = {
|
|
941
|
-
combine: childChain,
|
|
942
|
-
over: preChain,
|
|
943
|
-
tail,
|
|
944
|
-
refs: !!(childChain?.refs || preChain?.refs || tail.refs)
|
|
945
|
-
};
|
|
946
|
-
}
|
|
947
|
-
inheritedChain = lastTailCombined;
|
|
948
|
-
} else if (childChain === void 0) inheritedChain = preChain;
|
|
939
|
+
if (childChain === void 0) inheritedChain = preChain;
|
|
949
940
|
else if (preChain === void 0) inheritedChain = childChain;
|
|
950
941
|
else if (childChain === lastChildChain) inheritedChain = lastCombined;
|
|
951
942
|
else {
|
|
@@ -956,6 +947,19 @@ var Elysia = class Elysia {
|
|
|
956
947
|
refs: childChain.refs || preChain.refs
|
|
957
948
|
};
|
|
958
949
|
}
|
|
950
|
+
if (callback) {
|
|
951
|
+
if (inheritedChain !== lastInner) {
|
|
952
|
+
lastInner = inheritedChain;
|
|
953
|
+
lastCovered = {
|
|
954
|
+
combine: inheritedChain,
|
|
955
|
+
over: void 0,
|
|
956
|
+
callback,
|
|
957
|
+
inner: childChain,
|
|
958
|
+
refs: !!(inheritedChain?.refs || callback.refs)
|
|
959
|
+
};
|
|
960
|
+
}
|
|
961
|
+
inheritedChain = lastCovered;
|
|
962
|
+
}
|
|
959
963
|
this.#emitRoute(route, this["~scopeChild"] ? this : void 0, this["~Prefix"], inheritedChain, name);
|
|
960
964
|
}
|
|
961
965
|
}
|
|
@@ -985,11 +989,11 @@ var Elysia = class Elysia {
|
|
|
985
989
|
});
|
|
986
990
|
}
|
|
987
991
|
get pending() {
|
|
988
|
-
return this
|
|
992
|
+
return this.#pending > 0;
|
|
989
993
|
}
|
|
990
994
|
#useAsync(promise) {
|
|
991
995
|
if (!this.ready) this._error = void 0;
|
|
992
|
-
this
|
|
996
|
+
this.#pending++;
|
|
993
997
|
const next = (this.ready ?? Promise.resolve()).then(() => promise).then((value) => {
|
|
994
998
|
const plugin = value && typeof value === "object" && "default" in value && value.default ? value.default : value;
|
|
995
999
|
const snapshots = this.macroSnapshots;
|
|
@@ -1013,19 +1017,19 @@ var Elysia = class Elysia {
|
|
|
1013
1017
|
}
|
|
1014
1018
|
}
|
|
1015
1019
|
}).finally(() => {
|
|
1016
|
-
this
|
|
1020
|
+
this.#pending--;
|
|
1017
1021
|
}).then(() => {}, (err) => {
|
|
1018
1022
|
this._error ??= { error: err };
|
|
1019
1023
|
console.error(err);
|
|
1020
1024
|
}).finally(() => {
|
|
1021
|
-
if (this
|
|
1025
|
+
if (this.#pending > 0) return;
|
|
1022
1026
|
if (this.ready !== next) return;
|
|
1023
1027
|
const previousCompiled = this.compiled;
|
|
1024
1028
|
const previousJitColdRemaining = this.jitColdRemaining;
|
|
1025
1029
|
this.ready = void 0;
|
|
1026
1030
|
this.compiled = void 0;
|
|
1027
1031
|
this.fetchFn = void 0;
|
|
1028
|
-
this
|
|
1032
|
+
this.#routerBuilt = false;
|
|
1029
1033
|
clearContextCache(this);
|
|
1030
1034
|
try {
|
|
1031
1035
|
this.#buildRouter(false);
|
|
@@ -1050,7 +1054,7 @@ var Elysia = class Elysia {
|
|
|
1050
1054
|
break;
|
|
1051
1055
|
}
|
|
1052
1056
|
}
|
|
1053
|
-
if (isHook) throw new Error(`[Elysia] .${method === "*" ? "all" : method.toLowerCase()}('${path}', handler, hook) is the 1.x order; Elysia 2 takes (path, hook, handler)
|
|
1057
|
+
if (isHook) throw new Error(`[Elysia] .${method === "*" ? "all" : method.toLowerCase()}('${path}', handler, hook) is the 1.x order; Elysia 2 takes (path, hook, handler) \u2014 see the 2.0 migration guide`);
|
|
1054
1058
|
}
|
|
1055
1059
|
if (hasHook && hookOrFn) assertSchemaShape(hookOrFn, `${method} ${path}`);
|
|
1056
1060
|
const handler = hasHook ? fn : hookOrFn;
|
|
@@ -1077,7 +1081,7 @@ var Elysia = class Elysia {
|
|
|
1077
1081
|
handler,
|
|
1078
1082
|
this
|
|
1079
1083
|
]);
|
|
1080
|
-
if (this
|
|
1084
|
+
if (this.#routerBuilt || this.compiled !== void 0) this.#invalidateRouter();
|
|
1081
1085
|
return this;
|
|
1082
1086
|
}
|
|
1083
1087
|
#assertMutable(api) {
|
|
@@ -1085,8 +1089,15 @@ var Elysia = class Elysia {
|
|
|
1085
1089
|
if (this["~generation"] === void 0) return;
|
|
1086
1090
|
throw new Error(`[Elysia] .${api}() called after the app was sealed by its first request, listen or compile`);
|
|
1087
1091
|
}
|
|
1092
|
+
/**
|
|
1093
|
+
* `#assertMutable` for the tables a group child shares with its parents:
|
|
1094
|
+
* a child kept past its callback must not write into a sealed one
|
|
1095
|
+
*/
|
|
1096
|
+
#assertTableMutable(api) {
|
|
1097
|
+
for (let app = this; app; app = app.scopeParent) app.#assertMutable(api);
|
|
1098
|
+
}
|
|
1088
1099
|
get #isCacheable() {
|
|
1089
|
-
return this["~generation"] !== void 0 && this
|
|
1100
|
+
return this["~generation"] !== void 0 && this.#routerBuilt && !Capture.isCapturing();
|
|
1090
1101
|
}
|
|
1091
1102
|
#cacheRoutes(generation) {
|
|
1092
1103
|
if (this.cachedGeneration === generation && this.cachedEpoch === mutationEpoch) return;
|
|
@@ -1109,29 +1120,29 @@ var Elysia = class Elysia {
|
|
|
1109
1120
|
const sequence = routes.length;
|
|
1110
1121
|
routes.push(route);
|
|
1111
1122
|
if (source) (this.routeSources ??= [])[sequence] = source;
|
|
1112
|
-
if (this
|
|
1123
|
+
if (this.#routerBuilt || this.compiled !== void 0) this.#invalidateRouter();
|
|
1113
1124
|
}
|
|
1114
|
-
#
|
|
1125
|
+
#invalidateRouter() {
|
|
1115
1126
|
this.compiled = void 0;
|
|
1116
1127
|
this.jitColdRemaining = void 0;
|
|
1117
1128
|
this.jitTable = void 0;
|
|
1118
1129
|
this.jitRoute = void 0;
|
|
1119
1130
|
this.jitAliases = void 0;
|
|
1120
1131
|
this.fetchFn = void 0;
|
|
1121
|
-
this
|
|
1132
|
+
this.#routerBuilt = false;
|
|
1122
1133
|
}
|
|
1123
1134
|
model(name, model) {
|
|
1124
|
-
this.#
|
|
1125
|
-
const models = this
|
|
1135
|
+
this.#assertTableMutable("model");
|
|
1136
|
+
const models = this.#table("models");
|
|
1126
1137
|
switch (typeof name) {
|
|
1127
1138
|
case "object":
|
|
1128
1139
|
for (const [key, value] of Object.entries(name)) if (!(key in models)) models[key] = toModel(key, value);
|
|
1129
1140
|
return this;
|
|
1130
1141
|
case "function": {
|
|
1131
1142
|
const remapped = name(models);
|
|
1132
|
-
const next = nullObject();
|
|
1143
|
+
const next = remapped === models ? models : nullObject();
|
|
1133
1144
|
for (const key in remapped) next[key] = toModel(key, remapped[key]);
|
|
1134
|
-
this
|
|
1145
|
+
this.#ext.models = next;
|
|
1135
1146
|
return this;
|
|
1136
1147
|
}
|
|
1137
1148
|
case "string":
|
|
@@ -1143,7 +1154,7 @@ var Elysia = class Elysia {
|
|
|
1143
1154
|
* Registered reusable models (via `.model()`), keyed by name.
|
|
1144
1155
|
*/
|
|
1145
1156
|
get models() {
|
|
1146
|
-
return this["~ext"]?.models ?? nullObject();
|
|
1157
|
+
return this["~ext"]?.models ?? this.scopeParent?.models ?? nullObject();
|
|
1147
1158
|
}
|
|
1148
1159
|
Ref(key) {
|
|
1149
1160
|
return Ref(key);
|
|
@@ -1240,13 +1251,13 @@ var Elysia = class Elysia {
|
|
|
1240
1251
|
compile() {
|
|
1241
1252
|
this["~config"] ??= nullObject();
|
|
1242
1253
|
this["~config"].precompile = true;
|
|
1243
|
-
this.#
|
|
1254
|
+
this.#invalidateRouter();
|
|
1244
1255
|
this.fetch;
|
|
1245
1256
|
return this;
|
|
1246
1257
|
}
|
|
1247
1258
|
handler(index, immediate, route, aliases, table) {
|
|
1248
1259
|
if (this.compiled?.[index]) return this.compiled[index];
|
|
1249
|
-
const indexedTable = table ?? (this
|
|
1260
|
+
const indexedTable = table ?? (this.#routerBuilt ? this["~routeTable"] : void 0);
|
|
1250
1261
|
const compiled = this.compiled ??= new Array(indexedTable?.length ?? this["~routes"].length);
|
|
1251
1262
|
if (immediate ?? this["~config"]?.precompile) {
|
|
1252
1263
|
const row = route ?? (indexedTable ? routeRow(indexedTable, index) : this["~routes"][index]);
|
|
@@ -1265,7 +1276,7 @@ var Elysia = class Elysia {
|
|
|
1265
1276
|
if (indexedTable !== void 0) this.jitTable = indexedTable;
|
|
1266
1277
|
if (jitRoute !== void 0) (this.jitRoute ??= [])[index] = jitRoute;
|
|
1267
1278
|
if (aliases !== void 0) (this.jitAliases ??= [])[index] = aliases;
|
|
1268
|
-
return (context) => this
|
|
1279
|
+
return (context) => this["~dispatch"](index, context);
|
|
1269
1280
|
}
|
|
1270
1281
|
#staticAliases(table, index) {
|
|
1271
1282
|
const flags = table.flags[index];
|
|
@@ -1291,6 +1302,7 @@ var Elysia = class Elysia {
|
|
|
1291
1302
|
};
|
|
1292
1303
|
}
|
|
1293
1304
|
#releaseJit() {
|
|
1305
|
+
releaseAnalysisCaches();
|
|
1294
1306
|
Compiled.release(this["~programId"]);
|
|
1295
1307
|
this.jitColdRemaining = void 0;
|
|
1296
1308
|
this.jitRoute = void 0;
|
|
@@ -1309,7 +1321,7 @@ var Elysia = class Elysia {
|
|
|
1309
1321
|
this.#releaseJit();
|
|
1310
1322
|
return true;
|
|
1311
1323
|
}
|
|
1312
|
-
|
|
1324
|
+
"~dispatch"(index, context) {
|
|
1313
1325
|
if (this.compiled[index]) return this.compiled[index](context);
|
|
1314
1326
|
const route = this.jitRoute?.[index];
|
|
1315
1327
|
const table = this.jitTable ?? this["~routeTable"];
|
|
@@ -1321,7 +1333,7 @@ var Elysia = class Elysia {
|
|
|
1321
1333
|
} catch (error) {
|
|
1322
1334
|
const routeError = new Error(`[Elysia] Failed to compile route ${materialized[0]} ${materialized[1]}: ${error?.message ?? error}`, { cause: error });
|
|
1323
1335
|
const finalize = this["~finalizeError"];
|
|
1324
|
-
if (finalize) return finalize(context, routeError);
|
|
1336
|
+
if (finalize) return finalize(context, routeError, void 0, true);
|
|
1325
1337
|
throw routeError;
|
|
1326
1338
|
}
|
|
1327
1339
|
this.compiled[index] = handler;
|
|
@@ -1366,11 +1378,11 @@ var Elysia = class Elysia {
|
|
|
1366
1378
|
}
|
|
1367
1379
|
return false;
|
|
1368
1380
|
}
|
|
1369
|
-
static #slotHasTypeBox(value, models,
|
|
1381
|
+
static #slotHasTypeBox(value, models, allowStatusMap) {
|
|
1370
1382
|
if (typeof value === "string") value = models?.[value];
|
|
1371
1383
|
if (!value || typeof value !== "object") return false;
|
|
1372
1384
|
if ("~kind" in value || "~elyAcl" in value) return true;
|
|
1373
|
-
if (!
|
|
1385
|
+
if (!allowStatusMap || "~standard" in value) return false;
|
|
1374
1386
|
for (const status in value) if (Elysia.#slotHasTypeBox(value[status], models)) return true;
|
|
1375
1387
|
return false;
|
|
1376
1388
|
}
|
|
@@ -1396,7 +1408,7 @@ var Elysia = class Elysia {
|
|
|
1396
1408
|
if (Elysia.#hookHasTypeBox(resolve ? resolve(node) : node.added, models)) return true;
|
|
1397
1409
|
node = node.parent;
|
|
1398
1410
|
} else {
|
|
1399
|
-
if (Elysia.#chainHasTypeBox(node.combine, models, seen, resolve)
|
|
1411
|
+
if (Elysia.#chainHasTypeBox(node.combine, models, seen, resolve)) return true;
|
|
1400
1412
|
node = node.over;
|
|
1401
1413
|
}
|
|
1402
1414
|
}
|
|
@@ -1427,8 +1439,9 @@ var Elysia = class Elysia {
|
|
|
1427
1439
|
const schemas = hook?.schemas;
|
|
1428
1440
|
if (Array.isArray(schemas)) for (let s = 0; s < schemas.length; s++) checkSlots(schemas[s]);
|
|
1429
1441
|
}
|
|
1442
|
+
#routerBuilt = false;
|
|
1430
1443
|
#buildRouter(seal = false) {
|
|
1431
|
-
if (this
|
|
1444
|
+
if (this.#routerBuilt) {
|
|
1432
1445
|
if (seal && this["~generation"] === void 0) this.#publishGeneration();
|
|
1433
1446
|
return;
|
|
1434
1447
|
}
|
|
@@ -1463,8 +1476,8 @@ var Elysia = class Elysia {
|
|
|
1463
1476
|
Object.assign(previousRouter, nextRouter);
|
|
1464
1477
|
this["~router"] = previousRouter;
|
|
1465
1478
|
}
|
|
1466
|
-
this.routerBuilt = true;
|
|
1467
1479
|
if (seal) this.#publishGeneration();
|
|
1480
|
+
this.#routerBuilt = true;
|
|
1468
1481
|
buildSucceeded = true;
|
|
1469
1482
|
} catch (error) {
|
|
1470
1483
|
this["~map"] = previousMap;
|
|
@@ -1516,9 +1529,10 @@ var Elysia = class Elysia {
|
|
|
1516
1529
|
if (!this["~ext"]?.macro && !this["~scopeChildren"]) this.declaredRoutes = void 0;
|
|
1517
1530
|
}
|
|
1518
1531
|
const ext = this["~ext"];
|
|
1519
|
-
if (ext?.hoc) extCallbackIndexes.delete(ext.hoc);
|
|
1520
1532
|
if (ext?.setup) extCallbackIndexes.delete(ext.setup);
|
|
1521
1533
|
if (ext?.cleanup) extCallbackIndexes.delete(ext.cleanup);
|
|
1534
|
+
if (ext?.decorator) markPropertySingletons(ext.decorator);
|
|
1535
|
+
if (ext?.store) markPropertySingletons(ext.store);
|
|
1522
1536
|
}
|
|
1523
1537
|
#buildRouterUnsafe() {
|
|
1524
1538
|
const precompile = this["~config"]?.precompile;
|
|
@@ -1621,8 +1635,14 @@ var Elysia = class Elysia {
|
|
|
1621
1635
|
if (isDynamic) {
|
|
1622
1636
|
if (isHTMLBundle(table.handler[i])) continue;
|
|
1623
1637
|
const router = this["~router"] ??= new Memoirist({ loosePath: isLoose });
|
|
1624
|
-
|
|
1625
|
-
|
|
1638
|
+
let store;
|
|
1639
|
+
if (precompile || this.compiled?.[i]) store = this.handler(i, precompile, void 0, void 0, table);
|
|
1640
|
+
else {
|
|
1641
|
+
this.compiled ??= new Array(length);
|
|
1642
|
+
this.jitTable = table;
|
|
1643
|
+
store = i;
|
|
1644
|
+
}
|
|
1645
|
+
for (let p = 0; p < paths.length; p++) router.add(routeMethod, paths[p], store);
|
|
1626
1646
|
} else {
|
|
1627
1647
|
const map = methods[routeMethod] ??= nullObject();
|
|
1628
1648
|
const handler = this.handler(i, precompile, void 0, {
|
|
@@ -1640,21 +1660,21 @@ var Elysia = class Elysia {
|
|
|
1640
1660
|
const run = () => this.fetch(request, ...rest);
|
|
1641
1661
|
return this.ready ? this.modules.then(run, run) : run();
|
|
1642
1662
|
};
|
|
1643
|
-
return this.#
|
|
1663
|
+
return this.#buildFetch();
|
|
1644
1664
|
}
|
|
1645
|
-
#
|
|
1646
|
-
this.#buildRouter(!this
|
|
1665
|
+
#buildFetch() {
|
|
1666
|
+
this.#buildRouter(!this.#pending);
|
|
1647
1667
|
if (this.ready) return applyHoc(this, createFetchHandler(this));
|
|
1648
1668
|
return this.fetchFn ??= applyHoc(this, createFetchHandler(this));
|
|
1649
1669
|
}
|
|
1650
1670
|
get handle() {
|
|
1651
|
-
return this._handle ??= async (requestOrUrl, options) => (this.fetchFn ?? this.#
|
|
1671
|
+
return this._handle ??= async (requestOrUrl, options) => (this.fetchFn ?? this.#buildFetch())(typeof requestOrUrl === "string" ? new Request(requestOrUrl.charCodeAt(0) === 47 ? `http://e.ly${requestOrUrl}` : requestOrUrl, options) : requestOrUrl);
|
|
1652
1672
|
}
|
|
1653
1673
|
listen(options, callback) {
|
|
1654
1674
|
const listen = (this["~config"]?.adapter ?? (isBun ? BunAdapter : void 0))?.listen;
|
|
1655
1675
|
if (!listen) {
|
|
1656
1676
|
const deno = typeof Deno !== "undefined";
|
|
1657
|
-
throw new Error(`[Elysia] listen() requires an adapter on ${deno ? "Deno" : typeof process === "undefined" ? "this runtime" : "Node.js"}
|
|
1677
|
+
throw new Error(`[Elysia] listen() requires an adapter on ${deno ? "Deno" : typeof process === "undefined" ? "this runtime" : "Node.js"} \u2014 https://elysiajs.com/integrations/${deno ? "deno" : "node"}`);
|
|
1658
1678
|
}
|
|
1659
1679
|
if (!Capture.isAotBuildEnv()) listen(this, options, callback);
|
|
1660
1680
|
return this;
|
|
@@ -1668,17 +1688,18 @@ var Elysia = class Elysia {
|
|
|
1668
1688
|
*
|
|
1669
1689
|
* new Elysia()
|
|
1670
1690
|
* .wrap(
|
|
1671
|
-
* (fetch) => (request) =>
|
|
1672
|
-
* ctx.run({ counter: 0 }, () => fetch(request))
|
|
1691
|
+
* (fetch) => (request, ...rest) =>
|
|
1692
|
+
* ctx.run({ counter: 0 }, () => fetch(request, ...rest))
|
|
1673
1693
|
* )
|
|
1674
1694
|
* .get('/', () => ctx.getStore())
|
|
1675
1695
|
* ```
|
|
1676
1696
|
*/
|
|
1677
1697
|
wrap(callback) {
|
|
1678
1698
|
this.#assertMutable("wrap");
|
|
1679
|
-
if (this.fetchFn && !this
|
|
1680
|
-
const ext = this
|
|
1699
|
+
if (this.fetchFn && !this.#pending) console.warn("[Elysia] .wrap() was called after the fetch handler was built");
|
|
1700
|
+
const ext = this.#ext;
|
|
1681
1701
|
(ext.hoc ??= []).push(callback);
|
|
1702
|
+
(ext.hocOrigin ??= []).push(this.hash ?? {});
|
|
1682
1703
|
return this;
|
|
1683
1704
|
}
|
|
1684
1705
|
/**
|
|
@@ -1697,7 +1718,7 @@ var Elysia = class Elysia {
|
|
|
1697
1718
|
cleanup(handler) {
|
|
1698
1719
|
if (this["~ext"]?.cleanupEpoch?.(handler)) return this;
|
|
1699
1720
|
this.#assertMutable("cleanup");
|
|
1700
|
-
(this
|
|
1721
|
+
(this.#ext.cleanup ??= []).push(...[].concat(handler));
|
|
1701
1722
|
return this;
|
|
1702
1723
|
}
|
|
1703
1724
|
/**
|