wireweave 0.3.23 → 0.3.25
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/package.json +1 -1
- package/src/relay-pool.js +20 -3
package/package.json
CHANGED
package/src/relay-pool.js
CHANGED
|
@@ -12,6 +12,9 @@ const DEFAULT_RELAYS = [
|
|
|
12
12
|
];
|
|
13
13
|
|
|
14
14
|
const SEEN_MAX = 10000;
|
|
15
|
+
const PENDING_MAX = 500;
|
|
16
|
+
const PENDING_TTL_MS = 120000;
|
|
17
|
+
const jitter = (ms) => Math.round(ms * (0.75 + Math.random() * 0.5));
|
|
15
18
|
|
|
16
19
|
const lruTouch = (map, key) => {
|
|
17
20
|
if (map.has(key)) { map.delete(key); map.set(key, 1); return false; }
|
|
@@ -36,16 +39,22 @@ export class RelayPool extends EventTarget {
|
|
|
36
39
|
this.subs = new Map();
|
|
37
40
|
this.pending = [];
|
|
38
41
|
this.seen = new Map();
|
|
42
|
+
this._reconnectTimers = new Map();
|
|
43
|
+
this._closed = false;
|
|
39
44
|
this.verifyEvent = verifyEvent;
|
|
40
45
|
this.WS = WebSocketImpl || (typeof WebSocket !== 'undefined' ? WebSocket : null);
|
|
41
46
|
if (!this.WS) throw new Error('No WebSocket implementation available');
|
|
42
47
|
}
|
|
43
48
|
|
|
44
49
|
connect() {
|
|
50
|
+
this._closed = false;
|
|
45
51
|
for (const url of this.urls) this._open(url);
|
|
46
52
|
}
|
|
47
53
|
|
|
48
54
|
disconnect() {
|
|
55
|
+
this._closed = true;
|
|
56
|
+
for (const [, t] of this._reconnectTimers) clearTimeout(t);
|
|
57
|
+
this._reconnectTimers.clear();
|
|
49
58
|
for (const [, r] of this.relays) {
|
|
50
59
|
if (r.ws) {
|
|
51
60
|
r.ws.onclose = null; r.ws.onerror = null; r.ws.onopen = null; r.ws.onmessage = null;
|
|
@@ -58,6 +67,8 @@ export class RelayPool extends EventTarget {
|
|
|
58
67
|
}
|
|
59
68
|
|
|
60
69
|
_open(url) {
|
|
70
|
+
if (this._closed) return;
|
|
71
|
+
this._reconnectTimers.delete(url);
|
|
61
72
|
const existing = this.relays.get(url);
|
|
62
73
|
if (existing?.ws && (existing.ws.readyState === 0 || existing.ws.readyState === 1)) return;
|
|
63
74
|
const relay = existing || { ws: null, status: 'connecting', subIds: new Set(), latencyMs: null, failCount: 0, reconnectDelay: 1000, _reqSentAt: null, _openedAt: null };
|
|
@@ -94,7 +105,9 @@ export class RelayPool extends EventTarget {
|
|
|
94
105
|
if (sustained) { relay.failCount = 0; relay.reconnectDelay = 1000; }
|
|
95
106
|
else { relay.failCount++; relay.reconnectDelay = Math.min(relay.reconnectDelay * 2, 30000); }
|
|
96
107
|
relay._openedAt = null;
|
|
97
|
-
|
|
108
|
+
if (this._closed) return;
|
|
109
|
+
const t = setTimeout(() => this._open(url), jitter(relay.reconnectDelay));
|
|
110
|
+
this._reconnectTimers.set(url, t);
|
|
98
111
|
};
|
|
99
112
|
}
|
|
100
113
|
|
|
@@ -156,13 +169,17 @@ export class RelayPool extends EventTarget {
|
|
|
156
169
|
sent = true;
|
|
157
170
|
}
|
|
158
171
|
}
|
|
159
|
-
if (!sent)
|
|
172
|
+
if (!sent) {
|
|
173
|
+
this.pending.push({ event, ts: Date.now() });
|
|
174
|
+
if (this.pending.length > PENDING_MAX) this.pending.splice(0, this.pending.length - PENDING_MAX);
|
|
175
|
+
}
|
|
160
176
|
return sent;
|
|
161
177
|
}
|
|
162
178
|
|
|
163
179
|
_drainPending() {
|
|
180
|
+
const cutoff = Date.now() - PENDING_TTL_MS;
|
|
164
181
|
const pending = this.pending.splice(0);
|
|
165
|
-
for (const
|
|
182
|
+
for (const p of pending) { if (p.ts >= cutoff) this.publish(p.event); }
|
|
166
183
|
}
|
|
167
184
|
|
|
168
185
|
isConnected() {
|