@computesdk/cloudflare 1.6.2 โ†’ 1.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.
Files changed (2) hide show
  1. package/README.md +96 -212
  2. package/package.json +4 -4
package/README.md CHANGED
@@ -1,17 +1,6 @@
1
1
  # @computesdk/cloudflare
2
2
 
3
- Cloudflare provider for ComputeSDK - execute code in secure sandboxes on Cloudflare's edge network using Durable Objects.
4
-
5
- ## Features
6
-
7
- - **๐Ÿ”’ Secure Isolation**: Each sandbox runs in its own container with full process isolation
8
- - **โšก Edge-Native**: Runs on Cloudflare's global network for low latency worldwide
9
- - **๐Ÿ“ Full Filesystem Support**: Read, write, and manage files within the sandbox
10
- - **๐Ÿ”ง Command Execution**: Run any command or process inside the container
11
- - **๐ŸŒ Port Forwarding**: Expose services running in your sandbox via public URLs
12
- - **๐Ÿ”„ Git Integration**: Clone repositories directly into sandboxes
13
- - **๐Ÿงช Code Interpreter**: Execute Python and JavaScript with rich outputs
14
- - **๐ŸŽฎ Session Management**: Maintain state across multiple operations
3
+ Cloudflare provider for ComputeSDK โ€” execute code in secure, isolated sandboxes on Cloudflare's edge network.
15
4
 
16
5
  ## Installation
17
6
 
@@ -19,101 +8,44 @@ Cloudflare provider for ComputeSDK - execute code in secure sandboxes on Cloudfl
19
8
  npm install @computesdk/cloudflare
20
9
  ```
21
10
 
22
- ## Prerequisites
11
+ ## Setup
23
12
 
24
- This provider requires a Cloudflare Workers environment with Durable Objects configured. You'll need:
13
+ Run the setup command to deploy a gateway Worker to your Cloudflare account:
25
14
 
26
- Note: Cloudflare API key should include the following permissions:
27
- - Workers Scripts:Edit
28
- - Workers KV Storage:Edit
29
- - Account Settings:Read
30
- - Workers Scripts:Read
31
- - Workers KV Storage:Read
32
- - Workers Tail:Read
15
+ ```bash
16
+ npx @computesdk/cloudflare
17
+ ```
33
18
 
34
- 1. **Cloudflare Workers account** with Durable Objects enabled
35
- 2. **wrangler.toml configuration** with Sandbox Durable Object binding
36
- 3. **Dockerfile** setup (temporary requirement)
19
+ This requires two environment variables:
37
20
 
38
- ### Setup Instructions
21
+ - `CLOUDFLARE_API_TOKEN` โ€” a Cloudflare API token with the following permissions:
22
+ - Workers Scripts: Read & Edit
23
+ - Workers KV Storage: Read & Edit
24
+ - Account Settings: Read
25
+ - Workers Tail: Read
26
+ - `CLOUDFLARE_ACCOUNT_ID` โ€” your Cloudflare account ID
39
27
 
40
- 1. **Create a Dockerfile** (temporary requirement):
41
- ```dockerfile
42
- FROM docker.io/cloudflare/sandbox:0.3.0
28
+ You can set these in a `.env` file or export them in your shell. Get your API token at [dash.cloudflare.com/profile/api-tokens](https://dash.cloudflare.com/profile/api-tokens).
43
29
 
44
- # Expose the ports you want to expose
45
- EXPOSE 3000
46
- ```
30
+ The setup command will deploy the gateway Worker and output two values:
47
31
 
48
- 2. **Configure wrangler.toml**:
49
- ```toml
50
- [durable_objects]
51
- bindings = [
52
- { name = "Sandbox", class_name = "Sandbox" }
53
- ]
54
-
55
- [[migrations]]
56
- tag = "v1"
57
- new_sqlite_classes = ["Sandbox"]
58
-
59
- [[containers]]
60
- class_name = "Sandbox"
61
- image = "./Dockerfile"
62
- max_instances = 1
63
32
  ```
64
-
65
- 3. **Export the Sandbox class in your Worker**:
66
- ```typescript
67
- import { getSandbox } from "@cloudflare/sandbox";
68
-
69
- // Export the Sandbox class in your Worker
70
- export { Sandbox } from "@cloudflare/sandbox";
71
-
72
- export default {
73
- async fetch(request: Request, env: Env) {
74
- // Your worker code here
75
- },
76
- };
33
+ CLOUDFLARE_SANDBOX_URL=https://computesdk-sandbox.<subdomain>.workers.dev
34
+ CLOUDFLARE_SANDBOX_SECRET=<generated-secret>
77
35
  ```
78
36
 
79
- ## Quick Start
37
+ Add these to your `.env` file. These are the only env vars needed at runtime.
80
38
 
81
- ### Gateway Mode (Recommended)
82
-
83
- Use the gateway for zero-config auto-detection:
84
-
85
- ```typescript
86
- import { compute } from 'computesdk';
87
-
88
- // Auto-detects from environment (when running in Cloudflare Workers)
89
- const sandbox = await compute.sandbox.create();
90
-
91
- // Execute Python code
92
- const result = await sandbox.runCode(`
93
- import sys
94
- print(f"Python version: {sys.version}")
95
- print("Hello from Cloudflare!")
96
- `);
97
-
98
- console.log(result.stdout);
99
- await sandbox.destroy();
100
- ```
39
+ > **Note:** Docker must be installed for the setup command to build the sandbox container image.
101
40
 
102
- ### Direct Mode
103
-
104
- For direct SDK usage without the gateway:
41
+ ## Quick Start
105
42
 
106
43
  ```typescript
107
44
  import { cloudflare } from '@computesdk/cloudflare';
108
45
 
109
- // Initialize with your Durable Object binding
110
46
  const compute = cloudflare({
111
- sandboxBinding: env.Sandbox, // Your Durable Object binding
112
- runtime: 'python',
113
- timeout: 300000,
114
- envVars: {
115
- MY_VAR: 'hello world'
116
- }
47
+ sandboxUrl: process.env.CLOUDFLARE_SANDBOX_URL,
48
+ sandboxSecret: process.env.CLOUDFLARE_SANDBOX_SECRET,
117
49
  });
118
50
 
119
51
  const sandbox = await compute.sandbox.create();
@@ -125,164 +57,130 @@ print(f"Python version: {sys.version}")
125
57
  print("Hello from Cloudflare!")
126
58
  `);
127
59
 
128
- console.log(result.stdout);
129
-
130
- // Execute shell commands
131
- const cmdResult = await sandbox.runCommand('ls', ['-la']);
132
- console.log(cmdResult.stdout);
133
-
134
- // File operations
135
- await sandbox.filesystem.writeFile('/tmp/hello.txt', 'Hello Cloudflare!');
136
- const content = await sandbox.filesystem.readFile('/tmp/hello.txt');
137
- console.log(content); // "Hello Cloudflare!"
138
-
139
- // Expose a web service
140
- await sandbox.runCode(`
141
- import http.server
142
- import socketserver
143
- PORT = 3000
144
- Handler = http.server.SimpleHTTPRequestHandler
145
- with socketserver.TCPServer(("", PORT), Handler) as httpd:
146
- print(f"Server running on port {PORT}")
147
- httpd.serve_forever()
148
- `);
149
-
150
- // Get the public URL
151
- const url = await sandbox.getUrl({ port: 3000 });
152
- console.log(`Service available at: ${url}`);
153
-
60
+ console.log(result.output);
154
61
  await sandbox.destroy();
155
62
  ```
156
63
 
157
- ## Advanced Usage
64
+ ## Usage
158
65
 
159
- ### Runtime Detection
66
+ ### Run Code
160
67
 
161
68
  The provider automatically detects the runtime based on code content:
162
69
 
163
70
  ```typescript
164
- // Automatically detected as Python
71
+ // Detected as Python
165
72
  await sandbox.runCode('print("Hello Python")');
166
73
 
167
- // Automatically detected as Node.js
74
+ // Detected as Node.js
168
75
  await sandbox.runCode('console.log("Hello Node.js")');
169
76
 
170
77
  // Explicitly specify runtime
171
78
  await sandbox.runCode('print("Hello")', 'python');
172
79
  ```
173
80
 
174
- ### Environment Variables
81
+ ### Run Commands
175
82
 
176
83
  ```typescript
177
- import { cloudflare } from '@computesdk/cloudflare';
178
-
179
- const compute = cloudflare({
180
- sandboxBinding: env.Sandbox,
181
- envVars: {
182
- API_KEY: 'your-api-key',
183
- DATABASE_URL: 'postgresql://localhost:5432/mydb',
184
- NODE_ENV: 'production'
185
- }
186
- });
84
+ const result = await sandbox.runCommand('ls -la /app');
85
+ console.log(result.stdout);
187
86
  ```
188
87
 
189
- ### Port Forwarding
88
+ ### File System
190
89
 
191
90
  ```typescript
192
- // Start a web server
193
- await sandbox.runCode(`
194
- const express = require('express');
195
- const app = express();
196
- app.get('/', (req, res) => res.json({ message: 'Hello from Cloudflare!' }));
197
- app.listen(8080);
198
- `);
199
-
200
- // Get public URL
201
- const url = await sandbox.getUrl({ port: 8080, protocol: 'https' });
202
- console.log(`API available at: ${url}`);
203
- ```
91
+ // Write and read files
92
+ await sandbox.filesystem.writeFile('/app/config.json', JSON.stringify({ key: 'value' }));
93
+ const content = await sandbox.filesystem.readFile('/app/config.json');
204
94
 
205
- ### File System Operations
206
-
207
- ```typescript
208
95
  // Create directories
209
- await sandbox.filesystem.mkdir('/app');
210
-
211
- // Write files
212
- await sandbox.filesystem.writeFile('/app/package.json', JSON.stringify({
213
- name: 'my-app',
214
- version: '1.0.0'
215
- }, null, 2));
216
-
217
- // Read files
218
- const packageJson = await sandbox.filesystem.readFile('/app/package.json');
219
- const config = JSON.parse(packageJson);
96
+ await sandbox.filesystem.mkdir('/app/data');
220
97
 
221
98
  // List directory contents
222
99
  const files = await sandbox.filesystem.readdir('/app');
223
- files.forEach(file => {
224
- console.log(`${file.name} (${file.isDirectory ? 'dir' : 'file'})`);
225
- });
226
100
 
227
- // Check if file exists
228
- if (await sandbox.filesystem.exists('/app/package.json')) {
229
- console.log('Package.json found!');
230
- }
101
+ // Check existence
102
+ const exists = await sandbox.filesystem.exists('/app/config.json');
231
103
 
232
- // Remove files/directories
233
- await sandbox.filesystem.remove('/app/temp');
104
+ // Remove files
105
+ await sandbox.filesystem.remove('/app/temp.txt');
234
106
  ```
235
107
 
236
- ### Git Operations
108
+ ### Port Forwarding
237
109
 
238
110
  ```typescript
239
- // Clone a repository
111
+ // Start a web server in the sandbox
240
112
  await sandbox.runCode(`
241
- import subprocess
242
- result = subprocess.run([
243
- 'git', 'clone', 'https://github.com/user/repo.git', '/app'
244
- ], capture_output=True, text=True)
245
- print(result.stdout)
113
+ import http.server, socketserver
114
+ PORT = 3000
115
+ with socketserver.TCPServer(("", PORT), http.server.SimpleHTTPRequestHandler) as httpd:
116
+ httpd.serve_forever()
246
117
  `);
247
118
 
248
- // Or using the built-in git functionality (if available)
249
- const result = await sandbox.runCommand('git', [
250
- 'clone',
251
- 'https://github.com/user/repo.git',
252
- '/app'
253
- ]);
119
+ // Get the public URL
120
+ const url = await sandbox.getUrl({ port: 3000 });
121
+ console.log(`Service available at: ${url}`);
122
+ ```
123
+
124
+ ### Environment Variables
125
+
126
+ Pass environment variables to the sandbox at initialization:
127
+
128
+ ```typescript
129
+ const compute = cloudflare({
130
+ sandboxUrl: process.env.CLOUDFLARE_SANDBOX_URL,
131
+ sandboxSecret: process.env.CLOUDFLARE_SANDBOX_SECRET,
132
+ envVars: {
133
+ API_KEY: 'your-api-key',
134
+ DATABASE_URL: 'postgresql://localhost:5432/mydb',
135
+ },
136
+ });
137
+ ```
138
+
139
+ Or per-sandbox at creation time:
140
+
141
+ ```typescript
142
+ const sandbox = await compute.sandbox.create({
143
+ envs: { NODE_ENV: 'production' },
144
+ });
254
145
  ```
255
146
 
256
- ## Configuration Options
147
+ ## Configuration
257
148
 
258
149
  ```typescript
259
150
  interface CloudflareConfig {
260
- /** Cloudflare Sandbox binding from Workers environment (required) */
261
- sandboxBinding: any;
262
-
263
- /** Default runtime environment */
264
- runtime?: 'python' | 'node';
265
-
266
- /** Execution timeout in milliseconds (default: 300000) */
151
+ /** URL of the deployed gateway Worker */
152
+ sandboxUrl?: string;
153
+ /** Shared secret for authenticating with the gateway Worker */
154
+ sandboxSecret?: string;
155
+ /** Durable Object binding (direct mode only โ€” see below) */
156
+ sandboxBinding?: any;
157
+ /** Default runtime: 'python' | 'node' | 'bun' | 'deno' */
158
+ runtime?: Runtime;
159
+ /** Execution timeout in milliseconds */
267
160
  timeout?: number;
268
-
269
161
  /** Environment variables to pass to sandbox */
270
162
  envVars?: Record<string, string>;
271
-
272
- /** Base URL for preview URLs (defaults to worker domain) */
273
- baseUrl?: string;
274
163
  }
275
164
  ```
276
165
 
277
- ## Error Handling
166
+ ## Direct Mode
167
+
168
+ If your code already runs inside a Cloudflare Worker, you can skip the gateway and use the Durable Object binding directly:
278
169
 
279
170
  ```typescript
280
171
  import { cloudflare } from '@computesdk/cloudflare';
281
172
 
173
+ const compute = cloudflare({
174
+ sandboxBinding: env.Sandbox,
175
+ });
176
+ ```
177
+
178
+ This requires configuring the Sandbox Durable Object binding in your `wrangler.toml`. See the [Cloudflare Sandbox docs](https://developers.cloudflare.com/sandbox/get-started/) for setup instructions.
179
+
180
+ ## Error Handling
181
+
182
+ ```typescript
282
183
  try {
283
- const compute = cloudflare({ sandboxBinding: env.Sandbox });
284
- const sandbox = await compute.sandbox.create();
285
-
286
184
  const result = await sandbox.runCode('invalid python syntax');
287
185
  } catch (error) {
288
186
  if (error.message.includes('Syntax error')) {
@@ -295,24 +193,10 @@ try {
295
193
 
296
194
  ## Limitations
297
195
 
298
- - Requires Cloudflare Workers environment with Durable Objects
299
- - Container setup currently requires Docker configuration
300
196
  - Resource limits apply based on your Cloudflare plan
301
197
  - Some system calls may be restricted in the container environment
302
-
303
- ## Examples
304
-
305
- Check out the [examples directory](../../examples) for complete working examples:
306
-
307
- - **Basic Usage**: Simple code execution
308
- - **Web Server**: Express.js app with public URLs
309
- - **Data Processing**: Python data analysis with file I/O
310
- - **CI/CD**: Automated testing and building
198
+ - Listing all sandboxes is not supported โ€” use `getById` to reconnect to a specific sandbox
311
199
 
312
200
  ## License
313
201
 
314
- MIT
315
-
316
- ## Contributing
317
-
318
- See the [main repository](https://github.com/computesdk/computesdk) for contribution guidelines.
202
+ MIT
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@computesdk/cloudflare",
3
- "version": "1.6.2",
3
+ "version": "1.6.4",
4
4
  "description": "Cloudflare provider for ComputeSDK - edge code execution using Cloudflare Workers and Durable Objects",
5
5
  "author": "Garrison",
6
6
  "license": "MIT",
@@ -23,8 +23,8 @@
23
23
  ],
24
24
  "dependencies": {
25
25
  "@cloudflare/sandbox": "^0.7.18",
26
- "@computesdk/provider": "1.0.32",
27
- "computesdk": "2.5.2"
26
+ "@computesdk/provider": "1.1.0",
27
+ "computesdk": "2.5.4"
28
28
  },
29
29
  "keywords": [
30
30
  "computesdk",
@@ -60,7 +60,7 @@
60
60
  "typescript": "^5.0.0",
61
61
  "vitest": "^1.0.0",
62
62
  "wrangler": "^3.0.0",
63
- "@computesdk/test-utils": "1.5.1"
63
+ "@computesdk/test-utils": "1.6.1"
64
64
  },
65
65
  "scripts": {
66
66
  "build": "tsup",