@sandboxxjs/core 0.5.1 → 2.0.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.
Files changed (50) hide show
  1. package/.turbo/turbo-build.log +1 -0
  2. package/CHANGELOG.md +17 -0
  3. package/dist/allocator.d.ts +44 -0
  4. package/dist/allocator.d.ts.map +1 -0
  5. package/dist/allocator.js +14 -0
  6. package/dist/allocator.js.map +1 -0
  7. package/dist/client.d.ts +50 -0
  8. package/dist/client.d.ts.map +1 -0
  9. package/dist/client.js +21 -0
  10. package/dist/client.js.map +1 -0
  11. package/dist/create-client.d.ts +11 -0
  12. package/dist/create-client.d.ts.map +1 -0
  13. package/dist/create-client.js +159 -0
  14. package/dist/create-client.js.map +1 -0
  15. package/dist/index.d.ts +25 -326
  16. package/dist/index.d.ts.map +1 -0
  17. package/dist/index.js +20 -16858
  18. package/dist/index.js.map +1 -295
  19. package/dist/protocol.d.ts +96 -0
  20. package/dist/protocol.d.ts.map +1 -0
  21. package/dist/protocol.js +15 -0
  22. package/dist/protocol.js.map +1 -0
  23. package/dist/provider.d.ts +54 -0
  24. package/dist/provider.d.ts.map +1 -0
  25. package/dist/provider.js +14 -0
  26. package/dist/provider.js.map +1 -0
  27. package/dist/registry.d.ts +28 -0
  28. package/dist/registry.d.ts.map +1 -0
  29. package/dist/registry.js +19 -0
  30. package/dist/registry.js.map +1 -0
  31. package/dist/router.d.ts +24 -0
  32. package/dist/router.d.ts.map +1 -0
  33. package/dist/router.js +18 -0
  34. package/dist/router.js.map +1 -0
  35. package/dist/sandbox.d.ts +54 -0
  36. package/dist/sandbox.d.ts.map +1 -0
  37. package/dist/sandbox.js +15 -0
  38. package/dist/sandbox.js.map +1 -0
  39. package/package.json +10 -35
  40. package/src/allocator.ts +48 -0
  41. package/src/client.ts +51 -0
  42. package/src/create-client.ts +187 -0
  43. package/src/index.ts +45 -0
  44. package/src/protocol.ts +133 -0
  45. package/src/provider.ts +54 -0
  46. package/src/registry.ts +29 -0
  47. package/src/router.ts +25 -0
  48. package/src/sandbox.ts +52 -0
  49. package/tsconfig.json +12 -0
  50. package/README.md +0 -60
@@ -0,0 +1 @@
1
+ $ tsc
package/CHANGELOG.md ADDED
@@ -0,0 +1,17 @@
1
+ # @sandboxxjs/core
2
+
3
+ ## 2.0.0
4
+
5
+ ### Major Changes
6
+
7
+ - 9c7ae4c: Complete architecture rewrite: Provider-based unified sandbox lifecycle.
8
+
9
+ Breaking changes:
10
+
11
+ - Removed old Isolator + Mixin + State architecture
12
+ - Removed @sandboxxjs/state, @sandboxxjs/cli, @sandboxxjs/cloudflare-isolator packages
13
+ - New unified lifecycle: Allocate → Prepare → Register → Ready → Command
14
+ - New SandboxProvider interface with pluggable components (Executor, FileSystem, ProcessManager)
15
+ - New @sandboxxjs/node-provider for cloud containers (child_process + node:fs)
16
+ - New @sandboxxjs/web-provider for browser WebContainer (@webcontainer/api)
17
+ - createSandboxClient(provider) replaces createSandbox()
@@ -0,0 +1,44 @@
1
+ /**
2
+ * SandboxAllocator — provisions sandbox resources.
3
+ *
4
+ * Step 1 of the lifecycle: Allocate.
5
+ *
6
+ * The allocator creates a sandbox environment and returns a SandboxContainer
7
+ * with status "pending". The sandbox is NOT ready for commands yet —
8
+ * it becomes ready only after a sandbox-client connects and registers.
9
+ *
10
+ * Lifecycle: Allocate → Prepare → Register → Ready → Command
11
+ * ^^^^^^^^
12
+ */
13
+ export type SandboxContainerType = "cloud" | "web";
14
+ export type SandboxStatus = "pending" | "ready" | "destroyed";
15
+ export interface SandboxContainer {
16
+ id: string;
17
+ type: SandboxContainerType;
18
+ status: SandboxStatus;
19
+ createdAt: number;
20
+ source?: string;
21
+ /** Connection info for sandbox-client to register */
22
+ connection: {
23
+ wsUrl: string;
24
+ token: string;
25
+ };
26
+ }
27
+ export interface AllocateRequest {
28
+ type?: SandboxContainerType;
29
+ sandboxId?: string;
30
+ source?: string;
31
+ }
32
+ export interface SandboxAllocator {
33
+ /** Allocate a sandbox — returns container with status "pending" */
34
+ allocate(request: AllocateRequest): Promise<SandboxContainer>;
35
+ /** Release sandbox resources */
36
+ deallocate(sandboxId: string): Promise<void>;
37
+ /** List all sandboxes */
38
+ list(): Promise<SandboxContainer[]>;
39
+ /** Get a single sandbox by id */
40
+ get(sandboxId: string): Promise<SandboxContainer | null>;
41
+ /** Update sandbox status (called by registry on registration) */
42
+ updateStatus(sandboxId: string, status: SandboxStatus): Promise<void>;
43
+ }
44
+ //# sourceMappingURL=allocator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"allocator.d.ts","sourceRoot":"","sources":["../src/allocator.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,MAAM,MAAM,oBAAoB,GAAG,OAAO,GAAG,KAAK,CAAC;AAEnD,MAAM,MAAM,aAAa,GAAG,SAAS,GAAG,OAAO,GAAG,WAAW,CAAC;AAE9D,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,oBAAoB,CAAC;IAC3B,MAAM,EAAE,aAAa,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,qDAAqD;IACrD,UAAU,EAAE;QACV,KAAK,EAAE,MAAM,CAAC;QACd,KAAK,EAAE,MAAM,CAAC;KACf,CAAC;CACH;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,CAAC,EAAE,oBAAoB,CAAC;IAC5B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,gBAAgB;IAC/B,mEAAmE;IACnE,QAAQ,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAAC;IAC9D,gCAAgC;IAChC,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7C,yBAAyB;IACzB,IAAI,IAAI,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAAC;IACpC,iCAAiC;IACjC,GAAG,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAAC;IACzD,iEAAiE;IACjE,YAAY,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACvE"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * SandboxAllocator — provisions sandbox resources.
3
+ *
4
+ * Step 1 of the lifecycle: Allocate.
5
+ *
6
+ * The allocator creates a sandbox environment and returns a SandboxContainer
7
+ * with status "pending". The sandbox is NOT ready for commands yet —
8
+ * it becomes ready only after a sandbox-client connects and registers.
9
+ *
10
+ * Lifecycle: Allocate → Prepare → Register → Ready → Command
11
+ * ^^^^^^^^
12
+ */
13
+ export {};
14
+ //# sourceMappingURL=allocator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"allocator.js","sourceRoot":"","sources":["../src/allocator.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG"}
@@ -0,0 +1,50 @@
1
+ /**
2
+ * SandboxClient — the agent that runs inside every sandbox environment.
3
+ *
4
+ * Step 2-3 of the lifecycle: Prepare → Register.
5
+ *
6
+ * After allocation, the sandbox environment starts a SandboxClient.
7
+ * The client connects to the service via WebSocket, registers itself,
8
+ * and then listens for commands (exec, fs, process operations).
9
+ *
10
+ * The client is platform-agnostic. Platform differences are injected
11
+ * via SandboxProvider, which supplies Executor, FileSystem, and
12
+ * ProcessManager components:
13
+ * - node-provider: child_process + node:fs
14
+ * - web-provider: @webcontainer/api
15
+ * - Future: Docker, SSH, etc.
16
+ *
17
+ * Lifecycle: Allocate → Prepare → Register → Ready → Command
18
+ * ^^^^^^^^^^^^^^^^^
19
+ */
20
+ /**
21
+ * Connection options for a sandbox-client.
22
+ */
23
+ export interface SandboxClientOptions {
24
+ /** WebSocket URL of the sandbox service registry */
25
+ wsUrl: string;
26
+ /** Sandbox identifier */
27
+ sandboxId: string;
28
+ /** Authentication token */
29
+ token: string;
30
+ /** Heartbeat interval in milliseconds (default: 30000) */
31
+ heartbeatInterval?: number;
32
+ }
33
+ /**
34
+ * SandboxClient — connects to service, receives commands, executes via provider components.
35
+ *
36
+ * Usage:
37
+ * const provider = new NodeProvider(); // or WebContainerProvider
38
+ * const client = createSandboxClient(provider);
39
+ * await client.connect({ wsUrl, sandboxId, token });
40
+ * // Client is now registered and listening for commands
41
+ */
42
+ export interface SandboxClient {
43
+ /** Connect to the sandbox service and register */
44
+ connect(options: SandboxClientOptions): Promise<void>;
45
+ /** Disconnect from the service */
46
+ disconnect(): Promise<void>;
47
+ /** Whether the client is connected and registered */
48
+ readonly connected: boolean;
49
+ }
50
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,oDAAoD;IACpD,KAAK,EAAE,MAAM,CAAC;IACd,yBAAyB;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,2BAA2B;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,0DAA0D;IAC1D,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED;;;;;;;;GAQG;AACH,MAAM,WAAW,aAAa;IAC5B,kDAAkD;IAClD,OAAO,CAAC,OAAO,EAAE,oBAAoB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACtD,kCAAkC;IAClC,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5B,qDAAqD;IACrD,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;CAC7B"}
package/dist/client.js ADDED
@@ -0,0 +1,21 @@
1
+ /**
2
+ * SandboxClient — the agent that runs inside every sandbox environment.
3
+ *
4
+ * Step 2-3 of the lifecycle: Prepare → Register.
5
+ *
6
+ * After allocation, the sandbox environment starts a SandboxClient.
7
+ * The client connects to the service via WebSocket, registers itself,
8
+ * and then listens for commands (exec, fs, process operations).
9
+ *
10
+ * The client is platform-agnostic. Platform differences are injected
11
+ * via SandboxProvider, which supplies Executor, FileSystem, and
12
+ * ProcessManager components:
13
+ * - node-provider: child_process + node:fs
14
+ * - web-provider: @webcontainer/api
15
+ * - Future: Docker, SSH, etc.
16
+ *
17
+ * Lifecycle: Allocate → Prepare → Register → Ready → Command
18
+ * ^^^^^^^^^^^^^^^^^
19
+ */
20
+ export {};
21
+ //# sourceMappingURL=client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * createSandboxClient — the runtime implementation of SandboxClient.
3
+ *
4
+ * Platform-agnostic: uses standard WebSocket API (available in Node 22+, browsers).
5
+ * Platform differences are injected via SandboxProvider, which supplies
6
+ * Executor, FileSystem, and ProcessManager components.
7
+ */
8
+ import type { SandboxClient } from "./client";
9
+ import type { SandboxProvider } from "./provider";
10
+ export declare function createSandboxClient(provider: SandboxProvider): SandboxClient;
11
+ //# sourceMappingURL=create-client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create-client.d.ts","sourceRoot":"","sources":["../src/create-client.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAwB,MAAM,UAAU,CAAC;AAQpE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAElD,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,eAAe,GAAG,aAAa,CAwK5E"}
@@ -0,0 +1,159 @@
1
+ /**
2
+ * createSandboxClient — the runtime implementation of SandboxClient.
3
+ *
4
+ * Platform-agnostic: uses standard WebSocket API (available in Node 22+, browsers).
5
+ * Platform differences are injected via SandboxProvider, which supplies
6
+ * Executor, FileSystem, and ProcessManager components.
7
+ */
8
+ export function createSandboxClient(provider) {
9
+ const executor = provider.createExecutor();
10
+ const fs = provider.createFileSystem();
11
+ const pm = provider.createProcessManager();
12
+ let ws = null;
13
+ let heartbeatTimer = null;
14
+ let isConnected = false;
15
+ async function connect(options) {
16
+ const { wsUrl, sandboxId, token, heartbeatInterval = 30_000 } = options;
17
+ return new Promise((resolve, reject) => {
18
+ ws = new WebSocket(wsUrl);
19
+ ws.onopen = () => {
20
+ // Step 3: Register
21
+ const registerMsg = { type: "register", sandboxId, token };
22
+ ws.send(JSON.stringify(registerMsg));
23
+ };
24
+ ws.onmessage = (event) => {
25
+ const data = typeof event.data === "string" ? event.data : "";
26
+ let msg;
27
+ try {
28
+ msg = JSON.parse(data);
29
+ }
30
+ catch {
31
+ return;
32
+ }
33
+ if (msg.type === "registered") {
34
+ // Step 4: Ready
35
+ isConnected = true;
36
+ heartbeatTimer = setInterval(() => {
37
+ if (ws?.readyState === WebSocket.OPEN) {
38
+ const hb = { type: "heartbeat" };
39
+ ws.send(JSON.stringify(hb));
40
+ }
41
+ }, heartbeatInterval);
42
+ resolve();
43
+ return;
44
+ }
45
+ // Step 5: Command — handle and respond
46
+ handleCommand(msg);
47
+ };
48
+ ws.onerror = () => {
49
+ if (!isConnected)
50
+ reject(new Error("WebSocket connection failed"));
51
+ };
52
+ ws.onclose = () => {
53
+ cleanup();
54
+ };
55
+ });
56
+ }
57
+ async function handleCommand(msg) {
58
+ if (!ws || ws.readyState !== WebSocket.OPEN)
59
+ return;
60
+ try {
61
+ switch (msg.type) {
62
+ // Executor
63
+ case "exec": {
64
+ const result = await executor.exec(msg.command, {
65
+ cwd: msg.cwd,
66
+ timeout: msg.timeout,
67
+ });
68
+ const reply = {
69
+ type: "result",
70
+ id: msg.id,
71
+ stdout: result.stdout,
72
+ stderr: result.stderr,
73
+ exitCode: result.exitCode,
74
+ };
75
+ ws.send(JSON.stringify(reply));
76
+ break;
77
+ }
78
+ // FileSystem
79
+ case "fs.read": {
80
+ const content = await fs.readFile(msg.path);
81
+ sendFsResult(msg.id, { content });
82
+ break;
83
+ }
84
+ case "fs.write": {
85
+ await fs.writeFile(msg.path, msg.content);
86
+ sendFsResult(msg.id, { written: true });
87
+ break;
88
+ }
89
+ case "fs.list": {
90
+ const files = await fs.listFiles(msg.path);
91
+ sendFsResult(msg.id, files);
92
+ break;
93
+ }
94
+ case "fs.mkdir": {
95
+ await fs.mkdir(msg.path, { recursive: msg.recursive });
96
+ sendFsResult(msg.id, { created: true });
97
+ break;
98
+ }
99
+ case "fs.delete": {
100
+ await fs.deleteFile(msg.path);
101
+ sendFsResult(msg.id, { deleted: true });
102
+ break;
103
+ }
104
+ // ProcessManager
105
+ case "process.start": {
106
+ const proc = await pm.start(msg.command, { cwd: msg.cwd });
107
+ sendFsResult(msg.id, proc);
108
+ break;
109
+ }
110
+ case "process.kill": {
111
+ await pm.kill(msg.processId);
112
+ sendFsResult(msg.id, { killed: true });
113
+ break;
114
+ }
115
+ case "process.list": {
116
+ const procs = await pm.list();
117
+ sendFsResult(msg.id, procs);
118
+ break;
119
+ }
120
+ }
121
+ }
122
+ catch (err) {
123
+ const errorMsg = {
124
+ type: "error",
125
+ id: msg.id || "unknown",
126
+ message: err instanceof Error ? err.message : "Command failed",
127
+ };
128
+ ws.send(JSON.stringify(errorMsg));
129
+ }
130
+ }
131
+ function sendFsResult(id, data) {
132
+ if (!ws || ws.readyState !== WebSocket.OPEN)
133
+ return;
134
+ const reply = { type: "fs.result", id, data };
135
+ ws.send(JSON.stringify(reply));
136
+ }
137
+ function cleanup() {
138
+ isConnected = false;
139
+ if (heartbeatTimer) {
140
+ clearInterval(heartbeatTimer);
141
+ heartbeatTimer = null;
142
+ }
143
+ ws = null;
144
+ }
145
+ async function disconnect() {
146
+ if (ws) {
147
+ ws.close();
148
+ cleanup();
149
+ }
150
+ }
151
+ return {
152
+ connect,
153
+ disconnect,
154
+ get connected() {
155
+ return isConnected;
156
+ },
157
+ };
158
+ }
159
+ //# sourceMappingURL=create-client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create-client.js","sourceRoot":"","sources":["../src/create-client.ts"],"names":[],"mappings":"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"}