@candypoets/nipworker 0.91.0 → 0.91.1

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