SurfSense/surfsense_web/lib/electric/client.ts
Anish Sarkar 82c6dd0221 feat: Integrate Electric SQL for real-time notifications and enhance PostgreSQL configuration
- Added Electric SQL service to docker-compose for real-time data synchronization.
- Introduced PostgreSQL configuration for logical replication and performance tuning.
- Created scripts for initializing Electric SQL user and electrifying tables.
- Implemented notification model and service in the backend.
- Developed ElectricProvider and useNotifications hook in the frontend for managing notifications.
- Updated environment variables and package dependencies for Electric SQL integration.
2026-01-12 12:47:00 +05:30

86 lines
2.2 KiB
TypeScript

/**
* Electric SQL client setup
* This initializes the Electric SQL client with local PGlite database (PostgreSQL in browser)
*/
import { PGlite } from '@electric-sql/pglite'
import { electrify } from 'electric-sql/pglite'
import { getElectricAuthToken } from './auth'
// We'll generate the schema after running electric:generate
// For now, we'll use a placeholder type
type Electric = any
type Schema = any
let electric: Electric | null = null
let isInitializing = false
let initPromise: Promise<Electric> | null = null
export async function initElectric(): Promise<Electric> {
if (electric) {
return electric
}
if (isInitializing && initPromise) {
return initPromise
}
isInitializing = true
initPromise = (async () => {
try {
const config = {
auth: {
token: await getElectricAuthToken(),
},
url: process.env.NEXT_PUBLIC_ELECTRIC_URL || 'http://localhost:5133',
}
// Initialize PGlite database (PostgreSQL in browser)
// Use idb:// prefix for IndexedDB storage in browser
// relaxedDurability improves responsiveness by scheduling flush after query returns
const conn = new PGlite('idb://surfsense.db', {
relaxedDurability: true,
})
// Import schema (will be generated by electric:generate)
// For now, we'll use a dynamic import that will work after schema generation
let schema: Schema
try {
const schemaModule = await import('./generated/schema')
schema = schemaModule.schema
} catch (error) {
console.warn(
'Electric SQL schema not found. Run "pnpm electric:generate" to generate it.',
error
)
// Return a mock electric client for now
return null as any
}
// Electrify the PGlite database connection
electric = await electrify(conn, schema, config)
console.log('Electric SQL initialized successfully with PGlite')
return electric
} catch (error) {
console.error('Failed to initialize Electric SQL:', error)
throw error
} finally {
isInitializing = false
}
})()
return initPromise
}
export function getElectric(): Electric {
if (!electric) {
throw new Error('Electric not initialized. Call initElectric() first.')
}
return electric
}
export function isElectricInitialized(): boolean {
return electric !== null
}