diff --git a/src/controllers/api/statuses.ts b/src/controllers/api/statuses.ts index 91b4d45..b5ecf01 100644 --- a/src/controllers/api/statuses.ts +++ b/src/controllers/api/statuses.ts @@ -203,6 +203,7 @@ const deleteStatusController: AppController = async (c) => { const contextController: AppController = async (c) => { const id = c.req.param('id'); + const store = c.get('store'); const event = await getEvent(id, { kind: 1, relations: ['author', 'event_stats', 'author_stats'] }); const viewerPubkey = await c.get('signer')?.getPublicKey(); @@ -214,9 +215,20 @@ const contextController: AppController = async (c) => { } if (event) { + const [ancestorEvents, descendantEvents] = await Promise.all([ + getAncestors(store, event), + getDescendants(store, event.id), + ]); + + await hydrateEvents({ + events: [...ancestorEvents, ...descendantEvents], + signal: c.req.raw.signal, + store, + }); + const [ancestors, descendants] = await Promise.all([ - getAncestors(event).then(renderStatuses), - getDescendants(event.id).then(renderStatuses), + renderStatuses(ancestorEvents), + renderStatuses(descendantEvents), ]); return c.json({ ancestors, descendants }); diff --git a/src/queries.ts b/src/queries.ts index 1fccb68..745429d 100644 --- a/src/queries.ts +++ b/src/queries.ts @@ -1,4 +1,4 @@ -import { NostrEvent, NostrFilter } from '@nostrify/nostrify'; +import { NostrEvent, NostrFilter, NStore } from '@nostrify/nostrify'; import Debug from '@soapbox/stickynotes/debug'; import { Conf } from '@/config.ts'; @@ -68,17 +68,17 @@ async function getFeedPubkeys(pubkey: string): Promise { return [...authors, pubkey]; } -async function getAncestors(event: NostrEvent, result: NostrEvent[] = []): Promise { +async function getAncestors(store: NStore, event: NostrEvent, result: NostrEvent[] = []): Promise { if (result.length < 100) { const replyTag = findReplyTag(event.tags); const inReplyTo = replyTag ? replyTag[1] : undefined; if (inReplyTo) { - const parentEvent = await getEvent(inReplyTo, { kind: 1 }); + const [parentEvent] = await store.query([{ kinds: [1], ids: [inReplyTo], limit: 1 }]); if (parentEvent) { result.push(parentEvent); - return getAncestors(parentEvent, result); + return getAncestors(store, parentEvent, result); } } } @@ -86,14 +86,14 @@ async function getAncestors(event: NostrEvent, result: NostrEvent[] = []): Promi return result.reverse(); } -async function getDescendants(eventId: string, signal = AbortSignal.timeout(2000)): Promise { - const store = await Storages.db(); - - const events = await store - .query([{ kinds: [1], '#e': [eventId] }], { limit: 200, signal }) +async function getDescendants( + store: NStore, + eventId: string, + signal = AbortSignal.timeout(2000), +): Promise { + return await store + .query([{ kinds: [1], '#e': [eventId], limit: 200 }], { signal }) .then((events) => events.filter(({ tags }) => findReplyTag(tags)?.[1] === eventId)); - - return hydrateEvents({ events, store, signal }); } /** Returns whether the pubkey is followed by a local user. */ diff --git a/src/storages/UserStore.ts b/src/storages/UserStore.ts index 43c1771..2449d8c 100644 --- a/src/storages/UserStore.ts +++ b/src/storages/UserStore.ts @@ -4,6 +4,8 @@ import { DittoEvent } from '@/interfaces/DittoEvent.ts'; import { getTagSet } from '@/utils/tags.ts'; export class UserStore implements NStore { + private promise: Promise | undefined; + constructor(private pubkey: string, private store: NStore) {} async event(event: NostrEvent, opts?: { signal?: AbortSignal }): Promise { @@ -24,7 +26,10 @@ export class UserStore implements NStore { } private async getMuteList(): Promise { - const [muteList] = await this.store.query([{ authors: [this.pubkey], kinds: [10000], limit: 1 }]); + if (!this.promise) { + this.promise = this.store.query([{ authors: [this.pubkey], kinds: [10000], limit: 1 }]); + } + const [muteList] = await this.promise; return muteList; }