agentfs-sdk 0.6.2 → 0.6.4

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,38 @@
1
+ /**
2
+ * Adapter that wraps @tursodatabase/serverless Connection to match
3
+ * the DatabasePromise interface used by AgentFS internals.
4
+ *
5
+ * The core challenge: DatabasePromise.prepare() is synchronous and returns
6
+ * a Statement immediately, but serverless Connection.prepare() is async
7
+ * (it needs to fetch column metadata over HTTP).
8
+ *
9
+ * Solution: return a LazyStatement that defers the actual prepare() call
10
+ * until run()/get()/all() is called — those are already async, so the
11
+ * deferral is invisible to callers.
12
+ *
13
+ * Note on parameter passing: DatabasePromise's Statement uses rest params
14
+ * (run(...args)), while serverless Statement uses a single array param
15
+ * (run(args?)). The adapter collects rest params and forwards them as a
16
+ * single array — this is correct and tested.
17
+ */
18
+ import type { Connection } from "@tursodatabase/serverless";
19
+ import type { DatabasePromise } from "@tursodatabase/database-common";
20
+ /**
21
+ * Wraps a @tursodatabase/serverless Connection to match
22
+ * the DatabasePromise interface expected by AgentFS.openWith().
23
+ *
24
+ * @example
25
+ * ```typescript
26
+ * import { connect } from "@tursodatabase/serverless";
27
+ * import { AgentFS } from "agentfs-sdk";
28
+ * import { createServerlessAdapter } from "agentfs-sdk/serverless";
29
+ *
30
+ * const conn = connect({
31
+ * url: "http://localhost:8080",
32
+ * });
33
+ *
34
+ * const db = createServerlessAdapter(conn);
35
+ * const agent = await AgentFS.openWith(db);
36
+ * ```
37
+ */
38
+ export declare function createServerlessAdapter(conn: Connection): DatabasePromise;
@@ -0,0 +1,165 @@
1
+ /**
2
+ * Adapter that wraps @tursodatabase/serverless Connection to match
3
+ * the DatabasePromise interface used by AgentFS internals.
4
+ *
5
+ * The core challenge: DatabasePromise.prepare() is synchronous and returns
6
+ * a Statement immediately, but serverless Connection.prepare() is async
7
+ * (it needs to fetch column metadata over HTTP).
8
+ *
9
+ * Solution: return a LazyStatement that defers the actual prepare() call
10
+ * until run()/get()/all() is called — those are already async, so the
11
+ * deferral is invisible to callers.
12
+ *
13
+ * Note on parameter passing: DatabasePromise's Statement uses rest params
14
+ * (run(...args)), while serverless Statement uses a single array param
15
+ * (run(args?)). The adapter collects rest params and forwards them as a
16
+ * single array — this is correct and tested.
17
+ */
18
+ /**
19
+ * A statement that defers the async prepare() call until execution.
20
+ *
21
+ * DatabasePromise.prepare() must return synchronously, but the serverless
22
+ * driver's prepare() is async. LazyStatement bridges this by storing the
23
+ * SQL and only calling conn.prepare() when run/get/all is invoked.
24
+ *
25
+ * The statement promise is cached for performance — options (raw, pluck,
26
+ * safeIntegers) are applied at execution time on the resolved statement.
27
+ */
28
+ class LazyStatement {
29
+ conn;
30
+ sql;
31
+ stmtPromise = null;
32
+ _raw = false;
33
+ _pluck = false;
34
+ _safeIntegers = false;
35
+ constructor(conn, sql) {
36
+ this.conn = conn;
37
+ this.sql = sql;
38
+ }
39
+ async getStmt() {
40
+ if (!this.stmtPromise) {
41
+ this.stmtPromise = this.conn.prepare(this.sql);
42
+ }
43
+ const stmt = await this.stmtPromise;
44
+ // Apply options at execution time so they reflect the current state
45
+ stmt.raw(this._raw);
46
+ stmt.pluck(this._pluck);
47
+ stmt.safeIntegers(this._safeIntegers);
48
+ return stmt;
49
+ }
50
+ raw(raw) {
51
+ this._raw = raw !== false;
52
+ return this;
53
+ }
54
+ pluck(pluck) {
55
+ this._pluck = pluck !== false;
56
+ return this;
57
+ }
58
+ safeIntegers(toggle) {
59
+ this._safeIntegers = toggle !== false;
60
+ return this;
61
+ }
62
+ columns() {
63
+ throw new Error("columns() requires an async prepare — not supported synchronously in serverless mode");
64
+ }
65
+ get source() {
66
+ return undefined;
67
+ }
68
+ get reader() {
69
+ return undefined;
70
+ }
71
+ get database() {
72
+ return undefined;
73
+ }
74
+ // Note: DatabasePromise Statement uses rest params (...args),
75
+ // but serverless Statement uses a single array param (args?).
76
+ // We collect rest params and forward as a single array.
77
+ async run(...args) {
78
+ const stmt = await this.getStmt();
79
+ return stmt.run(args);
80
+ }
81
+ async get(...args) {
82
+ const stmt = await this.getStmt();
83
+ return stmt.get(args);
84
+ }
85
+ async all(...args) {
86
+ const stmt = await this.getStmt();
87
+ return stmt.all(args);
88
+ }
89
+ async *iterate(...args) {
90
+ const stmt = await this.getStmt();
91
+ yield* stmt.iterate(args);
92
+ }
93
+ bind(..._args) {
94
+ throw new Error("bind() is not supported in serverless mode — pass parameters to run/get/all instead");
95
+ }
96
+ interrupt() { }
97
+ close() { }
98
+ }
99
+ function notSupported(name) {
100
+ return () => {
101
+ throw new Error(`${name}() is not supported in serverless mode`);
102
+ };
103
+ }
104
+ /**
105
+ * Wraps a @tursodatabase/serverless Connection to match
106
+ * the DatabasePromise interface expected by AgentFS.openWith().
107
+ *
108
+ * @example
109
+ * ```typescript
110
+ * import { connect } from "@tursodatabase/serverless";
111
+ * import { AgentFS } from "agentfs-sdk";
112
+ * import { createServerlessAdapter } from "agentfs-sdk/serverless";
113
+ *
114
+ * const conn = connect({
115
+ * url: "http://localhost:8080",
116
+ * });
117
+ *
118
+ * const db = createServerlessAdapter(conn);
119
+ * const agent = await AgentFS.openWith(db);
120
+ * ```
121
+ */
122
+ export function createServerlessAdapter(conn) {
123
+ return {
124
+ name: "serverless",
125
+ readonly: false,
126
+ open: true,
127
+ memory: false,
128
+ inTransaction: false,
129
+ async connect() {
130
+ // Validate the connection by running a simple query
131
+ await conn.execute("SELECT 1");
132
+ },
133
+ prepare(sql) {
134
+ return new LazyStatement(conn, sql);
135
+ },
136
+ // DatabasePromise.transaction() returns a wrapper function that
137
+ // executes fn inside a transaction when called. The serverless
138
+ // driver's transaction() has the same shape.
139
+ transaction(fn) {
140
+ return (...bindParameters) => {
141
+ return conn.transaction(async () => {
142
+ return fn(...bindParameters);
143
+ });
144
+ };
145
+ },
146
+ async exec(sql) {
147
+ await conn.exec(sql);
148
+ },
149
+ pragma() {
150
+ throw new Error("pragma() is not supported in serverless mode — pragmas are not available over HTTP");
151
+ },
152
+ backup: notSupported("backup"),
153
+ serialize: notSupported("serialize"),
154
+ function: notSupported("function"),
155
+ aggregate: notSupported("aggregate"),
156
+ table: notSupported("table"),
157
+ loadExtension: notSupported("loadExtension"),
158
+ maxWriteReplicationIndex: notSupported("maxWriteReplicationIndex"),
159
+ interrupt: notSupported("interrupt"),
160
+ defaultSafeIntegers(_toggle) { },
161
+ async close() {
162
+ await conn.close();
163
+ },
164
+ };
165
+ }
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Serverless integration for AgentFS.
3
+ *
4
+ * Provides an adapter that wraps `@tursodatabase/serverless` Connection
5
+ * to be compatible with AgentFS's DatabasePromise interface, enabling
6
+ * AgentFS to work with remote Turso databases over HTTP.
7
+ *
8
+ * @example
9
+ * ```typescript
10
+ * import { connect } from "@tursodatabase/serverless";
11
+ * import { AgentFS } from "agentfs-sdk";
12
+ * import { createServerlessAdapter } from "agentfs-sdk/serverless";
13
+ *
14
+ * const conn = connect({
15
+ * url: process.env.TURSO_DATABASE_URL!,
16
+ * authToken: process.env.TURSO_AUTH_TOKEN,
17
+ * });
18
+ *
19
+ * const db = createServerlessAdapter(conn);
20
+ * const agent = await AgentFS.openWith(db);
21
+ *
22
+ * await agent.fs.writeFile("/hello.txt", "Hello from Turso Cloud!");
23
+ * const content = await agent.fs.readFile("/hello.txt", "utf8");
24
+ * console.log(content);
25
+ *
26
+ * await agent.close();
27
+ * ```
28
+ *
29
+ * @see https://github.com/tursodatabase/agentfs/issues/156
30
+ */
31
+ export { createServerlessAdapter } from "./adapter.js";
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Serverless integration for AgentFS.
3
+ *
4
+ * Provides an adapter that wraps `@tursodatabase/serverless` Connection
5
+ * to be compatible with AgentFS's DatabasePromise interface, enabling
6
+ * AgentFS to work with remote Turso databases over HTTP.
7
+ *
8
+ * @example
9
+ * ```typescript
10
+ * import { connect } from "@tursodatabase/serverless";
11
+ * import { AgentFS } from "agentfs-sdk";
12
+ * import { createServerlessAdapter } from "agentfs-sdk/serverless";
13
+ *
14
+ * const conn = connect({
15
+ * url: process.env.TURSO_DATABASE_URL!,
16
+ * authToken: process.env.TURSO_AUTH_TOKEN,
17
+ * });
18
+ *
19
+ * const db = createServerlessAdapter(conn);
20
+ * const agent = await AgentFS.openWith(db);
21
+ *
22
+ * await agent.fs.writeFile("/hello.txt", "Hello from Turso Cloud!");
23
+ * const content = await agent.fs.readFile("/hello.txt", "utf8");
24
+ * console.log(content);
25
+ *
26
+ * await agent.close();
27
+ * ```
28
+ *
29
+ * @see https://github.com/tursodatabase/agentfs/issues/156
30
+ */
31
+ export { createServerlessAdapter } from "./adapter.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agentfs-sdk",
3
- "version": "0.6.2",
3
+ "version": "0.6.4",
4
4
  "description": "AgentFS SDK",
5
5
  "main": "dist/index_node.js",
6
6
  "types": "dist/index_node.d.ts",
@@ -29,6 +29,10 @@
29
29
  "./cloudflare": {
30
30
  "import": "./dist/integrations/cloudflare/index.js",
31
31
  "types": "./dist/integrations/cloudflare/index.d.ts"
32
+ },
33
+ "./serverless": {
34
+ "import": "./dist/integrations/serverless/index.js",
35
+ "types": "./dist/integrations/serverless/index.d.ts"
32
36
  }
33
37
  },
34
38
  "keywords": [
@@ -47,6 +51,7 @@
47
51
  },
48
52
  "devDependencies": {
49
53
  "@tursodatabase/database-wasm": "^0.4.0-pre.18",
54
+ "@tursodatabase/serverless": "^0.2.4",
50
55
  "@types/node": "^20.0.0",
51
56
  "@vitest/browser": "^4.0.16",
52
57
  "@vitest/browser-playwright": "^4.0.16",
@@ -56,11 +61,15 @@
56
61
  "vitest": "^4.0.1"
57
62
  },
58
63
  "peerDependencies": {
64
+ "@tursodatabase/serverless": "^0.2.4",
59
65
  "just-bash": ">=2.0.0"
60
66
  },
61
67
  "peerDependenciesMeta": {
62
68
  "just-bash": {
63
69
  "optional": true
70
+ },
71
+ "@tursodatabase/serverless": {
72
+ "optional": true
64
73
  }
65
74
  },
66
75
  "dependencies": {