@mauroandre/velojs 0.0.51 → 0.0.53
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 +23 -1
- package/agent/skills/velojs-boot-state/SKILL.md +82 -0
- package/agent/skills/velojs-testing/SKILL.md +35 -4
- package/dist/components.d.ts +39 -0
- package/dist/components.js +44 -33
- package/dist/hooks.d.ts +24 -0
- package/dist/hooks.js +49 -45
- package/dist/index.d.ts +1 -1
- package/dist/index.js +9 -8
- package/dist/server.d.ts +15 -0
- package/dist/server.js +42 -37
- package/dist/testing/createTestApp.d.ts +8 -0
- package/dist/testing/index.js +432 -386
- package/dist/testing/types.d.ts +30 -0
- package/package.json +3 -1
package/dist/server.d.ts
CHANGED
|
@@ -4,6 +4,21 @@ import { AsyncLocalStorage } from "node:async_hooks";
|
|
|
4
4
|
export declare const serverDataStorage: AsyncLocalStorage<Record<string, unknown>>;
|
|
5
5
|
type ServerCallback = (server: import("http").Server) => void;
|
|
6
6
|
export declare function onServer(fn: ServerCallback): void;
|
|
7
|
+
/**
|
|
8
|
+
* Points the global `activeServer` at `server` and drains the callbacks
|
|
9
|
+
* registered in the current context. Exported for the testing toolkit, which
|
|
10
|
+
* serves a TestApp over TCP and must hand the real server to `onServer()`
|
|
11
|
+
* callbacks (same flush as `startServer`).
|
|
12
|
+
*/
|
|
13
|
+
export declare function flushServerCallbacks(server: import("http").Server): void;
|
|
14
|
+
/**
|
|
15
|
+
* Drops the global `activeServer` when it still points at `server`. A closed
|
|
16
|
+
* server must stop answering `onServer()`: a late registrant would receive a
|
|
17
|
+
* dead instance (address() === null) instead of queueing for the next one.
|
|
18
|
+
* `startServer` does the same through `server.once("close", …)`; the testing
|
|
19
|
+
* toolkit has no such event to lean on because it closes the server itself.
|
|
20
|
+
*/
|
|
21
|
+
export declare function clearActiveServer(server: import("http").Server): void;
|
|
7
22
|
export interface StartServerOptions {
|
|
8
23
|
routes: AppRoutes;
|
|
9
24
|
port?: number;
|
package/dist/server.js
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
|
-
import { jsx as
|
|
1
|
+
import { jsx as w } from "preact/jsx-runtime";
|
|
2
2
|
import { Hono as R } from "hono";
|
|
3
3
|
import { logger as T } from "hono/logger";
|
|
4
4
|
import { trimTrailingSlash as E } from "hono/trailing-slash";
|
|
5
5
|
import { render as C } from "preact-render-to-string";
|
|
6
|
-
import { Router as
|
|
7
|
-
import { AsyncLocalStorage as
|
|
6
|
+
import { Router as A } from "wouter-preact";
|
|
7
|
+
import { AsyncLocalStorage as $ } from "node:async_hooks";
|
|
8
8
|
import { getAppContext as _ } from "./app-context.js";
|
|
9
|
-
import { flushPendingStreamRoutes as
|
|
9
|
+
import { flushPendingStreamRoutes as k, registerStreamHandler as D } from "./events.js";
|
|
10
10
|
import { registerSocketRoutes as O, injectWebSocketServer as S } from "./sockets.js";
|
|
11
|
-
const P = new
|
|
11
|
+
const P = new $();
|
|
12
12
|
globalThis.__veloServerData = P;
|
|
13
13
|
let g = null;
|
|
14
|
-
function
|
|
14
|
+
function ee(e) {
|
|
15
15
|
if (g) {
|
|
16
16
|
e(g);
|
|
17
17
|
return;
|
|
@@ -24,23 +24,26 @@ function b(e) {
|
|
|
24
24
|
for (const s of t.serverCallbacks) s(e);
|
|
25
25
|
t.serverCallbacks.length = 0;
|
|
26
26
|
}
|
|
27
|
-
function
|
|
27
|
+
function I(e) {
|
|
28
|
+
g === e && (g = null);
|
|
29
|
+
}
|
|
30
|
+
function te(e) {
|
|
28
31
|
_().pendingRoutes.push(e);
|
|
29
32
|
}
|
|
30
|
-
const
|
|
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) => {
|
|
31
34
|
if (a && a !== 200 && e.status(a), e.req.query("_data") === "1") {
|
|
32
35
|
const c = globalThis.__veloBuildHash || void 0, r = s ? { ...s, __buildHash: c } : { __buildHash: c };
|
|
33
36
|
return e.json(r);
|
|
34
37
|
}
|
|
35
38
|
const o = e.req.path, n = P.run(
|
|
36
39
|
s ?? {},
|
|
37
|
-
() => C(/* @__PURE__ */
|
|
40
|
+
() => C(/* @__PURE__ */ w(A, { ssrPath: o, children: t }))
|
|
38
41
|
);
|
|
39
42
|
if (e.header("Cache-Control", "no-cache"), !s)
|
|
40
43
|
return e.html(n);
|
|
41
|
-
const i = `<script>window.__PAGE_DATA__=${
|
|
44
|
+
const i = `<script>window.__PAGE_DATA__=${N(s)}<\/script>`;
|
|
42
45
|
return e.html(n.replace("</head>", () => `${i}</head>`));
|
|
43
|
-
},
|
|
46
|
+
}, G = async (e, t) => {
|
|
44
47
|
const s = t.req.param(), a = t.req.query(), o = { params: s, query: a, c: t }, n = await Promise.all(
|
|
45
48
|
e.map(async (r) => {
|
|
46
49
|
if (!r.loader) return null;
|
|
@@ -66,16 +69,16 @@ const I = (e) => JSON.stringify(e).replace(/</g, "\\u003c").replace(/>/g, "\\u00
|
|
|
66
69
|
data: c,
|
|
67
70
|
shortCircuit: i
|
|
68
71
|
};
|
|
69
|
-
},
|
|
72
|
+
}, x = (e) => {
|
|
70
73
|
if (e.length === 0) return null;
|
|
71
74
|
const t = e.filter(Boolean);
|
|
72
75
|
if (t.length === 0) return null;
|
|
73
76
|
if (t.length === 1) {
|
|
74
77
|
const o = t[0];
|
|
75
|
-
return /* @__PURE__ */
|
|
78
|
+
return /* @__PURE__ */ w(o, {});
|
|
76
79
|
}
|
|
77
80
|
const s = t[t.length - 1];
|
|
78
|
-
return t.slice(0, -1).reduceRight((o, n) => /* @__PURE__ */
|
|
81
|
+
return t.slice(0, -1).reduceRight((o, n) => /* @__PURE__ */ w(n, { children: o }), /* @__PURE__ */ w(s, {}));
|
|
79
82
|
}, y = (e, t, s = [], a = []) => {
|
|
80
83
|
for (const o of t) {
|
|
81
84
|
if (o.handler && !o.module) {
|
|
@@ -107,13 +110,13 @@ const I = (e) => JSON.stringify(e).replace(/</g, "\\u003c").replace(/>/g, "\\u00
|
|
|
107
110
|
continue;
|
|
108
111
|
}
|
|
109
112
|
const l = async (d) => {
|
|
110
|
-
const { components: u, data: h, shortCircuit: m } = await
|
|
113
|
+
const { components: u, data: h, shortCircuit: m } = await G(n, d);
|
|
111
114
|
if (m) {
|
|
112
|
-
const
|
|
113
|
-
return d.req.query("_data") === "1" &&
|
|
115
|
+
const v = m.headers.get("Location");
|
|
116
|
+
return d.req.query("_data") === "1" && v && m.status >= 300 && m.status < 400 ? d.json({ __redirect: v }) : m;
|
|
114
117
|
}
|
|
115
|
-
const p =
|
|
116
|
-
return
|
|
118
|
+
const p = x(u);
|
|
119
|
+
return H(d, p, h, r);
|
|
117
120
|
};
|
|
118
121
|
c ? e.notFound(l) : i.length > 0 ? e.on(["GET"], [f], ...i, l) : e.on(["GET"], [f], l);
|
|
119
122
|
} else
|
|
@@ -148,8 +151,8 @@ const I = (e) => JSON.stringify(e).replace(/</g, "\\u003c").replace(/>/g, "\\u00
|
|
|
148
151
|
const p = await f(m);
|
|
149
152
|
return u.json(p ?? { ok: !0 });
|
|
150
153
|
} catch (p) {
|
|
151
|
-
const
|
|
152
|
-
return u.json({ error:
|
|
154
|
+
const v = p instanceof Error ? p.message : "Action failed";
|
|
155
|
+
return u.json({ error: v }, 500);
|
|
153
156
|
}
|
|
154
157
|
};
|
|
155
158
|
n.length > 0 ? e.on(
|
|
@@ -163,7 +166,7 @@ const I = (e) => JSON.stringify(e).replace(/</g, "\\u003c").replace(/>/g, "\\u00
|
|
|
163
166
|
}
|
|
164
167
|
a.children && q(e, a.children, n);
|
|
165
168
|
}
|
|
166
|
-
},
|
|
169
|
+
}, V = async (e, t, s = []) => {
|
|
167
170
|
const a = (o, n) => {
|
|
168
171
|
for (const i of o) {
|
|
169
172
|
const c = i.module?.metadata?.moduleId, r = [
|
|
@@ -191,7 +194,7 @@ const I = (e) => JSON.stringify(e).replace(/</g, "\\u003c").replace(/>/g, "\\u00
|
|
|
191
194
|
}
|
|
192
195
|
};
|
|
193
196
|
a(t, s);
|
|
194
|
-
},
|
|
197
|
+
}, W = (e, t) => t ? t.startsWith("/") ? e + t : e ? e + "/" + t : "/" + t : e || "", K = (e) => {
|
|
195
198
|
const t = /* @__PURE__ */ new Set(), s = (a) => {
|
|
196
199
|
for (const o of a) {
|
|
197
200
|
if (o.module && !o.children) {
|
|
@@ -204,7 +207,7 @@ const I = (e) => JSON.stringify(e).replace(/</g, "\\u003c").replace(/>/g, "\\u00
|
|
|
204
207
|
return s(e), t;
|
|
205
208
|
}, j = (e, t, s, a = "", o = []) => {
|
|
206
209
|
for (const n of t) {
|
|
207
|
-
const i =
|
|
210
|
+
const i = W(a, n.path), c = [
|
|
208
211
|
...o,
|
|
209
212
|
...n.middlewares || []
|
|
210
213
|
], r = !!n.handler, f = !!n.method;
|
|
@@ -236,21 +239,21 @@ const I = (e) => JSON.stringify(e).replace(/</g, "\\u003c").replace(/>/g, "\\u00
|
|
|
236
239
|
c
|
|
237
240
|
);
|
|
238
241
|
}
|
|
239
|
-
},
|
|
242
|
+
}, L = async (e) => {
|
|
240
243
|
const t = new R();
|
|
241
244
|
t.use(E()), process.env.NODE_ENV !== "production" && t.use("*", T());
|
|
242
245
|
const a = _().pendingRoutes.splice(0);
|
|
243
246
|
for (const n of a)
|
|
244
247
|
await n(t);
|
|
245
|
-
y(t, e), q(t, e), await
|
|
246
|
-
const o =
|
|
247
|
-
if (j(t, e, o), await O(t, e),
|
|
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) {
|
|
248
251
|
const n = globalThis.__veloDevServer;
|
|
249
252
|
n && (b(n), await S(t, n));
|
|
250
253
|
}
|
|
251
254
|
return t;
|
|
252
|
-
},
|
|
253
|
-
const { routes: t } = e, s = Number(process.env.PORT) || e.port || 3e3, a = process.env.HOST || e.hostname || void 0, o = await
|
|
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);
|
|
254
257
|
if (process.env.NODE_ENV === "production" && !process.env.VELO_STATIC) {
|
|
255
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");
|
|
256
259
|
(process.env.STATIC_BASE_URL || "").startsWith("http") || o.use("/*", i({ root: r }));
|
|
@@ -263,17 +266,19 @@ const I = (e) => JSON.stringify(e).replace(/</g, "\\u003c").replace(/>/g, "\\u00
|
|
|
263
266
|
} else
|
|
264
267
|
console.log(`Server running on port ${s}`);
|
|
265
268
|
await S(o, l), b(l), l.once("close", () => {
|
|
266
|
-
|
|
269
|
+
I(l);
|
|
267
270
|
});
|
|
268
271
|
}
|
|
269
272
|
return o;
|
|
270
273
|
};
|
|
271
274
|
export {
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
275
|
+
te as addRoutes,
|
|
276
|
+
I as clearActiveServer,
|
|
277
|
+
L as createApp,
|
|
278
|
+
L as default,
|
|
279
|
+
b as flushServerCallbacks,
|
|
280
|
+
N as jsonForScript,
|
|
281
|
+
ee as onServer,
|
|
277
282
|
P as serverDataStorage,
|
|
278
|
-
|
|
283
|
+
oe as startServer
|
|
279
284
|
};
|
|
@@ -19,5 +19,13 @@ import type { TestApp, CreateTestAppOptions } from "./types.js";
|
|
|
19
19
|
* getSessionCookie: async ({ user }) => ({ session: await sign(user) }),
|
|
20
20
|
* });
|
|
21
21
|
* ```
|
|
22
|
+
*
|
|
23
|
+
* Pass `port` to also serve the same app over real TCP — for external actors
|
|
24
|
+
* (a worker in another process) that cannot call `hono.fetch` in-memory:
|
|
25
|
+
*
|
|
26
|
+
* ```typescript
|
|
27
|
+
* const app = await createTestApp({ routes, port: 0 });
|
|
28
|
+
* await handToWorker(`${app.url}/_action/Jobs/notify`);
|
|
29
|
+
* ```
|
|
22
30
|
*/
|
|
23
31
|
export declare function createTestApp(opts: CreateTestAppOptions): Promise<TestApp>;
|