refactor(dm-db): use singleton IndexedDB connection to avoid N+1 overhead

Co-authored-by: PR0M3TH3AN <[email protected]>
This commit is contained in:
google-labs-jules[bot]andPR0M3TH3AN committed 2026-02-08 03:41:19 +00:00
1 parent 1fbee4219b
commit 03f4efbfeb
3 files changed
+108 -11

No files matched your search

+51 -11
View File
@@ -84,6 +84,9 @@ const MIGRATIONS = [
},
];
let dbInstance = null;
let dbPromise = null;
function isIndexedDbAvailable() {
try {
return typeof indexedDB !== "undefined";
@@ -101,7 +104,15 @@ function applyMigrations(db, oldVersion, newVersion, transaction) {
}
function openDmDb() {
return new Promise((resolve, reject) => {
if (dbInstance) {
return Promise.resolve(dbInstance);
}
if (dbPromise) {
return dbPromise;
}
dbPromise = new Promise((resolve, reject) => {
if (!isIndexedDbAvailable()) {
resolve(null);
return;
@@ -118,10 +129,39 @@ function openDmDb() {
applyMigrations(db, oldVersion, newVersion, upgradeTransaction);
};
request.onsuccess = () => resolve(request.result);
request.onerror = () =>
request.onsuccess = () => {
const db = request.result;
dbInstance = db;
db.onversionchange = () => {
db.close();
dbInstance = null;
dbPromise = null;
};
db.onclose = () => {
dbInstance = null;
dbPromise = null;
};
resolve(db);
};
request.onerror = () => {
dbPromise = null;
reject(request.error || new Error("Failed to open DM database."));
};
});
return dbPromise;
}
export async function closeDmDb() {
if (dbInstance) {
dbInstance.close();
dbInstance = null;
}
dbPromise = null;
}
function sanitizeTimestamp(value) {
@@ -264,7 +304,7 @@ export async function writeConversationMetadata(conversation) {
const tx = db.transaction(STORES.CONVERSATIONS, "readwrite");
tx.objectStore(STORES.CONVERSATIONS).put(normalized);
await finalizeTransaction(tx);
db.close();
// db.close(); // Keep connection open
return normalized;
} catch (error) {
userLogger.warn("[dmDb] Failed to write conversation metadata", error);
@@ -296,7 +336,7 @@ export async function writeMessages(messages) {
}
await finalizeTransaction(tx);
db.close();
// db.close(); // Keep connection open
return normalized;
} catch (error) {
userLogger.warn("[dmDb] Failed to persist messages", error);
@@ -319,7 +359,7 @@ export async function getConversation(conversationId) {
const store = tx.objectStore(STORES.CONVERSATIONS);
const result = await runRequest(store.get(conversationId.trim()));
await finalizeTransaction(tx);
db.close();
// db.close(); // Keep connection open
return result || null;
} catch (error) {
userLogger.warn("[dmDb] Failed to read conversation metadata", error);
@@ -369,7 +409,7 @@ export async function listMessagesByConversation(conversationId, options = {}) {
userLogger.warn("[dmDb] Failed to list messages", request.error);
resolve(results);
};
}).finally(() => db.close());
}); // removed finally db.close()
} catch (error) {
userLogger.warn("[dmDb] Failed to list messages", error);
return [];
@@ -429,7 +469,7 @@ export async function updateConversationFromMessage(message, options = {}) {
store.put(next);
await finalizeTransaction(tx);
db.close();
// db.close(); // Keep connection open
return next;
} catch (error) {
userLogger.warn("[dmDb] Failed to update conversation metadata", error);
@@ -478,7 +518,7 @@ export async function updateConversationOpenState(
store.put(next);
await finalizeTransaction(tx);
db.close();
// db.close(); // Keep connection open
return next;
} catch (error) {
userLogger.warn("[dmDb] Failed to update conversation open state", error);
@@ -512,7 +552,7 @@ export async function listConversations() {
userLogger.warn("[dmDb] Failed to list conversations", request.error);
resolve(results);
};
}).finally(() => db.close());
}); // removed finally db.close()
} catch (error) {
userLogger.warn("[dmDb] Failed to list conversations", error);
return [];
@@ -542,7 +582,7 @@ export async function clearDmDb() {
}
await finalizeTransaction(tx);
db.close();
// db.close(); // Keep connection open
return true;
} catch (error) {
devLogger.warn("[dmDb] Failed to clear DM database", error);