import { BaseObserver, DBAdapterListener, DBAdapter, DBLockOptions, LockContext, QueryResult, Transaction, Mutex, timeoutSignal } from '@powersync/common'; const MOCK_QUERY_RESPONSE: QueryResult = { rowsAffected: 0 }; /** * Implements a Mock DB adapter for use in Server Side Rendering (SSR). * This adapter will return empty results for queries, which will allow * server rendered views to initially generate scaffolding components */ export class SSRDBAdapter extends BaseObserver implements DBAdapter { name: string; readMutex: Mutex; writeMutex: Mutex; constructor() { super(); this.name = 'SSR DB'; this.readMutex = new Mutex(); this.writeMutex = new Mutex(); } close() {} async readLock(fn: (tx: LockContext) => Promise, options?: DBLockOptions) { return this.readMutex.runExclusive(() => fn(this), timeoutSignal(options?.timeoutMs)); } async readTransaction(fn: (tx: Transaction) => Promise, options?: DBLockOptions) { return this.readLock(() => fn(this.generateMockTransactionContext()), options); } async writeLock(fn: (tx: LockContext) => Promise, options?: DBLockOptions) { return this.writeMutex.runExclusive(() => fn(this), timeoutSignal(options?.timeoutMs)); } async writeTransaction(fn: (tx: Transaction) => Promise, options?: DBLockOptions) { return this.writeLock(() => fn(this.generateMockTransactionContext()), options); } async execute(query: string, params?: any[]): Promise { return this.writeMutex.runExclusive(async () => MOCK_QUERY_RESPONSE); } async executeRaw(query: string, params?: any[]): Promise { return this.writeMutex.runExclusive(async () => []); } async executeBatch(query: string, params?: any[][]): Promise { return this.writeMutex.runExclusive(async () => MOCK_QUERY_RESPONSE); } async getAll(sql: string, parameters?: any[]): Promise { return []; } async getOptional(sql: string, parameters?: any[] | undefined): Promise { return null; } async get(sql: string, parameters?: any[] | undefined): Promise { throw new Error(`No values are returned in SSR mode`); } /** * Generates a mock context for use in read/write transactions. * `this` already mocks most of the API, commit and rollback mocks * are added here */ private generateMockTransactionContext(): Transaction { return { ...this, commit: async () => { return MOCK_QUERY_RESPONSE; }, rollback: async () => { return MOCK_QUERY_RESPONSE; } }; } async refreshSchema(): Promise {} }