applesauce-relay 0.0.0-next-20250428223834 → 0.0.0-next-20250430170741

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/group.d.ts CHANGED
@@ -11,7 +11,7 @@ export declare class RelayGroup implements IGroup {
11
11
  /** Send an event to all relays */
12
12
  event(event: NostrEvent): Observable<PublishResponse>;
13
13
  /** Publish an event to all relays with retries ( default 3 retries ) */
14
- publish(event: NostrEvent, opts?: PublishOptions): Observable<PublishResponse[]>;
14
+ publish(event: NostrEvent, opts?: PublishOptions): Observable<PublishResponse>;
15
15
  /** Request events from all relays with retries ( default 3 retries ) */
16
16
  request(filters: Filter | Filter[], opts?: RequestOptions): Observable<NostrEvent>;
17
17
  /** Open a subscription to all relays with retries ( default 3 retries ) */
package/dist/group.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { nanoid } from "nanoid";
2
- import { catchError, EMPTY, endWith, ignoreElements, merge, of, toArray } from "rxjs";
2
+ import { catchError, EMPTY, endWith, ignoreElements, merge, of } from "rxjs";
3
3
  import { completeOnEose } from "./operators/complete-on-eose.js";
4
4
  import { onlyEvents } from "./operators/only-events.js";
5
5
  export class RelayGroup {
@@ -37,7 +37,7 @@ export class RelayGroup {
37
37
  publish(event, opts) {
38
38
  return merge(...this.relays.map((relay) => relay.publish(event, opts).pipe(
39
39
  // Catch error and return as PublishResponse
40
- catchError((err) => of({ ok: false, from: relay.url, message: err?.message || "Unknown error" }))))).pipe(toArray());
40
+ catchError((err) => of({ ok: false, from: relay.url, message: err?.message || "Unknown error" })))));
41
41
  }
42
42
  /** Request events from all relays with retries ( default 3 retries ) */
43
43
  request(filters, opts) {
package/dist/pool.d.ts CHANGED
@@ -1,13 +1,18 @@
1
1
  import { NostrEvent, type Filter } from "nostr-tools";
2
- import { Observable } from "rxjs";
2
+ import { BehaviorSubject, Observable } from "rxjs";
3
3
  import { RelayGroup } from "./group.js";
4
4
  import { Relay, RelayOptions } from "./relay.js";
5
5
  import { IPool, PublishResponse, PublishOptions, RequestOptions, SubscriptionOptions, SubscriptionResponse } from "./types.js";
6
6
  export declare class RelayPool implements IPool {
7
7
  options?: RelayOptions | undefined;
8
- relays: Map<string, Relay>;
9
- groups: Map<string, RelayGroup>;
8
+ groups$: BehaviorSubject<Map<string, RelayGroup>>;
9
+ get groups(): Map<string, RelayGroup>;
10
+ relays$: BehaviorSubject<Map<string, Relay>>;
11
+ get relays(): Map<string, Relay>;
12
+ /** An array of relays to never connect to */
13
+ blacklist: Set<string>;
10
14
  constructor(options?: RelayOptions | undefined);
15
+ protected filterBlacklist(urls: string[]): string[];
11
16
  /** Get or create a new relay connection */
12
17
  relay(url: string): Relay;
13
18
  /** Create a group of relays */
@@ -17,7 +22,7 @@ export declare class RelayPool implements IPool {
17
22
  /** Send an EVENT message to multiple relays */
18
23
  event(relays: string[], event: NostrEvent): Observable<PublishResponse>;
19
24
  /** Publish an event to multiple relays */
20
- publish(relays: string[], event: NostrEvent, opts?: PublishOptions): Observable<PublishResponse[]>;
25
+ publish(relays: string[], event: NostrEvent, opts?: PublishOptions): Observable<PublishResponse>;
21
26
  /** Request events from multiple relays */
22
27
  request(relays: string[], filters: Filter | Filter[], opts?: RequestOptions): Observable<NostrEvent>;
23
28
  /** Open a subscription to multiple relays */
package/dist/pool.js CHANGED
@@ -1,31 +1,46 @@
1
+ import { BehaviorSubject } from "rxjs";
1
2
  import { RelayGroup } from "./group.js";
2
3
  import { Relay } from "./relay.js";
3
4
  export class RelayPool {
4
5
  options;
5
- relays = new Map();
6
- groups = new Map();
6
+ groups$ = new BehaviorSubject(new Map());
7
+ get groups() {
8
+ return this.groups$.value;
9
+ }
10
+ relays$ = new BehaviorSubject(new Map());
11
+ get relays() {
12
+ return this.relays$.value;
13
+ }
14
+ /** An array of relays to never connect to */
15
+ blacklist = new Set();
7
16
  constructor(options) {
8
17
  this.options = options;
9
18
  }
19
+ filterBlacklist(urls) {
20
+ return urls.filter((url) => !this.blacklist.has(url));
21
+ }
10
22
  /** Get or create a new relay connection */
11
23
  relay(url) {
24
+ if (this.blacklist.has(url))
25
+ throw new Error("Relay is on blacklist");
12
26
  let relay = this.relays.get(url);
13
27
  if (relay)
14
28
  return relay;
15
29
  else {
16
30
  relay = new Relay(url, this.options);
17
- this.relays.set(url, relay);
31
+ this.relays$.next(this.relays.set(url, relay));
18
32
  return relay;
19
33
  }
20
34
  }
21
35
  /** Create a group of relays */
22
36
  group(relays) {
37
+ relays = this.filterBlacklist(relays);
23
38
  const key = relays.sort().join(",");
24
39
  let group = this.groups.get(key);
25
40
  if (group)
26
41
  return group;
27
42
  group = new RelayGroup(relays.map((url) => this.relay(url)));
28
- this.groups.set(key, group);
43
+ this.groups$.next(this.groups.set(key, group));
29
44
  return group;
30
45
  }
31
46
  /** Make a REQ to multiple relays that does not deduplicate events */
package/dist/relay.d.ts CHANGED
@@ -28,14 +28,22 @@ export declare class Relay implements IRelay {
28
28
  authenticated$: BehaviorSubject<boolean>;
29
29
  /** The notices from the relay */
30
30
  notices$: BehaviorSubject<string[]>;
31
+ /** The last connection error */
32
+ error$: BehaviorSubject<Error | null>;
31
33
  /** An observable that emits the NIP-11 information document for the relay */
32
34
  information$: Observable<RelayInformation | null>;
33
35
  protected _nip11: RelayInformation | null;
34
36
  /** An observable that emits the limitations for the relay */
35
37
  limitations$: Observable<RelayInformation["limitation"] | null>;
36
- /** An observable of all messages from the relay */
38
+ /**
39
+ * An observable of all messages from the relay
40
+ * @note Subscribing to this will cause the relay to connect
41
+ */
37
42
  message$: Observable<any>;
38
- /** An observable of NOTICE messages from the relay */
43
+ /**
44
+ * An observable of NOTICE messages from the relay
45
+ * @note Subscribing to this will cause the relay to connect
46
+ */
39
47
  notice$: Observable<string>;
40
48
  get connected(): boolean;
41
49
  get challenge(): string | null;
package/dist/relay.js CHANGED
@@ -27,14 +27,22 @@ export class Relay {
27
27
  authenticated$ = new BehaviorSubject(false);
28
28
  /** The notices from the relay */
29
29
  notices$ = new BehaviorSubject([]);
30
+ /** The last connection error */
31
+ error$ = new BehaviorSubject(null);
30
32
  /** An observable that emits the NIP-11 information document for the relay */
31
33
  information$;
32
34
  _nip11 = null;
33
35
  /** An observable that emits the limitations for the relay */
34
36
  limitations$;
35
- /** An observable of all messages from the relay */
37
+ /**
38
+ * An observable of all messages from the relay
39
+ * @note Subscribing to this will cause the relay to connect
40
+ */
36
41
  message$;
37
- /** An observable of NOTICE messages from the relay */
42
+ /**
43
+ * An observable of NOTICE messages from the relay
44
+ * @note Subscribing to this will cause the relay to connect
45
+ */
38
46
  notice$;
39
47
  // sync state
40
48
  get connected() {
@@ -91,6 +99,7 @@ export class Relay {
91
99
  this.log("Connected");
92
100
  this.connected$.next(true);
93
101
  this.attempts$.next(0);
102
+ this.error$.next(null);
94
103
  this.resetState();
95
104
  },
96
105
  },
@@ -168,6 +177,7 @@ export class Relay {
168
177
  startReconnectTimer(error) {
169
178
  if (!this.ready$.value)
170
179
  return;
180
+ this.error$.next(error instanceof Error ? error : new Error("Connection error"));
171
181
  this.ready$.next(false);
172
182
  this.reconnectTimer(error, this.attempts$.value)
173
183
  .pipe(take(1))
package/dist/types.d.ts CHANGED
@@ -66,7 +66,7 @@ export interface IGroup extends Nip01Actions {
66
66
  /** Send an EVENT message with retries */
67
67
  publish(event: NostrEvent, opts?: {
68
68
  retries?: number;
69
- }): Observable<PublishResponse[]>;
69
+ }): Observable<PublishResponse>;
70
70
  /** Send a REQ message with retries */
71
71
  request(filters: Filter | Filter[], opts?: {
72
72
  id?: string;
@@ -90,7 +90,7 @@ export interface IPool {
90
90
  /** Send an EVENT message to relays with retries */
91
91
  publish(relays: string[], event: NostrEvent, opts?: {
92
92
  retries?: number;
93
- }): Observable<PublishResponse[]>;
93
+ }): Observable<PublishResponse>;
94
94
  /** Send a REQ message to relays with retries */
95
95
  request(relays: string[], filters: Filter | Filter[], opts?: {
96
96
  id?: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "applesauce-relay",
3
- "version": "0.0.0-next-20250428223834",
3
+ "version": "0.0.0-next-20250430170741",
4
4
  "description": "nostr relay communication framework built on rxjs",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -54,7 +54,7 @@
54
54
  },
55
55
  "dependencies": {
56
56
  "@noble/hashes": "^1.7.1",
57
- "applesauce-core": "0.0.0-next-20250428223834",
57
+ "applesauce-core": "^1.0.0",
58
58
  "nanoid": "^5.0.9",
59
59
  "nostr-tools": "^2.10.4",
60
60
  "rxjs": "^7.8.1"