Add hydrator module to hydrate relationships on events
This commit is contained in:
parent
d170eb6d8e
commit
412f71599a
|
@ -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 };
|
|
@ -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 { Debug, type Event, type Filter } from '@/deps.ts';
|
||||||
import { type DittoFilter, normalizeFilters } from '@/filter.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 { type DittoEvent, type EventStore, type GetEventsOpts, type StoreEventOpts } from '@/storages/types.ts';
|
||||||
import { EventSet } from '@/utils/event-set.ts';
|
import { EventSet } from '@/utils/event-set.ts';
|
||||||
|
|
||||||
interface SearchStoreOpts {
|
interface SearchStoreOpts {
|
||||||
relay: string | undefined;
|
relay: string | undefined;
|
||||||
fallback: EventStore;
|
fallback: EventStore;
|
||||||
|
hydrator?: EventStore;
|
||||||
}
|
}
|
||||||
|
|
||||||
class SearchStore implements EventStore {
|
class SearchStore implements EventStore {
|
||||||
#debug = Debug('ditto:storages:search');
|
#debug = Debug('ditto:storages:search');
|
||||||
|
|
||||||
#fallback: EventStore;
|
#fallback: EventStore;
|
||||||
|
#hydrator: EventStore;
|
||||||
#relay: NiceRelay | undefined;
|
#relay: NiceRelay | undefined;
|
||||||
|
|
||||||
supportedNips = [50];
|
supportedNips = [50];
|
||||||
|
|
||||||
constructor(opts: SearchStoreOpts) {
|
constructor(opts: SearchStoreOpts) {
|
||||||
this.#fallback = opts.fallback;
|
this.#fallback = opts.fallback;
|
||||||
|
this.#hydrator = opts.hydrator ?? this;
|
||||||
|
|
||||||
if (opts.relay) {
|
if (opts.relay) {
|
||||||
this.#relay = new NiceRelay(opts.relay);
|
this.#relay = new NiceRelay(opts.relay);
|
||||||
|
@ -53,15 +57,7 @@ class SearchStore implements EventStore {
|
||||||
events.add(event);
|
events.add(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (filters[0]?.relations?.includes('author')) {
|
return hydrateEvents({ events: [...events], filters, storage: this.#hydrator });
|
||||||
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];
|
|
||||||
} else {
|
} else {
|
||||||
this.#debug(`Searching for "${query}" locally...`);
|
this.#debug(`Searching for "${query}" locally...`);
|
||||||
return this.#fallback.getEvents(filters, opts);
|
return this.#fallback.getEvents(filters, opts);
|
||||||
|
|
Loading…
Reference in New Issue