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.
|
|
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": {
|