applesauce-relay 1.0.0 → 1.0.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/dist/__tests__/relay.test.js +28 -4
- package/dist/relay.js +17 -9
- package/package.json +1 -1
|
@@ -47,17 +47,33 @@ describe("req", () => {
|
|
|
47
47
|
await firstValueFrom(relay.connected$.pipe(filter(Boolean)));
|
|
48
48
|
expect(relay.connected).toBe(true);
|
|
49
49
|
});
|
|
50
|
-
it("should send
|
|
50
|
+
it("should send expected messages to relay", async () => {
|
|
51
|
+
subscribeSpyTo(relay.req([{ kinds: [1] }], "sub1"));
|
|
52
|
+
// Wait for all message to be sent
|
|
53
|
+
await new Promise((resolve) => setTimeout(resolve, 10));
|
|
54
|
+
expect(server.messages).toEqual([["REQ", "sub1", { kinds: [1] }]]);
|
|
55
|
+
});
|
|
56
|
+
it("should not close the REQ when EOSE is received", async () => {
|
|
51
57
|
// Create subscription that completes after first EOSE
|
|
52
|
-
const sub = relay.req([{ kinds: [1] }], "sub1")
|
|
58
|
+
const sub = subscribeSpyTo(relay.req([{ kinds: [1] }], "sub1"));
|
|
53
59
|
// Verify REQ was sent
|
|
54
|
-
expect(
|
|
60
|
+
await expect(server).toReceiveMessage(["REQ", "sub1", { kinds: [1] }]);
|
|
55
61
|
// Send EOSE to complete subscription
|
|
62
|
+
server.send(["EVENT", "sub1", mockEvent]);
|
|
56
63
|
server.send(["EOSE", "sub1"]);
|
|
64
|
+
// Verify the subscription did not complete
|
|
65
|
+
expect(sub.receivedComplete()).toBe(false);
|
|
66
|
+
expect(sub.getValues()).toEqual([expect.objectContaining(mockEvent), "EOSE"]);
|
|
67
|
+
});
|
|
68
|
+
it("should send CLOSE when unsubscribed", async () => {
|
|
69
|
+
// Create subscription that completes after first EOSE
|
|
70
|
+
const sub = subscribeSpyTo(relay.req([{ kinds: [1] }], "sub1"));
|
|
71
|
+
// Verify REQ was sent
|
|
72
|
+
await expect(server).toReceiveMessage(["REQ", "sub1", { kinds: [1] }]);
|
|
57
73
|
// Complete the subscription
|
|
58
74
|
sub.unsubscribe();
|
|
59
75
|
// Verify CLOSE was sent
|
|
60
|
-
expect(
|
|
76
|
+
await expect(server).toReceiveMessage(["CLOSE", "sub1"]);
|
|
61
77
|
});
|
|
62
78
|
it("should emit nostr event and EOSE", async () => {
|
|
63
79
|
const spy = subscribeSpyTo(relay.req([{ kinds: [1] }], "sub1"));
|
|
@@ -99,6 +115,14 @@ describe("req", () => {
|
|
|
99
115
|
// Verify the subscription completed
|
|
100
116
|
expect(spy.receivedError()).toBe(true);
|
|
101
117
|
});
|
|
118
|
+
it("should not send multiple REQ messages for multiple subscriptions", async () => {
|
|
119
|
+
const sub = relay.req([{ kinds: [1] }], "sub1");
|
|
120
|
+
sub.subscribe();
|
|
121
|
+
sub.subscribe();
|
|
122
|
+
// Wait for all messages to be sent
|
|
123
|
+
await new Promise((resolve) => setTimeout(resolve, 10));
|
|
124
|
+
expect(server.messages).toEqual([["REQ", "sub1", { kinds: [1] }]]);
|
|
125
|
+
});
|
|
102
126
|
it("should wait for authentication if relay responds with auth-required", async () => {
|
|
103
127
|
// First subscription to trigger auth-required
|
|
104
128
|
const firstSub = subscribeSpyTo(relay.req([{ kinds: [1] }], "sub1"), { expectErrors: true });
|
package/dist/relay.js
CHANGED
|
@@ -187,13 +187,17 @@ export class Relay {
|
|
|
187
187
|
}
|
|
188
188
|
/** Wait for the relay to be ready to accept connections */
|
|
189
189
|
waitForReady(observable) {
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
190
|
+
// Don't wait if the relay is already ready
|
|
191
|
+
if (this.ready$.value)
|
|
192
|
+
return observable;
|
|
193
|
+
else
|
|
194
|
+
return this.ready$.pipe(
|
|
195
|
+
// wait for ready to be true
|
|
196
|
+
filter((ready) => ready),
|
|
197
|
+
// complete after the first value so this does not repeat
|
|
198
|
+
take(1),
|
|
199
|
+
// switch to the observable
|
|
200
|
+
switchMap(() => observable));
|
|
197
201
|
}
|
|
198
202
|
multiplex(open, close, filter) {
|
|
199
203
|
return this.socket.multiplex(open, close, filter);
|
|
@@ -234,7 +238,9 @@ export class Relay {
|
|
|
234
238
|
timeout({
|
|
235
239
|
first: this.eoseTimeout,
|
|
236
240
|
with: () => merge(of("EOSE"), NEVER),
|
|
237
|
-
})
|
|
241
|
+
}),
|
|
242
|
+
// Only create one upstream subscription
|
|
243
|
+
share());
|
|
238
244
|
// Wait for auth if required and make sure to start the watch tower
|
|
239
245
|
return this.waitForReady(this.waitForAuth(this.authRequiredForReq, observable));
|
|
240
246
|
}
|
|
@@ -264,7 +270,9 @@ export class Relay {
|
|
|
264
270
|
timeout({
|
|
265
271
|
first: this.eventTimeout,
|
|
266
272
|
with: () => of({ ok: false, from: this.url, message: "Timeout" }),
|
|
267
|
-
})
|
|
273
|
+
}),
|
|
274
|
+
// Only create one upstream subscription
|
|
275
|
+
share());
|
|
268
276
|
// skip wait for auth if verb is AUTH
|
|
269
277
|
if (verb === "AUTH")
|
|
270
278
|
return this.waitForReady(observable);
|