@candypoets/nipworker 0.91.2 → 0.92.0

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.
@@ -1,50 +1,49 @@
1
1
  import * as A from "flatbuffers";
2
- import { WebSocketServer as w, WebSocket as m } from "ws";
3
- import { SocksProxyAgent as v } from "socks-proxy-agent";
4
- import { C as T, W as E, M as k, G as M, R as F, N as C, S as N } from "./worker-message.js";
5
- function q(t = {}) {
6
- const r = t.host ?? "127.0.0.1", n = t.port ?? 7777, e = t.path ?? "/", s = t.logger ?? console, o = t.torSocksProxy;
7
- let f;
2
+ import { WebSocketServer as b, WebSocket as m } from "ws";
3
+ import { SocksProxyAgent as R } from "socks-proxy-agent";
4
+ import { C as T, W as M, M as N, G as I, R as W, N as B, S as v } from "./worker-message.js";
5
+ function X(t = {}) {
6
+ const n = t.host ?? "127.0.0.1", r = t.port ?? 7777, e = t.path ?? "/", o = t.logger ?? console, a = t.torSocksProxy;
7
+ let s;
8
8
  try {
9
- f = new w({
10
- host: r,
11
- port: n,
9
+ s = new b({
10
+ host: n,
11
+ port: r,
12
12
  path: e
13
13
  });
14
14
  } catch (i) {
15
- throw s.error(`[relay-proxy] failed to create WebSocketServer: ${String(i)}`), i;
15
+ throw o.error(`[relay-proxy] failed to create WebSocketServer: ${String(i)}`), i;
16
16
  }
17
- let a = n;
18
- const c = f.address();
19
- return c && typeof c == "object" && (a = c.port), f.on("error", (i) => {
20
- s.error(`[relay-proxy] WebSocketServer error: ${String(i)}`);
21
- }), f.on("connection", (i) => {
17
+ let f = r;
18
+ const c = s.address();
19
+ return c && typeof c == "object" && (f = c.port), s.on("error", (i) => {
20
+ o.error(`[relay-proxy] WebSocketServer error: ${String(i)}`);
21
+ }), s.on("connection", (i) => {
22
22
  const u = {
23
23
  relaySockets: /* @__PURE__ */ new Map(),
24
24
  pendingFrames: /* @__PURE__ */ new Map(),
25
25
  dedupBySubId: /* @__PURE__ */ new Map(),
26
26
  lastSubIdByRelay: /* @__PURE__ */ new Map(),
27
- torSocksProxy: o,
28
- lastAuthChallenge: /* @__PURE__ */ new Map()
27
+ torSocksProxy: a
29
28
  };
30
- i.on("message", (y, p) => {
31
- if (p) {
32
- const d = $(y);
33
- if (!d) return;
34
- x(u, i, d, s);
29
+ i.on("message", (y, d) => {
30
+ if (d) {
31
+ const p = k(y);
32
+ if (!p) return;
33
+ E(u, i, p, o);
35
34
  return;
36
35
  }
37
- const l = h(y);
38
- l && b(u, l, s);
36
+ const g = $(y);
37
+ g && O(u, g, o);
39
38
  }), i.on("close", () => {
40
- g(u, s);
39
+ l(u, o);
41
40
  }), i.on("error", () => {
42
- g(u, s);
41
+ l(u, o);
43
42
  });
44
- }), s.info(`[relay-proxy] listening on ws://${r}:${a}${e}`), {
45
- port: a,
43
+ }), o.info(`[relay-proxy] listening on ws://${n}:${f}${e}`), {
44
+ port: f,
46
45
  close: () => new Promise((i, u) => {
47
- f.close((y) => {
46
+ s.close((y) => {
48
47
  if (y) {
49
48
  u(y);
50
49
  return;
@@ -54,11 +53,11 @@ function q(t = {}) {
54
53
  })
55
54
  };
56
55
  }
57
- function X(t) {
58
- const r = t.path ?? "/", n = t.logger ?? console, e = t.torSocksProxy, s = new w({
56
+ function Y(t) {
57
+ const n = t.path ?? "/", r = t.logger ?? console, e = t.torSocksProxy, o = new b({
59
58
  noServer: true
60
- }), o = /* @__PURE__ */ new Map();
61
- return s.on("connection", (a) => {
59
+ }), a = /* @__PURE__ */ new Map();
60
+ return o.on("connection", (f) => {
62
61
  const c = {
63
62
  relaySockets: /* @__PURE__ */ new Map(),
64
63
  pendingFrames: /* @__PURE__ */ new Map(),
@@ -66,124 +65,124 @@ function X(t) {
66
65
  lastSubIdByRelay: /* @__PURE__ */ new Map(),
67
66
  torSocksProxy: e
68
67
  };
69
- o.set(a, c), a.on("message", (i, u) => {
70
- const y = o.get(a);
68
+ a.set(f, c), f.on("message", (i, u) => {
69
+ const y = a.get(f);
71
70
  if (!y) return;
72
71
  if (u) {
73
- const l = $(i);
74
- if (!l) return;
75
- x(y, a, l, n);
72
+ const g = k(i);
73
+ if (!g) return;
74
+ E(y, f, g, r);
76
75
  return;
77
76
  }
78
- const p = h(i);
79
- p && b(y, p, n);
80
- }), a.on("close", () => {
81
- const i = o.get(a);
82
- i && (g(i, n), o.delete(a));
83
- }), a.on("error", () => {
84
- const i = o.get(a);
85
- i && (g(i, n), o.delete(a));
77
+ const d = $(i);
78
+ d && O(y, d, r);
79
+ }), f.on("close", () => {
80
+ const i = a.get(f);
81
+ i && (l(i, r), a.delete(f));
82
+ }), f.on("error", () => {
83
+ const i = a.get(f);
84
+ i && (l(i, r), a.delete(f));
86
85
  });
87
86
  }), {
88
- wss: s,
89
- close: () => new Promise((a, c) => {
90
- o.forEach((i) => g(i, n)), o.clear(), s.close((i) => {
87
+ wss: o,
88
+ close: () => new Promise((f, c) => {
89
+ a.forEach((i) => l(i, r)), a.clear(), o.close((i) => {
91
90
  if (i) {
92
91
  c(i);
93
92
  return;
94
93
  }
95
- a();
94
+ f();
96
95
  });
97
96
  }),
98
- handleUpgrade: (a, c, i) => {
99
- (a.url ?? "").startsWith(r) && s.handleUpgrade(a, c, i, (y) => {
100
- s.emit("connection", y, a);
97
+ handleUpgrade: (f, c, i) => {
98
+ (f.url ?? "").startsWith(n) && o.handleUpgrade(f, c, i, (y) => {
99
+ o.emit("connection", y, f);
101
100
  });
102
101
  }
103
102
  };
104
103
  }
105
- function Y(t) {
106
- const { server: r, path: n = "/", logger: e = console, torSocksProxy: s } = t, o = new w({
107
- server: r,
108
- path: n
104
+ function Z(t) {
105
+ const { server: n, path: r = "/", logger: e = console, torSocksProxy: o } = t, a = new b({
106
+ server: n,
107
+ path: r
109
108
  });
110
- return o.on("connection", (f) => {
111
- const a = {
109
+ return a.on("connection", (s) => {
110
+ const f = {
112
111
  relaySockets: /* @__PURE__ */ new Map(),
113
112
  pendingFrames: /* @__PURE__ */ new Map(),
114
113
  dedupBySubId: /* @__PURE__ */ new Map(),
115
114
  lastSubIdByRelay: /* @__PURE__ */ new Map(),
116
- torSocksProxy: s
115
+ torSocksProxy: o
117
116
  };
118
- f.on("message", (c, i) => {
117
+ s.on("message", (c, i) => {
119
118
  if (i) {
120
- const y = $(c);
119
+ const y = k(c);
121
120
  if (!y) return;
122
- x(a, f, y, e);
121
+ E(f, s, y, e);
123
122
  return;
124
123
  }
125
- const u = h(c);
126
- u && b(a, u, e);
127
- }), f.on("close", () => {
128
- g(a, e);
129
- }), f.on("error", () => {
130
- g(a, e);
124
+ const u = $(c);
125
+ u && O(f, u, e);
126
+ }), s.on("close", () => {
127
+ l(f, e);
128
+ }), s.on("error", () => {
129
+ l(f, e);
131
130
  });
132
- }), e.info(`[relay-proxy] attached to server at path: ${n}`), {
133
- close: () => new Promise((f, a) => {
134
- o.close((c) => {
131
+ }), e.info(`[relay-proxy] attached to server at path: ${r}`), {
132
+ close: () => new Promise((s, f) => {
133
+ a.close((c) => {
135
134
  if (c) {
136
- a(c);
135
+ f(c);
137
136
  return;
138
137
  }
139
- f();
138
+ s();
140
139
  });
141
140
  })
142
141
  };
143
142
  }
144
- function Z(t, r) {
145
- const n = r.path ?? "/ws-proxy", e = r.logger ?? console, s = r.torSocksProxy;
146
- let o = null;
147
- const f = /* @__PURE__ */ new Map(), a = t.listen.bind(t);
143
+ function U(t, n) {
144
+ const r = n.path ?? "/ws-proxy", e = n.logger ?? console, o = n.torSocksProxy;
145
+ let a = null;
146
+ const s = /* @__PURE__ */ new Map(), f = t.listen.bind(t);
148
147
  return t.listen = (...c) => {
149
- const i = a(...c);
150
- return o = new w({
148
+ const i = f(...c);
149
+ return a = new b({
151
150
  server: i,
152
- path: n
153
- }), o.on("connection", (u) => {
151
+ path: r
152
+ }), a.on("connection", (u) => {
154
153
  const y = {
155
154
  relaySockets: /* @__PURE__ */ new Map(),
156
155
  pendingFrames: /* @__PURE__ */ new Map(),
157
156
  dedupBySubId: /* @__PURE__ */ new Map(),
158
157
  lastSubIdByRelay: /* @__PURE__ */ new Map(),
159
- torSocksProxy: s
158
+ torSocksProxy: o
160
159
  };
161
- f.set(u, y), u.on("message", (p, l) => {
162
- const d = f.get(u);
163
- if (!d) return;
164
- if (l) {
165
- const B = $(p);
166
- if (!B) return;
167
- x(d, u, B, e);
160
+ s.set(u, y), u.on("message", (d, g) => {
161
+ const p = s.get(u);
162
+ if (!p) return;
163
+ if (g) {
164
+ const x = k(d);
165
+ if (!x) return;
166
+ E(p, u, x, e);
168
167
  return;
169
168
  }
170
- const I = h(p);
171
- I && b(d, I, e);
169
+ const h = $(d);
170
+ h && O(p, h, e);
172
171
  }), u.on("close", () => {
173
- const p = f.get(u);
174
- p && (g(p, e), f.delete(u));
172
+ const d = s.get(u);
173
+ d && (l(d, e), s.delete(u));
175
174
  }), u.on("error", () => {
176
- const p = f.get(u);
177
- p && (g(p, e), f.delete(u));
175
+ const d = s.get(u);
176
+ d && (l(d, e), s.delete(u));
178
177
  });
179
- }), e.info(`[relay-proxy] attached to Express server at path: ${n}`), i;
178
+ }), e.info(`[relay-proxy] attached to Express server at path: ${r}`), i;
180
179
  }, {
181
180
  close: () => new Promise((c, i) => {
182
- if (!o) {
181
+ if (!a) {
183
182
  c();
184
183
  return;
185
184
  }
186
- f.forEach((u) => g(u, e)), f.clear(), o.close((u) => {
185
+ s.forEach((u) => l(u, e)), s.clear(), a.close((u) => {
187
186
  if (u) {
188
187
  i(u);
189
188
  return;
@@ -193,326 +192,349 @@ function Z(t, r) {
193
192
  })
194
193
  };
195
194
  }
196
- function b(t, r, n) {
197
- n.info(`[relay-proxy] handleClientCommand: ${r.slice(0, 200)}`);
195
+ function O(t, n, r) {
196
+ r.info(`[relay-proxy] handleClientCommand: ${n.slice(0, 200)}`);
198
197
  let e;
199
198
  try {
200
- e = JSON.parse(r);
201
- } catch (s) {
202
- n.warn(`[relay-proxy] failed to parse command JSON: ${s}`);
199
+ e = JSON.parse(n);
200
+ } catch (o) {
201
+ r.warn(`[relay-proxy] failed to parse command JSON: ${o}`);
203
202
  return;
204
203
  }
205
- if (j(e)) {
206
- n.info(`[relay-proxy] received auth_response for relay: ${e.relay}`);
207
- const s = JSON.stringify(["AUTH", e.event]);
208
- n.info(`[relay-proxy] sending AUTH frame to relay: ${e.relay}`), P(t, e.relay, s, n);
204
+ if (z(e)) {
205
+ r.info(`[relay-proxy] received auth_response for relay: ${e.relay}`);
206
+ const o = JSON.stringify(["AUTH", e.event]);
207
+ r.info(`[relay-proxy] sending AUTH frame to relay: ${e.relay}`), C(t, e.relay, o, r);
209
208
  return;
210
209
  }
211
- if (G(e)) {
210
+ if (K(e)) {
212
211
  t.dedupBySubId.delete(e.subscription_id);
213
- for (const [s, o] of t.relaySockets.entries())
214
- o.readyState === m.OPEN && o.send(JSON.stringify(["CLOSE", e.subscription_id])), t.lastSubIdByRelay.set(s, e.subscription_id);
212
+ for (const [o, a] of t.relaySockets.entries())
213
+ a.readyState === m.OPEN && a.send(JSON.stringify(["CLOSE", e.subscription_id])), t.lastSubIdByRelay.set(o, e.subscription_id);
215
214
  }
216
215
  }
217
- function x(t, r, n, e) {
218
- e.info(`[relay-proxy] handleEnvelope: ${n.relays.length} relays, ${n.frames.length} frames`), e.info(`[relay-proxy] relays: ${n.relays.join(", ")}`);
219
- const s = n.frames.map((o) => ({
220
- frame: o,
221
- state: L(o)
216
+ function E(t, n, r, e) {
217
+ e.info(`[relay-proxy] handleEnvelope: ${r.relays.length} relays, ${r.frames.length} frames`), e.info(`[relay-proxy] relays: ${r.relays.join(", ")}`);
218
+ const o = r.frames.map((a) => ({
219
+ frame: a,
220
+ state: J(a)
222
221
  }));
223
- e.info(`[relay-proxy] tracked ${s.length} frames`);
224
- for (const o of n.relays) {
225
- e.info(`[relay-proxy] processing relay: ${o}`), W(t, r, o, e);
226
- for (const f of s) {
227
- _(t, o, f.state);
228
- const a = f.frame;
229
- e.info(`[relay-proxy] sending frame to ${o}: ${a.slice(0, 100)}`), P(t, o, a, e);
222
+ e.info(`[relay-proxy] tracked ${o.length} frames`);
223
+ for (const a of r.relays) {
224
+ e.info(`[relay-proxy] processing relay: ${a}`), F(t, n, a, e);
225
+ for (const s of o) {
226
+ _(t, a, s.state);
227
+ const f = s.frame;
228
+ e.info(`[relay-proxy] sending frame to ${a}: ${f.slice(0, 100)}`), C(t, a, f, e);
230
229
  }
231
230
  }
232
231
  }
233
- function W(t, r, n, e) {
234
- const s = t.relaySockets.get(n);
235
- if (s && s.readyState !== m.CLOSED) {
236
- e.info(`[relay-proxy] reusing existing connection to ${n}`);
232
+ function F(t, n, r, e) {
233
+ const o = t.relaySockets.get(r);
234
+ if (o && o.readyState !== m.CLOSED) {
235
+ e.info(`[relay-proxy] reusing existing connection to ${r}`);
237
236
  return;
238
237
  }
239
- e.info(`[relay-proxy] creating new WebSocket connection to ${n}`);
240
- const o = new URL(n), f = `${o.protocol}//${o.host}`, a = o.hostname.endsWith(".onion"), c = {
238
+ e.info(`[relay-proxy] creating new WebSocket connection to ${r}`);
239
+ const a = new URL(r), s = `${a.protocol}//${a.host}`, f = a.hostname.endsWith(".onion"), c = {
241
240
  headers: {
242
- Origin: f,
241
+ Origin: s,
243
242
  "User-Agent": "nipworker/0.91.0"
244
243
  }
245
244
  };
246
- a && t.torSocksProxy && (e.info(`[relay-proxy] using Tor SOCKS proxy ${t.torSocksProxy} for ${n}`), c.agent = new v(t.torSocksProxy));
247
- const i = new m(n, c);
248
- t.relaySockets.set(n, i), t.pendingFrames.set(n, []);
245
+ f && t.torSocksProxy && (e.info(`[relay-proxy] using Tor SOCKS proxy ${t.torSocksProxy} for ${r}`), c.agent = new R(t.torSocksProxy));
246
+ const i = new m(r, c);
247
+ t.relaySockets.set(r, i), t.pendingFrames.set(r, []);
249
248
  const u = Date.now();
250
249
  i.on("open", () => {
251
- e.info(`[relay-proxy] connected to ${n}`);
252
- const y = t.pendingFrames.get(n);
250
+ e.info(`[relay-proxy] connected to ${r}`);
251
+ const y = t.pendingFrames.get(r);
253
252
  if (y) {
254
- e.info(`[relay-proxy] sending ${y.length} pending frames to ${n}`);
255
- for (const p of y)
256
- i.send(p);
257
- t.pendingFrames.set(n, []);
253
+ e.info(`[relay-proxy] sending ${y.length} pending frames to ${r}`);
254
+ for (const d of y)
255
+ i.send(d);
256
+ t.pendingFrames.set(r, []);
258
257
  }
259
258
  }), i.on("message", (y) => {
260
- const p = h(y);
261
- if (e.info(`[relay-proxy] received from ${n}: ${p == null ? void 0 : p.slice(0, 100)}`), !p || r.readyState !== m.OPEN) {
262
- e.warn(`[relay-proxy] cannot forward message: raw=${!!p}, clientOpen=${r.readyState === m.OPEN}`);
263
- return;
264
- }
265
- const l = t.lastSubIdByRelay.get(n), d = H(t, n, p, l, e);
266
- if (!d) {
267
- e.warn("[relay-proxy] failed to convert relay frame to worker message");
259
+ const d = $(y);
260
+ if (e.info(`[relay-proxy] received from ${r}: ${d == null ? void 0 : d.slice(0, 100)}`), !d || n.readyState !== m.OPEN) {
261
+ e.warn(`[relay-proxy] cannot forward message: raw=${!!d}, clientOpen=${n.readyState === m.OPEN}`);
268
262
  return;
269
263
  }
270
- e.info(`[relay-proxy] forwarding ${d.length} bytes to client`), r.send(d, { binary: true });
271
- }), i.on("close", (y, p) => {
264
+ const g = t.lastSubIdByRelay.get(r), p = V(t, r, d, g, e, (h, x) => {
265
+ e[h](`[relay-proxy] ${r}: ${x}`);
266
+ });
267
+ p && (e.info(`[relay-proxy] forwarding ${p.length} bytes to client`), n.send(p, { binary: true }));
268
+ }), i.on("close", (y, d) => {
272
269
  var _a, _b;
273
- if (e.info(`[relay-proxy] connection closed to ${n} (code: ${y}, reason: ${p})`), t.pendingFrames.has(n) && ((_a = t.pendingFrames.get(n)) == null ? void 0 : _a.length) > 0) {
274
- const l = ((_b = t.pendingFrames.get(n)) == null ? void 0 : _b.length) ?? 0;
275
- if (e.warn(`[relay-proxy] connection to ${n} closed with ${l} pending frames - subscription may fail`), r.readyState === m.OPEN) {
276
- const d = S(
277
- t.lastSubIdByRelay.get(n) ?? "",
278
- n,
270
+ if (e.info(`[relay-proxy] connection closed to ${r} (code: ${y}, reason: ${d})`), t.pendingFrames.has(r) && ((_a = t.pendingFrames.get(r)) == null ? void 0 : _a.length) > 0) {
271
+ const g = ((_b = t.pendingFrames.get(r)) == null ? void 0 : _b.length) ?? 0;
272
+ if (e.warn(`[relay-proxy] connection to ${r} closed with ${g} pending frames - subscription may fail`), n.readyState === m.OPEN) {
273
+ const p = S(
274
+ t.lastSubIdByRelay.get(r) ?? "",
275
+ r,
279
276
  "failed",
280
- `Connection failed: ${y} ${p}`
277
+ `Connection failed: ${y} ${d}`
281
278
  );
282
- r.send(d, { binary: true });
279
+ n.send(p, { binary: true });
283
280
  }
284
281
  }
285
- t.pendingFrames.delete(n);
282
+ t.pendingFrames.delete(r);
286
283
  }), i.on("error", (y) => {
287
- if (!t.pendingFrames.has(n)) return;
288
- const p = String(y), l = Date.now() - u;
289
- e.warn(`[relay-proxy] relay socket error for ${n} after ${l}ms: ${p}`), p.includes("403") && e.warn(`[relay-proxy] 403 Forbidden from ${n} - relay may require NIP-42 auth or block this connection`), t.pendingFrames.delete(n);
284
+ if (!t.pendingFrames.has(r)) return;
285
+ const d = String(y), g = Date.now() - u;
286
+ e.warn(`[relay-proxy] relay socket error for ${r} after ${g}ms: ${d}`), d.includes("403") && e.warn(`[relay-proxy] 403 Forbidden from ${r} - relay may require NIP-42 auth or block this connection`), t.pendingFrames.delete(r);
290
287
  });
291
288
  }
292
- function _(t, r, n) {
293
- if (n) {
294
- if (t.lastSubIdByRelay.set(r, n.subId), n.type === "REQ") {
295
- const e = n.subId;
289
+ function _(t, n, r) {
290
+ if (r) {
291
+ if (t.lastSubIdByRelay.set(n, r.subId), r.type === "REQ") {
292
+ const e = r.subId;
296
293
  t.dedupBySubId.has(e) || t.dedupBySubId.set(e, /* @__PURE__ */ new Set());
297
294
  return;
298
295
  }
299
- t.dedupBySubId.delete(n.subId);
296
+ t.dedupBySubId.delete(r.subId);
300
297
  }
301
298
  }
302
- function L(t) {
303
- const r = R(t);
304
- if (!r) return null;
305
- const n = r[0];
306
- if (n !== "REQ" && n !== "CLOSE") return null;
307
- const e = typeof r[1] == "string" ? r[1] : null;
308
- return e ? { type: n, subId: e } : null;
299
+ function J(t) {
300
+ const n = P(t);
301
+ if (!n) return null;
302
+ const r = n[0];
303
+ if (r !== "REQ" && r !== "CLOSE") return null;
304
+ const e = typeof n[1] == "string" ? n[1] : null;
305
+ return e ? { type: r, subId: e } : null;
309
306
  }
310
- function P(t, r, n, e) {
311
- const s = t.relaySockets.get(r);
312
- if (!s) {
313
- e.warn(`[relay-proxy] no relay socket for ${r}`);
307
+ function C(t, n, r, e) {
308
+ const o = t.relaySockets.get(n);
309
+ if (!o) {
310
+ e.warn(`[relay-proxy] no relay socket for ${n}`);
314
311
  return;
315
312
  }
316
- if (s.readyState === m.OPEN) {
317
- e.info(`[relay-proxy] sending frame to ${r} (OPEN): ${n.slice(0, 100)}`), s.send(n);
313
+ if (o.readyState === m.OPEN) {
314
+ e.info(`[relay-proxy] sending frame to ${n} (OPEN): ${r.slice(0, 100)}`), o.send(r);
318
315
  return;
319
316
  }
320
- if (s.readyState === m.CONNECTING) {
321
- e.info(`[relay-proxy] queueing frame for ${r} (CONNECTING)`);
322
- const o = t.pendingFrames.get(r) ?? [];
323
- o.push(n), t.pendingFrames.set(r, o);
317
+ if (o.readyState === m.CONNECTING) {
318
+ e.info(`[relay-proxy] queueing frame for ${n} (CONNECTING)`);
319
+ const a = t.pendingFrames.get(n) ?? [];
320
+ a.push(r), t.pendingFrames.set(n, a);
324
321
  return;
325
322
  }
326
- e.warn(`[relay-proxy] dropping frame for closed relay socket ${r} (state: ${s.readyState})`);
323
+ e.warn(`[relay-proxy] dropping frame for closed relay socket ${n} (state: ${o.readyState})`);
327
324
  }
328
- function H(t, r, n, e, s) {
329
- const o = R(n);
330
- if (!o || o.length < 1 || typeof o[0] != "string")
331
- return O(e ?? "", r, n);
332
- const f = o[0];
325
+ function V(t, n, r, e, o, a) {
326
+ const s = P(r);
327
+ if (!s)
328
+ return a == null ? void 0 : a("warn", `parse failed: invalid JSON or not an array, raw=${r.slice(0, 200)}`), w(e ?? "", n, r);
329
+ if (s.length < 1 || typeof s[0] != "string")
330
+ return a == null ? void 0 : a("warn", `parse failed: empty frame or missing kind, frame=${JSON.stringify(s).slice(0, 200)}`), w(e ?? "", n, r);
331
+ const f = s[0];
333
332
  if (f === "EVENT") {
334
- const a = typeof o[1] == "string" ? o[1] : "", c = J(o[2]);
335
- if (!a || !c)
336
- return O(a, r, n);
337
- const i = t.dedupBySubId.get(a);
338
- return i && i.has(c.id) ? null : (i && i.add(c.id), D(a, r, c));
333
+ const c = typeof s[1] == "string" ? s[1] : "", i = D(s[2]);
334
+ if (!c)
335
+ return a == null ? void 0 : a("warn", `EVENT missing subscription ID, frame=${JSON.stringify(s).slice(0, 200)}`), w(c, n, r);
336
+ if (!i) {
337
+ const y = H(s[2]);
338
+ return a == null ? void 0 : a("warn", `EVENT has invalid event structure: ${y}, frame=${JSON.stringify(s).slice(0, 300)}`), w(c, n, r);
339
+ }
340
+ const u = t.dedupBySubId.get(c);
341
+ return u && u.has(i.id) ? (a == null ? void 0 : a("info", `EVENT deduplicated: subId=${c}, eventId=${i.id.slice(0, 16)}...`), null) : (u && u.add(i.id), j(c, n, i));
339
342
  }
340
343
  if (f === "NOTICE") {
341
- const a = o[1] === void 0 ? null : String(o[1]);
342
- return S("", r, "NOTICE", a);
344
+ const c = s[1] === void 0 ? null : String(s[1]);
345
+ return S("", n, "NOTICE", c);
343
346
  }
344
347
  if (f === "AUTH") {
345
- const a = o[1] === void 0 ? null : String(o[1]), c = Date.now(), i = t.lastAuthChallenge.get(r);
346
- if (i) {
347
- const y = c - i.timestamp;
348
- if (i.challenge === a && y < 5e3)
349
- return s == null ? void 0 : s.info(`[relay-proxy] dropping duplicate AUTH from ${r} (${y}ms ago)`), null;
350
- if (y < 1e3)
351
- return s == null ? void 0 : s.info(`[relay-proxy] rate limiting AUTH from ${r} (${y}ms since last)`), null;
352
- }
353
- t.lastAuthChallenge.set(r, { challenge: a, timestamp: c }), s == null ? void 0 : s.info(`[relay-proxy] received AUTH challenge from ${r}: ${a}`);
354
- const u = S(e ?? "", r, "AUTH", a);
355
- return s == null ? void 0 : s.info(`[relay-proxy] built AUTH worker message (${u.length} bytes)`), u;
348
+ const c = s[1] === void 0 ? null : String(s[1]);
349
+ o == null ? void 0 : o.info(`[relay-proxy] received AUTH challenge from ${n}: ${c}`);
350
+ const i = S(e ?? "", n, "AUTH", c);
351
+ return o == null ? void 0 : o.info(`[relay-proxy] built AUTH worker message (${i.length} bytes)`), i;
356
352
  }
357
353
  if (f === "CLOSED") {
358
- const a = typeof o[1] == "string" ? o[1] : "", c = o[2] === void 0 ? null : String(o[2]);
359
- return S(a, r, "CLOSED", c);
354
+ const c = typeof s[1] == "string" ? s[1] : "", i = s[2] === void 0 ? null : String(s[2]);
355
+ return S(c, n, "CLOSED", i);
360
356
  }
361
357
  if (f === "OK") {
362
- const a = typeof o[1] == "string" ? o[1] : "", c = o[2] === void 0 ? "false" : String(o[2]), i = o[3] === void 0 ? null : String(o[3]);
363
- return S(a, r, c, i);
358
+ const c = typeof s[1] == "string" ? s[1] : "", i = s[2] === void 0 ? "false" : String(s[2]), u = s[3] === void 0 ? null : String(s[3]);
359
+ return S(c, n, i, u);
364
360
  }
365
361
  if (f === "EOSE") {
366
- const a = typeof o[1] == "string" ? o[1] : "";
367
- return S(a, r, "EOSE", null);
362
+ const c = typeof s[1] == "string" ? s[1] : "";
363
+ return S(c, n, "EOSE", null);
368
364
  }
369
- return O(e ?? "", r, n);
365
+ return a == null ? void 0 : a("info", `unknown frame kind='${f}', forwarding as raw message`), w(e ?? "", n, r);
370
366
  }
371
- function D(t, r, n) {
372
- const e = new A.Builder(1024), s = t ? e.createString(t) : 0, o = e.createString(r), f = e.createString(n.id), a = e.createString(n.pubkey), c = e.createString(n.content), i = e.createString(n.sig), u = new Array(n.tags.length);
373
- for (let d = 0; d < n.tags.length; d++)
374
- u[d] = V(e, n.tags[d]);
375
- const y = C.createTagsVector(e, u), p = C.createNostrEvent(
367
+ function j(t, n, r) {
368
+ const e = new A.Builder(1024), o = t ? e.createString(t) : 0, a = e.createString(n), s = e.createString(r.id), f = e.createString(r.pubkey), c = e.createString(r.content), i = e.createString(r.sig), u = new Array(r.tags.length);
369
+ for (let p = 0; p < r.tags.length; p++)
370
+ u[p] = G(e, r.tags[p]);
371
+ const y = B.createTagsVector(e, u), d = B.createNostrEvent(
376
372
  e,
373
+ s,
377
374
  f,
378
- a,
379
- n.kind,
375
+ r.kind,
380
376
  c,
381
377
  y,
382
- n.created_at,
378
+ r.created_at,
383
379
  i
384
- ), l = E.createWorkerMessage(
380
+ ), g = M.createWorkerMessage(
385
381
  e,
386
- s,
387
382
  o,
388
- k.NostrEvent,
389
- M.NostrEvent,
390
- p
383
+ a,
384
+ N.NostrEvent,
385
+ I.NostrEvent,
386
+ d
391
387
  );
392
- return e.finish(l), e.asUint8Array();
388
+ return e.finish(g), e.asUint8Array();
393
389
  }
394
- function S(t, r, n, e) {
395
- const s = new A.Builder(256), o = t ? s.createString(t) : 0, f = s.createString(r), a = s.createString(n), c = e === null ? 0 : s.createString(e), i = T.createConnectionStatus(
390
+ function S(t, n, r, e) {
391
+ const o = new A.Builder(256), a = t ? o.createString(t) : 0, s = o.createString(n), f = o.createString(r), c = e === null ? 0 : o.createString(e), i = T.createConnectionStatus(
392
+ o,
396
393
  s,
397
394
  f,
398
- a,
399
395
  c
400
- ), u = E.createWorkerMessage(
401
- s,
396
+ ), u = M.createWorkerMessage(
402
397
  o,
403
- f,
404
- k.ConnectionStatus,
405
- M.ConnectionStatus,
398
+ a,
399
+ s,
400
+ N.ConnectionStatus,
401
+ I.ConnectionStatus,
406
402
  i
407
403
  );
408
- return s.finish(u), s.asUint8Array();
404
+ return o.finish(u), o.asUint8Array();
409
405
  }
410
- function O(t, r, n) {
411
- const e = new A.Builder(256), s = t ? e.createString(t) : 0, o = e.createString(r), f = e.createString(n), a = F.createRaw(e, f), c = E.createWorkerMessage(
406
+ function w(t, n, r) {
407
+ const e = new A.Builder(256), o = t ? e.createString(t) : 0, a = e.createString(n), s = e.createString(r), f = W.createRaw(e, s), c = M.createWorkerMessage(
412
408
  e,
413
- s,
414
409
  o,
415
- k.Raw,
416
- M.Raw,
417
- a
410
+ a,
411
+ N.Raw,
412
+ I.Raw,
413
+ f
418
414
  );
419
415
  return e.finish(c), e.asUint8Array();
420
416
  }
421
- function J(t) {
417
+ function D(t) {
422
418
  if (!t || typeof t != "object") return null;
423
- const r = t;
424
- if (typeof r.id != "string" || typeof r.pubkey != "string" || typeof r.kind != "number" || typeof r.content != "string" || typeof r.created_at != "number" || typeof r.sig != "string" || !Array.isArray(r.tags))
419
+ const n = t;
420
+ if (typeof n.id != "string" || typeof n.pubkey != "string" || typeof n.kind != "number" || typeof n.content != "string" || typeof n.created_at != "number" || typeof n.sig != "string" || !Array.isArray(n.tags))
425
421
  return null;
426
- const n = r.tags;
422
+ const r = n.tags;
427
423
  let e = false;
428
- for (const o of n) {
429
- if (!Array.isArray(o) || o.length === 0) {
424
+ for (const a of r) {
425
+ if (!Array.isArray(a) || a.length === 0) {
430
426
  e = true;
431
427
  continue;
432
428
  }
433
- for (const f of o)
434
- if (typeof f != "string") {
429
+ for (const s of a)
430
+ if (typeof s != "string") {
435
431
  e = true;
436
432
  break;
437
433
  }
438
434
  }
439
- let s;
435
+ let o;
440
436
  if (!e)
441
- s = n;
437
+ o = r;
442
438
  else {
443
- s = [];
444
- for (const o of n) {
445
- if (!Array.isArray(o)) continue;
446
- const f = [];
447
- for (const a of o)
448
- typeof a == "string" && f.push(a);
449
- f.length > 0 && s.push(f);
439
+ o = [];
440
+ for (const a of r) {
441
+ if (!Array.isArray(a)) continue;
442
+ const s = [];
443
+ for (const f of a)
444
+ typeof f == "string" && s.push(f);
445
+ s.length > 0 && o.push(s);
450
446
  }
451
447
  }
452
448
  return {
453
- id: r.id,
454
- pubkey: r.pubkey,
455
- kind: r.kind,
456
- content: r.content,
457
- created_at: r.created_at,
458
- sig: r.sig,
459
- tags: s
449
+ id: n.id,
450
+ pubkey: n.pubkey,
451
+ kind: n.kind,
452
+ content: n.content,
453
+ created_at: n.created_at,
454
+ sig: n.sig,
455
+ tags: o
460
456
  };
461
457
  }
462
- function V(t, r) {
463
- const n = new Array(r.length);
464
- for (let s = 0; s < r.length; s++)
465
- n[s] = t.createString(r[s]);
466
- const e = N.createItemsVector(t, n);
467
- return N.createStringVec(t, e);
458
+ function H(t) {
459
+ if (!t) return "value is null/undefined";
460
+ if (typeof t != "object") return `expected object, got ${typeof t}`;
461
+ const n = t, r = [
462
+ ["id", "string", typeof n.id],
463
+ ["pubkey", "string", typeof n.pubkey],
464
+ ["kind", "number", typeof n.kind],
465
+ ["content", "string", typeof n.content],
466
+ ["created_at", "number", typeof n.created_at],
467
+ ["sig", "string", typeof n.sig]
468
+ ];
469
+ for (const [e, o, a] of r)
470
+ if (a !== o)
471
+ return `${e} is ${a === "undefined" ? "missing" : `type ${a} (expected ${o})`}`;
472
+ if (!Array.isArray(n.tags))
473
+ return `tags is ${n.tags === void 0 ? "missing" : `type ${typeof n.tags} (expected array)`}`;
474
+ for (let e = 0; e < n.tags.length; e++) {
475
+ const o = n.tags[e];
476
+ if (!Array.isArray(o))
477
+ return `tags[${e}] is not an array`;
478
+ for (let a = 0; a < o.length; a++)
479
+ if (typeof o[a] != "string")
480
+ return `tags[${e}][${a}] is type ${typeof o[a]} (expected string)`;
481
+ }
482
+ return "unknown validation error";
483
+ }
484
+ function G(t, n) {
485
+ const r = new Array(n.length);
486
+ for (let o = 0; o < n.length; o++)
487
+ r[o] = t.createString(n[o]);
488
+ const e = v.createItemsVector(t, r);
489
+ return v.createStringVec(t, e);
468
490
  }
469
- function R(t) {
491
+ function P(t) {
470
492
  try {
471
- const r = JSON.parse(t);
472
- return Array.isArray(r) ? r : null;
493
+ const n = JSON.parse(t);
494
+ return Array.isArray(n) ? n : null;
473
495
  } catch {
474
496
  return null;
475
497
  }
476
498
  }
477
- function $(t, r) {
478
- const n = h(t);
479
- if (!n)
499
+ function k(t, n) {
500
+ const r = $(t);
501
+ if (!r)
480
502
  return null;
481
503
  try {
482
- const e = JSON.parse(n);
504
+ const e = JSON.parse(r);
483
505
  if (!Array.isArray(e.relays) || !Array.isArray(e.frames))
484
- return r == null ? void 0 : r.warn(`[relay-proxy] parseEnvelope: invalid structure (relays: ${Array.isArray(e.relays)}, frames: ${Array.isArray(e.frames)})`), null;
485
- const s = e.relays.filter((f) => typeof f == "string"), o = e.frames.filter((f) => typeof f == "string");
486
- return r == null ? void 0 : r.info(`[relay-proxy] parseEnvelope: ${s.length} relays, ${o.length} frames`), s.length === 0 || o.length === 0 ? (r == null ? void 0 : r.warn("[relay-proxy] parseEnvelope: empty relays or frames after filter"), null) : { relays: s, frames: o };
506
+ return n == null ? void 0 : n.warn(`[relay-proxy] parseEnvelope: invalid structure (relays: ${Array.isArray(e.relays)}, frames: ${Array.isArray(e.frames)})`), null;
507
+ const o = e.relays.filter((s) => typeof s == "string"), a = e.frames.filter((s) => typeof s == "string");
508
+ return n == null ? void 0 : n.info(`[relay-proxy] parseEnvelope: ${o.length} relays, ${a.length} frames`), o.length === 0 || a.length === 0 ? (n == null ? void 0 : n.warn("[relay-proxy] parseEnvelope: empty relays or frames after filter"), null) : { relays: o, frames: a };
487
509
  } catch {
488
510
  return null;
489
511
  }
490
512
  }
491
- function h(t) {
492
- return typeof t == "string" ? t : t instanceof ArrayBuffer ? Buffer.from(t).toString("utf8") : Buffer.isBuffer(t) ? t.toString("utf8") : t instanceof Uint8Array ? Buffer.from(t).toString("utf8") : Array.isArray(t) ? Buffer.concat(t.filter((r) => Buffer.isBuffer(r))).toString("utf8") : "";
513
+ function $(t) {
514
+ return typeof t == "string" ? t : t instanceof ArrayBuffer ? Buffer.from(t).toString("utf8") : Buffer.isBuffer(t) ? t.toString("utf8") : t instanceof Uint8Array ? Buffer.from(t).toString("utf8") : Array.isArray(t) ? Buffer.concat(t.filter((n) => Buffer.isBuffer(n))).toString("utf8") : "";
493
515
  }
494
- function j(t) {
516
+ function z(t) {
495
517
  if (!t || typeof t != "object") return false;
496
- const r = t;
497
- return r.type === "auth_response" && typeof r.relay == "string" && r.event !== void 0;
518
+ const n = t;
519
+ return n.type === "auth_response" && typeof n.relay == "string" && n.event !== void 0;
498
520
  }
499
- function G(t) {
521
+ function K(t) {
500
522
  if (!t || typeof t != "object") return false;
501
- const r = t;
502
- return r.type === "close_sub" && typeof r.subscription_id == "string";
523
+ const n = t;
524
+ return n.type === "close_sub" && typeof n.subscription_id == "string";
503
525
  }
504
- function g(t, r) {
505
- r == null ? void 0 : r.info("[relay-proxy] closing session"), t.dedupBySubId.clear(), t.lastSubIdByRelay.clear();
506
- for (const [n, e] of t.relaySockets.entries())
526
+ function l(t, n) {
527
+ n == null ? void 0 : n.info("[relay-proxy] closing session"), t.dedupBySubId.clear(), t.lastSubIdByRelay.clear();
528
+ for (const [r, e] of t.relaySockets.entries())
507
529
  try {
508
- r == null ? void 0 : r.info(`[relay-proxy] closing socket to ${n}`), e.close();
530
+ n == null ? void 0 : n.info(`[relay-proxy] closing socket to ${r}`), e.close();
509
531
  } catch {
510
532
  }
511
533
  t.relaySockets.clear(), t.pendingFrames.clear();
512
534
  }
513
535
  export {
514
- Y as attachRelayProxyToServer,
515
- Z as createExpressRelayProxyMiddleware,
516
- q as createRelayProxyServer,
517
- X as createRelayProxyWebSocketServer
536
+ Z as attachRelayProxyToServer,
537
+ U as createExpressRelayProxyMiddleware,
538
+ X as createRelayProxyServer,
539
+ Y as createRelayProxyWebSocketServer
518
540
  };