computesdk 1.0.0 → 1.0.2
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.
- package/README.md +306 -133
- package/dist/index.d.mts +467 -0
- package/dist/index.d.ts +467 -0
- package/dist/index.js +534 -1
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +494 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +68 -22
package/README.md
CHANGED
|
@@ -1,185 +1,358 @@
|
|
|
1
|
-
# ComputeSDK
|
|
1
|
+
# ComputeSDK
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
A unified abstraction layer for executing code in secure, isolated sandboxed environments across multiple cloud providers.
|
|
4
|
+
|
|
5
|
+
Similar to how Vercel's AI SDK abstracts different LLM providers, ComputeSDK abstracts different compute sandbox providers into a single, consistent TypeScript interface.
|
|
6
|
+
|
|
7
|
+
## Features
|
|
8
|
+
|
|
9
|
+
- **Unified API** - Single interface for multiple sandbox providers
|
|
10
|
+
- **Auto-detection** - Automatically detects and uses available providers
|
|
11
|
+
- **Provider-agnostic** - Switch between providers without code changes
|
|
12
|
+
- **Type-safe** - Full TypeScript support with comprehensive type definitions
|
|
13
|
+
- **Extensible** - Easy to add new providers
|
|
14
|
+
- **Production-ready** - Built for real-world applications
|
|
15
|
+
|
|
16
|
+
## Supported Providers
|
|
17
|
+
|
|
18
|
+
- **E2B** - Python-focused code execution with templates
|
|
19
|
+
- **Vercel** - Node.js and Python execution on Vercel infrastructure
|
|
20
|
+
- **Cloudflare** - Edge computing with Cloudflare Workers and Durable Objects
|
|
21
|
+
- **Fly.io** - Fast boot containers (community contribution target)
|
|
4
22
|
|
|
5
23
|
## Installation
|
|
6
24
|
|
|
7
25
|
```bash
|
|
8
26
|
npm install computesdk
|
|
9
|
-
# or
|
|
10
|
-
yarn add computesdk
|
|
11
|
-
# or
|
|
12
|
-
pnpm add computesdk
|
|
13
27
|
```
|
|
14
28
|
|
|
15
|
-
|
|
29
|
+
### Install Provider Packages
|
|
16
30
|
|
|
17
|
-
```
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
const client = new ComputeClient();
|
|
23
|
-
|
|
24
|
-
// Create a new compute instance
|
|
25
|
-
const compute = await client.create();
|
|
26
|
-
|
|
27
|
-
// Listen for server ready events
|
|
28
|
-
compute.onServerReady((port, url) => {
|
|
29
|
-
console.log(`Server is ready on port ${port} at ${url}`);
|
|
30
|
-
});
|
|
31
|
-
}
|
|
31
|
+
```bash
|
|
32
|
+
# Install the providers you need
|
|
33
|
+
npm install @computesdk/e2b # E2B provider
|
|
34
|
+
npm install @computesdk/vercel # Vercel provider
|
|
35
|
+
npm install @computesdk/cloudflare # Cloudflare provider
|
|
32
36
|
```
|
|
33
37
|
|
|
34
|
-
##
|
|
38
|
+
## Quick Start
|
|
35
39
|
|
|
36
|
-
###
|
|
40
|
+
### Auto-detection (Recommended)
|
|
37
41
|
|
|
38
|
-
|
|
42
|
+
```typescript
|
|
43
|
+
import { ComputeSDK } from 'computesdk';
|
|
39
44
|
|
|
40
|
-
|
|
41
|
-
const
|
|
42
|
-
|
|
43
|
-
|
|
45
|
+
// Automatically detects and uses available providers
|
|
46
|
+
const sdk = new ComputeSDK();
|
|
47
|
+
const sandbox = await sdk.createSandbox();
|
|
48
|
+
|
|
49
|
+
const result = await sandbox.execute('print("Hello from ComputeSDK!")');
|
|
50
|
+
console.log(result.stdout); // "Hello from ComputeSDK!"
|
|
51
|
+
|
|
52
|
+
await sandbox.kill();
|
|
44
53
|
```
|
|
45
54
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
// Returns: Promise<Compute>
|
|
59
|
-
// Throws: Error if compute creation fails
|
|
60
|
-
```
|
|
61
|
-
|
|
62
|
-
- `delete(computeId)`: Terminates and removes a compute instance
|
|
63
|
-
```javascript
|
|
64
|
-
// Delete a specific compute instance
|
|
65
|
-
await client.delete(compute.computeId);
|
|
66
|
-
|
|
67
|
-
// Parameters:
|
|
68
|
-
// - computeId: string (required) - The ID of the compute instance to delete
|
|
69
|
-
|
|
70
|
-
// Returns: Promise<void>
|
|
71
|
-
// Throws: Error if deletion fails or computeId is invalid
|
|
72
|
-
```
|
|
73
|
-
|
|
74
|
-
Note: It's recommended to use the `compute.teardown()` method instead of calling `delete()` directly, as it properly closes WebSocket connections and handles cleanup.
|
|
75
|
-
|
|
76
|
-
### Compute
|
|
77
|
-
|
|
78
|
-
Represents a compute instance with capabilities for file management, terminal operations, and process execution.
|
|
79
|
-
|
|
80
|
-
#### File Operations
|
|
81
|
-
|
|
82
|
-
```javascript
|
|
83
|
-
// Watch files for changes
|
|
84
|
-
const watcher = compute.watchFiles({
|
|
85
|
-
path: '/home/project',
|
|
86
|
-
includeContent: false, // Optional: include file contents in change events
|
|
87
|
-
ignored: ['**/node_modules/**'] // Optional: patterns to ignore
|
|
55
|
+
### Provider-specific Usage
|
|
56
|
+
|
|
57
|
+
```typescript
|
|
58
|
+
import { executeSandbox } from 'computesdk';
|
|
59
|
+
import { e2b } from '@computesdk/e2b';
|
|
60
|
+
|
|
61
|
+
// Execute with specific provider
|
|
62
|
+
const result = await executeSandbox({
|
|
63
|
+
sandbox: e2b(),
|
|
64
|
+
code: 'print("Hello from E2B!")',
|
|
65
|
+
runtime: 'python'
|
|
88
66
|
});
|
|
89
67
|
|
|
90
|
-
|
|
68
|
+
console.log(result.stdout);
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
### Multiple Providers
|
|
72
|
+
|
|
73
|
+
```typescript
|
|
74
|
+
import { executeSandbox } from 'computesdk';
|
|
75
|
+
import { e2b } from '@computesdk/e2b';
|
|
76
|
+
import { vercel } from '@computesdk/vercel';
|
|
77
|
+
import { cloudflare } from '@computesdk/cloudflare';
|
|
78
|
+
|
|
79
|
+
// Try different providers for different use cases
|
|
80
|
+
const providers = [
|
|
81
|
+
{ name: 'E2B', provider: e2b() },
|
|
82
|
+
{ name: 'Vercel', provider: vercel() },
|
|
83
|
+
{ name: 'Cloudflare', provider: cloudflare({ env }) }
|
|
84
|
+
];
|
|
85
|
+
|
|
86
|
+
for (const { name, provider } of providers) {
|
|
87
|
+
try {
|
|
88
|
+
const result = await executeSandbox({
|
|
89
|
+
sandbox: provider,
|
|
90
|
+
code: 'print("Hello from ' + name + '!")'
|
|
91
|
+
});
|
|
92
|
+
console.log(`${name}:`, result.stdout);
|
|
93
|
+
} catch (error) {
|
|
94
|
+
console.error(`${name} failed:`, error.message);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
```
|
|
91
98
|
|
|
92
|
-
|
|
93
|
-
const content = await compute.readFile('/path/to/file');
|
|
99
|
+
## API Reference
|
|
94
100
|
|
|
95
|
-
|
|
96
|
-
await compute.writeFile('/path/to/file', 'content');
|
|
101
|
+
### `ComputeSDK`
|
|
97
102
|
|
|
98
|
-
|
|
99
|
-
await compute.mkdir('/path/to/dir', {
|
|
100
|
-
recursive: true // Optional: create parent directories if they don't exist
|
|
101
|
-
});
|
|
103
|
+
Main SDK class for auto-detection and management.
|
|
102
104
|
|
|
103
|
-
|
|
104
|
-
|
|
105
|
+
```typescript
|
|
106
|
+
const sdk = new ComputeSDK(options?: ComputeSDKOptions);
|
|
105
107
|
```
|
|
106
108
|
|
|
107
|
-
####
|
|
109
|
+
#### Methods
|
|
108
110
|
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
rows: 24, // Optional
|
|
113
|
-
cols: 80, // Optional
|
|
114
|
-
command: null, // Optional
|
|
115
|
-
args: [] // Optional
|
|
116
|
-
});
|
|
111
|
+
- `createSandbox(config?: SandboxConfig)` - Creates a sandbox using auto-detection
|
|
112
|
+
- `getAvailableProviders()` - Returns list of available providers
|
|
113
|
+
- `registerProvider(name: string, provider: ComputeSpecification)` - Registers a custom provider
|
|
117
114
|
|
|
118
|
-
|
|
119
|
-
terminal.onData(data => console.log('Received:', data));
|
|
120
|
-
terminal.onExit(({ exitCode, signal }) => console.log('Terminal exited'));
|
|
115
|
+
### `executeSandbox(config: ExecutionConfig)`
|
|
121
116
|
|
|
122
|
-
|
|
123
|
-
terminal.write('echo "Hello World"\n');
|
|
117
|
+
Utility function for one-off code execution.
|
|
124
118
|
|
|
125
|
-
|
|
126
|
-
|
|
119
|
+
```typescript
|
|
120
|
+
interface ExecutionConfig {
|
|
121
|
+
sandbox: ComputeSpecification;
|
|
122
|
+
code: string;
|
|
123
|
+
runtime?: 'python' | 'node';
|
|
124
|
+
timeout?: number;
|
|
125
|
+
}
|
|
127
126
|
```
|
|
128
127
|
|
|
129
|
-
|
|
128
|
+
### `ExecutionResult`
|
|
129
|
+
|
|
130
|
+
Result object returned by all execution methods.
|
|
131
|
+
|
|
132
|
+
```typescript
|
|
133
|
+
interface ExecutionResult {
|
|
134
|
+
stdout: string;
|
|
135
|
+
stderr: string;
|
|
136
|
+
exitCode: number;
|
|
137
|
+
executionTime: number;
|
|
138
|
+
sandboxId: string;
|
|
139
|
+
provider: string;
|
|
140
|
+
}
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
### `SandboxInfo`
|
|
144
|
+
|
|
145
|
+
Information about a sandbox instance.
|
|
146
|
+
|
|
147
|
+
```typescript
|
|
148
|
+
interface SandboxInfo {
|
|
149
|
+
id: string;
|
|
150
|
+
provider: string;
|
|
151
|
+
runtime: string;
|
|
152
|
+
status: 'running' | 'stopped';
|
|
153
|
+
createdAt: Date;
|
|
154
|
+
timeout: number;
|
|
155
|
+
metadata?: Record<string, any>;
|
|
156
|
+
}
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
## Configuration
|
|
160
|
+
|
|
161
|
+
### Environment Variables
|
|
162
|
+
|
|
163
|
+
Each provider requires specific environment variables:
|
|
130
164
|
|
|
131
|
-
```
|
|
132
|
-
|
|
133
|
-
|
|
165
|
+
```bash
|
|
166
|
+
# E2B
|
|
167
|
+
E2B_API_KEY=your_e2b_api_key
|
|
168
|
+
|
|
169
|
+
# Vercel
|
|
170
|
+
VERCEL_TOKEN=your_vercel_token
|
|
171
|
+
VERCEL_TEAM_ID=your_team_id
|
|
172
|
+
VERCEL_PROJECT_ID=your_project_id
|
|
173
|
+
|
|
174
|
+
# Cloudflare (Workers environment only)
|
|
175
|
+
# Requires Durable Object bindings in wrangler.toml
|
|
134
176
|
```
|
|
135
177
|
|
|
136
|
-
|
|
178
|
+
### Provider Configuration
|
|
137
179
|
|
|
138
|
-
```
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
180
|
+
```typescript
|
|
181
|
+
import { ComputeSDK } from 'computesdk';
|
|
182
|
+
import { e2b } from '@computesdk/e2b';
|
|
183
|
+
import { vercel } from '@computesdk/vercel';
|
|
184
|
+
|
|
185
|
+
const sdk = new ComputeSDK({
|
|
186
|
+
preferredProviders: ['e2b', 'vercel'], // Order of preference
|
|
187
|
+
timeout: 300000, // Global timeout (5 minutes)
|
|
188
|
+
retryAttempts: 3 // Retry failed executions
|
|
189
|
+
});
|
|
142
190
|
|
|
143
|
-
//
|
|
144
|
-
|
|
145
|
-
|
|
191
|
+
// Or configure providers individually
|
|
192
|
+
const customSandbox = e2b({
|
|
193
|
+
timeout: 600000, // 10 minutes
|
|
194
|
+
template: 'python-data-science'
|
|
195
|
+
});
|
|
146
196
|
```
|
|
147
197
|
|
|
148
|
-
##
|
|
198
|
+
## Examples
|
|
199
|
+
|
|
200
|
+
### Data Processing
|
|
149
201
|
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
- Automatic reconnection on unexpected disconnections
|
|
202
|
+
```typescript
|
|
203
|
+
import { executeSandbox } from 'computesdk';
|
|
204
|
+
import { e2b } from '@computesdk/e2b';
|
|
154
205
|
|
|
155
|
-
|
|
206
|
+
const result = await executeSandbox({
|
|
207
|
+
sandbox: e2b(),
|
|
208
|
+
code: `
|
|
209
|
+
import pandas as pd
|
|
210
|
+
import numpy as np
|
|
156
211
|
|
|
157
|
-
|
|
212
|
+
# Create sample data
|
|
213
|
+
data = pd.DataFrame({
|
|
214
|
+
'sales': [100, 150, 200, 120, 180],
|
|
215
|
+
'profit': [20, 30, 45, 25, 40]
|
|
216
|
+
})
|
|
158
217
|
|
|
159
|
-
|
|
160
|
-
|
|
218
|
+
# Calculate metrics
|
|
219
|
+
total_sales = data['sales'].sum()
|
|
220
|
+
avg_profit = data['profit'].mean()
|
|
221
|
+
profit_margin = (data['profit'].sum() / total_sales) * 100
|
|
222
|
+
|
|
223
|
+
print(f"Total Sales: ${total_sales}")
|
|
224
|
+
print(f"Average Profit: ${avg_profit:.2f}")
|
|
225
|
+
print(f"Profit Margin: {profit_margin:.1f}%")
|
|
226
|
+
`
|
|
227
|
+
});
|
|
228
|
+
|
|
229
|
+
console.log(result.stdout);
|
|
161
230
|
```
|
|
162
231
|
|
|
163
|
-
|
|
232
|
+
### Web API Simulation
|
|
233
|
+
|
|
234
|
+
```typescript
|
|
235
|
+
import { executeSandbox } from 'computesdk';
|
|
236
|
+
import { vercel } from '@computesdk/vercel';
|
|
237
|
+
|
|
238
|
+
const result = await executeSandbox({
|
|
239
|
+
sandbox: vercel({ runtime: 'node' }),
|
|
240
|
+
code: `
|
|
241
|
+
const express = require('express');
|
|
242
|
+
const app = express();
|
|
243
|
+
|
|
244
|
+
// Simulate API routes
|
|
245
|
+
const routes = {
|
|
246
|
+
'/api/users': { users: ['Alice', 'Bob', 'Charlie'] },
|
|
247
|
+
'/api/stats': { active: 150, total: 1000 }
|
|
248
|
+
};
|
|
164
249
|
|
|
165
|
-
|
|
250
|
+
// Process request
|
|
251
|
+
const path = '/api/users';
|
|
252
|
+
const response = routes[path] || { error: 'Not found' };
|
|
166
253
|
|
|
167
|
-
|
|
168
|
-
|
|
254
|
+
console.log('API Response:', JSON.stringify(response, null, 2));
|
|
255
|
+
`
|
|
256
|
+
});
|
|
257
|
+
|
|
258
|
+
console.log(result.stdout);
|
|
169
259
|
```
|
|
170
260
|
|
|
171
|
-
|
|
261
|
+
### Edge Computing
|
|
262
|
+
|
|
263
|
+
```typescript
|
|
264
|
+
import { executeSandbox } from 'computesdk';
|
|
265
|
+
import { cloudflare } from '@computesdk/cloudflare';
|
|
266
|
+
|
|
267
|
+
// Within a Cloudflare Worker
|
|
268
|
+
export default {
|
|
269
|
+
async fetch(request: Request, env: Env): Promise<Response> {
|
|
270
|
+
const result = await executeSandbox({
|
|
271
|
+
sandbox: cloudflare({ env }),
|
|
272
|
+
code: `
|
|
273
|
+
import json
|
|
274
|
+
from datetime import datetime
|
|
275
|
+
|
|
276
|
+
# Process request data
|
|
277
|
+
data = {
|
|
278
|
+
"timestamp": datetime.now().isoformat(),
|
|
279
|
+
"region": "auto",
|
|
280
|
+
"processed": True
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
print(json.dumps(data))
|
|
284
|
+
`
|
|
285
|
+
});
|
|
172
286
|
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
287
|
+
return new Response(result.stdout, {
|
|
288
|
+
headers: { 'Content-Type': 'application/json' }
|
|
289
|
+
});
|
|
290
|
+
}
|
|
291
|
+
};
|
|
292
|
+
```
|
|
177
293
|
|
|
178
294
|
## Error Handling
|
|
179
295
|
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
296
|
+
ComputeSDK provides comprehensive error handling:
|
|
297
|
+
|
|
298
|
+
```typescript
|
|
299
|
+
import {
|
|
300
|
+
ExecutionError,
|
|
301
|
+
TimeoutError,
|
|
302
|
+
AuthenticationError,
|
|
303
|
+
QuotaExceededError
|
|
304
|
+
} from 'computesdk';
|
|
305
|
+
|
|
306
|
+
try {
|
|
307
|
+
const result = await executeSandbox({
|
|
308
|
+
sandbox: e2b(),
|
|
309
|
+
code: 'print("Hello World")'
|
|
310
|
+
});
|
|
311
|
+
} catch (error) {
|
|
312
|
+
if (error instanceof TimeoutError) {
|
|
313
|
+
console.error('Execution timed out');
|
|
314
|
+
} else if (error instanceof AuthenticationError) {
|
|
315
|
+
console.error('Check your API credentials');
|
|
316
|
+
} else if (error instanceof QuotaExceededError) {
|
|
317
|
+
console.error('API quota exceeded');
|
|
318
|
+
} else if (error instanceof ExecutionError) {
|
|
319
|
+
console.error('Code execution failed:', error.stderr);
|
|
320
|
+
} else {
|
|
321
|
+
console.error('Unknown error:', error.message);
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
```
|
|
325
|
+
|
|
326
|
+
## Provider Comparison
|
|
327
|
+
|
|
328
|
+
| Provider | Runtimes | Max Timeout | Use Cases |
|
|
329
|
+
|----------|----------|-------------|-----------|
|
|
330
|
+
| E2B | Python | 5 minutes | Data science, AI/ML |
|
|
331
|
+
| Vercel | Node.js, Python | 45 minutes | Web apps, APIs |
|
|
332
|
+
| Cloudflare | Python, Node.js | 30 seconds | Edge computing, real-time |
|
|
333
|
+
| Fly.io | Custom | Variable | Custom containers |
|
|
334
|
+
|
|
335
|
+
## Contributing
|
|
336
|
+
|
|
337
|
+
We welcome contributions! Please see our [Contributing Guide](https://github.com/computesdk/computesdk/blob/main/CONTRIBUTING.md) for details.
|
|
338
|
+
|
|
339
|
+
### Adding New Providers
|
|
340
|
+
|
|
341
|
+
1. Implement the `ComputeSpecification` interface
|
|
342
|
+
2. Add comprehensive tests
|
|
343
|
+
3. Include documentation and examples
|
|
344
|
+
4. Submit a pull request
|
|
345
|
+
|
|
346
|
+
## License
|
|
347
|
+
|
|
348
|
+
MIT - see [LICENSE](https://github.com/computesdk/computesdk/blob/main/LICENSE) for details.
|
|
349
|
+
|
|
350
|
+
## Support
|
|
351
|
+
|
|
352
|
+
- [GitHub Issues](https://github.com/computesdk/computesdk/issues)
|
|
353
|
+
- [Documentation](https://github.com/computesdk/computesdk)
|
|
354
|
+
- [Examples](https://github.com/computesdk/computesdk/tree/main/examples)
|
|
355
|
+
|
|
356
|
+
---
|
|
184
357
|
|
|
185
|
-
|
|
358
|
+
Made with ❤️ by the ComputeSDK team
|