@boxlite-ai/boxlite 0.1.0

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,232 @@
1
+ "use strict";
2
+ /**
3
+ * SimpleBox - Foundation for specialized container types.
4
+ *
5
+ * Provides common functionality for all specialized boxes (CodeBox, BrowserBox, etc.)
6
+ * This class encapsulates common patterns:
7
+ * 1. Automatic runtime lifecycle management
8
+ * 2. Command execution with output collection
9
+ * 3. Try/finally cleanup patterns
10
+ */
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.SimpleBox = void 0;
13
+ const native_1 = require("./native");
14
+ /**
15
+ * Base class for specialized container types.
16
+ *
17
+ * This class provides the foundation for all specialized boxes:
18
+ * - CodeBox: Python code execution sandbox
19
+ * - BrowserBox: Browser automation
20
+ * - ComputerBox: Desktop automation
21
+ * - InteractiveBox: PTY terminal sessions
22
+ *
23
+ * ## Usage
24
+ *
25
+ * SimpleBox can be used directly for simple command execution:
26
+ *
27
+ * ```typescript
28
+ * const box = new SimpleBox({ image: 'alpine:latest' });
29
+ * try {
30
+ * const result = await box.exec('ls', '-la', '/');
31
+ * console.log(result.stdout);
32
+ * } finally {
33
+ * await box.stop();
34
+ * }
35
+ * ```
36
+ *
37
+ * Or extended for specialized use cases:
38
+ *
39
+ * ```typescript
40
+ * class MyBox extends SimpleBox {
41
+ * constructor() {
42
+ * super({ image: 'my-custom-image:latest' });
43
+ * }
44
+ *
45
+ * async myMethod() {
46
+ * const result = await this.exec('my-command');
47
+ * return result.stdout;
48
+ * }
49
+ * }
50
+ * ```
51
+ */
52
+ class SimpleBox {
53
+ /**
54
+ * Create a new SimpleBox.
55
+ *
56
+ * @param options - Box configuration options
57
+ *
58
+ * @example
59
+ * ```typescript
60
+ * const box = new SimpleBox({
61
+ * image: 'python:slim',
62
+ * memoryMib: 512,
63
+ * cpus: 2,
64
+ * name: 'my-box'
65
+ * });
66
+ * ```
67
+ */
68
+ constructor(options = {}) {
69
+ const JsBoxlite = (0, native_1.getJsBoxlite)();
70
+ // Use provided runtime or get global default
71
+ if (options.runtime) {
72
+ this._runtime = options.runtime;
73
+ }
74
+ else {
75
+ this._runtime = JsBoxlite.withDefaultConfig();
76
+ }
77
+ // Convert options to BoxOptions format
78
+ const boxOpts = {
79
+ image: options.image,
80
+ cpus: options.cpus,
81
+ memoryMib: options.memoryMib,
82
+ autoRemove: options.autoRemove ?? true,
83
+ detach: options.detach ?? false,
84
+ workingDir: options.workingDir,
85
+ env: options.env
86
+ ? Object.entries(options.env).map(([key, value]) => ({ key, value }))
87
+ : undefined,
88
+ volumes: options.volumes,
89
+ ports: options.ports,
90
+ };
91
+ this._name = options.name;
92
+ this._box = this._runtime.create(boxOpts, options.name);
93
+ }
94
+ /**
95
+ * Get the box ID (ULID format).
96
+ */
97
+ get id() {
98
+ return this._box.id;
99
+ }
100
+ /**
101
+ * Get the box name (if set).
102
+ */
103
+ get name() {
104
+ return this._name;
105
+ }
106
+ /**
107
+ * Get box metadata.
108
+ */
109
+ info() {
110
+ return this._box.info();
111
+ }
112
+ async exec(cmd, argsOrFirstArg, envOrSecondArg, ...restArgs) {
113
+ // Parse overloaded arguments
114
+ let args;
115
+ let env;
116
+ if (Array.isArray(argsOrFirstArg)) {
117
+ // exec(cmd, args[], env?)
118
+ args = argsOrFirstArg;
119
+ env = envOrSecondArg;
120
+ }
121
+ else {
122
+ // exec(cmd, ...args, env?)
123
+ // Collect all arguments
124
+ const allArgs = [
125
+ argsOrFirstArg,
126
+ envOrSecondArg,
127
+ ...restArgs,
128
+ ].filter(a => a !== undefined);
129
+ // Check if last arg is env object (before filtering to strings)
130
+ const lastArg = allArgs[allArgs.length - 1];
131
+ if (lastArg && typeof lastArg === 'object' && !Array.isArray(lastArg)) {
132
+ env = lastArg;
133
+ args = allArgs.slice(0, -1).filter((a) => typeof a === 'string');
134
+ }
135
+ else {
136
+ env = undefined;
137
+ args = allArgs.filter((a) => typeof a === 'string');
138
+ }
139
+ }
140
+ // Convert env to array of tuples
141
+ const envArray = env
142
+ ? Object.entries(env).map(([k, v]) => [k, v])
143
+ : undefined;
144
+ // Execute via Rust (returns Execution)
145
+ const execution = await this._box.exec(cmd, args, envArray, false);
146
+ // Collect stdout and stderr
147
+ const stdoutLines = [];
148
+ const stderrLines = [];
149
+ // Get streams
150
+ let stdout;
151
+ let stderr;
152
+ try {
153
+ stdout = await execution.stdout();
154
+ }
155
+ catch (err) {
156
+ // Stream not available (expected for some commands)
157
+ stdout = null;
158
+ }
159
+ try {
160
+ stderr = await execution.stderr();
161
+ }
162
+ catch (err) {
163
+ // Stream not available (expected for some commands)
164
+ stderr = null;
165
+ }
166
+ // Read stdout
167
+ if (stdout) {
168
+ try {
169
+ while (true) {
170
+ const line = await stdout.next();
171
+ if (line === null)
172
+ break;
173
+ stdoutLines.push(line);
174
+ }
175
+ }
176
+ catch (err) {
177
+ // Stream ended or error occurred
178
+ }
179
+ }
180
+ // Read stderr
181
+ if (stderr) {
182
+ try {
183
+ while (true) {
184
+ const line = await stderr.next();
185
+ if (line === null)
186
+ break;
187
+ stderrLines.push(line);
188
+ }
189
+ }
190
+ catch (err) {
191
+ // Stream ended or error occurred
192
+ }
193
+ }
194
+ // Wait for completion
195
+ const result = await execution.wait();
196
+ return {
197
+ exitCode: result.exitCode,
198
+ stdout: stdoutLines.join(''),
199
+ stderr: stderrLines.join(''),
200
+ };
201
+ }
202
+ /**
203
+ * Stop the box.
204
+ *
205
+ * Sends a graceful shutdown signal to the VM. If `autoRemove` is true
206
+ * (default), the box files will be deleted after stopping.
207
+ *
208
+ * @example
209
+ * ```typescript
210
+ * await box.stop();
211
+ * console.log('Box stopped');
212
+ * ```
213
+ */
214
+ async stop() {
215
+ await this._box.stop();
216
+ }
217
+ /**
218
+ * Implement async disposable pattern (TypeScript 5.2+).
219
+ *
220
+ * Allows using `await using` syntax for automatic cleanup:
221
+ *
222
+ * ```typescript
223
+ * await using box = new SimpleBox({ image: 'alpine' });
224
+ * // Box automatically stopped when leaving scope
225
+ * ```
226
+ */
227
+ async [Symbol.asyncDispose]() {
228
+ await this.stop();
229
+ }
230
+ }
231
+ exports.SimpleBox = SimpleBox;
232
+ //# sourceMappingURL=simplebox.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"simplebox.js","sourceRoot":"","sources":["../lib/simplebox.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,57 @@
1
+ {
2
+ "name": "@boxlite-ai/boxlite",
3
+ "version": "0.1.0",
4
+ "description": "BoxLite - Embeddable micro-VM runtime for secure, isolated code execution",
5
+ "main": "dist/index.js",
6
+ "types": "dist/index.d.ts",
7
+ "files": [
8
+ "dist"
9
+ ],
10
+ "scripts": {
11
+ "build": "tsc",
12
+ "build:debug": "tsc",
13
+ "test": "vitest run",
14
+ "test:watch": "vitest",
15
+ "prepublishOnly": "npm run build"
16
+ },
17
+ "devDependencies": {
18
+ "@napi-rs/cli": "^3.0.0-alpha.62",
19
+ "@types/node": "^22.0.0",
20
+ "typescript": "^5.2.0",
21
+ "vitest": "^2.0.0"
22
+ },
23
+ "optionalDependencies": {
24
+ "@boxlite-ai/boxlite-darwin-arm64": "0.1.0",
25
+ "@boxlite-ai/boxlite-darwin-x64": "0.1.0",
26
+ "@boxlite-ai/boxlite-linux-x64-gnu": "0.1.0",
27
+ "@boxlite-ai/boxlite-linux-arm64-gnu": "0.1.0"
28
+ },
29
+ "keywords": [
30
+ "boxlite",
31
+ "sandbox",
32
+ "container",
33
+ "virtualization",
34
+ "vm",
35
+ "kvm",
36
+ "hypervisor",
37
+ "isolation",
38
+ "security",
39
+ "code-execution"
40
+ ],
41
+ "license": "Apache-2.0",
42
+ "repository": {
43
+ "type": "git",
44
+ "url": "https://github.com/boxlite-ai/boxlite.git",
45
+ "directory": "sdks/node"
46
+ },
47
+ "bugs": {
48
+ "url": "https://github.com/boxlite-ai/boxlite/issues"
49
+ },
50
+ "engines": {
51
+ "node": ">=18.0.0"
52
+ },
53
+ "author": "Dorian Zheng <xingzhengde72@gmail.com>",
54
+ "dependencies": {
55
+ "@node-rs/helper": "^1.6.0"
56
+ }
57
+ }