@mauroandre/velojs 0.0.55 → 0.0.57

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