applesauce-relay 0.0.0-next-20250522030625 → 0.0.0-next-20250606170247
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 +12 -2
- package/dist/negentropy.d.ts +2 -2
- package/dist/negentropy.js +1 -1
- package/dist/relay.d.ts +2 -2
- package/dist/relay.js +7 -7
- package/package.json +3 -3
|
@@ -144,7 +144,7 @@ describe("req", () => {
|
|
|
144
144
|
// Verify the second subscription received the event and EOSE
|
|
145
145
|
expect(secondSub.getValues()).toEqual([expect.objectContaining(mockEvent), "EOSE"]);
|
|
146
146
|
});
|
|
147
|
-
it("should wait for authentication if relay info document has limitations.auth_required = true", async () => {
|
|
147
|
+
it("should open connection and wait for authentication if relay info document has limitations.auth_required = true", async () => {
|
|
148
148
|
// Mock the fetchInformationDocument method to return a document with auth_required = true
|
|
149
149
|
vi.spyOn(Relay, "fetchInformationDocument").mockImplementation(() => of({
|
|
150
150
|
name: "Auth Required Relay",
|
|
@@ -162,10 +162,20 @@ describe("req", () => {
|
|
|
162
162
|
const sub = subscribeSpyTo(relay.req([{ kinds: [1] }], "sub1"));
|
|
163
163
|
// Wait 10ms to ensure the information document is fetched
|
|
164
164
|
await new Promise((resolve) => setTimeout(resolve, 10));
|
|
165
|
+
// Wait for connection
|
|
166
|
+
await server.connected;
|
|
165
167
|
// Verify no REQ message was sent yet (waiting for auth)
|
|
166
168
|
expect(server).not.toHaveReceivedMessages(["REQ", "sub1", { kinds: [1] }]);
|
|
169
|
+
// Send AUTH challenge
|
|
170
|
+
server.send(["AUTH", "challenge"]);
|
|
171
|
+
// Send auth response
|
|
172
|
+
subscribeSpyTo(relay.auth(mockEvent));
|
|
173
|
+
// Verify the auth event was sent
|
|
174
|
+
await expect(server.nextMessage).resolves.toEqual(["AUTH", mockEvent]);
|
|
175
|
+
// Accept auth
|
|
176
|
+
server.send(["OK", mockEvent.id, true, ""]);
|
|
167
177
|
// Simulate successful authentication
|
|
168
|
-
relay.authenticated
|
|
178
|
+
expect(relay.authenticated).toBe(true);
|
|
169
179
|
// Now the REQ should be sent
|
|
170
180
|
await expect(server).toReceiveMessage(["REQ", "sub1", { kinds: [1] }]);
|
|
171
181
|
// Send EVENT and EOSE to complete the subscription
|
package/dist/negentropy.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { IEventStoreRead } from "applesauce-core";
|
|
2
2
|
import { Filter } from "nostr-tools";
|
|
3
3
|
import { MultiplexWebSocket } from "./types.js";
|
|
4
4
|
import { NegentropyStorageVector } from "./lib/negentropy.js";
|
|
5
|
-
export declare function buildStorageFromFilter(store:
|
|
5
|
+
export declare function buildStorageFromFilter(store: IEventStoreRead, filter: Filter): NegentropyStorageVector;
|
|
6
6
|
export declare function buildStorageVector(items: {
|
|
7
7
|
id: string;
|
|
8
8
|
created_at: number;
|
package/dist/negentropy.js
CHANGED
|
@@ -5,7 +5,7 @@ import { Negentropy, NegentropyStorageVector } from "./lib/negentropy.js";
|
|
|
5
5
|
const log = logger.extend("negentropy");
|
|
6
6
|
export function buildStorageFromFilter(store, filter) {
|
|
7
7
|
const storage = new NegentropyStorageVector();
|
|
8
|
-
for (const event of store.
|
|
8
|
+
for (const event of store.getByFilters(filter))
|
|
9
9
|
storage.insert(event.created_at, event.id);
|
|
10
10
|
storage.seal();
|
|
11
11
|
return storage;
|
package/dist/relay.d.ts
CHANGED
|
@@ -61,12 +61,12 @@ export declare class Relay implements IRelay {
|
|
|
61
61
|
protected authRequiredForReq: Observable<boolean>;
|
|
62
62
|
protected authRequiredForEvent: Observable<boolean>;
|
|
63
63
|
protected resetState(): void;
|
|
64
|
-
/** An internal observable that is responsible for watching all messages and updating state */
|
|
64
|
+
/** An internal observable that is responsible for watching all messages and updating state, subscribing to it will trigger a connection to the relay */
|
|
65
65
|
protected watchTower: Observable<never>;
|
|
66
66
|
constructor(url: string, opts?: RelayOptions);
|
|
67
67
|
/** Set ready = false and start the reconnect timer */
|
|
68
68
|
protected startReconnectTimer(error: Error | CloseEvent): void;
|
|
69
|
-
/** Wait for
|
|
69
|
+
/** Wait for authentication state, make connection and then wait for authentication if required */
|
|
70
70
|
protected waitForAuth<T extends unknown = unknown>(requireAuth: Observable<boolean>, observable: Observable<T>): Observable<T>;
|
|
71
71
|
/** Wait for the relay to be ready to accept connections */
|
|
72
72
|
protected waitForReady<T extends unknown = unknown>(observable: Observable<T>): Observable<T>;
|
package/dist/relay.js
CHANGED
|
@@ -2,7 +2,7 @@ import { logger } from "applesauce-core";
|
|
|
2
2
|
import { simpleTimeout } from "applesauce-core/observable";
|
|
3
3
|
import { nanoid } from "nanoid";
|
|
4
4
|
import { nip42 } from "nostr-tools";
|
|
5
|
-
import { BehaviorSubject, catchError, combineLatest, defer, endWith, filter, finalize, from, ignoreElements, isObservable, map, merge, mergeMap, NEVER, of, retry, scan, share, shareReplay, Subject, switchMap, take, takeUntil, tap, throwError, timeout, timer, } from "rxjs";
|
|
5
|
+
import { BehaviorSubject, catchError, combineLatest, defer, endWith, filter, finalize, from, ignoreElements, isObservable, map, merge, mergeMap, mergeWith, NEVER, of, retry, scan, share, shareReplay, Subject, switchMap, take, takeUntil, tap, throwError, timeout, timer, } from "rxjs";
|
|
6
6
|
import { webSocket } from "rxjs/webSocket";
|
|
7
7
|
import { completeOnEose } from "./operators/complete-on-eose.js";
|
|
8
8
|
import { markFromRelay } from "./operators/mark-from-relay.js";
|
|
@@ -85,7 +85,7 @@ export class Relay {
|
|
|
85
85
|
if (this.receivedAuthRequiredForEvent.value)
|
|
86
86
|
this.receivedAuthRequiredForEvent.next(false);
|
|
87
87
|
}
|
|
88
|
-
/** An internal observable that is responsible for watching all messages and updating state */
|
|
88
|
+
/** An internal observable that is responsible for watching all messages and updating state, subscribing to it will trigger a connection to the relay */
|
|
89
89
|
watchTower;
|
|
90
90
|
constructor(url, opts) {
|
|
91
91
|
this.url = url;
|
|
@@ -190,11 +190,13 @@ export class Relay {
|
|
|
190
190
|
.pipe(take(1))
|
|
191
191
|
.subscribe(() => this.ready$.next(true));
|
|
192
192
|
}
|
|
193
|
-
/** Wait for
|
|
193
|
+
/** Wait for authentication state, make connection and then wait for authentication if required */
|
|
194
194
|
waitForAuth(
|
|
195
195
|
// NOTE: require BehaviorSubject so it always has a value
|
|
196
196
|
requireAuth, observable) {
|
|
197
197
|
return combineLatest([requireAuth, this.authenticated$]).pipe(
|
|
198
|
+
// Once the auth state is known, make a connection and watch for auth challenges
|
|
199
|
+
mergeWith(this.watchTower),
|
|
198
200
|
// wait for auth not required or authenticated
|
|
199
201
|
filter(([required, authenticated]) => !required || authenticated),
|
|
200
202
|
// complete after the first value so this does not repeat
|
|
@@ -284,10 +286,8 @@ export class Relay {
|
|
|
284
286
|
// format OK message
|
|
285
287
|
map((m) => ({ ok: m[2], message: m[3], from: this.url })));
|
|
286
288
|
});
|
|
287
|
-
// Start the watch tower
|
|
288
|
-
const
|
|
289
|
-
// Add complete operators
|
|
290
|
-
const observable = withWatchTower.pipe(
|
|
289
|
+
// Start the watch tower and add complete operators
|
|
290
|
+
const observable = merge(this.watchTower, base).pipe(
|
|
291
291
|
// complete on first value
|
|
292
292
|
take(1),
|
|
293
293
|
// listen for OK auth-required
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "applesauce-relay",
|
|
3
|
-
"version": "0.0.0-next-
|
|
3
|
+
"version": "0.0.0-next-20250606170247",
|
|
4
4
|
"description": "nostr relay communication framework built on rxjs",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -54,14 +54,14 @@
|
|
|
54
54
|
},
|
|
55
55
|
"dependencies": {
|
|
56
56
|
"@noble/hashes": "^1.7.1",
|
|
57
|
-
"applesauce-core": "0.0.0-next-
|
|
57
|
+
"applesauce-core": "0.0.0-next-20250606170247",
|
|
58
58
|
"nanoid": "^5.0.9",
|
|
59
59
|
"nostr-tools": "^2.13",
|
|
60
60
|
"rxjs": "^7.8.1"
|
|
61
61
|
},
|
|
62
62
|
"devDependencies": {
|
|
63
63
|
"@hirez_io/observer-spy": "^2.2.0",
|
|
64
|
-
"applesauce-signers": "0.0.0-next-
|
|
64
|
+
"applesauce-signers": "0.0.0-next-20250606170247",
|
|
65
65
|
"@vitest/expect": "^3.1.1",
|
|
66
66
|
"typescript": "^5.7.3",
|
|
67
67
|
"vitest": "^3.1.1",
|