@sandbox-engine/sdk 0.2.1 → 0.2.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/dist/index.d.mts +20 -6
- package/dist/index.d.ts +20 -6
- package/dist/index.js +59 -15
- package/dist/index.mjs +59 -15
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -1,6 +1,20 @@
|
|
|
1
|
-
import WebSocket from 'ws';
|
|
2
1
|
import { EventEmitter } from 'node:events';
|
|
3
2
|
|
|
3
|
+
interface WsLike {
|
|
4
|
+
on(event: 'message', handler: (data: unknown) => void): void;
|
|
5
|
+
on(event: 'error', handler: (err: Error) => void): void;
|
|
6
|
+
on(event: 'close', handler: () => void): void;
|
|
7
|
+
on(event: 'open', handler: () => void): void;
|
|
8
|
+
once(event: 'message', handler: (data: unknown) => void): void;
|
|
9
|
+
once(event: 'error', handler: (err: Error) => void): void;
|
|
10
|
+
once(event: 'open', handler: () => void): void;
|
|
11
|
+
send(data: string): void;
|
|
12
|
+
close(): void;
|
|
13
|
+
readyState: number;
|
|
14
|
+
readonly OPEN: number;
|
|
15
|
+
readonly CONNECTING: number;
|
|
16
|
+
}
|
|
17
|
+
|
|
4
18
|
declare class HttpClient {
|
|
5
19
|
private readonly baseUrl;
|
|
6
20
|
private readonly apiKey;
|
|
@@ -9,7 +23,7 @@ declare class HttpClient {
|
|
|
9
23
|
get<T>(path: string, query?: Record<string, string>): Promise<T>;
|
|
10
24
|
post<T>(path: string, body?: unknown, timeoutMs?: number): Promise<T>;
|
|
11
25
|
delete<T = void>(path: string, query?: Record<string, string>): Promise<T>;
|
|
12
|
-
openWebSocket(path: string):
|
|
26
|
+
openWebSocket(path: string): Promise<WsLike>;
|
|
13
27
|
}
|
|
14
28
|
|
|
15
29
|
interface SandboxOptions {
|
|
@@ -174,7 +188,7 @@ declare class Filesystem {
|
|
|
174
188
|
|
|
175
189
|
declare class Process extends EventEmitter {
|
|
176
190
|
private ws;
|
|
177
|
-
constructor(ws:
|
|
191
|
+
constructor(ws: WsLike);
|
|
178
192
|
kill(): void;
|
|
179
193
|
wait(): Promise<ExecResult>;
|
|
180
194
|
}
|
|
@@ -198,9 +212,9 @@ declare class BackgroundProcess {
|
|
|
198
212
|
}>;
|
|
199
213
|
waitForPort(port: number, opts?: WaitForPortOptions): Promise<void>;
|
|
200
214
|
waitForLog(pattern: string | RegExp, opts?: WaitForLogOptions): Promise<string>;
|
|
201
|
-
streamLogs(opts?: StreamLogsOptions): {
|
|
215
|
+
streamLogs(opts?: StreamLogsOptions): Promise<{
|
|
202
216
|
close: () => void;
|
|
203
|
-
}
|
|
217
|
+
}>;
|
|
204
218
|
}
|
|
205
219
|
declare class ProcessManager {
|
|
206
220
|
private readonly sandboxId;
|
|
@@ -215,7 +229,7 @@ declare class ProcessManager {
|
|
|
215
229
|
|
|
216
230
|
declare class Terminal extends EventEmitter {
|
|
217
231
|
private ws;
|
|
218
|
-
constructor(ws:
|
|
232
|
+
constructor(ws: WsLike);
|
|
219
233
|
write(data: string): void;
|
|
220
234
|
resize(cols: number, rows: number): void;
|
|
221
235
|
close(): void;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,20 @@
|
|
|
1
|
-
import WebSocket from 'ws';
|
|
2
1
|
import { EventEmitter } from 'node:events';
|
|
3
2
|
|
|
3
|
+
interface WsLike {
|
|
4
|
+
on(event: 'message', handler: (data: unknown) => void): void;
|
|
5
|
+
on(event: 'error', handler: (err: Error) => void): void;
|
|
6
|
+
on(event: 'close', handler: () => void): void;
|
|
7
|
+
on(event: 'open', handler: () => void): void;
|
|
8
|
+
once(event: 'message', handler: (data: unknown) => void): void;
|
|
9
|
+
once(event: 'error', handler: (err: Error) => void): void;
|
|
10
|
+
once(event: 'open', handler: () => void): void;
|
|
11
|
+
send(data: string): void;
|
|
12
|
+
close(): void;
|
|
13
|
+
readyState: number;
|
|
14
|
+
readonly OPEN: number;
|
|
15
|
+
readonly CONNECTING: number;
|
|
16
|
+
}
|
|
17
|
+
|
|
4
18
|
declare class HttpClient {
|
|
5
19
|
private readonly baseUrl;
|
|
6
20
|
private readonly apiKey;
|
|
@@ -9,7 +23,7 @@ declare class HttpClient {
|
|
|
9
23
|
get<T>(path: string, query?: Record<string, string>): Promise<T>;
|
|
10
24
|
post<T>(path: string, body?: unknown, timeoutMs?: number): Promise<T>;
|
|
11
25
|
delete<T = void>(path: string, query?: Record<string, string>): Promise<T>;
|
|
12
|
-
openWebSocket(path: string):
|
|
26
|
+
openWebSocket(path: string): Promise<WsLike>;
|
|
13
27
|
}
|
|
14
28
|
|
|
15
29
|
interface SandboxOptions {
|
|
@@ -174,7 +188,7 @@ declare class Filesystem {
|
|
|
174
188
|
|
|
175
189
|
declare class Process extends EventEmitter {
|
|
176
190
|
private ws;
|
|
177
|
-
constructor(ws:
|
|
191
|
+
constructor(ws: WsLike);
|
|
178
192
|
kill(): void;
|
|
179
193
|
wait(): Promise<ExecResult>;
|
|
180
194
|
}
|
|
@@ -198,9 +212,9 @@ declare class BackgroundProcess {
|
|
|
198
212
|
}>;
|
|
199
213
|
waitForPort(port: number, opts?: WaitForPortOptions): Promise<void>;
|
|
200
214
|
waitForLog(pattern: string | RegExp, opts?: WaitForLogOptions): Promise<string>;
|
|
201
|
-
streamLogs(opts?: StreamLogsOptions): {
|
|
215
|
+
streamLogs(opts?: StreamLogsOptions): Promise<{
|
|
202
216
|
close: () => void;
|
|
203
|
-
}
|
|
217
|
+
}>;
|
|
204
218
|
}
|
|
205
219
|
declare class ProcessManager {
|
|
206
220
|
private readonly sandboxId;
|
|
@@ -215,7 +229,7 @@ declare class ProcessManager {
|
|
|
215
229
|
|
|
216
230
|
declare class Terminal extends EventEmitter {
|
|
217
231
|
private ws;
|
|
218
|
-
constructor(ws:
|
|
232
|
+
constructor(ws: WsLike);
|
|
219
233
|
write(data: string): void;
|
|
220
234
|
resize(cols: number, rows: number): void;
|
|
221
235
|
close(): void;
|
package/dist/index.js
CHANGED
|
@@ -39,8 +39,37 @@ __export(index_exports, {
|
|
|
39
39
|
});
|
|
40
40
|
module.exports = __toCommonJS(index_exports);
|
|
41
41
|
|
|
42
|
+
// src/ws-compat.ts
|
|
43
|
+
var import_node_events = require("events");
|
|
44
|
+
var WsEmitterAdapter = class extends import_node_events.EventEmitter {
|
|
45
|
+
constructor(ws) {
|
|
46
|
+
super();
|
|
47
|
+
this.ws = ws;
|
|
48
|
+
ws.accept?.();
|
|
49
|
+
ws.addEventListener("message", (e) => {
|
|
50
|
+
const raw = e.data;
|
|
51
|
+
this.emit("message", typeof raw === "string" ? raw : String(raw));
|
|
52
|
+
});
|
|
53
|
+
ws.addEventListener("error", (e) => this.emit("error", e));
|
|
54
|
+
ws.addEventListener("close", () => this.emit("close"));
|
|
55
|
+
ws.addEventListener("open", () => this.emit("open"));
|
|
56
|
+
}
|
|
57
|
+
ws;
|
|
58
|
+
OPEN = 1;
|
|
59
|
+
CONNECTING = 0;
|
|
60
|
+
get readyState() {
|
|
61
|
+
return this.ws.readyState;
|
|
62
|
+
}
|
|
63
|
+
send(data) {
|
|
64
|
+
this.ws.send(data);
|
|
65
|
+
}
|
|
66
|
+
close() {
|
|
67
|
+
this.ws.close();
|
|
68
|
+
}
|
|
69
|
+
};
|
|
70
|
+
var IS_CF_WORKERS = typeof globalThis.WebSocketPair !== "undefined";
|
|
71
|
+
|
|
42
72
|
// src/client.ts
|
|
43
|
-
var import_ws = __toESM(require("ws"));
|
|
44
73
|
var HttpClient = class {
|
|
45
74
|
constructor(baseUrl, apiKey) {
|
|
46
75
|
this.baseUrl = baseUrl;
|
|
@@ -98,11 +127,26 @@ var HttpClient = class {
|
|
|
98
127
|
if (!text) return void 0;
|
|
99
128
|
return JSON.parse(text);
|
|
100
129
|
}
|
|
101
|
-
|
|
130
|
+
// ── WebSocket ───────────────────────────────────────────────────────────────
|
|
131
|
+
// CF Workers: uses fetch() with Upgrade header (supports Authorization).
|
|
132
|
+
// Node.js: uses the ws package (installed as an optional dependency).
|
|
133
|
+
async openWebSocket(path) {
|
|
102
134
|
const wsUrl = this.baseUrl.replace(/^http/, "ws") + path;
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
135
|
+
const authHeader = `Bearer ${this.apiKey}`;
|
|
136
|
+
if (IS_CF_WORKERS) {
|
|
137
|
+
const resp = await fetch(wsUrl, {
|
|
138
|
+
headers: {
|
|
139
|
+
Upgrade: "websocket",
|
|
140
|
+
Connection: "Upgrade",
|
|
141
|
+
Authorization: authHeader
|
|
142
|
+
}
|
|
143
|
+
});
|
|
144
|
+
const cfWs = resp.webSocket;
|
|
145
|
+
if (!cfWs) throw new Error("WebSocket upgrade failed \u2014 server did not accept");
|
|
146
|
+
return new WsEmitterAdapter(cfWs);
|
|
147
|
+
}
|
|
148
|
+
const { default: WS } = await import("ws");
|
|
149
|
+
return new WS(wsUrl, { headers: { authorization: authHeader } });
|
|
106
150
|
}
|
|
107
151
|
};
|
|
108
152
|
|
|
@@ -169,7 +213,7 @@ var Filesystem = class {
|
|
|
169
213
|
});
|
|
170
214
|
}
|
|
171
215
|
async watch(dirPath, opts) {
|
|
172
|
-
const ws = this.client.openWebSocket(`/api/sandboxes/${this.sandboxId}/files/watch`);
|
|
216
|
+
const ws = await this.client.openWebSocket(`/api/sandboxes/${this.sandboxId}/files/watch`);
|
|
173
217
|
await new Promise((resolve, reject) => {
|
|
174
218
|
ws.once("open", () => {
|
|
175
219
|
ws.send(JSON.stringify({ path: dirPath, recursive: opts.recursive ?? false }));
|
|
@@ -179,7 +223,7 @@ var Filesystem = class {
|
|
|
179
223
|
});
|
|
180
224
|
ws.on("message", (raw) => {
|
|
181
225
|
try {
|
|
182
|
-
const event = JSON.parse(raw
|
|
226
|
+
const event = JSON.parse(String(raw));
|
|
183
227
|
opts.onEvent(event);
|
|
184
228
|
} catch {
|
|
185
229
|
}
|
|
@@ -195,8 +239,8 @@ var Filesystem = class {
|
|
|
195
239
|
};
|
|
196
240
|
|
|
197
241
|
// src/process.ts
|
|
198
|
-
var
|
|
199
|
-
var Process = class extends
|
|
242
|
+
var import_node_events2 = require("events");
|
|
243
|
+
var Process = class extends import_node_events2.EventEmitter {
|
|
200
244
|
ws;
|
|
201
245
|
constructor(ws) {
|
|
202
246
|
super();
|
|
@@ -282,8 +326,8 @@ var BackgroundProcess = class {
|
|
|
282
326
|
);
|
|
283
327
|
return res.match;
|
|
284
328
|
}
|
|
285
|
-
streamLogs(opts = {}) {
|
|
286
|
-
const ws = this.client.openWebSocket(
|
|
329
|
+
async streamLogs(opts = {}) {
|
|
330
|
+
const ws = await this.client.openWebSocket(
|
|
287
331
|
`/api/sandboxes/${this.sandboxId}/processes/logs/stream`
|
|
288
332
|
);
|
|
289
333
|
ws.on("open", () => {
|
|
@@ -344,8 +388,8 @@ var ProcessManager = class {
|
|
|
344
388
|
};
|
|
345
389
|
|
|
346
390
|
// src/terminal.ts
|
|
347
|
-
var
|
|
348
|
-
var Terminal = class extends
|
|
391
|
+
var import_node_events3 = require("events");
|
|
392
|
+
var Terminal = class extends import_node_events3.EventEmitter {
|
|
349
393
|
ws;
|
|
350
394
|
constructor(ws) {
|
|
351
395
|
super();
|
|
@@ -427,7 +471,7 @@ var Sandbox = class _Sandbox {
|
|
|
427
471
|
async exec(cmd, opts = {}) {
|
|
428
472
|
const { args, cwd, env, timeout, stream } = opts;
|
|
429
473
|
if (stream) {
|
|
430
|
-
const ws = this.client.openWebSocket(`/api/sandboxes/${this.id}/exec/stream`);
|
|
474
|
+
const ws = await this.client.openWebSocket(`/api/sandboxes/${this.id}/exec/stream`);
|
|
431
475
|
const proc = new Process(ws);
|
|
432
476
|
await new Promise((resolve, reject) => {
|
|
433
477
|
ws.once("open", () => {
|
|
@@ -454,7 +498,7 @@ var Sandbox = class _Sandbox {
|
|
|
454
498
|
});
|
|
455
499
|
}
|
|
456
500
|
async terminal() {
|
|
457
|
-
const ws = this.client.openWebSocket(`/api/sandboxes/${this.id}/terminal`);
|
|
501
|
+
const ws = await this.client.openWebSocket(`/api/sandboxes/${this.id}/terminal`);
|
|
458
502
|
await new Promise((resolve, reject) => {
|
|
459
503
|
ws.once("open", resolve);
|
|
460
504
|
ws.once("error", reject);
|
package/dist/index.mjs
CHANGED
|
@@ -1,5 +1,34 @@
|
|
|
1
|
+
// src/ws-compat.ts
|
|
2
|
+
import { EventEmitter } from "events";
|
|
3
|
+
var WsEmitterAdapter = class extends EventEmitter {
|
|
4
|
+
constructor(ws) {
|
|
5
|
+
super();
|
|
6
|
+
this.ws = ws;
|
|
7
|
+
ws.accept?.();
|
|
8
|
+
ws.addEventListener("message", (e) => {
|
|
9
|
+
const raw = e.data;
|
|
10
|
+
this.emit("message", typeof raw === "string" ? raw : String(raw));
|
|
11
|
+
});
|
|
12
|
+
ws.addEventListener("error", (e) => this.emit("error", e));
|
|
13
|
+
ws.addEventListener("close", () => this.emit("close"));
|
|
14
|
+
ws.addEventListener("open", () => this.emit("open"));
|
|
15
|
+
}
|
|
16
|
+
ws;
|
|
17
|
+
OPEN = 1;
|
|
18
|
+
CONNECTING = 0;
|
|
19
|
+
get readyState() {
|
|
20
|
+
return this.ws.readyState;
|
|
21
|
+
}
|
|
22
|
+
send(data) {
|
|
23
|
+
this.ws.send(data);
|
|
24
|
+
}
|
|
25
|
+
close() {
|
|
26
|
+
this.ws.close();
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
var IS_CF_WORKERS = typeof globalThis.WebSocketPair !== "undefined";
|
|
30
|
+
|
|
1
31
|
// src/client.ts
|
|
2
|
-
import WebSocket from "ws";
|
|
3
32
|
var HttpClient = class {
|
|
4
33
|
constructor(baseUrl, apiKey) {
|
|
5
34
|
this.baseUrl = baseUrl;
|
|
@@ -57,11 +86,26 @@ var HttpClient = class {
|
|
|
57
86
|
if (!text) return void 0;
|
|
58
87
|
return JSON.parse(text);
|
|
59
88
|
}
|
|
60
|
-
|
|
89
|
+
// ── WebSocket ───────────────────────────────────────────────────────────────
|
|
90
|
+
// CF Workers: uses fetch() with Upgrade header (supports Authorization).
|
|
91
|
+
// Node.js: uses the ws package (installed as an optional dependency).
|
|
92
|
+
async openWebSocket(path) {
|
|
61
93
|
const wsUrl = this.baseUrl.replace(/^http/, "ws") + path;
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
94
|
+
const authHeader = `Bearer ${this.apiKey}`;
|
|
95
|
+
if (IS_CF_WORKERS) {
|
|
96
|
+
const resp = await fetch(wsUrl, {
|
|
97
|
+
headers: {
|
|
98
|
+
Upgrade: "websocket",
|
|
99
|
+
Connection: "Upgrade",
|
|
100
|
+
Authorization: authHeader
|
|
101
|
+
}
|
|
102
|
+
});
|
|
103
|
+
const cfWs = resp.webSocket;
|
|
104
|
+
if (!cfWs) throw new Error("WebSocket upgrade failed \u2014 server did not accept");
|
|
105
|
+
return new WsEmitterAdapter(cfWs);
|
|
106
|
+
}
|
|
107
|
+
const { default: WS } = await import("ws");
|
|
108
|
+
return new WS(wsUrl, { headers: { authorization: authHeader } });
|
|
65
109
|
}
|
|
66
110
|
};
|
|
67
111
|
|
|
@@ -128,7 +172,7 @@ var Filesystem = class {
|
|
|
128
172
|
});
|
|
129
173
|
}
|
|
130
174
|
async watch(dirPath, opts) {
|
|
131
|
-
const ws = this.client.openWebSocket(`/api/sandboxes/${this.sandboxId}/files/watch`);
|
|
175
|
+
const ws = await this.client.openWebSocket(`/api/sandboxes/${this.sandboxId}/files/watch`);
|
|
132
176
|
await new Promise((resolve, reject) => {
|
|
133
177
|
ws.once("open", () => {
|
|
134
178
|
ws.send(JSON.stringify({ path: dirPath, recursive: opts.recursive ?? false }));
|
|
@@ -138,7 +182,7 @@ var Filesystem = class {
|
|
|
138
182
|
});
|
|
139
183
|
ws.on("message", (raw) => {
|
|
140
184
|
try {
|
|
141
|
-
const event = JSON.parse(raw
|
|
185
|
+
const event = JSON.parse(String(raw));
|
|
142
186
|
opts.onEvent(event);
|
|
143
187
|
} catch {
|
|
144
188
|
}
|
|
@@ -154,8 +198,8 @@ var Filesystem = class {
|
|
|
154
198
|
};
|
|
155
199
|
|
|
156
200
|
// src/process.ts
|
|
157
|
-
import { EventEmitter } from "events";
|
|
158
|
-
var Process = class extends
|
|
201
|
+
import { EventEmitter as EventEmitter2 } from "events";
|
|
202
|
+
var Process = class extends EventEmitter2 {
|
|
159
203
|
ws;
|
|
160
204
|
constructor(ws) {
|
|
161
205
|
super();
|
|
@@ -241,8 +285,8 @@ var BackgroundProcess = class {
|
|
|
241
285
|
);
|
|
242
286
|
return res.match;
|
|
243
287
|
}
|
|
244
|
-
streamLogs(opts = {}) {
|
|
245
|
-
const ws = this.client.openWebSocket(
|
|
288
|
+
async streamLogs(opts = {}) {
|
|
289
|
+
const ws = await this.client.openWebSocket(
|
|
246
290
|
`/api/sandboxes/${this.sandboxId}/processes/logs/stream`
|
|
247
291
|
);
|
|
248
292
|
ws.on("open", () => {
|
|
@@ -303,8 +347,8 @@ var ProcessManager = class {
|
|
|
303
347
|
};
|
|
304
348
|
|
|
305
349
|
// src/terminal.ts
|
|
306
|
-
import { EventEmitter as
|
|
307
|
-
var Terminal = class extends
|
|
350
|
+
import { EventEmitter as EventEmitter3 } from "events";
|
|
351
|
+
var Terminal = class extends EventEmitter3 {
|
|
308
352
|
ws;
|
|
309
353
|
constructor(ws) {
|
|
310
354
|
super();
|
|
@@ -386,7 +430,7 @@ var Sandbox = class _Sandbox {
|
|
|
386
430
|
async exec(cmd, opts = {}) {
|
|
387
431
|
const { args, cwd, env, timeout, stream } = opts;
|
|
388
432
|
if (stream) {
|
|
389
|
-
const ws = this.client.openWebSocket(`/api/sandboxes/${this.id}/exec/stream`);
|
|
433
|
+
const ws = await this.client.openWebSocket(`/api/sandboxes/${this.id}/exec/stream`);
|
|
390
434
|
const proc = new Process(ws);
|
|
391
435
|
await new Promise((resolve, reject) => {
|
|
392
436
|
ws.once("open", () => {
|
|
@@ -413,7 +457,7 @@ var Sandbox = class _Sandbox {
|
|
|
413
457
|
});
|
|
414
458
|
}
|
|
415
459
|
async terminal() {
|
|
416
|
-
const ws = this.client.openWebSocket(`/api/sandboxes/${this.id}/terminal`);
|
|
460
|
+
const ws = await this.client.openWebSocket(`/api/sandboxes/${this.id}/terminal`);
|
|
417
461
|
await new Promise((resolve, reject) => {
|
|
418
462
|
ws.once("open", resolve);
|
|
419
463
|
ws.once("error", reject);
|