@alibaba-group/opensandbox 0.1.0-dev2 → 0.1.0-dev4
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 +13 -0
- package/dist/adapters/sse.d.ts.map +1 -1
- package/dist/adapters/sse.js +2 -0
- package/dist/config/connection.d.ts +20 -9
- package/dist/config/connection.d.ts.map +1 -1
- package/dist/config/connection.js +140 -33
- package/dist/factory/defaultAdapterFactory.d.ts.map +1 -1
- package/dist/factory/defaultAdapterFactory.js +0 -1
- package/dist/manager.d.ts +5 -3
- package/dist/manager.d.ts.map +1 -1
- package/dist/manager.js +21 -7
- package/dist/sandbox.d.ts +4 -0
- package/dist/sandbox.d.ts.map +1 -1
- package/dist/sandbox.js +81 -43
- package/package.json +3 -2
package/README.md
CHANGED
|
@@ -52,6 +52,7 @@ try {
|
|
|
52
52
|
|
|
53
53
|
// Optional but recommended: terminate the remote instance when you are done.
|
|
54
54
|
await sandbox.kill();
|
|
55
|
+
await sandbox.close();
|
|
55
56
|
} catch (err) {
|
|
56
57
|
if (err instanceof SandboxException) {
|
|
57
58
|
console.error(`Sandbox Error: [${err.error.code}] ${err.error.message ?? ""}`);
|
|
@@ -157,6 +158,7 @@ import { SandboxManager } from "@alibaba-group/opensandbox";
|
|
|
157
158
|
const manager = SandboxManager.create({ connectionConfig: config });
|
|
158
159
|
const list = await manager.listSandboxInfos({ states: ["Running"], pageSize: 10 });
|
|
159
160
|
console.log(list.items.map((s) => s.id));
|
|
161
|
+
await manager.close();
|
|
160
162
|
```
|
|
161
163
|
|
|
162
164
|
## Configuration
|
|
@@ -165,6 +167,10 @@ console.log(list.items.map((s) => s.id));
|
|
|
165
167
|
|
|
166
168
|
The `ConnectionConfig` class manages API server connection settings.
|
|
167
169
|
|
|
170
|
+
Runtime notes:
|
|
171
|
+
- In browsers, the SDK uses the global `fetch` implementation.
|
|
172
|
+
- In Node.js, every `Sandbox` and `SandboxManager` clones the base `ConnectionConfig` via `withTransportIfMissing()`, so each instance gets an isolated `undici` keep-alive pool. Call `sandbox.close()` or `manager.close()` when you are done so the SDK can release the associated agent.
|
|
173
|
+
|
|
168
174
|
| Parameter | Description | Default | Environment Variable |
|
|
169
175
|
| --- | --- | --- | --- |
|
|
170
176
|
| `apiKey` | API key for authentication | Optional | `OPEN_SANDBOX_API_KEY` |
|
|
@@ -210,6 +216,13 @@ const config2 = new ConnectionConfig({
|
|
|
210
216
|
| `readyTimeoutSeconds` | Max time to wait for readiness | 30 seconds |
|
|
211
217
|
| `healthCheckPollingInterval` | Poll interval while waiting (milliseconds) | 200 ms |
|
|
212
218
|
|
|
219
|
+
### 3. Resource cleanup
|
|
220
|
+
|
|
221
|
+
Both `Sandbox` and `SandboxManager` own a scoped HTTP agent when running on Node.js
|
|
222
|
+
so you can safely reuse the same `ConnectionConfig`. Once you are finished interacting
|
|
223
|
+
with the sandbox or administration APIs, call `sandbox.close()` / `manager.close()` to
|
|
224
|
+
release the underlying agent.
|
|
225
|
+
|
|
213
226
|
## Browser Notes
|
|
214
227
|
|
|
215
228
|
- The SDK can run in browsers, but **streaming file uploads are Node-only**.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sse.d.ts","sourceRoot":"","sources":["../../src/adapters/sse.ts"],"names":[],"mappings":"AAwBA;;;;GAIG;AACH,wBAAuB,oBAAoB,CAAC,CAAC,EAC3C,GAAG,EAAE,QAAQ,EACb,IAAI,CAAC,EAAE;IAAE,oBAAoB,CAAC,EAAE,MAAM,CAAA;CAAE,GACvC,aAAa,CAAC,CAAC,CAAC,
|
|
1
|
+
{"version":3,"file":"sse.d.ts","sourceRoot":"","sources":["../../src/adapters/sse.ts"],"names":[],"mappings":"AAwBA;;;;GAIG;AACH,wBAAuB,oBAAoB,CAAC,CAAC,EAC3C,GAAG,EAAE,QAAQ,EACb,IAAI,CAAC,EAAE;IAAE,oBAAoB,CAAC,EAAE,MAAM,CAAA;CAAE,GACvC,aAAa,CAAC,CAAC,CAAC,CA8DlB"}
|
package/dist/adapters/sse.js
CHANGED
|
@@ -33,18 +33,14 @@ export declare class ConnectionConfig {
|
|
|
33
33
|
readonly domain: string;
|
|
34
34
|
readonly apiKey?: string;
|
|
35
35
|
readonly headers: Record<string, string>;
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
* Fetch function intended for long-lived streaming requests (SSE).
|
|
39
|
-
*
|
|
40
|
-
* This is separate from {@link fetch} so callers can supply a different implementation
|
|
41
|
-
* (e.g. Node undici with bodyTimeout disabled) and so the SDK can apply distinct
|
|
42
|
-
* timeout semantics for streaming vs normal HTTP calls.
|
|
43
|
-
*/
|
|
44
|
-
readonly sseFetch: typeof fetch;
|
|
36
|
+
private _fetch;
|
|
37
|
+
private _sseFetch;
|
|
45
38
|
readonly requestTimeoutSeconds: number;
|
|
46
39
|
readonly debug: boolean;
|
|
47
40
|
readonly userAgent: string;
|
|
41
|
+
private _closeTransport;
|
|
42
|
+
private _closePromise;
|
|
43
|
+
private _transportInitialized;
|
|
48
44
|
/**
|
|
49
45
|
* Create a connection configuration.
|
|
50
46
|
*
|
|
@@ -53,6 +49,21 @@ export declare class ConnectionConfig {
|
|
|
53
49
|
* - `OPEN_SANDBOX_API_KEY`
|
|
54
50
|
*/
|
|
55
51
|
constructor(opts?: ConnectionConfigOptions);
|
|
52
|
+
get fetch(): typeof fetch;
|
|
53
|
+
get sseFetch(): typeof fetch;
|
|
56
54
|
getBaseUrl(): string;
|
|
55
|
+
private initializeTransport;
|
|
56
|
+
/**
|
|
57
|
+
* Ensure this configuration has transport helpers (fetch/SSE) allocated.
|
|
58
|
+
*
|
|
59
|
+
* On Node.js this creates a dedicated `undici` dispatcher; on browsers it
|
|
60
|
+
* simply reuses the global fetch. Returns either `this` or a cloned config
|
|
61
|
+
* with the transport initialized.
|
|
62
|
+
*/
|
|
63
|
+
withTransportIfMissing(): ConnectionConfig;
|
|
64
|
+
/**
|
|
65
|
+
* Close the Node.js agent owned by this configuration.
|
|
66
|
+
*/
|
|
67
|
+
closeTransport(): Promise<void>;
|
|
57
68
|
}
|
|
58
69
|
//# sourceMappingURL=connection.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"connection.d.ts","sourceRoot":"","sources":["../../src/config/connection.ts"],"names":[],"mappings":"AAcA,MAAM,MAAM,kBAAkB,GAAG,MAAM,GAAG,OAAO,CAAC;AAElD;;;;GAIG;AACH,MAAM,WAAW,uBAAuB;IACtC;;;;;;;;OAQG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,kBAAkB,CAAC;IAC9B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAEjC;;;OAGG;IACH,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B;;OAEG;IACH,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;
|
|
1
|
+
{"version":3,"file":"connection.d.ts","sourceRoot":"","sources":["../../src/config/connection.ts"],"names":[],"mappings":"AAcA,MAAM,MAAM,kBAAkB,GAAG,MAAM,GAAG,OAAO,CAAC;AAElD;;;;GAIG;AACH,MAAM,WAAW,uBAAuB;IACtC;;;;;;;;OAQG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,kBAAkB,CAAC;IAC9B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAEjC;;;OAGG;IACH,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B;;OAEG;IACH,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAsMD,qBAAa,gBAAgB;IAC3B,QAAQ,CAAC,QAAQ,EAAE,kBAAkB,CAAC;IACtC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACzC,OAAO,CAAC,MAAM,CAAsB;IACpC,OAAO,CAAC,SAAS,CAAsB;IACvC,QAAQ,CAAC,qBAAqB,EAAE,MAAM,CAAC;IACvC,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;IACxB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAA8B;IACxD,OAAO,CAAC,eAAe,CAAsB;IAC7C,OAAO,CAAC,aAAa,CAA8B;IACnD,OAAO,CAAC,qBAAqB,CAAS;IAEtC;;;;;;OAMG;gBACS,IAAI,GAAE,uBAA4B;IAsC9C,IAAI,KAAK,IAAI,OAAO,KAAK,CAExB;IAED,IAAI,QAAQ,IAAI,OAAO,KAAK,CAE3B;IAED,UAAU,IAAI,MAAM;IAWpB,OAAO,CAAC,mBAAmB;IAqB3B;;;;;;OAMG;IACH,sBAAsB,IAAI,gBAAgB;IAiB1C;;OAEG;IACG,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC;CAKtC"}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
// Copyright 2026 Alibaba Group Holding Ltd.
|
|
2
|
-
//
|
|
2
|
+
//
|
|
3
3
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
4
|
// you may not use this file except in compliance with the License.
|
|
5
5
|
// You may obtain a copy of the License at
|
|
6
|
-
//
|
|
6
|
+
//
|
|
7
7
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
-
//
|
|
8
|
+
//
|
|
9
9
|
// Unless required by applicable law or agreed to in writing, software
|
|
10
10
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
11
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
// limitations under the License.
|
|
14
14
|
function isNodeRuntime() {
|
|
15
15
|
const p = globalThis?.process;
|
|
16
|
-
return !!
|
|
16
|
+
return !!p?.versions?.node;
|
|
17
17
|
}
|
|
18
18
|
function redactHeaders(headers) {
|
|
19
19
|
const out = { ...headers };
|
|
@@ -35,6 +35,7 @@ function stripV1Suffix(s) {
|
|
|
35
35
|
const trimmed = stripTrailingSlashes(s);
|
|
36
36
|
return trimmed.endsWith("/v1") ? trimmed.slice(0, -3) : trimmed;
|
|
37
37
|
}
|
|
38
|
+
const DEFAULT_KEEPALIVE_TIMEOUT_MS = 30_000;
|
|
38
39
|
function normalizeDomainBase(input) {
|
|
39
40
|
// Accept a full URL and preserve its path prefix (if any).
|
|
40
41
|
if (input.startsWith("http://") || input.startsWith("https://")) {
|
|
@@ -47,6 +48,64 @@ function normalizeDomainBase(input) {
|
|
|
47
48
|
// No scheme: treat as "host[:port]" or "host[:port]/prefix" and normalize trailing "/v1" or "/".
|
|
48
49
|
return { domainBase: stripV1Suffix(input) };
|
|
49
50
|
}
|
|
51
|
+
function createNodeFetch() {
|
|
52
|
+
if (!isNodeRuntime()) {
|
|
53
|
+
return {
|
|
54
|
+
fetch,
|
|
55
|
+
close: async () => {
|
|
56
|
+
// Browser fetch has no pooled dispatcher to close.
|
|
57
|
+
},
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
const baseFetch = fetch;
|
|
61
|
+
let dispatcher;
|
|
62
|
+
let dispatcherPromise = null;
|
|
63
|
+
const nodeFetch = async (input, init) => {
|
|
64
|
+
dispatcherPromise ??= (async () => {
|
|
65
|
+
try {
|
|
66
|
+
const mod = await import("undici");
|
|
67
|
+
const Agent = mod.Agent;
|
|
68
|
+
if (!Agent) {
|
|
69
|
+
return undefined;
|
|
70
|
+
}
|
|
71
|
+
dispatcher = new Agent({
|
|
72
|
+
keepAliveTimeout: DEFAULT_KEEPALIVE_TIMEOUT_MS,
|
|
73
|
+
keepAliveMaxTimeout: DEFAULT_KEEPALIVE_TIMEOUT_MS,
|
|
74
|
+
});
|
|
75
|
+
return dispatcher;
|
|
76
|
+
}
|
|
77
|
+
catch {
|
|
78
|
+
return undefined;
|
|
79
|
+
}
|
|
80
|
+
})();
|
|
81
|
+
if (dispatcherPromise) {
|
|
82
|
+
await dispatcherPromise;
|
|
83
|
+
}
|
|
84
|
+
if (dispatcher) {
|
|
85
|
+
const mergedInit = { ...(init ?? {}), dispatcher };
|
|
86
|
+
return baseFetch(input, mergedInit);
|
|
87
|
+
}
|
|
88
|
+
return baseFetch(input, init);
|
|
89
|
+
};
|
|
90
|
+
return {
|
|
91
|
+
fetch: nodeFetch,
|
|
92
|
+
close: async () => {
|
|
93
|
+
if (dispatcherPromise) {
|
|
94
|
+
await dispatcherPromise.catch(() => undefined);
|
|
95
|
+
}
|
|
96
|
+
if (dispatcher &&
|
|
97
|
+
typeof dispatcher === "object" &&
|
|
98
|
+
typeof dispatcher.close === "function") {
|
|
99
|
+
try {
|
|
100
|
+
await dispatcher.close();
|
|
101
|
+
}
|
|
102
|
+
catch {
|
|
103
|
+
// swallow close errors
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
},
|
|
107
|
+
};
|
|
108
|
+
}
|
|
50
109
|
function createTimedFetch(opts) {
|
|
51
110
|
const baseFetch = opts.baseFetch;
|
|
52
111
|
const timeoutSeconds = opts.timeoutSeconds;
|
|
@@ -55,7 +114,9 @@ function createTimedFetch(opts) {
|
|
|
55
114
|
const label = opts.label;
|
|
56
115
|
return async (input, init) => {
|
|
57
116
|
const method = init?.method ?? "GET";
|
|
58
|
-
const url = typeof input === "string"
|
|
117
|
+
const url = typeof input === "string"
|
|
118
|
+
? input
|
|
119
|
+
: input?.toString?.() ?? String(input);
|
|
59
120
|
const ac = new AbortController();
|
|
60
121
|
const timeoutMs = Math.floor(timeoutSeconds * 1000);
|
|
61
122
|
const t = Number.isFinite(timeoutMs) && timeoutMs > 0
|
|
@@ -73,7 +134,10 @@ function createTimedFetch(opts) {
|
|
|
73
134
|
signal: ac.signal,
|
|
74
135
|
};
|
|
75
136
|
if (debug) {
|
|
76
|
-
const mergedHeaders = {
|
|
137
|
+
const mergedHeaders = {
|
|
138
|
+
...defaultHeaders,
|
|
139
|
+
...(init?.headers ?? {}),
|
|
140
|
+
};
|
|
77
141
|
// eslint-disable-next-line no-console
|
|
78
142
|
console.log(`[opensandbox:${label}] ->`, method, url, redactHeaders(mergedHeaders));
|
|
79
143
|
}
|
|
@@ -98,18 +162,14 @@ export class ConnectionConfig {
|
|
|
98
162
|
domain;
|
|
99
163
|
apiKey;
|
|
100
164
|
headers;
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
* Fetch function intended for long-lived streaming requests (SSE).
|
|
104
|
-
*
|
|
105
|
-
* This is separate from {@link fetch} so callers can supply a different implementation
|
|
106
|
-
* (e.g. Node undici with bodyTimeout disabled) and so the SDK can apply distinct
|
|
107
|
-
* timeout semantics for streaming vs normal HTTP calls.
|
|
108
|
-
*/
|
|
109
|
-
sseFetch;
|
|
165
|
+
_fetch;
|
|
166
|
+
_sseFetch;
|
|
110
167
|
requestTimeoutSeconds;
|
|
111
168
|
debug;
|
|
112
169
|
userAgent = "OpenSandbox-JS-SDK/0.1.0";
|
|
170
|
+
_closeTransport;
|
|
171
|
+
_closePromise = null;
|
|
172
|
+
_transportInitialized = false;
|
|
113
173
|
/**
|
|
114
174
|
* Create a connection configuration.
|
|
115
175
|
*
|
|
@@ -126,9 +186,10 @@ export class ConnectionConfig {
|
|
|
126
186
|
this.protocol = normalized.protocol ?? opts.protocol ?? "http";
|
|
127
187
|
this.domain = normalized.domainBase;
|
|
128
188
|
this.apiKey = opts.apiKey ?? envApiKey;
|
|
129
|
-
this.requestTimeoutSeconds =
|
|
130
|
-
|
|
131
|
-
|
|
189
|
+
this.requestTimeoutSeconds =
|
|
190
|
+
typeof opts.requestTimeoutSeconds === "number"
|
|
191
|
+
? opts.requestTimeoutSeconds
|
|
192
|
+
: 30;
|
|
132
193
|
this.debug = !!opts.debug;
|
|
133
194
|
const headers = { ...(opts.headers ?? {}) };
|
|
134
195
|
// Attach API key via header unless the user already provided one.
|
|
@@ -136,36 +197,82 @@ export class ConnectionConfig {
|
|
|
136
197
|
headers["OPEN-SANDBOX-API-KEY"] = this.apiKey;
|
|
137
198
|
}
|
|
138
199
|
// Best-effort user-agent (Node only).
|
|
139
|
-
if (isNodeRuntime() &&
|
|
200
|
+
if (isNodeRuntime() &&
|
|
201
|
+
this.userAgent &&
|
|
202
|
+
!headers["user-agent"] &&
|
|
203
|
+
!headers["User-Agent"]) {
|
|
140
204
|
headers["user-agent"] = this.userAgent;
|
|
141
205
|
}
|
|
142
206
|
this.headers = headers;
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
207
|
+
this._fetch = null;
|
|
208
|
+
this._sseFetch = null;
|
|
209
|
+
this._closeTransport = async () => { };
|
|
210
|
+
this._transportInitialized = false;
|
|
211
|
+
}
|
|
212
|
+
get fetch() {
|
|
213
|
+
return this._fetch ?? fetch;
|
|
214
|
+
}
|
|
215
|
+
get sseFetch() {
|
|
216
|
+
return this._sseFetch ?? fetch;
|
|
217
|
+
}
|
|
218
|
+
getBaseUrl() {
|
|
219
|
+
// If `domain` already contains a scheme, treat it as a full base URL prefix.
|
|
220
|
+
if (this.domain.startsWith("http://") ||
|
|
221
|
+
this.domain.startsWith("https://")) {
|
|
222
|
+
return `${stripV1Suffix(this.domain)}/v1`;
|
|
223
|
+
}
|
|
224
|
+
return `${this.protocol}://${stripV1Suffix(this.domain)}/v1`;
|
|
225
|
+
}
|
|
226
|
+
initializeTransport() {
|
|
227
|
+
if (this._transportInitialized)
|
|
228
|
+
return;
|
|
229
|
+
const { fetch: baseFetch, close } = createNodeFetch();
|
|
230
|
+
this._fetch = createTimedFetch({
|
|
149
231
|
baseFetch,
|
|
150
232
|
timeoutSeconds: this.requestTimeoutSeconds,
|
|
151
233
|
debug: this.debug,
|
|
152
234
|
defaultHeaders: this.headers,
|
|
153
235
|
label: "http",
|
|
154
236
|
});
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
baseFetch: baseSseFetch,
|
|
237
|
+
this._sseFetch = createTimedFetch({
|
|
238
|
+
baseFetch,
|
|
158
239
|
timeoutSeconds: 0,
|
|
159
240
|
debug: this.debug,
|
|
160
241
|
defaultHeaders: this.headers,
|
|
161
242
|
label: "sse",
|
|
162
243
|
});
|
|
244
|
+
this._closeTransport = close;
|
|
245
|
+
this._transportInitialized = true;
|
|
163
246
|
}
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
247
|
+
/**
|
|
248
|
+
* Ensure this configuration has transport helpers (fetch/SSE) allocated.
|
|
249
|
+
*
|
|
250
|
+
* On Node.js this creates a dedicated `undici` dispatcher; on browsers it
|
|
251
|
+
* simply reuses the global fetch. Returns either `this` or a cloned config
|
|
252
|
+
* with the transport initialized.
|
|
253
|
+
*/
|
|
254
|
+
withTransportIfMissing() {
|
|
255
|
+
if (this._transportInitialized) {
|
|
256
|
+
return this;
|
|
168
257
|
}
|
|
169
|
-
|
|
258
|
+
const clone = new ConnectionConfig({
|
|
259
|
+
domain: this.domain,
|
|
260
|
+
protocol: this.protocol,
|
|
261
|
+
apiKey: this.apiKey,
|
|
262
|
+
headers: { ...this.headers },
|
|
263
|
+
requestTimeoutSeconds: this.requestTimeoutSeconds,
|
|
264
|
+
debug: this.debug,
|
|
265
|
+
});
|
|
266
|
+
clone.initializeTransport();
|
|
267
|
+
return clone;
|
|
268
|
+
}
|
|
269
|
+
/**
|
|
270
|
+
* Close the Node.js agent owned by this configuration.
|
|
271
|
+
*/
|
|
272
|
+
async closeTransport() {
|
|
273
|
+
if (!this._transportInitialized)
|
|
274
|
+
return;
|
|
275
|
+
this._closePromise ??= this._closeTransport();
|
|
276
|
+
await this._closePromise;
|
|
170
277
|
}
|
|
171
278
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"defaultAdapterFactory.d.ts","sourceRoot":"","sources":["../../src/factory/defaultAdapterFactory.ts"],"names":[],"mappings":"AAuBA,OAAO,KAAK,EAAE,cAAc,EAAE,uBAAuB,EAAE,2BAA2B,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAE5I,qBAAa,qBAAsB,YAAW,cAAc;IAC1D,oBAAoB,CAAC,IAAI,EAAE,2BAA2B,GAAG,cAAc;IAWvE,gBAAgB,CAAC,IAAI,EAAE,uBAAuB,GAAG,UAAU;
|
|
1
|
+
{"version":3,"file":"defaultAdapterFactory.d.ts","sourceRoot":"","sources":["../../src/factory/defaultAdapterFactory.ts"],"names":[],"mappings":"AAuBA,OAAO,KAAK,EAAE,cAAc,EAAE,uBAAuB,EAAE,2BAA2B,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAE5I,qBAAa,qBAAsB,YAAW,cAAc;IAC1D,oBAAoB,CAAC,IAAI,EAAE,2BAA2B,GAAG,cAAc;IAWvE,gBAAgB,CAAC,IAAI,EAAE,uBAAuB,GAAG,UAAU;CA2B5D;AAED,wBAAgB,2BAA2B,IAAI,cAAc,CAE5D"}
|
|
@@ -44,7 +44,6 @@ export class DefaultAdapterFactory {
|
|
|
44
44
|
});
|
|
45
45
|
const commands = new CommandsAdapter(execdClient, {
|
|
46
46
|
baseUrl: opts.execdBaseUrl,
|
|
47
|
-
// Streaming calls (SSE) use a dedicated fetch, aligned with Kotlin/Python SDKs.
|
|
48
47
|
fetch: opts.connectionConfig.sseFetch,
|
|
49
48
|
headers: opts.connectionConfig.headers,
|
|
50
49
|
});
|
package/dist/manager.d.ts
CHANGED
|
@@ -18,6 +18,7 @@ export interface SandboxFilter {
|
|
|
18
18
|
*/
|
|
19
19
|
export declare class SandboxManager {
|
|
20
20
|
private readonly sandboxes;
|
|
21
|
+
private readonly connectionConfig;
|
|
21
22
|
private constructor();
|
|
22
23
|
static create(opts?: SandboxManagerOptions): SandboxManager;
|
|
23
24
|
listSandboxInfos(filter?: SandboxFilter): Promise<ListSandboxesResponse>;
|
|
@@ -30,10 +31,11 @@ export declare class SandboxManager {
|
|
|
30
31
|
*/
|
|
31
32
|
renewSandbox(sandboxId: SandboxId, timeoutSeconds: number): Promise<void>;
|
|
32
33
|
/**
|
|
33
|
-
*
|
|
34
|
+
* Release the HTTP agent resources allocated for this manager instance.
|
|
34
35
|
*
|
|
35
|
-
*
|
|
36
|
-
*
|
|
36
|
+
* Each manager clone owns a scoped `ConnectionConfig` clone.
|
|
37
|
+
*
|
|
38
|
+
* This mirrors the Python SDK's default transport lifecycle.
|
|
37
39
|
*/
|
|
38
40
|
close(): Promise<void>;
|
|
39
41
|
}
|
package/dist/manager.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"manager.d.ts","sourceRoot":"","sources":["../src/manager.ts"],"names":[],"mappings":"AAcA,OAAO,EAAE,gBAAgB,EAAE,KAAK,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AAExF,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAElE,OAAO,KAAK,EAAE,qBAAqB,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAG3F,MAAM,WAAW,qBAAqB;IACpC,gBAAgB,CAAC,EAAE,gBAAgB,GAAG,uBAAuB,CAAC;IAC9D,cAAc,CAAC,EAAE,cAAc,CAAC;CACjC;AAED,MAAM,WAAW,aAAa;IAC5B,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAClC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;;;GAIG;AACH,qBAAa,cAAc;IACzB,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAY;
|
|
1
|
+
{"version":3,"file":"manager.d.ts","sourceRoot":"","sources":["../src/manager.ts"],"names":[],"mappings":"AAcA,OAAO,EAAE,gBAAgB,EAAE,KAAK,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AAExF,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAElE,OAAO,KAAK,EAAE,qBAAqB,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAG3F,MAAM,WAAW,qBAAqB;IACpC,gBAAgB,CAAC,EAAE,gBAAgB,GAAG,uBAAuB,CAAC;IAC9D,cAAc,CAAC,EAAE,cAAc,CAAC;CACjC;AAED,MAAM,WAAW,aAAa;IAC5B,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAClC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;;;GAIG;AACH,qBAAa,cAAc;IACzB,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAY;IACtC,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAmB;IAEpD,OAAO;IAKP,MAAM,CAAC,MAAM,CAAC,IAAI,GAAE,qBAA0B,GAAG,cAAc;IAoB/D,gBAAgB,CAAC,MAAM,GAAE,aAAkB,GAAG,OAAO,CAAC,qBAAqB,CAAC;IAS5E,cAAc,CAAC,SAAS,EAAE,SAAS,GAAG,OAAO,CAAC,WAAW,CAAC;IAI1D,WAAW,CAAC,SAAS,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC;IAIhD,YAAY,CAAC,SAAS,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC;IAIjD,aAAa,CAAC,SAAS,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC;IAIlD;;OAEG;IACG,YAAY,CAAC,SAAS,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAK/E;;;;;;OAMG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAG7B"}
|
package/dist/manager.js
CHANGED
|
@@ -20,17 +20,30 @@ import { createDefaultAdapterFactory } from "./factory/defaultAdapterFactory.js"
|
|
|
20
20
|
*/
|
|
21
21
|
export class SandboxManager {
|
|
22
22
|
sandboxes;
|
|
23
|
+
connectionConfig;
|
|
23
24
|
constructor(opts) {
|
|
24
25
|
this.sandboxes = opts.sandboxes;
|
|
26
|
+
this.connectionConfig = opts.connectionConfig;
|
|
25
27
|
}
|
|
26
28
|
static create(opts = {}) {
|
|
27
|
-
const
|
|
29
|
+
const baseConnectionConfig = opts.connectionConfig instanceof ConnectionConfig
|
|
28
30
|
? opts.connectionConfig
|
|
29
31
|
: new ConnectionConfig(opts.connectionConfig);
|
|
32
|
+
const connectionConfig = baseConnectionConfig.withTransportIfMissing();
|
|
30
33
|
const lifecycleBaseUrl = connectionConfig.getBaseUrl();
|
|
31
34
|
const adapterFactory = opts.adapterFactory ?? createDefaultAdapterFactory();
|
|
32
|
-
|
|
33
|
-
|
|
35
|
+
let sandboxes;
|
|
36
|
+
try {
|
|
37
|
+
sandboxes = adapterFactory.createLifecycleStack({
|
|
38
|
+
connectionConfig,
|
|
39
|
+
lifecycleBaseUrl,
|
|
40
|
+
}).sandboxes;
|
|
41
|
+
}
|
|
42
|
+
catch (err) {
|
|
43
|
+
void connectionConfig.closeTransport().catch(() => undefined);
|
|
44
|
+
throw err;
|
|
45
|
+
}
|
|
46
|
+
return new SandboxManager({ sandboxes, connectionConfig });
|
|
34
47
|
}
|
|
35
48
|
listSandboxInfos(filter = {}) {
|
|
36
49
|
return this.sandboxes.listSandboxes({
|
|
@@ -60,12 +73,13 @@ export class SandboxManager {
|
|
|
60
73
|
await this.sandboxes.renewSandboxExpiration(sandboxId, { expiresAt });
|
|
61
74
|
}
|
|
62
75
|
/**
|
|
63
|
-
*
|
|
76
|
+
* Release the HTTP agent resources allocated for this manager instance.
|
|
64
77
|
*
|
|
65
|
-
*
|
|
66
|
-
*
|
|
78
|
+
* Each manager clone owns a scoped `ConnectionConfig` clone.
|
|
79
|
+
*
|
|
80
|
+
* This mirrors the Python SDK's default transport lifecycle.
|
|
67
81
|
*/
|
|
68
82
|
async close() {
|
|
69
|
-
|
|
83
|
+
await this.connectionConfig.closeTransport();
|
|
70
84
|
}
|
|
71
85
|
}
|
package/dist/sandbox.d.ts
CHANGED
|
@@ -111,6 +111,10 @@ export declare class Sandbox {
|
|
|
111
111
|
*/
|
|
112
112
|
static resume(opts: SandboxConnectOptions): Promise<Sandbox>;
|
|
113
113
|
kill(): Promise<void>;
|
|
114
|
+
/**
|
|
115
|
+
* Release any client-side resources (e.g. Node.js HTTP agents) owned by this Sandbox instance.
|
|
116
|
+
*/
|
|
117
|
+
close(): Promise<void>;
|
|
114
118
|
/**
|
|
115
119
|
* Renew expiration by setting expiresAt to now + timeoutSeconds.
|
|
116
120
|
*/
|
package/dist/sandbox.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sandbox.d.ts","sourceRoot":"","sources":["../src/sandbox.ts"],"names":[],"mappings":"AAsBA,OAAO,EAAE,gBAAgB,EAAE,KAAK,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AACxF,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAE7D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAElE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AACzD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AACjE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AAC7D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAC/D,OAAO,KAAK,EAEV,QAAQ,EACR,8BAA8B,EAC9B,SAAS,EACT,WAAW,EACZ,MAAM,uBAAuB,CAAC;AAG/B,MAAM,WAAW,oBAAoB;IACnC;;OAEG;IACH,gBAAgB,CAAC,EAAE,gBAAgB,GAAG,uBAAuB,CAAC;IAC9D;;OAEG;IACH,cAAc,CAAC,EAAE,cAAc,CAAC;IAEhC;;OAEG;IACH,KAAK,EACD,MAAM,GACN;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE;YAAE,QAAQ,EAAE,MAAM,CAAC;YAAC,QAAQ,EAAE,MAAM,CAAA;SAAE,CAAA;KAAE,CAAC;IAEnE,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7B,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAClC,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAEpC;;;;OAIG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAClC;;OAEG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IAExB;;;;;OAKG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B;;;;;OAKG;IACH,WAAW,CAAC,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC3D,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,0BAA0B,CAAC,EAAE,MAAM,CAAC;CACrC;AAED,MAAM,WAAW,qBAAqB;IACpC,gBAAgB,CAAC,EAAE,gBAAgB,GAAG,uBAAuB,CAAC;IAC9D,cAAc,CAAC,EAAE,cAAc,CAAC;IAChC,SAAS,EAAE,SAAS,CAAC;IAErB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,WAAW,CAAC,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC3D,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,0BAA0B,CAAC,EAAE,MAAM,CAAC;CACrC;AAaD,qBAAa,OAAO;IAClB,QAAQ,CAAC,EAAE,EAAE,SAAS,CAAC;IACvB,QAAQ,CAAC,gBAAgB,EAAE,gBAAgB,CAAC;IAE5C;;OAEG;IACH,QAAQ,CAAC,SAAS,EAAE,SAAS,CAAC;IAE9B;;OAEG;IACH,QAAQ,CAAC,QAAQ,EAAE,aAAa,CAAC;IACjC;;OAEG;IACH,QAAQ,CAAC,KAAK,EAAE,YAAY,CAAC;IAC7B,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC;IAC7B,QAAQ,CAAC,OAAO,EAAE,YAAY,CAAC;IAE/B;;;;OAIG;IACH,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAOzB;IAEJ,OAAO;WA2BM,MAAM,CAAC,IAAI,EAAE,oBAAoB,GAAG,OAAO,CAAC,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"sandbox.d.ts","sourceRoot":"","sources":["../src/sandbox.ts"],"names":[],"mappings":"AAsBA,OAAO,EAAE,gBAAgB,EAAE,KAAK,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AACxF,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAE7D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAElE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AACzD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AACjE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AAC7D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAC/D,OAAO,KAAK,EAEV,QAAQ,EACR,8BAA8B,EAC9B,SAAS,EACT,WAAW,EACZ,MAAM,uBAAuB,CAAC;AAG/B,MAAM,WAAW,oBAAoB;IACnC;;OAEG;IACH,gBAAgB,CAAC,EAAE,gBAAgB,GAAG,uBAAuB,CAAC;IAC9D;;OAEG;IACH,cAAc,CAAC,EAAE,cAAc,CAAC;IAEhC;;OAEG;IACH,KAAK,EACD,MAAM,GACN;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE;YAAE,QAAQ,EAAE,MAAM,CAAC;YAAC,QAAQ,EAAE,MAAM,CAAA;SAAE,CAAA;KAAE,CAAC;IAEnE,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7B,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAClC,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAEpC;;;;OAIG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAClC;;OAEG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IAExB;;;;;OAKG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B;;;;;OAKG;IACH,WAAW,CAAC,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC3D,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,0BAA0B,CAAC,EAAE,MAAM,CAAC;CACrC;AAED,MAAM,WAAW,qBAAqB;IACpC,gBAAgB,CAAC,EAAE,gBAAgB,GAAG,uBAAuB,CAAC;IAC9D,cAAc,CAAC,EAAE,cAAc,CAAC;IAChC,SAAS,EAAE,SAAS,CAAC;IAErB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,WAAW,CAAC,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC3D,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,0BAA0B,CAAC,EAAE,MAAM,CAAC;CACrC;AAaD,qBAAa,OAAO;IAClB,QAAQ,CAAC,EAAE,EAAE,SAAS,CAAC;IACvB,QAAQ,CAAC,gBAAgB,EAAE,gBAAgB,CAAC;IAE5C;;OAEG;IACH,QAAQ,CAAC,SAAS,EAAE,SAAS,CAAC;IAE9B;;OAEG;IACH,QAAQ,CAAC,QAAQ,EAAE,aAAa,CAAC;IACjC;;OAEG;IACH,QAAQ,CAAC,KAAK,EAAE,YAAY,CAAC;IAC7B,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC;IAC7B,QAAQ,CAAC,OAAO,EAAE,YAAY,CAAC;IAE/B;;;;OAIG;IACH,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAOzB;IAEJ,OAAO;WA2BM,MAAM,CAAC,IAAI,EAAE,oBAAoB,GAAG,OAAO,CAAC,OAAO,CAAC;WAqFpD,OAAO,CAAC,IAAI,EAAE,qBAAqB,GAAG,OAAO,CAAC,OAAO,CAAC;IA+D7D,OAAO,IAAI,OAAO,CAAC,WAAW,CAAC;IAI/B,SAAS,IAAI,OAAO,CAAC,OAAO,CAAC;IAQ7B,UAAU;IAIV,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAI5B;;;;;OAKG;IACG,MAAM,CACV,IAAI,GAAE;QACJ,eAAe,CAAC,EAAE,OAAO,CAAC;QAC1B,mBAAmB,CAAC,EAAE,MAAM,CAAC;QAC7B,0BAA0B,CAAC,EAAE,MAAM,CAAC;KAChC,GACL,OAAO,CAAC,OAAO,CAAC;IAYnB;;OAEG;WACU,MAAM,CAAC,IAAI,EAAE,qBAAqB,GAAG,OAAO,CAAC,OAAO,CAAC;IAyB5D,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAI3B;;OAEG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAI5B;;OAEG;IACG,KAAK,CAAC,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,8BAA8B,CAAC;IAO5E;;OAEG;IACG,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC;IAIlD;;OAEG;IACG,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAK7C,cAAc,CAAC,IAAI,EAAE;QACzB,mBAAmB,EAAE,MAAM,CAAC;QAC5B,qBAAqB,EAAE,MAAM,CAAC;QAC9B,WAAW,CAAC,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;KAC5D,GAAG,OAAO,CAAC,IAAI,CAAC;CAwBlB"}
|
package/dist/sandbox.js
CHANGED
|
@@ -61,15 +61,23 @@ export class Sandbox {
|
|
|
61
61
|
this.metrics = opts.metrics;
|
|
62
62
|
}
|
|
63
63
|
static async create(opts) {
|
|
64
|
-
const
|
|
64
|
+
const baseConnectionConfig = opts.connectionConfig instanceof ConnectionConfig
|
|
65
65
|
? opts.connectionConfig
|
|
66
66
|
: new ConnectionConfig(opts.connectionConfig);
|
|
67
|
+
const connectionConfig = baseConnectionConfig.withTransportIfMissing();
|
|
67
68
|
const lifecycleBaseUrl = connectionConfig.getBaseUrl();
|
|
68
69
|
const adapterFactory = opts.adapterFactory ?? createDefaultAdapterFactory();
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
70
|
+
let sandboxes;
|
|
71
|
+
try {
|
|
72
|
+
sandboxes = adapterFactory.createLifecycleStack({
|
|
73
|
+
connectionConfig,
|
|
74
|
+
lifecycleBaseUrl,
|
|
75
|
+
}).sandboxes;
|
|
76
|
+
}
|
|
77
|
+
catch (err) {
|
|
78
|
+
await connectionConfig.closeTransport();
|
|
79
|
+
throw err;
|
|
80
|
+
}
|
|
73
81
|
const req = {
|
|
74
82
|
image: toImageSpec(opts.image),
|
|
75
83
|
entrypoint: opts.entrypoint ?? DEFAULT_ENTRYPOINT,
|
|
@@ -120,46 +128,61 @@ export class Sandbox {
|
|
|
120
128
|
// Ignore cleanup failure; surface original error.
|
|
121
129
|
}
|
|
122
130
|
}
|
|
131
|
+
await connectionConfig.closeTransport();
|
|
123
132
|
throw err;
|
|
124
133
|
}
|
|
125
134
|
}
|
|
126
135
|
static async connect(opts) {
|
|
127
|
-
const
|
|
136
|
+
const baseConnectionConfig = opts.connectionConfig instanceof ConnectionConfig
|
|
128
137
|
? opts.connectionConfig
|
|
129
138
|
: new ConnectionConfig(opts.connectionConfig);
|
|
139
|
+
const connectionConfig = baseConnectionConfig.withTransportIfMissing();
|
|
130
140
|
const adapterFactory = opts.adapterFactory ?? createDefaultAdapterFactory();
|
|
131
141
|
const lifecycleBaseUrl = connectionConfig.getBaseUrl();
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
commands,
|
|
150
|
-
files,
|
|
151
|
-
health,
|
|
152
|
-
metrics,
|
|
153
|
-
});
|
|
154
|
-
if (!(opts.skipHealthCheck ?? false)) {
|
|
155
|
-
await sbx.waitUntilReady({
|
|
156
|
-
readyTimeoutSeconds: opts.readyTimeoutSeconds ?? DEFAULT_READY_TIMEOUT_SECONDS,
|
|
157
|
-
pollingIntervalMillis: opts.healthCheckPollingInterval ??
|
|
158
|
-
DEFAULT_HEALTH_CHECK_POLLING_INTERVAL_MILLIS,
|
|
159
|
-
healthCheck: opts.healthCheck,
|
|
142
|
+
let sandboxes;
|
|
143
|
+
try {
|
|
144
|
+
sandboxes = adapterFactory.createLifecycleStack({
|
|
145
|
+
connectionConfig,
|
|
146
|
+
lifecycleBaseUrl,
|
|
147
|
+
}).sandboxes;
|
|
148
|
+
}
|
|
149
|
+
catch (err) {
|
|
150
|
+
await connectionConfig.closeTransport();
|
|
151
|
+
throw err;
|
|
152
|
+
}
|
|
153
|
+
try {
|
|
154
|
+
const endpoint = await sandboxes.getSandboxEndpoint(opts.sandboxId, DEFAULT_EXECD_PORT);
|
|
155
|
+
const execdBaseUrl = `${connectionConfig.protocol}://${endpoint.endpoint}`;
|
|
156
|
+
const { commands, files, health, metrics } = adapterFactory.createExecdStack({
|
|
157
|
+
connectionConfig,
|
|
158
|
+
execdBaseUrl,
|
|
160
159
|
});
|
|
160
|
+
const sbx = new Sandbox({
|
|
161
|
+
id: opts.sandboxId,
|
|
162
|
+
connectionConfig,
|
|
163
|
+
adapterFactory,
|
|
164
|
+
lifecycleBaseUrl,
|
|
165
|
+
execdBaseUrl,
|
|
166
|
+
sandboxes,
|
|
167
|
+
commands,
|
|
168
|
+
files,
|
|
169
|
+
health,
|
|
170
|
+
metrics,
|
|
171
|
+
});
|
|
172
|
+
if (!(opts.skipHealthCheck ?? false)) {
|
|
173
|
+
await sbx.waitUntilReady({
|
|
174
|
+
readyTimeoutSeconds: opts.readyTimeoutSeconds ?? DEFAULT_READY_TIMEOUT_SECONDS,
|
|
175
|
+
pollingIntervalMillis: opts.healthCheckPollingInterval ??
|
|
176
|
+
DEFAULT_HEALTH_CHECK_POLLING_INTERVAL_MILLIS,
|
|
177
|
+
healthCheck: opts.healthCheck,
|
|
178
|
+
});
|
|
179
|
+
}
|
|
180
|
+
return sbx;
|
|
181
|
+
}
|
|
182
|
+
catch (err) {
|
|
183
|
+
await connectionConfig.closeTransport();
|
|
184
|
+
throw err;
|
|
161
185
|
}
|
|
162
|
-
return sbx;
|
|
163
186
|
}
|
|
164
187
|
async getInfo() {
|
|
165
188
|
return await this.sandboxes.getSandbox(this.id);
|
|
@@ -199,21 +222,36 @@ export class Sandbox {
|
|
|
199
222
|
* Resume a paused sandbox by id, then connect to its execd endpoint.
|
|
200
223
|
*/
|
|
201
224
|
static async resume(opts) {
|
|
202
|
-
const
|
|
225
|
+
const baseConnectionConfig = opts.connectionConfig instanceof ConnectionConfig
|
|
203
226
|
? opts.connectionConfig
|
|
204
227
|
: new ConnectionConfig(opts.connectionConfig);
|
|
205
228
|
const adapterFactory = opts.adapterFactory ?? createDefaultAdapterFactory();
|
|
206
|
-
const
|
|
207
|
-
const
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
229
|
+
const resumeConnectionConfig = baseConnectionConfig.withTransportIfMissing();
|
|
230
|
+
const lifecycleBaseUrl = resumeConnectionConfig.getBaseUrl();
|
|
231
|
+
let sandboxes;
|
|
232
|
+
try {
|
|
233
|
+
sandboxes = adapterFactory.createLifecycleStack({
|
|
234
|
+
connectionConfig: resumeConnectionConfig,
|
|
235
|
+
lifecycleBaseUrl,
|
|
236
|
+
}).sandboxes;
|
|
237
|
+
await sandboxes.resumeSandbox(opts.sandboxId);
|
|
238
|
+
}
|
|
239
|
+
catch (err) {
|
|
240
|
+
await resumeConnectionConfig.closeTransport();
|
|
241
|
+
throw err;
|
|
242
|
+
}
|
|
243
|
+
await resumeConnectionConfig.closeTransport();
|
|
244
|
+
return await Sandbox.connect({ ...opts, connectionConfig: baseConnectionConfig, adapterFactory });
|
|
213
245
|
}
|
|
214
246
|
async kill() {
|
|
215
247
|
await this.sandboxes.deleteSandbox(this.id);
|
|
216
248
|
}
|
|
249
|
+
/**
|
|
250
|
+
* Release any client-side resources (e.g. Node.js HTTP agents) owned by this Sandbox instance.
|
|
251
|
+
*/
|
|
252
|
+
async close() {
|
|
253
|
+
await this.connectionConfig.closeTransport();
|
|
254
|
+
}
|
|
217
255
|
/**
|
|
218
256
|
* Renew expiration by setting expiresAt to now + timeoutSeconds.
|
|
219
257
|
*/
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@alibaba-group/opensandbox",
|
|
3
|
-
"version": "0.1.0-
|
|
3
|
+
"version": "0.1.0-dev4",
|
|
4
4
|
"description": "OpenSandbox TypeScript/JavaScript SDK (sandbox lifecycle + execd APIs)",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"type": "module",
|
|
@@ -33,7 +33,8 @@
|
|
|
33
33
|
"node": ">=20"
|
|
34
34
|
},
|
|
35
35
|
"dependencies": {
|
|
36
|
-
"openapi-fetch": "^0.13.8"
|
|
36
|
+
"openapi-fetch": "^0.13.8",
|
|
37
|
+
"undici": "^7.18.2"
|
|
37
38
|
},
|
|
38
39
|
"devDependencies": {
|
|
39
40
|
"@eslint/js": "^9.39.2",
|