@mauroandre/velojs 0.0.49 → 0.0.51

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.
@@ -71,6 +71,45 @@ export default defineConfig({
71
71
 
72
72
  In dev, `velojs dev --port 5000` still overrides everything (it's passed straight to Vite).
73
73
 
74
+ ## Choosing the bind interface (hostname)
75
+
76
+ By default `velojs start` binds to **all interfaces** (`::`) — the norm for Node servers and what containers and cloud platforms expect (they route traffic through the network interface; loopback-only would make the container unreachable). To change it, in order of precedence:
77
+
78
+ 1. The `HOST` environment variable.
79
+ 2. The `hostname` field in `defineConfig`.
80
+ 3. The Node default (all interfaces).
81
+
82
+ ### Secure bind for local/sensitive apps
83
+
84
+ If your app is **local and single-user** — a cockpit with a terminal, file access, real user data — it must listen on loopback only. An all-interfaces bind exposes that surface to the whole network without any error: the developer finds out by scanning, not by the app telling them.
85
+
86
+ ```bash
87
+ # Deploy do app local: bind em loopback, sempre
88
+ HOST=127.0.0.1 velojs start
89
+ ```
90
+
91
+ Because "set HOST" is easy to forget, sensitive apps should also **fail fast if the bind is wrong** — check the real address after the server starts, via `onServer`:
92
+
93
+ ```typescript
94
+ // app/server.tsx
95
+ import { onServer } from "@mauroandre/velojs/server";
96
+
97
+ onServer((server) => {
98
+ const addr = server.address();
99
+ const loopback = ["127.0.0.1", "::1", "::ffff:127.0.0.1"];
100
+ if (!addr || typeof addr !== "object" || !loopback.includes(addr.address)) {
101
+ console.error(
102
+ `[${process.env.APP_NAME ?? "app"}][CRIT] ` +
103
+ `server bound on ${addr && typeof addr === "object" ? addr.address : "?"} — outside loopback. ` +
104
+ `This app runs commands on this machine: it may only listen on 127.0.0.1/::1. Aborting.`
105
+ );
106
+ process.exit(1);
107
+ }
108
+ });
109
+ ```
110
+
111
+ This pattern caught a real exposure in production: the server had bound to `::` and the guard aborted instead of serving. When deploying the same app to a VPS later, the bind changes **consciously** to `HOST=0.0.0.0` — together with authentication and its own security spec, not by accident.
112
+
74
113
  ## Static assets on CDN
75
114
 
76
115
  If you want to serve static assets (JS, CSS, images) from a CDN or S3 bucket instead of the Node.js server, set the `STATIC_BASE_URL` environment variable:
@@ -7,17 +7,36 @@ description: "The `veloPlugin` build pipeline: the 9 AST transforms that inject
7
7
 
8
8
  The `veloPlugin()` is the core of VeloJS. It's a single function that returns 6 Vite plugins working together to handle routing, SSR, code transforms, and more.
9
9
 
10
- ## The 6 plugins
10
+ ## The 7 plugins
11
11
 
12
12
  | Plugin | What it does |
13
13
  |--------|-------------|
14
14
  | `velo:config` | Sets up build config for client/server modes, Preact aliases, and environment defines |
15
15
  | `velo:transform` | Performs AST transforms on your code (the most important plugin) |
16
16
  | `velo:static-url` | Rewrites CSS `url(/path)` to use `STATIC_BASE_URL` in production builds |
17
+ | `velo:graph` | Generates `.velojs/graph.json` (route tree + dependency graph) on build and dev |
17
18
  | `@preact/preset-vite` | Adds Preact JSX support |
18
19
  | `@hono/vite-dev-server` | Runs the SSR dev server |
19
20
  | `velo:ws-bridge` | Exposes Vite's HTTP server for WebSocket handlers during development |
20
21
 
22
+ ## Dev server: what is served × intercepted
23
+
24
+ During `velojs dev`, every request that is **not** excluded falls through to the SSR app — if no route matches, it gets the app's 404/fallback HTML. Excluded (delegated to Vite, which serves and transforms them as modules): `.js`, `.mjs`, `.ts`, `.tsx`, `.jsx`, `.css`, `.md`, `.svelte`, `.vue`, `/@vite/*`, `/node_modules/*`, `/static/*`, and `?t=` cache-busted requests.
25
+
26
+ Project `.mjs` files are covered — relevant for build-time generators (Panda CSS, vanilla-extract) that emit ESM artifacts such as `styled-system/`.
27
+
28
+ Need more patterns? Declare them in the plugin config — they are **composed with** the defaults, not a replacement:
29
+
30
+ ```typescript
31
+ export default defineConfig({
32
+ plugins: [
33
+ veloPlugin({
34
+ devServerExclude: ["/generated/**"],
35
+ }),
36
+ ],
37
+ });
38
+ ```
39
+
21
40
  ## AST Transformations
22
41
 
23
42
  The `velo:transform` plugin uses Babel to modify your code at build time. It applies 9 transformations to `.ts`/`.tsx` files inside your `appDirectory` (a file elsewhere, or a `.js`/`.jsx` one, is not transformed at all):
package/dist/config.d.ts CHANGED
@@ -25,5 +25,18 @@ export interface VeloConfig {
25
25
  * @default 3000
26
26
  */
27
27
  port?: number;
28
+ /**
29
+ * Interface de bind do servidor de produção. A env `HOST` tem precedência.
30
+ * Default do Node: todas as interfaces (o que Docker/cloud esperam).
31
+ * Apps locais/sensíveis devem declarar "127.0.0.1".
32
+ */
33
+ hostname?: string;
34
+ /**
35
+ * Padrões adicionais de URL que o dev server deve delegar ao Vite em vez
36
+ * de interceptar como página (ex.: artefatos de geradores build-time como
37
+ * Panda CSS — "/styled-system/**"). Compostos com os defaults do
38
+ * @hono/vite-dev-server, não os substituem.
39
+ */
40
+ devServerExclude?: (string | RegExp)[];
28
41
  }
29
42
  export declare function defineConfig(config: VeloConfig): VeloConfig;
package/dist/server.d.ts CHANGED
@@ -7,6 +7,12 @@ export declare function onServer(fn: ServerCallback): void;
7
7
  export interface StartServerOptions {
8
8
  routes: AppRoutes;
9
9
  port?: number;
10
+ /**
11
+ * Hostname/interface to bind. Precedence: HOST env > this option > Node
12
+ * default (all interfaces — the ecosystem norm for containers/proxies).
13
+ * Local/sensitive apps should bind "127.0.0.1".
14
+ */
15
+ hostname?: string;
10
16
  }
11
17
  export declare function addRoutes(fn: (app: Hono) => void | Promise<void>): void;
12
18
  /**
package/dist/server.js CHANGED
@@ -1,94 +1,94 @@
1
- import { jsx as _ } from "preact/jsx-runtime";
2
- import { Hono as j } from "hono";
3
- import { logger as E } from "hono/logger";
4
- import { trimTrailingSlash as T } from "hono/trailing-slash";
1
+ import { jsx as v } 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
5
  import { render as C } from "preact-render-to-string";
6
- import { Router as k } from "wouter-preact";
7
- import { AsyncLocalStorage as A } from "node:async_hooks";
8
- import { getAppContext as w } from "./app-context.js";
9
- import { flushPendingStreamRoutes as D, registerStreamHandler as $ } from "./events.js";
10
- import { registerSocketRoutes as I, injectWebSocketServer as S } from "./sockets.js";
11
- const P = new A();
6
+ import { Router as $ } from "wouter-preact";
7
+ import { AsyncLocalStorage as k } from "node:async_hooks";
8
+ import { getAppContext as _ } from "./app-context.js";
9
+ import { flushPendingStreamRoutes as A, registerStreamHandler as D } from "./events.js";
10
+ import { registerSocketRoutes as O, injectWebSocketServer as S } from "./sockets.js";
11
+ const P = new k();
12
12
  globalThis.__veloServerData = P;
13
- let v = null;
13
+ let g = null;
14
14
  function Z(e) {
15
- if (v) {
16
- e(v);
15
+ if (g) {
16
+ e(g);
17
17
  return;
18
18
  }
19
- w().serverCallbacks.push(e);
19
+ _().serverCallbacks.push(e);
20
20
  }
21
21
  function b(e) {
22
- v = e;
23
- const t = w();
22
+ g = e;
23
+ const t = _();
24
24
  for (const s of t.serverCallbacks) s(e);
25
25
  t.serverCallbacks.length = 0;
26
26
  }
27
27
  function ee(e) {
28
- w().pendingRoutes.push(e);
28
+ _().pendingRoutes.push(e);
29
29
  }
30
- const N = (e) => JSON.stringify(e).replace(/</g, "\\u003c").replace(/>/g, "\\u003e").replace(/\u2028/g, "\\u2028").replace(/\u2029/g, "\\u2029"), O = (e, t, s, r) => {
31
- if (r && r !== 200 && e.status(r), e.req.query("_data") === "1") {
32
- const c = globalThis.__veloBuildHash || void 0, i = s ? { ...s, __buildHash: c } : { __buildHash: c };
33
- return e.json(i);
30
+ const I = (e) => JSON.stringify(e).replace(/</g, "\\u003c").replace(/>/g, "\\u003e").replace(/\u2028/g, "\\u2028").replace(/\u2029/g, "\\u2029"), N = (e, t, s, a) => {
31
+ if (a && a !== 200 && e.status(a), e.req.query("_data") === "1") {
32
+ const c = globalThis.__veloBuildHash || void 0, r = s ? { ...s, __buildHash: c } : { __buildHash: c };
33
+ return e.json(r);
34
34
  }
35
35
  const o = e.req.path, n = P.run(
36
36
  s ?? {},
37
- () => C(/* @__PURE__ */ _(k, { ssrPath: o, children: t }))
37
+ () => C(/* @__PURE__ */ v($, { ssrPath: o, children: t }))
38
38
  );
39
39
  if (e.header("Cache-Control", "no-cache"), !s)
40
40
  return e.html(n);
41
- const a = `<script>window.__PAGE_DATA__=${N(s)}<\/script>`;
42
- return e.html(n.replace("</head>", () => `${a}</head>`));
43
- }, G = async (e, t) => {
44
- const s = t.req.param(), r = t.req.query(), o = { params: s, query: r, c: t }, n = await Promise.all(
45
- e.map(async (i) => {
46
- if (!i.loader) return null;
47
- const l = await i.loader(o), d = i.metadata?.moduleId;
48
- return d ? { moduleId: d, loaderData: l } : null;
41
+ const i = `<script>window.__PAGE_DATA__=${I(s)}<\/script>`;
42
+ return e.html(n.replace("</head>", () => `${i}</head>`));
43
+ }, H = async (e, t) => {
44
+ const s = t.req.param(), a = t.req.query(), o = { params: s, query: a, c: t }, n = await Promise.all(
45
+ e.map(async (r) => {
46
+ if (!r.loader) return null;
47
+ const f = await r.loader(o), l = r.metadata?.moduleId;
48
+ return l ? { moduleId: l, loaderData: f } : null;
49
49
  })
50
50
  );
51
- let a;
52
- for (const i of n)
53
- if (i && i.loaderData instanceof Response) {
54
- a = i.loaderData;
51
+ let i;
52
+ for (const r of n)
53
+ if (r && r.loaderData instanceof Response) {
54
+ i = r.loaderData;
55
55
  break;
56
56
  }
57
57
  const c = {
58
58
  __params: s,
59
- __query: r,
59
+ __query: a,
60
60
  __pathname: t.req.path
61
61
  };
62
- for (const i of n)
63
- i && !(i.loaderData instanceof Response) && (c[i.moduleId] = i.loaderData);
62
+ for (const r of n)
63
+ r && !(r.loaderData instanceof Response) && (c[r.moduleId] = r.loaderData);
64
64
  return {
65
- components: e.map((i) => i.Component),
65
+ components: e.map((r) => r.Component),
66
66
  data: c,
67
- shortCircuit: a
67
+ shortCircuit: i
68
68
  };
69
- }, H = (e) => {
69
+ }, G = (e) => {
70
70
  if (e.length === 0) return null;
71
71
  const t = e.filter(Boolean);
72
72
  if (t.length === 0) return null;
73
73
  if (t.length === 1) {
74
74
  const o = t[0];
75
- return /* @__PURE__ */ _(o, {});
75
+ return /* @__PURE__ */ v(o, {});
76
76
  }
77
77
  const s = t[t.length - 1];
78
- return t.slice(0, -1).reduceRight((o, n) => /* @__PURE__ */ _(n, { children: o }), /* @__PURE__ */ _(s, {}));
79
- }, y = (e, t, s = [], r = []) => {
78
+ return t.slice(0, -1).reduceRight((o, n) => /* @__PURE__ */ v(n, { children: o }), /* @__PURE__ */ v(s, {}));
79
+ }, y = (e, t, s = [], a = []) => {
80
80
  for (const o of t) {
81
81
  if (o.handler && !o.module) {
82
82
  o.children && y(
83
83
  e,
84
84
  o.children,
85
85
  s,
86
- [...r, ...o.middlewares || []]
86
+ [...a, ...o.middlewares || []]
87
87
  );
88
88
  continue;
89
89
  }
90
- const n = o.module ? [...s, o.module] : s, a = [
91
- ...r,
90
+ const n = o.module ? [...s, o.module] : s, i = [
91
+ ...a,
92
92
  ...o.middlewares || []
93
93
  ];
94
94
  if (o.children)
@@ -96,104 +96,104 @@ const N = (e) => JSON.stringify(e).replace(/</g, "\\u003c").replace(/>/g, "\\u00
96
96
  e,
97
97
  o.children,
98
98
  n,
99
- a
99
+ i
100
100
  );
101
101
  else if (o.module) {
102
- const c = o.path === "*", i = o.statusCode ?? (c ? 404 : void 0), l = o.module.metadata?.fullPath;
103
- if (!l && !c) {
102
+ const c = o.path === "*", r = o.statusCode ?? (c ? 404 : void 0), f = o.module.metadata?.fullPath;
103
+ if (!f && !c) {
104
104
  console.warn(
105
105
  `Module ${o.module.metadata?.moduleId} has no fullPath`
106
106
  );
107
107
  continue;
108
108
  }
109
- const d = async (h) => {
110
- const { components: u, data: m, shortCircuit: f } = await G(n, h);
111
- if (f) {
112
- const g = f.headers.get("Location");
113
- return h.req.query("_data") === "1" && g && f.status >= 300 && f.status < 400 ? h.json({ __redirect: g }) : f;
109
+ const l = async (d) => {
110
+ const { components: u, data: h, shortCircuit: m } = await H(n, d);
111
+ if (m) {
112
+ const w = m.headers.get("Location");
113
+ return d.req.query("_data") === "1" && w && m.status >= 300 && m.status < 400 ? d.json({ __redirect: w }) : m;
114
114
  }
115
- const p = H(u);
116
- return O(h, p, m, i);
115
+ const p = G(u);
116
+ return N(d, p, h, r);
117
117
  };
118
- c ? e.notFound(d) : a.length > 0 ? e.on(["GET"], [l], ...a, d) : e.on(["GET"], [l], d);
118
+ c ? e.notFound(l) : i.length > 0 ? e.on(["GET"], [f], ...i, l) : e.on(["GET"], [f], l);
119
119
  } else
120
120
  continue;
121
121
  }
122
122
  }, q = (e, t, s = []) => {
123
- for (const r of t) {
124
- const o = r.module?.metadata?.moduleId, n = [
123
+ for (const a of t) {
124
+ const o = a.module?.metadata?.moduleId, n = [
125
125
  ...s,
126
- ...r.middlewares || []
126
+ ...a.middlewares || []
127
127
  ];
128
- if (r.module && o) {
129
- const a = Object.keys(r.module).filter(
128
+ if (a.module && o) {
129
+ const i = Object.keys(a.module).filter(
130
130
  (c) => c.startsWith("action_")
131
131
  );
132
- for (const c of a) {
133
- const i = c.replace("action_", ""), l = r.module[c];
134
- if (typeof l == "function") {
135
- const d = `/_action/${o}/${i}`, h = async (u) => {
136
- let m = {};
132
+ for (const c of i) {
133
+ const r = c.replace("action_", ""), f = a.module[c];
134
+ if (typeof f == "function") {
135
+ const l = `/_action/${o}/${r}`, d = async (u) => {
136
+ let h = {};
137
137
  try {
138
- m = await u.req.json();
138
+ h = await u.req.json();
139
139
  } catch {
140
140
  }
141
- const f = {
142
- body: m,
141
+ const m = {
142
+ body: h,
143
143
  params: u.req.param(),
144
144
  query: u.req.query(),
145
145
  c: u
146
146
  };
147
147
  try {
148
- const p = await l(f);
148
+ const p = await f(m);
149
149
  return u.json(p ?? { ok: !0 });
150
150
  } catch (p) {
151
- const g = p instanceof Error ? p.message : "Action failed";
152
- return u.json({ error: g }, 500);
151
+ const w = p instanceof Error ? p.message : "Action failed";
152
+ return u.json({ error: w }, 500);
153
153
  }
154
154
  };
155
155
  n.length > 0 ? e.on(
156
156
  ["POST"],
157
- [d],
157
+ [l],
158
158
  ...n,
159
- h
160
- ) : e.on(["POST"], [d], h);
159
+ d
160
+ ) : e.on(["POST"], [l], d);
161
161
  }
162
162
  }
163
163
  }
164
- r.children && q(e, r.children, n);
164
+ a.children && q(e, a.children, n);
165
165
  }
166
166
  }, x = async (e, t, s = []) => {
167
- const r = (o, n) => {
168
- for (const a of o) {
169
- const c = a.module?.metadata?.moduleId, i = [
167
+ const a = (o, n) => {
168
+ for (const i of o) {
169
+ const c = i.module?.metadata?.moduleId, r = [
170
170
  ...n,
171
- ...a.middlewares || []
171
+ ...i.middlewares || []
172
172
  ];
173
- if (a.module && c) {
174
- const l = Object.keys(a.module).filter(
175
- (d) => d.startsWith("stream_")
173
+ if (i.module && c) {
174
+ const f = Object.keys(i.module).filter(
175
+ (l) => l.startsWith("stream_")
176
176
  );
177
- for (const d of l) {
178
- const h = d.replace("stream_", ""), u = a.module[d];
177
+ for (const l of f) {
178
+ const d = l.replace("stream_", ""), u = i.module[l];
179
179
  if (u?.__isVeloEventStream) {
180
- const m = `/_event/${c}/${h}`;
181
- u.__path = m, $(
180
+ const h = `/_event/${c}/${d}`;
181
+ u.__path = h, D(
182
182
  e,
183
- m,
183
+ h,
184
184
  u,
185
- i
185
+ r
186
186
  );
187
187
  }
188
188
  }
189
189
  }
190
- a.children && r(a.children, i);
190
+ i.children && a(i.children, r);
191
191
  }
192
192
  };
193
- r(t, s);
193
+ a(t, s);
194
194
  }, V = (e, t) => t ? t.startsWith("/") ? e + t : e ? e + "/" + t : "/" + t : e || "", W = (e) => {
195
- const t = /* @__PURE__ */ new Set(), s = (r) => {
196
- for (const o of r) {
195
+ const t = /* @__PURE__ */ new Set(), s = (a) => {
196
+ for (const o of a) {
197
197
  if (o.module && !o.children) {
198
198
  const n = o.module.metadata?.fullPath;
199
199
  n && t.add(n);
@@ -202,68 +202,77 @@ const N = (e) => JSON.stringify(e).replace(/</g, "\\u003c").replace(/>/g, "\\u00
202
202
  }
203
203
  };
204
204
  return s(e), t;
205
- }, R = (e, t, s, r = "", o = []) => {
205
+ }, j = (e, t, s, a = "", o = []) => {
206
206
  for (const n of t) {
207
- const a = V(r, n.path), c = [
207
+ const i = V(a, n.path), c = [
208
208
  ...o,
209
209
  ...n.middlewares || []
210
- ], i = !!n.handler, l = !!n.method;
211
- if (i && !l ? console.warn(
212
- `[velojs] invalid route at "${a || "/"}" — "handler" set without "method"; endpoint skipped`
213
- ) : l && !i ? console.warn(
214
- `[velojs] invalid route at "${a || "/"}" — "method" set without "handler"; endpoint skipped`
215
- ) : i && n.module ? console.warn(
216
- `[velojs] ambiguous route at "${a || "/"}" — both "module" and "handler" set; endpoint ignored, page kept`
217
- ) : i && n.isRoot && console.warn(
218
- `[velojs] "isRoot" has no effect on endpoint at "${a || "/"}"; ignored`
219
- ), i && l && !n.module) {
220
- const h = n.method;
221
- h === "GET" && s.has(a) && console.warn(
222
- `[velojs] path "${a}" has both a page GET and an endpoint GET; the page wins and the endpoint is unreachable. Consider renaming one.`
210
+ ], r = !!n.handler, f = !!n.method;
211
+ if (r && !f ? console.warn(
212
+ `[velojs] invalid route at "${i || "/"}" — "handler" set without "method"; endpoint skipped`
213
+ ) : f && !r ? console.warn(
214
+ `[velojs] invalid route at "${i || "/"}" — "method" set without "handler"; endpoint skipped`
215
+ ) : r && n.module ? console.warn(
216
+ `[velojs] ambiguous route at "${i || "/"}" — both "module" and "handler" set; endpoint ignored, page kept`
217
+ ) : r && n.isRoot && console.warn(
218
+ `[velojs] "isRoot" has no effect on endpoint at "${i || "/"}"; ignored`
219
+ ), r && f && !n.module) {
220
+ const d = n.method;
221
+ d === "GET" && s.has(i) && console.warn(
222
+ `[velojs] path "${i}" has both a page GET and an endpoint GET; the page wins and the endpoint is unreachable. Consider renaming one.`
223
223
  );
224
- const u = n.handler, m = async (f) => await u({
225
- c: f,
226
- params: f.req.param(),
227
- query: f.req.query()
224
+ const u = n.handler, h = async (m) => await u({
225
+ c: m,
226
+ params: m.req.param(),
227
+ query: m.req.query()
228
228
  });
229
- c.length > 0 ? e.on([h], [a], ...c, m) : e.on([h], [a], m);
229
+ c.length > 0 ? e.on([d], [i], ...c, h) : e.on([d], [i], h);
230
230
  }
231
- n.children && R(
231
+ n.children && j(
232
232
  e,
233
233
  n.children,
234
234
  s,
235
- a,
235
+ i,
236
236
  c
237
237
  );
238
238
  }
239
239
  }, K = async (e) => {
240
- const t = new j();
241
- t.use(T()), process.env.NODE_ENV !== "production" && t.use("*", E());
242
- const r = w().pendingRoutes.splice(0);
243
- for (const n of r)
240
+ const t = new R();
241
+ t.use(E()), process.env.NODE_ENV !== "production" && t.use("*", T());
242
+ const a = _().pendingRoutes.splice(0);
243
+ for (const n of a)
244
244
  await n(t);
245
245
  y(t, e), q(t, e), await x(t, e);
246
246
  const o = W(e);
247
- if (R(t, e, o), await I(t, e), D(t), process.env.NODE_ENV !== "production" && !v) {
247
+ if (j(t, e, o), await O(t, e), A(t), process.env.NODE_ENV !== "production" && !g) {
248
248
  const n = globalThis.__veloDevServer;
249
249
  n && (b(n), await S(t, n));
250
250
  }
251
251
  return t;
252
252
  }, te = async (e) => {
253
- const { routes: t } = e, s = Number(process.env.PORT) || e.port || 3e3, r = await K(t);
253
+ const { routes: t } = e, s = Number(process.env.PORT) || e.port || 3e3, a = process.env.HOST || e.hostname || void 0, o = await K(t);
254
254
  if (process.env.NODE_ENV === "production" && !process.env.VELO_STATIC) {
255
- const { serve: o } = await import("@hono/node-server"), { serveStatic: n } = await import("@hono/node-server/serve-static"), { join: a } = await import("node:path"), c = a(process.cwd(), "dist/client");
256
- (process.env.STATIC_BASE_URL || "").startsWith("http") || r.use("/*", n({ root: c })), console.log(`Server running on http://localhost:${s}`);
257
- const l = o({ fetch: r.fetch, port: s });
258
- await S(r, l), b(l);
255
+ 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");
256
+ (process.env.STATIC_BASE_URL || "").startsWith("http") || o.use("/*", i({ root: r }));
257
+ const l = n({ fetch: o.fetch, port: s, ...a ? { hostname: a } : {} });
258
+ l.listening || await new Promise((u) => l.once("listening", u));
259
+ const d = l.address();
260
+ if (d && typeof d == "object") {
261
+ const h = d.address === "::" || d.address === "0.0.0.0" ? "0.0.0.0 (all interfaces)" : d.address;
262
+ console.log(`Server running on ${h}:${d.port}`);
263
+ } else
264
+ console.log(`Server running on port ${s}`);
265
+ await S(o, l), b(l), l.once("close", () => {
266
+ g === l && (g = null);
267
+ });
259
268
  }
260
- return r;
269
+ return o;
261
270
  };
262
271
  export {
263
272
  ee as addRoutes,
264
273
  K as createApp,
265
274
  K as default,
266
- N as jsonForScript,
275
+ I as jsonForScript,
267
276
  Z as onServer,
268
277
  P as serverDataStorage,
269
278
  te as startServer
package/dist/vite.d.ts CHANGED
@@ -66,4 +66,14 @@ export declare function buildFullPathMap(code: string): Map<string, PathInfo>;
66
66
  * Percorre recursivamente a árvore de rotas e coleta moduleName → { fullPath, path }
67
67
  */
68
68
  export declare function collectFullPaths(elements: (t.Expression | t.SpreadElement | null)[], parentPath: string, result: Map<string, PathInfo>): void;
69
+ /**
70
+ * @hono/vite-dev-server treats `exclude` as all-or-nothing: passing one
71
+ * replaces the defaults entirely. We compose instead — the upstream defaults
72
+ * (imported, so they track the installed version) plus `.mjs`, which upstream
73
+ * misses: build-time generators (Panda CSS, vanilla-extract) emit ESM
74
+ * artifacts inside the project, and a project `.mjs` that falls through to
75
+ * the SSR app comes back as fallback HTML/404 — the browser's ESM import
76
+ * dies silently.
77
+ */
78
+ export declare function devServerExcludeFor(veloConfig: VeloConfig): (string | RegExp)[];
69
79
  export declare function veloPlugin(config?: VeloConfig): PluginOption[];
package/dist/vite.js CHANGED
@@ -1,15 +1,15 @@
1
1
  import d from "node:path";
2
2
  import g from "node:fs";
3
3
  import R from "@preact/preset-vite";
4
- import $ from "@hono/vite-dev-server";
5
- import { parse as h } from "@babel/parser";
4
+ import $, { defaultOptions as J } from "@hono/vite-dev-server";
5
+ import { parse as _ } from "@babel/parser";
6
6
  import j from "@babel/traverse";
7
7
  import L from "@babel/generator";
8
8
  import * as e from "@babel/types";
9
9
  import { buildGraph as U } from "./graph.js";
10
- const m = typeof j == "function" ? j : j.default, _ = typeof L == "function" ? L : L.default;
11
- function W(p, o, n, i) {
12
- const l = h(p, {
10
+ const m = typeof j == "function" ? j : j.default, h = typeof L == "function" ? L : L.default;
11
+ function W(u, o, n, i) {
12
+ const l = _(u, {
13
13
  sourceType: "module",
14
14
  plugins: ["typescript", "jsx"]
15
15
  });
@@ -70,10 +70,10 @@ function W(p, o, n, i) {
70
70
  );
71
71
  l.program.body.unshift(c);
72
72
  }
73
- return _(l, { retainLines: !0 }).code;
73
+ return h(l, { retainLines: !0 }).code;
74
74
  }
75
- function J(p, o) {
76
- const n = h(p, {
75
+ function M(u, o) {
76
+ const n = _(u, {
77
77
  sourceType: "module",
78
78
  plugins: ["typescript", "jsx"]
79
79
  });
@@ -81,13 +81,13 @@ function J(p, o) {
81
81
  CallExpression(l) {
82
82
  const t = l.node.callee, a = e.isIdentifier(t, { name: "Loader" }) || e.isTSInstantiationExpression(t) && e.isIdentifier(t.expression, { name: "Loader" }), s = e.isIdentifier(t, { name: "useLoader" }) || e.isTSInstantiationExpression(t) && e.isIdentifier(t.expression, { name: "useLoader" });
83
83
  if (!a && !s) return;
84
- const c = l.node.arguments, r = e.stringLiteral(o), u = c[0];
85
- e.isStringLiteral(u) && u.value.includes("/") || (l.node.arguments = [r, ...c]);
84
+ const c = l.node.arguments, r = e.stringLiteral(o), p = c[0];
85
+ e.isStringLiteral(p) && p.value.includes("/") || (l.node.arguments = [r, ...c]);
86
86
  }
87
- }), _(n, { retainLines: !0 }).code;
87
+ }), h(n, { retainLines: !0 }).code;
88
88
  }
89
- function B(p, o) {
90
- const n = h(p, {
89
+ function B(u, o) {
90
+ const n = _(u, {
91
91
  sourceType: "module",
92
92
  plugins: ["typescript", "jsx"]
93
93
  });
@@ -101,13 +101,13 @@ function B(p, o) {
101
101
  if (!s.startsWith("action_")) return;
102
102
  const c = s.replace("action_", ""), r = a.init;
103
103
  if (!e.isArrowFunctionExpression(r) || !r.async) return;
104
- const u = r.params, f = M(o, c, u);
105
- r.body = e.blockStatement([e.returnStatement(f)]), H(r, u);
104
+ const p = r.params, f = H(o, c, p);
105
+ r.body = e.blockStatement([e.returnStatement(f)]), G(r, p);
106
106
  }
107
- }), _(n, { retainLines: !0 }).code;
107
+ }), h(n, { retainLines: !0 }).code;
108
108
  }
109
- function M(p, o, n) {
110
- const i = `/_action/${p}/${o}`;
109
+ function H(u, o, n) {
110
+ const i = `/_action/${u}/${o}`;
111
111
  return n.length === 0 ? e.callExpression(
112
112
  e.memberExpression(
113
113
  e.callExpression(e.identifier("fetch"), [
@@ -176,7 +176,7 @@ function M(p, o, n) {
176
176
  ]
177
177
  );
178
178
  }
179
- function H(p, o) {
179
+ function G(u, o) {
180
180
  if (o.length === 0) return;
181
181
  const n = o[0];
182
182
  if (e.isObjectPattern(n)) {
@@ -199,11 +199,11 @@ function H(p, o) {
199
199
  e.tsTypeAnnotation(i)
200
200
  )
201
201
  ])
202
- )), p.params = [t];
202
+ )), u.params = [t];
203
203
  }
204
204
  }
205
- function G(p, o) {
206
- const n = h(p, {
205
+ function z(u, o) {
206
+ const n = _(u, {
207
207
  sourceType: "module",
208
208
  plugins: ["typescript", "jsx"]
209
209
  });
@@ -227,10 +227,10 @@ function G(p, o) {
227
227
  )
228
228
  ]), a.id.typeAnnotation = null;
229
229
  }
230
- }), _(n, { retainLines: !0 }).code;
230
+ }), h(n, { retainLines: !0 }).code;
231
231
  }
232
- function z(p, o) {
233
- const n = h(p, {
232
+ function Y(u, o) {
233
+ const n = _(u, {
234
234
  sourceType: "module",
235
235
  plugins: ["typescript", "jsx"]
236
236
  });
@@ -254,10 +254,10 @@ function z(p, o) {
254
254
  )
255
255
  ]), a.id.typeAnnotation = null;
256
256
  }
257
- }), _(n, { retainLines: !0 }).code;
257
+ }), h(n, { retainLines: !0 }).code;
258
258
  }
259
- function Y(p) {
260
- const o = h(p, {
259
+ function X(u) {
260
+ const o = _(u, {
261
261
  sourceType: "module",
262
262
  plugins: ["typescript", "jsx"]
263
263
  });
@@ -268,10 +268,10 @@ function Y(p) {
268
268
  const t = l.declarations[0];
269
269
  !t || !e.isIdentifier(t.id) || t.id.name === "loader" && i.remove();
270
270
  }
271
- }), _(o, { retainLines: !0 }).code;
271
+ }), h(o, { retainLines: !0 }).code;
272
272
  }
273
- function X(p) {
274
- const o = h(p, {
273
+ function q(u) {
274
+ const o = _(u, {
275
275
  sourceType: "module",
276
276
  plugins: ["typescript", "jsx"]
277
277
  }), n = /* @__PURE__ */ new Set();
@@ -284,10 +284,10 @@ function X(p) {
284
284
  const s = a.filter((c) => n.has(c.local.name));
285
285
  s.length !== a.length && (i = !0, s.length === 0 ? t.remove() : t.node.specifiers = s);
286
286
  }
287
- }), i ? _(o, { retainLines: !0 }).code : p;
287
+ }), i ? h(o, { retainLines: !0 }).code : u;
288
288
  }
289
- function q(p) {
290
- const o = h(p, {
289
+ function K(u) {
290
+ const o = _(u, {
291
291
  sourceType: "module",
292
292
  plugins: ["typescript", "jsx"]
293
293
  }), n = [];
@@ -295,7 +295,7 @@ function q(p) {
295
295
  ObjectProperty(s) {
296
296
  e.isIdentifier(s.node.key, { name: "middlewares" }) && (n.push(s.node.value), s.remove());
297
297
  }
298
- }), n.length === 0) return p;
298
+ }), n.length === 0) return u;
299
299
  const i = /* @__PURE__ */ new Set();
300
300
  for (const s of n)
301
301
  x(s, i);
@@ -306,12 +306,12 @@ function q(p) {
306
306
  l.has(s) || t.add(s);
307
307
  return t.size > 0 && m(o, {
308
308
  ImportDeclaration(s) {
309
- const c = s.node.specifiers, r = c.filter((u) => !t.has(u.local.name));
309
+ const c = s.node.specifiers, r = c.filter((p) => !t.has(p.local.name));
310
310
  r.length === 0 ? s.remove() : r.length !== c.length && (s.node.specifiers = r);
311
311
  }
312
- }), _(o, { retainLines: !0 }).code;
312
+ }), h(o, { retainLines: !0 }).code;
313
313
  }
314
- function x(p, o) {
314
+ function x(u, o) {
315
315
  const n = (i) => {
316
316
  if (!(!i || typeof i != "object")) {
317
317
  if (Array.isArray(i)) {
@@ -339,43 +339,43 @@ function x(p, o) {
339
339
  l === "loc" || l === "start" || l === "end" || l === "leadingComments" || l === "trailingComments" || l === "innerComments" || n(i[l]);
340
340
  }
341
341
  };
342
- n(p);
342
+ n(u);
343
343
  }
344
- function K(p) {
345
- for (const o of p.properties)
344
+ function Q(u) {
345
+ for (const o of u.properties)
346
346
  if (e.isObjectProperty(o) && e.isIdentifier(o.key) && o.key.name === "handler")
347
347
  return !0;
348
348
  return !1;
349
349
  }
350
- function Q(p) {
351
- for (const o of p.properties)
350
+ function Z(u) {
351
+ for (const o of u.properties)
352
352
  if (e.isObjectProperty(o) && e.isIdentifier(o.key) && o.key.name === "children" && e.isArrayExpression(o.value))
353
353
  return o.value;
354
354
  return null;
355
355
  }
356
- function Z(p) {
357
- const o = h(p, {
356
+ function ee(u) {
357
+ const o = _(u, {
358
358
  sourceType: "module",
359
359
  plugins: ["typescript", "jsx"]
360
360
  }), n = [], i = (c) => {
361
361
  for (let r = c.elements.length - 1; r >= 0; r--) {
362
- const u = c.elements[r];
363
- if (!e.isObjectExpression(u)) continue;
364
- if (K(u)) {
365
- n.push(u), c.elements.splice(r, 1);
362
+ const p = c.elements[r];
363
+ if (!e.isObjectExpression(p)) continue;
364
+ if (Q(p)) {
365
+ n.push(p), c.elements.splice(r, 1);
366
366
  continue;
367
367
  }
368
- const f = Q(u);
368
+ const f = Z(p);
369
369
  f && i(f);
370
370
  }
371
371
  };
372
372
  if (m(o, {
373
373
  ExportDefaultDeclaration(c) {
374
374
  const r = c.node.declaration;
375
- let u = null;
376
- e.isArrayExpression(r) ? u = r : (e.isTSSatisfiesExpression(r) && e.isArrayExpression(r.expression) || e.isTSAsExpression(r) && e.isArrayExpression(r.expression)) && (u = r.expression), u && i(u);
375
+ let p = null;
376
+ e.isArrayExpression(r) ? p = r : (e.isTSSatisfiesExpression(r) && e.isArrayExpression(r.expression) || e.isTSAsExpression(r) && e.isArrayExpression(r.expression)) && (p = r.expression), p && i(p);
377
377
  }
378
- }), n.length === 0) return p;
378
+ }), n.length === 0) return u;
379
379
  const l = /* @__PURE__ */ new Set();
380
380
  for (const c of n)
381
381
  x(c, l);
@@ -386,13 +386,13 @@ function Z(p) {
386
386
  t.has(c) || a.add(c);
387
387
  return a.size > 0 && m(o, {
388
388
  ImportDeclaration(c) {
389
- const r = c.node.specifiers, u = r.filter((f) => !a.has(f.local.name));
390
- u.length === 0 ? c.remove() : u.length !== r.length && (c.node.specifiers = u);
389
+ const r = c.node.specifiers, p = r.filter((f) => !a.has(f.local.name));
390
+ p.length === 0 ? c.remove() : p.length !== r.length && (c.node.specifiers = p);
391
391
  }
392
- }), _(o, { retainLines: !0 }).code;
392
+ }), h(o, { retainLines: !0 }).code;
393
393
  }
394
- function A(p) {
395
- const o = h(p, {
394
+ function A(u) {
395
+ const o = _(u, {
396
396
  sourceType: "module",
397
397
  plugins: ["typescript", "jsx"]
398
398
  }), n = /* @__PURE__ */ new Map();
@@ -408,7 +408,7 @@ function A(p) {
408
408
  ExportDefaultDeclaration(t) {
409
409
  const a = t.node.declaration;
410
410
  let s = null;
411
- e.isArrayExpression(a) ? s = a : (e.isTSSatisfiesExpression(a) || e.isTSAsExpression(a)) && e.isArrayExpression(a.expression) && (s = a.expression), s && D(s.elements, "", i);
411
+ e.isArrayExpression(a) ? s = a : (e.isTSSatisfiesExpression(a) || e.isTSAsExpression(a)) && e.isArrayExpression(a.expression) && (s = a.expression), s && C(s.elements, "", i);
412
412
  }
413
413
  });
414
414
  const l = /* @__PURE__ */ new Map();
@@ -421,14 +421,14 @@ function A(p) {
421
421
  }
422
422
  return l;
423
423
  }
424
- function D(p, o, n) {
425
- for (const i of p) {
424
+ function C(u, o, n) {
425
+ for (const i of u) {
426
426
  if (!e.isObjectExpression(i)) continue;
427
427
  let l = "", t = o, a = null, s = null;
428
428
  for (const c of i.properties) {
429
429
  if (!e.isObjectProperty(c)) continue;
430
- const r = c.key, u = e.isIdentifier(r) ? r.name : null;
431
- u === "path" && e.isStringLiteral(c.value) && (l = c.value.value, l && !l.startsWith("/") ? t = o + "/" + l : t = o + l), u === "module" && e.isIdentifier(c.value) && (a = c.value.name), u === "children" && e.isArrayExpression(c.value) && (s = c.value);
430
+ const r = c.key, p = e.isIdentifier(r) ? r.name : null;
431
+ p === "path" && e.isStringLiteral(c.value) && (l = c.value.value, l && !l.startsWith("/") ? t = o + "/" + l : t = o + l), p === "module" && e.isIdentifier(c.value) && (a = c.value.name), p === "children" && e.isArrayExpression(c.value) && (s = c.value);
432
432
  }
433
433
  if (a) {
434
434
  const r = !s && l === "/" ? o || "/" : t;
@@ -437,13 +437,13 @@ function D(p, o, n) {
437
437
  path: l
438
438
  });
439
439
  }
440
- s && D(s.elements, t, n);
440
+ s && C(s.elements, t, n);
441
441
  }
442
442
  }
443
- const b = "virtual:velo/server-entry", E = "virtual:velo/client-entry", P = "\0" + b, N = "\0" + E;
444
- function ee(p, o) {
443
+ const E = "virtual:velo/server-entry", b = "virtual:velo/client-entry", N = "\0" + E, P = "\0" + b;
444
+ function te(u, o) {
445
445
  let n = d.resolve(process.cwd(), o);
446
- const i = p.routesFile ?? "routes.tsx", l = /* @__PURE__ */ new Map();
446
+ const i = u.routesFile ?? "routes.tsx", l = /* @__PURE__ */ new Map();
447
447
  return {
448
448
  name: "velo:transform",
449
449
  enforce: "pre",
@@ -464,27 +464,27 @@ function ee(p, o) {
464
464
  if (t === s) {
465
465
  const c = g.readFileSync(s, "utf-8"), r = A(c);
466
466
  l.clear();
467
- for (const [u, f] of r)
468
- l.set(u, f);
467
+ for (const [p, f] of r)
468
+ l.set(p, f);
469
469
  return a.ws.send({ type: "full-reload" }), [];
470
470
  }
471
471
  },
472
472
  resolveId(t) {
473
- return t === b || t.endsWith(b) ? P : t === E || t.endsWith(E) || t === "/__velo_client.js" ? N : null;
473
+ return t === E || t.endsWith(E) ? N : t === b || t.endsWith(b) || t === "/__velo_client.js" ? P : null;
474
474
  },
475
475
  load(t) {
476
- const a = p.routesFile ?? "routes.tsx", s = p.serverInit ?? "server.tsx", c = p.clientInit ?? "client.tsx", r = d.join(n, a).replace(/\.tsx?$/, ".js"), u = d.join(n, s).replace(/\.tsx?$/, ".js"), f = d.join(n, c).replace(/\.tsx?$/, ".js");
477
- return t === P ? `
476
+ const a = u.routesFile ?? "routes.tsx", s = u.serverInit ?? "server.tsx", c = u.clientInit ?? "client.tsx", r = d.join(n, a).replace(/\.tsx?$/, ".js"), p = d.join(n, s).replace(/\.tsx?$/, ".js"), f = d.join(n, c).replace(/\.tsx?$/, ".js");
477
+ return t === N ? `
478
478
  globalThis.__veloBuildHash = __VELO_BUILD_HASH__;
479
479
  globalThis.__veloClientJs = __VELO_CLIENT_JS__;
480
480
  globalThis.__veloClientCss = __VELO_CLIENT_CSS__;
481
- import "${u}";
481
+ import "${p}";
482
482
  import routes from "${r}";
483
483
  import { startServer } from "@mauroandre/velojs/server";
484
484
 
485
485
  export { routes };
486
- export default await startServer({ routes, port: __VELO_CONFIG_PORT__ });
487
- ` : t === N ? `
486
+ export default await startServer({ routes, port: __VELO_CONFIG_PORT__, hostname: __VELO_CONFIG_HOSTNAME__ });
487
+ ` : t === P ? `
488
488
  import "${f}";
489
489
  import routes from "${r}";
490
490
  import { startClient } from "@mauroandre/velojs/client";
@@ -495,39 +495,39 @@ startClient({ routes });
495
495
  transform(t, a, s) {
496
496
  const c = s?.ssr === !0;
497
497
  if (a.startsWith("\0") || a.includes("/.velojs/") || !a.endsWith(".tsx") && !a.endsWith(".ts") || !a.startsWith(n)) return null;
498
- let r = t, u = !1;
498
+ let r = t, p = !1;
499
499
  const f = /middlewares:\s*\[/.test(t), y = /export\s+(const|function)\s+Component/.test(
500
500
  t
501
- ), v = /export\s+(const|function)\s+loader/.test(t), C = /export\s+const\s+action_\w+/.test(t), I = /export\s+const\s+stream_\w+/.test(t), T = /export\s+const\s+socket_\w+/.test(t), w = /\bLoader\s*</.test(t) || /\bLoader\s*\(/.test(t), k = /\buseLoader\s*</.test(t) || /\buseLoader\s*\(/.test(t), F = /\bhandler\s*:/.test(t), V = d.join(n, i);
502
- if (!c && f && (r = q(r), u = !0), !c && F && a === V && (r = Z(r), u = !0), y || v || C || I || T || w || k) {
501
+ ), v = /export\s+(const|function)\s+loader/.test(t), D = /export\s+const\s+action_\w+/.test(t), I = /export\s+const\s+stream_\w+/.test(t), T = /export\s+const\s+socket_\w+/.test(t), w = /\bLoader\s*</.test(t) || /\bLoader\s*\(/.test(t), F = /\buseLoader\s*</.test(t) || /\buseLoader\s*\(/.test(t), k = /\bhandler\s*:/.test(t), V = d.join(n, i);
502
+ if (!c && f && (r = K(r), p = !0), !c && k && a === V && (r = ee(r), p = !0), y || v || D || I || T || w || F) {
503
503
  const S = d.relative(n, a).replace(/\.(tsx?|jsx?)$/, "").replace(/\\/g, "/"), O = l.get(S);
504
- r = W(r, S, O?.fullPath, O?.path), r = J(r, S), c || (r = B(
504
+ r = W(r, S, O?.fullPath, O?.path), r = M(r, S), c || (r = B(
505
505
  r,
506
506
  S
507
- )), !c && I && (r = G(
507
+ )), !c && I && (r = z(
508
508
  r,
509
509
  S
510
- )), !c && T && (r = z(
510
+ )), !c && T && (r = Y(
511
511
  r,
512
512
  S
513
- )), c || (r = Y(r)), c || (r = X(r)), u = !0;
513
+ )), c || (r = X(r)), c || (r = q(r)), p = !0;
514
514
  }
515
- return u ? {
515
+ return p ? {
516
516
  code: r,
517
517
  map: null
518
518
  } : null;
519
519
  }
520
520
  };
521
521
  }
522
- function te(p) {
522
+ function re(u) {
523
523
  return {
524
524
  name: "velo:config",
525
525
  config(o, { mode: n }) {
526
- const i = n === "server", l = n === "development", t = !!process.env.VELO_STATIC, a = o.server?.port ?? (Number(process.env.PORT) || p.port || 3e3);
526
+ const i = n === "server", l = n === "development", t = !!process.env.VELO_STATIC, a = o.server?.port ?? (Number(process.env.PORT) || u.port || 3e3);
527
527
  let s = "client.js", c = "client.css";
528
528
  if (i)
529
529
  try {
530
- const u = d.resolve(process.cwd(), "dist/client/.vite/manifest.json"), y = JSON.parse(g.readFileSync(u, "utf-8"))[E];
530
+ const p = d.resolve(process.cwd(), "dist/client/.vite/manifest.json"), y = JSON.parse(g.readFileSync(p, "utf-8"))[b];
531
531
  y && (s = y.file || s, y.css?.[0] && (c = y.css[0]));
532
532
  } catch {
533
533
  }
@@ -541,7 +541,9 @@ function te(p) {
541
541
  __VELO_CLIENT_CSS__: JSON.stringify(c),
542
542
  // Baked into the server bundle as startServer's port fallback.
543
543
  // null when unset → startServer falls back to PORT env / 3000.
544
- __VELO_CONFIG_PORT__: JSON.stringify(p.port ?? null)
544
+ __VELO_CONFIG_PORT__: JSON.stringify(u.port ?? null),
545
+ // Same for the bind interface: null → HOST env / Node default.
546
+ __VELO_CONFIG_HOSTNAME__: JSON.stringify(u.hostname ?? null)
545
547
  },
546
548
  resolve: {
547
549
  alias: {
@@ -554,7 +556,7 @@ function te(p) {
554
556
  }
555
557
  };
556
558
  return i ? r.build = {
557
- ssr: b,
559
+ ssr: E,
558
560
  outDir: "dist",
559
561
  emptyOutDir: !1,
560
562
  copyPublicDir: !1,
@@ -567,22 +569,22 @@ function te(p) {
567
569
  manifest: !0,
568
570
  outDir: "dist/client",
569
571
  rollupOptions: {
570
- input: E,
572
+ input: b,
571
573
  output: {
572
574
  entryFileNames: "client.[hash].js",
573
- assetFileNames: (u) => u.names?.[0]?.endsWith(".css") ? "client.[hash].css" : "[name].[hash][extname]"
575
+ assetFileNames: (p) => p.names?.[0]?.endsWith(".css") ? "client.[hash].css" : "[name].[hash][extname]"
574
576
  }
575
577
  }
576
578
  }), r;
577
579
  }
578
580
  };
579
581
  }
580
- function re() {
582
+ function ne() {
581
583
  return {
582
584
  name: "velo:static-url",
583
585
  apply: "build",
584
586
  enforce: "post",
585
- generateBundle(p, o) {
587
+ generateBundle(u, o) {
586
588
  const n = process.env.STATIC_BASE_URL || "";
587
589
  if (n)
588
590
  for (const i of Object.values(o))
@@ -593,7 +595,7 @@ function re() {
593
595
  }
594
596
  };
595
597
  }
596
- function ne(p, o) {
598
+ function ie(u, o) {
597
599
  let n = "", i = "", l = !1, t = null;
598
600
  function a() {
599
601
  if (!n) return;
@@ -616,45 +618,54 @@ function ne(p, o) {
616
618
  configureServer(s) {
617
619
  a(), l = !0;
618
620
  const c = d.resolve(n, o);
619
- s.watcher.on("all", (r, u) => {
620
- l && u.startsWith(c) && (t && clearTimeout(t), t = setTimeout(() => a(), 500));
621
+ s.watcher.on("all", (r, p) => {
622
+ l && p.startsWith(c) && (t && clearTimeout(t), t = setTimeout(() => a(), 500));
621
623
  });
622
624
  }
623
625
  };
624
626
  }
625
- function de(p) {
626
- const o = p ?? {}, n = o.appDirectory ?? "./app";
627
+ function se(u) {
627
628
  return [
628
- te(o),
629
- ee(o, n),
630
- re(),
631
- ne(o, n),
629
+ ...J.exclude,
630
+ /.*\.mjs$/,
631
+ ...u.devServerExclude ?? []
632
+ ];
633
+ }
634
+ function ye(u) {
635
+ const o = u ?? {}, n = o.appDirectory ?? "./app";
636
+ return [
637
+ re(o),
638
+ te(o, n),
639
+ ne(),
640
+ ie(o, n),
632
641
  R(),
633
642
  $({
634
- entry: b
643
+ entry: E,
644
+ exclude: se(o)
635
645
  }),
636
- ie()
646
+ oe()
637
647
  ];
638
648
  }
639
- function ie() {
649
+ function oe() {
640
650
  return {
641
651
  name: "velo:ws-bridge",
642
- configureServer(p) {
643
- globalThis.__veloDevServer = p.httpServer;
652
+ configureServer(u) {
653
+ globalThis.__veloDevServer = u.httpServer;
644
654
  }
645
655
  };
646
656
  }
647
657
  export {
648
658
  A as buildFullPathMap,
649
- D as collectFullPaths,
659
+ C as collectFullPaths,
660
+ se as devServerExcludeFor,
650
661
  W as injectMetadata,
651
- X as pruneClientOnlyImports,
652
- Z as removeEndpointRoutes,
653
- Y as removeLoaders,
654
- q as removeMiddlewares,
662
+ q as pruneClientOnlyImports,
663
+ ee as removeEndpointRoutes,
664
+ X as removeLoaders,
665
+ K as removeMiddlewares,
655
666
  B as transformActionsForClient,
656
- J as transformLoaderFunctions,
657
- z as transformSocketsForClient,
658
- G as transformStreamsForClient,
659
- de as veloPlugin
667
+ M as transformLoaderFunctions,
668
+ Y as transformSocketsForClient,
669
+ z as transformStreamsForClient,
670
+ ye as veloPlugin
660
671
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mauroandre/velojs",
3
- "version": "0.0.49",
3
+ "version": "0.0.51",
4
4
  "type": "module",
5
5
  "description": "Fullstack web framework built on Hono + Preact with Vite-powered AST transforms",
6
6
  "keywords": [