Refactor Storages to get lazy-loaded only when they are used

This commit is contained in:
Alex Gleason
2024-05-01 14:56:47 -05:00
parent a6681a97d9
commit c190d2c8ce
27 changed files with 175 additions and 140 deletions

View File

@@ -7,7 +7,7 @@ import { Conf } from '@/config.ts';
import { getAuthor, getFollowedPubkeys } from '@/queries.ts';
import { booleanParamSchema, fileSchema } from '@/schema.ts';
import { jsonMetaContentSchema } from '@/schemas/nostr.ts';
import { eventsDB, searchStore } from '@/storages.ts';
import { Storages } from '@/storages.ts';
import { addTag, deleteTag, findReplyTag, getTagSet } from '@/tags.ts';
import { uploadFile } from '@/upload.ts';
import { nostrNow } from '@/utils.ts';
@@ -92,12 +92,12 @@ const accountSearchController: AppController = async (c) => {
const [event, events] = await Promise.all([
lookupAccount(query),
searchStore.query([{ kinds: [0], search: query, limit: 20 }], { signal: c.req.raw.signal }),
Storages.search.query([{ kinds: [0], search: query, limit: 20 }], { signal: c.req.raw.signal }),
]);
const results = await hydrateEvents({
events: event ? [event, ...events] : events,
storage: eventsDB,
storage: Storages.db,
signal: c.req.raw.signal,
});
@@ -143,7 +143,7 @@ const accountStatusesController: AppController = async (c) => {
const { signal } = c.req.raw;
if (pinned) {
const [pinEvent] = await eventsDB.query([{ kinds: [10001], authors: [pubkey], limit: 1 }], { signal });
const [pinEvent] = await Storages.db.query([{ kinds: [10001], authors: [pubkey], limit: 1 }], { signal });
if (pinEvent) {
const pinnedEventIds = getTagSet(pinEvent.tags, 'e');
return renderStatuses(c, [...pinnedEventIds].reverse());
@@ -164,8 +164,8 @@ const accountStatusesController: AppController = async (c) => {
filter['#t'] = [tagged];
}
const events = await eventsDB.query([filter], { signal })
.then((events) => hydrateEvents({ events, storage: eventsDB, signal }))
const events = await Storages.db.query([filter], { signal })
.then((events) => hydrateEvents({ events, storage: Storages.db, signal }))
.then((events) => {
if (exclude_replies) {
return events.filter((event) => !findReplyTag(event.tags));
@@ -306,7 +306,7 @@ const favouritesController: AppController = async (c) => {
const params = paginationSchema.parse(c.req.query());
const { signal } = c.req.raw;
const events7 = await eventsDB.query(
const events7 = await Storages.db.query(
[{ kinds: [7], authors: [pubkey], ...params }],
{ signal },
);
@@ -315,8 +315,8 @@ const favouritesController: AppController = async (c) => {
.map((event) => event.tags.find((tag) => tag[0] === 'e')?.[1])
.filter((id): id is string => !!id);
const events1 = await eventsDB.query([{ kinds: [1], ids }], { signal })
.then((events) => hydrateEvents({ events, storage: eventsDB, signal }));
const events1 = await Storages.db.query([{ kinds: [1], ids }], { signal })
.then((events) => hydrateEvents({ events, storage: Storages.db, signal }));
const statuses = await Promise.all(events1.map((event) => renderStatus(event, { viewerPubkey: c.get('pubkey') })));
return paginated(c, events1, statuses);

View File

@@ -3,7 +3,7 @@ import { z } from 'zod';
import { type AppController } from '@/app.ts';
import { Conf } from '@/config.ts';
import { booleanParamSchema } from '@/schema.ts';
import { eventsDB } from '@/storages.ts';
import { Storages } from '@/storages.ts';
import { renderAdminAccount } from '@/views/mastodon/admin-accounts.ts';
import { paginated, paginationSchema } from '@/utils/api.ts';
@@ -41,9 +41,9 @@ const adminAccountsController: AppController = async (c) => {
const { since, until, limit } = paginationSchema.parse(c.req.query());
const { signal } = c.req.raw;
const events = await eventsDB.query([{ kinds: [30361], authors: [Conf.pubkey], since, until, limit }], { signal });
const events = await Storages.db.query([{ kinds: [30361], authors: [Conf.pubkey], since, until, limit }], { signal });
const pubkeys = events.map((event) => event.tags.find(([name]) => name === 'd')?.[1]!);
const authors = await eventsDB.query([{ kinds: [0], authors: pubkeys }], { signal });
const authors = await Storages.db.query([{ kinds: [0], authors: pubkeys }], { signal });
for (const event of events) {
const d = event.tags.find(([name]) => name === 'd')?.[1];

View File

@@ -1,5 +1,5 @@
import { type AppController } from '@/app.ts';
import { eventsDB } from '@/storages.ts';
import { Storages } from '@/storages.ts';
import { getTagSet } from '@/tags.ts';
import { renderAccounts } from '@/views.ts';
@@ -8,7 +8,7 @@ const blocksController: AppController = async (c) => {
const pubkey = c.get('pubkey')!;
const { signal } = c.req.raw;
const [event10000] = await eventsDB.query(
const [event10000] = await Storages.db.query(
[{ kinds: [10000], authors: [pubkey], limit: 1 }],
{ signal },
);

View File

@@ -1,5 +1,5 @@
import { type AppController } from '@/app.ts';
import { eventsDB } from '@/storages.ts';
import { Storages } from '@/storages.ts';
import { getTagSet } from '@/tags.ts';
import { renderStatuses } from '@/views.ts';
@@ -8,7 +8,7 @@ const bookmarksController: AppController = async (c) => {
const pubkey = c.get('pubkey')!;
const { signal } = c.req.raw;
const [event10003] = await eventsDB.query(
const [event10003] = await Storages.db.query(
[{ kinds: [10003], authors: [pubkey], limit: 1 }],
{ signal },
);

View File

@@ -3,7 +3,7 @@ import { z } from 'zod';
import { AppController } from '@/app.ts';
import { Conf } from '@/config.ts';
import { eventsDB } from '@/storages.ts';
import { Storages } from '@/storages.ts';
import { AdminSigner } from '@/signers/AdminSigner.ts';
const relaySchema = z.object({
@@ -15,7 +15,7 @@ const relaySchema = z.object({
type RelayEntity = z.infer<typeof relaySchema>;
export const adminRelaysController: AppController = async (c) => {
const [event] = await eventsDB.query([
const [event] = await Storages.db.query([
{ kinds: [10002], authors: [Conf.pubkey], limit: 1 },
]);
@@ -36,7 +36,7 @@ export const adminSetRelaysController: AppController = async (c) => {
created_at: Math.floor(Date.now() / 1000),
});
await eventsDB.event(event);
await Storages.db.event(event);
return c.json(renderRelays(event));
};

View File

@@ -1,13 +1,13 @@
import { type AppController } from '@/app.ts';
import { Conf } from '@/config.ts';
import { jsonServerMetaSchema } from '@/schemas/nostr.ts';
import { eventsDB } from '@/storages.ts';
import { Storages } from '@/storages.ts';
const instanceController: AppController = async (c) => {
const { host, protocol } = Conf.url;
const { signal } = c.req.raw;
const [event] = await eventsDB.query([{ kinds: [0], authors: [Conf.pubkey], limit: 1 }], { signal });
const [event] = await Storages.db.query([{ kinds: [0], authors: [Conf.pubkey], limit: 1 }], { signal });
const meta = jsonServerMetaSchema.parse(event?.content);
/** Protocol to use for WebSocket URLs, depending on the protocol of the `LOCAL_DOMAIN`. */

View File

@@ -1,5 +1,5 @@
import { type AppController } from '@/app.ts';
import { eventsDB } from '@/storages.ts';
import { Storages } from '@/storages.ts';
import { paginated, paginationSchema } from '@/utils/api.ts';
import { renderNotification } from '@/views/mastodon/notifications.ts';
@@ -8,7 +8,7 @@ const notificationsController: AppController = async (c) => {
const { since, until } = paginationSchema.parse(c.req.query());
const { signal } = c.req.raw;
const events = await eventsDB.query(
const events = await Storages.db.query(
[{ kinds: [1], '#p': [pubkey], since, until }],
{ signal },
);

View File

@@ -4,7 +4,7 @@ import { type AppController } from '@/app.ts';
import { Conf } from '@/config.ts';
import { configSchema, elixirTupleSchema, type PleromaConfig } from '@/schemas/pleroma-api.ts';
import { AdminSigner } from '@/signers/AdminSigner.ts';
import { eventsDB } from '@/storages.ts';
import { Storages } from '@/storages.ts';
import { createAdminEvent } from '@/utils/api.ts';
import { jsonSchema } from '@/schema.ts';
@@ -66,7 +66,7 @@ const pleromaAdminDeleteStatusController: AppController = async (c) => {
async function getConfigs(signal: AbortSignal): Promise<PleromaConfig[]> {
const { pubkey } = Conf;
const [event] = await eventsDB.query([{
const [event] = await Storages.db.query([{
kinds: [30078],
authors: [pubkey],
'#d': ['pub.ditto.pleroma.config'],

View File

@@ -5,7 +5,7 @@ import { z } from 'zod';
import { AppController } from '@/app.ts';
import { booleanParamSchema } from '@/schema.ts';
import { nostrIdSchema } from '@/schemas/nostr.ts';
import { searchStore } from '@/storages.ts';
import { Storages } from '@/storages.ts';
import { dedupeEvents } from '@/utils.ts';
import { nip05Cache } from '@/utils/nip05.ts';
import { accountFromPubkey, renderAccount } from '@/views/mastodon/accounts.ts';
@@ -91,8 +91,8 @@ function searchEvents({ q, type, limit, account_id }: SearchQuery, signal: Abort
filter.authors = [account_id];
}
return searchStore.query([filter], { signal })
.then((events) => hydrateEvents({ events, storage: searchStore, signal }));
return Storages.search.query([filter], { signal })
.then((events) => hydrateEvents({ events, storage: Storages.search, signal }));
}
/** Get event kinds to search from `type` query param. */
@@ -111,8 +111,8 @@ function typeToKinds(type: SearchQuery['type']): number[] {
async function lookupEvent(query: SearchQuery, signal: AbortSignal): Promise<NostrEvent | undefined> {
const filters = await getLookupFilters(query, signal);
return searchStore.query(filters, { limit: 1, signal })
.then((events) => hydrateEvents({ events, storage: searchStore, signal }))
return Storages.search.query(filters, { limit: 1, signal })
.then((events) => hydrateEvents({ events, storage: Storages.search, signal }))
.then(([event]) => event);
}

View File

@@ -15,7 +15,7 @@ import { renderReblog, renderStatus } from '@/views/mastodon/statuses.ts';
import { getLnurl } from '@/utils/lnurl.ts';
import { nip05Cache } from '@/utils/nip05.ts';
import { asyncReplaceAll } from '@/utils/text.ts';
import { eventsDB } from '@/storages.ts';
import { Storages } from '@/storages.ts';
import { hydrateEvents } from '@/storages/hydrate.ts';
const createStatusSchema = z.object({
@@ -137,7 +137,7 @@ const createStatusController: AppController = async (c) => {
if (data.quote_id) {
await hydrateEvents({
events: [event],
storage: eventsDB,
storage: Storages.db,
signal: c.req.raw.signal,
});
}
@@ -242,7 +242,7 @@ const reblogStatusController: AppController = async (c) => {
await hydrateEvents({
events: [reblogEvent],
storage: eventsDB,
storage: Storages.db,
signal: signal,
});
@@ -262,7 +262,7 @@ const unreblogStatusController: AppController = async (c) => {
if (!event) return c.json({ error: 'Event not found.' }, 404);
const filters: NostrFilter[] = [{ kinds: [6], authors: [pubkey], '#e': [event.id] }];
const [repostedEvent] = await eventsDB.query(filters, { limit: 1 });
const [repostedEvent] = await Storages.db.query(filters, { limit: 1 });
if (!repostedEvent) return c.json({ error: 'Event not found.' }, 404);
await createEvent({

View File

@@ -10,7 +10,6 @@ import { renderReblog, renderStatus } from '@/views/mastodon/statuses.ts';
import { hydrateEvents } from '@/storages/hydrate.ts';
import { Storages } from '@/storages.ts';
import { UserStore } from '@/storages/UserStore.ts';
import { getAdminStore } from '@/storages/adminStore.ts';
const debug = Debug('ditto:streaming');
@@ -69,11 +68,11 @@ const streamingController: AppController = (c) => {
const filter = await topicToFilter(stream, c.req.query(), pubkey);
if (!filter) return;
const store = pubkey ? new UserStore(pubkey, Storages.admin) : Storages.admin;
try {
for await (const msg of Storages.pubsub.req([filter], { signal: controller.signal })) {
if (msg[0] === 'EVENT') {
const store = new UserStore(pubkey as string, getAdminStore());
const [event] = await store.query([{ ids: [msg[2].id] }]);
if (!event) continue;