@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.
package/dist/server.js CHANGED
@@ -1,17 +1,19 @@
1
1
  import { jsx as w } from "preact/jsx-runtime";
2
- import { Hono as R } from "hono";
3
- import { logger as T } from "hono/logger";
4
- import { trimTrailingSlash as E } from "hono/trailing-slash";
5
- import { render as C } from "preact-render-to-string";
6
- import { Router as A } from "wouter-preact";
7
- import { AsyncLocalStorage as $ } from "node:async_hooks";
2
+ import { Hono as C } from "hono";
3
+ import { logger as E } from "hono/logger";
4
+ import { trimTrailingSlash as T } from "hono/trailing-slash";
5
+ import { render as A } from "preact-render-to-string";
6
+ import { Router as $ } from "wouter-preact";
7
+ import { AsyncLocalStorage as k } from "node:async_hooks";
8
8
  import { getAppContext as _ } from "./app-context.js";
9
- import { flushPendingStreamRoutes as k, registerStreamHandler as D } from "./events.js";
10
- import { registerSocketRoutes as O, injectWebSocketServer as S } from "./sockets.js";
11
- const P = new $();
9
+ import { flushPendingStreamRoutes as D, registerStreamHandler as I } from "./events.js";
10
+ import { registerSocketRoutes as N, injectWebSocketServer as S } from "./sockets.js";
11
+ import { inspectChannels as O, registerChannelRoute as H } from "./channels.js";
12
+ import { emit as le, registerChannels as de } from "./channels.js";
13
+ const P = new k();
12
14
  globalThis.__veloServerData = P;
13
15
  let g = null;
14
- function ee(e) {
16
+ function re(e) {
15
17
  if (g) {
16
18
  e(g);
17
19
  return;
@@ -21,55 +23,55 @@ function ee(e) {
21
23
  function b(e) {
22
24
  g = e;
23
25
  const t = _();
24
- for (const s of t.serverCallbacks) s(e);
26
+ for (const a of t.serverCallbacks) a(e);
25
27
  t.serverCallbacks.length = 0;
26
28
  }
27
- function I(e) {
29
+ function x(e) {
28
30
  g === e && (g = null);
29
31
  }
30
- function te(e) {
32
+ function se(e) {
31
33
  _().pendingRoutes.push(e);
32
34
  }
33
- const N = (e) => JSON.stringify(e).replace(/</g, "\\u003c").replace(/>/g, "\\u003e").replace(/\u2028/g, "\\u2028").replace(/\u2029/g, "\\u2029"), H = (e, t, s, a) => {
34
- if (a && a !== 200 && e.status(a), e.req.query("_data") === "1") {
35
- const c = globalThis.__veloBuildHash || void 0, r = s ? { ...s, __buildHash: c } : { __buildHash: c };
36
- return e.json(r);
35
+ const G = (e) => JSON.stringify(e).replace(/</g, "\\u003c").replace(/>/g, "\\u003e").replace(/\u2028/g, "\\u2028").replace(/\u2029/g, "\\u2029"), V = (e, t, a, r) => {
36
+ if (r && r !== 200 && e.status(r), e.req.query("_data") === "1") {
37
+ const c = globalThis.__veloBuildHash || void 0, i = a ? { ...a, __buildHash: c } : { __buildHash: c };
38
+ return e.json(i);
37
39
  }
38
40
  const o = e.req.path, n = P.run(
39
- s ?? {},
40
- () => C(/* @__PURE__ */ w(A, { ssrPath: o, children: t }))
41
+ a ?? {},
42
+ () => A(/* @__PURE__ */ w($, { ssrPath: o, children: t }))
41
43
  );
42
- if (e.header("Cache-Control", "no-cache"), !s)
44
+ if (e.header("Cache-Control", "no-cache"), !a)
43
45
  return e.html(n);
44
- const i = `<script>window.__PAGE_DATA__=${N(s)}<\/script>`;
45
- return e.html(n.replace("</head>", () => `${i}</head>`));
46
- }, G = async (e, t) => {
47
- const s = t.req.param(), a = t.req.query(), o = { params: s, query: a, c: t }, n = await Promise.all(
48
- e.map(async (r) => {
49
- if (!r.loader) return null;
50
- const f = await r.loader(o), l = r.metadata?.moduleId;
46
+ const s = `<script>window.__PAGE_DATA__=${G(a)}<\/script>`;
47
+ return e.html(n.replace("</head>", () => `${s}</head>`));
48
+ }, M = async (e, t) => {
49
+ const a = t.req.param(), r = t.req.query(), o = { params: a, query: r, c: t }, n = await Promise.all(
50
+ e.map(async (i) => {
51
+ if (!i.loader) return null;
52
+ const f = await i.loader(o), l = i.metadata?.moduleId;
51
53
  return l ? { moduleId: l, loaderData: f } : null;
52
54
  })
53
55
  );
54
- let i;
55
- for (const r of n)
56
- if (r && r.loaderData instanceof Response) {
57
- i = r.loaderData;
56
+ let s;
57
+ for (const i of n)
58
+ if (i && i.loaderData instanceof Response) {
59
+ s = i.loaderData;
58
60
  break;
59
61
  }
60
62
  const c = {
61
- __params: s,
62
- __query: a,
63
+ __params: a,
64
+ __query: r,
63
65
  __pathname: t.req.path
64
66
  };
65
- for (const r of n)
66
- r && !(r.loaderData instanceof Response) && (c[r.moduleId] = r.loaderData);
67
+ for (const i of n)
68
+ i && !(i.loaderData instanceof Response) && (c[i.moduleId] = i.loaderData);
67
69
  return {
68
- components: e.map((r) => r.Component),
70
+ components: e.map((i) => i.Component),
69
71
  data: c,
70
- shortCircuit: i
72
+ shortCircuit: s
71
73
  };
72
- }, x = (e) => {
74
+ }, W = (e) => {
73
75
  if (e.length === 0) return null;
74
76
  const t = e.filter(Boolean);
75
77
  if (t.length === 0) return null;
@@ -77,21 +79,21 @@ const N = (e) => JSON.stringify(e).replace(/</g, "\\u003c").replace(/>/g, "\\u00
77
79
  const o = t[0];
78
80
  return /* @__PURE__ */ w(o, {});
79
81
  }
80
- const s = t[t.length - 1];
81
- return t.slice(0, -1).reduceRight((o, n) => /* @__PURE__ */ w(n, { children: o }), /* @__PURE__ */ w(s, {}));
82
- }, y = (e, t, s = [], a = []) => {
82
+ const a = t[t.length - 1];
83
+ return t.slice(0, -1).reduceRight((o, n) => /* @__PURE__ */ w(n, { children: o }), /* @__PURE__ */ w(a, {}));
84
+ }, y = (e, t, a = [], r = []) => {
83
85
  for (const o of t) {
84
86
  if (o.handler && !o.module) {
85
87
  o.children && y(
86
88
  e,
87
89
  o.children,
88
- s,
89
- [...a, ...o.middlewares || []]
90
+ a,
91
+ [...r, ...o.middlewares || []]
90
92
  );
91
93
  continue;
92
94
  }
93
- const n = o.module ? [...s, o.module] : s, i = [
94
- ...a,
95
+ const n = o.module ? [...a, o.module] : a, s = [
96
+ ...r,
95
97
  ...o.middlewares || []
96
98
  ];
97
99
  if (o.children)
@@ -99,10 +101,10 @@ const N = (e) => JSON.stringify(e).replace(/</g, "\\u003c").replace(/>/g, "\\u00
99
101
  e,
100
102
  o.children,
101
103
  n,
102
- i
104
+ s
103
105
  );
104
106
  else if (o.module) {
105
- const c = o.path === "*", r = o.statusCode ?? (c ? 404 : void 0), f = o.module.metadata?.fullPath;
107
+ const c = o.path === "*", i = o.statusCode ?? (c ? 404 : void 0), f = o.module.metadata?.fullPath;
106
108
  if (!f && !c) {
107
109
  console.warn(
108
110
  `Module ${o.module.metadata?.moduleId} has no fullPath`
@@ -110,32 +112,32 @@ const N = (e) => JSON.stringify(e).replace(/</g, "\\u003c").replace(/>/g, "\\u00
110
112
  continue;
111
113
  }
112
114
  const l = async (d) => {
113
- const { components: u, data: h, shortCircuit: m } = await G(n, d);
115
+ const { components: u, data: h, shortCircuit: m } = await M(n, d);
114
116
  if (m) {
115
117
  const v = m.headers.get("Location");
116
118
  return d.req.query("_data") === "1" && v && m.status >= 300 && m.status < 400 ? d.json({ __redirect: v }) : m;
117
119
  }
118
- const p = x(u);
119
- return H(d, p, h, r);
120
+ const p = W(u);
121
+ return V(d, p, h, i);
120
122
  };
121
- c ? e.notFound(l) : i.length > 0 ? e.on(["GET"], [f], ...i, l) : e.on(["GET"], [f], l);
123
+ c ? e.notFound(l) : s.length > 0 ? e.on(["GET"], [f], ...s, l) : e.on(["GET"], [f], l);
122
124
  } else
123
125
  continue;
124
126
  }
125
- }, q = (e, t, s = []) => {
126
- for (const a of t) {
127
- const o = a.module?.metadata?.moduleId, n = [
128
- ...s,
129
- ...a.middlewares || []
127
+ }, R = (e, t, a = []) => {
128
+ for (const r of t) {
129
+ const o = r.module?.metadata?.moduleId, n = [
130
+ ...a,
131
+ ...r.middlewares || []
130
132
  ];
131
- if (a.module && o) {
132
- const i = Object.keys(a.module).filter(
133
+ if (r.module && o) {
134
+ const s = Object.keys(r.module).filter(
133
135
  (c) => c.startsWith("action_")
134
136
  );
135
- for (const c of i) {
136
- const r = c.replace("action_", ""), f = a.module[c];
137
+ for (const c of s) {
138
+ const i = c.replace("action_", ""), f = r.module[c];
137
139
  if (typeof f == "function") {
138
- const l = `/_action/${o}/${r}`, d = async (u) => {
140
+ const l = `/_action/${o}/${i}`, d = async (u) => {
139
141
  let h = {};
140
142
  try {
141
143
  h = await u.req.json();
@@ -164,121 +166,145 @@ const N = (e) => JSON.stringify(e).replace(/</g, "\\u003c").replace(/>/g, "\\u00
164
166
  }
165
167
  }
166
168
  }
167
- a.children && q(e, a.children, n);
169
+ r.children && R(e, r.children, n);
168
170
  }
169
- }, V = async (e, t, s = []) => {
170
- const a = (o, n) => {
171
- for (const i of o) {
172
- const c = i.module?.metadata?.moduleId, r = [
171
+ }, K = async (e, t, a = []) => {
172
+ const r = (o, n) => {
173
+ for (const s of o) {
174
+ const c = s.module?.metadata?.moduleId, i = [
173
175
  ...n,
174
- ...i.middlewares || []
176
+ ...s.middlewares || []
175
177
  ];
176
- if (i.module && c) {
177
- const f = Object.keys(i.module).filter(
178
+ if (s.module && c) {
179
+ const f = Object.keys(s.module).filter(
178
180
  (l) => l.startsWith("stream_")
179
181
  );
180
182
  for (const l of f) {
181
- const d = l.replace("stream_", ""), u = i.module[l];
183
+ const d = l.replace("stream_", ""), u = s.module[l];
182
184
  if (u?.__isVeloEventStream) {
183
185
  const h = `/_event/${c}/${d}`;
184
- u.__path = h, D(
186
+ u.__path = h, I(
185
187
  e,
186
188
  h,
187
189
  u,
188
- r
190
+ i
189
191
  );
190
192
  }
191
193
  }
192
194
  }
193
- i.children && a(i.children, r);
195
+ s.children && r(s.children, i);
194
196
  }
195
197
  };
196
- a(t, s);
197
- }, W = (e, t) => t ? t.startsWith("/") ? e + t : e ? e + "/" + t : "/" + t : e || "", K = (e) => {
198
- const t = /* @__PURE__ */ new Set(), s = (a) => {
199
- for (const o of a) {
198
+ r(t, a);
199
+ }, j = (e, t, a = []) => {
200
+ for (const r of t) {
201
+ const o = r.module?.metadata?.moduleId, n = [
202
+ ...a,
203
+ ...r.middlewares || []
204
+ ];
205
+ if (r.module && o) {
206
+ const s = r.module.channels;
207
+ if (Array.isArray(s))
208
+ for (const c of s)
209
+ H(
210
+ e,
211
+ `/_channel/${o}/${c}`,
212
+ c,
213
+ r.module,
214
+ o,
215
+ n
216
+ );
217
+ }
218
+ r.children && j(e, r.children, n);
219
+ }
220
+ }, L = (e, t) => t ? t.startsWith("/") ? e + t : e ? e + "/" + t : "/" + t : e || "", B = (e) => {
221
+ const t = /* @__PURE__ */ new Set(), a = (r) => {
222
+ for (const o of r) {
200
223
  if (o.module && !o.children) {
201
224
  const n = o.module.metadata?.fullPath;
202
225
  n && t.add(n);
203
226
  }
204
- o.children && s(o.children);
227
+ o.children && a(o.children);
205
228
  }
206
229
  };
207
- return s(e), t;
208
- }, j = (e, t, s, a = "", o = []) => {
230
+ return a(e), t;
231
+ }, q = (e, t, a, r = "", o = []) => {
209
232
  for (const n of t) {
210
- const i = W(a, n.path), c = [
233
+ const s = L(r, n.path), c = [
211
234
  ...o,
212
235
  ...n.middlewares || []
213
- ], r = !!n.handler, f = !!n.method;
214
- if (r && !f ? console.warn(
215
- `[velojs] invalid route at "${i || "/"}" — "handler" set without "method"; endpoint skipped`
216
- ) : f && !r ? console.warn(
217
- `[velojs] invalid route at "${i || "/"}" — "method" set without "handler"; endpoint skipped`
218
- ) : r && n.module ? console.warn(
219
- `[velojs] ambiguous route at "${i || "/"}" — both "module" and "handler" set; endpoint ignored, page kept`
220
- ) : r && n.isRoot && console.warn(
221
- `[velojs] "isRoot" has no effect on endpoint at "${i || "/"}"; ignored`
222
- ), r && f && !n.module) {
236
+ ], i = !!n.handler, f = !!n.method;
237
+ if (i && !f ? console.warn(
238
+ `[velojs] invalid route at "${s || "/"}" — "handler" set without "method"; endpoint skipped`
239
+ ) : f && !i ? console.warn(
240
+ `[velojs] invalid route at "${s || "/"}" — "method" set without "handler"; endpoint skipped`
241
+ ) : i && n.module ? console.warn(
242
+ `[velojs] ambiguous route at "${s || "/"}" — both "module" and "handler" set; endpoint ignored, page kept`
243
+ ) : i && n.isRoot && console.warn(
244
+ `[velojs] "isRoot" has no effect on endpoint at "${s || "/"}"; ignored`
245
+ ), i && f && !n.module) {
223
246
  const d = n.method;
224
- d === "GET" && s.has(i) && console.warn(
225
- `[velojs] path "${i}" has both a page GET and an endpoint GET; the page wins and the endpoint is unreachable. Consider renaming one.`
247
+ d === "GET" && a.has(s) && console.warn(
248
+ `[velojs] path "${s}" has both a page GET and an endpoint GET; the page wins and the endpoint is unreachable. Consider renaming one.`
226
249
  );
227
250
  const u = n.handler, h = async (m) => await u({
228
251
  c: m,
229
252
  params: m.req.param(),
230
253
  query: m.req.query()
231
254
  });
232
- c.length > 0 ? e.on([d], [i], ...c, h) : e.on([d], [i], h);
255
+ c.length > 0 ? e.on([d], [s], ...c, h) : e.on([d], [s], h);
233
256
  }
234
- n.children && j(
257
+ n.children && q(
235
258
  e,
236
259
  n.children,
260
+ a,
237
261
  s,
238
- i,
239
262
  c
240
263
  );
241
264
  }
242
- }, L = async (e) => {
243
- const t = new R();
244
- t.use(E()), process.env.NODE_ENV !== "production" && t.use("*", T());
245
- const a = _().pendingRoutes.splice(0);
246
- for (const n of a)
265
+ }, F = async (e) => {
266
+ const t = new C();
267
+ t.use(T()), process.env.NODE_ENV !== "production" && t.use("*", E());
268
+ const r = _().pendingRoutes.splice(0);
269
+ for (const n of r)
247
270
  await n(t);
248
- y(t, e), q(t, e), await V(t, e);
249
- const o = K(e);
250
- if (j(t, e, o), await O(t, e), k(t), process.env.NODE_ENV !== "production" && !g) {
271
+ y(t, e), R(t, e), await K(t, e), j(t, e), process.env.NODE_ENV !== "production" && t.get("/_channel-inspect", (n) => n.json(O()));
272
+ const o = B(e);
273
+ if (q(t, e, o), await N(t, e), D(t), process.env.NODE_ENV !== "production" && !g) {
251
274
  const n = globalThis.__veloDevServer;
252
275
  n && (b(n), await S(t, n));
253
276
  }
254
277
  return t;
255
- }, oe = async (e) => {
256
- const { routes: t } = e, s = Number(process.env.PORT) || e.port || 3e3, a = process.env.HOST || e.hostname || void 0, o = await L(t);
278
+ }, ae = async (e) => {
279
+ const { routes: t } = e, a = Number(process.env.PORT) || e.port || 3e3, r = process.env.HOST || e.hostname || void 0, o = await F(t);
257
280
  if (process.env.NODE_ENV === "production" && !process.env.VELO_STATIC) {
258
- const { serve: n } = await import("@hono/node-server"), { serveStatic: i } = await import("@hono/node-server/serve-static"), { join: c } = await import("node:path"), r = c(process.cwd(), "dist/client");
259
- (process.env.STATIC_BASE_URL || "").startsWith("http") || o.use("/*", i({ root: r }));
260
- const l = n({ fetch: o.fetch, port: s, ...a ? { hostname: a } : {} });
281
+ const { serve: n } = await import("@hono/node-server"), { serveStatic: s } = await import("@hono/node-server/serve-static"), { join: c } = await import("node:path"), i = c(process.cwd(), "dist/client");
282
+ (process.env.STATIC_BASE_URL || "").startsWith("http") || o.use("/*", s({ root: i }));
283
+ const l = n({ fetch: o.fetch, port: a, ...r ? { hostname: r } : {} });
261
284
  l.listening || await new Promise((u) => l.once("listening", u));
262
285
  const d = l.address();
263
286
  if (d && typeof d == "object") {
264
287
  const h = d.address === "::" || d.address === "0.0.0.0" ? "0.0.0.0 (all interfaces)" : d.address;
265
288
  console.log(`Server running on ${h}:${d.port}`);
266
289
  } else
267
- console.log(`Server running on port ${s}`);
290
+ console.log(`Server running on port ${a}`);
268
291
  await S(o, l), b(l), l.once("close", () => {
269
- I(l);
292
+ x(l);
270
293
  });
271
294
  }
272
295
  return o;
273
296
  };
274
297
  export {
275
- te as addRoutes,
276
- I as clearActiveServer,
277
- L as createApp,
278
- L as default,
298
+ se as addRoutes,
299
+ x as clearActiveServer,
300
+ F as createApp,
301
+ F as default,
302
+ le as emit,
279
303
  b as flushServerCallbacks,
280
- N as jsonForScript,
281
- ee as onServer,
304
+ O as inspectChannels,
305
+ G as jsonForScript,
306
+ re as onServer,
307
+ de as registerChannels,
282
308
  P as serverDataStorage,
283
- oe as startServer
309
+ ae as startServer
284
310
  };
@@ -15,6 +15,10 @@
15
15
  * expect(res.status).toBe(200);
16
16
  * await app.close();
17
17
  * ```
18
+ *
19
+ * The live loader is exercised deterministically with `app.channel(module,
20
+ * name)`: open a channel connection with a principal, emit and await the next
21
+ * snapshot — no sleep, no retry.
18
22
  */
19
23
  export { createTestApp } from "./createTestApp.js";
20
- export type { TestApp, TestResponse, TestSubscription, CreateTestAppOptions, RequestOptions, BodyRequestOptions, LoaderRequestOptions, SubscribeOptions, NextOptions, MockContextOptions, Cookies, Headers, Query, Params, } from "./types.js";
24
+ export type { TestApp, TestResponse, TestSubscription, TestChannelSubscription, ChannelEvent, ChannelModuleRef, CreateTestAppOptions, RequestOptions, BodyRequestOptions, LoaderRequestOptions, SubscribeOptions, ChannelSubscribeOptions, NextOptions, MockContextOptions, Cookies, Headers, Query, Params, } from "./types.js";