@ereo/db-surrealdb 0.1.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,76 @@
1
+ /**
2
+ * @ereo/db-surrealdb - SurrealDB Adapter Implementation
3
+ *
4
+ * Implements the DatabaseAdapter interface for SurrealDB.
5
+ */
6
+ import { type DatabaseAdapter } from '@ereo/db';
7
+ import type { SurrealDBConfig } from './types';
8
+ /**
9
+ * SurrealDB client interface.
10
+ * This matches the API from the 'surrealdb' package.
11
+ */
12
+ interface SurrealClient {
13
+ connect(url: string): Promise<void>;
14
+ close(): Promise<void>;
15
+ use(params: {
16
+ namespace: string;
17
+ database: string;
18
+ }): Promise<void>;
19
+ signin(credentials: Record<string, unknown>): Promise<string>;
20
+ query<T = unknown>(sql: string, vars?: Record<string, unknown>): Promise<T[]>;
21
+ select<T = unknown>(thing: string): Promise<T[]>;
22
+ create<T = unknown>(thing: string, data?: Record<string, unknown>): Promise<T>;
23
+ insert<T = unknown>(thing: string, data?: Record<string, unknown> | Record<string, unknown>[]): Promise<T[]>;
24
+ update<T = unknown>(thing: string, data?: Record<string, unknown>): Promise<T>;
25
+ merge<T = unknown>(thing: string, data?: Record<string, unknown>): Promise<T>;
26
+ patch<T = unknown>(thing: string, data?: unknown[]): Promise<T>;
27
+ delete<T = unknown>(thing: string): Promise<T>;
28
+ }
29
+ /**
30
+ * Create a SurrealDB database adapter.
31
+ *
32
+ * @param config - SurrealDB configuration
33
+ * @returns A configured DatabaseAdapter instance
34
+ *
35
+ * @example
36
+ * import { createSurrealAdapter } from '@ereo/db-surrealdb';
37
+ * import { createDatabasePlugin } from '@ereo/db';
38
+ *
39
+ * const adapter = createSurrealAdapter({
40
+ * url: 'http://localhost:8000',
41
+ * namespace: 'test',
42
+ * database: 'test',
43
+ * auth: {
44
+ * username: 'root',
45
+ * password: 'root',
46
+ * },
47
+ * });
48
+ *
49
+ * export default defineConfig({
50
+ * plugins: [createDatabasePlugin(adapter)],
51
+ * });
52
+ */
53
+ export declare function createSurrealAdapter(config: SurrealDBConfig): DatabaseAdapter<SurrealClient>;
54
+ /**
55
+ * Create a SurrealQL SELECT query.
56
+ */
57
+ export declare function select(table: string, options?: {
58
+ where?: string;
59
+ orderBy?: string;
60
+ limit?: number;
61
+ start?: number;
62
+ }): string;
63
+ /**
64
+ * Create a SurrealQL CREATE query.
65
+ */
66
+ export declare function create(table: string, id?: string): string;
67
+ /**
68
+ * Create a SurrealQL UPDATE query.
69
+ */
70
+ export declare function update(table: string, id?: string): string;
71
+ /**
72
+ * Create a SurrealQL DELETE query.
73
+ */
74
+ export declare function deleteFrom(table: string, id?: string): string;
75
+ export type { SurrealClient };
76
+ //# sourceMappingURL=adapter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../src/adapter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,108 @@
1
+ /**
2
+ * @ereo/db-surrealdb - Configuration Helpers
3
+ *
4
+ * Type-safe configuration builders for SurrealDB adapter.
5
+ */
6
+ import type { SurrealDBConfig, RootAuth, NamespaceAuth, DatabaseAuth, RecordAccessAuth } from './types';
7
+ /**
8
+ * Type-safe configuration builder for SurrealDB adapter.
9
+ *
10
+ * @example
11
+ * const config = defineSurrealConfig({
12
+ * url: 'http://localhost:8000',
13
+ * namespace: 'test',
14
+ * database: 'test',
15
+ * auth: {
16
+ * username: 'root',
17
+ * password: 'root',
18
+ * },
19
+ * });
20
+ */
21
+ export declare function defineSurrealConfig(config: SurrealDBConfig): SurrealDBConfig;
22
+ /**
23
+ * Create root-level authentication credentials.
24
+ *
25
+ * @example
26
+ * const auth = rootAuth('root', 'surrealdb');
27
+ */
28
+ export declare function rootAuth(username: string, password: string): RootAuth;
29
+ /**
30
+ * Create namespace-level authentication credentials.
31
+ *
32
+ * @example
33
+ * const auth = namespaceAuth('myns', 'admin', 'password');
34
+ */
35
+ export declare function namespaceAuth(namespace: string, username: string, password: string): NamespaceAuth;
36
+ /**
37
+ * Create database-level authentication credentials.
38
+ *
39
+ * @example
40
+ * const auth = databaseAuth('myns', 'mydb', 'admin', 'password');
41
+ */
42
+ export declare function databaseAuth(namespace: string, database: string, username: string, password: string): DatabaseAuth;
43
+ /**
44
+ * Create record access authentication (SurrealDB 2.x+).
45
+ *
46
+ * @example
47
+ * const auth = recordAccessAuth('myns', 'mydb', 'user', {
48
+ * email: 'user@example.com',
49
+ * password: 'secret',
50
+ * });
51
+ */
52
+ export declare function recordAccessAuth(namespace: string, database: string, access: string, variables?: Record<string, unknown>): RecordAccessAuth;
53
+ /**
54
+ * Build a SurrealDB connection URL.
55
+ *
56
+ * @example
57
+ * const url = buildSurrealUrl('localhost', 8000, 'http');
58
+ * // => 'http://localhost:8000'
59
+ */
60
+ export declare function buildSurrealUrl(host: string, port?: number, protocol?: 'http' | 'https' | 'ws' | 'wss'): string;
61
+ /**
62
+ * Parse a SurrealDB connection URL into components.
63
+ */
64
+ export declare function parseSurrealUrl(url: string): {
65
+ protocol: string;
66
+ host: string;
67
+ port: number;
68
+ path: string;
69
+ };
70
+ /**
71
+ * Create a local development configuration.
72
+ *
73
+ * @example
74
+ * const config = localConfig('test', 'test');
75
+ */
76
+ export declare function localConfig(namespace: string, database: string, options?: Partial<SurrealDBConfig>): SurrealDBConfig;
77
+ /**
78
+ * Create a cloud/production configuration.
79
+ *
80
+ * @example
81
+ * const config = cloudConfig(
82
+ * 'https://cloud.surrealdb.com',
83
+ * 'production',
84
+ * 'mydb',
85
+ * rootAuth('user', 'password')
86
+ * );
87
+ */
88
+ export declare function cloudConfig(url: string, namespace: string, database: string, auth: SurrealDBConfig['auth'], options?: Partial<SurrealDBConfig>): SurrealDBConfig;
89
+ /**
90
+ * Create configuration from environment variables.
91
+ *
92
+ * Expected env vars:
93
+ * - SURREAL_URL (required)
94
+ * - SURREAL_NAMESPACE (required)
95
+ * - SURREAL_DATABASE (required)
96
+ * - SURREAL_USERNAME (optional)
97
+ * - SURREAL_PASSWORD (optional)
98
+ *
99
+ * @example
100
+ * const config = envConfig();
101
+ */
102
+ export declare function envConfig(env?: Record<string, string | undefined>): SurrealDBConfig;
103
+ /**
104
+ * Validate a SurrealDB configuration.
105
+ * Throws an error if the configuration is invalid.
106
+ */
107
+ export declare function validateConfig(config: SurrealDBConfig): void;
108
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EACV,eAAe,EACf,QAAQ,EACR,aAAa,EACb,YAAY,EACZ,gBAAgB,EACjB,MAAM,SAAS,CAAC;AAMjB;;;;;;;;;;;;;GAaG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,eAAe,GAAG,eAAe,CAM5E;AAMD;;;;;GAKG;AACH,wBAAgB,QAAQ,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,QAAQ,CAErE;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CAC3B,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,GACf,aAAa,CAEf;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CAC1B,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,GACf,YAAY,CAEd;AAED;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,CAC9B,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,EACd,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAClC,gBAAgB,CAElB;AAMD;;;;;;GAMG;AACH,wBAAgB,eAAe,CAC7B,IAAI,EAAE,MAAM,EACZ,IAAI,GAAE,MAAa,EACnB,QAAQ,GAAE,MAAM,GAAG,OAAO,GAAG,IAAI,GAAG,KAAc,GACjD,MAAM,CAER;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG;IAC5C,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CACd,CAQA;AAMD;;;;;GAKG;AACH,wBAAgB,WAAW,CACzB,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,EAChB,OAAO,CAAC,EAAE,OAAO,CAAC,eAAe,CAAC,GACjC,eAAe,CAQjB;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,WAAW,CACzB,GAAG,EAAE,MAAM,EACX,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,eAAe,CAAC,MAAM,CAAC,EAC7B,OAAO,CAAC,EAAE,OAAO,CAAC,eAAe,CAAC,GACjC,eAAe,CASjB;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,SAAS,CACvB,GAAG,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAe,GACpD,eAAe,CAyBjB;AAMD;;;GAGG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,eAAe,GAAG,IAAI,CAsB5D"}
@@ -0,0 +1,58 @@
1
+ /**
2
+ * @ereo/db-surrealdb - SurrealDB Adapter
3
+ *
4
+ * Provides SurrealDB integration for the EreoJS database abstraction layer.
5
+ * SurrealDB is a multi-model database that supports SQL-like queries, graph
6
+ * relationships, and real-time subscriptions.
7
+ *
8
+ * @example
9
+ * // Basic setup
10
+ * import { createSurrealAdapter, defineSurrealConfig } from '@ereo/db-surrealdb';
11
+ * import { createDatabasePlugin } from '@ereo/db';
12
+ *
13
+ * const adapter = createSurrealAdapter(defineSurrealConfig({
14
+ * url: 'http://localhost:8000',
15
+ * namespace: 'test',
16
+ * database: 'test',
17
+ * auth: {
18
+ * username: 'root',
19
+ * password: 'root',
20
+ * },
21
+ * }));
22
+ *
23
+ * export default defineConfig({
24
+ * plugins: [createDatabasePlugin(adapter)],
25
+ * });
26
+ *
27
+ * @example
28
+ * // Using in routes
29
+ * import { useDb } from '@ereo/db';
30
+ *
31
+ * export const loader = createLoader({
32
+ * load: async ({ context }) => {
33
+ * const db = useDb(context);
34
+ *
35
+ * // Use SurrealQL
36
+ * const result = await db.client.query('SELECT * FROM users WHERE active = true');
37
+ *
38
+ * // Or use the convenience methods
39
+ * const users = await db.client.select('users');
40
+ *
41
+ * return users;
42
+ * },
43
+ * });
44
+ *
45
+ * @example
46
+ * // Environment-based configuration
47
+ * import { createSurrealAdapter, envConfig } from '@ereo/db-surrealdb';
48
+ *
49
+ * const adapter = createSurrealAdapter(envConfig());
50
+ * // Uses: SURREAL_URL, SURREAL_NAMESPACE, SURREAL_DATABASE, SURREAL_USERNAME, SURREAL_PASSWORD
51
+ *
52
+ * @packageDocumentation
53
+ */
54
+ export { createSurrealAdapter, select, create, update, deleteFrom, type SurrealClient, } from './adapter';
55
+ export { defineSurrealConfig, rootAuth, namespaceAuth, databaseAuth, recordAccessAuth, buildSurrealUrl, parseSurrealUrl, localConfig, cloudConfig, envConfig, validateConfig, } from './config';
56
+ export { type SurrealDBConfig, type SurrealAuth, type RootAuth, type NamespaceAuth, type DatabaseAuth, type RecordAccessAuth, type ScopeAuth, type ConnectionProtocol, type SurrealEngine, type SurrealQueryResult, type SurrealRawResponse, type RecordId, type SurrealRecord, type LiveAction, type LiveNotification, isRootAuth, isNamespaceAuth, isDatabaseAuth, isRecordAccessAuth, isScopeAuth, } from './types';
57
+ export { createDatabasePlugin, useDb, useAdapter, getDb, withTransaction, type DatabaseAdapter, type RequestScopedClient, type QueryResult, type MutationResult, type DedupResult, type DedupStats, type TransactionOptions, } from '@ereo/db';
58
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoDG;AAMH,OAAO,EACL,oBAAoB,EAEpB,MAAM,EACN,MAAM,EACN,MAAM,EACN,UAAU,EAEV,KAAK,aAAa,GACnB,MAAM,WAAW,CAAC;AAMnB,OAAO,EAEL,mBAAmB,EAEnB,QAAQ,EACR,aAAa,EACb,YAAY,EACZ,gBAAgB,EAEhB,eAAe,EACf,eAAe,EAEf,WAAW,EACX,WAAW,EACX,SAAS,EAET,cAAc,GACf,MAAM,UAAU,CAAC;AAMlB,OAAO,EAEL,KAAK,eAAe,EAEpB,KAAK,WAAW,EAChB,KAAK,QAAQ,EACb,KAAK,aAAa,EAClB,KAAK,YAAY,EACjB,KAAK,gBAAgB,EACrB,KAAK,SAAS,EAEd,KAAK,kBAAkB,EACvB,KAAK,aAAa,EAElB,KAAK,kBAAkB,EACvB,KAAK,kBAAkB,EAEvB,KAAK,QAAQ,EACb,KAAK,aAAa,EAElB,KAAK,UAAU,EACf,KAAK,gBAAgB,EAErB,UAAU,EACV,eAAe,EACf,cAAc,EACd,kBAAkB,EAClB,WAAW,GACZ,MAAM,SAAS,CAAC;AAMjB,OAAO,EAEL,oBAAoB,EACpB,KAAK,EACL,UAAU,EACV,KAAK,EACL,eAAe,EAEf,KAAK,eAAe,EACpB,KAAK,mBAAmB,EACxB,KAAK,WAAW,EAChB,KAAK,cAAc,EACnB,KAAK,WAAW,EAChB,KAAK,UAAU,EACf,KAAK,kBAAkB,GACxB,MAAM,UAAU,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,393 @@
1
+ // @bun
2
+ var __require = import.meta.require;
3
+
4
+ // src/adapter.ts
5
+ import {
6
+ dedupQuery,
7
+ clearDedupCache,
8
+ invalidateTables,
9
+ getRequestDedupStats,
10
+ ConnectionError,
11
+ QueryError,
12
+ TransactionError
13
+ } from "@ereo/db";
14
+
15
+ // src/config.ts
16
+ function defineSurrealConfig(config) {
17
+ return {
18
+ timeout: 30000,
19
+ debug: false,
20
+ ...config
21
+ };
22
+ }
23
+ function rootAuth(username, password) {
24
+ return { username, password };
25
+ }
26
+ function namespaceAuth(namespace, username, password) {
27
+ return { namespace, username, password };
28
+ }
29
+ function databaseAuth(namespace, database, username, password) {
30
+ return { namespace, database, username, password };
31
+ }
32
+ function recordAccessAuth(namespace, database, access, variables) {
33
+ return { namespace, database, access, variables };
34
+ }
35
+ function buildSurrealUrl(host, port = 8000, protocol = "http") {
36
+ return `${protocol}://${host}:${port}`;
37
+ }
38
+ function parseSurrealUrl(url) {
39
+ const parsed = new URL(url);
40
+ return {
41
+ protocol: parsed.protocol.replace(":", ""),
42
+ host: parsed.hostname,
43
+ port: parseInt(parsed.port) || (parsed.protocol === "https:" || parsed.protocol === "wss:" ? 443 : 8000),
44
+ path: parsed.pathname
45
+ };
46
+ }
47
+ function localConfig(namespace, database, options) {
48
+ return defineSurrealConfig({
49
+ url: "http://127.0.0.1:8000",
50
+ namespace,
51
+ database,
52
+ debug: true,
53
+ ...options
54
+ });
55
+ }
56
+ function cloudConfig(url, namespace, database, auth, options) {
57
+ return defineSurrealConfig({
58
+ url,
59
+ namespace,
60
+ database,
61
+ auth,
62
+ debug: false,
63
+ ...options
64
+ });
65
+ }
66
+ function envConfig(env = process.env) {
67
+ const url = env.SURREAL_URL;
68
+ const namespace = env.SURREAL_NAMESPACE;
69
+ const database = env.SURREAL_DATABASE;
70
+ if (!url) {
71
+ throw new Error("SURREAL_URL environment variable is required");
72
+ }
73
+ if (!namespace) {
74
+ throw new Error("SURREAL_NAMESPACE environment variable is required");
75
+ }
76
+ if (!database) {
77
+ throw new Error("SURREAL_DATABASE environment variable is required");
78
+ }
79
+ const username = env.SURREAL_USERNAME;
80
+ const password = env.SURREAL_PASSWORD;
81
+ return defineSurrealConfig({
82
+ url,
83
+ namespace,
84
+ database,
85
+ auth: username && password ? { username, password } : undefined,
86
+ debug: env.SURREAL_DEBUG === "true"
87
+ });
88
+ }
89
+ function validateConfig(config) {
90
+ if (!config.url) {
91
+ throw new Error("SurrealDB url is required");
92
+ }
93
+ if (!config.namespace) {
94
+ throw new Error("SurrealDB namespace is required");
95
+ }
96
+ if (!config.database) {
97
+ throw new Error("SurrealDB database is required");
98
+ }
99
+ try {
100
+ if (!config.url.startsWith("mem://") && !config.url.startsWith("surrealkv://")) {
101
+ new URL(config.url);
102
+ }
103
+ } catch {
104
+ throw new Error(`Invalid SurrealDB URL: ${config.url}`);
105
+ }
106
+ }
107
+
108
+ // src/adapter.ts
109
+ class SurrealDBAdapter {
110
+ name = "surrealdb";
111
+ edgeCompatible = true;
112
+ client = null;
113
+ config;
114
+ isConnected = false;
115
+ constructor(config) {
116
+ validateConfig(config);
117
+ this.config = config;
118
+ }
119
+ async connect() {
120
+ if (this.isConnected && this.client) {
121
+ return;
122
+ }
123
+ try {
124
+ const SurrealModule = await import("surrealdb");
125
+ const Surreal = SurrealModule.default || SurrealModule.Surreal || SurrealModule;
126
+ this.client = new Surreal;
127
+ let connectionUrl = this.config.url;
128
+ if ((connectionUrl.startsWith("http://") || connectionUrl.startsWith("https://")) && !connectionUrl.endsWith("/rpc")) {
129
+ connectionUrl = connectionUrl.replace(/\/$/, "") + "/rpc";
130
+ }
131
+ if (this.config.debug) {
132
+ console.log(`[surrealdb] Connecting to ${connectionUrl}...`);
133
+ }
134
+ await this.client.connect(connectionUrl);
135
+ if (this.config.auth) {
136
+ if (this.config.debug) {
137
+ console.log("[surrealdb] Signing in...");
138
+ }
139
+ await this.client.signin(this.config.auth);
140
+ }
141
+ await this.client.use({
142
+ namespace: this.config.namespace,
143
+ database: this.config.database
144
+ });
145
+ this.isConnected = true;
146
+ if (this.config.debug) {
147
+ console.log(`[surrealdb] Connected to ${this.config.namespace}/${this.config.database}`);
148
+ }
149
+ } catch (error) {
150
+ this.client = null;
151
+ this.isConnected = false;
152
+ throw new ConnectionError(`Failed to connect to SurrealDB: ${error instanceof Error ? error.message : error}`, error instanceof Error ? error : undefined);
153
+ }
154
+ }
155
+ getClient() {
156
+ if (!this.client || !this.isConnected) {
157
+ throw new ConnectionError("SurrealDB not connected. Call connect() first or use the plugin which handles this automatically.");
158
+ }
159
+ return this.client;
160
+ }
161
+ getRequestClient(context) {
162
+ const adapter = this;
163
+ return {
164
+ get client() {
165
+ return adapter.getClient();
166
+ },
167
+ async query(sql, params) {
168
+ const vars = params ? arrayToVars(params) : undefined;
169
+ return dedupQuery(context, sql, params, async () => adapter.query(sql, params));
170
+ },
171
+ getDedupStats() {
172
+ return getRequestDedupStats(context);
173
+ },
174
+ clearDedup() {
175
+ clearDedupCache(context);
176
+ },
177
+ invalidate(tables) {
178
+ if (tables) {
179
+ invalidateTables(context, tables);
180
+ } else {
181
+ clearDedupCache(context);
182
+ }
183
+ }
184
+ };
185
+ }
186
+ async query(sql, params) {
187
+ await this.connect();
188
+ try {
189
+ const vars = params ? arrayToVars(params) : undefined;
190
+ if (this.config.debug) {
191
+ console.log("[surrealdb] Query:", sql, vars);
192
+ }
193
+ const results = await this.client.query(sql, vars);
194
+ const flatResults = Array.isArray(results) ? results.flat() : [results];
195
+ return {
196
+ rows: flatResults,
197
+ rowCount: flatResults.length
198
+ };
199
+ } catch (error) {
200
+ throw new QueryError(`SurrealDB query failed: ${error instanceof Error ? error.message : error}`, sql, params, error instanceof Error ? error : undefined);
201
+ }
202
+ }
203
+ async execute(sql, params) {
204
+ await this.connect();
205
+ try {
206
+ const vars = params ? arrayToVars(params) : undefined;
207
+ if (this.config.debug) {
208
+ console.log("[surrealdb] Execute:", sql, vars);
209
+ }
210
+ const results = await this.client.query(sql, vars);
211
+ const flatResults = Array.isArray(results) ? results.flat() : [results];
212
+ return {
213
+ rowsAffected: flatResults.length
214
+ };
215
+ } catch (error) {
216
+ throw new QueryError(`SurrealDB execute failed: ${error instanceof Error ? error.message : error}`, sql, params, error instanceof Error ? error : undefined);
217
+ }
218
+ }
219
+ async transaction(fn, _options) {
220
+ await this.connect();
221
+ try {
222
+ await this.client.query("BEGIN TRANSACTION");
223
+ try {
224
+ const result = await fn(this.client);
225
+ await this.client.query("COMMIT TRANSACTION");
226
+ return result;
227
+ } catch (error) {
228
+ await this.client.query("CANCEL TRANSACTION");
229
+ throw error;
230
+ }
231
+ } catch (error) {
232
+ throw new TransactionError(`SurrealDB transaction failed: ${error instanceof Error ? error.message : error}`, error instanceof Error ? error : undefined);
233
+ }
234
+ }
235
+ async beginTransaction(_options) {
236
+ await this.connect();
237
+ let isActive = true;
238
+ const client = this.client;
239
+ await client.query("BEGIN TRANSACTION");
240
+ return {
241
+ client,
242
+ async commit() {
243
+ if (!isActive) {
244
+ throw new TransactionError("Transaction is not active");
245
+ }
246
+ isActive = false;
247
+ await client.query("COMMIT TRANSACTION");
248
+ },
249
+ async rollback() {
250
+ if (!isActive) {
251
+ throw new TransactionError("Transaction is not active");
252
+ }
253
+ isActive = false;
254
+ await client.query("CANCEL TRANSACTION");
255
+ },
256
+ get isActive() {
257
+ return isActive;
258
+ }
259
+ };
260
+ }
261
+ async healthCheck() {
262
+ const start = Date.now();
263
+ try {
264
+ await this.connect();
265
+ await this.client.query("INFO FOR DB");
266
+ return {
267
+ healthy: true,
268
+ latencyMs: Date.now() - start,
269
+ metadata: {
270
+ namespace: this.config.namespace,
271
+ database: this.config.database,
272
+ url: this.config.url
273
+ }
274
+ };
275
+ } catch (error) {
276
+ return {
277
+ healthy: false,
278
+ latencyMs: Date.now() - start,
279
+ error: error instanceof Error ? error.message : String(error),
280
+ metadata: {
281
+ namespace: this.config.namespace,
282
+ database: this.config.database
283
+ }
284
+ };
285
+ }
286
+ }
287
+ async disconnect() {
288
+ if (!this.client || !this.isConnected) {
289
+ return;
290
+ }
291
+ try {
292
+ await this.client.close();
293
+ if (this.config.debug) {
294
+ console.log("[surrealdb] Disconnected");
295
+ }
296
+ } catch (error) {
297
+ if (this.config.debug) {
298
+ console.error("[surrealdb] Error during disconnect:", error);
299
+ }
300
+ } finally {
301
+ this.client = null;
302
+ this.isConnected = false;
303
+ }
304
+ }
305
+ }
306
+ function arrayToVars(params) {
307
+ const vars = {};
308
+ for (let i = 0;i < params.length; i++) {
309
+ vars[i.toString()] = params[i];
310
+ }
311
+ return vars;
312
+ }
313
+ function createSurrealAdapter(config) {
314
+ return new SurrealDBAdapter(config);
315
+ }
316
+ function select(table, options) {
317
+ let query = `SELECT * FROM ${table}`;
318
+ if (options?.where) {
319
+ query += ` WHERE ${options.where}`;
320
+ }
321
+ if (options?.orderBy) {
322
+ query += ` ORDER BY ${options.orderBy}`;
323
+ }
324
+ if (options?.limit !== undefined) {
325
+ query += ` LIMIT ${options.limit}`;
326
+ }
327
+ if (options?.start !== undefined) {
328
+ query += ` START ${options.start}`;
329
+ }
330
+ return query;
331
+ }
332
+ function create(table, id) {
333
+ return id ? `CREATE ${table}:${id}` : `CREATE ${table}`;
334
+ }
335
+ function update(table, id) {
336
+ return id ? `UPDATE ${table}:${id}` : `UPDATE ${table}`;
337
+ }
338
+ function deleteFrom(table, id) {
339
+ return id ? `DELETE ${table}:${id}` : `DELETE ${table}`;
340
+ }
341
+ // src/types.ts
342
+ function isRootAuth(auth) {
343
+ return "username" in auth && "password" in auth && !("namespace" in auth);
344
+ }
345
+ function isNamespaceAuth(auth) {
346
+ return "namespace" in auth && "username" in auth && !("database" in auth);
347
+ }
348
+ function isDatabaseAuth(auth) {
349
+ return "namespace" in auth && "database" in auth && "username" in auth && !("access" in auth) && !("scope" in auth);
350
+ }
351
+ function isRecordAccessAuth(auth) {
352
+ return "namespace" in auth && "database" in auth && "access" in auth;
353
+ }
354
+ function isScopeAuth(auth) {
355
+ return "namespace" in auth && "database" in auth && "scope" in auth;
356
+ }
357
+
358
+ // src/index.ts
359
+ import {
360
+ createDatabasePlugin,
361
+ useDb,
362
+ useAdapter,
363
+ getDb,
364
+ withTransaction
365
+ } from "@ereo/db";
366
+ export {
367
+ withTransaction,
368
+ validateConfig,
369
+ useDb,
370
+ useAdapter,
371
+ update,
372
+ select,
373
+ rootAuth,
374
+ recordAccessAuth,
375
+ parseSurrealUrl,
376
+ namespaceAuth,
377
+ localConfig,
378
+ isScopeAuth,
379
+ isRootAuth,
380
+ isRecordAccessAuth,
381
+ isNamespaceAuth,
382
+ isDatabaseAuth,
383
+ getDb,
384
+ envConfig,
385
+ deleteFrom,
386
+ defineSurrealConfig,
387
+ databaseAuth,
388
+ createSurrealAdapter,
389
+ createDatabasePlugin,
390
+ create,
391
+ cloudConfig,
392
+ buildSurrealUrl
393
+ };