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]], tags: [['e', event.id], ['p', event.pubkey]],
}, c); }, c);
const status = await renderReblog(reblogEvent); const status = await renderReblog(reblogEvent, { loadOriginalPostEvent: true });
return c.json(status); return c.json(status);
}; };

View File

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

View File

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

View File

@ -3,6 +3,7 @@ import { db } from '@/db.ts';
import { type NostrEvent, type NStore } from '@/deps.ts'; import { type NostrEvent, type NStore } from '@/deps.ts';
import { type DittoEvent } from '@/interfaces/DittoEvent.ts'; import { type DittoEvent } from '@/interfaces/DittoEvent.ts';
import { type DittoRelation } from '@/interfaces/DittoFilter.ts'; import { type DittoRelation } from '@/interfaces/DittoFilter.ts';
import { eventsDB } from '@/storages.ts';
interface HydrateEventOpts { interface HydrateEventOpts {
events: DittoEvent[]; events: DittoEvent[];
@ -33,6 +34,9 @@ async function hydrateEvents(opts: HydrateEventOpts): Promise<DittoEvent[]> {
case 'user': case 'user':
await hydrateUsers({ events, storage, signal }); await hydrateUsers({ events, storage, signal });
break; break;
case 'repost':
await hydrateRepostEvents(events);
break;
} }
} }
@ -111,6 +115,24 @@ async function hydrateEventStats(events: DittoEvent[]): Promise<DittoEvent[]> {
return events; 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. */ /** Return a normalized event without any non-standard keys. */
function purifyEvent(event: NostrEvent): NostrEvent { function purifyEvent(event: NostrEvent): NostrEvent {
return { 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; if (!event.author) return;
const repostId = event.tags.find(([name]) => name === 'e')?.[1]; const repostId = event.tags.find(([name]) => name === 'e')?.[1];
if (!repostId) return; if (!repostId) return;
if (loadOriginalPostEvent) {
event.repost = await getEvent(repostId, { kind: 1 }); event.repost = await getEvent(repostId, { kind: 1 });
}
if (!event.repost) return; if (!event.repost) return;
const reblog = await renderStatus(event.repost); const reblog = await renderStatus(event.repost);