applesauce-relay 0.0.0-next-20250430195017 → 0.0.0-next-20250430195256

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.
@@ -47,33 +47,17 @@ describe("req", () => {
47
47
  await firstValueFrom(relay.connected$.pipe(filter(Boolean)));
48
48
  expect(relay.connected).toBe(true);
49
49
  });
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 () => {
50
+ it("should send REQ and CLOSE messages", async () => {
57
51
  // Create subscription that completes after first EOSE
58
- const sub = subscribeSpyTo(relay.req([{ kinds: [1] }], "sub1"));
52
+ const sub = relay.req([{ kinds: [1] }], "sub1").subscribe();
59
53
  // Verify REQ was sent
60
- await expect(server).toReceiveMessage(["REQ", "sub1", { kinds: [1] }]);
54
+ expect(await server.nextMessage).toEqual(["REQ", "sub1", { kinds: [1] }]);
61
55
  // Send EOSE to complete subscription
62
- server.send(["EVENT", "sub1", mockEvent]);
63
56
  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] }]);
73
57
  // Complete the subscription
74
58
  sub.unsubscribe();
75
59
  // Verify CLOSE was sent
76
- await expect(server).toReceiveMessage(["CLOSE", "sub1"]);
60
+ expect(await server.nextMessage).toEqual(["CLOSE", "sub1"]);
77
61
  });
78
62
  it("should emit nostr event and EOSE", async () => {
79
63
  const spy = subscribeSpyTo(relay.req([{ kinds: [1] }], "sub1"));
package/dist/relay.js CHANGED
@@ -191,7 +191,9 @@ export class Relay {
191
191
  .subscribe(() => this.ready$.next(true));
192
192
  }
193
193
  /** Wait for ready and authenticated */
194
- waitForAuth(requireAuth, observable) {
194
+ waitForAuth(
195
+ // NOTE: require BehaviorSubject so it always has a value
196
+ requireAuth, observable) {
195
197
  return combineLatest([requireAuth, this.authenticated$]).pipe(
196
198
  // wait for auth not required or authenticated
197
199
  filter(([required, authenticated]) => !required || authenticated),
@@ -202,17 +204,13 @@ export class Relay {
202
204
  }
203
205
  /** Wait for the relay to be ready to accept connections */
204
206
  waitForReady(observable) {
205
- // If the relay is ready, don't wait
206
- if (this.ready$.value)
207
- return observable;
208
- else
209
- return this.ready$.pipe(
210
- // wait for ready to be true
211
- filter((ready) => ready),
212
- // complete after the first value so this does not repeat
213
- take(1),
214
- // switch to the observable
215
- switchMap(() => observable));
207
+ return this.ready$.pipe(
208
+ // wait for ready to be true
209
+ filter((ready) => ready),
210
+ // complete after the first value so this does not repeat
211
+ take(1),
212
+ // switch to the observable
213
+ switchMap(() => observable));
216
214
  }
217
215
  multiplex(open, close, filter) {
218
216
  return this.socket.multiplex(open, close, filter);
@@ -253,7 +251,9 @@ export class Relay {
253
251
  timeout({
254
252
  first: this.eoseTimeout,
255
253
  with: () => merge(of("EOSE"), NEVER),
256
- }));
254
+ }),
255
+ // Only create one upstream subscription
256
+ share());
257
257
  // Wait for auth if required and make sure to start the watch tower
258
258
  return this.waitForReady(this.waitForAuth(this.authRequiredForReq, observable));
259
259
  }
@@ -283,7 +283,9 @@ export class Relay {
283
283
  timeout({
284
284
  first: this.eventTimeout,
285
285
  with: () => of({ ok: false, from: this.url, message: "Timeout" }),
286
- }));
286
+ }),
287
+ // Only create one upstream subscription
288
+ share());
287
289
  // skip wait for auth if verb is AUTH
288
290
  if (verb === "AUTH")
289
291
  return this.waitForReady(observable);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "applesauce-relay",
3
- "version": "0.0.0-next-20250430195017",
3
+ "version": "0.0.0-next-20250430195256",
4
4
  "description": "nostr relay communication framework built on rxjs",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",