71 lines
1.9 KiB
TypeScript
71 lines
1.9 KiB
TypeScript
|
import { AssetBundle } from "../asset_bundle/bundle.ts";
|
||
|
import workerBundleJson from "./worker_bundle.json" assert { type: "json" };
|
||
|
|
||
|
const workerBundle = new AssetBundle(workerBundleJson);
|
||
|
|
||
|
export class AsyncSQLite {
|
||
|
worker: Worker;
|
||
|
requestId = 0;
|
||
|
outstandingRequests = new Map<
|
||
|
number,
|
||
|
{ resolve: (val: any) => void; reject: (error: Error) => void }
|
||
|
>();
|
||
|
|
||
|
constructor(readonly dbPath: string) {
|
||
|
const workerHref = URL.createObjectURL(
|
||
|
new Blob([
|
||
|
workerBundle.readFileSync("worker.js"),
|
||
|
], {
|
||
|
type: "application/javascript",
|
||
|
}),
|
||
|
);
|
||
|
this.worker = new Worker(
|
||
|
workerHref,
|
||
|
{
|
||
|
type: "module",
|
||
|
},
|
||
|
);
|
||
|
this.worker.addEventListener("message", (event: MessageEvent) => {
|
||
|
const { data } = event;
|
||
|
// console.log("Got data back", data);
|
||
|
const { id, result, error } = data;
|
||
|
const req = this.outstandingRequests.get(id);
|
||
|
if (!req) {
|
||
|
console.error("Invalid request id", id);
|
||
|
return;
|
||
|
}
|
||
|
if (result !== undefined) {
|
||
|
req.resolve(result);
|
||
|
} else if (error) {
|
||
|
req.reject(new Error(error));
|
||
|
}
|
||
|
this.outstandingRequests.delete(id);
|
||
|
});
|
||
|
}
|
||
|
|
||
|
private request(message: Record<string, any>): Promise<any> {
|
||
|
this.requestId++;
|
||
|
return new Promise((resolve, reject) => {
|
||
|
this.outstandingRequests.set(this.requestId, { resolve, reject });
|
||
|
// console.log("Sending request", message);
|
||
|
this.worker.postMessage({ ...message, id: this.requestId });
|
||
|
});
|
||
|
}
|
||
|
|
||
|
init(): Promise<void> {
|
||
|
return this.request({ type: "init", dbPath: this.dbPath });
|
||
|
}
|
||
|
|
||
|
execute(query: string, ...params: any[]): Promise<number> {
|
||
|
return this.request({ type: "execute", query, params });
|
||
|
}
|
||
|
|
||
|
query(query: string, ...params: any[]): Promise<any[]> {
|
||
|
return this.request({ type: "query", query, params });
|
||
|
}
|
||
|
|
||
|
stop() {
|
||
|
this.worker.terminate();
|
||
|
}
|
||
|
}
|