wireweave 0.3.26 → 0.3.27
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 +48 -5
package/package.json
CHANGED
package/src/relay-pool.js
CHANGED
|
@@ -38,8 +38,10 @@ export class RelayPool extends EventTarget {
|
|
|
38
38
|
this.relays = new Map();
|
|
39
39
|
this.subs = new Map();
|
|
40
40
|
this.pending = [];
|
|
41
|
+
this._pendingIds = new Set();
|
|
41
42
|
this.seen = new Map();
|
|
42
43
|
this._reconnectTimers = new Map();
|
|
44
|
+
this._acks = new Map();
|
|
43
45
|
this._closed = false;
|
|
44
46
|
this.verifyEvent = verifyEvent;
|
|
45
47
|
this.WS = WebSocketImpl || (typeof WebSocket !== 'undefined' ? WebSocket : null);
|
|
@@ -55,6 +57,8 @@ export class RelayPool extends EventTarget {
|
|
|
55
57
|
this._closed = true;
|
|
56
58
|
for (const [, t] of this._reconnectTimers) clearTimeout(t);
|
|
57
59
|
this._reconnectTimers.clear();
|
|
60
|
+
for (const [, rec] of this._acks) { clearTimeout(rec.timer); rec.resolve(false); }
|
|
61
|
+
this._acks.clear();
|
|
58
62
|
for (const [, r] of this.relays) {
|
|
59
63
|
if (r.ws) {
|
|
60
64
|
r.ws.onclose = null; r.ws.onerror = null; r.ws.onopen = null; r.ws.onmessage = null;
|
|
@@ -132,8 +136,12 @@ export class RelayPool extends EventTarget {
|
|
|
132
136
|
this._emit('eose', { subId });
|
|
133
137
|
} else if (type === 'NOTICE') {
|
|
134
138
|
this._emit('notice', { url, message: msg[1] });
|
|
135
|
-
} else if (type === 'OK'
|
|
136
|
-
|
|
139
|
+
} else if (type === 'OK') {
|
|
140
|
+
const accepted = msg[2] === true;
|
|
141
|
+
const id = msg[1], reason = msg[3] || '';
|
|
142
|
+
if (accepted) this._emit('ok', { url, id });
|
|
143
|
+
else this._emit('reject', { url, id, reason });
|
|
144
|
+
this._settleAck(id, accepted, reason);
|
|
137
145
|
}
|
|
138
146
|
}
|
|
139
147
|
|
|
@@ -169,16 +177,51 @@ export class RelayPool extends EventTarget {
|
|
|
169
177
|
sent = true;
|
|
170
178
|
}
|
|
171
179
|
}
|
|
172
|
-
if (
|
|
173
|
-
this.
|
|
174
|
-
|
|
180
|
+
if (sent) {
|
|
181
|
+
if (event?.id) this._pendingIds.delete(event.id);
|
|
182
|
+
} else {
|
|
183
|
+
this._queuePending(event);
|
|
175
184
|
}
|
|
176
185
|
return sent;
|
|
177
186
|
}
|
|
178
187
|
|
|
188
|
+
_queuePending(event) {
|
|
189
|
+
if (event?.id && this._pendingIds.has(event.id)) return;
|
|
190
|
+
if (event?.id) this._pendingIds.add(event.id);
|
|
191
|
+
this.pending.push({ event, ts: Date.now() });
|
|
192
|
+
while (this.pending.length > PENDING_MAX) {
|
|
193
|
+
const dropped = this.pending.shift();
|
|
194
|
+
if (dropped.event?.id) this._pendingIds.delete(dropped.event.id);
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
// Resolves true once any relay sends OK accepted, false on relay reject,
|
|
199
|
+
// or false on timeout. Gives callers delivery confidence beyond fire-and-forget.
|
|
200
|
+
publishAndWait(event, { timeoutMs = 8000 } = {}) {
|
|
201
|
+
const sent = this.publish(event);
|
|
202
|
+
if (!event?.id) return Promise.resolve(sent);
|
|
203
|
+
return new Promise((resolve) => {
|
|
204
|
+
const prior = this._acks.get(event.id);
|
|
205
|
+
if (prior) clearTimeout(prior.timer);
|
|
206
|
+
const settle = (ok) => {
|
|
207
|
+
const rec = this._acks.get(event.id);
|
|
208
|
+
if (rec) { clearTimeout(rec.timer); this._acks.delete(event.id); }
|
|
209
|
+
resolve(ok);
|
|
210
|
+
};
|
|
211
|
+
const timer = setTimeout(() => settle(false), timeoutMs);
|
|
212
|
+
this._acks.set(event.id, { resolve: settle, timer });
|
|
213
|
+
});
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
_settleAck(id, accepted) {
|
|
217
|
+
const rec = this._acks.get(id);
|
|
218
|
+
if (rec) rec.resolve(accepted);
|
|
219
|
+
}
|
|
220
|
+
|
|
179
221
|
_drainPending() {
|
|
180
222
|
const cutoff = Date.now() - PENDING_TTL_MS;
|
|
181
223
|
const pending = this.pending.splice(0);
|
|
224
|
+
this._pendingIds.clear();
|
|
182
225
|
for (const p of pending) { if (p.ts >= cutoff) this.publish(p.event); }
|
|
183
226
|
}
|
|
184
227
|
|