perf: hydrate repost event in home timeline

This commit is contained in:
P. Reis 2024-04-12 21:51:57 -03:00
parent 581ecd67d6
commit 24efca5ea0
5 changed files with 41 additions and 6 deletions

View File

@ -226,7 +226,7 @@ const reblogStatusController: AppController = async (c) => {
tags: [['e', event.id], ['p', event.pubkey]],
}, c);
const status = await renderReblog(reblogEvent);
const status = await renderReblog(reblogEvent, { loadOriginalPostEvent: true });
return c.json(status);
};

View File

@ -64,7 +64,7 @@ const streamingController: AppController = (c) => {
if (filter) {
for await (const event of Sub.sub(socket, '1', [filter])) {
if (event.kind === 6) {
const status = await renderReblog(event);
const status = await renderReblog(event, { loadOriginalPostEvent: true });
if (status) {
send('update', status);
}

View File

@ -49,7 +49,12 @@ async function renderStatuses(c: AppContext, filters: NostrFilter[]) {
const events = await eventsDB
.query(filters, { signal })
.then((events) =>
hydrateEvents({ events, relations: ['author', 'author_stats', 'event_stats'], storage: eventsDB, signal })
hydrateEvents({
events,
relations: ['author', 'author_stats', 'event_stats', 'repost'],
storage: eventsDB,
signal,
})
);
if (!events.length) {
@ -58,7 +63,7 @@ async function renderStatuses(c: AppContext, filters: NostrFilter[]) {
const statuses = (await Promise.all(events.map((event) => {
if (event.kind === 6) {
return renderReblog(event);
return renderReblog(event, {});
}
return renderStatus(event, c.get('pubkey'));
}))).filter((boolean) => boolean);

View File

@ -3,6 +3,7 @@ import { db } from '@/db.ts';
import { type NostrEvent, type NStore } from '@/deps.ts';
import { type DittoEvent } from '@/interfaces/DittoEvent.ts';
import { type DittoRelation } from '@/interfaces/DittoFilter.ts';
import { eventsDB } from '@/storages.ts';
interface HydrateEventOpts {
events: DittoEvent[];
@ -33,6 +34,9 @@ async function hydrateEvents(opts: HydrateEventOpts): Promise<DittoEvent[]> {
case 'user':
await hydrateUsers({ events, storage, signal });
break;
case 'repost':
await hydrateRepostEvents(events);
break;
}
}
@ -111,6 +115,24 @@ async function hydrateEventStats(events: DittoEvent[]): Promise<DittoEvent[]> {
return events;
}
async function hydrateRepostEvents(events: DittoEvent[]): Promise<DittoEvent[]> {
const results = await eventsDB.query([{ kinds: [1], ids: events.map((event) => event.id) }]);
for (const event of events) {
if (event.kind === 6) {
const originalPostId = event.tags.find(([name]) => name === 'e')?.[1];
if (!originalPostId) continue;
const originalPostEvent = results.find((event) => event.id === originalPostId);
if (!originalPostEvent) continue;
event.repost = originalPostEvent;
}
}
return events;
}
/** Return a normalized event without any non-standard keys. */
function purifyEvent(event: NostrEvent): NostrEvent {
return {

View File

@ -100,13 +100,21 @@ async function renderStatus(event: DittoEvent, viewerPubkey?: string) {
};
}
async function renderReblog(event: DittoEvent) {
type reblogOpts = {
loadOriginalPostEvent?: boolean;
};
async function renderReblog(event: DittoEvent, opts: reblogOpts) {
const { loadOriginalPostEvent } = opts;
if (!event.author) return;
const repostId = event.tags.find(([name]) => name === 'e')?.[1];
if (!repostId) return;
if (loadOriginalPostEvent) {
event.repost = await getEvent(repostId, { kind: 1 });
}
if (!event.repost) return;
const reblog = await renderStatus(event.repost);