Files
jap_web_ng/src/sqlite-api.ts
T
2026-09-15 10:41:24 +03:00

77 lines
2.2 KiB
TypeScript

const worker = new Worker(new URL('./db-worker.ts', import.meta.url), {
type: 'module',
});
let requestId = 0;
type WorkerRequest = {
resolve: (data: any) => void;
reject: (error: Error) => void;
};
let initPromise: Promise<void> | null = null;
const pending = new Map<number, WorkerRequest>();
export function initWorker(): Promise<void> {
if (initPromise) return initPromise;
initPromise = new Promise((resolve, reject) => {
worker.onmessage = (e: MessageEvent) => {
const msg = e.data;
if (msg.type === 'ready') {
// Готов — запрос init уже обработан
return;
}
const pendingReq = pending.get(msg.id);
if (!pendingReq) return;
pending.delete(msg.id);
if (msg.type == "success") {
pendingReq.resolve(msg.data);
} else {
pendingReq.reject(new Error(msg.error ?? msg.message ?? 'Неизвестная ошибка Worker'));
}
};
worker.onerror = (err) => {
console.error('[SQLite Worker] Ошибка:', err);
reject(new Error('Ошибка Worker'));
};
// Отправляем init
const id = ++requestId;
pending.set(id, { resolve, reject });
worker.postMessage({ type: 'start', id });
});
return initPromise;
}
function sendToWorker(type: string, payload?: any): Promise<any> {
return new Promise((resolve, reject) => {
if (!worker) {
reject(new Error('Worker не создан'));
return;
}
const id = ++requestId;
pending.set(id, { resolve, reject });
worker.postMessage({ type, id, ...payload });
});
}
export async function query(sql: string, params?: any[]): Promise<any[]> {
const result = await sendToWorker('query', { sql, params: params ?? [] });
return result;
}
export async function command(sql: string, params?: any[]): Promise<void> {
await sendToWorker('command', { sql, params: params ?? [] });
}
export async function closeDb(): Promise<void> {
await sendToWorker('close');
worker.terminate();
}