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/context.js
CHANGED
|
@@ -8,6 +8,19 @@ function pickValidator(validators, defaultValidator, data) {
|
|
|
8
8
|
if (data instanceof require_error.ElysiaStatus) return validators[data.status];
|
|
9
9
|
return defaultValidator;
|
|
10
10
|
}
|
|
11
|
+
function trackWSSettling(data, result, onSettled) {
|
|
12
|
+
if (!(result instanceof Promise)) return;
|
|
13
|
+
data.settling = (data.settling ?? 0) + 1;
|
|
14
|
+
const release = () => {
|
|
15
|
+
data.settling--;
|
|
16
|
+
onSettled?.();
|
|
17
|
+
};
|
|
18
|
+
result.then(release, release);
|
|
19
|
+
}
|
|
20
|
+
const runWSLifecycle = (data, callback, ...args) => {
|
|
21
|
+
const lifecycle = data["~lifecycleRun"];
|
|
22
|
+
return lifecycle ? lifecycle(callback, ...args) : callback(...args);
|
|
23
|
+
};
|
|
11
24
|
function memoize(view, key, value) {
|
|
12
25
|
const self = view.raw.data.elysia ?? view;
|
|
13
26
|
Object.defineProperty(self, key, {
|
|
@@ -24,6 +37,15 @@ var ElysiaWS = class {
|
|
|
24
37
|
this.raw = raw;
|
|
25
38
|
if (context) for (const key in context) {
|
|
26
39
|
if (key === "ws" || key === "body") continue;
|
|
40
|
+
if (key === "__proto__") {
|
|
41
|
+
Object.defineProperty(this, key, {
|
|
42
|
+
value: context[key],
|
|
43
|
+
writable: true,
|
|
44
|
+
enumerable: true,
|
|
45
|
+
configurable: true
|
|
46
|
+
});
|
|
47
|
+
continue;
|
|
48
|
+
}
|
|
27
49
|
this[key] = context[key];
|
|
28
50
|
}
|
|
29
51
|
}
|
|
@@ -62,58 +84,71 @@ var ElysiaWS = class {
|
|
|
62
84
|
get data() {
|
|
63
85
|
return this.raw.data;
|
|
64
86
|
}
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
});
|
|
71
|
-
if (typeof data === "object") return JSON.stringify(data);
|
|
72
|
-
return data;
|
|
73
|
-
}
|
|
74
|
-
#validatedOrError(data) {
|
|
87
|
+
/**
|
|
88
|
+
* Validate, redact and serialize an outbound value, or return the
|
|
89
|
+
* `ValidationError` the payload was refused with.
|
|
90
|
+
*/
|
|
91
|
+
#frame(data) {
|
|
75
92
|
const connectionData = this.raw.data;
|
|
76
93
|
const v = pickValidator(connectionData?.validator, connectionData?.defaultValidator, data);
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
if (v
|
|
80
|
-
|
|
94
|
+
const status = data instanceof require_error.ElysiaStatus ? data : void 0;
|
|
95
|
+
let value = status ? status.response : data;
|
|
96
|
+
if (v) {
|
|
97
|
+
const encode = v.EncodeFrom;
|
|
98
|
+
let redacted;
|
|
99
|
+
if (typeof encode === "function" && !v.hasCodec && !v.mayReturnPromise) try {
|
|
100
|
+
redacted = encode.call(v, value, "message");
|
|
101
|
+
} catch {}
|
|
102
|
+
if (redacted !== void 0) value = redacted;
|
|
103
|
+
else if (!v.Check(value)) return new require_error.ValidationError("message", value, v.Errors(value));
|
|
104
|
+
}
|
|
105
|
+
if (status) return JSON.stringify({
|
|
106
|
+
status: status.status,
|
|
107
|
+
error: value
|
|
108
|
+
});
|
|
109
|
+
if (value === void 0) return null;
|
|
110
|
+
if (typeof value === "object") return JSON.stringify(value);
|
|
111
|
+
return value;
|
|
81
112
|
}
|
|
82
113
|
#send(data, compress) {
|
|
83
114
|
if (data === void 0) return 0;
|
|
84
115
|
if (data instanceof ArrayBuffer || ArrayBuffer.isView(data)) return this.raw.send(data, compress);
|
|
85
|
-
const
|
|
86
|
-
if (
|
|
87
|
-
return this.raw.send(
|
|
116
|
+
const frame = this.#frame(data);
|
|
117
|
+
if (frame instanceof require_error.ValidationError) return this.raw.send(frame.message);
|
|
118
|
+
return this.raw.send(frame, compress);
|
|
88
119
|
}
|
|
89
120
|
#ping(data) {
|
|
90
121
|
if (data === void 0) return this.raw.ping();
|
|
91
122
|
if (data instanceof ArrayBuffer || ArrayBuffer.isView(data)) return this.raw.ping(data);
|
|
92
|
-
const
|
|
93
|
-
if (
|
|
94
|
-
return this.raw.ping(
|
|
123
|
+
const frame = this.#frame(data);
|
|
124
|
+
if (frame instanceof require_error.ValidationError) return this.raw.send(frame.message);
|
|
125
|
+
return this.raw.ping(frame);
|
|
95
126
|
}
|
|
96
127
|
#pong(data) {
|
|
97
128
|
if (data === void 0) return this.raw.pong();
|
|
98
129
|
if (data instanceof ArrayBuffer || ArrayBuffer.isView(data)) return this.raw.pong(data);
|
|
99
|
-
const
|
|
100
|
-
if (
|
|
101
|
-
return this.raw.pong(
|
|
130
|
+
const frame = this.#frame(data);
|
|
131
|
+
if (frame instanceof require_error.ValidationError) return this.raw.send(frame.message);
|
|
132
|
+
return this.raw.pong(frame);
|
|
102
133
|
}
|
|
103
134
|
#publish(topic, data, compress) {
|
|
104
135
|
if (data === void 0) return 0;
|
|
105
136
|
if (data instanceof ArrayBuffer || ArrayBuffer.isView(data)) return this.raw.publish(topic, data, compress);
|
|
106
|
-
const
|
|
107
|
-
if (
|
|
108
|
-
return this.raw.publish(topic,
|
|
137
|
+
const frame = this.#frame(data);
|
|
138
|
+
if (frame instanceof require_error.ValidationError) return this.raw.send(frame.message);
|
|
139
|
+
return this.raw.publish(topic, frame, compress);
|
|
109
140
|
}
|
|
110
141
|
#close(code, reason) {
|
|
111
142
|
const data = this.raw.data;
|
|
112
143
|
if (!data.closeHandlerInvoked && data.close) {
|
|
113
144
|
data.closeHandlerInvoked = true;
|
|
114
145
|
try {
|
|
115
|
-
const result = data.close
|
|
116
|
-
if (result instanceof Promise)
|
|
146
|
+
const result = runWSLifecycle(data, data.close, this, code ?? 1e3, reason ?? "");
|
|
147
|
+
if (result instanceof Promise) {
|
|
148
|
+
const closing = result.catch(() => {});
|
|
149
|
+
trackWSSettling(data, closing);
|
|
150
|
+
closing.then(() => this.raw.close(code, reason)).catch(() => this.raw.close(code, reason));
|
|
151
|
+
}
|
|
117
152
|
return;
|
|
118
153
|
} catch {}
|
|
119
154
|
}
|
|
@@ -149,4 +184,5 @@ function isGeneratorObject(value) {
|
|
|
149
184
|
|
|
150
185
|
//#endregion
|
|
151
186
|
exports.ElysiaWS = ElysiaWS;
|
|
152
|
-
exports.isGeneratorObject = isGeneratorObject;
|
|
187
|
+
exports.isGeneratorObject = isGeneratorObject;
|
|
188
|
+
exports.trackWSSettling = trackWSSettling;
|
package/dist/ws/context.mjs
CHANGED
|
@@ -7,6 +7,19 @@ function pickValidator(validators, defaultValidator, data) {
|
|
|
7
7
|
if (data instanceof ElysiaStatus) return validators[data.status];
|
|
8
8
|
return defaultValidator;
|
|
9
9
|
}
|
|
10
|
+
function trackWSSettling(data, result, onSettled) {
|
|
11
|
+
if (!(result instanceof Promise)) return;
|
|
12
|
+
data.settling = (data.settling ?? 0) + 1;
|
|
13
|
+
const release = () => {
|
|
14
|
+
data.settling--;
|
|
15
|
+
onSettled?.();
|
|
16
|
+
};
|
|
17
|
+
result.then(release, release);
|
|
18
|
+
}
|
|
19
|
+
const runWSLifecycle = (data, callback, ...args) => {
|
|
20
|
+
const lifecycle = data["~lifecycleRun"];
|
|
21
|
+
return lifecycle ? lifecycle(callback, ...args) : callback(...args);
|
|
22
|
+
};
|
|
10
23
|
function memoize(view, key, value) {
|
|
11
24
|
const self = view.raw.data.elysia ?? view;
|
|
12
25
|
Object.defineProperty(self, key, {
|
|
@@ -23,6 +36,15 @@ var ElysiaWS = class {
|
|
|
23
36
|
this.raw = raw;
|
|
24
37
|
if (context) for (const key in context) {
|
|
25
38
|
if (key === "ws" || key === "body") continue;
|
|
39
|
+
if (key === "__proto__") {
|
|
40
|
+
Object.defineProperty(this, key, {
|
|
41
|
+
value: context[key],
|
|
42
|
+
writable: true,
|
|
43
|
+
enumerable: true,
|
|
44
|
+
configurable: true
|
|
45
|
+
});
|
|
46
|
+
continue;
|
|
47
|
+
}
|
|
26
48
|
this[key] = context[key];
|
|
27
49
|
}
|
|
28
50
|
}
|
|
@@ -61,58 +83,71 @@ var ElysiaWS = class {
|
|
|
61
83
|
get data() {
|
|
62
84
|
return this.raw.data;
|
|
63
85
|
}
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
});
|
|
70
|
-
if (typeof data === "object") return JSON.stringify(data);
|
|
71
|
-
return data;
|
|
72
|
-
}
|
|
73
|
-
#validatedOrError(data) {
|
|
86
|
+
/**
|
|
87
|
+
* Validate, redact and serialize an outbound value, or return the
|
|
88
|
+
* `ValidationError` the payload was refused with.
|
|
89
|
+
*/
|
|
90
|
+
#frame(data) {
|
|
74
91
|
const connectionData = this.raw.data;
|
|
75
92
|
const v = pickValidator(connectionData?.validator, connectionData?.defaultValidator, data);
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
if (v
|
|
79
|
-
|
|
93
|
+
const status = data instanceof ElysiaStatus ? data : void 0;
|
|
94
|
+
let value = status ? status.response : data;
|
|
95
|
+
if (v) {
|
|
96
|
+
const encode = v.EncodeFrom;
|
|
97
|
+
let redacted;
|
|
98
|
+
if (typeof encode === "function" && !v.hasCodec && !v.mayReturnPromise) try {
|
|
99
|
+
redacted = encode.call(v, value, "message");
|
|
100
|
+
} catch {}
|
|
101
|
+
if (redacted !== void 0) value = redacted;
|
|
102
|
+
else if (!v.Check(value)) return new ValidationError("message", value, v.Errors(value));
|
|
103
|
+
}
|
|
104
|
+
if (status) return JSON.stringify({
|
|
105
|
+
status: status.status,
|
|
106
|
+
error: value
|
|
107
|
+
});
|
|
108
|
+
if (value === void 0) return null;
|
|
109
|
+
if (typeof value === "object") return JSON.stringify(value);
|
|
110
|
+
return value;
|
|
80
111
|
}
|
|
81
112
|
#send(data, compress) {
|
|
82
113
|
if (data === void 0) return 0;
|
|
83
114
|
if (data instanceof ArrayBuffer || ArrayBuffer.isView(data)) return this.raw.send(data, compress);
|
|
84
|
-
const
|
|
85
|
-
if (
|
|
86
|
-
return this.raw.send(
|
|
115
|
+
const frame = this.#frame(data);
|
|
116
|
+
if (frame instanceof ValidationError) return this.raw.send(frame.message);
|
|
117
|
+
return this.raw.send(frame, compress);
|
|
87
118
|
}
|
|
88
119
|
#ping(data) {
|
|
89
120
|
if (data === void 0) return this.raw.ping();
|
|
90
121
|
if (data instanceof ArrayBuffer || ArrayBuffer.isView(data)) return this.raw.ping(data);
|
|
91
|
-
const
|
|
92
|
-
if (
|
|
93
|
-
return this.raw.ping(
|
|
122
|
+
const frame = this.#frame(data);
|
|
123
|
+
if (frame instanceof ValidationError) return this.raw.send(frame.message);
|
|
124
|
+
return this.raw.ping(frame);
|
|
94
125
|
}
|
|
95
126
|
#pong(data) {
|
|
96
127
|
if (data === void 0) return this.raw.pong();
|
|
97
128
|
if (data instanceof ArrayBuffer || ArrayBuffer.isView(data)) return this.raw.pong(data);
|
|
98
|
-
const
|
|
99
|
-
if (
|
|
100
|
-
return this.raw.pong(
|
|
129
|
+
const frame = this.#frame(data);
|
|
130
|
+
if (frame instanceof ValidationError) return this.raw.send(frame.message);
|
|
131
|
+
return this.raw.pong(frame);
|
|
101
132
|
}
|
|
102
133
|
#publish(topic, data, compress) {
|
|
103
134
|
if (data === void 0) return 0;
|
|
104
135
|
if (data instanceof ArrayBuffer || ArrayBuffer.isView(data)) return this.raw.publish(topic, data, compress);
|
|
105
|
-
const
|
|
106
|
-
if (
|
|
107
|
-
return this.raw.publish(topic,
|
|
136
|
+
const frame = this.#frame(data);
|
|
137
|
+
if (frame instanceof ValidationError) return this.raw.send(frame.message);
|
|
138
|
+
return this.raw.publish(topic, frame, compress);
|
|
108
139
|
}
|
|
109
140
|
#close(code, reason) {
|
|
110
141
|
const data = this.raw.data;
|
|
111
142
|
if (!data.closeHandlerInvoked && data.close) {
|
|
112
143
|
data.closeHandlerInvoked = true;
|
|
113
144
|
try {
|
|
114
|
-
const result = data.close
|
|
115
|
-
if (result instanceof Promise)
|
|
145
|
+
const result = runWSLifecycle(data, data.close, this, code ?? 1e3, reason ?? "");
|
|
146
|
+
if (result instanceof Promise) {
|
|
147
|
+
const closing = result.catch(() => {});
|
|
148
|
+
trackWSSettling(data, closing);
|
|
149
|
+
closing.then(() => this.raw.close(code, reason)).catch(() => this.raw.close(code, reason));
|
|
150
|
+
}
|
|
116
151
|
return;
|
|
117
152
|
} catch {}
|
|
118
153
|
}
|
|
@@ -147,4 +182,4 @@ function isGeneratorObject(value) {
|
|
|
147
182
|
}
|
|
148
183
|
|
|
149
184
|
//#endregion
|
|
150
|
-
export { ElysiaWS, isGeneratorObject };
|
|
185
|
+
export { ElysiaWS, isGeneratorObject, trackWSSettling };
|
package/dist/ws/route.js
CHANGED
|
@@ -2,11 +2,12 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
|
2
2
|
const require_universal_constants = require('../universal/constants.js');
|
|
3
3
|
const require_utils = require('../utils.js');
|
|
4
4
|
const require_type_bridge = require('../type/bridge.js');
|
|
5
|
-
const require_universal_is_production = require('../universal/is-production.js');
|
|
6
5
|
const require_error = require('../error.js');
|
|
7
6
|
const require_adapter_web_standard_handler = require('../adapter/web-standard/handler.js');
|
|
8
7
|
const require_parse_query = require('../parse-query.js');
|
|
9
8
|
const require_generation = require('../generation.js');
|
|
9
|
+
const require_cookie_config = require('../cookie/config.js');
|
|
10
|
+
const require_cookie_utils = require('../cookie/utils.js');
|
|
10
11
|
const require_handler_error = require('../handler/error.js');
|
|
11
12
|
const require_compile_handler_utils = require('../compile/handler/utils.js');
|
|
12
13
|
const require_validator_index = require('../validator/index.js');
|
|
@@ -181,9 +182,45 @@ function wsErrorFrame(error) {
|
|
|
181
182
|
}
|
|
182
183
|
return wsErrorFrameFallback(error);
|
|
183
184
|
}
|
|
185
|
+
/**
|
|
186
|
+
* Frame served by an error that claims an RFC 9457 problem document, mirroring
|
|
187
|
+
* the HTTP tiers in `handler/error.ts`: `value` replaces the whole frame,
|
|
188
|
+
* `detail` fills the `detail` member, the message is the last resort.
|
|
189
|
+
*
|
|
190
|
+
* A frame carries no headers, so a `headers` annotation is ignored outright
|
|
191
|
+
* rather than half-applied
|
|
192
|
+
*/
|
|
193
|
+
function wsProblemFrame(error) {
|
|
194
|
+
const status = require_handler_error.resolveStatus(error.status);
|
|
195
|
+
const served = typeof status === "number" && status >= 100 ? status : 500;
|
|
196
|
+
const stringify = (value) => typeof value === "object" && value !== null ? JSON.stringify(value) : String(value);
|
|
197
|
+
const problemFrame = (detail) => JSON.stringify(require_error.problemBody({
|
|
198
|
+
type: error.type ?? "about:blank",
|
|
199
|
+
detail,
|
|
200
|
+
status: served
|
|
201
|
+
}));
|
|
202
|
+
const serveMessage = () => problemFrame(require_handler_error.statusFallbackBody(error, served));
|
|
203
|
+
const serveDetail = () => {
|
|
204
|
+
const detail = require_handler_error.readAnnotation(error, "detail", true);
|
|
205
|
+
if (detail === void 0) return serveMessage();
|
|
206
|
+
if (detail instanceof Promise) return detail.then((resolved) => resolved === void 0 ? serveMessage() : problemFrame(resolved)).catch(() => wsLegacyFrame(error));
|
|
207
|
+
return problemFrame(detail);
|
|
208
|
+
};
|
|
209
|
+
const value = require_handler_error.readAnnotation(error, "value", true);
|
|
210
|
+
if (value === void 0) return serveDetail();
|
|
211
|
+
if (value instanceof Promise) return value.then((resolved) => resolved === void 0 ? serveDetail() : stringify(resolved)).catch(() => wsLegacyFrame(error));
|
|
212
|
+
return stringify(value);
|
|
213
|
+
}
|
|
184
214
|
function wsErrorFrameFallback(error) {
|
|
215
|
+
if (require_handler_error.claimsProblemType(error)) try {
|
|
216
|
+
return wsProblemFrame(error);
|
|
217
|
+
} catch {}
|
|
218
|
+
return wsLegacyFrame(error);
|
|
219
|
+
}
|
|
220
|
+
/** Frame an error that never self-described has always served */
|
|
221
|
+
function wsLegacyFrame(error) {
|
|
185
222
|
if (error?.status) {
|
|
186
|
-
const body =
|
|
223
|
+
const body = require_handler_error.statusFallbackBody(error, error.status);
|
|
187
224
|
return typeof body === "object" ? JSON.stringify(body) : String(body);
|
|
188
225
|
}
|
|
189
226
|
return require_error.internalServerErrorBodyString(error);
|
|
@@ -218,13 +255,20 @@ const wsOptions = [
|
|
|
218
255
|
];
|
|
219
256
|
function buildWSRoute(route, app) {
|
|
220
257
|
const hook = require_compile_handler_index.resolveWSLocalHook(require_compile_handler_index.localMacroRoot(route[7] ?? route[3] ?? app, app), route[4], app) ?? require_utils.nullObject();
|
|
258
|
+
const instance = route[3] ?? app;
|
|
259
|
+
const appHookChain = route[5];
|
|
260
|
+
const inheritedChain = route[6];
|
|
261
|
+
const composed = require_compile_handler_index.composeRouteHook(instance, route[4], appHookChain, inheritedChain, app, route[7]) ?? hook;
|
|
221
262
|
let validators;
|
|
222
|
-
const frozenEager = require_type_bridge.isBridgeLive() ? void 0 : require_compile_handler_frozen_validator.buildFrozenRouteValidator(
|
|
263
|
+
const frozenEager = require_type_bridge.isBridgeLive() ? void 0 : require_compile_handler_frozen_validator.buildFrozenRouteValidator(composed, app, "WS", route[1]);
|
|
223
264
|
if (frozenEager) validators = frozenEager;
|
|
224
265
|
else try {
|
|
225
|
-
validators = new require_validator_route.RouteValidator(
|
|
266
|
+
validators = new require_validator_route.RouteValidator(composed, {
|
|
226
267
|
models: require_generation.frozenRootOf(app)["~ext"]?.models,
|
|
227
268
|
app,
|
|
269
|
+
normalize: require_generation.frozenRootOf(app)["~config"]?.normalize,
|
|
270
|
+
sanitize: require_generation.frozenRootOf(app)["~config"]?.sanitize,
|
|
271
|
+
schemas: composed.schemas,
|
|
228
272
|
aot: {
|
|
229
273
|
method: "WS",
|
|
230
274
|
path: route[1]
|
|
@@ -233,18 +277,17 @@ function buildWSRoute(route, app) {
|
|
|
233
277
|
});
|
|
234
278
|
} catch (error) {
|
|
235
279
|
if (!require_compile_handler_frozen_validator.isBridgeNotInitialized(error)) throw error;
|
|
236
|
-
const frozen = require_compile_handler_frozen_validator.buildFrozenRouteValidator(
|
|
280
|
+
const frozen = require_compile_handler_frozen_validator.buildFrozenRouteValidator(composed, app, "WS", route[1]);
|
|
237
281
|
if (!frozen) throw error;
|
|
238
282
|
validators = frozen;
|
|
239
283
|
}
|
|
240
284
|
const responseValidator = validators.response;
|
|
241
285
|
const defaultResponseValidator = responseValidator ? responseValidator[200] ?? responseValidator[Object.keys(responseValidator)[0]] : void 0;
|
|
286
|
+
const cookieConfig = validators.cookie ? require_cookie_config.compileCookieConfig(composed.cookie, require_generation.frozenRootOf(app)["~config"]?.cookie) : void 0;
|
|
287
|
+
const cookieIsOptional = !!composed.cookie?.["~optional"];
|
|
242
288
|
const queryChannels = require_compile_handler_utils.getQueryParseChannels(validators.query?.schema);
|
|
243
289
|
const queryArray = queryChannels?.array;
|
|
244
290
|
const queryObject = queryChannels?.object;
|
|
245
|
-
const instance = route[3] ?? app;
|
|
246
|
-
const appHookChain = route[5];
|
|
247
|
-
const inheritedChain = route[6];
|
|
248
291
|
const flatAppHook = require_compile_handler_index.composeRouteHook(instance, void 0, appHookChain, inheritedChain, app, route[7]) ?? {};
|
|
249
292
|
const parseHooks = hook.parse == null ? [] : Array.isArray(hook.parse) ? hook.parse : [hook.parse];
|
|
250
293
|
const transforms = concatHooks(flatAppHook.transform, hook.transform);
|
|
@@ -272,6 +315,7 @@ function buildWSRoute(route, app) {
|
|
|
272
315
|
break;
|
|
273
316
|
}
|
|
274
317
|
if (r !== void 0) {
|
|
318
|
+
r = require_handler_error.adoptErrorType(r, error);
|
|
275
319
|
try {
|
|
276
320
|
await handleWSResponse(ws, r, mapResponses);
|
|
277
321
|
} catch {}
|
|
@@ -419,6 +463,15 @@ function buildWSRoute(route, app) {
|
|
|
419
463
|
if (r instanceof Promise) r = await r;
|
|
420
464
|
context.headers = r;
|
|
421
465
|
}
|
|
466
|
+
if (cookieConfig) {
|
|
467
|
+
const raw = await require_cookie_utils.parseCookieRaw(request.headers.get("cookie"), cookieConfig);
|
|
468
|
+
let r = raw;
|
|
469
|
+
if (!cookieIsOptional || Object.keys(raw).length) {
|
|
470
|
+
r = validateUpgradeChannel(validators.cookie, raw, "cookie");
|
|
471
|
+
if (r instanceof Promise) r = await r;
|
|
472
|
+
}
|
|
473
|
+
context.cookie = require_cookie_utils.buildCookieJar(context.set, r, cookieConfig);
|
|
474
|
+
}
|
|
422
475
|
for (let i = 0; i < transforms.length; i++) {
|
|
423
476
|
const r = transforms[i](context);
|
|
424
477
|
if (r instanceof Promise) await r;
|
|
@@ -430,7 +483,7 @@ function buildWSRoute(route, app) {
|
|
|
430
483
|
const deriveMode = upgradeDeriveModes?.[i];
|
|
431
484
|
if (deriveMode !== void 0 && !(r instanceof require_error.ElysiaStatus)) {
|
|
432
485
|
if (r && typeof r === "object") if (deriveMode) context = require_compile_handler_utils.replaceDeriveContext(context, r);
|
|
433
|
-
else
|
|
486
|
+
else require_utils.assignOwn(context, r);
|
|
434
487
|
} else if (r !== void 0) {
|
|
435
488
|
if (r instanceof Response) return r;
|
|
436
489
|
return require_adapter_web_standard_handler.mapResponse(r, context.set, context.request);
|
|
@@ -485,23 +538,40 @@ function resolveWSOptions(entries) {
|
|
|
485
538
|
const incoming = entry.value[key];
|
|
486
539
|
if (key in result && result[key] !== incoming && !warned?.has(key)) {
|
|
487
540
|
(warned ??= /* @__PURE__ */ new Set()).add(key);
|
|
488
|
-
console.warn(`[Elysia] Conflicting WebSocket option '${key}' across .use(websocket())
|
|
541
|
+
console.warn(`[Elysia] Conflicting WebSocket option '${key}' across .use(websocket()). Using nearest-root registration.`);
|
|
489
542
|
}
|
|
490
543
|
result[key] = incoming;
|
|
491
544
|
}
|
|
492
545
|
return result;
|
|
493
546
|
}
|
|
547
|
+
const wsLimits = [
|
|
548
|
+
"maxPayloadLength",
|
|
549
|
+
"backpressureLimit",
|
|
550
|
+
"idleTimeout"
|
|
551
|
+
];
|
|
552
|
+
const routeOwnedKeys = /* @__PURE__ */ new WeakMap();
|
|
494
553
|
function accumulateWSOptions(target, routeOptions, _path) {
|
|
495
554
|
if (!require_utils.isNotEmpty(routeOptions)) return;
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
555
|
+
let owned = routeOwnedKeys.get(target);
|
|
556
|
+
if (!owned) routeOwnedKeys.set(target, owned = /* @__PURE__ */ new Set());
|
|
557
|
+
for (const key in routeOptions) {
|
|
558
|
+
const incoming = routeOptions[key];
|
|
559
|
+
const current = target[key];
|
|
560
|
+
if (key in target && current !== incoming) {
|
|
561
|
+
if (require_universal_constants.isBun) {
|
|
562
|
+
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).`);
|
|
563
|
+
console.warn((/* @__PURE__ */ new Error()).stack);
|
|
564
|
+
}
|
|
565
|
+
if (owned.has(key) && typeof current === "number" && typeof incoming === "number" && current < incoming && wsLimits.includes(key)) continue;
|
|
500
566
|
}
|
|
567
|
+
owned.add(key);
|
|
568
|
+
target[key] = incoming;
|
|
501
569
|
}
|
|
502
|
-
Object.assign(target, routeOptions);
|
|
503
570
|
}
|
|
571
|
+
const MAX_INFLIGHT_MESSAGES = 256;
|
|
504
572
|
function buildGlobalWSHandler() {
|
|
573
|
+
let lifecycle;
|
|
574
|
+
const runLifecycle = (callback, ...args) => lifecycle ? lifecycle.run(callback, ...args) : callback(...args);
|
|
505
575
|
function getElysia(ws) {
|
|
506
576
|
let elysia = ws.data.elysia;
|
|
507
577
|
if (!elysia) {
|
|
@@ -516,39 +586,117 @@ function buildGlobalWSHandler() {
|
|
|
516
586
|
ws.send(typeof error?.message === "string" ? error.message : "Internal Server Error");
|
|
517
587
|
} catch {}
|
|
518
588
|
};
|
|
519
|
-
|
|
589
|
+
const releaseLifecycle = (ws) => {
|
|
590
|
+
if (!lifecycle?.closing && require_utils.isSocketQuiet(ws)) {
|
|
591
|
+
delete ws.data["~lifecycleRun"];
|
|
592
|
+
lifecycle?.sockets.delete(ws);
|
|
593
|
+
}
|
|
594
|
+
};
|
|
595
|
+
const release = (ws) => {
|
|
596
|
+
const data = ws.data;
|
|
597
|
+
const inflight = data.inflight;
|
|
598
|
+
if (inflight) {
|
|
599
|
+
data.inflight = inflight - 1;
|
|
600
|
+
if (inflight === 1 && data.closeHandlerInvoked) releaseLifecycle(ws);
|
|
601
|
+
}
|
|
602
|
+
};
|
|
603
|
+
function dispatch(ws, message) {
|
|
604
|
+
let result;
|
|
605
|
+
try {
|
|
606
|
+
result = ws.data.message(getElysia(ws), message);
|
|
607
|
+
} catch (error) {
|
|
608
|
+
release(ws);
|
|
609
|
+
sendErrMsg(ws, error);
|
|
610
|
+
return;
|
|
611
|
+
}
|
|
612
|
+
if (result instanceof Promise) result.then(() => release(ws), (error) => {
|
|
613
|
+
release(ws);
|
|
614
|
+
sendErrMsg(ws, error);
|
|
615
|
+
});
|
|
616
|
+
else release(ws);
|
|
617
|
+
}
|
|
618
|
+
const handler = {
|
|
520
619
|
message(ws, message) {
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
620
|
+
if (lifecycle?.closing) return;
|
|
621
|
+
const data = ws.data;
|
|
622
|
+
if (!data.message) return;
|
|
623
|
+
const inflight = (data.inflight ?? 0) + 1;
|
|
624
|
+
if (inflight > MAX_INFLIGHT_MESSAGES) {
|
|
625
|
+
try {
|
|
626
|
+
ws.close(1013, "Too many in-flight messages");
|
|
627
|
+
} catch {}
|
|
526
628
|
return;
|
|
527
629
|
}
|
|
528
|
-
|
|
630
|
+
data.inflight = inflight;
|
|
631
|
+
const opening = data.opening;
|
|
632
|
+
if (opening) return void opening.then(() => {
|
|
633
|
+
if (lifecycle?.closing || ws.readyState > 1) return release(ws);
|
|
634
|
+
dispatch(ws, message);
|
|
635
|
+
});
|
|
636
|
+
dispatch(ws, message);
|
|
529
637
|
},
|
|
530
638
|
open(ws) {
|
|
531
|
-
ws.data
|
|
639
|
+
if (lifecycle) Object.defineProperty(ws.data, "~lifecycleRun", {
|
|
640
|
+
configurable: true,
|
|
641
|
+
value: lifecycle.run
|
|
642
|
+
});
|
|
643
|
+
lifecycle?.sockets.add(ws);
|
|
644
|
+
if (lifecycle?.closing) {
|
|
645
|
+
ws.data.closeHandlerInvoked = true;
|
|
646
|
+
try {
|
|
647
|
+
ws.terminate();
|
|
648
|
+
} catch {}
|
|
649
|
+
return;
|
|
650
|
+
}
|
|
651
|
+
const open = ws.data.open;
|
|
652
|
+
const result = open && runLifecycle(open, getElysia(ws));
|
|
653
|
+
if (result instanceof Promise) {
|
|
654
|
+
const clear = () => {
|
|
655
|
+
ws.data.opening = void 0;
|
|
656
|
+
releaseLifecycle(ws);
|
|
657
|
+
};
|
|
658
|
+
ws.data.opening = result.then(clear, clear);
|
|
659
|
+
}
|
|
532
660
|
},
|
|
533
661
|
drain(ws) {
|
|
662
|
+
if (lifecycle?.closing) return;
|
|
534
663
|
const elyWs = getElysia(ws);
|
|
535
664
|
drainWaiters(elyWs);
|
|
536
|
-
ws.data.drain
|
|
665
|
+
const drain = ws.data.drain;
|
|
666
|
+
require_ws_context.trackWSSettling(ws.data, drain && runLifecycle(drain, elyWs), () => releaseLifecycle(ws));
|
|
537
667
|
},
|
|
538
668
|
close(ws, code, reason) {
|
|
539
669
|
const elyWs = getElysia(ws);
|
|
540
670
|
drainWaiters(elyWs);
|
|
541
|
-
if (ws.data.closeHandlerInvoked) return;
|
|
671
|
+
if (ws.data.closeHandlerInvoked) return releaseLifecycle(ws);
|
|
542
672
|
ws.data.closeHandlerInvoked = true;
|
|
543
|
-
|
|
673
|
+
let result;
|
|
674
|
+
try {
|
|
675
|
+
const close = ws.data.close;
|
|
676
|
+
result = close && runLifecycle(close, elyWs, code, reason);
|
|
677
|
+
} finally {
|
|
678
|
+
if (!(result instanceof Promise)) releaseLifecycle(ws);
|
|
679
|
+
}
|
|
680
|
+
if (result instanceof Promise) {
|
|
681
|
+
const closing = result.catch(() => {});
|
|
682
|
+
require_ws_context.trackWSSettling(ws.data, closing, () => releaseLifecycle(ws));
|
|
683
|
+
}
|
|
544
684
|
},
|
|
545
685
|
ping(ws, data) {
|
|
546
|
-
|
|
686
|
+
if (lifecycle?.closing) return;
|
|
687
|
+
const ping = ws.data.ping;
|
|
688
|
+
require_ws_context.trackWSSettling(ws.data, ping && runLifecycle(ping, getElysia(ws), data), () => releaseLifecycle(ws));
|
|
547
689
|
},
|
|
548
690
|
pong(ws, data) {
|
|
549
|
-
|
|
691
|
+
if (lifecycle?.closing) return;
|
|
692
|
+
const pong = ws.data.pong;
|
|
693
|
+
require_ws_context.trackWSSettling(ws.data, pong && runLifecycle(pong, getElysia(ws), data), () => releaseLifecycle(ws));
|
|
550
694
|
}
|
|
551
695
|
};
|
|
696
|
+
Object.defineProperty(handler, "~lifecycle", { set(value) {
|
|
697
|
+
lifecycle = value;
|
|
698
|
+
} });
|
|
699
|
+
return handler;
|
|
552
700
|
}
|
|
553
701
|
|
|
554
702
|
//#endregion
|