@mauroandre/velojs 0.0.56 → 0.0.58

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.
@@ -3,11 +3,18 @@
3
3
  *
4
4
  * After hydration, every rendered module that declares `channels` opens one SSE
5
5
  * connection per (module, channel) at `/_channel/{moduleId}/{channel}`. The
6
- * snapshot the connection receives — the connect snapshot and each emit's —
7
- * replaces the value of the module's entry in the loader store, so the page
8
- * stays faithful to server state without a line of code from the developer:
9
- * `useLoader()`/`Loader()` handles keep the same signal instance and the
10
- * reading component re-renders on its own.
6
+ * connection declares the route params the module's path declares, extracted
7
+ * from the current URL and serialized in `?_route=` — the client declares the
8
+ * address it is already seeing, the server validates it against the declared
9
+ * path and decides the partition. The snapshot the connection receives — the
10
+ * connect snapshot and each emit's — replaces the value of the module's entry
11
+ * in the loader store, so the page stays faithful to server state without a
12
+ * line of code from the developer: `useLoader()`/`Loader()` handles keep the
13
+ * same signal instance and the reading component re-renders on its own.
14
+ *
15
+ * The connection is keyed by those params, not by the pathname: navigating
16
+ * between children of the same params keeps the connection; a move to another
17
+ * resource closes it and opens a new one.
11
18
  *
12
19
  * A `slice` event is the other delivery mode: the producer already holds the
13
20
  * value, so the payload carries only the changed keys. A slice is merged
@@ -68,19 +75,45 @@ export declare function loaderFreshness(): Signal<Freshness>;
68
75
  * closer — the channel lives exactly as long as the module that declares it is
69
76
  * mounted.
70
77
  *
78
+ * `routeParams` are the params the module's route declares, extracted from the
79
+ * current URL: the client **declares** the address it is already seeing (the
80
+ * same information `?_data=1` carries on every SPA navigation), serialized in
81
+ * the `?_route=` query param of the connection. It is not free input — the
82
+ * server validates the keys against the module's path and rejects what the path
83
+ * does not declare.
84
+ *
71
85
  * Inert (no connection, no freshness change) in a static build: there is no
72
86
  * server to speak SSE.
73
87
  */
74
- export declare function connectChannel(moduleId: string, channel: string): () => void;
88
+ export declare function connectChannel(moduleId: string, channel: string, routeParams?: Record<string, string> | undefined): () => void;
89
+ /**
90
+ * The params the module's route declares, extracted from a pathname. The
91
+ * module's `fullPath` matches as a **prefix** of the pathname: a layout
92
+ * declared at `/projeto/:id` covers `/projeto/7/sala` and extracts `id=7` —
93
+ * the child's suffix takes no part in the extraction. A path with a catch-all
94
+ * (`/docs/*`) declares no `:` key and yields the empty object, so the channel
95
+ * travels by principal.
96
+ */
97
+ export declare function channelRouteParams(fullPath: string | undefined, pathname: string): Record<string, string>;
75
98
  /**
76
99
  * Mounts the live channels of one route module. It renders its children
77
100
  * unchanged (no DOM node, so SSR output and hydration are untouched) and only
78
101
  * exists to tie the connection lifecycle to the module's own mount/unmount —
79
102
  * SPA navigation and page close close the connections.
103
+ *
104
+ * The connection is **keyed by the params the module's route declares**, not
105
+ * by the pathname: navigating between children of the same params
106
+ * (`/projeto/7` → `/projeto/7/sala`) does not reconnect (the child's suffix is
107
+ * not part of the connection's identity), while a move to another resource
108
+ * (`/projeto/7` → `/projeto/9`) closes the old connection and opens a new one —
109
+ * with a fresh snapshot on connect, mirroring the loader store, which refetches
110
+ * when its own route's params move.
80
111
  */
81
- export declare function ChannelBoundary({ moduleId, channels, children, }: {
112
+ export declare function ChannelBoundary({ moduleId, channels, fullPath, children, }: {
82
113
  moduleId?: string | undefined;
83
114
  channels?: readonly string[] | undefined;
115
+ /** The module's declared route path (`metadata.fullPath`) — its `:params`. */
116
+ fullPath?: string | undefined;
84
117
  children?: ComponentChildren;
85
118
  }): ComponentChildren;
86
119
  /** Test-only. Drops every connection and resets every freshness signal. */
@@ -1,33 +1,34 @@
1
- import { signal as h } from "@preact/signals";
2
- import { useEffect as S } from "preact/hooks";
3
- import { loaderEntry as v } from "./loader-store.js";
4
- const E = 6e4, _ = "snapshot", g = "slice", a = /* @__PURE__ */ new Set(), u = h("live"), d = /* @__PURE__ */ new Map();
5
- function b(e) {
6
- let n = d.get(e);
7
- return n || (n = h({}), d.set(e, n)), n;
1
+ import { signal as v } from "@preact/signals";
2
+ import { useEffect as m } from "preact/hooks";
3
+ import { useLocation as g } from "wouter-preact";
4
+ import { extractParams as _, loaderEntry as S } from "./loader-store.js";
5
+ const L = 6e4, C = "snapshot", w = "slice", f = /* @__PURE__ */ new Set(), p = v("live"), y = /* @__PURE__ */ new Map();
6
+ function R(e) {
7
+ let n = y.get(e);
8
+ return n || (n = v({}), y.set(e, n)), n;
8
9
  }
9
- function O() {
10
- return u;
10
+ function V() {
11
+ return p;
11
12
  }
12
- const f = /* @__PURE__ */ new Map();
13
- let p = !1;
14
- function m(e, n) {
15
- let t = f.get(e);
16
- t || (t = [], f.set(e, t)), t.push(n), !p && (p = !0, queueMicrotask(y));
13
+ const u = /* @__PURE__ */ new Map();
14
+ let h = !1;
15
+ function N(e, n) {
16
+ let o = u.get(e);
17
+ o || (o = [], u.set(e, o)), o.push(n), !h && (h = !0, queueMicrotask(E));
17
18
  }
18
- function y() {
19
- if (p = !1, f.size === 0) return;
20
- const e = [...f];
21
- f.clear();
22
- for (const [n, t] of e) {
23
- const r = v(n);
24
- let s = r.value;
25
- for (const o of t)
26
- s = { ...s !== null && typeof s == "object" && !Array.isArray(s) ? s : {}, ...o };
27
- r.value = s;
19
+ function E() {
20
+ if (h = !1, u.size === 0) return;
21
+ const e = [...u];
22
+ u.clear();
23
+ for (const [n, o] of e) {
24
+ const s = S(n);
25
+ let t = s.value;
26
+ for (const l of o)
27
+ t = { ...t !== null && typeof t == "object" && !Array.isArray(t) ? t : {}, ...l };
28
+ s.value = t;
28
29
  }
29
30
  }
30
- function L(e) {
31
+ function T(e) {
31
32
  if (typeof e != "string" || e.length === 0) return null;
32
33
  try {
33
34
  const n = JSON.parse(e);
@@ -36,96 +37,105 @@ function L(e) {
36
37
  return null;
37
38
  }
38
39
  }
39
- function C(e) {
40
+ function O(e) {
40
41
  return e.some((n) => n.failed) ? "error" : e.some((n) => n.state === "open" && !n.silent) ? "live" : "stale";
41
42
  }
42
- function c() {
43
+ function a() {
43
44
  let e = !1, n = !1;
44
- for (const t of a)
45
- t.failed && (e = !0), t.state === "open" && !t.silent && (n = !0);
46
- e ? u.value = "error" : a.size > 0 && !n ? u.value = "stale" : u.value = "live";
47
- for (const [t, r] of d) {
48
- const s = /* @__PURE__ */ new Map();
49
- for (const l of a) {
50
- if (l.moduleId !== t) continue;
51
- const i = s.get(l.channel);
52
- i ? i.push(l) : s.set(l.channel, [l]);
45
+ for (const o of f)
46
+ o.failed && (e = !0), o.state === "open" && !o.silent && (n = !0);
47
+ e ? p.value = "error" : f.size > 0 && !n ? p.value = "stale" : p.value = "live";
48
+ for (const [o, s] of y) {
49
+ const t = /* @__PURE__ */ new Map();
50
+ for (const i of f) {
51
+ if (i.moduleId !== o) continue;
52
+ const r = t.get(i.channel);
53
+ r ? r.push(i) : t.set(i.channel, [i]);
53
54
  }
54
- const o = {};
55
- for (const [l, i] of s)
56
- o[l] = C(i);
57
- r.value = o;
55
+ const l = {};
56
+ for (const [i, r] of t)
57
+ l[i] = O(r);
58
+ s.value = l;
58
59
  }
59
60
  }
60
- function T(e, n) {
61
+ function A(e, n, o) {
61
62
  if (typeof __VELO_STATIC__ < "u" && __VELO_STATIC__) return () => {
62
63
  };
63
64
  if (typeof window > "u" || typeof EventSource > "u")
64
65
  return () => {
65
66
  };
66
- const t = {
67
+ const s = {
67
68
  state: "open",
68
69
  failed: !1,
69
70
  silent: !1,
70
71
  moduleId: e,
71
72
  channel: n
72
73
  };
73
- a.add(t), c();
74
- let r = null;
75
- const s = () => {
76
- r !== null && clearTimeout(r), r = setTimeout(() => {
77
- r = null, t.silent = !0, c();
78
- }, E);
74
+ f.add(s), a();
75
+ let t = null;
76
+ const l = () => {
77
+ t !== null && clearTimeout(t), t = setTimeout(() => {
78
+ t = null, s.silent = !0, a();
79
+ }, L);
79
80
  };
80
- s();
81
- const o = new EventSource(
82
- `/_channel/${encodeURI(e)}/${encodeURIComponent(n)}`
81
+ l();
82
+ const i = o && Object.keys(o).length > 0 ? `?_route=${encodeURIComponent(JSON.stringify(o))}` : "", r = new EventSource(
83
+ `/_channel/${encodeURI(e)}/${encodeURIComponent(n)}${i}`
83
84
  );
84
- return o.addEventListener(_, (l) => {
85
+ return r.addEventListener(C, (c) => {
85
86
  try {
86
- y(), v(e).value = JSON.parse(l.data), t.state = "open", t.failed = !1, t.silent = !1, s(), c();
87
+ E(), S(e).value = JSON.parse(c.data), s.state = "open", s.failed = !1, s.silent = !1, l(), a();
87
88
  } catch {
88
89
  }
89
- }), o.addEventListener(g, (l) => {
90
- const i = L(l.data);
91
- i && (t.state = "open", t.failed = !1, t.silent = !1, s(), c(), m(e, i));
92
- }), o.addEventListener("error", (l) => {
93
- const i = l.data;
94
- typeof i == "string" && i.length > 0 ? t.failed = !0 : t.state = o.readyState === EventSource.CLOSED ? "closed" : "reconnecting", c();
95
- }), o.addEventListener("close", () => {
96
- t.state = "closed", c();
90
+ }), r.addEventListener(w, (c) => {
91
+ const d = T(c.data);
92
+ d && (s.state = "open", s.failed = !1, s.silent = !1, l(), a(), N(e, d));
93
+ }), r.addEventListener("error", (c) => {
94
+ const d = c.data;
95
+ typeof d == "string" && d.length > 0 ? s.failed = !0 : s.state = r.readyState === EventSource.CLOSED ? "closed" : "reconnecting", a();
96
+ }), r.addEventListener("close", () => {
97
+ s.state = "closed", a();
97
98
  }), () => {
98
- a.delete(t), r !== null && clearTimeout(r);
99
+ f.delete(s), t !== null && clearTimeout(t);
99
100
  try {
100
- o.close();
101
+ r.close();
101
102
  } catch {
102
103
  }
103
- c();
104
+ a();
104
105
  };
105
106
  }
106
- function M({
107
+ function b(e, n) {
108
+ return e ? _(e, n) ?? {} : {};
109
+ }
110
+ function $({
107
111
  moduleId: e,
108
112
  channels: n,
109
- children: t
113
+ fullPath: o,
114
+ children: s
110
115
  }) {
111
- const r = n && n.length > 0 ? n.join(",") : "";
112
- return S(() => {
113
- if (!e || r === "") return;
114
- const s = r.split(",").map((o) => T(e, o));
116
+ const t = n && n.length > 0 ? n.join(",") : "";
117
+ g();
118
+ const l = t === "" || typeof window > "u" ? "" : JSON.stringify(b(o, window.location.pathname));
119
+ return m(() => {
120
+ if (!e || t === "") return;
121
+ const i = l === "" ? void 0 : JSON.parse(l), r = t.split(",").map(
122
+ (c) => A(e, c, i)
123
+ );
115
124
  return () => {
116
- for (const o of s) o();
125
+ for (const c of r) c();
117
126
  };
118
- }, [e, r]), t;
127
+ }, [e, t, l]), s;
119
128
  }
120
- function F() {
121
- a.clear(), f.clear(), p = !1, u.value = "live";
122
- for (const e of d.values()) e.value = {};
129
+ function k() {
130
+ f.clear(), u.clear(), h = !1, p.value = "live";
131
+ for (const e of y.values()) e.value = {};
123
132
  }
124
133
  export {
125
- E as CHANNEL_SILENCE_MS,
126
- M as ChannelBoundary,
127
- F as __resetLiveLoader,
128
- T as connectChannel,
129
- O as loaderFreshness,
130
- b as moduleChannelFreshness
134
+ L as CHANNEL_SILENCE_MS,
135
+ $ as ChannelBoundary,
136
+ k as __resetLiveLoader,
137
+ b as channelRouteParams,
138
+ A as connectChannel,
139
+ V as loaderFreshness,
140
+ R as moduleChannelFreshness
131
141
  };
package/dist/server.d.ts CHANGED
@@ -2,7 +2,7 @@ import { Hono } from "hono";
2
2
  import type { AppRoutes } from "./types.js";
3
3
  import { AsyncLocalStorage } from "node:async_hooks";
4
4
  export { emit, inspectChannels, registerChannels } from "./channels.js";
5
- export type { ChannelDefinition, ChannelMap, ChannelScopeResult, ChannelRegistryOptions, ChannelEmitModule, ChannelEmitKind, ChannelSlice, ChannelInspectGroup, ChannelInspectChannel, ChannelInspectWindow, ChannelInspectReport, } from "./channels.js";
5
+ export type { ChannelDefinition, ChannelMap, ChannelScopeContext, ChannelGroupOpenContext, ChannelGroupCloseContext, ChannelScopeResult, ChannelRegistryOptions, ChannelEmitModule, ChannelEmitKind, ChannelSlice, ChannelInspectGroup, ChannelInspectChannel, ChannelInspectWindow, ChannelInspectReport, } from "./channels.js";
6
6
  export declare const serverDataStorage: AsyncLocalStorage<Record<string, unknown>>;
7
7
  type ServerCallback = (server: import("http").Server) => void;
8
8
  export declare function onServer(fn: ServerCallback): void;
package/dist/server.js CHANGED
@@ -1,38 +1,38 @@
1
1
  import { jsx as w } from "preact/jsx-runtime";
2
- import { Hono as C } from "hono";
3
- import { logger as E } from "hono/logger";
2
+ import { Hono as j } from "hono";
3
+ import { logger as q } from "hono/logger";
4
4
  import { trimTrailingSlash as T } from "hono/trailing-slash";
5
5
  import { render as A } from "preact-render-to-string";
6
6
  import { Router as $ } from "wouter-preact";
7
7
  import { AsyncLocalStorage as k } from "node:async_hooks";
8
8
  import { getAppContext as _ } from "./app-context.js";
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";
9
+ import { flushPendingStreamRoutes as D, registerStreamHandler as N } from "./events.js";
10
+ import { registerSocketRoutes as O, injectWebSocketServer as S } from "./sockets.js";
11
+ import { inspectChannels as I, registerChannelRoute as H } from "./channels.js";
12
+ import { emit as de, registerChannels as ue } from "./channels.js";
13
13
  const P = new k();
14
14
  globalThis.__veloServerData = P;
15
15
  let g = null;
16
- function re(e) {
16
+ function se(e) {
17
17
  if (g) {
18
18
  e(g);
19
19
  return;
20
20
  }
21
21
  _().serverCallbacks.push(e);
22
22
  }
23
- function b(e) {
23
+ function C(e) {
24
24
  g = e;
25
25
  const t = _();
26
26
  for (const a of t.serverCallbacks) a(e);
27
27
  t.serverCallbacks.length = 0;
28
28
  }
29
- function x(e) {
29
+ function V(e) {
30
30
  g === e && (g = null);
31
31
  }
32
- function se(e) {
32
+ function ae(e) {
33
33
  _().pendingRoutes.push(e);
34
34
  }
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) => {
35
+ const x = (e) => JSON.stringify(e).replace(/</g, "\\u003c").replace(/>/g, "\\u003e").replace(/\u2028/g, "\\u2028").replace(/\u2029/g, "\\u2029"), G = (e, t, a, r) => {
36
36
  if (r && r !== 200 && e.status(r), e.req.query("_data") === "1") {
37
37
  const c = globalThis.__veloBuildHash || void 0, i = a ? { ...a, __buildHash: c } : { __buildHash: c };
38
38
  return e.json(i);
@@ -43,14 +43,14 @@ const G = (e) => JSON.stringify(e).replace(/</g, "\\u003c").replace(/>/g, "\\u00
43
43
  );
44
44
  if (e.header("Cache-Control", "no-cache"), !a)
45
45
  return e.html(n);
46
- const s = `<script>window.__PAGE_DATA__=${G(a)}<\/script>`;
46
+ const s = `<script>window.__PAGE_DATA__=${x(a)}<\/script>`;
47
47
  return e.html(n.replace("</head>", () => `${s}</head>`));
48
- }, M = async (e, t) => {
48
+ }, L = async (e, t) => {
49
49
  const a = t.req.param(), r = t.req.query(), o = { params: a, query: r, c: t }, n = await Promise.all(
50
50
  e.map(async (i) => {
51
51
  if (!i.loader) return null;
52
- const f = await i.loader(o), l = i.metadata?.moduleId;
53
- return l ? { moduleId: l, loaderData: f } : null;
52
+ const l = await i.loader(o), d = i.metadata?.moduleId;
53
+ return d ? { moduleId: d, loaderData: l } : null;
54
54
  })
55
55
  );
56
56
  let s;
@@ -71,7 +71,7 @@ const G = (e) => JSON.stringify(e).replace(/</g, "\\u003c").replace(/>/g, "\\u00
71
71
  data: c,
72
72
  shortCircuit: s
73
73
  };
74
- }, W = (e) => {
74
+ }, M = (e) => {
75
75
  if (e.length === 0) return null;
76
76
  const t = e.filter(Boolean);
77
77
  if (t.length === 0) return null;
@@ -104,27 +104,27 @@ const G = (e) => JSON.stringify(e).replace(/</g, "\\u003c").replace(/>/g, "\\u00
104
104
  s
105
105
  );
106
106
  else if (o.module) {
107
- const c = o.path === "*", i = o.statusCode ?? (c ? 404 : void 0), f = o.module.metadata?.fullPath;
108
- if (!f && !c) {
107
+ const c = o.path === "*", i = o.statusCode ?? (c ? 404 : void 0), l = o.module.metadata?.fullPath;
108
+ if (!l && !c) {
109
109
  console.warn(
110
110
  `Module ${o.module.metadata?.moduleId} has no fullPath`
111
111
  );
112
112
  continue;
113
113
  }
114
- const l = async (d) => {
115
- const { components: u, data: h, shortCircuit: m } = await M(n, d);
116
- if (m) {
117
- const v = m.headers.get("Location");
118
- return d.req.query("_data") === "1" && v && m.status >= 300 && m.status < 400 ? d.json({ __redirect: v }) : m;
114
+ const d = async (f) => {
115
+ const { components: u, data: m, shortCircuit: h } = await L(n, f);
116
+ if (h) {
117
+ const v = h.headers.get("Location");
118
+ return f.req.query("_data") === "1" && v && h.status >= 300 && h.status < 400 ? f.json({ __redirect: v }) : h;
119
119
  }
120
- const p = W(u);
121
- return V(d, p, h, i);
120
+ const p = M(u);
121
+ return G(f, p, m, i);
122
122
  };
123
- c ? e.notFound(l) : s.length > 0 ? e.on(["GET"], [f], ...s, l) : e.on(["GET"], [f], l);
123
+ c ? e.notFound(d) : s.length > 0 ? e.on(["GET"], [l], ...s, d) : e.on(["GET"], [l], d);
124
124
  } else
125
125
  continue;
126
126
  }
127
- }, R = (e, t, a = []) => {
127
+ }, E = (e, t, a = []) => {
128
128
  for (const r of t) {
129
129
  const o = r.module?.metadata?.moduleId, n = [
130
130
  ...a,
@@ -135,22 +135,22 @@ const G = (e) => JSON.stringify(e).replace(/</g, "\\u003c").replace(/>/g, "\\u00
135
135
  (c) => c.startsWith("action_")
136
136
  );
137
137
  for (const c of s) {
138
- const i = c.replace("action_", ""), f = r.module[c];
139
- if (typeof f == "function") {
140
- const l = `/_action/${o}/${i}`, d = async (u) => {
141
- let h = {};
138
+ const i = c.replace("action_", ""), l = r.module[c];
139
+ if (typeof l == "function") {
140
+ const d = `/_action/${o}/${i}`, f = async (u) => {
141
+ let m = {};
142
142
  try {
143
- h = await u.req.json();
143
+ m = await u.req.json();
144
144
  } catch {
145
145
  }
146
- const m = {
147
- body: h,
146
+ const h = {
147
+ body: m,
148
148
  params: u.req.param(),
149
149
  query: u.req.query(),
150
150
  c: u
151
151
  };
152
152
  try {
153
- const p = await f(m);
153
+ const p = await l(h);
154
154
  return u.json(p ?? { ok: !0 });
155
155
  } catch (p) {
156
156
  const v = p instanceof Error ? p.message : "Action failed";
@@ -159,16 +159,16 @@ const G = (e) => JSON.stringify(e).replace(/</g, "\\u003c").replace(/>/g, "\\u00
159
159
  };
160
160
  n.length > 0 ? e.on(
161
161
  ["POST"],
162
- [l],
162
+ [d],
163
163
  ...n,
164
- d
165
- ) : e.on(["POST"], [l], d);
164
+ f
165
+ ) : e.on(["POST"], [d], f);
166
166
  }
167
167
  }
168
168
  }
169
- r.children && R(e, r.children, n);
169
+ r.children && E(e, r.children, n);
170
170
  }
171
- }, K = async (e, t, a = []) => {
171
+ }, W = async (e, t, a = []) => {
172
172
  const r = (o, n) => {
173
173
  for (const s of o) {
174
174
  const c = s.module?.metadata?.moduleId, i = [
@@ -176,16 +176,16 @@ const G = (e) => JSON.stringify(e).replace(/</g, "\\u003c").replace(/>/g, "\\u00
176
176
  ...s.middlewares || []
177
177
  ];
178
178
  if (s.module && c) {
179
- const f = Object.keys(s.module).filter(
180
- (l) => l.startsWith("stream_")
179
+ const l = Object.keys(s.module).filter(
180
+ (d) => d.startsWith("stream_")
181
181
  );
182
- for (const l of f) {
183
- const d = l.replace("stream_", ""), u = s.module[l];
182
+ for (const d of l) {
183
+ const f = d.replace("stream_", ""), u = s.module[d];
184
184
  if (u?.__isVeloEventStream) {
185
- const h = `/_event/${c}/${d}`;
186
- u.__path = h, I(
185
+ const m = `/_event/${c}/${f}`;
186
+ u.__path = m, N(
187
187
  e,
188
- h,
188
+ m,
189
189
  u,
190
190
  i
191
191
  );
@@ -196,7 +196,7 @@ const G = (e) => JSON.stringify(e).replace(/</g, "\\u003c").replace(/>/g, "\\u00
196
196
  }
197
197
  };
198
198
  r(t, a);
199
- }, j = (e, t, a = []) => {
199
+ }, b = (e, t, a = []) => {
200
200
  for (const r of t) {
201
201
  const o = r.module?.metadata?.moduleId, n = [
202
202
  ...a,
@@ -215,9 +215,9 @@ const G = (e) => JSON.stringify(e).replace(/</g, "\\u003c").replace(/>/g, "\\u00
215
215
  n
216
216
  );
217
217
  }
218
- r.children && j(e, r.children, n);
218
+ r.children && b(e, r.children, n);
219
219
  }
220
- }, L = (e, t) => t ? t.startsWith("/") ? e + t : e ? e + "/" + t : "/" + t : e || "", B = (e) => {
220
+ }, K = (e, t) => t ? t.startsWith("/") ? e + t : e ? e + "/" + t : "/" + t : e || "", B = (e) => {
221
221
  const t = /* @__PURE__ */ new Set(), a = (r) => {
222
222
  for (const o of r) {
223
223
  if (o.module && !o.children) {
@@ -228,33 +228,33 @@ const G = (e) => JSON.stringify(e).replace(/</g, "\\u003c").replace(/>/g, "\\u00
228
228
  }
229
229
  };
230
230
  return a(e), t;
231
- }, q = (e, t, a, r = "", o = []) => {
231
+ }, R = (e, t, a, r = "", o = []) => {
232
232
  for (const n of t) {
233
- const s = L(r, n.path), c = [
233
+ const s = K(r, n.path), c = [
234
234
  ...o,
235
235
  ...n.middlewares || []
236
- ], i = !!n.handler, f = !!n.method;
237
- if (i && !f ? console.warn(
236
+ ], i = !!n.handler, l = !!n.method;
237
+ if (i && !l ? console.warn(
238
238
  `[velojs] invalid route at "${s || "/"}" — "handler" set without "method"; endpoint skipped`
239
- ) : f && !i ? console.warn(
239
+ ) : l && !i ? console.warn(
240
240
  `[velojs] invalid route at "${s || "/"}" — "method" set without "handler"; endpoint skipped`
241
241
  ) : i && n.module ? console.warn(
242
242
  `[velojs] ambiguous route at "${s || "/"}" — both "module" and "handler" set; endpoint ignored, page kept`
243
243
  ) : i && n.isRoot && console.warn(
244
244
  `[velojs] "isRoot" has no effect on endpoint at "${s || "/"}"; ignored`
245
- ), i && f && !n.module) {
246
- const d = n.method;
247
- d === "GET" && a.has(s) && console.warn(
245
+ ), i && l && !n.module) {
246
+ const f = n.method;
247
+ f === "GET" && a.has(s) && console.warn(
248
248
  `[velojs] path "${s}" has both a page GET and an endpoint GET; the page wins and the endpoint is unreachable. Consider renaming one.`
249
249
  );
250
- const u = n.handler, h = async (m) => await u({
251
- c: m,
252
- params: m.req.param(),
253
- query: m.req.query()
250
+ const u = n.handler, m = async (h) => await u({
251
+ c: h,
252
+ params: h.req.param(),
253
+ query: h.req.query()
254
254
  });
255
- c.length > 0 ? e.on([d], [s], ...c, h) : e.on([d], [s], h);
255
+ c.length > 0 ? e.on([f], [s], ...c, m) : e.on([f], [s], m);
256
256
  }
257
- n.children && q(
257
+ n.children && R(
258
258
  e,
259
259
  n.children,
260
260
  a,
@@ -263,48 +263,50 @@ const G = (e) => JSON.stringify(e).replace(/</g, "\\u003c").replace(/>/g, "\\u00
263
263
  );
264
264
  }
265
265
  }, F = async (e) => {
266
- const t = new C();
267
- t.use(T()), process.env.NODE_ENV !== "production" && t.use("*", E());
266
+ if (process.env.NODE_ENV !== "production" || process.env.VELO_STATIC || (process.env.STATIC_BASE_URL || "").startsWith("http")) return;
267
+ const { serveStatic: a } = await import("@hono/node-server/serve-static"), { join: r } = await import("node:path");
268
+ e.use("/*", a({ root: r(process.cwd(), "dist/client") }));
269
+ }, U = async (e) => {
270
+ const t = new j();
271
+ t.use(T()), process.env.NODE_ENV !== "production" && t.use("*", q()), await F(t);
268
272
  const r = _().pendingRoutes.splice(0);
269
273
  for (const n of r)
270
274
  await n(t);
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()));
275
+ y(t, e), E(t, e), await W(t, e), b(t, e), process.env.NODE_ENV !== "production" && t.get("/_channel-inspect", (n) => n.json(I()));
272
276
  const o = B(e);
273
- if (q(t, e, o), await N(t, e), D(t), process.env.NODE_ENV !== "production" && !g) {
277
+ if (R(t, e, o), await O(t, e), D(t), process.env.NODE_ENV !== "production" && !g) {
274
278
  const n = globalThis.__veloDevServer;
275
- n && (b(n), await S(t, n));
279
+ n && (C(n), await S(t, n));
276
280
  }
277
281
  return 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);
282
+ }, ie = async (e) => {
283
+ const { routes: t } = e, a = Number(process.env.PORT) || e.port || 3e3, r = process.env.HOST || e.hostname || void 0, o = await U(t);
280
284
  if (process.env.NODE_ENV === "production" && !process.env.VELO_STATIC) {
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 } : {} });
284
- l.listening || await new Promise((u) => l.once("listening", u));
285
- const d = l.address();
286
- if (d && typeof d == "object") {
287
- const h = d.address === "::" || d.address === "0.0.0.0" ? "0.0.0.0 (all interfaces)" : d.address;
288
- console.log(`Server running on ${h}:${d.port}`);
285
+ const { serve: n } = await import("@hono/node-server"), s = n({ fetch: o.fetch, port: a, ...r ? { hostname: r } : {} });
286
+ s.listening || await new Promise((i) => s.once("listening", i));
287
+ const c = s.address();
288
+ if (c && typeof c == "object") {
289
+ const l = c.address === "::" || c.address === "0.0.0.0" ? "0.0.0.0 (all interfaces)" : c.address;
290
+ console.log(`Server running on ${l}:${c.port}`);
289
291
  } else
290
292
  console.log(`Server running on port ${a}`);
291
- await S(o, l), b(l), l.once("close", () => {
292
- x(l);
293
+ await S(o, s), C(s), s.once("close", () => {
294
+ V(s);
293
295
  });
294
296
  }
295
297
  return o;
296
298
  };
297
299
  export {
298
- se as addRoutes,
299
- x as clearActiveServer,
300
- F as createApp,
301
- F as default,
302
- le as emit,
303
- b as flushServerCallbacks,
304
- O as inspectChannels,
305
- G as jsonForScript,
306
- re as onServer,
307
- de as registerChannels,
300
+ ae as addRoutes,
301
+ V as clearActiveServer,
302
+ U as createApp,
303
+ U as default,
304
+ de as emit,
305
+ C as flushServerCallbacks,
306
+ I as inspectChannels,
307
+ x as jsonForScript,
308
+ se as onServer,
309
+ ue as registerChannels,
308
310
  P as serverDataStorage,
309
- ae as startServer
311
+ ie as startServer
310
312
  };