Add hydrator module to hydrate relationships on events

This commit is contained in:
Alex Gleason 2024-01-04 01:44:56 -06:00
parent d170eb6d8e
commit 412f71599a
No known key found for this signature in database
GPG Key ID: 7211D1F99744FBB7
2 changed files with 31 additions and 9 deletions

26
src/storages/hydrate.ts Normal file
View File

@ -0,0 +1,26 @@
import { type DittoFilter } from '@/filter.ts';
import { type DittoEvent, type EventStore } from '@/storages/types.ts';
interface HydrateEventOpts<K extends number> {
events: DittoEvent<K>[];
filters: DittoFilter<K>[];
storage: EventStore;
}
/** Hydrate event relationships using the provided storage. */
async function hydrateEvents<K extends number>(opts: HydrateEventOpts<K>): Promise<DittoEvent<K>[]> {
const { events, filters, storage } = opts;
if (filters.some((filter) => filter.relations?.includes('author'))) {
const pubkeys = new Set([...events].map((event) => event.pubkey));
const authors = await storage.getEvents([{ kinds: [0], authors: [...pubkeys] }]);
for (const event of events) {
event.author = authors.find((author) => author.pubkey === event.pubkey);
}
}
return events;
}
export { hydrateEvents };

View File

@ -2,24 +2,28 @@ import { NiceRelay } from 'https://gitlab.com/soapbox-pub/nostr-machina/-/raw/5f
import { Debug, type Event, type Filter } from '@/deps.ts';
import { type DittoFilter, normalizeFilters } from '@/filter.ts';
import { hydrateEvents } from '@/storages/hydrate.ts';
import { type DittoEvent, type EventStore, type GetEventsOpts, type StoreEventOpts } from '@/storages/types.ts';
import { EventSet } from '@/utils/event-set.ts';
interface SearchStoreOpts {
relay: string | undefined;
fallback: EventStore;
hydrator?: EventStore;
}
class SearchStore implements EventStore {
#debug = Debug('ditto:storages:search');
#fallback: EventStore;
#hydrator: EventStore;
#relay: NiceRelay | undefined;
supportedNips = [50];
constructor(opts: SearchStoreOpts) {
this.#fallback = opts.fallback;
this.#hydrator = opts.hydrator ?? this;
if (opts.relay) {
this.#relay = new NiceRelay(opts.relay);
@ -53,15 +57,7 @@ class SearchStore implements EventStore {
events.add(event);
}
if (filters[0]?.relations?.includes('author')) {
const authorIds = new Set([...events].map((event) => event.pubkey));
const authors = await this.getEvents([{ kinds: [0], authors: [...authorIds] }], opts);
for (const event of events) {
event.author = authors.find((author) => author.pubkey === event.pubkey);
}
}
return [...events];
return hydrateEvents({ events: [...events], filters, storage: this.#hydrator });
} else {
this.#debug(`Searching for "${query}" locally...`);
return this.#fallback.getEvents(filters, opts);