@mauroandre/velojs 0.0.51 → 0.0.53

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.
@@ -1,651 +1,697 @@
1
1
  import { getRegisteredStreams as D } from "../events.js";
2
- import { trackSocketSession as U, getAppSockets as q, abortAllSocketSessions as V } from "../sockets.js";
3
- import { createIsolatedContext as B, withAppContext as W } from "../app-context.js";
4
- function R(e) {
2
+ import { trackSocketSession as U, getAppSockets as $, injectWebSocketServer as V, abortAllSocketSessions as L } from "../sockets.js";
3
+ import { createIsolatedContext as W, withAppContext as B } from "../app-context.js";
4
+ function P(e) {
5
5
  if (!e) return;
6
- const s = Object.entries(e);
7
- if (s.length !== 0)
8
- return s.map(([n, u]) => `${encodeURIComponent(n)}=${encodeURIComponent(u)}`).join("; ");
6
+ const n = Object.entries(e);
7
+ if (n.length !== 0)
8
+ return n.map(([t, c]) => `${encodeURIComponent(t)}=${encodeURIComponent(c)}`).join("; ");
9
9
  }
10
- function L(e) {
11
- const s = {}, n = e.getSetCookie?.() ?? [];
12
- for (const u of n) {
13
- const l = u.indexOf(";"), a = l === -1 ? u : u.slice(0, l), p = a.indexOf("=");
14
- if (p === -1) continue;
15
- const c = a.slice(0, p).trim(), t = a.slice(p + 1).trim();
16
- c && (s[c] = decodeURIComponent(t));
10
+ function F(e) {
11
+ const n = {}, t = e.getSetCookie?.() ?? [];
12
+ for (const c of t) {
13
+ const u = c.indexOf(";"), l = u === -1 ? c : c.slice(0, u), f = l.indexOf("=");
14
+ if (f === -1) continue;
15
+ const h = l.slice(0, f).trim(), r = l.slice(f + 1).trim();
16
+ h && (n[h] = decodeURIComponent(r));
17
17
  }
18
- return s;
18
+ return n;
19
19
  }
20
- function N(e) {
20
+ function I(e) {
21
21
  if (!e) return "";
22
- const s = new URLSearchParams();
23
- for (const [u, l] of Object.entries(e))
24
- if (Array.isArray(l))
25
- for (const a of l) s.append(u, a);
22
+ const n = new URLSearchParams();
23
+ for (const [c, u] of Object.entries(e))
24
+ if (Array.isArray(u))
25
+ for (const l of u) n.append(c, l);
26
26
  else
27
- s.set(u, l);
28
- const n = s.toString();
29
- return n ? `?${n}` : "";
27
+ n.set(c, u);
28
+ const t = n.toString();
29
+ return t ? `?${t}` : "";
30
30
  }
31
31
  function z(e) {
32
- const s = {};
33
- return e.forEach((n, u) => {
34
- s[u] = n;
35
- }), s;
32
+ const n = {};
33
+ return e.forEach((t, c) => {
34
+ n[c] = t;
35
+ }), n;
36
36
  }
37
- function F(e) {
37
+ function G(e) {
38
38
  return e == null ? { body: null, contentType: null } : typeof e == "string" || e instanceof FormData || e instanceof URLSearchParams || e instanceof Blob || e instanceof ArrayBuffer || ArrayBuffer.isView(e) ? { body: e, contentType: null } : {
39
39
  body: JSON.stringify(e),
40
40
  contentType: "application/json"
41
41
  };
42
42
  }
43
- const $ = "http://velojs.test";
44
- function I(e, s) {
45
- const n = N(s);
46
- return e.startsWith("http://") || e.startsWith("https://") ? e + n : (e.startsWith("/") || (e = "/" + e), $ + e + n);
43
+ const N = "http://velojs.test";
44
+ function q(e, n) {
45
+ const t = I(n);
46
+ return e.startsWith("http://") || e.startsWith("https://") ? e + t : (e.startsWith("/") || (e = "/" + e), N + e + t);
47
47
  }
48
48
  function J(e = {}) {
49
- const { user: s, params: n = {}, query: u = {}, body: l, headers: a = {}, cookies: p } = e, c = R(p), t = new Headers(a);
50
- c && !t.has("cookie") && t.set("cookie", c);
51
- const r = $ + "/_mock" + N(u), f = {
52
- method: l == null ? "GET" : "POST",
53
- headers: t
49
+ const { user: n, params: t = {}, query: c = {}, body: u, headers: l = {}, cookies: f } = e, h = P(f), r = new Headers(l);
50
+ h && !r.has("cookie") && r.set("cookie", h);
51
+ const o = N + "/_mock" + I(c), i = {
52
+ method: u == null ? "GET" : "POST",
53
+ headers: r
54
54
  };
55
- l != null && (typeof l == "string" || l instanceof FormData || l instanceof Blob ? f.body = l : (f.body = JSON.stringify(l), t.has("content-type") || t.set("content-type", "application/json")));
56
- const d = new Request(r, f), w = /* @__PURE__ */ new Map();
57
- return s !== void 0 && w.set("user", s), {
55
+ u != null && (typeof u == "string" || u instanceof FormData || u instanceof Blob ? i.body = u : (i.body = JSON.stringify(u), r.has("content-type") || r.set("content-type", "application/json")));
56
+ const w = new Request(o, i), d = /* @__PURE__ */ new Map();
57
+ return n !== void 0 && d.set("user", n), {
58
58
  req: {
59
- raw: d,
60
- url: d.url,
61
- method: d.method,
62
- param(o) {
63
- return o === void 0 ? n : n[o];
59
+ raw: w,
60
+ url: w.url,
61
+ method: w.method,
62
+ param(s) {
63
+ return s === void 0 ? t : t[s];
64
64
  },
65
- query(o) {
66
- if (o === void 0) {
67
- const i = {};
68
- for (const [m, v] of Object.entries(u))
69
- i[m] = String(v);
70
- return i;
65
+ query(s) {
66
+ if (s === void 0) {
67
+ const a = {};
68
+ for (const [y, v] of Object.entries(c))
69
+ a[y] = String(v);
70
+ return a;
71
71
  }
72
- return u[o];
72
+ return c[s];
73
73
  },
74
- queries(o) {
75
- const i = u[o];
76
- if (i !== void 0)
77
- return Array.isArray(i) ? i : [i];
74
+ queries(s) {
75
+ const a = c[s];
76
+ if (a !== void 0)
77
+ return Array.isArray(a) ? a : [a];
78
78
  },
79
- header(o) {
80
- if (o === void 0) {
81
- const i = {};
82
- return t.forEach((m, v) => {
83
- i[v] = m;
84
- }), i;
79
+ header(s) {
80
+ if (s === void 0) {
81
+ const a = {};
82
+ return r.forEach((y, v) => {
83
+ a[v] = y;
84
+ }), a;
85
85
  }
86
- return t.get(o) ?? void 0;
86
+ return r.get(s) ?? void 0;
87
87
  },
88
88
  async json() {
89
- return l == null ? null : typeof l == "object" ? l : JSON.parse(String(l));
89
+ return u == null ? null : typeof u == "object" ? u : JSON.parse(String(u));
90
90
  },
91
91
  async text() {
92
- return l == null ? "" : typeof l == "string" ? l : JSON.stringify(l);
92
+ return u == null ? "" : typeof u == "string" ? u : JSON.stringify(u);
93
93
  },
94
94
  async parseBody() {
95
- return l ?? {};
95
+ return u ?? {};
96
96
  },
97
97
  path: "/_mock"
98
98
  },
99
99
  res: void 0,
100
100
  env: {},
101
101
  finalized: !1,
102
- get(o) {
103
- return w.get(o);
102
+ get(s) {
103
+ return d.get(s);
104
104
  },
105
- set(o, i) {
106
- w.set(o, i);
105
+ set(s, a) {
106
+ d.set(s, a);
107
107
  },
108
108
  var: new Proxy({}, {
109
- get(o, i) {
110
- return w.get(i);
109
+ get(s, a) {
110
+ return d.get(a);
111
111
  }
112
112
  }),
113
- json(o, i = 200) {
114
- return new Response(JSON.stringify(o), {
115
- status: i,
113
+ json(s, a = 200) {
114
+ return new Response(JSON.stringify(s), {
115
+ status: a,
116
116
  headers: { "content-type": "application/json" }
117
117
  });
118
118
  },
119
- text(o, i = 200) {
120
- return new Response(o, { status: i });
119
+ text(s, a = 200) {
120
+ return new Response(s, { status: a });
121
121
  },
122
- html(o, i = 200) {
123
- return new Response(o, {
124
- status: i,
122
+ html(s, a = 200) {
123
+ return new Response(s, {
124
+ status: a,
125
125
  headers: { "content-type": "text/html; charset=UTF-8" }
126
126
  });
127
127
  },
128
- body(o, i = 200) {
129
- return new Response(o, { status: i });
128
+ body(s, a = 200) {
129
+ return new Response(s, { status: a });
130
130
  },
131
- redirect(o, i = 302) {
132
- return new Response(null, { status: i, headers: { location: o } });
131
+ redirect(s, a = 302) {
132
+ return new Response(null, { status: a, headers: { location: s } });
133
133
  },
134
- header(o, i) {
134
+ header(s, a) {
135
135
  },
136
- status(o) {
136
+ status(s) {
137
137
  }
138
138
  };
139
139
  }
140
- function G(e, s) {
141
- if (typeof s == "string") {
142
- const n = q(e).get(s);
143
- if (!n)
140
+ function Q(e, n) {
141
+ if (typeof n == "string") {
142
+ const t = $(e).get(n);
143
+ if (!t)
144
144
  throw new Error(
145
- `[velojs/testing] no socket handler registered at "${s}". Make sure the route exports a socket_* handler and routes are wired.`
145
+ `[velojs/testing] no socket handler registered at "${n}". Make sure the route exports a socket_* handler and routes are wired.`
146
146
  );
147
- return { handler: n.handler, path: s };
147
+ return { handler: t.handler, path: n };
148
148
  }
149
- if (typeof s == "function") {
150
- const n = s.__path;
151
- if (!n)
149
+ if (typeof n == "function") {
150
+ const t = n.__path;
151
+ if (!t)
152
152
  throw new Error(
153
153
  "[velojs/testing] socket handler has no __path. Make sure your vitest.config.ts loads veloPlugin() and your routes are registered."
154
154
  );
155
- return { handler: s, path: n };
155
+ return { handler: n, path: t };
156
156
  }
157
- if (s && typeof s == "object" && typeof s.__path == "string") {
158
- const n = s.__path, u = q(e).get(n);
159
- if (!u)
157
+ if (n && typeof n == "object" && typeof n.__path == "string") {
158
+ const t = n.__path, c = $(e).get(t);
159
+ if (!c)
160
160
  throw new Error(
161
- `[velojs/testing] stub with __path="${n}" has no matching server handler.`
161
+ `[velojs/testing] stub with __path="${t}" has no matching server handler.`
162
162
  );
163
- return { handler: u.handler, path: n };
163
+ return { handler: c.handler, path: t };
164
164
  }
165
165
  throw new Error("[velojs/testing] socket(): unrecognized handler argument");
166
166
  }
167
- async function Q(e, s, n = {}) {
168
- const { handler: u, path: l } = G(e, s), a = {
169
- params: n.params ?? {},
167
+ async function K(e, n, t = {}) {
168
+ const { handler: c, path: u } = Q(e, n), l = {
169
+ params: t.params ?? {},
170
170
  query: {
171
- ...n.query,
172
- ...n.channel ? { channel: n.channel } : {}
171
+ ...t.query,
172
+ ...t.channel ? { channel: t.channel } : {}
173
173
  }
174
174
  };
175
- n.user !== void 0 && (a.user = n.user), n.headers && (a.headers = n.headers), n.cookies && (a.cookies = n.cookies);
176
- const p = J(a), c = [];
177
- let t = null, r = !1;
178
- const f = {
175
+ t.user !== void 0 && (l.user = t.user), t.headers && (l.headers = t.headers), t.cookies && (l.cookies = t.cookies);
176
+ const f = J(l), h = [];
177
+ let r = null, o = !1;
178
+ const i = {
179
179
  async *[Symbol.asyncIterator]() {
180
180
  for (; ; ) {
181
- for (; c.length > 0; )
182
- yield c.shift();
183
- if (r) return;
184
- await new Promise((g) => t = g), t = null;
181
+ for (; h.length > 0; )
182
+ yield h.shift();
183
+ if (o) return;
184
+ await new Promise((p) => r = p), r = null;
185
185
  }
186
186
  }
187
- }, d = (g) => {
188
- r || (c.push(g), t?.());
189
- }, w = () => {
190
- r || (r = !0, t?.());
191
- }, h = [];
192
- let o = [];
193
- const i = (g) => {
194
- h.push(g);
195
- const j = o;
196
- o = [];
197
- for (const S of j)
187
+ }, w = (p) => {
188
+ o || (h.push(p), r?.());
189
+ }, d = () => {
190
+ o || (o = !0, r?.());
191
+ }, g = [];
192
+ let s = [];
193
+ const a = (p) => {
194
+ g.push(p);
195
+ const S = s;
196
+ s = [];
197
+ for (const j of S)
198
198
  try {
199
- S();
199
+ j();
200
200
  } catch {
201
201
  }
202
- }, m = new AbortController(), v = U(e, m);
203
- let k = !1, y = !1;
204
- const b = (g) => {
205
- y || (typeof g == "string" || g instanceof Uint8Array ? i(g) : i(JSON.stringify(g)));
206
- }, C = (g, j) => {
202
+ }, y = new AbortController(), v = U(e, y);
203
+ let k = !1, m = !1;
204
+ const b = (p) => {
205
+ m || (typeof p == "string" || p instanceof Uint8Array ? a(p) : a(JSON.stringify(p)));
206
+ }, C = (p, S) => {
207
207
  T();
208
- }, O = () => {
208
+ }, H = () => {
209
209
  k = !0;
210
210
  }, T = () => {
211
- if (y) return;
212
- if (y = !0, !m.signal.aborted)
211
+ if (m) return;
212
+ if (m = !0, !y.signal.aborted)
213
213
  try {
214
- m.abort();
214
+ y.abort();
215
215
  } catch {
216
216
  }
217
- v(), w();
218
- const g = o;
219
- o = [];
220
- for (const j of g)
217
+ v(), d();
218
+ const p = s;
219
+ s = [];
220
+ for (const S of p)
221
221
  try {
222
- j();
222
+ S();
223
223
  } catch {
224
224
  }
225
- }, H = {
226
- incoming: f,
225
+ }, O = {
226
+ incoming: i,
227
227
  send: b,
228
228
  close: C,
229
- keepOpen: O,
230
- abortSignal: m.signal,
231
- c: p,
232
- params: n.params ?? {},
229
+ keepOpen: H,
230
+ abortSignal: y.signal,
231
+ c: f,
232
+ params: t.params ?? {},
233
233
  query: {
234
- ...n.query ?? {},
235
- ...n.channel ? { channel: n.channel } : {}
234
+ ...t.query ?? {},
235
+ ...t.channel ? { channel: t.channel } : {}
236
236
  }
237
237
  }, A = (async () => {
238
238
  try {
239
- await u(H);
240
- } catch (g) {
241
- console.error("[velojs/testing] socket handler threw:", g);
239
+ await c(O);
240
+ } catch (p) {
241
+ console.error("[velojs/testing] socket handler threw:", p);
242
242
  }
243
243
  k || T();
244
- })(), P = (g) => new Promise((j, S) => {
244
+ })(), R = (p) => new Promise((S, j) => {
245
245
  const x = setTimeout(() => {
246
- o = o.filter((M) => M !== _), S(new Error(`[velojs/testing] socket.next() timed out after ${g}ms`));
247
- }, g), _ = () => {
248
- clearTimeout(x), j();
246
+ s = s.filter((M) => M !== _), j(new Error(`[velojs/testing] socket.next() timed out after ${p}ms`));
247
+ }, p), _ = () => {
248
+ clearTimeout(x), S();
249
249
  };
250
- o.push(_);
250
+ s.push(_);
251
251
  });
252
252
  let E = 0;
253
253
  return {
254
- send(g) {
255
- y || (typeof g == "string" || g instanceof Uint8Array ? d(g) : d(JSON.stringify(g)));
254
+ send(p) {
255
+ m || (typeof p == "string" || p instanceof Uint8Array ? w(p) : w(JSON.stringify(p)));
256
256
  },
257
257
  get messages() {
258
- return h;
258
+ return g;
259
259
  },
260
260
  get closed() {
261
- return y;
261
+ return m;
262
262
  },
263
- async next(g) {
264
- for (; E >= h.length; ) {
265
- if (y)
263
+ async next(p) {
264
+ for (; E >= g.length; ) {
265
+ if (m)
266
266
  throw new Error("[velojs/testing] socket closed before next()");
267
- await P(g.timeoutMs);
267
+ await R(p.timeoutMs);
268
268
  }
269
- return h[E++];
269
+ return g[E++];
270
270
  },
271
- async nextN(g, j) {
272
- const S = Date.now() + j.timeoutMs, x = [];
273
- for (; x.length < g; ) {
274
- if (E < h.length) {
275
- x.push(h[E++]);
271
+ async nextN(p, S) {
272
+ const j = Date.now() + S.timeoutMs, x = [];
273
+ for (; x.length < p; ) {
274
+ if (E < g.length) {
275
+ x.push(g[E++]);
276
276
  continue;
277
277
  }
278
- if (y)
278
+ if (m)
279
279
  throw new Error("[velojs/testing] socket closed before nextN()");
280
- const _ = S - Date.now();
280
+ const _ = j - Date.now();
281
281
  if (_ <= 0)
282
282
  throw new Error(
283
- `[velojs/testing] socket.nextN() timed out after ${j.timeoutMs}ms`
283
+ `[velojs/testing] socket.nextN() timed out after ${S.timeoutMs}ms`
284
284
  );
285
- await P(_);
285
+ await R(_);
286
286
  }
287
287
  return x;
288
288
  },
289
- async close(g, j) {
289
+ async close(p, S) {
290
290
  T(), await Promise.race([
291
291
  A,
292
- new Promise((S) => setTimeout(S, 50))
292
+ new Promise((j) => setTimeout(j, 50))
293
293
  ]);
294
294
  },
295
295
  done: A
296
296
  };
297
297
  }
298
- function K(e) {
299
- const s = /* @__PURE__ */ new Map(), n = /* @__PURE__ */ new Map();
300
- function u(l) {
301
- for (const a of l) {
302
- const p = a.module?.metadata?.moduleId, c = a.module?.metadata?.fullPath;
303
- if (a.module && p) {
304
- for (const r of Object.keys(a.module)) {
305
- if (!r.startsWith("action_")) continue;
306
- const f = a.module[r];
307
- if (typeof f != "function") continue;
308
- const d = r.replace("action_", "");
309
- s.set(f, {
310
- name: d,
311
- fn: f,
312
- moduleId: p,
313
- url: `/_action/${p}/${d}`
298
+ function X(e) {
299
+ const n = /* @__PURE__ */ new Map(), t = /* @__PURE__ */ new Map();
300
+ function c(u) {
301
+ for (const l of u) {
302
+ const f = l.module?.metadata?.moduleId, h = l.module?.metadata?.fullPath;
303
+ if (l.module && f) {
304
+ for (const o of Object.keys(l.module)) {
305
+ if (!o.startsWith("action_")) continue;
306
+ const i = l.module[o];
307
+ if (typeof i != "function") continue;
308
+ const w = o.replace("action_", "");
309
+ n.set(i, {
310
+ name: w,
311
+ fn: i,
312
+ moduleId: f,
313
+ url: `/_action/${f}/${w}`
314
314
  });
315
315
  }
316
- const t = a.module.loader;
317
- if (typeof t == "function" && c) {
318
- const r = n.get(t);
319
- r ? r.paths.push(c) : n.set(t, {
320
- fn: t,
321
- moduleId: p,
322
- paths: [c]
316
+ const r = l.module.loader;
317
+ if (typeof r == "function" && h) {
318
+ const o = t.get(r);
319
+ o ? o.paths.push(h) : t.set(r, {
320
+ fn: r,
321
+ moduleId: f,
322
+ paths: [h]
323
323
  });
324
324
  }
325
325
  }
326
- a.children && u(a.children);
326
+ l.children && c(l.children);
327
327
  }
328
328
  }
329
- return u(e), { actions: s, loaders: n };
329
+ return c(e), { actions: n, loaders: t };
330
330
  }
331
- function X(e, s) {
332
- if (typeof s == "string") return s;
333
- const n = e.actions.get(s);
334
- if (!n)
331
+ function Y(e, n) {
332
+ if (typeof n == "string") return n;
333
+ const t = e.actions.get(n);
334
+ if (!t)
335
335
  throw new Error(
336
336
  `[velojs/testing] action_* function was not found in the route tree.
337
337
  Make sure your Vitest config loads the VeloJS Vite plugin so that metadata is injected. See https://github.com/mauro-andre/velojs#testing`
338
338
  );
339
- return n.url;
339
+ return t.url;
340
340
  }
341
- function Y(e, s, n) {
342
- if (typeof s == "string") return s;
343
- const u = e.loaders.get(s);
344
- if (!u)
341
+ function Z(e, n, t) {
342
+ if (typeof n == "string") return n;
343
+ const c = e.loaders.get(n);
344
+ if (!c)
345
345
  throw new Error(
346
346
  `[velojs/testing] loader function was not found in the route tree.
347
347
  Make sure your Vitest config loads the VeloJS Vite plugin so that metadata is injected.`
348
348
  );
349
- let l = u.paths[0];
350
- if (n)
351
- for (const [a, p] of Object.entries(n))
352
- l = l.replace(`:${a}`, encodeURIComponent(p));
353
- return l;
349
+ let u = c.paths[0];
350
+ if (t)
351
+ for (const [l, f] of Object.entries(t))
352
+ u = u.replace(`:${l}`, encodeURIComponent(f));
353
+ return u;
354
354
  }
355
- class Z {
355
+ class ee {
356
356
  buffer = "";
357
357
  current = {
358
358
  event: "message",
359
359
  data: []
360
360
  };
361
- push(s) {
362
- this.buffer += s;
363
- const n = [];
364
- let u;
365
- for (; (u = this.buffer.indexOf(`
361
+ push(n) {
362
+ this.buffer += n;
363
+ const t = [];
364
+ let c;
365
+ for (; (c = this.buffer.indexOf(`
366
366
  `)) !== -1; ) {
367
- const l = this.buffer.slice(0, u);
368
- if (this.buffer = this.buffer.slice(u + 1), l === "") {
367
+ const u = this.buffer.slice(0, c);
368
+ if (this.buffer = this.buffer.slice(c + 1), u === "") {
369
369
  if (this.current.data.length > 0 || this.current.event !== "message") {
370
- const t = {
370
+ const r = {
371
371
  event: this.current.event,
372
372
  data: this.current.data.join(`
373
373
  `)
374
374
  };
375
- this.current.id !== void 0 && (t.id = this.current.id), n.push(t);
375
+ this.current.id !== void 0 && (r.id = this.current.id), t.push(r);
376
376
  }
377
377
  this.current = { event: "message", data: [] };
378
378
  continue;
379
379
  }
380
- if (l.startsWith(":")) continue;
381
- const a = l.indexOf(":");
382
- if (a === -1) continue;
383
- const p = l.slice(0, a);
384
- let c = l.slice(a + 1);
385
- c.startsWith(" ") && (c = c.slice(1)), p === "event" ? this.current.event = c : p === "data" ? this.current.data.push(c) : p === "id" && (this.current.id = c);
380
+ if (u.startsWith(":")) continue;
381
+ const l = u.indexOf(":");
382
+ if (l === -1) continue;
383
+ const f = u.slice(0, l);
384
+ let h = u.slice(l + 1);
385
+ h.startsWith(" ") && (h = h.slice(1)), f === "event" ? this.current.event = h : f === "data" ? this.current.data.push(h) : f === "id" && (this.current.id = h);
386
386
  }
387
- return n;
387
+ return t;
388
388
  }
389
389
  }
390
- async function ee(e) {
391
- const { response: s } = e, n = s.status, u = [];
392
- let l = null, a = !1, p = null;
393
- const c = [];
394
- let t = null, r = Promise.resolve(void 0);
395
- const f = (h) => {
396
- for (; c.length > 0; ) {
397
- const o = c.shift();
398
- h ? o.reject(h) : o.reject(new Error("[velojs/testing] subscription closed before next event"));
390
+ async function te(e) {
391
+ const { response: n } = e, t = n.status, c = [];
392
+ let u = null, l = !1, f = null;
393
+ const h = [];
394
+ let r = null, o = Promise.resolve(void 0);
395
+ const i = (g) => {
396
+ for (; h.length > 0; ) {
397
+ const s = h.shift();
398
+ g ? s.reject(g) : s.reject(new Error("[velojs/testing] subscription closed before next event"));
399
399
  }
400
400
  };
401
- if (n >= 200 && n < 300 && s.body) {
402
- t = s.body.getReader();
403
- const h = new TextDecoder(), o = new Z();
404
- r = (async () => {
401
+ if (t >= 200 && t < 300 && n.body) {
402
+ r = n.body.getReader();
403
+ const g = new TextDecoder(), s = new ee();
404
+ o = (async () => {
405
405
  try {
406
406
  for (; ; ) {
407
- const { value: i, done: m } = await t.read();
408
- if (m) {
409
- a || (a = !0), f();
407
+ const { value: a, done: y } = await r.read();
408
+ if (y) {
409
+ l || (l = !0), i();
410
410
  return;
411
411
  }
412
- const v = h.decode(i, { stream: !0 }), k = o.push(v);
413
- for (const y of k) {
414
- if (y.event === "snapshot") {
412
+ const v = g.decode(a, { stream: !0 }), k = s.push(v);
413
+ for (const m of k) {
414
+ if (m.event === "snapshot") {
415
415
  try {
416
- l = JSON.parse(y.data);
416
+ u = JSON.parse(m.data);
417
417
  } catch (b) {
418
- p = b;
418
+ f = b;
419
419
  }
420
420
  continue;
421
421
  }
422
- if (y.event === "close") {
423
- a = !0, f(), t.cancel().catch(() => {
422
+ if (m.event === "close") {
423
+ l = !0, i(), r.cancel().catch(() => {
424
424
  });
425
425
  return;
426
426
  }
427
- if (y.event !== "heartbeat")
427
+ if (m.event !== "heartbeat")
428
428
  try {
429
- const b = JSON.parse(y.data);
430
- u.push(b);
431
- const C = c.shift();
429
+ const b = JSON.parse(m.data);
430
+ c.push(b);
431
+ const C = h.shift();
432
432
  C && C.resolve(b);
433
433
  } catch (b) {
434
- p = b;
434
+ f = b;
435
435
  }
436
436
  }
437
437
  }
438
- } catch (i) {
439
- if (i?.name === "AbortError") {
440
- f();
438
+ } catch (a) {
439
+ if (a?.name === "AbortError") {
440
+ i();
441
441
  return;
442
442
  }
443
- f(i);
443
+ i(a);
444
444
  }
445
445
  })();
446
446
  } else
447
- await s.text().catch(() => ""), a = !0;
448
- const d = {
447
+ await n.text().catch(() => ""), l = !0;
448
+ const w = {
449
449
  get status() {
450
- return n;
450
+ return t;
451
451
  },
452
452
  get events() {
453
- return u;
453
+ return c;
454
454
  },
455
455
  get snapshot() {
456
- return l;
456
+ return u;
457
457
  },
458
458
  get closed() {
459
- return a;
459
+ return l;
460
460
  },
461
- async next({ timeoutMs: h }) {
462
- if (p) throw p;
463
- if (u.length > w) {
464
- const o = u[w];
465
- return w++, o;
461
+ async next({ timeoutMs: g }) {
462
+ if (f) throw f;
463
+ if (c.length > d) {
464
+ const s = c[d];
465
+ return d++, s;
466
466
  }
467
- if (a)
467
+ if (l)
468
468
  throw new Error("[velojs/testing] subscription is closed");
469
- return new Promise((o, i) => {
470
- const m = setTimeout(() => {
471
- const y = c.findIndex((b) => b.resolve === v);
472
- y !== -1 && c.splice(y, 1), i(new Error(
473
- `[velojs/testing] timed out after ${h}ms waiting for next event`
469
+ return new Promise((s, a) => {
470
+ const y = setTimeout(() => {
471
+ const m = h.findIndex((b) => b.resolve === v);
472
+ m !== -1 && h.splice(m, 1), a(new Error(
473
+ `[velojs/testing] timed out after ${g}ms waiting for next event`
474
474
  ));
475
- }, h), v = (y) => {
476
- clearTimeout(m), w++, o(y);
477
- }, k = (y) => {
478
- clearTimeout(m), i(y);
475
+ }, g), v = (m) => {
476
+ clearTimeout(y), d++, s(m);
477
+ }, k = (m) => {
478
+ clearTimeout(y), a(m);
479
479
  };
480
- c.push({ resolve: v, reject: k });
480
+ h.push({ resolve: v, reject: k });
481
481
  });
482
482
  },
483
- async nextN(h, { timeoutMs: o }) {
484
- const i = Date.now(), m = [];
485
- for (let v = 0; v < h; v++) {
486
- const k = o - (Date.now() - i);
483
+ async nextN(g, { timeoutMs: s }) {
484
+ const a = Date.now(), y = [];
485
+ for (let v = 0; v < g; v++) {
486
+ const k = s - (Date.now() - a);
487
487
  if (k <= 0)
488
488
  throw new Error(
489
- `[velojs/testing] timed out after ${o}ms waiting for ${h} events (got ${m.length})`
489
+ `[velojs/testing] timed out after ${s}ms waiting for ${g} events (got ${y.length})`
490
490
  );
491
- m.push(await d.next({ timeoutMs: k }));
491
+ y.push(await w.next({ timeoutMs: k }));
492
492
  }
493
- return m;
493
+ return y;
494
494
  },
495
495
  async close() {
496
- if (t)
496
+ if (r)
497
497
  try {
498
- await t.cancel();
498
+ await r.cancel();
499
499
  } catch {
500
500
  }
501
- a = !0, f(), await r.catch(() => {
501
+ l = !0, i(), await o.catch(() => {
502
502
  });
503
503
  }
504
504
  };
505
- let w = 0;
506
- return d;
505
+ let d = 0;
506
+ return w;
507
507
  }
508
- async function ae(e) {
509
- const s = B();
510
- return await W(s, async () => {
508
+ async function fe(e) {
509
+ const n = W();
510
+ return await B(n, async () => {
511
511
  e.bootstrap && await e.bootstrap();
512
- const { createApp: n } = await import("../server.js"), u = await n(e.routes), l = K(e.routes);
513
- return te(u, s, l, e, void 0);
512
+ const { createApp: t } = await import("../server.js"), c = await t(e.routes), u = X(e.routes), l = e.port !== void 0 ? await ne(c, e.port, e.hostname) : void 0;
513
+ return se(c, n, u, e, void 0, l);
514
+ });
515
+ }
516
+ async function ne(e, n, t) {
517
+ const { serve: c } = await import("@hono/node-server"), { flushServerCallbacks: u, clearActiveServer: l } = await import("../server.js"), f = c({
518
+ fetch: e.fetch,
519
+ port: n,
520
+ ...t ? { hostname: t } : {}
521
+ }), h = /* @__PURE__ */ new Set();
522
+ f.on("connection", (d) => {
523
+ h.add(d), d.on("close", () => h.delete(d));
524
+ }), await oe(f, n, t), await V(e, f), u(f);
525
+ const r = f.address(), o = r && typeof r == "object" ? r.port : n, i = t && t !== "0.0.0.0" && t !== "::" ? t : "localhost";
526
+ let w = !1;
527
+ return {
528
+ port: o,
529
+ url: `http://${i}:${o}`,
530
+ async close() {
531
+ if (w) return;
532
+ w = !0;
533
+ const d = new Promise((g) => {
534
+ f.close(() => g());
535
+ });
536
+ for (const g of h) g.destroy();
537
+ h.clear(), f.closeAllConnections(), await d, l(f);
538
+ }
539
+ };
540
+ }
541
+ function oe(e, n, t) {
542
+ return e.listening ? Promise.resolve() : new Promise((c, u) => {
543
+ const l = `${t ?? "0.0.0.0"}:${n}`, f = () => {
544
+ e.off("listening", h), e.off("error", r);
545
+ }, h = () => {
546
+ f(), c();
547
+ }, r = (o) => {
548
+ f();
549
+ const i = o.code ? `${o.code}: ${o.message}` : o.message;
550
+ u(new Error(
551
+ `[velojs/testing] could not bind the test server on ${l} — ${i}`
552
+ ));
553
+ };
554
+ e.once("listening", h), e.once("error", r);
514
555
  });
515
556
  }
516
- function te(e, s, n, u, l) {
517
- async function a(t, r, f = {}) {
518
- const d = I(r, f.query), w = new Headers(f.headers ?? {}), h = { ...f.cookies ?? {} }, o = R(h);
519
- o && w.set("cookie", o);
520
- let i = null;
521
- if (f.body !== void 0) {
522
- const y = F(f.body);
523
- i = y.body, y.contentType && !w.has("content-type") && w.set("content-type", y.contentType);
557
+ function se(e, n, t, c, u, l) {
558
+ async function f(o, i, w = {}) {
559
+ const d = q(i, w.query), g = new Headers(w.headers ?? {}), s = { ...w.cookies ?? {} }, a = P(s);
560
+ a && g.set("cookie", a);
561
+ let y = null;
562
+ if (w.body !== void 0) {
563
+ const b = G(w.body);
564
+ y = b.body, b.contentType && !g.has("content-type") && g.set("content-type", b.contentType);
524
565
  }
525
- const m = { method: t, headers: w };
526
- i !== null && (m.body = i);
527
- const v = new Request(d, m), k = await e.fetch(v);
528
- return await ne(k);
566
+ const v = { method: o, headers: g };
567
+ y !== null && (v.body = y);
568
+ const k = new Request(d, v), m = await e.fetch(k);
569
+ return await re(m);
529
570
  }
530
- async function p(t, r, f = {}) {
531
- const d = I(r, {
532
- ...f.query ?? {},
533
- ...f.channel ? { channel: f.channel } : {}
534
- }), w = new Headers(f.headers ?? {}), h = { ...f.cookies ?? {} }, o = R(h);
535
- o && w.set("cookie", o);
536
- const i = new Request(d, { method: t, headers: w });
537
- return await e.fetch(i);
571
+ async function h(o, i, w = {}) {
572
+ const d = q(i, {
573
+ ...w.query ?? {},
574
+ ...w.channel ? { channel: w.channel } : {}
575
+ }), g = new Headers(w.headers ?? {}), s = { ...w.cookies ?? {} }, a = P(s);
576
+ a && g.set("cookie", a);
577
+ const y = new Request(d, { method: o, headers: g });
578
+ return await e.fetch(y);
538
579
  }
539
- const c = {
580
+ const r = {
540
581
  hono: e,
582
+ // `undefined` unless `port` was passed — no listener, no behavior change.
583
+ port: l?.port,
584
+ url: l?.url,
541
585
  // HTTP
542
- get: (t, r) => a("GET", t, r ?? {}),
543
- post: (t, r) => a("POST", t, r ?? {}),
544
- put: (t, r) => a("PUT", t, r ?? {}),
545
- patch: (t, r) => a("PATCH", t, r ?? {}),
546
- delete: (t, r) => a("DELETE", t, r ?? {}),
547
- async action(t, r = {}) {
548
- const f = X(n, t);
549
- return await a("POST", f, {
550
- ...r,
551
- body: r.body ?? {}
586
+ get: (o, i) => f("GET", o, i ?? {}),
587
+ post: (o, i) => f("POST", o, i ?? {}),
588
+ put: (o, i) => f("PUT", o, i ?? {}),
589
+ patch: (o, i) => f("PATCH", o, i ?? {}),
590
+ delete: (o, i) => f("DELETE", o, i ?? {}),
591
+ async action(o, i = {}) {
592
+ const w = Y(t, o);
593
+ return await f("POST", w, {
594
+ ...i,
595
+ body: i.body ?? {}
552
596
  });
553
597
  },
554
- async loader(t, r = {}) {
555
- const f = Y(n, t, r.params), d = await a("GET", f, {
556
- ...r,
557
- query: { ...r.query ?? {}, _data: "1" }
598
+ async loader(o, i = {}) {
599
+ const w = Z(t, o, i.params), d = await f("GET", w, {
600
+ ...i,
601
+ query: { ...i.query ?? {}, _data: "1" }
558
602
  });
559
603
  if (d.status >= 300 && d.status < 400 || d.status >= 400) return d;
560
- const w = typeof t == "function" ? n.loaders.get(t)?.moduleId : void 0, h = await d.json();
561
- return w && h && typeof h == "object" && w in h ? h[w] : h;
604
+ const g = typeof o == "function" ? t.loaders.get(o)?.moduleId : void 0, s = await d.json();
605
+ return g && s && typeof s == "object" && g in s ? s[g] : s;
562
606
  },
563
- async subscribe(t, r = {}) {
564
- const f = typeof t == "string" ? t : t.__path ?? se(), d = await p("GET", f, r);
565
- return await ee({ response: d });
607
+ async subscribe(o, i = {}) {
608
+ const w = typeof o == "string" ? o : o.__path ?? ie(), d = await h("GET", w, i);
609
+ return await te({ response: d });
566
610
  },
567
- async socket(t, r = {}) {
568
- return await Q(e, t, r);
611
+ async socket(o, i = {}) {
612
+ return await K(e, o, i);
569
613
  },
570
- async sessionCookies({ user: t }) {
571
- if (!u.getSessionCookie)
614
+ async sessionCookies({ user: o }) {
615
+ if (!c.getSessionCookie)
572
616
  throw new Error(
573
617
  "[velojs/testing] sessionCookies/as requires `getSessionCookie` in createTestApp options."
574
618
  );
575
- return await u.getSessionCookie({ user: t });
619
+ return await c.getSessionCookie({ user: o });
576
620
  },
577
- as({ user: t }) {
578
- if (!u.getSessionCookie)
621
+ as({ user: o }) {
622
+ if (!c.getSessionCookie)
579
623
  throw new Error(
580
624
  "[velojs/testing] app.as() requires `getSessionCookie` in createTestApp options."
581
625
  );
582
- let r = null;
583
- const f = () => (r || (r = Promise.resolve(u.getSessionCookie({ user: t }))), r), d = (h) => (async (...o) => {
584
- const i = await f(), [m, v] = o, k = {
585
- ...v ?? {},
586
- cookies: { ...i, ...v?.cookies ?? {} }
626
+ let i = null;
627
+ const w = () => (i || (i = Promise.resolve(c.getSessionCookie({ user: o }))), i), d = (s) => (async (...a) => {
628
+ const y = await w(), [v, k] = a, m = {
629
+ ...k ?? {},
630
+ cookies: { ...y, ...k?.cookies ?? {} }
587
631
  };
588
- return await h.call(c, m, k);
632
+ return await s.call(r, v, m);
589
633
  });
590
634
  return {
591
635
  hono: e,
592
- get: d(c.get),
593
- post: d(c.post),
594
- put: d(c.put),
595
- patch: d(c.patch),
596
- delete: d(c.delete),
597
- action: d(c.action),
598
- loader: d(c.loader),
599
- subscribe: d(c.subscribe),
600
- socket: d(c.socket),
601
- sessionCookies: c.sessionCookies,
602
- as: c.as,
636
+ port: r.port,
637
+ url: r.url,
638
+ get: d(r.get),
639
+ post: d(r.post),
640
+ put: d(r.put),
641
+ patch: d(r.patch),
642
+ delete: d(r.delete),
643
+ action: d(r.action),
644
+ loader: d(r.loader),
645
+ subscribe: d(r.subscribe),
646
+ socket: d(r.socket),
647
+ sessionCookies: r.sessionCookies,
648
+ as: r.as,
603
649
  // chaining .as.as works — last wins
604
- mockContext: c.mockContext,
605
- reset: c.reset,
606
- close: c.close
650
+ mockContext: r.mockContext,
651
+ reset: r.reset,
652
+ close: r.close
607
653
  };
608
654
  },
609
- mockContext(t = {}) {
610
- return J(t);
655
+ mockContext(o = {}) {
656
+ return J(o);
611
657
  },
612
658
  async reset() {
613
- for (const t of D())
659
+ for (const o of D())
614
660
  try {
615
- t.__reset();
616
- } catch (r) {
617
- console.error("[velojs/testing] stream.__reset failed:", r);
661
+ o.__reset();
662
+ } catch (i) {
663
+ console.error("[velojs/testing] stream.__reset failed:", i);
618
664
  }
619
665
  },
620
666
  async close() {
621
- await c.reset(), V(e);
622
- for (const t of s.disposers)
667
+ await r.reset(), L(e);
668
+ for (const o of n.disposers)
623
669
  try {
624
- t();
625
- } catch (r) {
626
- console.error("[velojs/testing] disposer failed:", r);
670
+ o();
671
+ } catch (i) {
672
+ console.error("[velojs/testing] disposer failed:", i);
627
673
  }
628
- s.disposers.clear();
674
+ n.disposers.clear(), await l?.close();
629
675
  }
630
676
  };
631
- return c;
677
+ return r;
632
678
  }
633
- async function ne(e) {
679
+ async function re(e) {
634
680
  return {
635
681
  status: e.status,
636
682
  headers: z(e.headers),
637
- cookies: L(e.headers),
683
+ cookies: F(e.headers),
638
684
  json: () => e.clone().json(),
639
685
  text: () => e.clone().text(),
640
686
  blob: () => e.clone().blob(),
641
687
  raw: e
642
688
  };
643
689
  }
644
- function se(e) {
690
+ function ie(e) {
645
691
  throw new Error(
646
692
  "[velojs/testing] subscribe(stream) — stream has no __path. If this is a stream_* declaration, make sure your routes import is processed by the VeloJS Vite plugin (your vitest.config.ts must include `veloPlugin()`)."
647
693
  );
648
694
  }
649
695
  export {
650
- ae as createTestApp
696
+ fe as createTestApp
651
697
  };