UNPKG

alinea

Version:
99 lines (97 loc) 2.7 kB
import { pLimit } from "../../chunks/chunk-C53YJRET.js"; import "../../chunks/chunk-NZLE2WMY.js"; // src/dashboard/boot/DashboardWorker.ts import { getScope } from "alinea/core/Scope"; import { trigger } from "alinea/core/Trigger"; import { IndexEvent } from "alinea/core/db/IndexEvent"; import { LocalDB } from "alinea/core/db/LocalDB"; var MutateEvent = class _MutateEvent extends Event { constructor(id, status, error) { super(_MutateEvent.type); this.id = id; this.status = status; this.error = error; } static type = "mutate"; }; var remote = pLimit(1); var DashboardWorker = class extends EventTarget { #source; #localDB; #localClient; #nextLoad = trigger(); #defer; #currentRevision; constructor(source) { super(); this.#source = source; } get db() { return this.#localDB ?? this.#nextLoad.then((res) => res.db); } get #client() { return this.#localClient ?? this.#nextLoad.then((res) => res.client); } async sync() { const db = await this.db; const client = await this.#client; if (remote.pendingCount > 0) return db.sha; const sync = remote(() => db.syncWith(client)); if (db.index.tree.isEmpty) await sync; return db.sha; } queue(id, mutations) { return remote(async () => { const db = await this.db; await db.mutate(mutations); const intoSha = db.sha; const client = await this.#client; try { const { sha } = await client.mutate(mutations); if (sha !== intoSha) return db.syncWith(client); return intoSha; } catch (error) { await db.syncWith(client); throw error; } }); } async resolve(raw) { const db = await this.db; const scope = getScope(db.config); const query = scope.parse(raw); return db.resolve(query); } async load(revision, config, client) { if (this.#currentRevision === revision) { await this.sync(); return; } this.#currentRevision = revision; const db = new LocalDB(config, this.#source); try { if (this.#defer) this.#defer(); this.#nextLoad.resolve({ db, client }); this.#localDB = db; this.#localClient = client; const listen = (event) => { if (event instanceof IndexEvent) this.dispatchEvent(new IndexEvent(event.data)); }; db.index.addEventListener(IndexEvent.type, listen); this.#defer = () => { db.index.removeEventListener(IndexEvent.type, listen); }; } catch (error) { this.#nextLoad.reject(new Error("Failed to load database")); } finally { this.#nextLoad = trigger(); } } }; export { DashboardWorker, MutateEvent };