101 lines
2.5 KiB
TypeScript
Executable File
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);
|