feat: use localhost relay over worker-relay

This commit is contained in:
2024-06-18 10:49:29 +01:00
parent 44435db21d
commit 37000ecc7a
9 changed files with 130 additions and 38 deletions

View File

@ -0,0 +1,55 @@
import { NostrEvent, OkResponse, ReqCommand, ReqFilter, TaggedNostrEvent } from "./nostr";
import { CacheRelay } from "./cache-relay";
import { Connection } from "./connection";
import { NoteCollection } from "./note-collection";
import { v4 as uuid } from "uuid";
/**
* Use a regular connection as a CacheRelay
*/
export class ConnectionCacheRelay implements CacheRelay {
#eventsSent = new Set<string>();
constructor(readonly connection: Connection) {}
async event(ev: NostrEvent): Promise<OkResponse> {
if (this.#eventsSent.has(ev.id))
return {
ok: true,
id: ev.id,
message: "duplicate",
} as OkResponse;
this.#eventsSent.add(ev.id);
return await this.connection.publish(ev);
}
query(req: ReqCommand): Promise<NostrEvent[]> {
const id = uuid();
return new Promise((resolve, reject) => {
const results = new NoteCollection();
const evh = (s: string, e: TaggedNostrEvent) => {
if (s === id) {
results.add(e);
}
};
const eoh = (s: string) => {
if (s === id) {
resolve(results.snapshot);
this.connection.closeRequest(id);
this.connection.off("event", evh);
this.connection.off("eose", eoh);
this.connection.off("closed", eoh);
}
};
this.connection.on("event", evh);
this.connection.on("eose", eoh);
this.connection.on("closed", eoh);
this.connection.request(["REQ", id, ...(req.slice(2) as Array<ReqFilter>)]);
});
}
delete(req: ReqCommand): Promise<string[]> {
// ignored
return Promise.resolve([]);
}
}

View File

@ -100,7 +100,7 @@ export class Connection extends EventEmitter<ConnectionTypeEvents> implements Co
return [...this.#activeRequests];
}
async connect() {
async connect(awaitOpen = false) {
// already connected
if (this.isOpen || this.isConnecting) return;
// wait for re-connect timer
@ -131,24 +131,31 @@ export class Connection extends EventEmitter<ConnectionTypeEvents> implements Co
// ignored
}
const wasReconnect = this.Socket !== null;
if (this.Socket) {
this.id = uuid();
if (this.isOpen) {
this.Socket.close();
try {
const wasReconnect = this.Socket !== null;
if (this.Socket) {
this.id = uuid();
if (this.isOpen) {
this.Socket.close();
}
this.Socket.onopen = null;
this.Socket.onmessage = null;
this.Socket.onerror = null;
this.Socket.onclose = null;
this.Socket = null;
}
this.Socket.onopen = null;
this.Socket.onmessage = null;
this.Socket.onerror = null;
this.Socket.onclose = null;
this.Socket = null;
this.Socket = new WebSocket(this.address);
this.Socket.onopen = () => this.#onOpen(wasReconnect);
this.Socket.onmessage = e => this.#onMessage(e);
this.Socket.onerror = e => this.#onError(e);
this.Socket.onclose = e => this.#onClose(e);
if (awaitOpen) {
await new Promise(resolve => this.once("connected", resolve));
}
} catch (e) {
this.#connectStarted = false;
throw e;
}
this.Socket = new WebSocket(this.address);
this.Socket.onopen = () => this.#onOpen(wasReconnect);
this.Socket.onmessage = e => this.#onMessage(e);
this.Socket.onerror = e => this.#onError(e);
this.Socket.onclose = e => this.#onClose(e);
this.#connectStarted = false;
}
close() {
@ -158,6 +165,7 @@ export class Connection extends EventEmitter<ConnectionTypeEvents> implements Co
#onOpen(wasReconnect: boolean) {
this.#downCount = 0;
this.#connectStarted = false;
this.#log(`Open!`);
this.#setupEphemeral();
this.emit("connected", wasReconnect);

View File

@ -28,6 +28,8 @@ export * from "./encrypted";
export * from "./outbox";
export * from "./sync";
export * from "./user-state";
export * from "./cache-relay";
export * from "./connection-cache-relay";
export * from "./impl/nip4";
export * from "./impl/nip7";