@mauroandre/velojs 0.0.26 → 0.0.27

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/hooks.js CHANGED
@@ -1,116 +1,176 @@
1
- import { signal as v, useSignal as c } from "@preact/signals";
2
- import { useEffect as h, useRef as p } from "preact/hooks";
3
- import { useLocation as w, useParams as g } from "wouter-preact";
4
- const S = v(!1);
5
- function L(e) {
1
+ import { signal as g, useSignal as h } from "@preact/signals";
2
+ import { useEffect as D, useRef as E } from "preact/hooks";
3
+ import { useLocation as L, useParams as A } from "wouter-preact";
4
+ const b = g(!1);
5
+ function O(e) {
6
6
  e.value !== null && typeof e.value == "object" && (e.value = { ...e.value });
7
7
  }
8
- function m(e) {
9
- const o = v(!1);
8
+ function C(e) {
9
+ const c = g(!1);
10
10
  if (typeof window > "u")
11
11
  return { data: {
12
12
  get value() {
13
13
  return e ? globalThis.__veloServerData?.getStore?.()?.[e] ?? null : null;
14
14
  }
15
- }, loading: o };
15
+ }, loading: c };
16
16
  const t = window.__PAGE_DATA__, r = e && t?.[e] ? t[e] : null;
17
- return { data: v(r), loading: o };
17
+ return { data: g(r), loading: c };
18
18
  }
19
- function A(e, o) {
19
+ function U(e, c) {
20
20
  let t, r;
21
- Array.isArray(e) ? r = e : (t = e, r = o);
22
- let n = null;
21
+ Array.isArray(e) ? r = e : (t = e, r = c);
22
+ let a = null;
23
23
  if (typeof window > "u" && t) {
24
- const i = globalThis.__veloServerData?.getStore?.();
25
- i?.[t] && (n = i[t]);
24
+ const _ = globalThis.__veloServerData?.getStore?.();
25
+ _?.[t] && (a = _[t]);
26
26
  }
27
27
  if (typeof window < "u" && t) {
28
- const a = window.__PAGE_DATA__;
29
- a?.[t] && (n = a[t], delete a[t]);
28
+ const n = window.__PAGE_DATA__;
29
+ n?.[t] && (a = n[t], delete n[t]);
30
30
  }
31
- const u = c(n), s = c(!1), _ = () => {
31
+ const o = h(a), s = h(!1), f = () => {
32
32
  if (typeof window > "u" || !t) return;
33
- const a = window.location.pathname;
33
+ const n = window.location.pathname;
34
34
  s.value = !0;
35
- const f = typeof __VELO_STATIC__ < "u" && __VELO_STATIC__ ? `${a === "/" ? "" : a}/index.json` : (() => {
35
+ const p = typeof __VELO_STATIC__ < "u" && __VELO_STATIC__ ? `${n === "/" ? "" : n}/index.json` : (() => {
36
36
  const l = new URLSearchParams(window.location.search);
37
- return l.set("_data", "1"), `${a}?${l.toString()}`;
37
+ return l.set("_data", "1"), `${n}?${l.toString()}`;
38
38
  })();
39
- fetch(f, { cache: "no-cache" }).then((l) => l.json()).then((l) => {
40
- typeof __VELO_BUILD_HASH__ < "u" && l.__buildHash && l.__buildHash !== __VELO_BUILD_HASH__ && (S.value = !0), u.value = l[t], s.value = !1;
39
+ fetch(p, { cache: "no-cache" }).then((l) => l.json()).then((l) => {
40
+ typeof __VELO_BUILD_HASH__ < "u" && l.__buildHash && l.__buildHash !== __VELO_BUILD_HASH__ && (b.value = !0), o.value = l[t], s.value = !1;
41
41
  }).catch(() => {
42
42
  s.value = !1;
43
43
  });
44
- }, d = p(n !== null);
45
- return h(() => {
46
- if (d.current) {
47
- d.current = !1;
44
+ }, y = E(a !== null);
45
+ return D(() => {
46
+ if (y.current) {
47
+ y.current = !1;
48
48
  return;
49
49
  }
50
- _();
51
- }, r ?? []), { data: u, loading: s, refetch: _ };
50
+ f();
51
+ }, r ?? []), { data: o, loading: s, refetch: f };
52
52
  }
53
- function P() {
54
- const [, e] = w();
53
+ function k() {
54
+ const [, e] = L();
55
55
  return e;
56
56
  }
57
- function T() {
58
- return typeof window > "u" ? globalThis.__veloServerData?.getStore?.()?.__params ?? {} : g();
57
+ function H() {
58
+ return typeof window > "u" ? globalThis.__veloServerData?.getStore?.()?.__params ?? {} : A();
59
59
  }
60
- function b() {
60
+ function R() {
61
61
  if (typeof window > "u")
62
62
  return globalThis.__veloServerData?.getStore?.()?.__query ?? {};
63
63
  const e = window.__PAGE_DATA__;
64
64
  if (e?.__query)
65
65
  return e.__query;
66
- const o = new URLSearchParams(window.location.search), t = {};
67
- return o.forEach((r, n) => {
68
- t[n] = r;
66
+ const c = new URLSearchParams(window.location.search), t = {};
67
+ return c.forEach((r, a) => {
68
+ t[a] = r;
69
69
  }), t;
70
70
  }
71
- function H() {
72
- return typeof window > "u" ? globalThis.__veloServerData?.getStore?.()?.__pathname ?? "/" : (w(), window.location.pathname);
71
+ function G() {
72
+ return typeof window > "u" ? globalThis.__veloServerData?.getStore?.()?.__pathname ?? "/" : (L(), window.location.pathname);
73
73
  }
74
- function U(e, o = {}) {
75
- const t = c(null), r = c(null), n = c(!1), u = c(null), { channel: s, enabled: _ = !0 } = o;
76
- return h(() => {
77
- if (typeof window > "u" || !_) return;
74
+ function W(e, c = {}) {
75
+ const t = h(null), r = h(null), a = h(!1), o = h(null), { channel: s, enabled: f = !0 } = c;
76
+ return D(() => {
77
+ if (typeof window > "u" || !f) return;
78
78
  if (!e.__path) {
79
79
  console.warn("[velojs] useEventStream: stream has no __path");
80
80
  return;
81
81
  }
82
- t.value = null, r.value = null, n.value = !1, u.value = null;
83
- const d = s ? `${e.__path}?channel=${encodeURIComponent(s)}` : e.__path, a = new EventSource(d);
84
- return a.addEventListener("snapshot", (i) => {
82
+ t.value = null, r.value = null, a.value = !1, o.value = null;
83
+ const y = s ? `${e.__path}?channel=${encodeURIComponent(s)}` : e.__path, n = new EventSource(y);
84
+ return n.addEventListener("snapshot", (_) => {
85
85
  try {
86
- r.value = JSON.parse(i.data);
87
- } catch (f) {
88
- u.value = f;
86
+ r.value = JSON.parse(_.data);
87
+ } catch (p) {
88
+ o.value = p;
89
89
  }
90
- }), a.addEventListener("message", (i) => {
90
+ }), n.addEventListener("message", (_) => {
91
91
  try {
92
- t.value = JSON.parse(i.data);
93
- } catch (f) {
94
- u.value = f;
92
+ t.value = JSON.parse(_.data);
93
+ } catch (p) {
94
+ o.value = p;
95
95
  }
96
- }), a.addEventListener("heartbeat", () => {
97
- }), a.addEventListener("close", () => {
98
- n.value = !0, a.close();
99
- }), a.addEventListener("error", () => {
100
- a.readyState === EventSource.CLOSED && (n.value = !0);
96
+ }), n.addEventListener("heartbeat", () => {
97
+ }), n.addEventListener("close", () => {
98
+ a.value = !0, n.close();
99
+ }), n.addEventListener("error", () => {
100
+ n.readyState === EventSource.CLOSED && (a.value = !0);
101
+ }), () => {
102
+ n.close();
103
+ };
104
+ }, [e, s, f]), { data: t, snapshot: r, closed: a, error: o };
105
+ }
106
+ function q(e, c = {}) {
107
+ const t = h("connecting"), r = h(null), a = h(null), o = E(null), s = E([]), { channel: f, onMessage: y, onOpen: n, onClose: _, onError: p, enabled: l = !0 } = c;
108
+ return D(() => {
109
+ if (typeof window > "u" || !l) return;
110
+ if (!e.__path) {
111
+ console.warn("[velojs] useSocket: stub has no __path");
112
+ return;
113
+ }
114
+ t.value = "connecting", r.value = null, a.value = null;
115
+ const v = `${window.location.protocol === "https:" ? "wss:" : "ws:"}//${window.location.host}`, i = f ? `${v}${e.__path}?channel=${encodeURIComponent(f)}` : `${v}${e.__path}`, d = new WebSocket(i);
116
+ return d.binaryType = "arraybuffer", o.current = d, d.addEventListener("open", () => {
117
+ t.value = "open";
118
+ const u = s.current;
119
+ s.current = [];
120
+ for (const S of u)
121
+ try {
122
+ d.send(S);
123
+ } catch {
124
+ }
125
+ n?.();
126
+ }), d.addEventListener("message", (u) => {
127
+ let S;
128
+ if (typeof u.data == "string")
129
+ S = u.data;
130
+ else if (u.data instanceof ArrayBuffer)
131
+ S = new Uint8Array(u.data);
132
+ else
133
+ return;
134
+ r.value = S, y?.(S);
135
+ }), d.addEventListener("close", (u) => {
136
+ t.value = "closed", o.current = null, _?.(u);
137
+ }), d.addEventListener("error", (u) => {
138
+ a.value = u, p?.(u);
101
139
  }), () => {
102
- a.close();
140
+ o.current = null;
141
+ try {
142
+ (d.readyState === WebSocket.OPEN || d.readyState === WebSocket.CONNECTING) && d.close();
143
+ } catch {
144
+ }
103
145
  };
104
- }, [e, s, _]), { data: t, snapshot: r, closed: n, error: u };
146
+ }, [e.__path, f, l]), { send: (w) => {
147
+ let v;
148
+ typeof w == "string" || w instanceof Uint8Array ? v = w : v = JSON.stringify(w);
149
+ const i = o.current;
150
+ if (i && i.readyState === WebSocket.OPEN)
151
+ try {
152
+ i.send(v);
153
+ } catch {
154
+ }
155
+ else i && i.readyState === WebSocket.CONNECTING && s.current.push(v);
156
+ }, close: (w, v) => {
157
+ const i = o.current;
158
+ if (i)
159
+ try {
160
+ i.close(w, v);
161
+ } catch {
162
+ }
163
+ }, status: t, lastMessage: r, error: a };
105
164
  }
106
165
  export {
107
- m as Loader,
108
- S as __veloUpdatePending,
109
- L as touch,
110
- U as useEventStream,
111
- A as useLoader,
112
- P as useNavigate,
113
- T as useParams,
114
- H as usePathname,
115
- b as useQuery
166
+ C as Loader,
167
+ b as __veloUpdatePending,
168
+ O as touch,
169
+ W as useEventStream,
170
+ U as useLoader,
171
+ k as useNavigate,
172
+ H as useParams,
173
+ G as usePathname,
174
+ R as useQuery,
175
+ q as useSocket
116
176
  };
package/dist/index.d.ts CHANGED
@@ -3,5 +3,6 @@ export type { VeloConfig } from "./config.js";
3
3
  export { defineConfig } from "./config.js";
4
4
  export { Scripts, Link } from "./components.js";
5
5
  export { createEventStream, poll } from "./events.js";
6
- export type { EventStream, EventStreamConfig, EmitFn, EmitOptions, SourceFn, PerChannelSourceFn, ChannelResolver, } from "./events.js";
6
+ export type { EventStream, EventStreamConfig, EmitFn, EmitOptions, SourceFn, PerChannelSourceFn, StreamPipeFn, StreamPipeArgs, ChannelResolver, } from "./events.js";
7
+ export type { SocketHandler, SocketHandlerArgs, SocketStub, } from "./sockets.js";
7
8
  export type { Context, MiddlewareHandler, Next } from "hono";
package/dist/server.js CHANGED
@@ -1,39 +1,40 @@
1
1
  import { jsx as g } from "preact/jsx-runtime";
2
- import { Hono as R } from "hono";
3
- import { logger as b } from "hono/logger";
4
- import { trimTrailingSlash as T } from "hono/trailing-slash";
5
- import { render as j } from "preact-render-to-string";
2
+ import { Hono as q } from "hono";
3
+ import { logger as T } from "hono/logger";
4
+ import { trimTrailingSlash as j } from "hono/trailing-slash";
5
+ import { render as k } from "preact-render-to-string";
6
6
  import { Router as A } from "wouter-preact";
7
7
  import { AsyncLocalStorage as C } from "node:async_hooks";
8
8
  import { getAppContext as v } from "./app-context.js";
9
- import { flushPendingStreamRoutes as $, registerStreamHandler as k } from "./events.js";
10
- const y = new C();
11
- globalThis.__veloServerData = y;
12
- let _ = null;
13
- function z(e) {
14
- if (_) {
15
- e(_);
9
+ import { flushPendingStreamRoutes as $, registerStreamHandler as D } from "./events.js";
10
+ import { registerSocketRoutes as I, injectWebSocketServer as y } from "./sockets.js";
11
+ const S = new C();
12
+ globalThis.__veloServerData = S;
13
+ let w = null;
14
+ function Y(e) {
15
+ if (w) {
16
+ e(w);
16
17
  return;
17
18
  }
18
19
  v().serverCallbacks.push(e);
19
20
  }
20
- function S(e) {
21
- _ = e;
21
+ function P(e) {
22
+ w = e;
22
23
  const t = v();
23
24
  for (const s of t.serverCallbacks) s(e);
24
25
  t.serverCallbacks.length = 0;
25
26
  }
26
- function Q(e) {
27
+ function Z(e) {
27
28
  v().pendingRoutes.push(e);
28
29
  }
29
- const D = (e, t, s) => {
30
+ const N = (e, t, s) => {
30
31
  if (e.req.query("_data") === "1") {
31
32
  const r = globalThis.__veloBuildHash || void 0, i = s ? { ...s, __buildHash: r } : { __buildHash: r };
32
33
  return e.json(i);
33
34
  }
34
- const a = e.req.path, o = y.run(
35
+ const a = e.req.path, o = S.run(
35
36
  s ?? {},
36
- () => j(/* @__PURE__ */ g(A, { ssrPath: a, children: t }))
37
+ () => k(/* @__PURE__ */ g(A, { ssrPath: a, children: t }))
37
38
  );
38
39
  if (e.header("Cache-Control", "no-cache"), !s)
39
40
  return e.html(o);
@@ -41,7 +42,7 @@ const D = (e, t, s) => {
41
42
  s
42
43
  )}<\/script>`;
43
44
  return e.html(o.replace("</head>", `${n}</head>`));
44
- }, I = async (e, t) => {
45
+ }, O = async (e, t) => {
45
46
  const s = t.req.param(), a = t.req.query(), o = { params: s, query: a, c: t }, n = await Promise.all(
46
47
  e.map(async (i) => {
47
48
  if (!i.loader) return null;
@@ -59,7 +60,7 @@ const D = (e, t, s) => {
59
60
  components: e.map((i) => i.Component),
60
61
  data: r
61
62
  };
62
- }, N = (e) => {
63
+ }, G = (e) => {
63
64
  if (e.length === 0) return null;
64
65
  const t = e.filter(Boolean);
65
66
  if (t.length === 0) return null;
@@ -69,10 +70,10 @@ const D = (e, t, s) => {
69
70
  }
70
71
  const s = t[t.length - 1];
71
72
  return t.slice(0, -1).reduceRight((o, n) => /* @__PURE__ */ g(n, { children: o }), /* @__PURE__ */ g(s, {}));
72
- }, w = (e, t, s = [], a = []) => {
73
+ }, _ = (e, t, s = [], a = []) => {
73
74
  for (const o of t) {
74
75
  if (o.handler && !o.module) {
75
- o.children && w(
76
+ o.children && _(
76
77
  e,
77
78
  o.children,
78
79
  s,
@@ -85,7 +86,7 @@ const D = (e, t, s) => {
85
86
  ...o.middlewares || []
86
87
  ];
87
88
  if (o.children)
88
- w(
89
+ _(
89
90
  e,
90
91
  o.children,
91
92
  n,
@@ -100,14 +101,14 @@ const D = (e, t, s) => {
100
101
  continue;
101
102
  }
102
103
  const l = async (c) => {
103
- const { components: u, data: h } = await I(n, c), d = N(u);
104
- return D(c, d, h);
104
+ const { components: u, data: h } = await O(n, c), d = G(u);
105
+ return N(c, d, h);
105
106
  };
106
107
  r.length > 0 ? e.on(["GET"], [i], ...r, l) : e.on(["GET"], [i], l);
107
108
  } else
108
109
  continue;
109
110
  }
110
- }, P = (e, t, s = []) => {
111
+ }, E = (e, t, s = []) => {
111
112
  for (const a of t) {
112
113
  const o = a.module?.metadata?.moduleId, n = [
113
114
  ...s,
@@ -136,8 +137,8 @@ const D = (e, t, s) => {
136
137
  const p = await c(f);
137
138
  return d.json(p ?? { ok: !0 });
138
139
  } catch (p) {
139
- const q = p instanceof Error ? p.message : "Action failed";
140
- return d.json({ error: q }, 500);
140
+ const b = p instanceof Error ? p.message : "Action failed";
141
+ return d.json({ error: b }, 500);
141
142
  }
142
143
  };
143
144
  n.length > 0 ? e.on(
@@ -149,9 +150,9 @@ const D = (e, t, s) => {
149
150
  }
150
151
  }
151
152
  }
152
- a.children && P(e, a.children, n);
153
+ a.children && E(e, a.children, n);
153
154
  }
154
- }, O = async (e, t, s = []) => {
155
+ }, H = async (e, t, s = []) => {
155
156
  const a = (o, n) => {
156
157
  for (const r of o) {
157
158
  const i = r.module?.metadata?.moduleId, l = [
@@ -166,7 +167,7 @@ const D = (e, t, s) => {
166
167
  const h = u.replace("stream_", ""), d = r.module[u];
167
168
  if (d?.__isVeloEventStream) {
168
169
  const m = `/_event/${i}/${h}`;
169
- d.__path = m, k(
170
+ d.__path = m, D(
170
171
  e,
171
172
  m,
172
173
  d,
@@ -179,7 +180,7 @@ const D = (e, t, s) => {
179
180
  }
180
181
  };
181
182
  a(t, s);
182
- }, G = (e, t) => t ? t.startsWith("/") ? e + t : e ? e + "/" + t : "/" + t : e || "", H = (e) => {
183
+ }, x = (e, t) => t ? t.startsWith("/") ? e + t : e ? e + "/" + t : "/" + t : e || "", V = (e) => {
183
184
  const t = /* @__PURE__ */ new Set(), s = (a) => {
184
185
  for (const o of a) {
185
186
  if (o.module && !o.children) {
@@ -190,9 +191,9 @@ const D = (e, t, s) => {
190
191
  }
191
192
  };
192
193
  return s(e), t;
193
- }, E = (e, t, s, a = "", o = []) => {
194
+ }, R = (e, t, s, a = "", o = []) => {
194
195
  for (const n of t) {
195
- const r = G(a, n.path), i = [
196
+ const r = x(a, n.path), i = [
196
197
  ...o,
197
198
  ...n.middlewares || []
198
199
  ], l = !!n.handler, c = !!n.method;
@@ -216,7 +217,7 @@ const D = (e, t, s) => {
216
217
  });
217
218
  i.length > 0 ? e.on([h], [r], ...i, m) : e.on([h], [r], m);
218
219
  }
219
- n.children && E(
220
+ n.children && R(
220
221
  e,
221
222
  n.children,
222
223
  s,
@@ -224,34 +225,34 @@ const D = (e, t, s) => {
224
225
  i
225
226
  );
226
227
  }
227
- }, x = async (e) => {
228
- const t = new R();
229
- t.use(T()), process.env.NODE_ENV !== "production" && t.use("*", b());
228
+ }, W = async (e) => {
229
+ const t = new q();
230
+ t.use(j()), process.env.NODE_ENV !== "production" && t.use("*", T());
230
231
  const a = v().pendingRoutes.splice(0);
231
232
  for (const n of a)
232
233
  await n(t);
233
- w(t, e), P(t, e), await O(t, e);
234
- const o = H(e);
235
- if (E(t, e, o), $(t), process.env.NODE_ENV !== "production" && !_) {
234
+ _(t, e), E(t, e), await H(t, e);
235
+ const o = V(e);
236
+ if (R(t, e, o), await I(t, e), $(t), process.env.NODE_ENV !== "production" && !w) {
236
237
  const n = globalThis.__veloDevServer;
237
- n && S(n);
238
+ n && (P(n), await y(t, n));
238
239
  }
239
240
  return t;
240
- }, X = async (e) => {
241
- const { routes: t, port: s = Number(process.env.SERVER_PORT) || 3e3 } = e, a = await x(t);
241
+ }, ee = async (e) => {
242
+ const { routes: t, port: s = Number(process.env.SERVER_PORT) || 3e3 } = e, a = await W(t);
242
243
  if (process.env.NODE_ENV === "production" && !process.env.VELO_STATIC) {
243
244
  const { serve: o } = await import("@hono/node-server"), { serveStatic: n } = await import("@hono/node-server/serve-static"), { join: r } = await import("node:path"), i = r(process.cwd(), "dist/client");
244
245
  (process.env.STATIC_BASE_URL || "").startsWith("http") || a.use("/*", n({ root: i })), console.log(`Server running on http://localhost:${s}`);
245
246
  const c = o({ fetch: a.fetch, port: s });
246
- S(c);
247
+ await y(a, c), P(c);
247
248
  }
248
249
  return a;
249
250
  };
250
251
  export {
251
- Q as addRoutes,
252
- x as createApp,
253
- x as default,
254
- z as onServer,
255
- y as serverDataStorage,
256
- X as startServer
252
+ Z as addRoutes,
253
+ W as createApp,
254
+ W as default,
255
+ Y as onServer,
256
+ S as serverDataStorage,
257
+ ee as startServer
257
258
  };
@@ -0,0 +1,94 @@
1
+ /**
2
+ * VeloJS Sockets — declarative WebSocket convention.
3
+ *
4
+ * Dev pattern: export `socket_<name>` from a page/layout module.
5
+ *
6
+ * ```typescript
7
+ * // app/workers/WorkerTerminal.tsx
8
+ * export const socket_terminal = async ({
9
+ * incoming, send, keepOpen, close, abortSignal, c, params, query,
10
+ * }) => {
11
+ * const user = c.get("user");
12
+ * const session = await createTerminal(params.workerId);
13
+ * session.on("data", (d) => send({ type: "data", data: d.toString() }));
14
+ * abortSignal.addEventListener("abort", () => session.destroy());
15
+ * keepOpen();
16
+ * for await (const raw of incoming) {
17
+ * const msg = JSON.parse(typeof raw === "string" ? raw : "");
18
+ * if (msg.type === "resize") session.resize(msg.cols, msg.rows);
19
+ * else if (msg.type === "data") session.write(msg.data);
20
+ * }
21
+ * };
22
+ * ```
23
+ *
24
+ * The plugin strips `socket_*` bodies from the client bundle and replaces them
25
+ * with a stub carrying `__path`. On the client, use `useSocket(socket_terminal)`.
26
+ */
27
+ import type { Context, Hono, MiddlewareHandler } from "hono";
28
+ import type { RouteNode } from "./types.js";
29
+ export interface SocketHandlerArgs {
30
+ /** Raw message frames from the client. Text frames → `string`, binary → `Uint8Array`. */
31
+ incoming: AsyncIterable<string | Uint8Array>;
32
+ /** Send a message. Objects are auto-serialized with `JSON.stringify`. */
33
+ send: (msg: string | Uint8Array | object) => void;
34
+ /** Close the socket imperatively. Accepts an optional WS close code + reason. */
35
+ close: (code?: number, reason?: string) => void;
36
+ /**
37
+ * Mark the socket as long-running. If the handler returns without calling
38
+ * `keepOpen()`, the framework closes the socket. When `keepOpen()` is set,
39
+ * the socket stays open until the abort signal fires.
40
+ *
41
+ * `for await (const msg of incoming)` naturally keeps the handler alive
42
+ * while messages flow — `keepOpen()` is redundant in that case but not
43
+ * harmful.
44
+ */
45
+ keepOpen: () => void;
46
+ /** Fires when the client disconnects, the server aborts, or `app.close()` is called. */
47
+ abortSignal: AbortSignal;
48
+ /** Hono Context — use `c.get("user")` etc. for middleware-provided values. */
49
+ c: Context;
50
+ /** URL params (e.g. `/:workerId`). */
51
+ params: Record<string, string>;
52
+ /** Query-string values. */
53
+ query: Record<string, string>;
54
+ }
55
+ export type SocketHandler = (args: SocketHandlerArgs) => void | Promise<void>;
56
+ /** Client-side stub shape — what the Vite plugin replaces `socket_*` with on the client bundle. */
57
+ export interface SocketStub {
58
+ readonly __isVeloSocket: true;
59
+ readonly __path: string;
60
+ }
61
+ /**
62
+ * Wraps a raw `incoming` iterable so each frame is JSON-parsed. Invalid JSON
63
+ * frames are skipped with a console warning (not thrown). Use when all client
64
+ * messages are JSON objects.
65
+ *
66
+ * ```typescript
67
+ * for await (const msg of parseJson<TerminalMsg>(incoming)) {
68
+ * if (msg.type === "resize") session.resize(msg.cols, msg.rows);
69
+ * }
70
+ * ```
71
+ */
72
+ export declare function parseJson<T = unknown>(incoming: AsyncIterable<string | Uint8Array>): AsyncIterable<T>;
73
+ interface RegisteredSocket {
74
+ path: string;
75
+ handler: SocketHandler;
76
+ middlewares: MiddlewareHandler[];
77
+ }
78
+ /** @internal Used by the testing toolkit so `app.close()` aborts in-memory sessions too. */
79
+ export declare function trackSocketSession(app: Hono, ctrl: AbortController): () => void;
80
+ /** @internal Abort every open socket session on `app`. Called by testing toolkit + disposers. */
81
+ export declare function abortAllSocketSessions(app: Hono): void;
82
+ /** @internal Returns registered sockets for `app` (used by the testing toolkit). */
83
+ export declare function getAppSockets(app: Hono): ReadonlyMap<string, RegisteredSocket>;
84
+ export declare function registerSocketHandler(app: Hono, path: string, handler: SocketHandler, middlewares?: MiddlewareHandler[]): Promise<void>;
85
+ /** Walks the route tree and registers every `socket_*` export. */
86
+ export declare function registerSocketRoutes(app: Hono, nodes: RouteNode[], parentMiddlewares?: MiddlewareHandler[]): Promise<void>;
87
+ /**
88
+ * Inject the WebSocket adapter into an HTTP server. Call after `serve()`
89
+ * returns (prod) or with Vite's dev http server (dev).
90
+ *
91
+ * No-op when no sockets are registered on `app`.
92
+ */
93
+ export declare function injectWebSocketServer(app: Hono, server: any): Promise<void>;
94
+ export {};