the statusphere demo reworked into a vite/react app in a monorepo

Replace the db resolver cache with an in-memory cache

+4 -72
-7
src/db/migrations.ts
··· 11 11 migrations['001'] = { 12 12 async up(db: Kysely<unknown>) { 13 13 await db.schema 14 - .createTable('did_cache') 15 - .addColumn('did', 'varchar', (col) => col.primaryKey()) 16 - .addColumn('doc', 'varchar', (col) => col.notNull()) 17 - .addColumn('updatedAt', 'varchar', (col) => col.notNull()) 18 - .execute() 19 - await db.schema 20 14 .createTable('status') 21 15 .addColumn('authorDid', 'varchar', (col) => col.primaryKey()) 22 16 .addColumn('status', 'varchar', (col) => col.notNull()) ··· 38 32 await db.schema.dropTable('auth_state').execute() 39 33 await db.schema.dropTable('auth_session').execute() 40 34 await db.schema.dropTable('status').execute() 41 - await db.schema.dropTable('did_cache').execute() 42 35 }, 43 36 }
-7
src/db/schema.ts
··· 1 1 export type DatabaseSchema = { 2 - did_cache: DidCache 3 2 status: Status 4 3 auth_session: AuthSession 5 4 auth_state: AuthState 6 - } 7 - 8 - export type DidCache = { 9 - did: string 10 - doc: string 11 - updatedAt: string 12 5 } 13 6 14 7 export type Status = {
+3 -57
src/ident/resolver.ts
··· 1 - import { IdResolver, DidDocument, CacheResult } from '@atproto/identity' 2 - import type { Database } from '#/db' 1 + import { IdResolver, MemoryCache } from '@atproto/identity' 3 2 4 3 const HOUR = 60e3 * 60 5 4 const DAY = HOUR * 24 6 5 7 - export function createResolver(db: Database) { 6 + export function createResolver() { 8 7 const resolver = new IdResolver({ 9 - didCache: { 10 - async cacheDid(did: string, doc: DidDocument): Promise<void> { 11 - await db 12 - .insertInto('did_cache') 13 - .values({ 14 - did, 15 - doc: JSON.stringify(doc), 16 - updatedAt: new Date().toISOString(), 17 - }) 18 - .onConflict((oc) => 19 - oc.column('did').doUpdateSet({ 20 - doc: JSON.stringify(doc), 21 - updatedAt: new Date().toISOString(), 22 - }) 23 - ) 24 - .execute() 25 - }, 26 - 27 - async checkCache(did: string): Promise<CacheResult | null> { 28 - const row = await db 29 - .selectFrom('did_cache') 30 - .selectAll() 31 - .where('did', '=', did) 32 - .executeTakeFirst() 33 - if (!row) return null 34 - const now = Date.now() 35 - const updatedAt = +new Date(row.updatedAt) 36 - return { 37 - did, 38 - doc: JSON.parse(row.doc), 39 - updatedAt, 40 - stale: now > updatedAt + HOUR, 41 - expired: now > updatedAt + DAY, 42 - } 43 - }, 44 - 45 - async refreshCache( 46 - did: string, 47 - getDoc: () => Promise<DidDocument | null> 48 - ): Promise<void> { 49 - const doc = await getDoc() 50 - if (doc) { 51 - await this.cacheDid(did, doc) 52 - } 53 - }, 54 - 55 - async clearEntry(did: string): Promise<void> { 56 - await db.deleteFrom('did_cache').where('did', '=', did).execute() 57 - }, 58 - 59 - async clear(): Promise<void> { 60 - await db.deleteFrom('did_cache').execute() 61 - }, 62 - }, 8 + didCache: new MemoryCache(HOUR, DAY), 63 9 }) 64 10 65 11 return {
+1 -1
src/server.ts
··· 30 30 await migrateToLatest(db) 31 31 const ingester = new Ingester(db) 32 32 const oauthClient = await createClient(db) 33 - const resolver = await createResolver(db) 33 + const resolver = createResolver() 34 34 ingester.start() 35 35 const ctx = { 36 36 db,