diff --git a/src/app.ts b/src/app.ts index 68306e5..abdec32 100644 --- a/src/app.ts +++ b/src/app.ts @@ -1,4 +1,4 @@ -import { NostrEvent } from '@nostrify/nostrify'; +import { NostrEvent, NStore } from '@nostrify/nostrify'; import { type Context, Env as HonoEnv, type Handler, Hono, Input as HonoInput, type MiddlewareHandler } from 'hono'; import { cors, logger, serveStatic } from 'hono/middleware'; @@ -78,6 +78,7 @@ import { auth98, requireProof, requireRole } from '@/middleware/auth98.ts'; import { cache } from '@/middleware/cache.ts'; import { csp } from '@/middleware/csp.ts'; import { adminRelaysController } from '@/controllers/api/ditto.ts'; +import { storeMiddleware } from '@/middleware/store.ts'; interface AppEnv extends HonoEnv { Variables: { @@ -89,6 +90,8 @@ interface AppEnv extends HonoEnv { proof?: NostrEvent; /** User associated with the pubkey, if any. */ user?: User; + /** Store */ + store?: NStore; }; } @@ -170,8 +173,8 @@ app.delete('/api/v1/statuses/:id{[0-9a-f]{64}}', requirePubkey, deleteStatusCont app.post('/api/v1/media', mediaController); app.post('/api/v2/media', mediaController); -app.get('/api/v1/timelines/home', requirePubkey, homeTimelineController); -app.get('/api/v1/timelines/public', publicTimelineController); +app.get('/api/v1/timelines/home', requirePubkey, storeMiddleware, homeTimelineController); +app.get('/api/v1/timelines/public', storeMiddleware, publicTimelineController); app.get('/api/v1/timelines/tag/:hashtag', hashtagTimelineController); app.get('/api/v1/preferences', preferencesController); diff --git a/src/controllers/api/timelines.ts b/src/controllers/api/timelines.ts index 5e7bab6..191fce7 100644 --- a/src/controllers/api/timelines.ts +++ b/src/controllers/api/timelines.ts @@ -1,11 +1,10 @@ -import { NostrFilter } from '@nostrify/nostrify'; +import { NostrFilter, NStore } from '@nostrify/nostrify'; import { z } from 'zod'; import { type AppContext, type AppController } from '@/app.ts'; import { Conf } from '@/config.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 { renderReblog, renderStatus } from '@/views/mastodon/statuses.ts'; @@ -46,13 +45,14 @@ const hashtagTimelineController: AppController = (c) => { /** Render statuses for timelines. */ async function renderStatuses(c: AppContext, filters: NostrFilter[]) { const { signal } = c.req.raw; + const store = c.get('store') as NStore; - const events = await eventsDB + const events = await store .query(filters, { signal }) .then((events) => hydrateEvents({ events, - storage: eventsDB, + storage: store, signal, }) ); diff --git a/src/middleware/store.ts b/src/middleware/store.ts new file mode 100644 index 0000000..8bb595c --- /dev/null +++ b/src/middleware/store.ts @@ -0,0 +1,18 @@ +import { AppMiddleware } from '@/app.ts'; +import { UserStore } from '@/storages/UserStore.ts'; +import { eventsDB } from '@/storages.ts'; + +/** Store middleware. */ +const storeMiddleware: AppMiddleware = async (c, next) => { + const pubkey = c.get('pubkey') as string; + + if (pubkey) { + const store = new UserStore(pubkey, eventsDB); + c.set('store', store); + } else { + c.set('store', eventsDB); + } + await next(); +}; + +export { storeMiddleware }; diff --git a/src/storages/UserStore.ts b/src/storages/UserStore.ts index 615e2af..78c3d33 100644 --- a/src/storages/UserStore.ts +++ b/src/storages/UserStore.ts @@ -29,7 +29,7 @@ export class UserStore implements NStore { const mutedPubkeys = getTagSet(mutedPubkeysEvent.tags, 'p'); return allEvents.filter((event) => { - mutedPubkeys.has(event.pubkey) === false; + return mutedPubkeys.has(event.pubkey) === false; }); }