UNPKG

@anysoftinc/anydb-sdk

Version:

AnyDB TypeScript SDK for querying and transacting with Datomic databases

114 lines (113 loc) 4.32 kB
import { stringifyEdn } from "./client"; // Load the DataScript backend if available let datascriptBackend = null; try { // Try to load the compiled DataScript module (shipped alongside dist output) datascriptBackend = globalThis.anydbDatascript || require("./anydb.datascript.core.js"); } catch (e) { console.warn("DataScript backend not available. Run `npx shadow-cljs compile datascript` to enable client-only development mode."); } export class DataScriptBackend { constructor(storageAlias, dbName) { this.dbAlias = `${storageAlias}/${dbName}`; if (!datascriptBackend) { throw new Error("DataScript backend not loaded. Please compile ClojureScript modules first."); } } // Database management async listDatabases() { if (!datascriptBackend) throw new Error("DataScript backend not available"); return datascriptBackend.listDatabases(); } async createDatabase() { if (!datascriptBackend) throw new Error("DataScript backend not available"); return datascriptBackend.createDatabase(this.dbAlias); } async deleteDatabase() { if (!datascriptBackend) throw new Error("DataScript backend not available"); return datascriptBackend.deleteDatabase(this.dbAlias); } // Transaction operations async transact(txData) { if (!datascriptBackend) throw new Error("DataScript backend not available"); const txDataEdn = stringifyEdn(txData); const result = datascriptBackend.transactData(this.dbAlias, txDataEdn); // Convert to match Datomic API format return { "db-before": { "basis-t": -1, "db/alias": this.dbAlias }, "db-after": { "basis-t": -1, "db/alias": this.dbAlias }, "tx-data": result["tx-data"] || [], tempids: result.tempids || {}, }; } // Query operations async query(query, ...args) { if (!datascriptBackend) throw new Error("DataScript backend not available"); const queryEdn = stringifyEdn(query); const argsEdn = args.map((arg) => stringifyEdn(arg)); return datascriptBackend.queryData(queryEdn, this.dbAlias, ...argsEdn); } // Entity operations async entity(entityId) { if (!datascriptBackend) throw new Error("DataScript backend not available"); const entity = datascriptBackend.getEntity(this.dbAlias, entityId); // Ensure db/id is present if (entity && !entity["db/id"]) { entity["db/id"] = entityId; } return entity; } // Datoms operations async datoms(index, options = {}) { if (!datascriptBackend) throw new Error("DataScript backend not available"); const components = []; if (options.e !== undefined) components.push(options.e); if (options.a !== undefined) components.push(options.a); if (options.v !== undefined) components.push(options.v); let datoms = datascriptBackend.getDatoms(this.dbAlias, index, ...components); // Apply client-side limit/offset since DataScript doesn't have built-in pagination if (options.offset) { datoms = datoms.slice(options.offset); } if (options.limit) { datoms = datoms.slice(0, options.limit); } // Convert to Datomic datom format return datoms.map((d) => ({ e: d.e || d[0], a: d.a || d[1], v: d.v || d[2], tx: d.tx || d[3], added: d.added !== false, // Default to true })); } // Database info (mock for compatibility) async databaseInfo() { return { "basis-t": -1, // DataScript doesn't have basis-t concept "db/alias": this.dbAlias, }; } } // Utility to check if DataScript backend is available export function isDataScriptAvailable() { return datascriptBackend !== null; } // Utility to detect if we should use DataScript backend export function shouldUseDataScript(storageAlias) { // Explicit opt-in: use DataScript when storage alias is exactly "datascript" return storageAlias === "datascript"; }