@mauroandre/velojs 0.0.57 → 0.0.59
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 +91 -2
- package/agent/AGENTS.md +2 -0
- package/agent/skills/velojs-live-loader/SKILL.md +3 -1
- package/agent/skills/velojs-production-deploy/SKILL.md +7 -1
- package/agent/skills/velojs-telemetry/SKILL.md +182 -0
- package/dist/channels.d.ts +8 -1
- package/dist/channels.js +282 -227
- package/dist/cli.js +46 -32
- package/dist/events.d.ts +9 -1
- package/dist/events.js +161 -152
- package/dist/server.js +245 -198
- package/dist/sockets.d.ts +4 -1
- package/dist/sockets.js +115 -102
- package/dist/telemetry-cli.d.ts +67 -0
- package/dist/telemetry-cli.js +265 -0
- package/dist/telemetry-node.d.ts +38 -0
- package/dist/telemetry-node.js +93 -0
- package/dist/telemetry.d.ts +204 -0
- package/dist/telemetry.js +240 -0
- package/package.json +1 -1
package/dist/channels.js
CHANGED
|
@@ -1,34 +1,48 @@
|
|
|
1
|
-
import { DEFAULT_HEARTBEAT_MS as
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
1
|
+
import { DEFAULT_HEARTBEAT_MS as H } from "./events.js";
|
|
2
|
+
import { trace as P, spanRecorder as W, byteLength as le } from "./telemetry.js";
|
|
3
|
+
const F = "snapshot", Q = "slice", ce = "error", ue = "close", B = 50, K = 3e5;
|
|
4
|
+
let f = {}, R = B, N = K, O = H, Y = !0;
|
|
5
|
+
function je(e, t) {
|
|
6
|
+
f = e ? { ...e } : {}, R = t?.coalesceMs ?? B, N = t?.idleMs ?? K, O = t?.heartbeatMs ?? H, Y = t?.logEmits ?? !0, X(), S.clear();
|
|
6
7
|
}
|
|
7
|
-
function
|
|
8
|
-
return
|
|
8
|
+
function Ae() {
|
|
9
|
+
return f;
|
|
9
10
|
}
|
|
10
|
-
function
|
|
11
|
-
return Object.keys(
|
|
11
|
+
function ke() {
|
|
12
|
+
return Object.keys(f);
|
|
12
13
|
}
|
|
13
|
-
const
|
|
14
|
-
function
|
|
15
|
-
const
|
|
16
|
-
if (
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
}
|
|
20
|
-
|
|
14
|
+
const d = /* @__PURE__ */ new Map(), S = /* @__PURE__ */ new Map(), b = /* @__PURE__ */ new Map();
|
|
15
|
+
function de(e, t, n) {
|
|
16
|
+
const o = D(e, t), r = b.get(o);
|
|
17
|
+
if (r) {
|
|
18
|
+
n && r.gestures.push(n);
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
const s = {
|
|
22
|
+
timer: void 0,
|
|
23
|
+
channel: e,
|
|
24
|
+
partition: t,
|
|
25
|
+
gestures: n ? [n] : []
|
|
26
|
+
}, i = setTimeout(() => {
|
|
27
|
+
b.delete(o), fe(s);
|
|
28
|
+
}, R), c = i.unref;
|
|
29
|
+
typeof c == "function" && c.call(i), s.timer = i, b.set(o, s);
|
|
21
30
|
}
|
|
22
|
-
function
|
|
23
|
-
|
|
24
|
-
|
|
31
|
+
async function fe(e) {
|
|
32
|
+
const t = W(), n = await te(e.channel, e.partition, t);
|
|
33
|
+
for (const o of e.gestures)
|
|
34
|
+
o.addSpans(t.spans), o.end({ status: "ok", connections: n });
|
|
25
35
|
}
|
|
26
|
-
function
|
|
36
|
+
function X() {
|
|
37
|
+
for (const e of b.values()) clearTimeout(e.timer);
|
|
38
|
+
b.clear();
|
|
39
|
+
}
|
|
40
|
+
function Ce() {
|
|
27
41
|
const e = [];
|
|
28
42
|
let t = 0;
|
|
29
|
-
for (const [
|
|
43
|
+
for (const [o, r] of d) {
|
|
30
44
|
const s = [];
|
|
31
|
-
for (const [
|
|
45
|
+
for (const [i, c] of r) {
|
|
32
46
|
const p = /* @__PURE__ */ new Map();
|
|
33
47
|
for (const a of c) {
|
|
34
48
|
const u = p.get(a.moduleId) ?? { count: 0, last: void 0 };
|
|
@@ -37,120 +51,125 @@ function ve() {
|
|
|
37
51
|
for (const [a, u] of p)
|
|
38
52
|
s.push({
|
|
39
53
|
moduleId: a,
|
|
40
|
-
partition:
|
|
54
|
+
partition: i,
|
|
41
55
|
connections: u.count,
|
|
42
56
|
lastDeliveryAt: u.last === void 0 ? null : new Date(u.last).toISOString()
|
|
43
57
|
});
|
|
44
58
|
}
|
|
45
59
|
e.push({
|
|
46
|
-
channel:
|
|
60
|
+
channel: o,
|
|
47
61
|
groups: s,
|
|
48
|
-
connections:
|
|
49
|
-
}), t +=
|
|
62
|
+
connections: U(r)
|
|
63
|
+
}), t += U(r);
|
|
50
64
|
}
|
|
51
|
-
const
|
|
52
|
-
for (const
|
|
53
|
-
|
|
54
|
-
return { channels: e, openCoalesceWindows:
|
|
65
|
+
const n = [];
|
|
66
|
+
for (const o of b.values())
|
|
67
|
+
n.push({ channel: o.channel, partition: o.partition });
|
|
68
|
+
return { channels: e, openCoalesceWindows: n, totalConnections: t };
|
|
55
69
|
}
|
|
56
|
-
function
|
|
70
|
+
function U(e) {
|
|
57
71
|
let t = 0;
|
|
58
|
-
for (const
|
|
72
|
+
for (const n of e.values()) t += n.size;
|
|
59
73
|
return t;
|
|
60
74
|
}
|
|
61
|
-
function
|
|
75
|
+
function D(e, t) {
|
|
62
76
|
return `${e}\0${t}`;
|
|
63
77
|
}
|
|
64
|
-
function
|
|
65
|
-
let t =
|
|
66
|
-
t || (t = /* @__PURE__ */ new Map(),
|
|
67
|
-
let
|
|
68
|
-
|
|
69
|
-
const
|
|
70
|
-
return
|
|
78
|
+
function pe(e) {
|
|
79
|
+
let t = d.get(e.channel);
|
|
80
|
+
t || (t = /* @__PURE__ */ new Map(), d.set(e.channel, t));
|
|
81
|
+
let n = t.get(e.partition);
|
|
82
|
+
n || (n = /* @__PURE__ */ new Set(), t.set(e.partition, n));
|
|
83
|
+
const o = n.size === 0;
|
|
84
|
+
return n.add(e), o;
|
|
71
85
|
}
|
|
72
|
-
function
|
|
73
|
-
const t =
|
|
74
|
-
if (!t || !
|
|
75
|
-
|
|
76
|
-
const
|
|
77
|
-
return
|
|
86
|
+
function V(e) {
|
|
87
|
+
const t = d.get(e.channel), n = t?.get(e.partition);
|
|
88
|
+
if (!t || !n) return !1;
|
|
89
|
+
n.delete(e);
|
|
90
|
+
const o = n.size === 0;
|
|
91
|
+
return o && t.delete(e.partition), t.size === 0 && d.delete(e.channel), o;
|
|
78
92
|
}
|
|
79
|
-
function
|
|
80
|
-
const
|
|
81
|
-
if (typeof
|
|
93
|
+
function Z(e, t, n) {
|
|
94
|
+
const o = D(e, t), r = f[e]?.onGroupOpen, s = (async () => {
|
|
95
|
+
if (typeof r == "function")
|
|
82
96
|
try {
|
|
83
|
-
await
|
|
84
|
-
} catch (
|
|
97
|
+
await r({ partition: t, params: n });
|
|
98
|
+
} catch (i) {
|
|
85
99
|
console.error(
|
|
86
100
|
`[velojs] channel "${e}" onGroupOpen failed for partition "${t}":`,
|
|
87
|
-
|
|
101
|
+
i
|
|
88
102
|
);
|
|
89
103
|
}
|
|
90
104
|
})();
|
|
91
|
-
return
|
|
92
|
-
|
|
105
|
+
return S.set(o, s), s.then(() => {
|
|
106
|
+
S.get(o) === s && S.delete(o);
|
|
93
107
|
}), s;
|
|
94
108
|
}
|
|
95
|
-
async function
|
|
96
|
-
const t =
|
|
97
|
-
|
|
98
|
-
const
|
|
99
|
-
if (!
|
|
100
|
-
|
|
109
|
+
async function me(e) {
|
|
110
|
+
const t = D(e.channel, e.partition), n = S.get(t);
|
|
111
|
+
n && await n;
|
|
112
|
+
const o = d.get(e.channel)?.get(e.partition);
|
|
113
|
+
if (!o || !o.has(e) || o.size > 1) {
|
|
114
|
+
V(e);
|
|
101
115
|
return;
|
|
102
116
|
}
|
|
103
|
-
const
|
|
104
|
-
if (typeof
|
|
117
|
+
const r = f[e.channel]?.onGroupClose;
|
|
118
|
+
if (typeof r == "function")
|
|
105
119
|
try {
|
|
106
|
-
await
|
|
120
|
+
await r({ partition: e.partition });
|
|
107
121
|
} catch (c) {
|
|
108
122
|
console.error(
|
|
109
123
|
`[velojs] channel "${e.channel}" onGroupClose failed for partition "${e.partition}":`,
|
|
110
124
|
c
|
|
111
125
|
);
|
|
112
126
|
}
|
|
113
|
-
|
|
114
|
-
const s =
|
|
115
|
-
|
|
127
|
+
V(e);
|
|
128
|
+
const s = d.get(e.channel)?.get(e.partition), i = s ? [...s][0] : void 0;
|
|
129
|
+
i && await Z(e.channel, e.partition, i.params);
|
|
116
130
|
}
|
|
117
|
-
function
|
|
118
|
-
|
|
131
|
+
function Te() {
|
|
132
|
+
d.clear(), S.clear(), X();
|
|
119
133
|
}
|
|
120
134
|
async function T(e, t) {
|
|
121
|
-
const
|
|
122
|
-
return typeof
|
|
135
|
+
const n = e.scope;
|
|
136
|
+
return typeof n != "function" ? "all" : await n(t);
|
|
123
137
|
}
|
|
124
|
-
function
|
|
138
|
+
function he(e, t) {
|
|
125
139
|
return e.get(t);
|
|
126
140
|
}
|
|
127
|
-
async function
|
|
128
|
-
const
|
|
129
|
-
if (!
|
|
130
|
-
const
|
|
131
|
-
for (const s of [...
|
|
132
|
-
let
|
|
141
|
+
async function ee(e, t) {
|
|
142
|
+
const n = d.get(e)?.get(t);
|
|
143
|
+
if (!n || n.size === 0) return null;
|
|
144
|
+
const o = f[e], r = [];
|
|
145
|
+
for (const s of [...n]) {
|
|
146
|
+
let i;
|
|
133
147
|
try {
|
|
134
|
-
|
|
148
|
+
i = await T(o, {
|
|
135
149
|
user: s.principal,
|
|
136
150
|
params: s.params
|
|
137
151
|
});
|
|
138
152
|
} catch (c) {
|
|
139
|
-
console.error(`[velojs] channel "${e}" scope threw on emit:`, c),
|
|
153
|
+
console.error(`[velojs] channel "${e}" scope threw on emit:`, c), i = null;
|
|
140
154
|
}
|
|
141
|
-
if (
|
|
155
|
+
if (i == null || i !== t) {
|
|
142
156
|
await s.terminate();
|
|
143
157
|
continue;
|
|
144
158
|
}
|
|
145
|
-
|
|
159
|
+
r.push(s);
|
|
146
160
|
}
|
|
147
|
-
return
|
|
161
|
+
return r.length > 0 ? r : null;
|
|
148
162
|
}
|
|
149
|
-
async function
|
|
150
|
-
const
|
|
151
|
-
|
|
163
|
+
async function te(e, t, n) {
|
|
164
|
+
const o = await ee(e, t);
|
|
165
|
+
return o ? (await Promise.all(
|
|
166
|
+
o.map(async (r) => {
|
|
167
|
+
const s = n.span(`loader:${r.moduleId}`), i = await ne(r);
|
|
168
|
+
s.end(i);
|
|
169
|
+
})
|
|
170
|
+
), o.length) : 0;
|
|
152
171
|
}
|
|
153
|
-
async function
|
|
172
|
+
async function ne(e) {
|
|
154
173
|
let t;
|
|
155
174
|
try {
|
|
156
175
|
t = await e.loader({
|
|
@@ -158,219 +177,255 @@ async function X(e) {
|
|
|
158
177
|
query: e.query,
|
|
159
178
|
c: e.c
|
|
160
179
|
});
|
|
161
|
-
} catch (
|
|
162
|
-
await e.send(
|
|
163
|
-
|
|
180
|
+
} catch (n) {
|
|
181
|
+
return await e.send(
|
|
182
|
+
ce,
|
|
164
183
|
JSON.stringify({
|
|
165
|
-
message:
|
|
184
|
+
message: n instanceof Error ? n.message : String(n)
|
|
166
185
|
})
|
|
167
|
-
);
|
|
168
|
-
return;
|
|
186
|
+
), "error";
|
|
169
187
|
}
|
|
170
|
-
t instanceof Response || await e.send(
|
|
188
|
+
return t instanceof Response || await e.send(F, JSON.stringify(t ?? null)), "ok";
|
|
171
189
|
}
|
|
172
|
-
function
|
|
173
|
-
return typeof e == "string" ?
|
|
190
|
+
function _e(e, t, n, o) {
|
|
191
|
+
return typeof e == "string" ? ye(e, t ?? {}) : we(e, t, n, o);
|
|
174
192
|
}
|
|
175
|
-
async function
|
|
176
|
-
const
|
|
177
|
-
if (!
|
|
193
|
+
async function ye(e, t) {
|
|
194
|
+
const n = f[e];
|
|
195
|
+
if (!n)
|
|
178
196
|
throw new Error(
|
|
179
197
|
`[velojs] emit("${e}"): this channel has no entry in app/channels.ts. Add one — a typo or a renamed channel would otherwise be a silent no-op.`
|
|
180
198
|
);
|
|
181
|
-
const
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
199
|
+
const o = await T(n, t), r = o == null ? 0 : d.get(e)?.get(o)?.size ?? 0;
|
|
200
|
+
oe(e, o, "invalidate", r);
|
|
201
|
+
const s = P("emit", {
|
|
202
|
+
channel: e,
|
|
203
|
+
partition: o ?? null,
|
|
204
|
+
mode: "invalidate",
|
|
205
|
+
connections: r
|
|
206
|
+
});
|
|
207
|
+
if (o == null) {
|
|
208
|
+
s.end({ status: "ok", connections: 0 });
|
|
209
|
+
return;
|
|
210
|
+
}
|
|
211
|
+
if (r === 0) {
|
|
212
|
+
s.end({ status: "ok", connections: 0 });
|
|
213
|
+
return;
|
|
188
214
|
}
|
|
215
|
+
if (R <= 0) {
|
|
216
|
+
const i = W(), c = await te(e, o, i);
|
|
217
|
+
s.addSpans(i.spans), s.end({ status: "ok", connections: c });
|
|
218
|
+
return;
|
|
219
|
+
}
|
|
220
|
+
de(e, o, s);
|
|
189
221
|
}
|
|
190
|
-
async function
|
|
191
|
-
const
|
|
192
|
-
if (!
|
|
222
|
+
async function we(e, t, n, o) {
|
|
223
|
+
const r = e?.metadata?.moduleId;
|
|
224
|
+
if (!r)
|
|
193
225
|
throw new Error(
|
|
194
226
|
`[velojs] emit(module, "${t}", …): the module has no metadata.moduleId — pass the imported route module (the Vite plugin injects its metadata), the same object the route tree uses.`
|
|
195
227
|
);
|
|
196
228
|
const s = e.channels;
|
|
197
229
|
if (!Array.isArray(s) || !s.includes(t))
|
|
198
230
|
throw new Error(
|
|
199
|
-
`[velojs] emit(module, "${t}", …): module "${
|
|
231
|
+
`[velojs] emit(module, "${t}", …): module "${r}" does not declare channel "${t}" — add it to the module's \`channels\` export, or use emit("${t}", ctx) for the invalidation mode.`
|
|
200
232
|
);
|
|
201
233
|
if (typeof e.loader != "function")
|
|
202
234
|
throw new Error(
|
|
203
|
-
`[velojs] emit(module, "${t}", …): module "${
|
|
235
|
+
`[velojs] emit(module, "${t}", …): module "${r}" has no \`loader\` — there is no data shape to slice.`
|
|
204
236
|
);
|
|
205
|
-
const
|
|
206
|
-
if (!
|
|
237
|
+
const i = f[t];
|
|
238
|
+
if (!i)
|
|
207
239
|
throw new Error(
|
|
208
240
|
`[velojs] emit(module, "${t}", …): this channel has no entry in app/channels.ts. Add one — a typo or a renamed channel would otherwise be a silent no-op.`
|
|
209
241
|
);
|
|
210
|
-
if (
|
|
242
|
+
if (o === null || typeof o != "object" || Array.isArray(o))
|
|
211
243
|
throw new Error(
|
|
212
|
-
`[velojs] emit(module, "${t}", …): the slice must be the object of changed keys — got ${
|
|
244
|
+
`[velojs] emit(module, "${t}", …): the slice must be the object of changed keys — got ${o === null ? "null" : Array.isArray(o) ? "an array" : typeof o}.`
|
|
213
245
|
);
|
|
214
|
-
const c = await T(
|
|
215
|
-
|
|
216
|
-
const u =
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
246
|
+
const c = await T(i, n), p = c == null ? void 0 : d.get(t)?.get(c), a = p?.size ?? 0;
|
|
247
|
+
oe(t, c, "slice", a);
|
|
248
|
+
const u = P("emit", {
|
|
249
|
+
channel: t,
|
|
250
|
+
partition: c ?? null,
|
|
251
|
+
mode: "slice",
|
|
252
|
+
connections: a
|
|
253
|
+
});
|
|
254
|
+
if (c == null) {
|
|
255
|
+
u.end({ status: "ok", connections: 0 });
|
|
256
|
+
return;
|
|
257
|
+
}
|
|
258
|
+
if (!p || a === 0) {
|
|
259
|
+
u.end({ status: "ok", connections: 0 });
|
|
260
|
+
return;
|
|
261
|
+
}
|
|
262
|
+
const m = await ee(t, c);
|
|
263
|
+
if (!m) {
|
|
264
|
+
u.end({ status: "ok", connections: 0 });
|
|
265
|
+
return;
|
|
266
|
+
}
|
|
267
|
+
const y = m.filter((E) => E.moduleId === r);
|
|
268
|
+
if (y.length === 0) {
|
|
269
|
+
u.end({ status: "ok", connections: 0 });
|
|
270
|
+
return;
|
|
271
|
+
}
|
|
272
|
+
const j = JSON.stringify(o);
|
|
273
|
+
await Promise.all(y.map((E) => E.send(Q, j))), u.end({ status: "ok", connections: y.length });
|
|
222
274
|
}
|
|
223
|
-
function
|
|
224
|
-
if (!
|
|
225
|
-
const
|
|
275
|
+
function oe(e, t, n, o) {
|
|
276
|
+
if (!Y) return;
|
|
277
|
+
const r = typeof t == "string" ? `"${t}"` : "null";
|
|
226
278
|
console.log(
|
|
227
|
-
`[velojs] emit kind=${
|
|
279
|
+
`[velojs] emit kind=${n} channel="${e}" partition=${r} connections=${o} at=${(/* @__PURE__ */ new Date()).toISOString()}`
|
|
228
280
|
);
|
|
229
281
|
}
|
|
230
|
-
function
|
|
231
|
-
let
|
|
232
|
-
return (
|
|
233
|
-
}).catch((
|
|
282
|
+
function ge(e, t) {
|
|
283
|
+
let n = Promise.resolve();
|
|
284
|
+
return (o) => (n = n.then(() => t(o)).then(() => {
|
|
285
|
+
}).catch((r) => {
|
|
234
286
|
console.warn(
|
|
235
287
|
`[velojs] channel "${e}": SSE write failed — the snapshot did not reach the client:`,
|
|
236
|
-
|
|
288
|
+
r
|
|
237
289
|
);
|
|
238
|
-
}),
|
|
290
|
+
}), n);
|
|
239
291
|
}
|
|
240
292
|
const C = "_route";
|
|
241
|
-
function
|
|
293
|
+
function ve(e) {
|
|
242
294
|
return e ? e.split("/").filter((t) => t.startsWith(":")).map((t) => t.slice(1)) : [];
|
|
243
295
|
}
|
|
244
|
-
function
|
|
296
|
+
function Ee(e, t) {
|
|
245
297
|
if (e == null || e === "")
|
|
246
298
|
return { params: {}, error: null };
|
|
247
|
-
let
|
|
299
|
+
let n;
|
|
248
300
|
try {
|
|
249
|
-
|
|
301
|
+
n = JSON.parse(e);
|
|
250
302
|
} catch {
|
|
251
303
|
return { params: {}, error: `the ?${C}= payload is not valid JSON` };
|
|
252
304
|
}
|
|
253
|
-
if (
|
|
305
|
+
if (n === null || typeof n != "object" || Array.isArray(n))
|
|
254
306
|
return {
|
|
255
307
|
params: {},
|
|
256
308
|
error: `the ?${C}= payload must be an object of route params`
|
|
257
309
|
};
|
|
258
|
-
const
|
|
259
|
-
for (const [
|
|
260
|
-
if (!t.includes(
|
|
261
|
-
const
|
|
310
|
+
const o = {};
|
|
311
|
+
for (const [r, s] of Object.entries(n)) {
|
|
312
|
+
if (!t.includes(r)) {
|
|
313
|
+
const i = t.length > 0 ? t.join(", ") : "none";
|
|
262
314
|
return {
|
|
263
315
|
params: {},
|
|
264
|
-
error: `route param "${
|
|
316
|
+
error: `route param "${r}" is not declared by the module's path (declared: ${i})`
|
|
265
317
|
};
|
|
266
318
|
}
|
|
267
319
|
if (typeof s != "string")
|
|
268
|
-
return { params: {}, error: `route param "${
|
|
269
|
-
|
|
320
|
+
return { params: {}, error: `route param "${r}" must be a URL string` };
|
|
321
|
+
o[r] = s;
|
|
270
322
|
}
|
|
271
|
-
return { params:
|
|
323
|
+
return { params: o, error: null };
|
|
272
324
|
}
|
|
273
|
-
function
|
|
274
|
-
if (typeof
|
|
325
|
+
function Me(e, t, n, o, r, s) {
|
|
326
|
+
if (typeof o.loader != "function")
|
|
275
327
|
throw new Error(
|
|
276
|
-
`[velojs] module "${
|
|
328
|
+
`[velojs] module "${r}" declares \`channels\` without a \`loader\` — there is nothing to synchronize. Add a loader or remove the export.`
|
|
277
329
|
);
|
|
278
|
-
if (!
|
|
330
|
+
if (!f[n])
|
|
279
331
|
throw new Error(
|
|
280
|
-
`[velojs] module "${
|
|
332
|
+
`[velojs] module "${r}" declares channel "${n}" with no entry in app/channels.ts — add the partition resolver for "${n}".`
|
|
281
333
|
);
|
|
282
|
-
const
|
|
283
|
-
const u =
|
|
334
|
+
const i = o.loader, c = ve(o.metadata?.fullPath), p = async (a) => {
|
|
335
|
+
const u = f[n], m = P("channel-connect", { route: t, module: r, channel: n }), y = Ee(
|
|
284
336
|
a.req.query(C),
|
|
285
337
|
c
|
|
286
338
|
);
|
|
287
|
-
if (
|
|
288
|
-
return console.error(`[velojs] channel "${
|
|
289
|
-
const
|
|
290
|
-
let
|
|
339
|
+
if (y.error)
|
|
340
|
+
return console.error(`[velojs] channel "${n}": rejecting subscription — ${y.error}`), m.end({ status: "error" }), a.json({ error: "invalid-route-params", message: y.error }, 400);
|
|
341
|
+
const j = y.params, E = he(a, "user");
|
|
342
|
+
let A;
|
|
291
343
|
try {
|
|
292
|
-
|
|
293
|
-
} catch (
|
|
294
|
-
return console.error(`[velojs] channel "${
|
|
344
|
+
A = await T(u, { user: E, params: j });
|
|
345
|
+
} catch (w) {
|
|
346
|
+
return console.error(`[velojs] channel "${n}" scope threw:`, w), m.end({ status: "error" }), a.json({ error: "forbidden" }, 403);
|
|
295
347
|
}
|
|
296
|
-
if (
|
|
297
|
-
return a.json({ error: "forbidden" }, 403);
|
|
298
|
-
const { streamSSE:
|
|
299
|
-
for (const [
|
|
300
|
-
|
|
301
|
-
const
|
|
302
|
-
let
|
|
348
|
+
if (A == null)
|
|
349
|
+
return m.end({ status: "error" }), a.json({ error: "forbidden" }, 403);
|
|
350
|
+
const { streamSSE: re } = await import("hono/streaming"), I = {};
|
|
351
|
+
for (const [w, h] of Object.entries(a.req.query()))
|
|
352
|
+
w !== C && (I[w] = h);
|
|
353
|
+
const k = await re(a, async (w) => {
|
|
354
|
+
let h = !1, L = () => {
|
|
303
355
|
};
|
|
304
|
-
const
|
|
305
|
-
|
|
306
|
-
}), _ =
|
|
307
|
-
|
|
308
|
-
(
|
|
309
|
-
),
|
|
310
|
-
channel:
|
|
311
|
-
partition:
|
|
312
|
-
moduleId:
|
|
313
|
-
principal:
|
|
314
|
-
loader:
|
|
356
|
+
const se = new Promise((l) => {
|
|
357
|
+
L = l;
|
|
358
|
+
}), _ = ge(
|
|
359
|
+
n,
|
|
360
|
+
(l) => typeof l == "string" ? w.write(l) : w.writeSSE(l)
|
|
361
|
+
), g = {
|
|
362
|
+
channel: n,
|
|
363
|
+
partition: A,
|
|
364
|
+
moduleId: r,
|
|
365
|
+
principal: E,
|
|
366
|
+
loader: i,
|
|
315
367
|
c: a,
|
|
316
|
-
params:
|
|
317
|
-
query:
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
let y = null;
|
|
328
|
-
const L = () => {
|
|
329
|
-
if (M <= 0 || m) return;
|
|
330
|
-
y !== null && clearTimeout(y), y = setTimeout(() => {
|
|
331
|
-
y = null, z("idle");
|
|
332
|
-
}, M);
|
|
333
|
-
const i = y.unref;
|
|
334
|
-
typeof i == "function" && i.call(y);
|
|
368
|
+
params: j,
|
|
369
|
+
query: I,
|
|
370
|
+
telemetry: m,
|
|
371
|
+
send: (l, M) => h ? Promise.resolve() : l === F || l === Q ? (g.telemetry?.enabled && g.telemetry.delivery(le(M)), _({ event: l, data: M }).then(() => {
|
|
372
|
+
h || (g.lastDeliveryAt = Date.now(), x());
|
|
373
|
+
})) : _({ event: l, data: M }),
|
|
374
|
+
terminate: (l) => q(l)
|
|
375
|
+
}, G = () => {
|
|
376
|
+
h || (h = !0, v !== null && clearTimeout(v), $ !== null && clearInterval($), L(), g.telemetry?.close(), me(g));
|
|
377
|
+
}, q = async (l = "partition") => {
|
|
378
|
+
h || (await g.send(ue, JSON.stringify({ reason: l })), G());
|
|
335
379
|
};
|
|
336
380
|
let v = null;
|
|
337
|
-
|
|
338
|
-
|
|
381
|
+
const x = () => {
|
|
382
|
+
if (N <= 0 || h) return;
|
|
383
|
+
v !== null && clearTimeout(v), v = setTimeout(() => {
|
|
384
|
+
v = null, q("idle");
|
|
385
|
+
}, N);
|
|
386
|
+
const l = v.unref;
|
|
387
|
+
typeof l == "function" && l.call(v);
|
|
388
|
+
};
|
|
389
|
+
let $ = null;
|
|
390
|
+
O > 0 && ($ = setInterval(() => {
|
|
391
|
+
h || _(`: ping
|
|
339
392
|
|
|
340
393
|
`);
|
|
341
|
-
},
|
|
342
|
-
const
|
|
343
|
-
if (
|
|
344
|
-
const
|
|
345
|
-
typeof
|
|
394
|
+
}, O));
|
|
395
|
+
const ie = pe(g);
|
|
396
|
+
if (w.onAbort(G), x(), $ !== null) {
|
|
397
|
+
const l = $.unref;
|
|
398
|
+
typeof l == "function" && l.call($);
|
|
346
399
|
}
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
400
|
+
ie && await Z(n, A, j);
|
|
401
|
+
const ae = m.span("snapshot"), J = await ne(g);
|
|
402
|
+
ae.end(J), m.end({ status: J }), await se;
|
|
403
|
+
}), z = new Headers(k.headers);
|
|
404
|
+
return z.set("Cache-Control", "no-store"), new Response(k.body, {
|
|
405
|
+
status: k.status,
|
|
406
|
+
statusText: k.statusText,
|
|
407
|
+
headers: z
|
|
353
408
|
});
|
|
354
409
|
};
|
|
355
410
|
s.length > 0 ? e.on(["GET"], [t], ...s, p) : e.on(["GET"], [t], p);
|
|
356
411
|
}
|
|
357
412
|
export {
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
413
|
+
ue as CHANNEL_CLOSE_EVENT,
|
|
414
|
+
ce as CHANNEL_ERROR_EVENT,
|
|
415
|
+
B as DEFAULT_COALESCE_MS,
|
|
416
|
+
K as DEFAULT_IDLE_MS,
|
|
362
417
|
C as ROUTE_PARAMS_QUERY,
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
418
|
+
Q as SLICE_EVENT,
|
|
419
|
+
F as SNAPSHOT_EVENT,
|
|
420
|
+
Te as __resetChannels,
|
|
421
|
+
ke as channelNames,
|
|
422
|
+
ge as createChannelWriteChain,
|
|
423
|
+
ve as declaredRouteParams,
|
|
424
|
+
_e as emit,
|
|
425
|
+
Ae as getChannelMap,
|
|
426
|
+
Ce as inspectChannels,
|
|
427
|
+
Ee as parseRouteParamsQuery,
|
|
428
|
+
ne as pushSnapshot,
|
|
429
|
+
Me as registerChannelRoute,
|
|
430
|
+
je as registerChannels
|
|
376
431
|
};
|