76 lines
2.3 KiB
TypeScript
76 lines
2.3 KiB
TypeScript
import { unwrap } from "@snort/shared";
|
|
import { NostrEvent, ReqFilter } from "./nostr";
|
|
import { FlatReqFilter } from "./query-optimizer";
|
|
|
|
/**
|
|
* Request router managed splitting of requests to one or more relays, and which relay to send events to.
|
|
*/
|
|
export interface RequestRouter {
|
|
/**
|
|
* Pick relays to send an event to
|
|
* @param pk The pubkey you are replying to
|
|
* @param system Nostr system interface
|
|
* @param pickN Number of relays to pick per recipient
|
|
* @returns
|
|
*/
|
|
forReplyTo(pk: string, pickN?: number): Promise<Array<string>>;
|
|
|
|
/**
|
|
* Pick relays to send an event to
|
|
* @param ev The reply event to send
|
|
* @param system Nostr system interface
|
|
* @param pickN Number of relays to pick per recipient
|
|
* @returns
|
|
*/
|
|
forReply(ev: NostrEvent, pickN?: number): Promise<Array<string>>;
|
|
|
|
/**
|
|
* Split a request filter to one or more relays.
|
|
* @param filter Filter to split
|
|
* @param pickN Number of relays to pick
|
|
* @returns
|
|
*/
|
|
forRequest(filter: ReqFilter, pickN?: number): Array<ReqFilter>;
|
|
|
|
/**
|
|
* Split a request filter to one or more relays.
|
|
* @param filter Filters to split
|
|
* @param pickN Number of relays to pick
|
|
* @returns
|
|
*/
|
|
forFlatRequest(filter: Array<FlatReqFilter>, pickN?: number): Array<FlatReqFilter>;
|
|
|
|
/**
|
|
* Same as forRequest, but merges the results
|
|
* @param filters
|
|
*/
|
|
forAllRequest(filters: Array<ReqFilter>): Array<ReqFilter>;
|
|
}
|
|
|
|
export abstract class BaseRequestRouter implements RequestRouter {
|
|
abstract forReplyTo(pk: string, pickN?: number): Promise<Array<string>>;
|
|
abstract forReply(ev: NostrEvent, pickN?: number): Promise<Array<string>>;
|
|
abstract forRequest(filter: ReqFilter, pickN?: number): Array<ReqFilter>;
|
|
abstract forFlatRequest(filter: FlatReqFilter[], pickN?: number): Array<FlatReqFilter>;
|
|
|
|
forAllRequest(filters: Array<ReqFilter>) {
|
|
const allSplit = filters
|
|
.map(a => this.forRequest(a))
|
|
.reduce((acc, v) => {
|
|
for (const vn of v) {
|
|
for (const r of (vn.relays?.length ?? 0) > 0 ? unwrap(vn.relays) : [""]) {
|
|
const existing = acc.get(r);
|
|
if (existing) {
|
|
existing.push(vn);
|
|
} else {
|
|
acc.set(r, [vn]);
|
|
}
|
|
}
|
|
}
|
|
return acc;
|
|
}, new Map<string, Array<ReqFilter>>());
|
|
|
|
return [...allSplit.values()].flat();
|
|
}
|
|
}
|