@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/README.md +423 -3
- package/agent/AGENTS.md +216 -0
- package/agent/skills/velojs-live-loader/SKILL.md +410 -0
- package/dist/channels.d.ts +370 -0
- package/dist/channels.js +376 -0
- package/dist/client.js +56 -45
- package/dist/components.js +7 -6
- package/dist/events.d.ts +6 -0
- package/dist/events.js +1 -0
- package/dist/hooks.d.ts +26 -21
- package/dist/hooks.js +117 -98
- package/dist/live-loader.d.ts +120 -0
- package/dist/live-loader.js +141 -0
- package/dist/server.d.ts +2 -0
- package/dist/server.js +144 -118
- package/dist/testing/index.d.ts +5 -1
- package/dist/testing/index.js +495 -412
- package/dist/testing/subscription.d.ts +18 -2
- package/dist/testing/types.d.ts +85 -0
- package/dist/types.d.ts +9 -0
- package/dist/vite.d.ts +15 -0
- package/dist/vite.js +431 -340
- package/package.json +1 -1
package/dist/server.js
CHANGED
|
@@ -1,17 +1,19 @@
|
|
|
1
1
|
import { jsx as w } from "preact/jsx-runtime";
|
|
2
|
-
import { Hono as
|
|
3
|
-
import { logger as
|
|
4
|
-
import { trimTrailingSlash as
|
|
5
|
-
import { render as
|
|
6
|
-
import { Router as
|
|
7
|
-
import { AsyncLocalStorage as
|
|
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
|
|
10
|
-
import { registerSocketRoutes as
|
|
11
|
-
|
|
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
|
|
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
|
|
26
|
+
for (const a of t.serverCallbacks) a(e);
|
|
25
27
|
t.serverCallbacks.length = 0;
|
|
26
28
|
}
|
|
27
|
-
function
|
|
29
|
+
function x(e) {
|
|
28
30
|
g === e && (g = null);
|
|
29
31
|
}
|
|
30
|
-
function
|
|
32
|
+
function se(e) {
|
|
31
33
|
_().pendingRoutes.push(e);
|
|
32
34
|
}
|
|
33
|
-
const
|
|
34
|
-
if (
|
|
35
|
-
const c = globalThis.__veloBuildHash || void 0,
|
|
36
|
-
return e.json(
|
|
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
|
-
|
|
40
|
-
() =>
|
|
41
|
+
a ?? {},
|
|
42
|
+
() => A(/* @__PURE__ */ w($, { ssrPath: o, children: t }))
|
|
41
43
|
);
|
|
42
|
-
if (e.header("Cache-Control", "no-cache"), !
|
|
44
|
+
if (e.header("Cache-Control", "no-cache"), !a)
|
|
43
45
|
return e.html(n);
|
|
44
|
-
const
|
|
45
|
-
return e.html(n.replace("</head>", () => `${
|
|
46
|
-
},
|
|
47
|
-
const
|
|
48
|
-
e.map(async (
|
|
49
|
-
if (!
|
|
50
|
-
const f = await
|
|
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
|
|
55
|
-
for (const
|
|
56
|
-
if (
|
|
57
|
-
|
|
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:
|
|
62
|
-
__query:
|
|
63
|
+
__params: a,
|
|
64
|
+
__query: r,
|
|
63
65
|
__pathname: t.req.path
|
|
64
66
|
};
|
|
65
|
-
for (const
|
|
66
|
-
|
|
67
|
+
for (const i of n)
|
|
68
|
+
i && !(i.loaderData instanceof Response) && (c[i.moduleId] = i.loaderData);
|
|
67
69
|
return {
|
|
68
|
-
components: e.map((
|
|
70
|
+
components: e.map((i) => i.Component),
|
|
69
71
|
data: c,
|
|
70
|
-
shortCircuit:
|
|
72
|
+
shortCircuit: s
|
|
71
73
|
};
|
|
72
|
-
},
|
|
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
|
|
81
|
-
return t.slice(0, -1).reduceRight((o, n) => /* @__PURE__ */ w(n, { children: o }), /* @__PURE__ */ w(
|
|
82
|
-
}, y = (e, t,
|
|
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
|
-
|
|
89
|
-
[...
|
|
90
|
+
a,
|
|
91
|
+
[...r, ...o.middlewares || []]
|
|
90
92
|
);
|
|
91
93
|
continue;
|
|
92
94
|
}
|
|
93
|
-
const n = o.module ? [...
|
|
94
|
-
...
|
|
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
|
-
|
|
104
|
+
s
|
|
103
105
|
);
|
|
104
106
|
else if (o.module) {
|
|
105
|
-
const c = o.path === "*",
|
|
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
|
|
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 =
|
|
119
|
-
return
|
|
120
|
+
const p = W(u);
|
|
121
|
+
return V(d, p, h, i);
|
|
120
122
|
};
|
|
121
|
-
c ? e.notFound(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
|
-
},
|
|
126
|
-
for (const
|
|
127
|
-
const o =
|
|
128
|
-
...
|
|
129
|
-
...
|
|
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 (
|
|
132
|
-
const
|
|
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
|
|
136
|
-
const
|
|
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}/${
|
|
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
|
-
|
|
169
|
+
r.children && R(e, r.children, n);
|
|
168
170
|
}
|
|
169
|
-
},
|
|
170
|
-
const
|
|
171
|
-
for (const
|
|
172
|
-
const c =
|
|
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
|
-
...
|
|
176
|
+
...s.middlewares || []
|
|
175
177
|
];
|
|
176
|
-
if (
|
|
177
|
-
const f = Object.keys(
|
|
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 =
|
|
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,
|
|
186
|
+
u.__path = h, I(
|
|
185
187
|
e,
|
|
186
188
|
h,
|
|
187
189
|
u,
|
|
188
|
-
|
|
190
|
+
i
|
|
189
191
|
);
|
|
190
192
|
}
|
|
191
193
|
}
|
|
192
194
|
}
|
|
193
|
-
|
|
195
|
+
s.children && r(s.children, i);
|
|
194
196
|
}
|
|
195
197
|
};
|
|
196
|
-
|
|
197
|
-
},
|
|
198
|
-
|
|
199
|
-
|
|
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 &&
|
|
227
|
+
o.children && a(o.children);
|
|
205
228
|
}
|
|
206
229
|
};
|
|
207
|
-
return
|
|
208
|
-
},
|
|
230
|
+
return a(e), t;
|
|
231
|
+
}, q = (e, t, a, r = "", o = []) => {
|
|
209
232
|
for (const n of t) {
|
|
210
|
-
const
|
|
233
|
+
const s = L(r, n.path), c = [
|
|
211
234
|
...o,
|
|
212
235
|
...n.middlewares || []
|
|
213
|
-
],
|
|
214
|
-
if (
|
|
215
|
-
`[velojs] invalid route at "${
|
|
216
|
-
) : f && !
|
|
217
|
-
`[velojs] invalid route at "${
|
|
218
|
-
) :
|
|
219
|
-
`[velojs] ambiguous route at "${
|
|
220
|
-
) :
|
|
221
|
-
`[velojs] "isRoot" has no effect on endpoint at "${
|
|
222
|
-
),
|
|
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" &&
|
|
225
|
-
`[velojs] path "${
|
|
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], [
|
|
255
|
+
c.length > 0 ? e.on([d], [s], ...c, h) : e.on([d], [s], h);
|
|
233
256
|
}
|
|
234
|
-
n.children &&
|
|
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
|
-
},
|
|
243
|
-
const t = new
|
|
244
|
-
t.use(
|
|
245
|
-
const
|
|
246
|
-
for (const n of
|
|
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),
|
|
249
|
-
const o =
|
|
250
|
-
if (
|
|
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
|
-
},
|
|
256
|
-
const { routes: t } = e,
|
|
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:
|
|
259
|
-
(process.env.STATIC_BASE_URL || "").startsWith("http") || o.use("/*",
|
|
260
|
-
const l = n({ fetch: o.fetch, port:
|
|
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 ${
|
|
290
|
+
console.log(`Server running on port ${a}`);
|
|
268
291
|
await S(o, l), b(l), l.once("close", () => {
|
|
269
|
-
|
|
292
|
+
x(l);
|
|
270
293
|
});
|
|
271
294
|
}
|
|
272
295
|
return o;
|
|
273
296
|
};
|
|
274
297
|
export {
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
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
|
-
|
|
281
|
-
|
|
304
|
+
O as inspectChannels,
|
|
305
|
+
G as jsonForScript,
|
|
306
|
+
re as onServer,
|
|
307
|
+
de as registerChannels,
|
|
282
308
|
P as serverDataStorage,
|
|
283
|
-
|
|
309
|
+
ae as startServer
|
|
284
310
|
};
|
package/dist/testing/index.d.ts
CHANGED
|
@@ -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";
|