nostr-tools 2.22.1 → 2.23.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.
- package/lib/cjs/abstract-pool.js +170 -235
- package/lib/cjs/abstract-pool.js.map +4 -4
- package/lib/cjs/abstract-relay.js +116 -199
- package/lib/cjs/abstract-relay.js.map +4 -4
- package/lib/cjs/index.js +235 -241
- package/lib/cjs/index.js.map +4 -4
- package/lib/cjs/nip04.js.map +1 -1
- package/lib/cjs/nip13.js +18 -8
- package/lib/cjs/nip13.js.map +2 -2
- package/lib/cjs/nip17.js.map +1 -1
- package/lib/cjs/nip18.js.map +1 -1
- package/lib/cjs/nip19.js.map +1 -1
- package/lib/cjs/nip21.js.map +1 -1
- package/lib/cjs/nip25.js.map +1 -1
- package/lib/cjs/nip27.js +1 -1
- package/lib/cjs/nip27.js.map +2 -2
- package/lib/cjs/nip28.js.map +1 -1
- package/lib/cjs/nip29.js.map +1 -1
- package/lib/cjs/nip44.js.map +1 -1
- package/lib/cjs/nip46.js +171 -236
- package/lib/cjs/nip46.js.map +4 -4
- package/lib/cjs/nip47.js.map +1 -1
- package/lib/cjs/nip57.js.map +1 -1
- package/lib/cjs/nip59.js.map +1 -1
- package/lib/cjs/nip98.js.map +1 -1
- package/lib/cjs/nipb7.js.map +1 -1
- package/lib/cjs/pool.js +171 -236
- package/lib/cjs/pool.js.map +4 -4
- package/lib/cjs/pure.js.map +1 -1
- package/lib/cjs/references.js.map +1 -1
- package/lib/cjs/relay.js +116 -199
- package/lib/cjs/relay.js.map +4 -4
- package/lib/cjs/signer.js.map +1 -1
- package/lib/cjs/utils.js +45 -44
- package/lib/cjs/utils.js.map +3 -3
- package/lib/esm/abstract-pool.js +170 -235
- package/lib/esm/abstract-pool.js.map +4 -4
- package/lib/esm/abstract-relay.js +116 -199
- package/lib/esm/abstract-relay.js.map +4 -4
- package/lib/esm/index.js +235 -241
- package/lib/esm/index.js.map +4 -4
- package/lib/esm/nip04.js.map +1 -1
- package/lib/esm/nip13.js +18 -8
- package/lib/esm/nip13.js.map +2 -2
- package/lib/esm/nip17.js.map +1 -1
- package/lib/esm/nip18.js.map +1 -1
- package/lib/esm/nip19.js.map +1 -1
- package/lib/esm/nip21.js.map +1 -1
- package/lib/esm/nip25.js.map +1 -1
- package/lib/esm/nip27.js +1 -1
- package/lib/esm/nip27.js.map +2 -2
- package/lib/esm/nip28.js.map +1 -1
- package/lib/esm/nip29.js.map +1 -1
- package/lib/esm/nip44.js.map +1 -1
- package/lib/esm/nip46.js +171 -236
- package/lib/esm/nip46.js.map +4 -4
- package/lib/esm/nip47.js.map +1 -1
- package/lib/esm/nip57.js.map +1 -1
- package/lib/esm/nip59.js.map +1 -1
- package/lib/esm/nip98.js.map +1 -1
- package/lib/esm/nipb7.js.map +1 -1
- package/lib/esm/pool.js +171 -236
- package/lib/esm/pool.js.map +4 -4
- package/lib/esm/pure.js.map +1 -1
- package/lib/esm/references.js.map +1 -1
- package/lib/esm/relay.js +116 -199
- package/lib/esm/relay.js.map +4 -4
- package/lib/esm/signer.js.map +1 -1
- package/lib/esm/utils.js +45 -44
- package/lib/esm/utils.js.map +3 -3
- package/lib/nostr.bundle.js +243 -249
- package/lib/nostr.bundle.js.map +4 -4
- package/lib/types/abstract-pool.d.ts +8 -1
- package/lib/types/abstract-relay.d.ts +3 -5
- package/lib/types/helpers.d.ts +0 -1
- package/lib/types/nip13.d.ts +0 -1
- package/lib/types/utils.d.ts +4 -16
- package/package.json +44 -1
package/lib/cjs/abstract-pool.js
CHANGED
|
@@ -52,54 +52,6 @@ function normalizeURL(url) {
|
|
|
52
52
|
throw new Error(`Invalid URL: ${url}`);
|
|
53
53
|
}
|
|
54
54
|
}
|
|
55
|
-
var QueueNode = class {
|
|
56
|
-
value;
|
|
57
|
-
next = null;
|
|
58
|
-
prev = null;
|
|
59
|
-
constructor(message) {
|
|
60
|
-
this.value = message;
|
|
61
|
-
}
|
|
62
|
-
};
|
|
63
|
-
var Queue = class {
|
|
64
|
-
first;
|
|
65
|
-
last;
|
|
66
|
-
constructor() {
|
|
67
|
-
this.first = null;
|
|
68
|
-
this.last = null;
|
|
69
|
-
}
|
|
70
|
-
enqueue(value) {
|
|
71
|
-
const newNode = new QueueNode(value);
|
|
72
|
-
if (!this.last) {
|
|
73
|
-
this.first = newNode;
|
|
74
|
-
this.last = newNode;
|
|
75
|
-
} else if (this.last === this.first) {
|
|
76
|
-
this.last = newNode;
|
|
77
|
-
this.last.prev = this.first;
|
|
78
|
-
this.first.next = newNode;
|
|
79
|
-
} else {
|
|
80
|
-
newNode.prev = this.last;
|
|
81
|
-
this.last.next = newNode;
|
|
82
|
-
this.last = newNode;
|
|
83
|
-
}
|
|
84
|
-
return true;
|
|
85
|
-
}
|
|
86
|
-
dequeue() {
|
|
87
|
-
if (!this.first)
|
|
88
|
-
return null;
|
|
89
|
-
if (this.first === this.last) {
|
|
90
|
-
const target2 = this.first;
|
|
91
|
-
this.first = null;
|
|
92
|
-
this.last = null;
|
|
93
|
-
return target2.value;
|
|
94
|
-
}
|
|
95
|
-
const target = this.first;
|
|
96
|
-
this.first = target.next;
|
|
97
|
-
if (this.first) {
|
|
98
|
-
this.first.prev = null;
|
|
99
|
-
}
|
|
100
|
-
return target.value;
|
|
101
|
-
}
|
|
102
|
-
};
|
|
103
55
|
|
|
104
56
|
// kinds.ts
|
|
105
57
|
var ClientAuth = 22242;
|
|
@@ -173,39 +125,6 @@ function makeAuthEvent(relayURL, challenge) {
|
|
|
173
125
|
};
|
|
174
126
|
}
|
|
175
127
|
|
|
176
|
-
// helpers.ts
|
|
177
|
-
async function yieldThread() {
|
|
178
|
-
return new Promise((resolve, reject) => {
|
|
179
|
-
try {
|
|
180
|
-
if (typeof MessageChannel !== "undefined") {
|
|
181
|
-
const ch = new MessageChannel();
|
|
182
|
-
const handler = () => {
|
|
183
|
-
ch.port1.removeEventListener("message", handler);
|
|
184
|
-
resolve();
|
|
185
|
-
};
|
|
186
|
-
ch.port1.addEventListener("message", handler);
|
|
187
|
-
ch.port2.postMessage(0);
|
|
188
|
-
ch.port1.start();
|
|
189
|
-
} else {
|
|
190
|
-
if (typeof setImmediate !== "undefined") {
|
|
191
|
-
setImmediate(resolve);
|
|
192
|
-
} else if (typeof setTimeout !== "undefined") {
|
|
193
|
-
setTimeout(resolve, 0);
|
|
194
|
-
} else {
|
|
195
|
-
resolve();
|
|
196
|
-
}
|
|
197
|
-
}
|
|
198
|
-
} catch (e) {
|
|
199
|
-
console.error("during yield: ", e);
|
|
200
|
-
reject(e);
|
|
201
|
-
}
|
|
202
|
-
});
|
|
203
|
-
}
|
|
204
|
-
var alwaysTrue = (t) => {
|
|
205
|
-
t[verifiedSymbol] = true;
|
|
206
|
-
return true;
|
|
207
|
-
};
|
|
208
|
-
|
|
209
128
|
// abstract-relay.ts
|
|
210
129
|
var SendingOnClosedConnection = class extends Error {
|
|
211
130
|
constructor(message, relay) {
|
|
@@ -227,16 +146,16 @@ var AbstractRelay = class {
|
|
|
227
146
|
openSubs = /* @__PURE__ */ new Map();
|
|
228
147
|
enablePing;
|
|
229
148
|
enableReconnect;
|
|
149
|
+
idleSince = Date.now();
|
|
150
|
+
ongoingOperations = 0;
|
|
230
151
|
reconnectTimeoutHandle;
|
|
231
152
|
pingIntervalHandle;
|
|
232
153
|
reconnectAttempts = 0;
|
|
233
|
-
|
|
154
|
+
skipReconnection = false;
|
|
234
155
|
connectionPromise;
|
|
235
156
|
openCountRequests = /* @__PURE__ */ new Map();
|
|
236
157
|
openEventPublishes = /* @__PURE__ */ new Map();
|
|
237
158
|
ws;
|
|
238
|
-
incomingMessageQueue = new Queue();
|
|
239
|
-
queueRunning = false;
|
|
240
159
|
challenge;
|
|
241
160
|
authPromise;
|
|
242
161
|
serial = 0;
|
|
@@ -288,12 +207,11 @@ var AbstractRelay = class {
|
|
|
288
207
|
}
|
|
289
208
|
this._connected = false;
|
|
290
209
|
this.connectionPromise = void 0;
|
|
291
|
-
|
|
292
|
-
this.
|
|
293
|
-
this.onclose?.();
|
|
294
|
-
if (this.enableReconnect && !wasIntentional) {
|
|
210
|
+
this.idleSince = void 0;
|
|
211
|
+
if (this.enableReconnect && !this.skipReconnection) {
|
|
295
212
|
this.reconnect();
|
|
296
213
|
} else {
|
|
214
|
+
this.onclose?.();
|
|
297
215
|
this.closeAllSubscriptions(reason);
|
|
298
216
|
}
|
|
299
217
|
}
|
|
@@ -303,11 +221,13 @@ var AbstractRelay = class {
|
|
|
303
221
|
return this.connectionPromise;
|
|
304
222
|
this.challenge = void 0;
|
|
305
223
|
this.authPromise = void 0;
|
|
224
|
+
this.skipReconnection = false;
|
|
306
225
|
this.connectionPromise = new Promise((resolve, reject) => {
|
|
307
226
|
if (opts?.timeout) {
|
|
308
227
|
connectionTimeoutHandle = setTimeout(() => {
|
|
309
228
|
reject("connection timed out");
|
|
310
229
|
this.connectionPromise = void 0;
|
|
230
|
+
this.skipReconnection = true;
|
|
311
231
|
this.onclose?.();
|
|
312
232
|
this.handleHardClose("relay connection timed out");
|
|
313
233
|
}, opts.timeout);
|
|
@@ -315,23 +235,14 @@ var AbstractRelay = class {
|
|
|
315
235
|
if (opts?.abort) {
|
|
316
236
|
opts.abort.onabort = reject;
|
|
317
237
|
}
|
|
318
|
-
const connectionFailed = () => {
|
|
319
|
-
clearTimeout(connectionTimeoutHandle);
|
|
320
|
-
reject("connection failed");
|
|
321
|
-
this.connectionPromise = void 0;
|
|
322
|
-
this.onclose?.();
|
|
323
|
-
this.handleHardClose("relay connection failed");
|
|
324
|
-
};
|
|
325
238
|
try {
|
|
326
239
|
this.ws = new this._WebSocket(this.url);
|
|
327
|
-
this.ws.addEventListener("error", connectionFailed);
|
|
328
240
|
} catch (err) {
|
|
329
241
|
clearTimeout(connectionTimeoutHandle);
|
|
330
242
|
reject(err);
|
|
331
243
|
return;
|
|
332
244
|
}
|
|
333
245
|
this.ws.onopen = () => {
|
|
334
|
-
this.ws?.removeEventListener("error", connectionFailed);
|
|
335
246
|
if (this.reconnectTimeoutHandle) {
|
|
336
247
|
clearTimeout(this.reconnectTimeoutHandle);
|
|
337
248
|
this.reconnectTimeoutHandle = void 0;
|
|
@@ -356,10 +267,13 @@ var AbstractRelay = class {
|
|
|
356
267
|
}
|
|
357
268
|
resolve();
|
|
358
269
|
};
|
|
359
|
-
this.ws.onerror = (
|
|
270
|
+
this.ws.onerror = () => {
|
|
360
271
|
clearTimeout(connectionTimeoutHandle);
|
|
361
|
-
reject(
|
|
362
|
-
this.
|
|
272
|
+
reject("connection failed");
|
|
273
|
+
this.connectionPromise = void 0;
|
|
274
|
+
this.skipReconnection = true;
|
|
275
|
+
this.onclose?.();
|
|
276
|
+
this.handleHardClose("relay connection failed");
|
|
363
277
|
};
|
|
364
278
|
this.ws.onclose = (ev) => {
|
|
365
279
|
clearTimeout(connectionTimeoutHandle);
|
|
@@ -385,7 +299,7 @@ var AbstractRelay = class {
|
|
|
385
299
|
const sub = this.subscribe(
|
|
386
300
|
[{ ids: ["aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"], limit: 0 }],
|
|
387
301
|
{
|
|
388
|
-
label: "forced-ping",
|
|
302
|
+
label: "<forced-ping>",
|
|
389
303
|
oneose: () => {
|
|
390
304
|
resolve(true);
|
|
391
305
|
sub.close();
|
|
@@ -414,20 +328,106 @@ var AbstractRelay = class {
|
|
|
414
328
|
}
|
|
415
329
|
}
|
|
416
330
|
}
|
|
417
|
-
async
|
|
418
|
-
this.
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
331
|
+
async send(message) {
|
|
332
|
+
if (!this.connectionPromise)
|
|
333
|
+
throw new SendingOnClosedConnection(message, this.url);
|
|
334
|
+
this.connectionPromise.then(() => {
|
|
335
|
+
this.ws?.send(message);
|
|
336
|
+
});
|
|
337
|
+
}
|
|
338
|
+
async auth(signAuthEvent) {
|
|
339
|
+
const challenge = this.challenge;
|
|
340
|
+
if (!challenge)
|
|
341
|
+
throw new Error("can't perform auth, no challenge was received");
|
|
342
|
+
if (this.authPromise)
|
|
343
|
+
return this.authPromise;
|
|
344
|
+
this.authPromise = new Promise(async (resolve, reject) => {
|
|
345
|
+
try {
|
|
346
|
+
let evt = await signAuthEvent(makeAuthEvent(this.url, challenge));
|
|
347
|
+
let timeout = setTimeout(() => {
|
|
348
|
+
let ep = this.openEventPublishes.get(evt.id);
|
|
349
|
+
if (ep) {
|
|
350
|
+
ep.reject(new Error("auth timed out"));
|
|
351
|
+
this.openEventPublishes.delete(evt.id);
|
|
352
|
+
}
|
|
353
|
+
}, this.publishTimeout);
|
|
354
|
+
this.openEventPublishes.set(evt.id, { resolve, reject, timeout });
|
|
355
|
+
this.send('["AUTH",' + JSON.stringify(evt) + "]");
|
|
356
|
+
} catch (err) {
|
|
357
|
+
console.warn("subscribe auth function failed:", err);
|
|
422
358
|
}
|
|
423
|
-
|
|
359
|
+
});
|
|
360
|
+
return this.authPromise;
|
|
361
|
+
}
|
|
362
|
+
async publish(event) {
|
|
363
|
+
this.idleSince = void 0;
|
|
364
|
+
this.ongoingOperations++;
|
|
365
|
+
const ret = new Promise((resolve, reject) => {
|
|
366
|
+
const timeout = setTimeout(() => {
|
|
367
|
+
const ep = this.openEventPublishes.get(event.id);
|
|
368
|
+
if (ep) {
|
|
369
|
+
ep.reject(new Error("publish timed out"));
|
|
370
|
+
this.openEventPublishes.delete(event.id);
|
|
371
|
+
}
|
|
372
|
+
}, this.publishTimeout);
|
|
373
|
+
this.openEventPublishes.set(event.id, { resolve, reject, timeout });
|
|
374
|
+
});
|
|
375
|
+
this.send('["EVENT",' + JSON.stringify(event) + "]");
|
|
376
|
+
this.ongoingOperations--;
|
|
377
|
+
if (this.ongoingOperations === 0)
|
|
378
|
+
this.idleSince = Date.now();
|
|
379
|
+
return ret;
|
|
380
|
+
}
|
|
381
|
+
async count(filters, params) {
|
|
382
|
+
this.serial++;
|
|
383
|
+
const id = params?.id || "count:" + this.serial;
|
|
384
|
+
const ret = new Promise((resolve, reject) => {
|
|
385
|
+
this.openCountRequests.set(id, { resolve, reject });
|
|
386
|
+
});
|
|
387
|
+
this.send('["COUNT","' + id + '",' + JSON.stringify(filters).substring(1));
|
|
388
|
+
return ret;
|
|
389
|
+
}
|
|
390
|
+
subscribe(filters, params) {
|
|
391
|
+
if (params.label !== "<forced-ping>") {
|
|
392
|
+
this.idleSince = void 0;
|
|
393
|
+
this.ongoingOperations++;
|
|
394
|
+
}
|
|
395
|
+
const sub = this.prepareSubscription(filters, params);
|
|
396
|
+
sub.fire();
|
|
397
|
+
if (params.abort) {
|
|
398
|
+
params.abort.onabort = () => sub.close(String(params.abort.reason || "<aborted>"));
|
|
424
399
|
}
|
|
425
|
-
|
|
400
|
+
return sub;
|
|
426
401
|
}
|
|
427
|
-
|
|
428
|
-
|
|
402
|
+
prepareSubscription(filters, params) {
|
|
403
|
+
this.serial++;
|
|
404
|
+
const id = params.id || (params.label ? params.label + ":" : "sub:") + this.serial;
|
|
405
|
+
const sub = new Subscription(this, id, filters, params);
|
|
406
|
+
this.openSubs.set(id, sub);
|
|
407
|
+
return sub;
|
|
408
|
+
}
|
|
409
|
+
close() {
|
|
410
|
+
this.skipReconnection = true;
|
|
411
|
+
if (this.reconnectTimeoutHandle) {
|
|
412
|
+
clearTimeout(this.reconnectTimeoutHandle);
|
|
413
|
+
this.reconnectTimeoutHandle = void 0;
|
|
414
|
+
}
|
|
415
|
+
if (this.pingIntervalHandle) {
|
|
416
|
+
clearInterval(this.pingIntervalHandle);
|
|
417
|
+
this.pingIntervalHandle = void 0;
|
|
418
|
+
}
|
|
419
|
+
this.closeAllSubscriptions("relay connection closed by us");
|
|
420
|
+
this._connected = false;
|
|
421
|
+
this.idleSince = void 0;
|
|
422
|
+
this.onclose?.();
|
|
423
|
+
if (this.ws?.readyState === this._WebSocket.OPEN) {
|
|
424
|
+
this.ws?.close();
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
_onmessage(ev) {
|
|
428
|
+
const json = ev.data;
|
|
429
429
|
if (!json) {
|
|
430
|
-
return
|
|
430
|
+
return;
|
|
431
431
|
}
|
|
432
432
|
const subid = getSubscriptionId(json);
|
|
433
433
|
if (subid) {
|
|
@@ -514,101 +514,11 @@ var AbstractRelay = class {
|
|
|
514
514
|
}
|
|
515
515
|
}
|
|
516
516
|
} catch (err) {
|
|
517
|
+
const [_, __, event] = JSON.parse(json);
|
|
518
|
+
window.printer.maybe(event.pubkey, ":: caught err", event, this.url, err);
|
|
517
519
|
return;
|
|
518
520
|
}
|
|
519
521
|
}
|
|
520
|
-
async send(message) {
|
|
521
|
-
if (!this.connectionPromise)
|
|
522
|
-
throw new SendingOnClosedConnection(message, this.url);
|
|
523
|
-
this.connectionPromise.then(() => {
|
|
524
|
-
this.ws?.send(message);
|
|
525
|
-
});
|
|
526
|
-
}
|
|
527
|
-
async auth(signAuthEvent) {
|
|
528
|
-
const challenge = this.challenge;
|
|
529
|
-
if (!challenge)
|
|
530
|
-
throw new Error("can't perform auth, no challenge was received");
|
|
531
|
-
if (this.authPromise)
|
|
532
|
-
return this.authPromise;
|
|
533
|
-
this.authPromise = new Promise(async (resolve, reject) => {
|
|
534
|
-
try {
|
|
535
|
-
let evt = await signAuthEvent(makeAuthEvent(this.url, challenge));
|
|
536
|
-
let timeout = setTimeout(() => {
|
|
537
|
-
let ep = this.openEventPublishes.get(evt.id);
|
|
538
|
-
if (ep) {
|
|
539
|
-
ep.reject(new Error("auth timed out"));
|
|
540
|
-
this.openEventPublishes.delete(evt.id);
|
|
541
|
-
}
|
|
542
|
-
}, this.publishTimeout);
|
|
543
|
-
this.openEventPublishes.set(evt.id, { resolve, reject, timeout });
|
|
544
|
-
this.send('["AUTH",' + JSON.stringify(evt) + "]");
|
|
545
|
-
} catch (err) {
|
|
546
|
-
console.warn("subscribe auth function failed:", err);
|
|
547
|
-
}
|
|
548
|
-
});
|
|
549
|
-
return this.authPromise;
|
|
550
|
-
}
|
|
551
|
-
async publish(event) {
|
|
552
|
-
const ret = new Promise((resolve, reject) => {
|
|
553
|
-
const timeout = setTimeout(() => {
|
|
554
|
-
const ep = this.openEventPublishes.get(event.id);
|
|
555
|
-
if (ep) {
|
|
556
|
-
ep.reject(new Error("publish timed out"));
|
|
557
|
-
this.openEventPublishes.delete(event.id);
|
|
558
|
-
}
|
|
559
|
-
}, this.publishTimeout);
|
|
560
|
-
this.openEventPublishes.set(event.id, { resolve, reject, timeout });
|
|
561
|
-
});
|
|
562
|
-
this.send('["EVENT",' + JSON.stringify(event) + "]");
|
|
563
|
-
return ret;
|
|
564
|
-
}
|
|
565
|
-
async count(filters, params) {
|
|
566
|
-
this.serial++;
|
|
567
|
-
const id = params?.id || "count:" + this.serial;
|
|
568
|
-
const ret = new Promise((resolve, reject) => {
|
|
569
|
-
this.openCountRequests.set(id, { resolve, reject });
|
|
570
|
-
});
|
|
571
|
-
this.send('["COUNT","' + id + '",' + JSON.stringify(filters).substring(1));
|
|
572
|
-
return ret;
|
|
573
|
-
}
|
|
574
|
-
subscribe(filters, params) {
|
|
575
|
-
const sub = this.prepareSubscription(filters, params);
|
|
576
|
-
sub.fire();
|
|
577
|
-
if (params.abort) {
|
|
578
|
-
params.abort.onabort = () => sub.close(String(params.abort.reason || "<aborted>"));
|
|
579
|
-
}
|
|
580
|
-
return sub;
|
|
581
|
-
}
|
|
582
|
-
prepareSubscription(filters, params) {
|
|
583
|
-
this.serial++;
|
|
584
|
-
const id = params.id || (params.label ? params.label + ":" : "sub:") + this.serial;
|
|
585
|
-
const subscription = new Subscription(this, id, filters, params);
|
|
586
|
-
this.openSubs.set(id, subscription);
|
|
587
|
-
return subscription;
|
|
588
|
-
}
|
|
589
|
-
close() {
|
|
590
|
-
this.closedIntentionally = true;
|
|
591
|
-
if (this.reconnectTimeoutHandle) {
|
|
592
|
-
clearTimeout(this.reconnectTimeoutHandle);
|
|
593
|
-
this.reconnectTimeoutHandle = void 0;
|
|
594
|
-
}
|
|
595
|
-
if (this.pingIntervalHandle) {
|
|
596
|
-
clearInterval(this.pingIntervalHandle);
|
|
597
|
-
this.pingIntervalHandle = void 0;
|
|
598
|
-
}
|
|
599
|
-
this.closeAllSubscriptions("relay connection closed by us");
|
|
600
|
-
this._connected = false;
|
|
601
|
-
this.onclose?.();
|
|
602
|
-
if (this.ws?.readyState === this._WebSocket.OPEN) {
|
|
603
|
-
this.ws?.close();
|
|
604
|
-
}
|
|
605
|
-
}
|
|
606
|
-
_onmessage(ev) {
|
|
607
|
-
this.incomingMessageQueue.enqueue(ev.data);
|
|
608
|
-
if (!this.queueRunning) {
|
|
609
|
-
this.runQueue();
|
|
610
|
-
}
|
|
611
|
-
}
|
|
612
522
|
};
|
|
613
523
|
var Subscription = class {
|
|
614
524
|
relay;
|
|
@@ -667,10 +577,19 @@ var Subscription = class {
|
|
|
667
577
|
this.closed = true;
|
|
668
578
|
}
|
|
669
579
|
this.relay.openSubs.delete(this.id);
|
|
580
|
+
this.relay.ongoingOperations--;
|
|
581
|
+
if (this.relay.ongoingOperations === 0)
|
|
582
|
+
this.relay.idleSince = Date.now();
|
|
670
583
|
this.onclose?.(reason);
|
|
671
584
|
}
|
|
672
585
|
};
|
|
673
586
|
|
|
587
|
+
// helpers.ts
|
|
588
|
+
var alwaysTrue = (t) => {
|
|
589
|
+
t[verifiedSymbol] = true;
|
|
590
|
+
return true;
|
|
591
|
+
};
|
|
592
|
+
|
|
674
593
|
// abstract-pool.ts
|
|
675
594
|
var AbstractSimplePool = class {
|
|
676
595
|
relays = /* @__PURE__ */ new Map();
|
|
@@ -682,7 +601,9 @@ var AbstractSimplePool = class {
|
|
|
682
601
|
automaticallyAuth;
|
|
683
602
|
trustedRelayURLs = /* @__PURE__ */ new Set();
|
|
684
603
|
onRelayConnectionFailure;
|
|
604
|
+
onRelayConnectionSuccess;
|
|
685
605
|
allowConnectingToRelay;
|
|
606
|
+
maxWaitForConnection;
|
|
686
607
|
_WebSocket;
|
|
687
608
|
constructor(opts) {
|
|
688
609
|
this.verifyEvent = opts.verifyEvent;
|
|
@@ -691,7 +612,9 @@ var AbstractSimplePool = class {
|
|
|
691
612
|
this.enableReconnect = opts.enableReconnect || false;
|
|
692
613
|
this.automaticallyAuth = opts.automaticallyAuth;
|
|
693
614
|
this.onRelayConnectionFailure = opts.onRelayConnectionFailure;
|
|
615
|
+
this.onRelayConnectionSuccess = opts.onRelayConnectionSuccess;
|
|
694
616
|
this.allowConnectingToRelay = opts.allowConnectingToRelay;
|
|
617
|
+
this.maxWaitForConnection = opts.maxWaitForConnection || 3e3;
|
|
695
618
|
}
|
|
696
619
|
async ensureRelay(url, params) {
|
|
697
620
|
url = normalizeURL(url);
|
|
@@ -704,9 +627,7 @@ var AbstractSimplePool = class {
|
|
|
704
627
|
enableReconnect: this.enableReconnect
|
|
705
628
|
});
|
|
706
629
|
relay.onclose = () => {
|
|
707
|
-
|
|
708
|
-
this.relays.delete(url);
|
|
709
|
-
}
|
|
630
|
+
this.relays.delete(url);
|
|
710
631
|
};
|
|
711
632
|
this.relays.set(url, relay);
|
|
712
633
|
}
|
|
@@ -716,10 +637,15 @@ var AbstractSimplePool = class {
|
|
|
716
637
|
relay.onauth = authSignerFn;
|
|
717
638
|
}
|
|
718
639
|
}
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
640
|
+
try {
|
|
641
|
+
await relay.connect({
|
|
642
|
+
timeout: params?.connectionTimeout,
|
|
643
|
+
abort: params?.abort
|
|
644
|
+
});
|
|
645
|
+
} catch (err) {
|
|
646
|
+
this.relays.delete(url);
|
|
647
|
+
throw err;
|
|
648
|
+
}
|
|
723
649
|
return relay;
|
|
724
650
|
}
|
|
725
651
|
close(relays) {
|
|
@@ -730,25 +656,20 @@ var AbstractSimplePool = class {
|
|
|
730
656
|
}
|
|
731
657
|
subscribe(relays, filter, params) {
|
|
732
658
|
const request = [];
|
|
659
|
+
const uniqUrls = [];
|
|
733
660
|
for (let i = 0; i < relays.length; i++) {
|
|
734
661
|
const url = normalizeURL(relays[i]);
|
|
735
662
|
if (!request.find((r) => r.url === url)) {
|
|
736
|
-
|
|
663
|
+
if (uniqUrls.indexOf(url) === -1) {
|
|
664
|
+
uniqUrls.push(url);
|
|
665
|
+
request.push({ url, filter });
|
|
666
|
+
}
|
|
737
667
|
}
|
|
738
668
|
}
|
|
739
669
|
return this.subscribeMap(request, params);
|
|
740
670
|
}
|
|
741
671
|
subscribeMany(relays, filter, params) {
|
|
742
|
-
|
|
743
|
-
const uniqUrls = [];
|
|
744
|
-
for (let i = 0; i < relays.length; i++) {
|
|
745
|
-
const url = normalizeURL(relays[i]);
|
|
746
|
-
if (uniqUrls.indexOf(url) === -1) {
|
|
747
|
-
uniqUrls.push(url);
|
|
748
|
-
request.push({ url, filter });
|
|
749
|
-
}
|
|
750
|
-
}
|
|
751
|
-
return this.subscribeMap(request, params);
|
|
672
|
+
return this.subscribe(relays, filter, params);
|
|
752
673
|
}
|
|
753
674
|
subscribeMap(requests, params) {
|
|
754
675
|
const grouped = /* @__PURE__ */ new Map();
|
|
@@ -811,7 +732,7 @@ var AbstractSimplePool = class {
|
|
|
811
732
|
let relay;
|
|
812
733
|
try {
|
|
813
734
|
relay = await this.ensureRelay(url, {
|
|
814
|
-
connectionTimeout: params.maxWait ? Math.max(params.maxWait * 0.8, params.maxWait - 1e3) :
|
|
735
|
+
connectionTimeout: this.maxWaitForConnection < (params.maxWait || 0) ? Math.max(params.maxWait * 0.8, params.maxWait - 1e3) : this.maxWaitForConnection,
|
|
815
736
|
abort: params.abort
|
|
816
737
|
});
|
|
817
738
|
} catch (err) {
|
|
@@ -819,6 +740,7 @@ var AbstractSimplePool = class {
|
|
|
819
740
|
handleClose(i, err?.message || String(err));
|
|
820
741
|
return;
|
|
821
742
|
}
|
|
743
|
+
this.onRelayConnectionSuccess?.(url);
|
|
822
744
|
let subscription = relay.subscribe(filters, {
|
|
823
745
|
...params,
|
|
824
746
|
oneose: () => handleEose(i),
|
|
@@ -859,22 +781,21 @@ var AbstractSimplePool = class {
|
|
|
859
781
|
};
|
|
860
782
|
}
|
|
861
783
|
subscribeEose(relays, filter, params) {
|
|
862
|
-
|
|
784
|
+
let subcloser;
|
|
785
|
+
subcloser = this.subscribe(relays, filter, {
|
|
863
786
|
...params,
|
|
864
787
|
oneose() {
|
|
865
|
-
|
|
788
|
+
const reason = "closed automatically on eose";
|
|
789
|
+
if (subcloser)
|
|
790
|
+
subcloser.close(reason);
|
|
791
|
+
else
|
|
792
|
+
params.onclose?.(relays.map((_) => reason));
|
|
866
793
|
}
|
|
867
794
|
});
|
|
868
795
|
return subcloser;
|
|
869
796
|
}
|
|
870
797
|
subscribeManyEose(relays, filter, params) {
|
|
871
|
-
|
|
872
|
-
...params,
|
|
873
|
-
oneose() {
|
|
874
|
-
subcloser.close("closed automatically on eose");
|
|
875
|
-
}
|
|
876
|
-
});
|
|
877
|
-
return subcloser;
|
|
798
|
+
return this.subscribeEose(relays, filter, params);
|
|
878
799
|
}
|
|
879
800
|
async querySync(relays, filter, params) {
|
|
880
801
|
return new Promise(async (resolve) => {
|
|
@@ -896,7 +817,7 @@ var AbstractSimplePool = class {
|
|
|
896
817
|
events.sort((a, b) => b.created_at - a.created_at);
|
|
897
818
|
return events[0] || null;
|
|
898
819
|
}
|
|
899
|
-
publish(relays, event,
|
|
820
|
+
publish(relays, event, params) {
|
|
900
821
|
return relays.map(normalizeURL).map(async (url, i, arr) => {
|
|
901
822
|
if (arr.indexOf(url) !== i) {
|
|
902
823
|
return Promise.reject("duplicate url");
|
|
@@ -906,14 +827,17 @@ var AbstractSimplePool = class {
|
|
|
906
827
|
}
|
|
907
828
|
let r;
|
|
908
829
|
try {
|
|
909
|
-
r = await this.ensureRelay(url
|
|
830
|
+
r = await this.ensureRelay(url, {
|
|
831
|
+
connectionTimeout: this.maxWaitForConnection < (params?.maxWait || 0) ? Math.max(params.maxWait * 0.8, params.maxWait - 1e3) : this.maxWaitForConnection,
|
|
832
|
+
abort: params?.abort
|
|
833
|
+
});
|
|
910
834
|
} catch (err) {
|
|
911
835
|
this.onRelayConnectionFailure?.(url);
|
|
912
836
|
return String("connection failure: " + String(err));
|
|
913
837
|
}
|
|
914
838
|
return r.publish(event).catch(async (err) => {
|
|
915
|
-
if (err instanceof Error && err.message.startsWith("auth-required: ") &&
|
|
916
|
-
await r.auth(
|
|
839
|
+
if (err instanceof Error && err.message.startsWith("auth-required: ") && params?.onauth) {
|
|
840
|
+
await r.auth(params.onauth);
|
|
917
841
|
return r.publish(event);
|
|
918
842
|
}
|
|
919
843
|
throw err;
|
|
@@ -939,4 +863,15 @@ var AbstractSimplePool = class {
|
|
|
939
863
|
this.relays.forEach((conn) => conn.close());
|
|
940
864
|
this.relays = /* @__PURE__ */ new Map();
|
|
941
865
|
}
|
|
866
|
+
pruneIdleRelays(idleThresholdMs = 1e4) {
|
|
867
|
+
const prunedUrls = [];
|
|
868
|
+
for (const [url, relay] of this.relays) {
|
|
869
|
+
if (relay.idleSince && Date.now() - relay.idleSince >= idleThresholdMs) {
|
|
870
|
+
this.relays.delete(url);
|
|
871
|
+
prunedUrls.push(url);
|
|
872
|
+
relay.close();
|
|
873
|
+
}
|
|
874
|
+
}
|
|
875
|
+
return prunedUrls;
|
|
876
|
+
}
|
|
942
877
|
};
|