elysia 2.0.0-beta.2 → 2.0.0-beta.4
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/adapter/bun/index.d.ts +1 -1
- package/dist/adapter/bun/index.js +320 -56
- package/dist/adapter/bun/index.mjs +321 -57
- package/dist/adapter/utils.js +51 -30
- package/dist/adapter/utils.mjs +52 -31
- package/dist/adapter/web-standard/handler.js +5 -2
- package/dist/adapter/web-standard/handler.mjs +5 -2
- package/dist/base.d.ts +18 -7
- package/dist/base.js +213 -101
- package/dist/base.mjs +215 -103
- package/dist/compile/aot-capture.js +1 -1
- package/dist/compile/aot-capture.mjs +1 -1
- package/dist/compile/aot.d.ts +5 -4
- package/dist/compile/aot.js +17 -9
- package/dist/compile/aot.mjs +18 -9
- package/dist/compile/handler/descriptor.js +1 -1
- package/dist/compile/handler/descriptor.mjs +1 -1
- package/dist/compile/handler/frozen-validator.d.ts +4 -1
- package/dist/compile/handler/frozen-validator.js +8 -3
- package/dist/compile/handler/frozen-validator.mjs +5 -3
- package/dist/compile/handler/index.d.ts +2 -2
- package/dist/compile/handler/index.js +8 -6
- package/dist/compile/handler/index.mjs +8 -6
- package/dist/compile/handler/reconstruct.d.ts +1 -1
- package/dist/compile/handler/reconstruct.js +4 -3
- package/dist/compile/handler/reconstruct.mjs +4 -3
- package/dist/compile/handler/utils.js +2 -2
- package/dist/compile/handler/utils.mjs +3 -3
- package/dist/compile/jit-probe.d.ts +2 -2
- package/dist/context.d.ts +1 -1
- package/dist/context.js +8 -5
- package/dist/context.mjs +8 -5
- package/dist/cookie/config.d.ts +1 -0
- package/dist/cookie/config.js +3 -2
- package/dist/cookie/config.mjs +3 -2
- package/dist/cookie/cookie.d.ts +1 -0
- package/dist/cookie/cookie.js +6 -5
- package/dist/cookie/cookie.mjs +6 -5
- package/dist/cookie/crypto.d.ts +8 -7
- package/dist/cookie/crypto.js +38 -31
- package/dist/cookie/crypto.mjs +38 -32
- package/dist/cookie/error.js +1 -2
- package/dist/cookie/error.mjs +1 -2
- package/dist/cookie/lib.js +5 -1
- package/dist/cookie/lib.mjs +5 -1
- package/dist/cookie/serialize.js +1 -1
- package/dist/cookie/serialize.mjs +1 -1
- package/dist/cookie/types.d.ts +10 -0
- package/dist/cookie/utils.js +28 -14
- package/dist/cookie/utils.mjs +29 -15
- package/dist/handler/error.d.ts +23 -12
- package/dist/handler/error.js +24 -21
- package/dist/handler/error.mjs +20 -21
- package/dist/handler/fetch.js +6 -7
- package/dist/handler/fetch.mjs +7 -8
- package/dist/handler/utils.js +4 -2
- package/dist/handler/utils.mjs +5 -3
- package/dist/index.js +1 -8
- package/dist/package.js +1 -1
- package/dist/package.mjs +1 -1
- package/dist/plugin/aot/core.d.ts +33 -6
- package/dist/plugin/aot/core.js +120 -40
- package/dist/plugin/aot/core.mjs +121 -43
- package/dist/plugin/aot/esbuild.js +8 -2
- package/dist/plugin/aot/esbuild.mjs +9 -3
- package/dist/plugin/aot/hooks.d.ts +2 -1
- package/dist/plugin/aot/hooks.js +3 -3
- package/dist/plugin/aot/hooks.mjs +4 -4
- package/dist/plugin/aot/source.d.ts +4 -1
- package/dist/plugin/aot/source.js +21 -14
- package/dist/plugin/aot/source.mjs +21 -14
- package/dist/plugin/aot/worker.js +2 -2
- package/dist/plugin/aot/worker.mjs +2 -2
- package/dist/route-table.d.ts +3 -0
- package/dist/route-table.js +16 -11
- package/dist/route-table.mjs +16 -11
- package/dist/schema-snapshot.js +17 -22
- package/dist/schema-snapshot.mjs +17 -22
- package/dist/type/bridge-live.d.ts +1 -1
- package/dist/type/bridge-live.js +2 -2
- package/dist/type/bridge-live.mjs +2 -2
- package/dist/type/bridge.d.ts +1 -1
- package/dist/type/coerce-plan.js +3 -4
- package/dist/type/coerce-plan.mjs +1 -1
- package/dist/type/coerce.d.ts +1 -1
- package/dist/type/compat.d.ts +3 -0
- package/dist/type/compat.js +32 -14
- package/dist/type/compat.mjs +27 -8
- package/dist/type/constants.d.ts +1 -1
- package/dist/type/elysia/array-buffer.js +2 -3
- package/dist/type/elysia/array-buffer.mjs +1 -1
- package/dist/type/elysia/array-string.js +7 -4
- package/dist/type/elysia/array-string.mjs +9 -5
- package/dist/type/elysia/boolean-string.js +2 -3
- package/dist/type/elysia/boolean-string.mjs +1 -1
- package/dist/type/elysia/boolean.js +4 -3
- package/dist/type/elysia/boolean.mjs +4 -2
- package/dist/type/elysia/cookie.js +2 -1
- package/dist/type/elysia/cookie.mjs +2 -1
- package/dist/type/elysia/date.js +7 -7
- package/dist/type/elysia/date.mjs +3 -2
- package/dist/type/elysia/file-type.d.ts +9 -2
- package/dist/type/elysia/file-type.js +16 -1
- package/dist/type/elysia/file-type.mjs +16 -2
- package/dist/type/elysia/file.js +8 -4
- package/dist/type/elysia/file.mjs +8 -3
- package/dist/type/elysia/files.js +6 -4
- package/dist/type/elysia/files.mjs +5 -2
- package/dist/type/elysia/form.js +2 -3
- package/dist/type/elysia/form.mjs +3 -3
- package/dist/type/elysia/integer-string.js +4 -5
- package/dist/type/elysia/integer-string.mjs +3 -3
- package/dist/type/elysia/integer.js +4 -3
- package/dist/type/elysia/integer.mjs +4 -2
- package/dist/type/elysia/maybe-empty.js +3 -4
- package/dist/type/elysia/maybe-empty.mjs +1 -1
- package/dist/type/elysia/nullable.js +2 -3
- package/dist/type/elysia/nullable.mjs +1 -1
- package/dist/type/elysia/number.js +4 -3
- package/dist/type/elysia/number.mjs +4 -2
- package/dist/type/elysia/numeric-enum.js +2 -3
- package/dist/type/elysia/numeric-enum.mjs +1 -1
- package/dist/type/elysia/numeric.js +5 -5
- package/dist/type/elysia/numeric.mjs +3 -2
- package/dist/type/elysia/object-string.js +7 -4
- package/dist/type/elysia/object-string.mjs +9 -5
- package/dist/type/elysia/string.js +4 -3
- package/dist/type/elysia/string.mjs +4 -2
- package/dist/type/elysia/uint8-array.js +2 -3
- package/dist/type/elysia/uint8-array.mjs +1 -1
- package/dist/type/elysia/union-enum.js +2 -3
- package/dist/type/elysia/union-enum.mjs +1 -1
- package/dist/type/elysia/utils.js +2 -3
- package/dist/type/elysia/utils.mjs +1 -1
- package/dist/type/exports.js +10 -1
- package/dist/type/exports.mjs +7 -0
- package/dist/type/index.d.ts +9 -1
- package/dist/type/index.js +41 -13
- package/dist/type/index.mjs +44 -9
- package/dist/type/typebox-type-live.d.ts +9 -0
- package/dist/type/typebox-type-live.js +31 -0
- package/dist/type/typebox-type-live.mjs +16 -0
- package/dist/type/typebox-type.d.ts +24 -0
- package/dist/type/typebox-type.js +130 -0
- package/dist/type/typebox-type.mjs +66 -0
- package/dist/type/typebox-value-live.d.ts +9 -0
- package/dist/type/typebox-value-live.js +27 -0
- package/dist/type/typebox-value-live.mjs +11 -0
- package/dist/type/typebox-value.d.ts +30 -0
- package/dist/type/typebox-value.js +147 -0
- package/dist/type/typebox-value.mjs +62 -0
- package/dist/type/validator/custom-error.js +4 -5
- package/dist/type/validator/custom-error.mjs +3 -3
- package/dist/type/validator/default-precompute.js +4 -5
- package/dist/type/validator/default-precompute.mjs +1 -1
- package/dist/type/validator/index.d.ts +1 -1
- package/dist/type/validator/index.js +51 -42
- package/dist/type/validator/index.mjs +33 -23
- package/dist/type/validator/validator-cache.d.ts +1 -1
- package/dist/type/validator/validator-cache.js +27 -14
- package/dist/type/validator/validator-cache.mjs +27 -13
- package/dist/universal/constants.d.ts +2 -1
- package/dist/universal/constants.js +3 -1
- package/dist/universal/constants.mjs +2 -1
- package/dist/utils.d.ts +19 -1
- package/dist/utils.js +25 -3
- package/dist/utils.mjs +19 -3
- package/dist/validator/index.js +2 -1
- package/dist/validator/index.mjs +2 -1
- package/dist/ws/context.d.ts +8 -1
- package/dist/ws/context.js +65 -29
- package/dist/ws/context.mjs +64 -29
- package/dist/ws/route.js +176 -28
- package/dist/ws/route.mjs +179 -31
- package/package.json +5 -3
package/dist/ws/route.mjs
CHANGED
|
@@ -1,18 +1,19 @@
|
|
|
1
1
|
import { isBun } from "../universal/constants.mjs";
|
|
2
|
-
import { deriveEntryFn, isNotEmpty, nullObject } from "../utils.mjs";
|
|
2
|
+
import { assignOwn, deriveEntryFn, isNotEmpty, isSocketQuiet, nullObject } from "../utils.mjs";
|
|
3
3
|
import { isBridgeLive } from "../type/bridge.mjs";
|
|
4
|
-
import { isProduction } from "../universal/is-production.mjs";
|
|
5
4
|
import { ElysiaError, ElysiaStatus, ValidationError, internalServerErrorBodyString, problemBody, problemResponse } from "../error.mjs";
|
|
6
5
|
import { mapResponse } from "../adapter/web-standard/handler.mjs";
|
|
7
6
|
import { parseQueryFromURL } from "../parse-query.mjs";
|
|
8
7
|
import { frozenRootOf } from "../generation.mjs";
|
|
9
|
-
import {
|
|
8
|
+
import { compileCookieConfig } from "../cookie/config.mjs";
|
|
9
|
+
import { buildCookieJar, parseCookieRaw } from "../cookie/utils.mjs";
|
|
10
|
+
import { adoptErrorType, claimsProblemType, createErrorHandler, readAnnotation, resolveStatus, statusFallbackBody } from "../handler/error.mjs";
|
|
10
11
|
import { deriveModes, getQueryParseChannels, replaceDeriveContext } from "../compile/handler/utils.mjs";
|
|
11
12
|
import { StandardValidator } from "../validator/index.mjs";
|
|
12
13
|
import { RouteValidator } from "../validator/route.mjs";
|
|
13
14
|
import { buildFrozenRouteValidator, isBridgeNotInitialized } from "../compile/handler/frozen-validator.mjs";
|
|
14
15
|
import { composeRouteHook, localMacroRoot, resolveWSLocalHook } from "../compile/handler/index.mjs";
|
|
15
|
-
import { ElysiaWS, isGeneratorObject } from "./context.mjs";
|
|
16
|
+
import { ElysiaWS, isGeneratorObject, trackWSSettling } from "./context.mjs";
|
|
16
17
|
import { createMessageParser } from "./parser.mjs";
|
|
17
18
|
|
|
18
19
|
//#region src/ws/route.ts
|
|
@@ -180,9 +181,45 @@ function wsErrorFrame(error) {
|
|
|
180
181
|
}
|
|
181
182
|
return wsErrorFrameFallback(error);
|
|
182
183
|
}
|
|
184
|
+
/**
|
|
185
|
+
* Frame served by an error that claims an RFC 9457 problem document, mirroring
|
|
186
|
+
* the HTTP tiers in `handler/error.ts`: `value` replaces the whole frame,
|
|
187
|
+
* `detail` fills the `detail` member, the message is the last resort.
|
|
188
|
+
*
|
|
189
|
+
* A frame carries no headers, so a `headers` annotation is ignored outright
|
|
190
|
+
* rather than half-applied
|
|
191
|
+
*/
|
|
192
|
+
function wsProblemFrame(error) {
|
|
193
|
+
const status = resolveStatus(error.status);
|
|
194
|
+
const served = typeof status === "number" && status >= 100 ? status : 500;
|
|
195
|
+
const stringify = (value) => typeof value === "object" && value !== null ? JSON.stringify(value) : String(value);
|
|
196
|
+
const problemFrame = (detail) => JSON.stringify(problemBody({
|
|
197
|
+
type: error.type ?? "about:blank",
|
|
198
|
+
detail,
|
|
199
|
+
status: served
|
|
200
|
+
}));
|
|
201
|
+
const serveMessage = () => problemFrame(statusFallbackBody(error, served));
|
|
202
|
+
const serveDetail = () => {
|
|
203
|
+
const detail = readAnnotation(error, "detail", true);
|
|
204
|
+
if (detail === void 0) return serveMessage();
|
|
205
|
+
if (detail instanceof Promise) return detail.then((resolved) => resolved === void 0 ? serveMessage() : problemFrame(resolved)).catch(() => wsLegacyFrame(error));
|
|
206
|
+
return problemFrame(detail);
|
|
207
|
+
};
|
|
208
|
+
const value = readAnnotation(error, "value", true);
|
|
209
|
+
if (value === void 0) return serveDetail();
|
|
210
|
+
if (value instanceof Promise) return value.then((resolved) => resolved === void 0 ? serveDetail() : stringify(resolved)).catch(() => wsLegacyFrame(error));
|
|
211
|
+
return stringify(value);
|
|
212
|
+
}
|
|
183
213
|
function wsErrorFrameFallback(error) {
|
|
214
|
+
if (claimsProblemType(error)) try {
|
|
215
|
+
return wsProblemFrame(error);
|
|
216
|
+
} catch {}
|
|
217
|
+
return wsLegacyFrame(error);
|
|
218
|
+
}
|
|
219
|
+
/** Frame an error that never self-described has always served */
|
|
220
|
+
function wsLegacyFrame(error) {
|
|
184
221
|
if (error?.status) {
|
|
185
|
-
const body = error
|
|
222
|
+
const body = statusFallbackBody(error, error.status);
|
|
186
223
|
return typeof body === "object" ? JSON.stringify(body) : String(body);
|
|
187
224
|
}
|
|
188
225
|
return internalServerErrorBodyString(error);
|
|
@@ -217,13 +254,20 @@ const wsOptions = [
|
|
|
217
254
|
];
|
|
218
255
|
function buildWSRoute(route, app) {
|
|
219
256
|
const hook = resolveWSLocalHook(localMacroRoot(route[7] ?? route[3] ?? app, app), route[4], app) ?? nullObject();
|
|
257
|
+
const instance = route[3] ?? app;
|
|
258
|
+
const appHookChain = route[5];
|
|
259
|
+
const inheritedChain = route[6];
|
|
260
|
+
const composed = composeRouteHook(instance, route[4], appHookChain, inheritedChain, app, route[7]) ?? hook;
|
|
220
261
|
let validators;
|
|
221
|
-
const frozenEager = isBridgeLive() ? void 0 : buildFrozenRouteValidator(
|
|
262
|
+
const frozenEager = isBridgeLive() ? void 0 : buildFrozenRouteValidator(composed, app, "WS", route[1]);
|
|
222
263
|
if (frozenEager) validators = frozenEager;
|
|
223
264
|
else try {
|
|
224
|
-
validators = new RouteValidator(
|
|
265
|
+
validators = new RouteValidator(composed, {
|
|
225
266
|
models: frozenRootOf(app)["~ext"]?.models,
|
|
226
267
|
app,
|
|
268
|
+
normalize: frozenRootOf(app)["~config"]?.normalize,
|
|
269
|
+
sanitize: frozenRootOf(app)["~config"]?.sanitize,
|
|
270
|
+
schemas: composed.schemas,
|
|
227
271
|
aot: {
|
|
228
272
|
method: "WS",
|
|
229
273
|
path: route[1]
|
|
@@ -232,18 +276,17 @@ function buildWSRoute(route, app) {
|
|
|
232
276
|
});
|
|
233
277
|
} catch (error) {
|
|
234
278
|
if (!isBridgeNotInitialized(error)) throw error;
|
|
235
|
-
const frozen = buildFrozenRouteValidator(
|
|
279
|
+
const frozen = buildFrozenRouteValidator(composed, app, "WS", route[1]);
|
|
236
280
|
if (!frozen) throw error;
|
|
237
281
|
validators = frozen;
|
|
238
282
|
}
|
|
239
283
|
const responseValidator = validators.response;
|
|
240
284
|
const defaultResponseValidator = responseValidator ? responseValidator[200] ?? responseValidator[Object.keys(responseValidator)[0]] : void 0;
|
|
285
|
+
const cookieConfig = validators.cookie ? compileCookieConfig(composed.cookie, frozenRootOf(app)["~config"]?.cookie) : void 0;
|
|
286
|
+
const cookieIsOptional = !!composed.cookie?.["~optional"];
|
|
241
287
|
const queryChannels = getQueryParseChannels(validators.query?.schema);
|
|
242
288
|
const queryArray = queryChannels?.array;
|
|
243
289
|
const queryObject = queryChannels?.object;
|
|
244
|
-
const instance = route[3] ?? app;
|
|
245
|
-
const appHookChain = route[5];
|
|
246
|
-
const inheritedChain = route[6];
|
|
247
290
|
const flatAppHook = composeRouteHook(instance, void 0, appHookChain, inheritedChain, app, route[7]) ?? {};
|
|
248
291
|
const parseHooks = hook.parse == null ? [] : Array.isArray(hook.parse) ? hook.parse : [hook.parse];
|
|
249
292
|
const transforms = concatHooks(flatAppHook.transform, hook.transform);
|
|
@@ -271,6 +314,7 @@ function buildWSRoute(route, app) {
|
|
|
271
314
|
break;
|
|
272
315
|
}
|
|
273
316
|
if (r !== void 0) {
|
|
317
|
+
r = adoptErrorType(r, error);
|
|
274
318
|
try {
|
|
275
319
|
await handleWSResponse(ws, r, mapResponses);
|
|
276
320
|
} catch {}
|
|
@@ -418,6 +462,15 @@ function buildWSRoute(route, app) {
|
|
|
418
462
|
if (r instanceof Promise) r = await r;
|
|
419
463
|
context.headers = r;
|
|
420
464
|
}
|
|
465
|
+
if (cookieConfig) {
|
|
466
|
+
const raw = await parseCookieRaw(request.headers.get("cookie"), cookieConfig);
|
|
467
|
+
let r = raw;
|
|
468
|
+
if (!cookieIsOptional || Object.keys(raw).length) {
|
|
469
|
+
r = validateUpgradeChannel(validators.cookie, raw, "cookie");
|
|
470
|
+
if (r instanceof Promise) r = await r;
|
|
471
|
+
}
|
|
472
|
+
context.cookie = buildCookieJar(context.set, r, cookieConfig);
|
|
473
|
+
}
|
|
421
474
|
for (let i = 0; i < transforms.length; i++) {
|
|
422
475
|
const r = transforms[i](context);
|
|
423
476
|
if (r instanceof Promise) await r;
|
|
@@ -429,7 +482,7 @@ function buildWSRoute(route, app) {
|
|
|
429
482
|
const deriveMode = upgradeDeriveModes?.[i];
|
|
430
483
|
if (deriveMode !== void 0 && !(r instanceof ElysiaStatus)) {
|
|
431
484
|
if (r && typeof r === "object") if (deriveMode) context = replaceDeriveContext(context, r);
|
|
432
|
-
else
|
|
485
|
+
else assignOwn(context, r);
|
|
433
486
|
} else if (r !== void 0) {
|
|
434
487
|
if (r instanceof Response) return r;
|
|
435
488
|
return mapResponse(r, context.set, context.request);
|
|
@@ -484,23 +537,40 @@ function resolveWSOptions(entries) {
|
|
|
484
537
|
const incoming = entry.value[key];
|
|
485
538
|
if (key in result && result[key] !== incoming && !warned?.has(key)) {
|
|
486
539
|
(warned ??= /* @__PURE__ */ new Set()).add(key);
|
|
487
|
-
console.warn(`[Elysia] Conflicting WebSocket option '${key}' across .use(websocket())
|
|
540
|
+
console.warn(`[Elysia] Conflicting WebSocket option '${key}' across .use(websocket()). Using nearest-root registration.`);
|
|
488
541
|
}
|
|
489
542
|
result[key] = incoming;
|
|
490
543
|
}
|
|
491
544
|
return result;
|
|
492
545
|
}
|
|
546
|
+
const wsLimits = [
|
|
547
|
+
"maxPayloadLength",
|
|
548
|
+
"backpressureLimit",
|
|
549
|
+
"idleTimeout"
|
|
550
|
+
];
|
|
551
|
+
const routeOwnedKeys = /* @__PURE__ */ new WeakMap();
|
|
493
552
|
function accumulateWSOptions(target, routeOptions, _path) {
|
|
494
553
|
if (!isNotEmpty(routeOptions)) return;
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
554
|
+
let owned = routeOwnedKeys.get(target);
|
|
555
|
+
if (!owned) routeOwnedKeys.set(target, owned = /* @__PURE__ */ new Set());
|
|
556
|
+
for (const key in routeOptions) {
|
|
557
|
+
const incoming = routeOptions[key];
|
|
558
|
+
const current = target[key];
|
|
559
|
+
if (key in target && current !== incoming) {
|
|
560
|
+
if (isBun) {
|
|
561
|
+
console.warn(`[Elysia] Conflicting per-route WebSocket option '${key}'\nBun uses one global WebSocket config per server, per-route values are not enforced (for limits the strictest route wins, otherwise the last-registered route).`);
|
|
562
|
+
console.warn((/* @__PURE__ */ new Error()).stack);
|
|
563
|
+
}
|
|
564
|
+
if (owned.has(key) && typeof current === "number" && typeof incoming === "number" && current < incoming && wsLimits.includes(key)) continue;
|
|
499
565
|
}
|
|
566
|
+
owned.add(key);
|
|
567
|
+
target[key] = incoming;
|
|
500
568
|
}
|
|
501
|
-
Object.assign(target, routeOptions);
|
|
502
569
|
}
|
|
570
|
+
const MAX_INFLIGHT_MESSAGES = 256;
|
|
503
571
|
function buildGlobalWSHandler() {
|
|
572
|
+
let lifecycle;
|
|
573
|
+
const runLifecycle = (callback, ...args) => lifecycle ? lifecycle.run(callback, ...args) : callback(...args);
|
|
504
574
|
function getElysia(ws) {
|
|
505
575
|
let elysia = ws.data.elysia;
|
|
506
576
|
if (!elysia) {
|
|
@@ -515,39 +585,117 @@ function buildGlobalWSHandler() {
|
|
|
515
585
|
ws.send(typeof error?.message === "string" ? error.message : "Internal Server Error");
|
|
516
586
|
} catch {}
|
|
517
587
|
};
|
|
518
|
-
|
|
588
|
+
const releaseLifecycle = (ws) => {
|
|
589
|
+
if (!lifecycle?.closing && isSocketQuiet(ws)) {
|
|
590
|
+
delete ws.data["~lifecycleRun"];
|
|
591
|
+
lifecycle?.sockets.delete(ws);
|
|
592
|
+
}
|
|
593
|
+
};
|
|
594
|
+
const release = (ws) => {
|
|
595
|
+
const data = ws.data;
|
|
596
|
+
const inflight = data.inflight;
|
|
597
|
+
if (inflight) {
|
|
598
|
+
data.inflight = inflight - 1;
|
|
599
|
+
if (inflight === 1 && data.closeHandlerInvoked) releaseLifecycle(ws);
|
|
600
|
+
}
|
|
601
|
+
};
|
|
602
|
+
function dispatch(ws, message) {
|
|
603
|
+
let result;
|
|
604
|
+
try {
|
|
605
|
+
result = ws.data.message(getElysia(ws), message);
|
|
606
|
+
} catch (error) {
|
|
607
|
+
release(ws);
|
|
608
|
+
sendErrMsg(ws, error);
|
|
609
|
+
return;
|
|
610
|
+
}
|
|
611
|
+
if (result instanceof Promise) result.then(() => release(ws), (error) => {
|
|
612
|
+
release(ws);
|
|
613
|
+
sendErrMsg(ws, error);
|
|
614
|
+
});
|
|
615
|
+
else release(ws);
|
|
616
|
+
}
|
|
617
|
+
const handler = {
|
|
519
618
|
message(ws, message) {
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
619
|
+
if (lifecycle?.closing) return;
|
|
620
|
+
const data = ws.data;
|
|
621
|
+
if (!data.message) return;
|
|
622
|
+
const inflight = (data.inflight ?? 0) + 1;
|
|
623
|
+
if (inflight > MAX_INFLIGHT_MESSAGES) {
|
|
624
|
+
try {
|
|
625
|
+
ws.close(1013, "Too many in-flight messages");
|
|
626
|
+
} catch {}
|
|
525
627
|
return;
|
|
526
628
|
}
|
|
527
|
-
|
|
629
|
+
data.inflight = inflight;
|
|
630
|
+
const opening = data.opening;
|
|
631
|
+
if (opening) return void opening.then(() => {
|
|
632
|
+
if (lifecycle?.closing || ws.readyState > 1) return release(ws);
|
|
633
|
+
dispatch(ws, message);
|
|
634
|
+
});
|
|
635
|
+
dispatch(ws, message);
|
|
528
636
|
},
|
|
529
637
|
open(ws) {
|
|
530
|
-
ws.data
|
|
638
|
+
if (lifecycle) Object.defineProperty(ws.data, "~lifecycleRun", {
|
|
639
|
+
configurable: true,
|
|
640
|
+
value: lifecycle.run
|
|
641
|
+
});
|
|
642
|
+
lifecycle?.sockets.add(ws);
|
|
643
|
+
if (lifecycle?.closing) {
|
|
644
|
+
ws.data.closeHandlerInvoked = true;
|
|
645
|
+
try {
|
|
646
|
+
ws.terminate();
|
|
647
|
+
} catch {}
|
|
648
|
+
return;
|
|
649
|
+
}
|
|
650
|
+
const open = ws.data.open;
|
|
651
|
+
const result = open && runLifecycle(open, getElysia(ws));
|
|
652
|
+
if (result instanceof Promise) {
|
|
653
|
+
const clear = () => {
|
|
654
|
+
ws.data.opening = void 0;
|
|
655
|
+
releaseLifecycle(ws);
|
|
656
|
+
};
|
|
657
|
+
ws.data.opening = result.then(clear, clear);
|
|
658
|
+
}
|
|
531
659
|
},
|
|
532
660
|
drain(ws) {
|
|
661
|
+
if (lifecycle?.closing) return;
|
|
533
662
|
const elyWs = getElysia(ws);
|
|
534
663
|
drainWaiters(elyWs);
|
|
535
|
-
ws.data.drain
|
|
664
|
+
const drain = ws.data.drain;
|
|
665
|
+
trackWSSettling(ws.data, drain && runLifecycle(drain, elyWs), () => releaseLifecycle(ws));
|
|
536
666
|
},
|
|
537
667
|
close(ws, code, reason) {
|
|
538
668
|
const elyWs = getElysia(ws);
|
|
539
669
|
drainWaiters(elyWs);
|
|
540
|
-
if (ws.data.closeHandlerInvoked) return;
|
|
670
|
+
if (ws.data.closeHandlerInvoked) return releaseLifecycle(ws);
|
|
541
671
|
ws.data.closeHandlerInvoked = true;
|
|
542
|
-
|
|
672
|
+
let result;
|
|
673
|
+
try {
|
|
674
|
+
const close = ws.data.close;
|
|
675
|
+
result = close && runLifecycle(close, elyWs, code, reason);
|
|
676
|
+
} finally {
|
|
677
|
+
if (!(result instanceof Promise)) releaseLifecycle(ws);
|
|
678
|
+
}
|
|
679
|
+
if (result instanceof Promise) {
|
|
680
|
+
const closing = result.catch(() => {});
|
|
681
|
+
trackWSSettling(ws.data, closing, () => releaseLifecycle(ws));
|
|
682
|
+
}
|
|
543
683
|
},
|
|
544
684
|
ping(ws, data) {
|
|
545
|
-
|
|
685
|
+
if (lifecycle?.closing) return;
|
|
686
|
+
const ping = ws.data.ping;
|
|
687
|
+
trackWSSettling(ws.data, ping && runLifecycle(ping, getElysia(ws), data), () => releaseLifecycle(ws));
|
|
546
688
|
},
|
|
547
689
|
pong(ws, data) {
|
|
548
|
-
|
|
690
|
+
if (lifecycle?.closing) return;
|
|
691
|
+
const pong = ws.data.pong;
|
|
692
|
+
trackWSSettling(ws.data, pong && runLifecycle(pong, getElysia(ws), data), () => releaseLifecycle(ws));
|
|
549
693
|
}
|
|
550
694
|
};
|
|
695
|
+
Object.defineProperty(handler, "~lifecycle", { set(value) {
|
|
696
|
+
lifecycle = value;
|
|
697
|
+
} });
|
|
698
|
+
return handler;
|
|
551
699
|
}
|
|
552
700
|
|
|
553
701
|
//#endregion
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "elysia",
|
|
3
3
|
"description": "Ergonomic Framework for Human",
|
|
4
|
-
"version": "2.0.0-beta.
|
|
4
|
+
"version": "2.0.0-beta.4",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "saltyAom",
|
|
7
7
|
"url": "https://github.com/SaltyAom",
|
|
@@ -238,11 +238,13 @@
|
|
|
238
238
|
"./dist/type/exports.mjs",
|
|
239
239
|
"./dist/type/exports.js",
|
|
240
240
|
"./dist/type/bridge-live.mjs",
|
|
241
|
-
"./dist/type/bridge-live.js"
|
|
241
|
+
"./dist/type/bridge-live.js",
|
|
242
|
+
"./dist/type/typebox-value-live.mjs",
|
|
243
|
+
"./dist/type/typebox-value-live.js"
|
|
242
244
|
],
|
|
243
245
|
"dependencies": {
|
|
244
246
|
"deuri": "^3.0.0",
|
|
245
|
-
"memoirist": "1.2.
|
|
247
|
+
"memoirist": "1.2.2"
|
|
246
248
|
},
|
|
247
249
|
"devDependencies": {
|
|
248
250
|
"@eslint/eslintrc": "^3.3.5",
|