Files
rdv/src/lib/server/connectors/surreal.db.ts
2026-01-03 22:40:04 +02:00

101 lines
2.5 KiB
TypeScript
Executable File

import Surreal, { StringRecordId } from "surrealdb";
import { logger } from "../logger";
export type { QueryResult } from "surrealdb";
try {
if (document || window) {
throw new Error("SurrealDB needs a NodeJS environment to run.");
}
} catch (err) {}
const CONFIG = {
url: process.env.SURREAL_URL ?? "",
user: process.env.SURREAL_USER ?? "",
pass: process.env.SURREAL_PASS ?? "",
ns: process.env.SURREAL_NS ?? "",
db: process.env.SURREAL_DB ?? "",
} as const;
const db = new Surreal();
async function connectDB() {
try {
await db.connect(`http://${CONFIG.url}/rpc`);
await db.use({ namespace: CONFIG.ns, database: CONFIG.db });
await authenticateDB();
return true;
} catch (error) {
logger.error("Error connecting to SurrealDB:", error);
return false;
}
}
async function authenticateDB() {
try {
await db.signin({ username: CONFIG.user, password: CONFIG.pass });
logger.info("🔑 Successfully authenticated with SurrealDB");
return true;
} catch (error) {
logger.warn("❌ Authentication failed:");
logger.error(error);
return false;
}
}
async function ensureAuthenticated() {
try {
await db.query("RETURN 1");
} catch (error: any) {
if (error.status === 401) {
logger.warn("⚠️ SurrealDB Auth token expired. Attempting reconnection...");
try {
// Full reconnection instead of just re-authentication
await db.close();
const success = await connectDB();
if (success) {
logger.info("✅ Successfully reconnected to database");
} else {
logger.error("❌ Failed to reconnect to database");
}
} catch (reconnectError) {
logger.error("❌ Reconnection failed:", reconnectError);
}
} else {
logger.error("Unexpected database error:", error);
}
}
}
// 1 minute
const CHECK_INTERVAL = 60 * 1000;
let intervalId: NodeJS.Timeout;
async function initializeDB() {
const success = await connectDB();
if (success) {
// Only start the interval if initial connection was successful
intervalId = setInterval(ensureAuthenticated, CHECK_INTERVAL);
} else {
logger.error("Failed to initialize database connection");
// Optionally implement retry logic here
}
}
export function cleanup() {
if (intervalId) {
clearInterval(intervalId);
}
return db.close();
}
await initializeDB();
export const surreal = db as Surreal;
export function parseToRID(idStr: string) {
return new StringRecordId(idStr);
}
process.on("SIGTERM", cleanup);
process.on("SIGINT", cleanup);