Browse Source

chore(linting): some linting problems fixed

sql-absurd-sql-further
Matthew Raymer 3 days ago
parent
commit
8edddb1a57
  1. 2
      src/libs/util.ts
  2. 201
      src/services/platforms/ElectronPlatformService.ts
  3. 18
      src/views/AccountViewView.vue

2
src/libs/util.ts

@ -657,7 +657,7 @@ export async function saveNewIdentity(
// Store the new secret // Store the new secret
await platformService.dbExec( await platformService.dbExec(
`INSERT INTO secret (id, secretBase64) VALUES (1, ?)`, `INSERT INTO secret (id, secretBase64) VALUES (1, ?)`,
[secretBase64] [secretBase64],
); );
} else { } else {
secretBase64 = secrets.values[0][0] as string; secretBase64 = secrets.values[0][0] as string;

201
src/services/platforms/ElectronPlatformService.ts

@ -93,7 +93,11 @@ export class ElectronPlatformService implements PlatformService {
private isConnectionOpen = false; private isConnectionOpen = false;
private operationQueue: Promise<unknown> = Promise.resolve(); private operationQueue: Promise<unknown> = Promise.resolve();
private queueLock = false; private queueLock = false;
private connectionState: 'disconnected' | 'connecting' | 'connected' | 'error' = 'disconnected'; private connectionState:
| "disconnected"
| "connecting"
| "connected"
| "error" = "disconnected";
private connectionPromise: Promise<void> | null = null; private connectionPromise: Promise<void> | null = null;
// SQLite initialization configuration // SQLite initialization configuration
@ -124,18 +128,25 @@ export class ElectronPlatformService implements PlatformService {
} }
// Check if SQLite is already available // Check if SQLite is already available
const isAvailable = await window.electron.ipcRenderer.invoke("sqlite-is-available"); const isAvailable = await window.electron.ipcRenderer.invoke(
"sqlite-is-available",
);
if (!isAvailable) { if (!isAvailable) {
return false; return false;
} }
// Check if database is already open // Check if database is already open
const isOpen = await window.electron.ipcRenderer.invoke("sqlite-is-db-open", { const isOpen = await window.electron.ipcRenderer.invoke(
"sqlite-is-db-open",
{
database: this.dbName, database: this.dbName,
}); },
);
if (isOpen) { if (isOpen) {
logger.info("[ElectronPlatformService] SQLite is already ready and database is open"); logger.info(
"[ElectronPlatformService] SQLite is already ready and database is open",
);
sqliteInitState.isReady = true; sqliteInitState.isReady = true;
sqliteInitState.isInitializing = false; sqliteInitState.isInitializing = false;
sqliteInitState.lastReadyCheck = Date.now(); sqliteInitState.lastReadyCheck = Date.now();
@ -144,7 +155,10 @@ export class ElectronPlatformService implements PlatformService {
return false; return false;
} catch (error) { } catch (error) {
logger.warn("[ElectronPlatformService] Error checking existing readiness:", error); logger.warn(
"[ElectronPlatformService] Error checking existing readiness:",
error,
);
return false; return false;
} }
}; };
@ -161,8 +175,14 @@ export class ElectronPlatformService implements PlatformService {
// If someone else is initializing, wait for them // If someone else is initializing, wait for them
if (sqliteInitState.isInitializing) { if (sqliteInitState.isInitializing) {
logger.info("[ElectronPlatformService] Another initialization in progress, waiting..."); logger.info(
setTimeout(attemptInitialization, ElectronPlatformService.SQLITE_CONFIG.INITIALIZATION.READY_CHECK_INTERVAL_MS); "[ElectronPlatformService] Another initialization in progress, waiting...",
);
setTimeout(
attemptInitialization,
ElectronPlatformService.SQLITE_CONFIG.INITIALIZATION
.READY_CHECK_INTERVAL_MS,
);
return; return;
} }
@ -171,7 +191,9 @@ export class ElectronPlatformService implements PlatformService {
// Verify Electron API exposure first // Verify Electron API exposure first
await verifyElectronAPI(); await verifyElectronAPI();
logger.info("[ElectronPlatformService] Electron API verification successful"); logger.info(
"[ElectronPlatformService] Electron API verification successful",
);
if (!window.electron?.ipcRenderer) { if (!window.electron?.ipcRenderer) {
logger.warn("[ElectronPlatformService] IPC renderer not available"); logger.warn("[ElectronPlatformService] IPC renderer not available");
@ -182,12 +204,16 @@ export class ElectronPlatformService implements PlatformService {
// Set up ready signal handler BEFORE setting timeout // Set up ready signal handler BEFORE setting timeout
window.electron.ipcRenderer.once("sqlite-ready", async () => { window.electron.ipcRenderer.once("sqlite-ready", async () => {
cleanup(); cleanup();
logger.info("[ElectronPlatformService] Received SQLite ready signal"); logger.info(
"[ElectronPlatformService] Received SQLite ready signal",
);
try { try {
// Test SQLite operations after receiving ready signal // Test SQLite operations after receiving ready signal
await testSQLiteOperations(); await testSQLiteOperations();
logger.info("[ElectronPlatformService] SQLite operations test successful"); logger.info(
"[ElectronPlatformService] SQLite operations test successful",
);
this.isInitialized = true; this.isInitialized = true;
sqliteInitState.isReady = true; sqliteInitState.isReady = true;
@ -197,43 +223,67 @@ export class ElectronPlatformService implements PlatformService {
} catch (error) { } catch (error) {
sqliteInitState.error = error as Error; sqliteInitState.error = error as Error;
sqliteInitState.isInitializing = false; sqliteInitState.isInitializing = false;
logger.error("[ElectronPlatformService] SQLite operations test failed:", error); logger.error(
"[ElectronPlatformService] SQLite operations test failed:",
error,
);
reject(error); reject(error);
} }
}); });
// Set up error handler // Set up error handler
window.electron.ipcRenderer.once("database-status", (...args: unknown[]) => { window.electron.ipcRenderer.once(
"database-status",
(...args: unknown[]) => {
cleanup(); cleanup();
const status = args[0] as { status: string; error?: string }; const status = args[0] as { status: string; error?: string };
if (status.status === "error") { if (status.status === "error") {
this.dbFatalError = true; this.dbFatalError = true;
sqliteInitState.error = new Error(status.error || "Database initialization failed"); sqliteInitState.error = new Error(
status.error || "Database initialization failed",
);
sqliteInitState.isInitializing = false; sqliteInitState.isInitializing = false;
reject(sqliteInitState.error); reject(sqliteInitState.error);
} }
}); },
);
// Set timeout for this attempt AFTER setting up handlers // Set timeout for this attempt AFTER setting up handlers
this.initializationTimeout = setTimeout(() => { this.initializationTimeout = setTimeout(() => {
if (retryCount < ElectronPlatformService.SQLITE_CONFIG.INITIALIZATION.RETRY_ATTEMPTS) { if (
retryCount <
ElectronPlatformService.SQLITE_CONFIG.INITIALIZATION
.RETRY_ATTEMPTS
) {
retryCount++; retryCount++;
logger.warn(`[ElectronPlatformService] SQLite initialization attempt ${retryCount} timed out, retrying...`); logger.warn(
setTimeout(attemptInitialization, ElectronPlatformService.SQLITE_CONFIG.INITIALIZATION.RETRY_DELAY_MS); `[ElectronPlatformService] SQLite initialization attempt ${retryCount} timed out, retrying...`,
);
setTimeout(
attemptInitialization,
ElectronPlatformService.SQLITE_CONFIG.INITIALIZATION
.RETRY_DELAY_MS,
);
} else { } else {
cleanup(); cleanup();
sqliteInitState.isInitializing = false; sqliteInitState.isInitializing = false;
sqliteInitState.error = new Error("SQLite initialization timeout after all retries"); sqliteInitState.error = new Error(
logger.error("[ElectronPlatformService] SQLite initialization failed after all retries"); "SQLite initialization timeout after all retries",
);
logger.error(
"[ElectronPlatformService] SQLite initialization failed after all retries",
);
reject(sqliteInitState.error); reject(sqliteInitState.error);
} }
}, ElectronPlatformService.SQLITE_CONFIG.INITIALIZATION.TIMEOUT_MS); }, ElectronPlatformService.SQLITE_CONFIG.INITIALIZATION.TIMEOUT_MS);
} catch (error) { } catch (error) {
cleanup(); cleanup();
sqliteInitState.error = error as Error; sqliteInitState.error = error as Error;
sqliteInitState.isInitializing = false; sqliteInitState.isInitializing = false;
logger.error("[ElectronPlatformService] Initialization failed:", error); logger.error(
"[ElectronPlatformService] Initialization failed:",
error,
);
reject(error); reject(error);
} }
}; };
@ -254,30 +304,30 @@ export class ElectronPlatformService implements PlatformService {
// Use IPC bridge with specific methods // Use IPC bridge with specific methods
this.sqlite = { this.sqlite = {
createConnection: async (options) => { createConnection: async (options) => {
await window.electron.ipcRenderer.invoke('sqlite-create-connection', { await window.electron.ipcRenderer.invoke("sqlite-create-connection", {
...options, ...options,
database: this.dbName database: this.dbName,
}); });
}, },
query: async (options) => { query: async (options) => {
return await window.electron.ipcRenderer.invoke('sqlite-query', { return await window.electron.ipcRenderer.invoke("sqlite-query", {
...options, ...options,
database: this.dbName database: this.dbName,
}); });
}, },
run: async (options) => { run: async (options) => {
return await window.electron.ipcRenderer.invoke('sqlite-run', { return await window.electron.ipcRenderer.invoke("sqlite-run", {
...options, ...options,
database: this.dbName database: this.dbName,
}); });
}, },
execute: async (options) => { execute: async (options) => {
await window.electron.ipcRenderer.invoke('sqlite-execute', { await window.electron.ipcRenderer.invoke("sqlite-execute", {
...options, ...options,
database: this.dbName, database: this.dbName,
statements: [{ statement: options.statements }] statements: [{ statement: options.statements }],
}); });
} },
} as SQLiteOperations; } as SQLiteOperations;
// Create the connection (idempotent) // Create the connection (idempotent)
@ -537,7 +587,7 @@ export class ElectronPlatformService implements PlatformService {
try { try {
// Acquire lock // Acquire lock
while (this.queueLock) { while (this.queueLock) {
await new Promise(resolve => setTimeout(resolve, 50)); await new Promise((resolve) => setTimeout(resolve, 50));
} }
this.queueLock = true; this.queueLock = true;
@ -562,20 +612,20 @@ export class ElectronPlatformService implements PlatformService {
} }
// If we're already connected, return immediately // If we're already connected, return immediately
if (this.connectionState === 'connected') { if (this.connectionState === "connected") {
return Promise.resolve(); return Promise.resolve();
} }
// Create new connection promise // Create new connection promise
this.connectionPromise = (async () => { this.connectionPromise = (async () => {
try { try {
this.connectionState = 'connecting'; this.connectionState = "connecting";
// Wait for any existing operations // Wait for any existing operations
await this.operationQueue; await this.operationQueue;
// Create connection // Create connection
await window.electron!.ipcRenderer.invoke('sqlite-create-connection', { await window.electron!.ipcRenderer.invoke("sqlite-create-connection", {
database: this.dbName, database: this.dbName,
encrypted: false, encrypted: false,
mode: "no-encryption", mode: "no-encryption",
@ -583,23 +633,26 @@ export class ElectronPlatformService implements PlatformService {
logger.debug("[ElectronPlatformService] Database connection created"); logger.debug("[ElectronPlatformService] Database connection created");
// Open database // Open database
await window.electron!.ipcRenderer.invoke('sqlite-open', { await window.electron!.ipcRenderer.invoke("sqlite-open", {
database: this.dbName database: this.dbName,
}); });
logger.debug("[ElectronPlatformService] Database opened"); logger.debug("[ElectronPlatformService] Database opened");
// Verify database is open // Verify database is open
const isOpen = await window.electron!.ipcRenderer.invoke('sqlite-is-db-open', { const isOpen = await window.electron!.ipcRenderer.invoke(
database: this.dbName "sqlite-is-db-open",
}); {
database: this.dbName,
},
);
if (!isOpen) { if (!isOpen) {
throw new Error('[ElectronPlatformService] Database failed to open'); throw new Error("[ElectronPlatformService] Database failed to open");
} }
this.connectionState = 'connected'; this.connectionState = "connected";
this.isConnectionOpen = true; this.isConnectionOpen = true;
} catch (error) { } catch (error) {
this.connectionState = 'error'; this.connectionState = "error";
this.connectionPromise = null; this.connectionPromise = null;
throw error; throw error;
} }
@ -609,28 +662,31 @@ export class ElectronPlatformService implements PlatformService {
} }
private async releaseConnection(): Promise<void> { private async releaseConnection(): Promise<void> {
if (this.connectionState !== 'connected') { if (this.connectionState !== "connected") {
return; return;
} }
try { try {
// Close database // Close database
await window.electron!.ipcRenderer.invoke('sqlite-close', { await window.electron!.ipcRenderer.invoke("sqlite-close", {
database: this.dbName database: this.dbName,
}); });
logger.debug("[ElectronPlatformService] Database closed"); logger.debug("[ElectronPlatformService] Database closed");
// Close connection // Close connection
await window.electron!.ipcRenderer.invoke('sqlite-close-connection', { await window.electron!.ipcRenderer.invoke("sqlite-close-connection", {
database: this.dbName database: this.dbName,
}); });
logger.debug("[ElectronPlatformService] Database connection closed"); logger.debug("[ElectronPlatformService] Database connection closed");
this.connectionState = 'disconnected'; this.connectionState = "disconnected";
this.isConnectionOpen = false; this.isConnectionOpen = false;
} catch (error) { } catch (error) {
logger.error("[ElectronPlatformService] Failed to close database:", error); logger.error(
this.connectionState = 'error'; "[ElectronPlatformService] Failed to close database:",
error,
);
this.connectionState = "error";
} finally { } finally {
this.connectionPromise = null; this.connectionPromise = null;
} }
@ -650,7 +706,9 @@ export class ElectronPlatformService implements PlatformService {
params: unknown[] = [], params: unknown[] = [],
): Promise<QueryExecResult<T>> { ): Promise<QueryExecResult<T>> {
if (this.dbFatalError) { if (this.dbFatalError) {
throw new Error("Database is in a fatal error state. Please restart the app."); throw new Error(
"Database is in a fatal error state. Please restart the app.",
);
} }
return this.enqueueOperation(async () => { return this.enqueueOperation(async () => {
@ -659,23 +717,33 @@ export class ElectronPlatformService implements PlatformService {
await this.getConnection(); await this.getConnection();
// Execute query // Execute query
const result = await window.electron!.ipcRenderer.invoke('sqlite-query', { const result = (await window.electron!.ipcRenderer.invoke(
"sqlite-query",
{
database: this.dbName, database: this.dbName,
statement: sql, statement: sql,
values: params values: params,
}) as SQLiteQueryResult; },
logger.debug("[ElectronPlatformService] [dbQuery] Query executed successfully"); )) as SQLiteQueryResult;
logger.debug(
"[ElectronPlatformService] [dbQuery] Query executed successfully",
);
// Process results // Process results
const columns = result.values?.[0] ? Object.keys(result.values[0]) : []; const columns = result.values?.[0] ? Object.keys(result.values[0]) : [];
const processedResult = { const processedResult = {
columns, columns,
values: (result.values || []).map((row: Record<string, unknown>) => row as T) values: (result.values || []).map(
(row: Record<string, unknown>) => row as T,
),
}; };
return processedResult; return processedResult;
} catch (error) { } catch (error) {
logger.error("[ElectronPlatformService] [dbQuery] Query failed:", error); logger.error(
"[ElectronPlatformService] [dbQuery] Query failed:",
error,
);
throw error; throw error;
} finally { } finally {
// Release connection after query // Release connection after query
@ -692,7 +760,9 @@ export class ElectronPlatformService implements PlatformService {
params?: unknown[], params?: unknown[],
): Promise<{ changes: number; lastId?: number }> { ): Promise<{ changes: number; lastId?: number }> {
if (this.dbFatalError) { if (this.dbFatalError) {
throw new Error("Database is in a fatal error state. Please restart the app."); throw new Error(
"Database is in a fatal error state. Please restart the app.",
);
} }
return this.enqueueOperation(async () => { return this.enqueueOperation(async () => {
@ -701,12 +771,17 @@ export class ElectronPlatformService implements PlatformService {
await this.getConnection(); await this.getConnection();
// Execute query // Execute query
const result = await window.electron!.ipcRenderer.invoke('sqlite-run', { const result = (await window.electron!.ipcRenderer.invoke(
"sqlite-run",
{
database: this.dbName, database: this.dbName,
statement: sql, statement: sql,
values: params values: params,
}) as SQLiteQueryResult; },
logger.debug("[ElectronPlatformService] [dbExec] Query executed successfully"); )) as SQLiteQueryResult;
logger.debug(
"[ElectronPlatformService] [dbExec] Query executed successfully",
);
return { return {
changes: result.changes?.changes || 0, changes: result.changes?.changes || 0,

18
src/views/AccountViewView.vue

@ -1889,7 +1889,7 @@ export default class AccountViewView extends Vue {
logger.debug("[AccountViewView] Starting API server update", { logger.debug("[AccountViewView] Starting API server update", {
current: this.apiServer, current: this.apiServer,
new: this.apiServerInput, new: this.apiServerInput,
component: 'AccountViewView' component: "AccountViewView",
}); });
try { try {
@ -1909,29 +1909,33 @@ export default class AccountViewView extends Vue {
} }
this.apiServer = this.apiServerInput; this.apiServer = this.apiServerInput;
logger.debug("[AccountViewView] Local state updated", { apiServer: this.apiServer }); logger.debug("[AccountViewView] Local state updated", {
apiServer: this.apiServer,
});
// Verify the update // Verify the update
const settings = await databaseUtil.retrieveSettingsForActiveAccount(); const settings = await databaseUtil.retrieveSettingsForActiveAccount();
logger.debug("[AccountViewView] Settings verification", { logger.debug("[AccountViewView] Settings verification", {
retrieved: settings.apiServer, retrieved: settings.apiServer,
expected: this.apiServerInput, expected: this.apiServerInput,
match: settings.apiServer === this.apiServerInput match: settings.apiServer === this.apiServerInput,
}); });
// Show success notification // Show success notification
this.$notify({ this.$notify(
{
group: "alert", group: "alert",
type: "success", type: "success",
title: "API Server Updated", title: "API Server Updated",
text: "API server settings saved successfully.", text: "API server settings saved successfully.",
}, 3000); },
3000,
);
} catch (error) { } catch (error) {
logger.error("[AccountViewView] API server update failed", { logger.error("[AccountViewView] API server update failed", {
error, error,
current: this.apiServer, current: this.apiServer,
attempted: this.apiServerInput attempted: this.apiServerInput,
}); });
this.$notify( this.$notify(
{ {

Loading…
Cancel
Save