forked from jsnbuchanan/crowd-funder-for-time-pwa
Fix worker-only database architecture and Vue Proxy serialization
- Implement worker-only database access to eliminate double migrations - Add parameter serialization in usePlatformService to prevent Capacitor "object could not be cloned" errors - Fix infinite logging loop with circuit breaker in databaseUtil - Use dynamic imports in WebPlatformService to prevent worker thread errors - Add higher-level database methods (getContacts, getSettings) to composable - Eliminate Vue Proxy objects through JSON serialization and Object.freeze protection Resolves Proxy(Array) serialization failures and worker context conflicts across Web/Capacitor/Electron platforms.
This commit is contained in:
@@ -169,6 +169,9 @@ export async function retrieveSettingsForActiveAccount(): Promise<Settings> {
|
||||
let lastCleanupDate: string | null = null;
|
||||
export let memoryLogs: string[] = [];
|
||||
|
||||
// Flag to prevent infinite logging loops during database operations
|
||||
let isLoggingToDatabase = false;
|
||||
|
||||
/**
|
||||
* Logs a message to the database with proper handling of concurrent writes
|
||||
* @param message - The message to log
|
||||
@@ -179,36 +182,44 @@ export async function logToDb(
|
||||
message: string,
|
||||
level: string = "info",
|
||||
): Promise<void> {
|
||||
const platform = PlatformServiceFactory.getInstance();
|
||||
const todayKey = new Date().toDateString();
|
||||
// Prevent infinite logging loops - if we're already trying to log to database,
|
||||
// just log to console instead to break circular dependency
|
||||
if (isLoggingToDatabase) {
|
||||
console.log(`[DB-PREVENTED-${level.toUpperCase()}] ${message}`);
|
||||
return;
|
||||
}
|
||||
|
||||
// Set flag to prevent circular logging
|
||||
isLoggingToDatabase = true;
|
||||
|
||||
try {
|
||||
memoryLogs.push(`${new Date().toISOString()} ${message}`);
|
||||
// Insert using actual schema: date, message (no level column)
|
||||
await platform.dbExec("INSERT INTO logs (date, message) VALUES (?, ?)", [
|
||||
todayKey, // Use date string to match schema
|
||||
`[${level.toUpperCase()}] ${message}`, // Include level in message
|
||||
]);
|
||||
const platform = PlatformServiceFactory.getInstance();
|
||||
const todayKey = new Date().toDateString();
|
||||
|
||||
// Clean up old logs (keep only last 7 days) - do this less frequently
|
||||
// Only clean up if the date is different from the last cleanup
|
||||
if (!lastCleanupDate || lastCleanupDate !== todayKey) {
|
||||
const sevenDaysAgo = new Date(
|
||||
new Date().getTime() - 7 * 24 * 60 * 60 * 1000,
|
||||
).toDateString(); // Use date string to match schema
|
||||
memoryLogs = memoryLogs.filter((log) => log.split(" ")[0] > sevenDaysAgo);
|
||||
await platform.dbExec("DELETE FROM logs WHERE date < ?", [sevenDaysAgo]);
|
||||
lastCleanupDate = todayKey;
|
||||
try {
|
||||
memoryLogs.push(`${new Date().toISOString()} ${message}`);
|
||||
// Insert using actual schema: date, message (no level column)
|
||||
await platform.dbExec("INSERT INTO logs (date, message) VALUES (?, ?)", [
|
||||
todayKey, // Use date string to match schema
|
||||
`[${level.toUpperCase()}] ${message}`, // Include level in message
|
||||
]);
|
||||
|
||||
// Clean up old logs (keep only last 7 days) - do this less frequently
|
||||
// Only clean up if the date is different from the last cleanup
|
||||
if (!lastCleanupDate || lastCleanupDate !== todayKey) {
|
||||
const sevenDaysAgo = new Date(
|
||||
new Date().getTime() - 7 * 24 * 60 * 60 * 1000,
|
||||
).toDateString(); // Use date string to match schema
|
||||
memoryLogs = memoryLogs.filter((log) => log.split(" ")[0] > sevenDaysAgo);
|
||||
await platform.dbExec("DELETE FROM logs WHERE date < ?", [sevenDaysAgo]);
|
||||
lastCleanupDate = todayKey;
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Error logging to database:", error, " ... for original message:", message);
|
||||
}
|
||||
} catch (error) {
|
||||
// Log to console as fallback
|
||||
// eslint-disable-next-line no-console
|
||||
console.error(
|
||||
"Error logging to database:",
|
||||
error,
|
||||
" ... for original message:",
|
||||
message,
|
||||
);
|
||||
} finally {
|
||||
// Always reset the flag to prevent permanent blocking of database logging
|
||||
isLoggingToDatabase = false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -217,13 +228,13 @@ export async function logConsoleAndDb(
|
||||
message: string,
|
||||
isError = false,
|
||||
): Promise<void> {
|
||||
const level = isError ? "error" : "info";
|
||||
if (isError) {
|
||||
logger.error(`${new Date().toISOString()}`, message);
|
||||
console.error(message);
|
||||
} else {
|
||||
logger.log(`${new Date().toISOString()}`, message);
|
||||
console.log(message);
|
||||
}
|
||||
await logToDb(message, level);
|
||||
|
||||
await logToDb(message, isError ? "error" : "info");
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user