@linkshell/wire 0.0.0-stage → 0.1.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.
@@ -0,0 +1,259 @@
1
+ import { gatewayChallengeMessage, publicIdentity, sign } from "./crypto.js";
2
+ import { serverFrameSchema, tunnelFrameSchema, } from "./relay.js";
3
+ export class RelayRequestError extends Error {
4
+ code;
5
+ constructor(code, message) {
6
+ super(message);
7
+ this.code = code;
8
+ }
9
+ }
10
+ const OPEN = 1;
11
+ export class RelayClient {
12
+ options;
13
+ socket;
14
+ statusValue = "offline";
15
+ attempt = 0;
16
+ timer;
17
+ nextId = 1;
18
+ pending = new Map();
19
+ statusListeners = new Set();
20
+ frameListeners = new Set();
21
+ undeliverableListeners = new Set();
22
+ eventListeners = new Map();
23
+ waiters = new Set();
24
+ /** Account the gateway recognised on the last connection. */
25
+ account;
26
+ lastError;
27
+ constructor(options) {
28
+ this.options = options;
29
+ }
30
+ get status() {
31
+ return this.statusValue;
32
+ }
33
+ get identity() {
34
+ return publicIdentity(this.options.identity);
35
+ }
36
+ onStatus(listener) {
37
+ this.statusListeners.add(listener);
38
+ return () => this.statusListeners.delete(listener);
39
+ }
40
+ onFrame(listener) {
41
+ this.frameListeners.add(listener);
42
+ return () => this.frameListeners.delete(listener);
43
+ }
44
+ onUndeliverable(listener) {
45
+ this.undeliverableListeners.add(listener);
46
+ return () => this.undeliverableListeners.delete(listener);
47
+ }
48
+ on(name, listener) {
49
+ let set = this.eventListeners.get(name);
50
+ if (!set)
51
+ this.eventListeners.set(name, (set = new Set()));
52
+ const entry = listener;
53
+ set.add(entry);
54
+ return () => set.delete(entry);
55
+ }
56
+ start() {
57
+ if (this.statusValue === "connecting" || this.statusValue === "online")
58
+ return;
59
+ this.open();
60
+ }
61
+ stop() {
62
+ this.setStatus("stopped");
63
+ clearTimeout(this.timer);
64
+ this.socket?.close(1000, "stopped");
65
+ this.socket = undefined;
66
+ this.failPending("stopped");
67
+ for (const wake of this.waiters)
68
+ wake();
69
+ }
70
+ /** Reconnect now instead of waiting out the backoff (app foregrounded, network back). */
71
+ reconnectNow() {
72
+ if (this.statusValue === "stopped" || this.statusValue === "online" || this.statusValue === "connecting")
73
+ return;
74
+ clearTimeout(this.timer);
75
+ this.attempt = 0;
76
+ this.open();
77
+ }
78
+ /** Waits (up to `timeoutMs`) for the gateway connection. */
79
+ waitOnline(timeoutMs) {
80
+ if (this.statusValue === "online")
81
+ return Promise.resolve(true);
82
+ if (this.statusValue === "stopped")
83
+ return Promise.resolve(false);
84
+ return new Promise((resolve) => {
85
+ const done = () => {
86
+ clearTimeout(timer);
87
+ this.waiters.delete(done);
88
+ resolve(this.statusValue === "online");
89
+ };
90
+ const timer = setTimeout(done, timeoutMs);
91
+ this.waiters.add(done);
92
+ });
93
+ }
94
+ async request(method, params, timeoutMs) {
95
+ const limit = timeoutMs ?? this.options.requestTimeoutMs ?? 20_000;
96
+ if (!(await this.waitOnline(limit)))
97
+ throw new RelayRequestError("offline", "not connected to the gateway");
98
+ const id = this.nextId++;
99
+ return new Promise((resolve, reject) => {
100
+ const timer = setTimeout(() => {
101
+ this.pending.delete(id);
102
+ reject(new RelayRequestError("timeout", `${method} timed out`));
103
+ }, limit);
104
+ this.pending.set(id, { resolve: resolve, reject, timer });
105
+ this.sendFrame({ t: "req", id, method, params });
106
+ });
107
+ }
108
+ /** Sends a tunnel frame to a peer. Returns false when not connected. */
109
+ send(to, frame) {
110
+ if (this.statusValue !== "online")
111
+ return false;
112
+ return this.sendFrame({ t: "to", to, d: JSON.stringify(frame) });
113
+ }
114
+ // ── internals ─────────────────────────────────────────────────────
115
+ sendFrame(frame) {
116
+ if (!this.socket || this.socket.readyState !== OPEN)
117
+ return false;
118
+ this.socket.send(JSON.stringify(frame));
119
+ return true;
120
+ }
121
+ setStatus(status, error) {
122
+ if (error)
123
+ this.lastError = error;
124
+ if (status === "online")
125
+ this.lastError = undefined;
126
+ if (this.statusValue === status && !error)
127
+ return;
128
+ this.statusValue = status;
129
+ for (const listener of this.statusListeners)
130
+ listener(status, error);
131
+ if (status === "online" || status === "stopped")
132
+ for (const wake of this.waiters)
133
+ wake();
134
+ }
135
+ failPending(reason) {
136
+ for (const [id, entry] of this.pending) {
137
+ clearTimeout(entry.timer);
138
+ entry.reject(new RelayRequestError("offline", reason));
139
+ this.pending.delete(id);
140
+ }
141
+ }
142
+ open() {
143
+ this.setStatus("connecting");
144
+ let socket;
145
+ try {
146
+ socket = this.options.createSocket(this.options.url);
147
+ }
148
+ catch (error) {
149
+ this.scheduleReconnect({ code: "connect_failed", message: error instanceof Error ? error.message : String(error) });
150
+ return;
151
+ }
152
+ this.socket = socket;
153
+ let fatal;
154
+ socket.onmessage = (event) => {
155
+ let frame;
156
+ try {
157
+ const parsed = serverFrameSchema.safeParse(JSON.parse(String(event.data)));
158
+ if (!parsed.success)
159
+ return;
160
+ frame = parsed.data;
161
+ }
162
+ catch {
163
+ return;
164
+ }
165
+ switch (frame.t) {
166
+ case "challenge":
167
+ void this.authenticate(frame.nonce);
168
+ return;
169
+ case "ready":
170
+ this.attempt = 0;
171
+ this.account = frame.userId ? { userId: frame.userId, email: frame.email } : undefined;
172
+ this.setStatus("online");
173
+ return;
174
+ case "res": {
175
+ const entry = this.pending.get(frame.id);
176
+ if (!entry)
177
+ return;
178
+ clearTimeout(entry.timer);
179
+ this.pending.delete(frame.id);
180
+ if (frame.error)
181
+ entry.reject(new RelayRequestError(frame.error.code, frame.error.message));
182
+ else
183
+ entry.resolve(frame.result);
184
+ return;
185
+ }
186
+ case "event":
187
+ for (const listener of this.eventListeners.get(frame.name) ?? [])
188
+ listener(frame.data);
189
+ return;
190
+ case "from": {
191
+ let inner;
192
+ try {
193
+ const parsed = tunnelFrameSchema.safeParse(JSON.parse(frame.d));
194
+ if (!parsed.success)
195
+ return;
196
+ inner = parsed.data;
197
+ }
198
+ catch {
199
+ return;
200
+ }
201
+ for (const listener of this.frameListeners)
202
+ listener(frame.from, frame.via, inner);
203
+ return;
204
+ }
205
+ case "undeliverable":
206
+ for (const listener of this.undeliverableListeners)
207
+ listener(frame.to, frame.reason);
208
+ return;
209
+ case "error":
210
+ fatal = { code: frame.code, message: frame.message };
211
+ return;
212
+ case "pong":
213
+ return;
214
+ }
215
+ };
216
+ socket.onerror = () => { };
217
+ socket.onclose = (event) => {
218
+ if (this.socket !== socket)
219
+ return;
220
+ this.socket = undefined;
221
+ this.failPending("connection closed");
222
+ if (this.statusValue === "stopped")
223
+ return;
224
+ // Another connection with our identity took over: don't fight it.
225
+ if (event.code === 4000) {
226
+ this.setStatus("offline", { code: "replaced", message: "connected elsewhere with this identity" });
227
+ return;
228
+ }
229
+ this.scheduleReconnect(fatal ?? { code: "disconnected", message: event.reason || "connection lost" });
230
+ };
231
+ }
232
+ async authenticate(nonce) {
233
+ let token;
234
+ try {
235
+ token = (await this.options.token?.()) ?? undefined;
236
+ }
237
+ catch {
238
+ token = undefined;
239
+ }
240
+ this.sendFrame({
241
+ t: "auth",
242
+ role: this.options.role,
243
+ identity: publicIdentity(this.options.identity),
244
+ signature: sign(this.options.identity, gatewayChallengeMessage(nonce)),
245
+ name: this.options.name.slice(0, 120),
246
+ platform: this.options.platform,
247
+ token,
248
+ });
249
+ }
250
+ scheduleReconnect(error) {
251
+ this.setStatus("offline", error);
252
+ const min = this.options.minBackoffMs ?? 500;
253
+ const max = this.options.maxBackoffMs ?? 30_000;
254
+ const delay = Math.min(max, min * 2 ** this.attempt) * (0.75 + Math.random() * 0.5);
255
+ this.attempt += 1;
256
+ this.timer = setTimeout(() => this.open(), delay);
257
+ }
258
+ }
259
+ //# sourceMappingURL=relay-client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"relay-client.js","sourceRoot":"","sources":["../src/relay-client.ts"],"names":[],"mappings":"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"}