From 1499f9b417ea987dfe6749989a57cd5ce6009793 Mon Sep 17 00:00:00 2001 From: Alex Gleason Date: Tue, 5 Mar 2024 14:26:38 -0600 Subject: [PATCH] Try hydrating timelines in a separate query instead of using relations --- src/controllers/api/timelines.ts | 8 ++++---- src/storages/hydrate.ts | 12 ++++++++---- src/storages/search-store.ts | 7 ++++++- 3 files changed, 18 insertions(+), 9 deletions(-) diff --git a/src/controllers/api/timelines.ts b/src/controllers/api/timelines.ts index f8434c4..885b871 100644 --- a/src/controllers/api/timelines.ts +++ b/src/controllers/api/timelines.ts @@ -4,6 +4,7 @@ import { type DittoFilter } from '@/interfaces/DittoFilter.ts'; import { getFeedPubkeys } from '@/queries.ts'; import { booleanParamSchema } from '@/schema.ts'; import { eventsDB } from '@/storages.ts'; +import { hydrateEvents } from '@/storages/hydrate.ts'; import { paginated, paginationSchema } from '@/utils/api.ts'; import { renderStatus } from '@/views/mastodon/statuses.ts'; @@ -34,10 +35,9 @@ const hashtagTimelineController: AppController = (c) => { async function renderStatuses(c: AppContext, filters: DittoFilter[]) { const { signal } = c.req.raw; - const events = await eventsDB.query( - filters.map((filter) => ({ ...filter, relations: ['author', 'event_stats', 'author_stats'] })), - { signal }, - ); + const events = await eventsDB + .query(filters, { signal }) + .then((events) => hydrateEvents({ events, relations: ['author'], storage: eventsDB, signal })); if (!events.length) { return c.json([]); diff --git a/src/storages/hydrate.ts b/src/storages/hydrate.ts index 4043024..718b7a1 100644 --- a/src/storages/hydrate.ts +++ b/src/storages/hydrate.ts @@ -1,19 +1,23 @@ import { type NostrEvent, type NStore } from '@/deps.ts'; import { type DittoEvent } from '@/interfaces/DittoEvent.ts'; -import { type DittoFilter } from '@/interfaces/DittoFilter.ts'; +import { type DittoRelation } from '@/interfaces/DittoFilter.ts'; interface HydrateEventOpts { events: DittoEvent[]; - filters: DittoFilter[]; + relations: DittoRelation[]; storage: NStore; signal?: AbortSignal; } /** Hydrate event relationships using the provided storage. */ async function hydrateEvents(opts: HydrateEventOpts): Promise { - const { events, filters, storage, signal } = opts; + const { events, relations, storage, signal } = opts; - if (filters.some((filter) => filter.relations?.includes('author'))) { + if (events.length === 0) { + return events; + } + + if (relations.includes('author')) { const pubkeys = new Set([...events].map((event) => event.pubkey)); const authors = await storage.query([{ kinds: [0], authors: [...pubkeys] }], { signal }); diff --git a/src/storages/search-store.ts b/src/storages/search-store.ts index 6e348d0..3f7c642 100644 --- a/src/storages/search-store.ts +++ b/src/storages/search-store.ts @@ -62,7 +62,12 @@ class SearchStore implements NStore { events.add(event); } - return hydrateEvents({ events: [...events], filters, storage: this.#hydrator, signal: opts?.signal }); + return hydrateEvents({ + events: [...events], + relations: ['author', 'event_stats', 'author_stats'], + storage: this.#hydrator, + signal: opts?.signal, + }); } else { this.#debug(`Searching for "${query}" locally...`); return this.#fallback.query(filters, opts);