Fixes #97: SQLite is now async, optimized, tests
This commit is contained in:
@@ -0,0 +1,70 @@
|
||||
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();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user