ATlast — you'll never need to find your favorites on another platform again. Find your favs in the ATmosphere.
atproto

use shared connection for db calls, reuse db client

+12 -17
+2
netlify/functions/db.ts
··· 1 1 import { neon, NeonQueryFunction } from '@neondatabase/serverless'; 2 2 3 3 let sql: NeonQueryFunction<any, any> | undefined = undefined; 4 + let connectionInitialized = false; 4 5 5 6 export function getDbClient() { 6 7 if (!sql) { 7 8 sql = neon(process.env.NETLIFY_DATABASE_URL!); 9 + connectionInitialized = true; 8 10 } 9 11 return sql; 10 12 }
+10 -17
netlify/functions/oauth-stores-db.ts
··· 11 11 tokenSet: any; 12 12 } 13 13 14 + // Reuse the same DB client across all store instances 15 + const sql = getDbClient(); 16 + 14 17 export class PostgresStateStore { 15 18 async get(key: string): Promise<StateData | undefined> { 16 - const sql = getDbClient(); 17 19 const result = await sql` 18 20 SELECT data FROM oauth_states 19 21 WHERE key = ${key} AND expires_at > NOW() 20 22 `; 21 - // FIX: Cast result to an array of records to resolve TypeScript error 7053 22 23 return (result as Record<string, any>[])[0]?.data as StateData | undefined; 23 24 } 24 25 25 26 async set(key: string, value: StateData): Promise<void> { 26 - const sql = getDbClient(); 27 - const expiresAt = new Date(Date.now() + 10 * 60 * 1000); // 10 minutes 28 - await sql` 29 - INSERT INTO oauth_states (key, data, expires_at) 30 - VALUES (${key}, ${JSON.stringify(value)}, ${expiresAt.toISOString()}) 31 - ON CONFLICT (key) DO UPDATE SET data = ${JSON.stringify(value)}, expires_at = ${expiresAt.toISOString()} 32 - `; 33 - } 27 + const expiresAt = new Date(Date.now() + 10 * 60 * 1000); // 10 minutes 28 + await sql` 29 + INSERT INTO oauth_states (key, data, expires_at) 30 + VALUES (${key}, ${JSON.stringify(value)}, ${expiresAt.toISOString()}) 31 + ON CONFLICT (key) DO UPDATE SET data = ${JSON.stringify(value)}, expires_at = ${expiresAt.toISOString()} 32 + `; 33 + } 34 34 35 35 async del(key: string): Promise<void> { 36 - const sql = getDbClient(); 37 36 await sql`DELETE FROM oauth_states WHERE key = ${key}`; 38 37 } 39 38 } 40 39 41 40 export class PostgresSessionStore { 42 41 async get(key: string): Promise<SessionData | undefined> { 43 - const sql = getDbClient(); 44 42 const result = await sql` 45 43 SELECT data FROM oauth_sessions 46 44 WHERE key = ${key} AND expires_at > NOW() ··· 49 47 } 50 48 51 49 async set(key: string, value: SessionData): Promise<void> { 52 - const sql = getDbClient(); 53 50 // Session includes tokens, DPoP keys, etc. 54 51 const expiresAt = new Date(Date.now() + 14 * 24 * 60 * 60 * 1000); // 14 days 55 52 await sql` ··· 60 57 } 61 58 62 59 async del(key: string): Promise<void> { 63 - const sql = getDbClient(); 64 60 await sql`DELETE FROM oauth_sessions WHERE key = ${key}`; 65 61 } 66 62 } 67 63 68 64 export class PostgresUserSessionStore { 69 65 async get(sessionId: string): Promise<{ did: string } | undefined> { 70 - const sql = getDbClient(); 71 66 const result = await sql` 72 67 SELECT did FROM user_sessions 73 68 WHERE session_id = ${sessionId} AND expires_at > NOW() ··· 77 72 } 78 73 79 74 async set(sessionId: string, data: { did: string }): Promise<void> { 80 - const sql = getDbClient(); 81 75 const expiresAt = new Date(Date.now() + 14 * 24 * 60 * 60 * 1000); // 14 days 82 76 await sql` 83 77 INSERT INTO user_sessions (session_id, did, expires_at) ··· 89 83 } 90 84 91 85 async del(sessionId: string): Promise<void> { 92 - const sql = getDbClient(); 93 86 await sql`DELETE FROM user_sessions WHERE session_id = ${sessionId}`; 94 87 } 95 88 }