You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
236 lines
6.5 KiB
236 lines
6.5 KiB
/**
|
|
* SQL Worker Thread Handler for TimeSafari Web Platform
|
|
*
|
|
* This worker handles all database operations for the web platform,
|
|
* ensuring single-threaded database access and preventing double migrations.
|
|
*
|
|
* Architecture:
|
|
* - Main thread sends messages to this worker
|
|
* - Worker initializes database once and handles all SQL operations
|
|
* - Results are sent back to main thread via postMessage
|
|
*
|
|
* @author Matthew Raymer
|
|
* @version 1.0.0
|
|
* @since 2025-07-02
|
|
*/
|
|
|
|
// import { logger } from "./utils/logger"; // DISABLED FOR DEBUGGING
|
|
|
|
/**
|
|
* Worker state management
|
|
*/
|
|
let isInitialized = false;
|
|
let initializationPromise = null;
|
|
let databaseService = null;
|
|
|
|
/**
|
|
* Lazy load database service to prevent circular dependencies
|
|
*/
|
|
async function getDatabaseService() {
|
|
if (!databaseService) {
|
|
// Dynamic import to prevent circular dependency
|
|
const { default: service } = await import("./services/AbsurdSqlDatabaseService");
|
|
databaseService = service;
|
|
}
|
|
return databaseService;
|
|
}
|
|
|
|
/**
|
|
* Send response back to main thread
|
|
*/
|
|
function sendResponse(id, type, data = null, error = null) {
|
|
const response = {
|
|
id,
|
|
type,
|
|
...(data && { data }),
|
|
...(error && { error }),
|
|
};
|
|
postMessage(response);
|
|
}
|
|
|
|
/**
|
|
* Initialize database service
|
|
*/
|
|
async function initializeDatabase() {
|
|
if (isInitialized) {
|
|
return;
|
|
}
|
|
|
|
if (initializationPromise) {
|
|
return initializationPromise;
|
|
}
|
|
|
|
initializationPromise = (async () => {
|
|
try {
|
|
// logger.log("[SQLWorker] Starting database initialization..."); // DISABLED
|
|
const dbService = await getDatabaseService();
|
|
await dbService.initialize();
|
|
isInitialized = true;
|
|
// logger.log("[SQLWorker] Database initialization completed successfully"); // DISABLED
|
|
} catch (error) {
|
|
// logger.error("[SQLWorker] Database initialization failed:", error); // DISABLED
|
|
console.error("[SQLWorker] Database initialization failed:", error); // Keep only critical errors
|
|
isInitialized = false;
|
|
initializationPromise = null;
|
|
throw error;
|
|
}
|
|
})();
|
|
|
|
return initializationPromise;
|
|
}
|
|
|
|
/**
|
|
* Handle database query operations
|
|
*/
|
|
async function handleQuery(id, sql, params = []) {
|
|
try {
|
|
await initializeDatabase();
|
|
// logger.log(`[SQLWorker] Executing query: ${sql}`, params); // DISABLED
|
|
|
|
const dbService = await getDatabaseService();
|
|
const result = await dbService.query(sql, params);
|
|
// logger.log(`[SQLWorker] Query completed successfully`); // DISABLED
|
|
|
|
sendResponse(id, "success", { result });
|
|
} catch (error) {
|
|
// logger.error(`[SQLWorker] Query failed:`, error); // DISABLED
|
|
console.error(`[SQLWorker] Query failed:`, error); // Keep only critical errors
|
|
sendResponse(id, "error", null, {
|
|
message: error.message,
|
|
stack: error.stack,
|
|
});
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Handle database execution operations (INSERT, UPDATE, DELETE)
|
|
*/
|
|
async function handleExec(id, sql, params = []) {
|
|
try {
|
|
await initializeDatabase();
|
|
// logger.log(`[SQLWorker] Executing statement: ${sql}`, params); // DISABLED
|
|
|
|
const dbService = await getDatabaseService();
|
|
const result = await dbService.run(sql, params);
|
|
// logger.log(`[SQLWorker] Statement executed successfully:`, result); // DISABLED
|
|
|
|
sendResponse(id, "success", result);
|
|
} catch (error) {
|
|
// logger.error(`[SQLWorker] Statement execution failed:`, error); // DISABLED
|
|
console.error(`[SQLWorker] Statement execution failed:`, error); // Keep only critical errors
|
|
sendResponse(id, "error", null, {
|
|
message: error.message,
|
|
stack: error.stack,
|
|
});
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Handle database get one row operations
|
|
*/
|
|
async function handleGetOneRow(id, sql, params = []) {
|
|
try {
|
|
await initializeDatabase();
|
|
// logger.log(`[SQLWorker] Executing getOneRow: ${sql}`, params); // DISABLED
|
|
|
|
const dbService = await getDatabaseService();
|
|
const result = await dbService.query(sql, params);
|
|
const oneRow = result?.[0]?.values?.[0];
|
|
// logger.log(`[SQLWorker] GetOneRow completed successfully`); // DISABLED
|
|
|
|
sendResponse(id, "success", oneRow);
|
|
} catch (error) {
|
|
// logger.error(`[SQLWorker] GetOneRow failed:`, error); // DISABLED
|
|
console.error(`[SQLWorker] GetOneRow failed:`, error); // Keep only critical errors
|
|
sendResponse(id, "error", null, {
|
|
message: error.message,
|
|
stack: error.stack,
|
|
});
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Handle initialization request
|
|
*/
|
|
async function handleInit(id) {
|
|
try {
|
|
await initializeDatabase();
|
|
// logger.log("[SQLWorker] Initialization request completed"); // DISABLED
|
|
sendResponse(id, "init-complete");
|
|
} catch (error) {
|
|
// logger.error("[SQLWorker] Initialization request failed:", error); // DISABLED
|
|
console.error("[SQLWorker] Initialization request failed:", error); // Keep only critical errors
|
|
sendResponse(id, "error", null, {
|
|
message: error.message,
|
|
stack: error.stack,
|
|
});
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Handle ping request for health check
|
|
*/
|
|
function handlePing(id) {
|
|
// logger.log("[SQLWorker] Ping received"); // DISABLED
|
|
sendResponse(id, "pong");
|
|
}
|
|
|
|
/**
|
|
* Main message handler
|
|
*/
|
|
onmessage = function (event) {
|
|
const { id, type, sql, params } = event.data;
|
|
|
|
if (!id || !type) {
|
|
// logger.error("[SQLWorker] Invalid message received:", event.data); // DISABLED
|
|
console.error("[SQLWorker] Invalid message received:", event.data);
|
|
return;
|
|
}
|
|
|
|
// logger.log(`[SQLWorker] Received message: ${type} (${id})`); // DISABLED
|
|
|
|
switch (type) {
|
|
case "query":
|
|
handleQuery(id, sql, params);
|
|
break;
|
|
|
|
case "exec":
|
|
handleExec(id, sql, params);
|
|
break;
|
|
|
|
case "getOneRow":
|
|
handleGetOneRow(id, sql, params);
|
|
break;
|
|
|
|
case "init":
|
|
handleInit(id);
|
|
break;
|
|
|
|
case "ping":
|
|
handlePing(id);
|
|
break;
|
|
|
|
default:
|
|
// logger.error(`[SQLWorker] Unknown message type: ${type}`); // DISABLED
|
|
console.error(`[SQLWorker] Unknown message type: ${type}`);
|
|
sendResponse(id, "error", null, {
|
|
message: `Unknown message type: ${type}`,
|
|
});
|
|
break;
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Handle worker errors
|
|
*/
|
|
onerror = function (error) {
|
|
// logger.error("[SQLWorker] Worker error:", error); // DISABLED
|
|
console.error("[SQLWorker] Worker error:", error);
|
|
};
|
|
|
|
/**
|
|
* Auto-initialize on worker startup (removed to prevent circular dependency)
|
|
* Initialization now happens on first database operation
|
|
*/
|
|
// logger.log("[SQLWorker] Worker loaded, ready to receive messages"); // DISABLED
|
|
console.log("[SQLWorker] Worker loaded, ready to receive messages");
|
|
|