@sandbox-engine/sdk 0.2.1 → 0.2.3
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 +60 -15
- package/dist/index.mjs +60 -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,27 @@ 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) {
|
|
134
|
+
const authHeader = `Bearer ${this.apiKey}`;
|
|
135
|
+
if (IS_CF_WORKERS) {
|
|
136
|
+
const httpUrl = this.baseUrl + path;
|
|
137
|
+
const resp = await fetch(httpUrl, {
|
|
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
|
+
}
|
|
102
148
|
const wsUrl = this.baseUrl.replace(/^http/, "ws") + path;
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
});
|
|
149
|
+
const { default: WS } = await import("ws");
|
|
150
|
+
return new WS(wsUrl, { headers: { authorization: authHeader } });
|
|
106
151
|
}
|
|
107
152
|
};
|
|
108
153
|
|
|
@@ -169,7 +214,7 @@ var Filesystem = class {
|
|
|
169
214
|
});
|
|
170
215
|
}
|
|
171
216
|
async watch(dirPath, opts) {
|
|
172
|
-
const ws = this.client.openWebSocket(`/api/sandboxes/${this.sandboxId}/files/watch`);
|
|
217
|
+
const ws = await this.client.openWebSocket(`/api/sandboxes/${this.sandboxId}/files/watch`);
|
|
173
218
|
await new Promise((resolve, reject) => {
|
|
174
219
|
ws.once("open", () => {
|
|
175
220
|
ws.send(JSON.stringify({ path: dirPath, recursive: opts.recursive ?? false }));
|
|
@@ -179,7 +224,7 @@ var Filesystem = class {
|
|
|
179
224
|
});
|
|
180
225
|
ws.on("message", (raw) => {
|
|
181
226
|
try {
|
|
182
|
-
const event = JSON.parse(raw
|
|
227
|
+
const event = JSON.parse(String(raw));
|
|
183
228
|
opts.onEvent(event);
|
|
184
229
|
} catch {
|
|
185
230
|
}
|
|
@@ -195,8 +240,8 @@ var Filesystem = class {
|
|
|
195
240
|
};
|
|
196
241
|
|
|
197
242
|
// src/process.ts
|
|
198
|
-
var
|
|
199
|
-
var Process = class extends
|
|
243
|
+
var import_node_events2 = require("events");
|
|
244
|
+
var Process = class extends import_node_events2.EventEmitter {
|
|
200
245
|
ws;
|
|
201
246
|
constructor(ws) {
|
|
202
247
|
super();
|
|
@@ -282,8 +327,8 @@ var BackgroundProcess = class {
|
|
|
282
327
|
);
|
|
283
328
|
return res.match;
|
|
284
329
|
}
|
|
285
|
-
streamLogs(opts = {}) {
|
|
286
|
-
const ws = this.client.openWebSocket(
|
|
330
|
+
async streamLogs(opts = {}) {
|
|
331
|
+
const ws = await this.client.openWebSocket(
|
|
287
332
|
`/api/sandboxes/${this.sandboxId}/processes/logs/stream`
|
|
288
333
|
);
|
|
289
334
|
ws.on("open", () => {
|
|
@@ -344,8 +389,8 @@ var ProcessManager = class {
|
|
|
344
389
|
};
|
|
345
390
|
|
|
346
391
|
// src/terminal.ts
|
|
347
|
-
var
|
|
348
|
-
var Terminal = class extends
|
|
392
|
+
var import_node_events3 = require("events");
|
|
393
|
+
var Terminal = class extends import_node_events3.EventEmitter {
|
|
349
394
|
ws;
|
|
350
395
|
constructor(ws) {
|
|
351
396
|
super();
|
|
@@ -427,7 +472,7 @@ var Sandbox = class _Sandbox {
|
|
|
427
472
|
async exec(cmd, opts = {}) {
|
|
428
473
|
const { args, cwd, env, timeout, stream } = opts;
|
|
429
474
|
if (stream) {
|
|
430
|
-
const ws = this.client.openWebSocket(`/api/sandboxes/${this.id}/exec/stream`);
|
|
475
|
+
const ws = await this.client.openWebSocket(`/api/sandboxes/${this.id}/exec/stream`);
|
|
431
476
|
const proc = new Process(ws);
|
|
432
477
|
await new Promise((resolve, reject) => {
|
|
433
478
|
ws.once("open", () => {
|
|
@@ -454,7 +499,7 @@ var Sandbox = class _Sandbox {
|
|
|
454
499
|
});
|
|
455
500
|
}
|
|
456
501
|
async terminal() {
|
|
457
|
-
const ws = this.client.openWebSocket(`/api/sandboxes/${this.id}/terminal`);
|
|
502
|
+
const ws = await this.client.openWebSocket(`/api/sandboxes/${this.id}/terminal`);
|
|
458
503
|
await new Promise((resolve, reject) => {
|
|
459
504
|
ws.once("open", resolve);
|
|
460
505
|
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,27 @@ 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) {
|
|
93
|
+
const authHeader = `Bearer ${this.apiKey}`;
|
|
94
|
+
if (IS_CF_WORKERS) {
|
|
95
|
+
const httpUrl = this.baseUrl + path;
|
|
96
|
+
const resp = await fetch(httpUrl, {
|
|
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
|
+
}
|
|
61
107
|
const wsUrl = this.baseUrl.replace(/^http/, "ws") + path;
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
});
|
|
108
|
+
const { default: WS } = await import("ws");
|
|
109
|
+
return new WS(wsUrl, { headers: { authorization: authHeader } });
|
|
65
110
|
}
|
|
66
111
|
};
|
|
67
112
|
|
|
@@ -128,7 +173,7 @@ var Filesystem = class {
|
|
|
128
173
|
});
|
|
129
174
|
}
|
|
130
175
|
async watch(dirPath, opts) {
|
|
131
|
-
const ws = this.client.openWebSocket(`/api/sandboxes/${this.sandboxId}/files/watch`);
|
|
176
|
+
const ws = await this.client.openWebSocket(`/api/sandboxes/${this.sandboxId}/files/watch`);
|
|
132
177
|
await new Promise((resolve, reject) => {
|
|
133
178
|
ws.once("open", () => {
|
|
134
179
|
ws.send(JSON.stringify({ path: dirPath, recursive: opts.recursive ?? false }));
|
|
@@ -138,7 +183,7 @@ var Filesystem = class {
|
|
|
138
183
|
});
|
|
139
184
|
ws.on("message", (raw) => {
|
|
140
185
|
try {
|
|
141
|
-
const event = JSON.parse(raw
|
|
186
|
+
const event = JSON.parse(String(raw));
|
|
142
187
|
opts.onEvent(event);
|
|
143
188
|
} catch {
|
|
144
189
|
}
|
|
@@ -154,8 +199,8 @@ var Filesystem = class {
|
|
|
154
199
|
};
|
|
155
200
|
|
|
156
201
|
// src/process.ts
|
|
157
|
-
import { EventEmitter } from "events";
|
|
158
|
-
var Process = class extends
|
|
202
|
+
import { EventEmitter as EventEmitter2 } from "events";
|
|
203
|
+
var Process = class extends EventEmitter2 {
|
|
159
204
|
ws;
|
|
160
205
|
constructor(ws) {
|
|
161
206
|
super();
|
|
@@ -241,8 +286,8 @@ var BackgroundProcess = class {
|
|
|
241
286
|
);
|
|
242
287
|
return res.match;
|
|
243
288
|
}
|
|
244
|
-
streamLogs(opts = {}) {
|
|
245
|
-
const ws = this.client.openWebSocket(
|
|
289
|
+
async streamLogs(opts = {}) {
|
|
290
|
+
const ws = await this.client.openWebSocket(
|
|
246
291
|
`/api/sandboxes/${this.sandboxId}/processes/logs/stream`
|
|
247
292
|
);
|
|
248
293
|
ws.on("open", () => {
|
|
@@ -303,8 +348,8 @@ var ProcessManager = class {
|
|
|
303
348
|
};
|
|
304
349
|
|
|
305
350
|
// src/terminal.ts
|
|
306
|
-
import { EventEmitter as
|
|
307
|
-
var Terminal = class extends
|
|
351
|
+
import { EventEmitter as EventEmitter3 } from "events";
|
|
352
|
+
var Terminal = class extends EventEmitter3 {
|
|
308
353
|
ws;
|
|
309
354
|
constructor(ws) {
|
|
310
355
|
super();
|
|
@@ -386,7 +431,7 @@ var Sandbox = class _Sandbox {
|
|
|
386
431
|
async exec(cmd, opts = {}) {
|
|
387
432
|
const { args, cwd, env, timeout, stream } = opts;
|
|
388
433
|
if (stream) {
|
|
389
|
-
const ws = this.client.openWebSocket(`/api/sandboxes/${this.id}/exec/stream`);
|
|
434
|
+
const ws = await this.client.openWebSocket(`/api/sandboxes/${this.id}/exec/stream`);
|
|
390
435
|
const proc = new Process(ws);
|
|
391
436
|
await new Promise((resolve, reject) => {
|
|
392
437
|
ws.once("open", () => {
|
|
@@ -413,7 +458,7 @@ var Sandbox = class _Sandbox {
|
|
|
413
458
|
});
|
|
414
459
|
}
|
|
415
460
|
async terminal() {
|
|
416
|
-
const ws = this.client.openWebSocket(`/api/sandboxes/${this.id}/terminal`);
|
|
461
|
+
const ws = await this.client.openWebSocket(`/api/sandboxes/${this.id}/terminal`);
|
|
417
462
|
await new Promise((resolve, reject) => {
|
|
418
463
|
ws.once("open", resolve);
|
|
419
464
|
ws.once("error", reject);
|