@bquery/bquery 1.10.0 → 1.11.1
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/README.md +91 -65
- package/dist/{a11y-DG2i4iZN.js → a11y-DgUQ8-fI.js} +1 -1
- package/dist/{a11y-DG2i4iZN.js.map → a11y-DgUQ8-fI.js.map} +1 -1
- package/dist/a11y.es.mjs +1 -1
- package/dist/{component-DRotf1hl.js → component-D8ydhe58.js} +2 -2
- package/dist/{component-DRotf1hl.js.map → component-D8ydhe58.js.map} +1 -1
- package/dist/component.es.mjs +1 -1
- package/dist/concurrency-BU1wPEsZ.js.map +1 -1
- package/dist/{constraints-CqjhmpZC.js → constraints-Dlbx_m1b.js} +1 -1
- package/dist/{constraints-CqjhmpZC.js.map → constraints-Dlbx_m1b.js.map} +1 -1
- package/dist/{core-EMYSLzaT.js → core-tOP6QOrY.js} +2 -2
- package/dist/{core-EMYSLzaT.js.map → core-tOP6QOrY.js.map} +1 -1
- package/dist/core.es.mjs +1 -1
- package/dist/{custom-directives-BjFzFhuf.js → custom-directives-5DlKqvd2.js} +1 -1
- package/dist/{custom-directives-BjFzFhuf.js.map → custom-directives-5DlKqvd2.js.map} +1 -1
- package/dist/{devtools-C5FExMwv.js → devtools-QosAqo0T.js} +2 -2
- package/dist/{devtools-C5FExMwv.js.map → devtools-QosAqo0T.js.map} +1 -1
- package/dist/devtools.es.mjs +1 -1
- package/dist/{dnd-BAqzPlSo.js → dnd-d2OU4len.js} +1 -1
- package/dist/{dnd-BAqzPlSo.js.map → dnd-d2OU4len.js.map} +1 -1
- package/dist/dnd.es.mjs +1 -1
- package/dist/{forms-Dx1Scvh0.js → forms-BLx4ZzT7.js} +1 -1
- package/dist/{forms-Dx1Scvh0.js.map → forms-BLx4ZzT7.js.map} +1 -1
- package/dist/forms.es.mjs +1 -1
- package/dist/full.d.ts +4 -2
- package/dist/full.d.ts.map +1 -1
- package/dist/full.es.mjs +258 -219
- package/dist/full.iife.js +41 -37
- package/dist/full.iife.js.map +1 -1
- package/dist/full.umd.js +41 -37
- package/dist/full.umd.js.map +1 -1
- package/dist/{i18n-Cazyk9RD.js → i18n--p7PM-9r.js} +1 -1
- package/dist/{i18n-Cazyk9RD.js.map → i18n--p7PM-9r.js.map} +1 -1
- package/dist/i18n.es.mjs +1 -1
- package/dist/index.d.ts +3 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.es.mjs +291 -252
- package/dist/match-CrZRVC4z.js +174 -0
- package/dist/match-CrZRVC4z.js.map +1 -0
- package/dist/{media-dAKIGPk3.js → media-gjbWNq50.js} +1 -1
- package/dist/{media-dAKIGPk3.js.map → media-gjbWNq50.js.map} +1 -1
- package/dist/media.es.mjs +1 -1
- package/dist/motion-BBMso9Ir.js.map +1 -1
- package/dist/{mount-C8O2vXkQ.js → mount-0A9qtcRJ.js} +3 -3
- package/dist/{mount-C8O2vXkQ.js.map → mount-0A9qtcRJ.js.map} +1 -1
- package/dist/platform-BPHIXbw8.js.map +1 -1
- package/dist/{plugin-DjTqWg-P.js → plugin-SZEirbwq.js} +2 -2
- package/dist/{plugin-DjTqWg-P.js.map → plugin-SZEirbwq.js.map} +1 -1
- package/dist/plugin.es.mjs +1 -1
- package/dist/reactive-BAd2hfl8.js.map +1 -1
- package/dist/{registry-Cr6VH8CR.js → registry-jpUQHf4E.js} +1 -1
- package/dist/{registry-Cr6VH8CR.js.map → registry-jpUQHf4E.js.map} +1 -1
- package/dist/router-C4weu0QL.js +333 -0
- package/dist/router-C4weu0QL.js.map +1 -0
- package/dist/router.es.mjs +1 -1
- package/dist/{sanitize-B1V4JswB.js → sanitize-DOMkRO9G.js} +12 -7
- package/dist/{sanitize-B1V4JswB.js.map → sanitize-DOMkRO9G.js.map} +1 -1
- package/dist/security.es.mjs +1 -1
- package/dist/server/create-server.d.ts +25 -0
- package/dist/server/create-server.d.ts.map +1 -0
- package/dist/server/index.d.ts +11 -0
- package/dist/server/index.d.ts.map +1 -0
- package/dist/server/types.d.ts +396 -0
- package/dist/server/types.d.ts.map +1 -0
- package/dist/server-QdyKtCS1.js +349 -0
- package/dist/server-QdyKtCS1.js.map +1 -0
- package/dist/server.es.mjs +6 -0
- package/dist/ssr/adapters.d.ts +74 -0
- package/dist/ssr/adapters.d.ts.map +1 -0
- package/dist/ssr/async.d.ts +40 -0
- package/dist/ssr/async.d.ts.map +1 -0
- package/dist/ssr/config.d.ts +60 -0
- package/dist/ssr/config.d.ts.map +1 -0
- package/dist/ssr/context.d.ts +73 -0
- package/dist/ssr/context.d.ts.map +1 -0
- package/dist/ssr/defer-brand.d.ts +5 -0
- package/dist/ssr/defer-brand.d.ts.map +1 -0
- package/dist/ssr/escape.d.ts +17 -0
- package/dist/ssr/escape.d.ts.map +1 -0
- package/dist/ssr/expression.d.ts +44 -0
- package/dist/ssr/expression.d.ts.map +1 -0
- package/dist/ssr/hash.d.ts +39 -0
- package/dist/ssr/hash.d.ts.map +1 -0
- package/dist/ssr/head.d.ts +102 -0
- package/dist/ssr/head.d.ts.map +1 -0
- package/dist/ssr/html-parser.d.ts +58 -0
- package/dist/ssr/html-parser.d.ts.map +1 -0
- package/dist/ssr/index.d.ts +49 -43
- package/dist/ssr/index.d.ts.map +1 -1
- package/dist/ssr/mismatch.d.ts +60 -0
- package/dist/ssr/mismatch.d.ts.map +1 -0
- package/dist/ssr/render-async.d.ts +84 -0
- package/dist/ssr/render-async.d.ts.map +1 -0
- package/dist/ssr/render.d.ts.map +1 -1
- package/dist/ssr/renderer.d.ts +25 -0
- package/dist/ssr/renderer.d.ts.map +1 -0
- package/dist/ssr/resumability.d.ts +65 -0
- package/dist/ssr/resumability.d.ts.map +1 -0
- package/dist/ssr/router-bridge.d.ts +101 -0
- package/dist/ssr/router-bridge.d.ts.map +1 -0
- package/dist/ssr/runtime.d.ts +63 -0
- package/dist/ssr/runtime.d.ts.map +1 -0
- package/dist/ssr/serialize.d.ts.map +1 -1
- package/dist/ssr/store-snapshot.d.ts +87 -0
- package/dist/ssr/store-snapshot.d.ts.map +1 -0
- package/dist/ssr/strategies.d.ts +43 -0
- package/dist/ssr/strategies.d.ts.map +1 -0
- package/dist/ssr/suspense.d.ts +47 -0
- package/dist/ssr/suspense.d.ts.map +1 -0
- package/dist/ssr/types.d.ts +17 -0
- package/dist/ssr/types.d.ts.map +1 -1
- package/dist/ssr-Bt6BQA3J.js +2127 -0
- package/dist/ssr-Bt6BQA3J.js.map +1 -0
- package/dist/ssr.es.mjs +42 -7
- package/dist/{store-CjmEeX9-.js → store-DnXuu6Li.js} +2 -2
- package/dist/{store-CjmEeX9-.js.map → store-DnXuu6Li.js.map} +1 -1
- package/dist/store.es.mjs +2 -2
- package/dist/storybook.es.mjs +1 -1
- package/dist/{testing-TdfaL7VE.js → testing-CeMUwrRD.js} +2 -2
- package/dist/{testing-TdfaL7VE.js.map → testing-CeMUwrRD.js.map} +1 -1
- package/dist/testing.es.mjs +1 -1
- package/dist/view.es.mjs +1 -1
- package/package.json +19 -14
- package/src/full.ts +99 -0
- package/src/index.ts +5 -2
- package/src/server/create-server.ts +754 -0
- package/src/server/index.ts +33 -0
- package/src/server/types.ts +490 -0
- package/src/ssr/adapters.ts +330 -0
- package/src/ssr/async.ts +125 -0
- package/src/ssr/config.ts +86 -0
- package/src/ssr/context.ts +245 -0
- package/src/ssr/defer-brand.ts +3 -0
- package/src/ssr/escape.ts +25 -0
- package/src/ssr/expression.ts +669 -0
- package/src/ssr/hash.ts +71 -0
- package/src/ssr/head.ts +240 -0
- package/src/ssr/html-parser.ts +387 -0
- package/src/ssr/index.ts +136 -43
- package/src/ssr/mismatch.ts +110 -0
- package/src/ssr/render-async.ts +286 -0
- package/src/ssr/render.ts +130 -59
- package/src/ssr/renderer.ts +453 -0
- package/src/ssr/resumability.ts +142 -0
- package/src/ssr/router-bridge.ts +177 -0
- package/src/ssr/runtime.ts +131 -0
- package/src/ssr/serialize.ts +1 -27
- package/src/ssr/store-snapshot.ts +209 -0
- package/src/ssr/strategies.ts +245 -0
- package/src/ssr/suspense.ts +504 -0
- package/src/ssr/types.ts +18 -0
- package/dist/router-CCepRMpC.js +0 -493
- package/dist/router-CCepRMpC.js.map +0 -1
- package/dist/ssr-D-1IPcfw.js +0 -248
- package/dist/ssr-D-1IPcfw.js.map +0 -1
|
@@ -0,0 +1,349 @@
|
|
|
1
|
+
import { n as q } from "./sanitize-DOMkRO9G.js";
|
|
2
|
+
import { i as L } from "./object-BCk-1c8T.js";
|
|
3
|
+
import { L as H, N as J } from "./ssr-Bt6BQA3J.js";
|
|
4
|
+
var M = "http://localhost", D = {
|
|
5
|
+
"<": "\\u003C",
|
|
6
|
+
">": "\\u003E",
|
|
7
|
+
"&": "\\u0026",
|
|
8
|
+
"\u2028": "\\u2028",
|
|
9
|
+
"\u2029": "\\u2029"
|
|
10
|
+
}, j = /[<>&\u2028\u2029]/g, B = null, O = "x-bquery-websocket-passthrough", F = (e) => e.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"), g = () => /* @__PURE__ */ Object.create(null), R = (e) => {
|
|
11
|
+
if (!e) throw new Error(`route path must be a non-empty string; received ${String(e)}`);
|
|
12
|
+
if (e === "*" || e === "/*") return "/*";
|
|
13
|
+
const t = e.startsWith("/") ? e : `/${e}`;
|
|
14
|
+
return t.length > 1 && t.endsWith("/") ? t.slice(0, -1) : t;
|
|
15
|
+
}, x = (e) => {
|
|
16
|
+
const t = R(e);
|
|
17
|
+
if (t === "/*") return {
|
|
18
|
+
path: t,
|
|
19
|
+
paramNames: [],
|
|
20
|
+
pattern: /^\/.*$/
|
|
21
|
+
};
|
|
22
|
+
const a = t.split("/").filter(Boolean);
|
|
23
|
+
if (a.length === 0) return {
|
|
24
|
+
path: t,
|
|
25
|
+
paramNames: [],
|
|
26
|
+
pattern: /^\/$/
|
|
27
|
+
};
|
|
28
|
+
const r = [];
|
|
29
|
+
let n = "^";
|
|
30
|
+
for (const [s, u] of a.entries()) {
|
|
31
|
+
if (n += "/", u === "*") {
|
|
32
|
+
if (s !== a.length - 1) throw new Error(`invalid route path: "*" must be the final segment in "${t}"`);
|
|
33
|
+
n += ".*";
|
|
34
|
+
break;
|
|
35
|
+
}
|
|
36
|
+
if (u.startsWith(":")) {
|
|
37
|
+
const l = u.slice(1);
|
|
38
|
+
if (!/^[A-Za-z_$][\w$]*$/.test(l)) throw new Error(`invalid route param name: ${l} - must start with a letter, $, or _ and contain only word characters`);
|
|
39
|
+
if (L(l)) throw new Error(`invalid route param name: ${l} - reserved for object safety`);
|
|
40
|
+
r.push(l), n += "([^/]+)";
|
|
41
|
+
continue;
|
|
42
|
+
}
|
|
43
|
+
n += F(u);
|
|
44
|
+
}
|
|
45
|
+
return n += "/?$", {
|
|
46
|
+
path: t,
|
|
47
|
+
paramNames: r,
|
|
48
|
+
pattern: new RegExp(n)
|
|
49
|
+
};
|
|
50
|
+
}, G = (e) => {
|
|
51
|
+
if (typeof e > "u") return B;
|
|
52
|
+
const t = Array.isArray(e) ? e : [e];
|
|
53
|
+
if (t.length === 0) throw new Error("route method must be specified - received empty array");
|
|
54
|
+
const a = new Set(t.map((r) => r.trim().toUpperCase()).filter(Boolean));
|
|
55
|
+
if (a.size === 0) throw new Error(`route method must include at least one non-empty method string; received ${JSON.stringify(e)}`);
|
|
56
|
+
return a;
|
|
57
|
+
}, P = (e) => {
|
|
58
|
+
const t = g();
|
|
59
|
+
for (const [a, r] of e.searchParams.entries()) {
|
|
60
|
+
if (L(a)) continue;
|
|
61
|
+
const n = t[a];
|
|
62
|
+
typeof n > "u" ? t[a] = r : Array.isArray(n) ? n.push(r) : t[a] = [n, r];
|
|
63
|
+
}
|
|
64
|
+
return t;
|
|
65
|
+
}, A = (e, t) => e instanceof URL ? new URL(e.toString()) : new URL(e, t), N = (e, t) => {
|
|
66
|
+
if (e instanceof Request) return e;
|
|
67
|
+
if (typeof e == "string" || e instanceof URL) return new Request(A(e, t).toString());
|
|
68
|
+
const { url: a, method: r = "GET", headers: n, body: s = null } = e;
|
|
69
|
+
return new Request(A(a, t).toString(), {
|
|
70
|
+
method: r,
|
|
71
|
+
headers: n,
|
|
72
|
+
body: s
|
|
73
|
+
});
|
|
74
|
+
}, I = (e) => typeof e > "u" ? [] : [...new Set((Array.isArray(e) ? e : [e]).map((t) => t.trim()).filter(Boolean))], K = (e) => {
|
|
75
|
+
const t = e.data;
|
|
76
|
+
if (typeof t == "string") try {
|
|
77
|
+
return JSON.parse(t);
|
|
78
|
+
} catch {
|
|
79
|
+
return t;
|
|
80
|
+
}
|
|
81
|
+
return t;
|
|
82
|
+
}, Z = (e) => e.replace(j, (t) => D[t]), h = (e) => new Headers(e), b = (e, t) => (e.has("content-type") || e.set("content-type", t), e), m = (e, t = {}) => {
|
|
83
|
+
const { headers: a, ...r } = t;
|
|
84
|
+
return new Response(e, {
|
|
85
|
+
...r,
|
|
86
|
+
headers: h(a)
|
|
87
|
+
});
|
|
88
|
+
}, T = (e, t = {}) => {
|
|
89
|
+
const a = b(h(t.headers), "text/plain; charset=utf-8");
|
|
90
|
+
return m(e, {
|
|
91
|
+
...t,
|
|
92
|
+
headers: a
|
|
93
|
+
});
|
|
94
|
+
}, E = (e, t = {}) => {
|
|
95
|
+
const { trusted: a = !1, ...r } = t, n = b(h(r.headers), "text/html; charset=utf-8");
|
|
96
|
+
return m(a ? e : q(e), {
|
|
97
|
+
...r,
|
|
98
|
+
headers: n
|
|
99
|
+
});
|
|
100
|
+
}, U = (e, t = {}) => {
|
|
101
|
+
const a = b(h(t.headers), "application/json; charset=utf-8");
|
|
102
|
+
let r;
|
|
103
|
+
try {
|
|
104
|
+
r = JSON.stringify(e) ?? "null";
|
|
105
|
+
} catch {
|
|
106
|
+
r = "null";
|
|
107
|
+
}
|
|
108
|
+
return m(Z(r), {
|
|
109
|
+
...t,
|
|
110
|
+
headers: a
|
|
111
|
+
});
|
|
112
|
+
}, W = (e, t = 302) => m(null, {
|
|
113
|
+
headers: h({ location: e.toString() }),
|
|
114
|
+
status: t
|
|
115
|
+
}), k = (e, t, a = {}) => {
|
|
116
|
+
const { includeStoreState: r = !1, status: n = 200, headers: s, ...u } = a, l = J(e, t, {
|
|
117
|
+
...u,
|
|
118
|
+
includeStoreState: !1
|
|
119
|
+
}), S = r ? H({ storeIds: Array.isArray(r) ? r : void 0 }).scriptTag : "";
|
|
120
|
+
return E(`${l.html}${S}`, {
|
|
121
|
+
headers: s,
|
|
122
|
+
status: n,
|
|
123
|
+
trusted: !0
|
|
124
|
+
});
|
|
125
|
+
}, $ = (e) => {
|
|
126
|
+
if (e.method.toUpperCase() !== "GET") return !1;
|
|
127
|
+
const t = e.headers.get("upgrade");
|
|
128
|
+
if (typeof t != "string" || t.trim().toLowerCase() !== "websocket") return !1;
|
|
129
|
+
const a = e.headers.get("connection");
|
|
130
|
+
if (typeof a != "string" || !a.split(",").some((n) => n.trim().toLowerCase() === "upgrade") || e.headers.get("sec-websocket-version")?.trim() !== "13") return !1;
|
|
131
|
+
const r = e.headers.get("sec-websocket-key")?.trim();
|
|
132
|
+
return typeof r == "string" && /^[A-Za-z0-9+/]{22}==$/.test(r);
|
|
133
|
+
}, ie = (e) => {
|
|
134
|
+
if (typeof e != "object" || e === null || e instanceof Response) return !1;
|
|
135
|
+
const t = e;
|
|
136
|
+
return typeof t.open == "function" && typeof t.message == "function" && typeof t.close == "function" && typeof t.error == "function";
|
|
137
|
+
}, Q = () => {
|
|
138
|
+
const e = /* @__PURE__ */ new WeakMap();
|
|
139
|
+
return (t) => {
|
|
140
|
+
const a = e.get(t);
|
|
141
|
+
if (a) return a;
|
|
142
|
+
const r = {
|
|
143
|
+
get protocol() {
|
|
144
|
+
return t.protocol;
|
|
145
|
+
},
|
|
146
|
+
get readyState() {
|
|
147
|
+
return t.readyState;
|
|
148
|
+
},
|
|
149
|
+
get url() {
|
|
150
|
+
return t.url;
|
|
151
|
+
},
|
|
152
|
+
send(n) {
|
|
153
|
+
t.send(n);
|
|
154
|
+
},
|
|
155
|
+
sendJson(n) {
|
|
156
|
+
const s = JSON.stringify(n);
|
|
157
|
+
if (typeof s != "string") throw new TypeError("socket.sendJson() does not support undefined values");
|
|
158
|
+
t.send(s);
|
|
159
|
+
},
|
|
160
|
+
close(n, s) {
|
|
161
|
+
t.close(n, s);
|
|
162
|
+
}
|
|
163
|
+
};
|
|
164
|
+
return e.set(t, r), r;
|
|
165
|
+
};
|
|
166
|
+
}, V = (e, t) => {
|
|
167
|
+
const a = Q(), r = t.deserialize ?? K;
|
|
168
|
+
return {
|
|
169
|
+
context: e,
|
|
170
|
+
protocols: I(t.protocols),
|
|
171
|
+
headers: t.headers,
|
|
172
|
+
async open(n) {
|
|
173
|
+
t.onOpen && await t.onOpen(a(n), e);
|
|
174
|
+
},
|
|
175
|
+
async message(n, s) {
|
|
176
|
+
t.onMessage && await t.onMessage(r(s), a(n), e, s);
|
|
177
|
+
},
|
|
178
|
+
async close(n, s) {
|
|
179
|
+
t.onClose && await t.onClose(s, a(n), e);
|
|
180
|
+
},
|
|
181
|
+
async error(n, s) {
|
|
182
|
+
t.onError && await t.onError(s, a(n), e);
|
|
183
|
+
}
|
|
184
|
+
};
|
|
185
|
+
}, X = () => m(null, {
|
|
186
|
+
headers: h({ [O]: "1" }),
|
|
187
|
+
status: 204
|
|
188
|
+
}), Y = (e) => e.headers.get(O) === "1", ee = (e, t, a) => {
|
|
189
|
+
if (e.methods && !e.methods.has(t)) return null;
|
|
190
|
+
const r = e.pattern.exec(a);
|
|
191
|
+
if (!r) return null;
|
|
192
|
+
const n = g();
|
|
193
|
+
for (const [s, u] of e.paramNames.entries()) try {
|
|
194
|
+
n[u] = decodeURIComponent(r[s + 1] ?? "");
|
|
195
|
+
} catch (l) {
|
|
196
|
+
if (l instanceof URIError) return null;
|
|
197
|
+
throw l;
|
|
198
|
+
}
|
|
199
|
+
return n;
|
|
200
|
+
}, C = (e, t, a, r) => {
|
|
201
|
+
for (const n of e) {
|
|
202
|
+
const s = ee(n, t, a);
|
|
203
|
+
if (s)
|
|
204
|
+
return r.params = s, n;
|
|
205
|
+
}
|
|
206
|
+
return null;
|
|
207
|
+
}, te = async (e, t, a) => {
|
|
208
|
+
const r = async (n) => {
|
|
209
|
+
const s = t[n];
|
|
210
|
+
if (!s) return a();
|
|
211
|
+
let u = !1;
|
|
212
|
+
return await s(e, async () => {
|
|
213
|
+
if (u) throw new Error("middleware next() called multiple times - if a middleware calls next(), it may only do so once");
|
|
214
|
+
return u = !0, await r(n + 1);
|
|
215
|
+
});
|
|
216
|
+
};
|
|
217
|
+
return await r(0);
|
|
218
|
+
}, re = async (e, t, a) => {
|
|
219
|
+
const r = async (n) => {
|
|
220
|
+
const s = t[n];
|
|
221
|
+
if (!s) return a();
|
|
222
|
+
let u = !1;
|
|
223
|
+
return await s(e, async () => {
|
|
224
|
+
if (u) throw new Error("middleware next() called multiple times - if a middleware calls next(), it may only do so once");
|
|
225
|
+
return u = !0, await r(n + 1);
|
|
226
|
+
});
|
|
227
|
+
};
|
|
228
|
+
return await r(0);
|
|
229
|
+
}, ne = (e) => async (t, a) => {
|
|
230
|
+
let r = null, n = null;
|
|
231
|
+
const s = await e(t, async () => (r = await a(), r instanceof Response ? (n = r, r) : X()));
|
|
232
|
+
return n ? s : s instanceof Response && Y(s) ? r : s;
|
|
233
|
+
}, z = (e) => {
|
|
234
|
+
const t = x(e.path);
|
|
235
|
+
return {
|
|
236
|
+
handler: e.handler,
|
|
237
|
+
methods: G(e.method),
|
|
238
|
+
middlewares: e.middlewares ?? [],
|
|
239
|
+
paramNames: t.paramNames,
|
|
240
|
+
path: t.path,
|
|
241
|
+
pattern: t.pattern
|
|
242
|
+
};
|
|
243
|
+
}, ce = (e = {}) => {
|
|
244
|
+
const t = e.baseUrl ?? M, a = [...e.middlewares ?? []], r = [], n = [], s = e.notFound ?? ((o) => o.text("Not Found", { status: 404 })), u = e.onError ?? ((o, i) => o instanceof Response ? o : i.text("Internal Server Error", { status: 500 })), l = (o, i, c, f) => (r.push(z({
|
|
245
|
+
handler: c,
|
|
246
|
+
method: o,
|
|
247
|
+
middlewares: f,
|
|
248
|
+
path: i
|
|
249
|
+
})), w), S = (o, i, c) => {
|
|
250
|
+
const f = x(o);
|
|
251
|
+
return n.push({
|
|
252
|
+
handler: i,
|
|
253
|
+
methods: /* @__PURE__ */ new Set(["GET"]),
|
|
254
|
+
middlewares: c ?? [],
|
|
255
|
+
paramNames: f.paramNames,
|
|
256
|
+
path: f.path,
|
|
257
|
+
pattern: f.pattern
|
|
258
|
+
}), w;
|
|
259
|
+
}, w = {
|
|
260
|
+
use(o) {
|
|
261
|
+
return a.push(o), w;
|
|
262
|
+
},
|
|
263
|
+
add(o) {
|
|
264
|
+
return r.push(z(o)), w;
|
|
265
|
+
},
|
|
266
|
+
get(o, i, c) {
|
|
267
|
+
return l("GET", o, i, c);
|
|
268
|
+
},
|
|
269
|
+
post(o, i, c) {
|
|
270
|
+
return l("POST", o, i, c);
|
|
271
|
+
},
|
|
272
|
+
put(o, i, c) {
|
|
273
|
+
return l("PUT", o, i, c);
|
|
274
|
+
},
|
|
275
|
+
patch(o, i, c) {
|
|
276
|
+
return l("PATCH", o, i, c);
|
|
277
|
+
},
|
|
278
|
+
delete(o, i, c) {
|
|
279
|
+
return l("DELETE", o, i, c);
|
|
280
|
+
},
|
|
281
|
+
all(o, i, c) {
|
|
282
|
+
return l(void 0, o, i, c);
|
|
283
|
+
},
|
|
284
|
+
ws(o, i, c) {
|
|
285
|
+
return S(o, i, c);
|
|
286
|
+
},
|
|
287
|
+
async handle(o) {
|
|
288
|
+
const i = N(o, t), c = new URL(i.url), f = i.method.toUpperCase(), y = R(c.pathname || "/"), v = P(c), p = {
|
|
289
|
+
request: i,
|
|
290
|
+
url: c,
|
|
291
|
+
method: f,
|
|
292
|
+
path: y,
|
|
293
|
+
params: g(),
|
|
294
|
+
query: v,
|
|
295
|
+
state: {},
|
|
296
|
+
response: m,
|
|
297
|
+
text: T,
|
|
298
|
+
html: E,
|
|
299
|
+
json: U,
|
|
300
|
+
redirect: W,
|
|
301
|
+
render: k,
|
|
302
|
+
isWebSocketRequest: $(i)
|
|
303
|
+
};
|
|
304
|
+
try {
|
|
305
|
+
const d = C(r, f, y, p);
|
|
306
|
+
return d ? await te(p, [
|
|
307
|
+
...a,
|
|
308
|
+
...d.middlewares,
|
|
309
|
+
async (_) => await d.handler(_)
|
|
310
|
+
], async () => await s(p)) : await s(p);
|
|
311
|
+
} catch (d) {
|
|
312
|
+
return await u(d, p);
|
|
313
|
+
}
|
|
314
|
+
},
|
|
315
|
+
async handleWebSocket(o) {
|
|
316
|
+
const i = N(o, t), c = new URL(i.url), f = i.method.toUpperCase(), y = R(c.pathname || "/"), v = P(c), p = {
|
|
317
|
+
request: i,
|
|
318
|
+
url: c,
|
|
319
|
+
method: f,
|
|
320
|
+
path: y,
|
|
321
|
+
params: g(),
|
|
322
|
+
query: v,
|
|
323
|
+
state: {},
|
|
324
|
+
response: m,
|
|
325
|
+
text: T,
|
|
326
|
+
html: E,
|
|
327
|
+
json: U,
|
|
328
|
+
redirect: W,
|
|
329
|
+
render: k,
|
|
330
|
+
isWebSocketRequest: $(i)
|
|
331
|
+
};
|
|
332
|
+
if (!p.isWebSocketRequest) return null;
|
|
333
|
+
try {
|
|
334
|
+
const d = C(n, f, y, p);
|
|
335
|
+
return d ? await re(p, [...a.map(ne), ...d.middlewares], async () => V(p, typeof d.handler == "function" ? await d.handler(p) : d.handler)) : null;
|
|
336
|
+
} catch (d) {
|
|
337
|
+
return await u(d, p);
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
};
|
|
341
|
+
return w;
|
|
342
|
+
};
|
|
343
|
+
export {
|
|
344
|
+
ie as n,
|
|
345
|
+
$ as r,
|
|
346
|
+
ce as t
|
|
347
|
+
};
|
|
348
|
+
|
|
349
|
+
//# sourceMappingURL=server-QdyKtCS1.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server-QdyKtCS1.js","names":[],"sources":["../src/server/create-server.ts"],"sourcesContent":["import { isPrototypePollutionKey } from '../core/utils/object';\nimport { sanitizeHtml } from '../security/index';\nimport { renderToString, serializeStoreState } from '../ssr/index';\nimport type {\n CreateServerOptions,\n ServerApp,\n ServerContext,\n ServerHandler,\n ServerHtmlResponseInit,\n ServerMiddleware,\n ServerNext,\n ServerQuery,\n ServerRenderResponseOptions,\n ServerResult,\n ServerRequestInit,\n ServerResponseInit,\n ServerRoute,\n ServerWebSocketConnection,\n ServerWebSocketHandlerSet,\n ServerWebSocketMiddleware,\n ServerWebSocketNext,\n ServerWebSocketPeer,\n ServerWebSocketRouteHandler,\n ServerWebSocketSession,\n} from './types';\n\ninterface CompiledRoute {\n handler: ServerHandler;\n methods: Set<string> | null;\n middlewares: ServerMiddleware[];\n paramNames: string[];\n path: string;\n pattern: RegExp;\n}\n\ntype CompiledWebSocketRoute = Omit<CompiledRoute, 'handler' | 'middlewares'> & {\n handler: ServerWebSocketRouteHandler<unknown>;\n middlewares: ServerWebSocketMiddleware[];\n};\n\ntype PipelineHandler = (context: ServerContext, next: ServerNext) => Response | Promise<Response>;\ntype WebSocketPipelineHandler = (\n context: ServerContext,\n next: ServerWebSocketNext\n) => ServerResult | Promise<ServerResult>;\n\nconst DEFAULT_BASE_URL = 'http://localhost';\nconst JSON_ESCAPE_LOOKUP: Record<string, string> = {\n '<': '\\\\u003C',\n '>': '\\\\u003E',\n '&': '\\\\u0026',\n '\\u2028': '\\\\u2028',\n '\\u2029': '\\\\u2029',\n};\nconst JSON_ESCAPE_PATTERN = /[<>&\\u2028\\u2029]/g;\nconst METHOD_ALL = null;\nconst WEBSOCKET_PASSTHROUGH_HEADER = 'x-bquery-websocket-passthrough';\n\nconst escapeRegex = (value: string): string => value.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n/**\n * Creates a null-prototype dictionary for request-derived data.\n *\n * Request-controlled keys such as query params and route params must never write\n * into the default object prototype, otherwise names like `__proto__` can trigger\n * prototype-pollution bugs. Using `Object.create(null)` keeps these maps isolated\n * even before higher-level validation runs.\n */\nconst createDictionary = <T>(): Record<string, T> => Object.create(null) as Record<string, T>;\n\nconst normalizePath = (path: string): string => {\n if (!path) {\n throw new Error(`route path must be a non-empty string; received ${String(path)}`);\n }\n\n if (path === '*' || path === '/*') {\n return '/*';\n }\n\n const withLeadingSlash = path.startsWith('/') ? path : `/${path}`;\n if (withLeadingSlash.length > 1 && withLeadingSlash.endsWith('/')) {\n return withLeadingSlash.slice(0, -1);\n }\n\n return withLeadingSlash;\n};\n\nconst compileRoutePath = (path: string): Pick<CompiledRoute, 'paramNames' | 'path' | 'pattern'> => {\n const normalizedPath = normalizePath(path);\n\n if (normalizedPath === '/*') {\n return { path: normalizedPath, paramNames: [], pattern: /^\\/.*$/ };\n }\n\n const segments = normalizedPath.split('/').filter(Boolean);\n if (segments.length === 0) {\n return { path: normalizedPath, paramNames: [], pattern: /^\\/$/ };\n }\n\n const paramNames: string[] = [];\n let source = '^';\n\n for (const [index, segment] of segments.entries()) {\n source += '/';\n if (segment === '*') {\n if (index !== segments.length - 1) {\n throw new Error(`invalid route path: \"*\" must be the final segment in \"${normalizedPath}\"`);\n }\n source += '.*';\n break;\n }\n\n if (segment.startsWith(':')) {\n const paramName = segment.slice(1);\n if (!/^[A-Za-z_$][\\w$]*$/.test(paramName)) {\n throw new Error(\n `invalid route param name: ${paramName} - must start with a letter, $, or _ and contain only word characters`\n );\n }\n if (isPrototypePollutionKey(paramName)) {\n throw new Error(`invalid route param name: ${paramName} - reserved for object safety`);\n }\n paramNames.push(paramName);\n source += '([^/]+)';\n continue;\n }\n\n source += escapeRegex(segment);\n }\n\n source += '/?$';\n return { path: normalizedPath, paramNames, pattern: new RegExp(source) };\n};\n\nconst normalizeMethods = (method?: string | string[]): Set<string> | null => {\n if (typeof method === 'undefined') {\n return METHOD_ALL;\n }\n\n const values = Array.isArray(method) ? method : [method];\n if (values.length === 0) {\n throw new Error('route method must be specified - received empty array');\n }\n\n const normalizedMethods = new Set(\n values.map((value) => value.trim().toUpperCase()).filter(Boolean)\n );\n if (normalizedMethods.size === 0) {\n throw new Error(\n `route method must include at least one non-empty method string; received ${JSON.stringify(method)}`\n );\n }\n\n return normalizedMethods;\n};\n\nconst parseQuery = (url: URL): ServerQuery => {\n const query = createDictionary<string | string[] | undefined>() as ServerQuery;\n\n for (const [key, value] of url.searchParams.entries()) {\n if (isPrototypePollutionKey(key)) {\n continue;\n }\n const current = query[key];\n if (typeof current === 'undefined') {\n query[key] = value;\n } else if (Array.isArray(current)) {\n current.push(value);\n } else {\n query[key] = [current, value];\n }\n }\n\n return query;\n};\n\nconst normalizeUrl = (value: string | URL, baseUrl: string): URL => {\n return value instanceof URL ? new URL(value.toString()) : new URL(value, baseUrl);\n};\n\nconst normalizeRequest = (\n input: Request | string | URL | ServerRequestInit,\n baseUrl: string\n): Request => {\n if (input instanceof Request) {\n return input;\n }\n\n if (typeof input === 'string' || input instanceof URL) {\n return new Request(normalizeUrl(input, baseUrl).toString());\n }\n\n const { url, method = 'GET', headers, body = null } = input;\n return new Request(normalizeUrl(url, baseUrl).toString(), { method, headers, body });\n};\n\nconst normalizeWebSocketProtocols = (protocols?: string | string[]): string[] => {\n if (typeof protocols === 'undefined') {\n return [];\n }\n\n const values = Array.isArray(protocols) ? protocols : [protocols];\n return [...new Set(values.map((value) => value.trim()).filter(Boolean))];\n};\n\nconst defaultDeserialize = <TReceive>(event: MessageEvent): TReceive => {\n const raw = event.data;\n if (typeof raw === 'string') {\n try {\n return JSON.parse(raw) as TReceive;\n } catch {\n // Match `useWebSocket()` in `src/reactive/websocket.ts`: malformed JSON\n // payloads fall back to the original string instead of throwing.\n return raw as TReceive;\n }\n }\n\n return raw as TReceive;\n};\n\nconst escapeJsonString = (value: string): string =>\n value.replace(JSON_ESCAPE_PATTERN, (match) => JSON_ESCAPE_LOOKUP[match]);\n\nconst createHeaders = (headers?: HeadersInit): Headers => new Headers(headers);\n\nconst withContentType = (headers: Headers, contentType: string): Headers => {\n if (!headers.has('content-type')) {\n headers.set('content-type', contentType);\n }\n return headers;\n};\n\nconst response = (body?: BodyInit | null, init: ServerResponseInit = {}): Response => {\n const { headers, ...rest } = init;\n return new Response(body, { ...rest, headers: createHeaders(headers) });\n};\n\nconst text = (body: string, init: ServerResponseInit = {}): Response => {\n const headers = withContentType(createHeaders(init.headers), 'text/plain; charset=utf-8');\n return response(body, { ...init, headers });\n};\n\nconst html = (body: string, init: ServerHtmlResponseInit = {}): Response => {\n const { trusted = false, ...rest } = init;\n const headers = withContentType(createHeaders(rest.headers), 'text/html; charset=utf-8');\n return response(trusted ? body : sanitizeHtml(body), { ...rest, headers });\n};\n\nconst json = (data: unknown, init: ServerResponseInit = {}): Response => {\n const headers = withContentType(createHeaders(init.headers), 'application/json; charset=utf-8');\n let serialized: string;\n try {\n serialized = JSON.stringify(data) ?? 'null';\n } catch {\n serialized = 'null';\n }\n return response(escapeJsonString(serialized), { ...init, headers });\n};\n\nconst redirect = (location: string | URL, status = 302): Response => {\n const headers = createHeaders({ location: location.toString() });\n return response(null, { headers, status });\n};\n\nconst render = (\n template: string,\n data: Parameters<typeof renderToString>[1],\n options: ServerRenderResponseOptions = {}\n): Response => {\n const { includeStoreState = false, status = 200, headers, ...renderOptions } = options;\n const result = renderToString(template, data, { ...renderOptions, includeStoreState: false });\n const storeState = includeStoreState\n ? serializeStoreState({\n storeIds: Array.isArray(includeStoreState) ? includeStoreState : undefined,\n }).scriptTag\n : '';\n const body = `${result.html}${storeState}`;\n return html(body, { headers, status, trusted: true });\n};\n\n/**\n * Returns `true` when the request is a WebSocket upgrade handshake.\n */\nexport const isWebSocketRequest = (request: Request): boolean => {\n if (request.method.toUpperCase() !== 'GET') {\n return false;\n }\n\n const upgrade = request.headers.get('upgrade');\n if (typeof upgrade !== 'string' || upgrade.trim().toLowerCase() !== 'websocket') {\n return false;\n }\n\n const connection = request.headers.get('connection');\n if (typeof connection !== 'string') {\n return false;\n }\n\n if (!connection.split(',').some((part) => part.trim().toLowerCase() === 'upgrade')) {\n return false;\n }\n\n const version = request.headers.get('sec-websocket-version');\n if (version?.trim() !== '13') {\n return false;\n }\n\n const key = request.headers.get('sec-websocket-key')?.trim();\n return typeof key === 'string' && /^[A-Za-z0-9+/]{22}==$/.test(key);\n};\n\n/**\n * Type guard for values returned by `handleWebSocket()`.\n */\nexport const isServerWebSocketSession = (value: unknown): value is ServerWebSocketSession => {\n if (typeof value !== 'object' || value === null || value instanceof Response) {\n return false;\n }\n\n const candidate = value as Record<string, unknown>;\n return (\n typeof candidate.open === 'function' &&\n typeof candidate.message === 'function' &&\n typeof candidate.close === 'function' &&\n typeof candidate.error === 'function'\n );\n};\n\nconst createWebSocketConnectionFactory = () => {\n const cache = new WeakMap<object, ServerWebSocketConnection>();\n\n return (socket: ServerWebSocketPeer): ServerWebSocketConnection => {\n const existing = cache.get(socket);\n if (existing) {\n return existing;\n }\n\n const connection: ServerWebSocketConnection = {\n get protocol() {\n return socket.protocol;\n },\n get readyState() {\n return socket.readyState;\n },\n get url() {\n return socket.url;\n },\n send(data) {\n socket.send(data);\n },\n sendJson(data) {\n const payload = JSON.stringify(data);\n if (typeof payload !== 'string') {\n throw new TypeError('socket.sendJson() does not support undefined values');\n }\n socket.send(payload);\n },\n close(code, reason) {\n socket.close(code, reason);\n },\n };\n\n cache.set(socket, connection);\n return connection;\n };\n};\n\nconst createWebSocketSession = <TReceive>(\n context: ServerContext,\n handlers: ServerWebSocketHandlerSet<TReceive>\n): ServerWebSocketSession => {\n const toConnection = createWebSocketConnectionFactory();\n const deserialize = handlers.deserialize ?? defaultDeserialize<TReceive>;\n\n return {\n context,\n protocols: normalizeWebSocketProtocols(handlers.protocols),\n headers: handlers.headers,\n async open(socket) {\n if (handlers.onOpen) {\n await handlers.onOpen(toConnection(socket), context);\n }\n },\n async message(socket, event) {\n if (handlers.onMessage) {\n await handlers.onMessage(deserialize(event), toConnection(socket), context, event);\n }\n },\n async close(socket, event) {\n if (handlers.onClose) {\n await handlers.onClose(event, toConnection(socket), context);\n }\n },\n async error(socket, event) {\n if (handlers.onError) {\n await handlers.onError(event, toConnection(socket), context);\n }\n },\n };\n};\n\nconst createWebSocketPassthroughResponse = (): Response => {\n const headers = createHeaders({\n [WEBSOCKET_PASSTHROUGH_HEADER]: '1',\n });\n return response(null, { headers, status: 204 });\n};\n\nconst isWebSocketPassthroughResponse = (value: Response): boolean => {\n return value.headers.get(WEBSOCKET_PASSTHROUGH_HEADER) === '1';\n};\n\nconst matchRoute = (\n route: Pick<CompiledRoute, 'methods' | 'paramNames' | 'pattern'>,\n method: string,\n path: string\n): Record<string, string> | null => {\n if (route.methods && !route.methods.has(method)) {\n return null;\n }\n\n const match = route.pattern.exec(path);\n if (!match) {\n return null;\n }\n\n const params = createDictionary<string>();\n for (const [index, paramName] of route.paramNames.entries()) {\n try {\n params[paramName] = decodeURIComponent(match[index + 1] ?? '');\n } catch (error) {\n if (error instanceof URIError) {\n return null;\n }\n throw error;\n }\n }\n\n return params;\n};\n\nconst resolveMatchingRoute = <TRoute extends CompiledRoute | CompiledWebSocketRoute>(\n routes: TRoute[],\n method: string,\n path: string,\n context: ServerContext\n): TRoute | null => {\n for (const candidate of routes) {\n const params = matchRoute(candidate, method, path);\n if (!params) {\n continue;\n }\n context.params = params;\n return candidate;\n }\n\n return null;\n};\n\nconst runPipeline = async (\n context: ServerContext,\n handlers: PipelineHandler[],\n terminal: ServerNext\n): Promise<Response> => {\n const dispatch = async (index: number): Promise<Response> => {\n const current = handlers[index];\n if (!current) {\n return terminal();\n }\n\n let advanced = false;\n return await current(context, async () => {\n if (advanced) {\n throw new Error(\n 'middleware next() called multiple times - if a middleware calls next(), it may only do so once'\n );\n }\n advanced = true;\n return await dispatch(index + 1);\n });\n };\n\n return await dispatch(0);\n};\n\nconst runWebSocketPipeline = async (\n context: ServerContext,\n handlers: WebSocketPipelineHandler[],\n terminal: ServerWebSocketNext\n): Promise<ServerResult> => {\n const dispatch = async (index: number): Promise<ServerResult> => {\n const current = handlers[index];\n if (!current) {\n return terminal();\n }\n\n let advanced = false;\n return await current(context, async () => {\n if (advanced) {\n throw new Error(\n 'middleware next() called multiple times - if a middleware calls next(), it may only do so once'\n );\n }\n advanced = true;\n return await dispatch(index + 1);\n });\n };\n\n return await dispatch(0);\n};\n\nconst adaptHttpMiddlewareToWebSocket = (middleware: ServerMiddleware): WebSocketPipelineHandler => {\n return async (context, next) => {\n let downstream: ServerResult = null;\n let downstreamResponse: Response | null = null;\n const middlewareResponse = await middleware(context, async () => {\n downstream = await next();\n if (downstream instanceof Response) {\n downstreamResponse = downstream;\n return downstream;\n }\n return createWebSocketPassthroughResponse();\n });\n\n if (downstreamResponse) {\n return middlewareResponse;\n }\n\n if (middlewareResponse instanceof Response && isWebSocketPassthroughResponse(middlewareResponse)) {\n return downstream;\n }\n\n return middlewareResponse;\n };\n};\n\nconst compileRoute = (route: ServerRoute): CompiledRoute => {\n const compiledPath = compileRoutePath(route.path);\n return {\n handler: route.handler,\n methods: normalizeMethods(route.method),\n middlewares: route.middlewares ?? [],\n paramNames: compiledPath.paramNames,\n path: compiledPath.path,\n pattern: compiledPath.pattern,\n };\n};\n\n/**\n * Create a lightweight, Express-inspired request pipeline for SSR-aware\n * backends without introducing runtime dependencies.\n *\n * @example\n * ```ts\n * import { createServer } from '@bquery/bquery/server';\n *\n * const app = createServer();\n * app.get('/health', (ctx) => ctx.json({ ok: true }));\n *\n * const response = await app.handle('/health');\n * ```\n */\nexport const createServer = (options: CreateServerOptions = {}): ServerApp => {\n const baseUrl = options.baseUrl ?? DEFAULT_BASE_URL;\n const middlewares = [...(options.middlewares ?? [])];\n const routes: CompiledRoute[] = [];\n const webSocketRoutes: CompiledWebSocketRoute[] = [];\n\n const notFound =\n options.notFound ??\n ((context: ServerContext) => {\n return context.text('Not Found', { status: 404 });\n });\n\n const onError =\n options.onError ??\n ((error: unknown, context: ServerContext) => {\n if (error instanceof Response) {\n return error;\n }\n return context.text('Internal Server Error', { status: 500 });\n });\n\n const addRoute = (\n method: string | string[] | undefined,\n path: string,\n handler: ServerHandler,\n routeMiddlewares?: ServerMiddleware[]\n ): ServerApp => {\n routes.push(\n compileRoute({\n handler,\n method,\n middlewares: routeMiddlewares,\n path,\n })\n );\n return app;\n };\n\n const addWebSocketRoute = (\n path: string,\n handler: ServerWebSocketRouteHandler<unknown>,\n routeMiddlewares?: ServerWebSocketMiddleware[]\n ): ServerApp => {\n const compiledPath = compileRoutePath(path);\n webSocketRoutes.push({\n handler,\n methods: new Set(['GET']),\n middlewares: routeMiddlewares ?? [],\n paramNames: compiledPath.paramNames,\n path: compiledPath.path,\n pattern: compiledPath.pattern,\n });\n return app;\n };\n\n const app: ServerApp = {\n use(middleware) {\n middlewares.push(middleware);\n return app;\n },\n\n add(route) {\n routes.push(compileRoute(route));\n return app;\n },\n\n get(path, handler, routeMiddlewares) {\n return addRoute('GET', path, handler, routeMiddlewares);\n },\n\n post(path, handler, routeMiddlewares) {\n return addRoute('POST', path, handler, routeMiddlewares);\n },\n\n put(path, handler, routeMiddlewares) {\n return addRoute('PUT', path, handler, routeMiddlewares);\n },\n\n patch(path, handler, routeMiddlewares) {\n return addRoute('PATCH', path, handler, routeMiddlewares);\n },\n\n delete(path, handler, routeMiddlewares) {\n return addRoute('DELETE', path, handler, routeMiddlewares);\n },\n\n all(path, handler, routeMiddlewares) {\n return addRoute(undefined, path, handler, routeMiddlewares);\n },\n\n ws(path, handler, routeMiddlewares) {\n return addWebSocketRoute(path, handler as ServerWebSocketRouteHandler<unknown>, routeMiddlewares);\n },\n\n async handle(input) {\n const request = normalizeRequest(input, baseUrl);\n const url = new URL(request.url);\n const method = request.method.toUpperCase();\n const path = normalizePath(url.pathname || '/');\n const query = parseQuery(url);\n\n const context: ServerContext = {\n request,\n url,\n method,\n path,\n params: createDictionary<string>(),\n query,\n state: {},\n response,\n text,\n html,\n json,\n redirect,\n render,\n isWebSocketRequest: isWebSocketRequest(request),\n };\n\n try {\n const route = resolveMatchingRoute(routes, method, path, context);\n\n if (!route) {\n return await notFound(context);\n }\n\n const stack: PipelineHandler[] = [\n ...middlewares,\n ...route.middlewares,\n async (ctx) => await route.handler(ctx),\n ];\n\n const result = await runPipeline(context, stack, async () => {\n return await notFound(context);\n });\n return result;\n } catch (error) {\n return await onError(error, context);\n }\n },\n\n async handleWebSocket(input) {\n const request = normalizeRequest(input, baseUrl);\n const url = new URL(request.url);\n const method = request.method.toUpperCase();\n const path = normalizePath(url.pathname || '/');\n const query = parseQuery(url);\n\n const context: ServerContext = {\n request,\n url,\n method,\n path,\n params: createDictionary<string>(),\n query,\n state: {},\n response,\n text,\n html,\n json,\n redirect,\n render,\n isWebSocketRequest: isWebSocketRequest(request),\n };\n\n if (!context.isWebSocketRequest) {\n return null;\n }\n\n try {\n const route = resolveMatchingRoute(webSocketRoutes, method, path, context);\n if (!route) {\n return null;\n }\n\n const stack: WebSocketPipelineHandler[] = [\n ...middlewares.map(adaptHttpMiddlewareToWebSocket),\n ...route.middlewares,\n ];\n return await runWebSocketPipeline(context, stack, async () => {\n const handlers =\n typeof route.handler === 'function'\n ? await route.handler(context)\n : route.handler;\n return createWebSocketSession(context, handlers as ServerWebSocketHandlerSet<unknown>);\n });\n } catch (error) {\n return await onError(error, context);\n }\n },\n };\n\n return app;\n};\n"],"mappings":"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"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Runtime adapters for SSR.
|
|
3
|
+
*
|
|
4
|
+
* Provide thin glue functions that turn a bQuery render handler into a
|
|
5
|
+
* runtime-native server callback. They share a common signature so the same
|
|
6
|
+
* application can be served by Bun, Deno, Node and any Web-`fetch` host.
|
|
7
|
+
*
|
|
8
|
+
* @module bquery/ssr
|
|
9
|
+
*/
|
|
10
|
+
import type { SSRContext } from './context';
|
|
11
|
+
/** A handler that turns a request into a Response (Web-fetch style). */
|
|
12
|
+
export type SSRRequestHandler = (request: Request, context?: SSRContext) => Promise<Response> | Response;
|
|
13
|
+
/**
|
|
14
|
+
* Identity adapter for Web-`fetch` style hosts (Hono, Elysia, Workerd, edge
|
|
15
|
+
* runtimes). Exists for symmetry and future logging hooks.
|
|
16
|
+
*/
|
|
17
|
+
export declare const createWebHandler: (handler: SSRRequestHandler) => SSRRequestHandler;
|
|
18
|
+
/**
|
|
19
|
+
* Wraps a handler for `Bun.serve()`. Returns a function with Bun's expected
|
|
20
|
+
* signature `(request, server) => Response | Promise<Response>`.
|
|
21
|
+
*/
|
|
22
|
+
export declare const createBunHandler: (handler: SSRRequestHandler) => ((request: Request) => Promise<Response>);
|
|
23
|
+
/**
|
|
24
|
+
* Wraps a handler for `Deno.serve()`. Returns a function with Deno's expected
|
|
25
|
+
* signature `(request, info?) => Response | Promise<Response>`.
|
|
26
|
+
*/
|
|
27
|
+
export declare const createDenoHandler: (handler: SSRRequestHandler) => ((request: Request) => Promise<Response>);
|
|
28
|
+
/** Minimal subset of `node:http` IncomingMessage we rely on. */
|
|
29
|
+
export interface NodeIncomingMessage {
|
|
30
|
+
url?: string;
|
|
31
|
+
method?: string;
|
|
32
|
+
headers: Record<string, string | string[] | undefined>;
|
|
33
|
+
on(event: 'data', listener: (chunk: Uint8Array | string) => void): void;
|
|
34
|
+
on(event: 'end', listener: () => void): void;
|
|
35
|
+
on(event: 'error', listener: (err: unknown) => void): void;
|
|
36
|
+
destroy?(error?: Error): void;
|
|
37
|
+
}
|
|
38
|
+
/** Minimal subset of `node:http` ServerResponse we rely on. */
|
|
39
|
+
export interface NodeServerResponse {
|
|
40
|
+
statusCode: number;
|
|
41
|
+
setHeader(name: string, value: string | number | readonly string[]): void;
|
|
42
|
+
write(chunk: Uint8Array | string): boolean;
|
|
43
|
+
end(chunk?: Uint8Array | string): void;
|
|
44
|
+
once?(event: 'drain' | 'error', listener: (error?: unknown) => void): void;
|
|
45
|
+
on?(event: 'drain' | 'error', listener: (error?: unknown) => void): void;
|
|
46
|
+
}
|
|
47
|
+
/** Optional hardening settings for the `node:http` adapter. */
|
|
48
|
+
export interface NodeHandlerOptions {
|
|
49
|
+
/** Reject request bodies that exceed this many bytes. Default: unlimited. */
|
|
50
|
+
maxBodyBytes?: number;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Wraps a handler so it can be passed directly to a `node:http` server.
|
|
54
|
+
*
|
|
55
|
+
* @example
|
|
56
|
+
* ```ts
|
|
57
|
+
* import { createServer } from 'node:http';
|
|
58
|
+
* import { createNodeHandler, renderToResponse } from '@bquery/bquery/ssr';
|
|
59
|
+
*
|
|
60
|
+
* const handler = createNodeHandler(async (request) => {
|
|
61
|
+
* return renderToResponse('<div bq-text="msg"></div>', { msg: 'Hello' });
|
|
62
|
+
* });
|
|
63
|
+
*
|
|
64
|
+
* createServer(handler).listen(3000);
|
|
65
|
+
* ```
|
|
66
|
+
*/
|
|
67
|
+
export declare const createNodeHandler: (handler: SSRRequestHandler, options?: NodeHandlerOptions) => ((req: NodeIncomingMessage, res: NodeServerResponse) => Promise<void>);
|
|
68
|
+
/**
|
|
69
|
+
* Convenience helper that picks the right adapter based on the current
|
|
70
|
+
* runtime. Returns the same handler unchanged for Web/Bun/Deno (they share a
|
|
71
|
+
* fetch-style signature). On Node it returns the `node:http` adapter.
|
|
72
|
+
*/
|
|
73
|
+
export declare const createSSRHandler: (handler: SSRRequestHandler) => SSRRequestHandler | ((req: NodeIncomingMessage, res: NodeServerResponse) => Promise<void>);
|
|
74
|
+
//# sourceMappingURL=adapters.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adapters.d.ts","sourceRoot":"","sources":["../../src/ssr/adapters.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAG5C,wEAAwE;AACxE,MAAM,MAAM,iBAAiB,GAAG,CAC9B,OAAO,EAAE,OAAO,EAChB,OAAO,CAAC,EAAE,UAAU,KACjB,OAAO,CAAC,QAAQ,CAAC,GAAG,QAAQ,CAAC;AAMlC;;;GAGG;AACH,eAAO,MAAM,gBAAgB,GAAI,SAAS,iBAAiB,KAAG,iBAA4B,CAAC;AAM3F;;;GAGG;AACH,eAAO,MAAM,gBAAgB,GAC3B,SAAS,iBAAiB,KACzB,CAAC,CAAC,OAAO,EAAE,OAAO,KAAK,OAAO,CAAC,QAAQ,CAAC,CAE1C,CAAC;AAMF;;;GAGG;AACH,eAAO,MAAM,iBAAiB,GAC5B,SAAS,iBAAiB,KACzB,CAAC,CAAC,OAAO,EAAE,OAAO,KAAK,OAAO,CAAC,QAAQ,CAAC,CAE1C,CAAC;AAMF,gEAAgE;AAChE,MAAM,WAAW,mBAAmB;IAClC,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,SAAS,CAAC,CAAC;IACvD,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,KAAK,EAAE,UAAU,GAAG,MAAM,KAAK,IAAI,GAAG,IAAI,CAAC;IACxE,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,IAAI,GAAG,IAAI,CAAC;IAC7C,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK,IAAI,GAAG,IAAI,CAAC;IAC3D,OAAO,CAAC,CAAC,KAAK,CAAC,EAAE,KAAK,GAAG,IAAI,CAAC;CAC/B;AAED,+DAA+D;AAC/D,MAAM,WAAW,kBAAkB;IACjC,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,MAAM,EAAE,GAAG,IAAI,CAAC;IAC1E,KAAK,CAAC,KAAK,EAAE,UAAU,GAAG,MAAM,GAAG,OAAO,CAAC;IAC3C,GAAG,CAAC,KAAK,CAAC,EAAE,UAAU,GAAG,MAAM,GAAG,IAAI,CAAC;IACvC,IAAI,CAAC,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,EAAE,QAAQ,EAAE,CAAC,KAAK,CAAC,EAAE,OAAO,KAAK,IAAI,GAAG,IAAI,CAAC;IAC3E,EAAE,CAAC,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,EAAE,QAAQ,EAAE,CAAC,KAAK,CAAC,EAAE,OAAO,KAAK,IAAI,GAAG,IAAI,CAAC;CAC1E;AAED,+DAA+D;AAC/D,MAAM,WAAW,kBAAkB;IACjC,6EAA6E;IAC7E,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAyLD;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,iBAAiB,GAC5B,SAAS,iBAAiB,EAC1B,UAAS,kBAAuB,KAC/B,CAAC,CAAC,GAAG,EAAE,mBAAmB,EAAE,GAAG,EAAE,kBAAkB,KAAK,OAAO,CAAC,IAAI,CAAC,CAevE,CAAC;AAMF;;;;GAIG;AACH,eAAO,MAAM,gBAAgB,GAC3B,SAAS,iBAAiB,KACzB,iBAAiB,GAAG,CAAC,CAAC,GAAG,EAAE,mBAAmB,EAAE,GAAG,EAAE,kBAAkB,KAAK,OAAO,CAAC,IAAI,CAAC,CAY3F,CAAC"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Async data helpers for SSR.
|
|
3
|
+
*
|
|
4
|
+
* These tiny utilities let `renderToStringAsync()`/`renderToStream()` await
|
|
5
|
+
* `Promise`-shaped values inside the binding context before the templates are
|
|
6
|
+
* evaluated, without coupling the synchronous renderer to async semantics.
|
|
7
|
+
*
|
|
8
|
+
* @module bquery/ssr
|
|
9
|
+
*/
|
|
10
|
+
import type { BindingContext } from '../view/types';
|
|
11
|
+
import type { SSRContext } from './context';
|
|
12
|
+
/** A loader function executed before render. */
|
|
13
|
+
export type SSRLoader<T = unknown> = (ctx: SSRContext) => T | Promise<T>;
|
|
14
|
+
/**
|
|
15
|
+
* Wraps a loader so it can be invoked or stored uniformly. The wrapper is
|
|
16
|
+
* tagged with the internal defer brand so `resolveContext()` recognises it
|
|
17
|
+
* and calls the loader with the active `SSRContext`.
|
|
18
|
+
*/
|
|
19
|
+
export declare const defineLoader: <T>(loader: SSRLoader<T>) => SSRLoader<T>;
|
|
20
|
+
interface DeferredValue<T> {
|
|
21
|
+
promise: Promise<T>;
|
|
22
|
+
fallback?: unknown;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Marks a promise as "may resolve in parallel". When `renderToStringAsync()`
|
|
26
|
+
* sees a deferred value in the context, it awaits the underlying promise.
|
|
27
|
+
* Streaming renderers can flush a fallback first and patch the resolved value
|
|
28
|
+
* later (see `renderToStreamSuspense()`).
|
|
29
|
+
*/
|
|
30
|
+
export declare const defer: <T>(promise: Promise<T> | T, fallback?: unknown) => DeferredValue<T>;
|
|
31
|
+
/**
|
|
32
|
+
* Walks the binding context, awaits all promises and deferred values, and
|
|
33
|
+
* returns a new context with the resolved values. Signals/computeds are kept
|
|
34
|
+
* as-is so the renderer can still unwrap them lazily.
|
|
35
|
+
*
|
|
36
|
+
* @internal
|
|
37
|
+
*/
|
|
38
|
+
export declare const resolveContext: (context: BindingContext, ctx: SSRContext) => Promise<BindingContext>;
|
|
39
|
+
export {};
|
|
40
|
+
//# sourceMappingURL=async.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"async.d.ts","sourceRoot":"","sources":["../../src/ssr/async.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAEpD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAG5C,gDAAgD;AAChD,MAAM,MAAM,SAAS,CAAC,CAAC,GAAG,OAAO,IAAI,CAAC,GAAG,EAAE,UAAU,KAAK,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;AAEzE;;;;GAIG;AACH,eAAO,MAAM,YAAY,GAAI,CAAC,EAAE,QAAQ,SAAS,CAAC,CAAC,CAAC,KAAG,SAAS,CAAC,CAAC,CAOjE,CAAC;AAEF,UAAU,aAAa,CAAC,CAAC;IAEvB,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC;IACpB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED;;;;;GAKG;AACH,eAAO,MAAM,KAAK,GAAI,CAAC,EAAE,SAAS,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,WAAW,OAAO,KAAG,aAAa,CAAC,CAAC,CAOrF,CAAC;AAOF;;;;;;GAMG;AACH,eAAO,MAAM,cAAc,GACzB,SAAS,cAAc,EACvB,KAAK,UAAU,KACd,OAAO,CAAC,cAAc,CAuDxB,CAAC"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Global SSR configuration.
|
|
3
|
+
*
|
|
4
|
+
* Lets users opt into a custom DOM implementation (`linkedom`, `happy-dom`,
|
|
5
|
+
* `jsdom`, …) for the legacy `DOMParser`-based renderer, or force the
|
|
6
|
+
* DOM-free renderer everywhere. Defaults are runtime-aware: if a global
|
|
7
|
+
* `DOMParser` exists, it is used (preserves legacy behaviour); otherwise the
|
|
8
|
+
* DOM-free renderer kicks in automatically.
|
|
9
|
+
*
|
|
10
|
+
* @module bquery/ssr
|
|
11
|
+
*/
|
|
12
|
+
/**
|
|
13
|
+
* Backend used by `renderToString()` and `renderToStringAsync()`.
|
|
14
|
+
*/
|
|
15
|
+
export type SSRRendererBackend = 'auto' | 'pure' | 'dom';
|
|
16
|
+
/**
|
|
17
|
+
* DOM implementation injected by `configureSSR()` for the `'dom'` backend.
|
|
18
|
+
*/
|
|
19
|
+
export interface SSRDocumentImpl {
|
|
20
|
+
/** A `DOMParser` constructor compatible with the WHATWG spec. */
|
|
21
|
+
DOMParser: typeof globalThis.DOMParser;
|
|
22
|
+
}
|
|
23
|
+
interface SSRConfig {
|
|
24
|
+
backend: SSRRendererBackend;
|
|
25
|
+
documentImpl: SSRDocumentImpl | null;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Updates the global SSR configuration. All options are optional and merged
|
|
29
|
+
* shallowly with the existing configuration.
|
|
30
|
+
*
|
|
31
|
+
* @example
|
|
32
|
+
* ```ts
|
|
33
|
+
* import { configureSSR } from '@bquery/bquery/ssr';
|
|
34
|
+
* import { DOMParser } from 'linkedom';
|
|
35
|
+
*
|
|
36
|
+
* configureSSR({ backend: 'dom', documentImpl: { DOMParser } });
|
|
37
|
+
* ```
|
|
38
|
+
*/
|
|
39
|
+
export declare const configureSSR: (options: Partial<{
|
|
40
|
+
backend: SSRRendererBackend;
|
|
41
|
+
documentImpl: SSRDocumentImpl | null;
|
|
42
|
+
}>) => void;
|
|
43
|
+
/**
|
|
44
|
+
* Returns a snapshot of the current SSR configuration.
|
|
45
|
+
*/
|
|
46
|
+
export declare const getSSRConfig: () => Readonly<SSRConfig>;
|
|
47
|
+
/**
|
|
48
|
+
* Resolves the renderer backend that should actually be used right now.
|
|
49
|
+
* Honours `configureSSR()` and falls back to runtime feature detection.
|
|
50
|
+
*
|
|
51
|
+
* @internal
|
|
52
|
+
*/
|
|
53
|
+
export declare const resolveBackend: () => "pure" | "dom";
|
|
54
|
+
/**
|
|
55
|
+
* Returns the configured `DOMParser` constructor or the global one.
|
|
56
|
+
* @internal
|
|
57
|
+
*/
|
|
58
|
+
export declare const getDOMParserImpl: () => typeof globalThis.DOMParser | null;
|
|
59
|
+
export {};
|
|
60
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/ssr/config.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH;;GAEG;AACH,MAAM,MAAM,kBAAkB,GAAG,MAAM,GAAG,MAAM,GAAG,KAAK,CAAC;AAEzD;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,iEAAiE;IACjE,SAAS,EAAE,OAAO,UAAU,CAAC,SAAS,CAAC;CACxC;AAED,UAAU,SAAS;IACjB,OAAO,EAAE,kBAAkB,CAAC;IAC5B,YAAY,EAAE,eAAe,GAAG,IAAI,CAAC;CACtC;AAOD;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,YAAY,GACvB,SAAS,OAAO,CAAC;IAAE,OAAO,EAAE,kBAAkB,CAAC;IAAC,YAAY,EAAE,eAAe,GAAG,IAAI,CAAA;CAAE,CAAC,KACtF,IAGF,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,YAAY,QAAO,QAAQ,CAAC,SAAS,CAGhD,CAAC;AAEH;;;;;GAKG;AACH,eAAO,MAAM,cAAc,QAAO,MAAM,GAAG,KAO1C,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,gBAAgB,QAAO,OAAO,UAAU,CAAC,SAAS,GAAG,IAIjE,CAAC"}
|