commit 2207d29e7d735b8007b9e56738e41897e1d35ba5
parent f4b51b23b0b6f8065b93e08a57c177b35ebe7cf4
Author: triesap <triesap@radroots.dev>
Date: Thu, 20 Nov 2025 15:04:14 +0000
client: add tangle web database client over wasm sql with typed data operations, migration tracking, backup handling, and browser bridges
Diffstat:
5 files changed, 617 insertions(+), 0 deletions(-)
diff --git a/client/package.json b/client/package.json
@@ -49,6 +49,11 @@
"types": "./dist/types/sql/index.d.ts",
"import": "./dist/esm/sql/index.js",
"require": "./dist/cjs/sql/index.js"
+ },
+ "./tangle": {
+ "types": "./dist/types/tangle/index.d.ts",
+ "import": "./dist/esm/tangle/index.js",
+ "require": "./dist/cjs/tangle/index.js"
}
},
"scripts": {
@@ -63,6 +68,7 @@
"dependencies": {
"@radroots/utils": "*",
"@radroots/utils-nostr": "*",
+ "@radroots/tangle-sql-wasm": "*",
"idb": "^8.0.3",
"idb-keyval": "^6.2.1",
"sql.js": "^1.13.0"
diff --git a/client/src/tangle/bridge.ts b/client/src/tangle/bridge.ts
@@ -0,0 +1,30 @@
+import type { SqlJsParams, SqlJsValue } from "../sql/types.js";
+import { WebSqlEngine } from "../sql/web.js";
+
+function parse_sql_params(params_json: string): SqlJsParams {
+ const trimmed = params_json.trim();
+ if (!trimmed) return [];
+ try {
+ const raw = JSON.parse(trimmed) as unknown;
+ if (Array.isArray(raw)) return raw as ReadonlyArray<SqlJsValue>;
+ if (raw && typeof raw === "object") return raw as Readonly<Record<string, SqlJsValue>>;
+ return [];
+ } catch {
+ return [];
+ }
+}
+
+export function radroots_sql_install_bridges(engine: WebSqlEngine): void {
+ Object.assign(globalThis, {
+ __radroots_sql_wasm_exec: (sql: string, params_json: string) => {
+ const params = parse_sql_params(params_json);
+ const res = engine.exec(sql, params);
+ return res;
+ },
+ __radroots_sql_wasm_query: (sql: string, params_json: string) => {
+ const params = parse_sql_params(params_json);
+ const res = engine.query(sql, params);
+ return res;
+ }
+ });
+}
+\ No newline at end of file
diff --git a/client/src/tangle/index.ts b/client/src/tangle/index.ts
@@ -0,0 +1,3 @@
+export * from "./types.js";
+export * from "./web.js";
+
diff --git a/client/src/tangle/types.ts b/client/src/tangle/types.ts
@@ -0,0 +1,136 @@
+import type {
+ IFarmCreate,
+ IFarmCreateResolve,
+ IFarmDelete,
+ IFarmDeleteResolve,
+ IFarmFindMany,
+ IFarmFindManyResolve,
+ IFarmFindOne,
+ IFarmFindOneResolve,
+ IFarmLocationRelation,
+ IFarmLocationResolve,
+ IFarmUpdate,
+ IFarmUpdateResolve,
+ ILocationGcsCreate,
+ ILocationGcsCreateResolve,
+ ILocationGcsDelete,
+ ILocationGcsDeleteResolve,
+ ILocationGcsFindMany,
+ ILocationGcsFindManyResolve,
+ ILocationGcsFindOne,
+ ILocationGcsFindOneResolve,
+ ILocationGcsUpdate,
+ ILocationGcsUpdateResolve,
+ ILogErrorCreate,
+ ILogErrorCreateResolve,
+ ILogErrorDelete,
+ ILogErrorDeleteResolve,
+ ILogErrorFindMany,
+ ILogErrorFindManyResolve,
+ ILogErrorFindOne,
+ ILogErrorFindOneResolve,
+ ILogErrorUpdate,
+ ILogErrorUpdateResolve,
+ IMediaImageCreate,
+ IMediaImageCreateResolve,
+ IMediaImageDelete,
+ IMediaImageDeleteResolve,
+ IMediaImageFindMany,
+ IMediaImageFindManyResolve,
+ IMediaImageFindOne,
+ IMediaImageFindOneResolve,
+ IMediaImageUpdate,
+ IMediaImageUpdateResolve,
+ INostrProfileCreate,
+ INostrProfileCreateResolve,
+ INostrProfileDelete,
+ INostrProfileDeleteResolve,
+ INostrProfileFindMany,
+ INostrProfileFindManyResolve,
+ INostrProfileFindOne,
+ INostrProfileFindOneResolve,
+ INostrProfileRelayRelation,
+ INostrProfileRelayResolve,
+ INostrProfileUpdate,
+ INostrProfileUpdateResolve,
+ INostrRelayCreate,
+ INostrRelayCreateResolve,
+ INostrRelayDelete,
+ INostrRelayDeleteResolve,
+ INostrRelayFindMany,
+ INostrRelayFindManyResolve,
+ INostrRelayFindOne,
+ INostrRelayFindOneResolve,
+ INostrRelayUpdate,
+ INostrRelayUpdateResolve,
+ ITradeProductCreate,
+ ITradeProductCreateResolve,
+ ITradeProductDelete,
+ ITradeProductDeleteResolve,
+ ITradeProductFindMany,
+ ITradeProductFindManyResolve,
+ ITradeProductFindOne,
+ ITradeProductFindOneResolve,
+ ITradeProductLocationRelation,
+ ITradeProductLocationResolve,
+ ITradeProductMediaRelation,
+ ITradeProductMediaResolve,
+ ITradeProductUpdate,
+ ITradeProductUpdateResolve
+} from "@radroots/tangle-schema-bindings";
+import type { IError } from "@radroots/types-bindings";
+import { type SqlJsMigrationState } from "../sql/types.js";
+import type { TangleDatabaseBackup } from "./web.js";
+
+export interface IClientTangleDatabase {
+ init(): Promise<void>;
+ migration_state(): Promise<SqlJsMigrationState>;
+ reset(): Promise<SqlJsMigrationState>;
+ reinit(): Promise<SqlJsMigrationState>;
+ get_store_key(): string;
+ export_backup(): Promise<TangleDatabaseBackup>;
+ import_backup(backup: TangleDatabaseBackup): Promise<void>;
+ farm_create(opts: IFarmCreate): Promise<IFarmCreateResolve | IError<string>>;
+ farm_find_one(opts: IFarmFindOne): Promise<IFarmFindOneResolve | IError<string>>;
+ farm_find_many(opts?: IFarmFindMany): Promise<IFarmFindManyResolve | IError<string>>;
+ farm_delete(opts: IFarmDelete): Promise<IFarmDeleteResolve | IError<string>>;
+ farm_update(opts: IFarmUpdate): Promise<IFarmUpdateResolve | IError<string>>;
+ location_gcs_create(opts: ILocationGcsCreate): Promise<ILocationGcsCreateResolve | IError<string>>;
+ location_gcs_find_one(opts: ILocationGcsFindOne): Promise<ILocationGcsFindOneResolve | IError<string>>;
+ location_gcs_find_many(opts?: ILocationGcsFindMany): Promise<ILocationGcsFindManyResolve | IError<string>>;
+ location_gcs_delete(opts: ILocationGcsDelete): Promise<ILocationGcsDeleteResolve | IError<string>>;
+ location_gcs_update(opts: ILocationGcsUpdate): Promise<ILocationGcsUpdateResolve | IError<string>>;
+ log_error_create(opts: ILogErrorCreate): Promise<ILogErrorCreateResolve | IError<string>>;
+ log_error_find_one(opts: ILogErrorFindOne): Promise<ILogErrorFindOneResolve | IError<string>>;
+ log_error_find_many(opts?: ILogErrorFindMany): Promise<ILogErrorFindManyResolve | IError<string>>;
+ log_error_delete(opts: ILogErrorDelete): Promise<ILogErrorDeleteResolve | IError<string>>;
+ log_error_update(opts: ILogErrorUpdate): Promise<ILogErrorUpdateResolve | IError<string>>;
+ media_image_create(opts: IMediaImageCreate): Promise<IMediaImageCreateResolve | IError<string>>;
+ media_image_find_one(opts: IMediaImageFindOne): Promise<IMediaImageFindOneResolve | IError<string>>;
+ media_image_find_many(opts?: IMediaImageFindMany): Promise<IMediaImageFindManyResolve | IError<string>>;
+ media_image_delete(opts: IMediaImageDelete): Promise<IMediaImageDeleteResolve | IError<string>>;
+ media_image_update(opts: IMediaImageUpdate): Promise<IMediaImageUpdateResolve | IError<string>>;
+ nostr_profile_create(opts: INostrProfileCreate): Promise<INostrProfileCreateResolve | IError<string>>;
+ nostr_profile_find_one(opts: INostrProfileFindOne): Promise<INostrProfileFindOneResolve | IError<string>>;
+ nostr_profile_find_many(opts?: INostrProfileFindMany): Promise<INostrProfileFindManyResolve | IError<string>>;
+ nostr_profile_delete(opts: INostrProfileDelete): Promise<INostrProfileDeleteResolve | IError<string>>;
+ nostr_profile_update(opts: INostrProfileUpdate): Promise<INostrProfileUpdateResolve | IError<string>>;
+ nostr_relay_create(opts: INostrRelayCreate): Promise<INostrRelayCreateResolve | IError<string>>;
+ nostr_relay_find_one(opts: INostrRelayFindOne): Promise<INostrRelayFindOneResolve | IError<string>>;
+ nostr_relay_find_many(opts?: INostrRelayFindMany): Promise<INostrRelayFindManyResolve | IError<string>>;
+ nostr_relay_delete(opts: INostrRelayDelete): Promise<INostrRelayDeleteResolve | IError<string>>;
+ nostr_relay_update(opts: INostrRelayUpdate): Promise<INostrRelayUpdateResolve | IError<string>>;
+ trade_product_create(opts: ITradeProductCreate): Promise<ITradeProductCreateResolve | IError<string>>;
+ trade_product_find_one(opts: ITradeProductFindOne): Promise<ITradeProductFindOneResolve | IError<string>>;
+ trade_product_find_many(opts?: ITradeProductFindMany): Promise<ITradeProductFindManyResolve | IError<string>>;
+ trade_product_delete(opts: ITradeProductDelete): Promise<ITradeProductDeleteResolve | IError<string>>;
+ trade_product_update(opts: ITradeProductUpdate): Promise<ITradeProductUpdateResolve | IError<string>>;
+ farm_location_set(opts: IFarmLocationRelation): Promise<IFarmLocationResolve | IError<string>>;
+ farm_location_unset(opts: IFarmLocationRelation): Promise<IFarmLocationResolve | IError<string>>;
+ nostr_profile_relay_set(opts: INostrProfileRelayRelation): Promise<INostrProfileRelayResolve | IError<string>>;
+ nostr_profile_relay_unset(opts: INostrProfileRelayRelation): Promise<INostrProfileRelayResolve | IError<string>>;
+ trade_product_location_set(opts: ITradeProductLocationRelation): Promise<ITradeProductLocationResolve | IError<string>>;
+ trade_product_location_unset(opts: ITradeProductLocationRelation): Promise<ITradeProductLocationResolve | IError<string>>;
+ trade_product_media_set(opts: ITradeProductMediaRelation): Promise<ITradeProductMediaResolve | IError<string>>;
+ trade_product_media_unset(opts: ITradeProductMediaRelation): Promise<ITradeProductMediaResolve | IError<string>>;
+}
diff --git a/client/src/tangle/web.ts b/client/src/tangle/web.ts
@@ -0,0 +1,441 @@
+import type {
+ IFarmCreate,
+ IFarmCreateResolve,
+ IFarmDelete,
+ IFarmDeleteResolve,
+ IFarmFindMany,
+ IFarmFindManyResolve,
+ IFarmFindOne,
+ IFarmFindOneResolve,
+ IFarmLocationRelation,
+ IFarmLocationResolve,
+ IFarmUpdate,
+ IFarmUpdateResolve,
+ ILocationGcsCreate,
+ ILocationGcsCreateResolve,
+ ILocationGcsDelete,
+ ILocationGcsDeleteResolve,
+ ILocationGcsFindMany,
+ ILocationGcsFindManyResolve,
+ ILocationGcsFindOne,
+ ILocationGcsFindOneResolve,
+ ILocationGcsUpdate,
+ ILocationGcsUpdateResolve,
+ ILogErrorCreate,
+ ILogErrorCreateResolve,
+ ILogErrorDelete,
+ ILogErrorDeleteResolve,
+ ILogErrorFindMany,
+ ILogErrorFindManyResolve,
+ ILogErrorFindOne,
+ ILogErrorFindOneResolve,
+ ILogErrorUpdate,
+ ILogErrorUpdateResolve,
+ IMediaImageCreate,
+ IMediaImageCreateResolve,
+ IMediaImageDelete,
+ IMediaImageDeleteResolve,
+ IMediaImageFindMany,
+ IMediaImageFindManyResolve,
+ IMediaImageFindOne,
+ IMediaImageFindOneResolve,
+ IMediaImageUpdate,
+ IMediaImageUpdateResolve,
+ INostrProfileCreate,
+ INostrProfileCreateResolve,
+ INostrProfileDelete,
+ INostrProfileDeleteResolve,
+ INostrProfileFindMany,
+ INostrProfileFindManyResolve,
+ INostrProfileFindOne,
+ INostrProfileFindOneResolve,
+ INostrProfileRelayRelation,
+ INostrProfileRelayResolve,
+ INostrProfileUpdate,
+ INostrProfileUpdateResolve,
+ INostrRelayCreate,
+ INostrRelayCreateResolve,
+ INostrRelayDelete,
+ INostrRelayDeleteResolve,
+ INostrRelayFindMany,
+ INostrRelayFindManyResolve,
+ INostrRelayFindOne,
+ INostrRelayFindOneResolve,
+ INostrRelayUpdate,
+ INostrRelayUpdateResolve,
+ ITradeProductCreate,
+ ITradeProductCreateResolve,
+ ITradeProductDelete,
+ ITradeProductDeleteResolve,
+ ITradeProductFindMany,
+ ITradeProductFindManyResolve,
+ ITradeProductFindOne,
+ ITradeProductFindOneResolve,
+ ITradeProductLocationRelation,
+ ITradeProductLocationResolve,
+ ITradeProductMediaRelation,
+ ITradeProductMediaResolve,
+ ITradeProductUpdate,
+ ITradeProductUpdateResolve
+} from "@radroots/tangle-schema-bindings";
+import init_wasm, {
+ query_sql,
+ tangle_db_export_backup,
+ tangle_db_farm_create,
+ tangle_db_farm_delete,
+ tangle_db_farm_find_many,
+ tangle_db_farm_find_one,
+ tangle_db_farm_location_set,
+ tangle_db_farm_location_unset,
+ tangle_db_farm_update,
+ tangle_db_import_backup,
+ tangle_db_location_gcs_create,
+ tangle_db_location_gcs_delete,
+ tangle_db_location_gcs_find_many,
+ tangle_db_location_gcs_find_one,
+ tangle_db_location_gcs_update,
+ tangle_db_log_error_create,
+ tangle_db_log_error_delete,
+ tangle_db_log_error_find_many,
+ tangle_db_log_error_find_one,
+ tangle_db_log_error_update,
+ tangle_db_media_image_create,
+ tangle_db_media_image_delete,
+ tangle_db_media_image_find_many,
+ tangle_db_media_image_find_one,
+ tangle_db_media_image_update,
+ tangle_db_nostr_profile_create,
+ tangle_db_nostr_profile_delete,
+ tangle_db_nostr_profile_find_many,
+ tangle_db_nostr_profile_find_one,
+ tangle_db_nostr_profile_relay_set,
+ tangle_db_nostr_profile_relay_unset,
+ tangle_db_nostr_profile_update,
+ tangle_db_nostr_relay_create,
+ tangle_db_nostr_relay_delete,
+ tangle_db_nostr_relay_find_many,
+ tangle_db_nostr_relay_find_one,
+ tangle_db_nostr_relay_update,
+ tangle_db_reset_database,
+ tangle_db_run_migrations,
+ tangle_db_trade_product_create,
+ tangle_db_trade_product_delete,
+ tangle_db_trade_product_find_many,
+ tangle_db_trade_product_find_one,
+ tangle_db_trade_product_location_set,
+ tangle_db_trade_product_location_unset,
+ tangle_db_trade_product_media_set,
+ tangle_db_trade_product_media_unset,
+ tangle_db_trade_product_update
+} from "@radroots/tangle-sql-wasm";
+import type { IError } from "@radroots/types-bindings";
+import { type IdbClientConfig } from "@radroots/utils";
+import type { SqlJsMigrationRow, SqlJsMigrationState } from "../sql/types.js";
+import { WebSqlEngine, } from "../sql/web.js";
+import { radroots_sql_install_bridges } from "./bridge.js";
+import type { IClientTangleDatabase } from "./types.js";
+
+export type TangleDatabaseBackup = {
+ format_version: string;
+ tangle_sql_version: string;
+ schema: {
+ object_type: string;
+ name: string;
+ table_name?: string;
+ sql?: string;
+ }[];
+ data: {
+ name: string;
+ rows: Record<string, unknown>[];
+ }[];
+ migrations: {
+ name: string;
+ up_sql: string;
+ down_sql: string;
+ }[];
+};
+
+export class WebTangleDatabase implements IClientTangleDatabase {
+ private engine: WebSqlEngine | null = null;
+ private readonly store_key: string = "radroots.tangle-db-v1.key";;
+ private cipher_config: IdbClientConfig | null = null;
+
+ constructor(config?: {
+ store_key?: string;
+ cipher?: IdbClientConfig;
+ }) {
+ if (config?.store_key) this.store_key = config?.store_key;
+ if (config?.cipher) this.cipher_config = config.cipher;
+ }
+
+ get_store_key(): string {
+ return this.store_key;
+ }
+
+ private serialize<T>(opts: T): string {
+ return JSON.stringify(opts);
+ }
+
+ private deserialize<T>(data: string): T {
+ return JSON.parse(data);
+ }
+
+ async init(): Promise<void> {
+ if (this.engine) return;
+ await init_wasm();
+ this.engine = await WebSqlEngine.create(this.store_key, this.cipher_config);
+ radroots_sql_install_bridges(this.engine);
+ tangle_db_run_migrations();
+ }
+
+ async migration_state(): Promise<SqlJsMigrationState> {
+ const res = await query_sql("select id, name, applied_at from __migrations order by id asc", "[]");
+ const rows = (typeof res === "string" ? JSON.parse(res) : res) as SqlJsMigrationRow[];
+ const names = rows.map((r) => r.name);
+ return { applied_names: names, applied_count: names.length };
+ }
+
+ async reset(): Promise<SqlJsMigrationState> {
+ tangle_db_reset_database();
+ tangle_db_run_migrations();
+ return this.migration_state();
+ }
+
+ async reinit(): Promise<SqlJsMigrationState> {
+ if (this.engine) {
+ await this.engine.purge_storage();
+ await this.engine.close();
+ }
+ this.engine = await WebSqlEngine.create(this.store_key, this.cipher_config);
+ radroots_sql_install_bridges(this.engine);
+ tangle_db_run_migrations();
+ return this.migration_state();
+ }
+
+ async export_backup(): Promise<TangleDatabaseBackup> {
+ await this.init();
+ const res = await tangle_db_export_backup();
+ return (typeof res === "string" ? JSON.parse(res) : res) as TangleDatabaseBackup;
+ }
+
+ async import_backup(backup: TangleDatabaseBackup): Promise<void> {
+ await this.init();
+ await tangle_db_import_backup(this.serialize(backup));
+ }
+
+ async farm_create(opts: IFarmCreate): Promise<IFarmCreateResolve | IError<string>> {
+ const res = await tangle_db_farm_create(this.serialize(opts));
+ return this.deserialize<IFarmCreateResolve>(res);
+ }
+
+ async farm_find_one(opts: IFarmFindOne): Promise<IFarmFindOneResolve | IError<string>> {
+ const res = await tangle_db_farm_find_one(this.serialize(opts));
+ return this.deserialize<IFarmFindOneResolve>(res);
+ }
+
+ async farm_find_many(opts?: IFarmFindMany): Promise<IFarmFindManyResolve | IError<string>> {
+ const res = await tangle_db_farm_find_many(this.serialize(opts ?? {}));
+ return this.deserialize<IFarmFindManyResolve>(res);
+ }
+
+ async farm_delete(opts: IFarmDelete): Promise<IFarmDeleteResolve | IError<string>> {
+ const res = await tangle_db_farm_delete(this.serialize(opts));
+ return this.deserialize<IFarmDeleteResolve>(res);
+ }
+
+ async farm_update(opts: IFarmUpdate): Promise<IFarmUpdateResolve | IError<string>> {
+ const res = await tangle_db_farm_update(this.serialize(opts));
+ return this.deserialize<IFarmUpdateResolve>(res);
+ }
+
+ async location_gcs_create(opts: ILocationGcsCreate): Promise<ILocationGcsCreateResolve | IError<string>> {
+ const res = await tangle_db_location_gcs_create(this.serialize(opts));
+ return this.deserialize<ILocationGcsCreateResolve>(res);
+ }
+
+ async location_gcs_find_one(opts: ILocationGcsFindOne): Promise<ILocationGcsFindOneResolve | IError<string>> {
+ const res = await tangle_db_location_gcs_find_one(this.serialize(opts));
+ return this.deserialize<ILocationGcsFindOneResolve>(res);
+ }
+
+ async location_gcs_find_many(opts?: ILocationGcsFindMany): Promise<ILocationGcsFindManyResolve | IError<string>> {
+ const res = await tangle_db_location_gcs_find_many(this.serialize(opts ?? {}));
+ return this.deserialize<ILocationGcsFindManyResolve>(res);
+ }
+
+ async location_gcs_delete(opts: ILocationGcsDelete): Promise<ILocationGcsDeleteResolve | IError<string>> {
+ const res = await tangle_db_location_gcs_delete(this.serialize(opts));
+ return this.deserialize<ILocationGcsDeleteResolve>(res);
+ }
+
+ async location_gcs_update(opts: ILocationGcsUpdate): Promise<ILocationGcsUpdateResolve | IError<string>> {
+ const res = await tangle_db_location_gcs_update(this.serialize(opts));
+ return this.deserialize<ILocationGcsUpdateResolve>(res);
+ }
+
+ async log_error_create(opts: ILogErrorCreate): Promise<ILogErrorCreateResolve | IError<string>> {
+ const res = await tangle_db_log_error_create(this.serialize(opts));
+ return this.deserialize<ILogErrorCreateResolve>(res);
+ }
+
+ async log_error_find_one(opts: ILogErrorFindOne): Promise<ILogErrorFindOneResolve | IError<string>> {
+ const res = await tangle_db_log_error_find_one(this.serialize(opts));
+ return this.deserialize<ILogErrorFindOneResolve>(res);
+ }
+
+ async log_error_find_many(opts?: ILogErrorFindMany): Promise<ILogErrorFindManyResolve | IError<string>> {
+ const res = await tangle_db_log_error_find_many(this.serialize(opts ?? {}));
+ return this.deserialize<ILogErrorFindManyResolve>(res);
+ }
+
+ async log_error_delete(opts: ILogErrorDelete): Promise<ILogErrorDeleteResolve | IError<string>> {
+ const res = await tangle_db_log_error_delete(this.serialize(opts));
+ return this.deserialize<ILogErrorDeleteResolve>(res);
+ }
+
+ async log_error_update(opts: ILogErrorUpdate): Promise<ILogErrorUpdateResolve | IError<string>> {
+ const res = await tangle_db_log_error_update(this.serialize(opts));
+ return this.deserialize<ILogErrorUpdateResolve>(res);
+ }
+
+ async media_image_create(opts: IMediaImageCreate): Promise<IMediaImageCreateResolve | IError<string>> {
+ const res = await tangle_db_media_image_create(this.serialize(opts));
+ return this.deserialize<IMediaImageCreateResolve>(res);
+ }
+
+ async media_image_find_one(opts: IMediaImageFindOne): Promise<IMediaImageFindOneResolve | IError<string>> {
+ const res = await tangle_db_media_image_find_one(this.serialize(opts));
+ return this.deserialize<IMediaImageFindOneResolve>(res);
+ }
+
+ async media_image_find_many(opts?: IMediaImageFindMany): Promise<IMediaImageFindManyResolve | IError<string>> {
+ const res = await tangle_db_media_image_find_many(this.serialize(opts ?? {}));
+ return this.deserialize<IMediaImageFindManyResolve>(res);
+ }
+
+ async media_image_delete(opts: IMediaImageDelete): Promise<IMediaImageDeleteResolve | IError<string>> {
+ const res = await tangle_db_media_image_delete(this.serialize(opts));
+ return this.deserialize<IMediaImageDeleteResolve>(res);
+ }
+
+ async media_image_update(opts: IMediaImageUpdate): Promise<IMediaImageUpdateResolve | IError<string>> {
+ const res = await tangle_db_media_image_update(this.serialize(opts));
+ return this.deserialize<IMediaImageUpdateResolve>(res);
+ }
+
+ async nostr_profile_create(opts: INostrProfileCreate): Promise<INostrProfileCreateResolve | IError<string>> {
+ const res = await tangle_db_nostr_profile_create(this.serialize(opts));
+ return this.deserialize<INostrProfileCreateResolve>(res);
+ }
+
+ async nostr_profile_find_one(opts: INostrProfileFindOne): Promise<INostrProfileFindOneResolve | IError<string>> {
+ const res = await tangle_db_nostr_profile_find_one(this.serialize(opts));
+ return this.deserialize<INostrProfileFindOneResolve>(res);
+ }
+
+ async nostr_profile_find_many(opts?: INostrProfileFindMany): Promise<INostrProfileFindManyResolve | IError<string>> {
+ const res = await tangle_db_nostr_profile_find_many(this.serialize(opts ?? {}));
+ return this.deserialize<INostrProfileFindManyResolve>(res);
+ }
+
+ async nostr_profile_delete(opts: INostrProfileDelete): Promise<INostrProfileDeleteResolve | IError<string>> {
+ const res = await tangle_db_nostr_profile_delete(this.serialize(opts));
+ return this.deserialize<INostrProfileDeleteResolve>(res);
+ }
+
+ async nostr_profile_update(opts: INostrProfileUpdate): Promise<INostrProfileUpdateResolve | IError<string>> {
+ const res = await tangle_db_nostr_profile_update(this.serialize(opts));
+ return this.deserialize<INostrProfileUpdateResolve>(res);
+ }
+
+ async nostr_relay_create(opts: INostrRelayCreate): Promise<INostrRelayCreateResolve | IError<string>> {
+ const res = await tangle_db_nostr_relay_create(this.serialize(opts));
+ return this.deserialize<INostrRelayCreateResolve>(res);
+ }
+
+ async nostr_relay_find_one(opts: INostrRelayFindOne): Promise<INostrRelayFindOneResolve | IError<string>> {
+ const res = await tangle_db_nostr_relay_find_one(this.serialize(opts));
+ return this.deserialize<INostrRelayFindOneResolve>(res);
+ }
+
+ async nostr_relay_find_many(opts?: INostrRelayFindMany): Promise<INostrRelayFindManyResolve | IError<string>> {
+ const res = await tangle_db_nostr_relay_find_many(this.serialize(opts ?? {}));
+ return this.deserialize<INostrRelayFindManyResolve>(res);
+ }
+
+ async nostr_relay_delete(opts: INostrRelayDelete): Promise<INostrRelayDeleteResolve | IError<string>> {
+ const res = await tangle_db_nostr_relay_delete(this.serialize(opts));
+ return this.deserialize<INostrRelayDeleteResolve>(res);
+ }
+
+ async nostr_relay_update(opts: INostrRelayUpdate): Promise<INostrRelayUpdateResolve | IError<string>> {
+ const res = await tangle_db_nostr_relay_update(this.serialize(opts));
+ return this.deserialize<INostrRelayUpdateResolve>(res);
+ }
+
+ async trade_product_create(opts: ITradeProductCreate): Promise<ITradeProductCreateResolve | IError<string>> {
+ const res = await tangle_db_trade_product_create(this.serialize(opts));
+ return this.deserialize<ITradeProductCreateResolve>(res);
+ }
+
+ async trade_product_find_one(opts: ITradeProductFindOne): Promise<ITradeProductFindOneResolve | IError<string>> {
+ const res = await tangle_db_trade_product_find_one(this.serialize(opts));
+ return this.deserialize<ITradeProductFindOneResolve>(res);
+ }
+
+ async trade_product_find_many(opts?: ITradeProductFindMany): Promise<ITradeProductFindManyResolve | IError<string>> {
+ const res = await tangle_db_trade_product_find_many(this.serialize(opts ?? {}));
+ return this.deserialize<ITradeProductFindManyResolve>(res);
+ }
+
+ async trade_product_delete(opts: ITradeProductDelete): Promise<ITradeProductDeleteResolve | IError<string>> {
+ const res = await tangle_db_trade_product_delete(this.serialize(opts));
+ return this.deserialize<ITradeProductDeleteResolve>(res);
+ }
+
+ async trade_product_update(opts: ITradeProductUpdate): Promise<ITradeProductUpdateResolve | IError<string>> {
+ const res = await tangle_db_trade_product_update(this.serialize(opts));
+ return this.deserialize<ITradeProductUpdateResolve>(res);
+ }
+
+ async farm_location_set(opts: IFarmLocationRelation): Promise<IFarmLocationResolve | IError<string>> {
+ const res = await tangle_db_farm_location_set(this.serialize(opts));
+ return this.deserialize<IFarmLocationResolve>(res);
+ }
+
+ async farm_location_unset(opts: IFarmLocationRelation): Promise<IFarmLocationResolve | IError<string>> {
+ const res = await tangle_db_farm_location_unset(this.serialize(opts));
+ return this.deserialize<IFarmLocationResolve>(res);
+ }
+
+ async nostr_profile_relay_set(opts: INostrProfileRelayRelation): Promise<INostrProfileRelayResolve | IError<string>> {
+ const res = await tangle_db_nostr_profile_relay_set(this.serialize(opts));
+ return this.deserialize<INostrProfileRelayResolve>(res);
+ }
+
+ async nostr_profile_relay_unset(opts: INostrProfileRelayRelation): Promise<INostrProfileRelayResolve | IError<string>> {
+ const res = await tangle_db_nostr_profile_relay_unset(this.serialize(opts));
+ return this.deserialize<INostrProfileRelayResolve>(res);
+ }
+
+ async trade_product_location_set(opts: ITradeProductLocationRelation): Promise<ITradeProductLocationResolve | IError<string>> {
+ const res = await tangle_db_trade_product_location_set(this.serialize(opts));
+ return this.deserialize<ITradeProductLocationResolve>(res);
+ }
+
+ async trade_product_location_unset(opts: ITradeProductLocationRelation): Promise<ITradeProductLocationResolve | IError<string>> {
+ const res = await tangle_db_trade_product_location_unset(this.serialize(opts));
+ return this.deserialize<ITradeProductLocationResolve>(res);
+ }
+
+ async trade_product_media_set(opts: ITradeProductMediaRelation): Promise<ITradeProductMediaResolve | IError<string>> {
+ const res = await tangle_db_trade_product_media_set(this.serialize(opts));
+ return this.deserialize<ITradeProductMediaResolve>(res);
+ }
+
+ async trade_product_media_unset(opts: ITradeProductMediaRelation): Promise<ITradeProductMediaResolve | IError<string>> {
+ const res = await tangle_db_trade_product_media_unset(this.serialize(opts));
+ return this.deserialize<ITradeProductMediaResolve>(res);
+ }
+
+}