@cloudflare/sandbox 0.9.3 → 0.9.4
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/bridge/index.js +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/openai/index.d.ts +1 -1
- package/dist/opencode/index.d.ts +1 -1
- package/dist/opencode/index.d.ts.map +1 -1
- package/dist/{sandbox-CW4QeITP.d.ts → sandbox-C-AzrX_L.d.ts} +13 -2
- package/dist/{sandbox-CW4QeITP.d.ts.map → sandbox-C-AzrX_L.d.ts.map} +1 -1
- package/dist/{sandbox-BAuU-2a0.js → sandbox-CdWjEUHl.js} +83 -21
- package/dist/sandbox-CdWjEUHl.js.map +1 -0
- package/package.json +1 -1
- package/dist/sandbox-BAuU-2a0.js.map +0 -1
|
@@ -765,8 +765,8 @@ function createErrorFromResponse(errorResponse, options) {
|
|
|
765
765
|
/**
|
|
766
766
|
* Container startup retry configuration
|
|
767
767
|
*/
|
|
768
|
-
const DEFAULT_RETRY_TIMEOUT_MS = 12e4;
|
|
769
|
-
const MIN_TIME_FOR_RETRY_MS = 15e3;
|
|
768
|
+
const DEFAULT_RETRY_TIMEOUT_MS$1 = 12e4;
|
|
769
|
+
const MIN_TIME_FOR_RETRY_MS$1 = 15e3;
|
|
770
770
|
/**
|
|
771
771
|
* Abstract base transport with shared retry logic
|
|
772
772
|
*
|
|
@@ -780,7 +780,7 @@ var BaseTransport = class {
|
|
|
780
780
|
constructor(config) {
|
|
781
781
|
this.config = config;
|
|
782
782
|
this.logger = config.logger ?? createNoOpLogger();
|
|
783
|
-
this.retryTimeoutMs = config.retryTimeoutMs ?? DEFAULT_RETRY_TIMEOUT_MS;
|
|
783
|
+
this.retryTimeoutMs = config.retryTimeoutMs ?? DEFAULT_RETRY_TIMEOUT_MS$1;
|
|
784
784
|
}
|
|
785
785
|
setRetryTimeoutMs(ms) {
|
|
786
786
|
this.retryTimeoutMs = ms;
|
|
@@ -802,7 +802,7 @@ var BaseTransport = class {
|
|
|
802
802
|
if (response.status === 503) {
|
|
803
803
|
const elapsed = Date.now() - startTime;
|
|
804
804
|
const remaining = this.retryTimeoutMs - elapsed;
|
|
805
|
-
if (remaining > MIN_TIME_FOR_RETRY_MS) {
|
|
805
|
+
if (remaining > MIN_TIME_FOR_RETRY_MS$1) {
|
|
806
806
|
const delay = Math.min(3e3 * 2 ** attempt, 3e4);
|
|
807
807
|
this.logger.info("Container not ready, retrying", {
|
|
808
808
|
status: response.status,
|
|
@@ -2756,6 +2756,9 @@ function normalizeBackupExcludePattern(pattern) {
|
|
|
2756
2756
|
//#endregion
|
|
2757
2757
|
//#region src/container-control/connection.ts
|
|
2758
2758
|
const DEFAULT_CONNECT_TIMEOUT_MS = 3e4;
|
|
2759
|
+
const DEFAULT_RETRY_TIMEOUT_MS = 12e4;
|
|
2760
|
+
const MIN_TIME_FOR_RETRY_MS = 15e3;
|
|
2761
|
+
const MAX_RETRY_BACKOFF_MS = 3e4;
|
|
2759
2762
|
/**
|
|
2760
2763
|
* Manages a capnweb WebSocket RPC session to the container.
|
|
2761
2764
|
*
|
|
@@ -2773,10 +2776,12 @@ var ContainerControlConnection = class {
|
|
|
2773
2776
|
containerStub;
|
|
2774
2777
|
port;
|
|
2775
2778
|
logger;
|
|
2779
|
+
retryTimeoutMs;
|
|
2776
2780
|
constructor(options) {
|
|
2777
2781
|
this.containerStub = options.stub;
|
|
2778
2782
|
this.port = options.port ?? 3e3;
|
|
2779
2783
|
this.logger = options.logger ?? createNoOpLogger();
|
|
2784
|
+
this.retryTimeoutMs = options.retryTimeoutMs ?? DEFAULT_RETRY_TIMEOUT_MS;
|
|
2780
2785
|
this.transport = new DeferredTransport();
|
|
2781
2786
|
this.session = new RpcSession(this.transport);
|
|
2782
2787
|
this.stub = this.session.getRemoteMain();
|
|
@@ -2826,20 +2831,17 @@ var ContainerControlConnection = class {
|
|
|
2826
2831
|
this.connected = false;
|
|
2827
2832
|
this.connectPromise = null;
|
|
2828
2833
|
}
|
|
2834
|
+
/**
|
|
2835
|
+
* Update the 503 retry budget without recreating the connection. Takes
|
|
2836
|
+
* effect on the next `connect()`; an in-flight connect uses the value
|
|
2837
|
+
* captured at start. Mirrors `WebSocketTransport.setRetryTimeoutMs`.
|
|
2838
|
+
*/
|
|
2839
|
+
setRetryTimeoutMs(ms) {
|
|
2840
|
+
this.retryTimeoutMs = ms;
|
|
2841
|
+
}
|
|
2829
2842
|
async doConnect() {
|
|
2830
|
-
const controller = new AbortController();
|
|
2831
|
-
const timeout = setTimeout(() => controller.abort(), DEFAULT_CONNECT_TIMEOUT_MS);
|
|
2832
2843
|
try {
|
|
2833
|
-
const
|
|
2834
|
-
const request = new Request(url, {
|
|
2835
|
-
headers: {
|
|
2836
|
-
Upgrade: "websocket",
|
|
2837
|
-
Connection: "Upgrade"
|
|
2838
|
-
},
|
|
2839
|
-
signal: controller.signal
|
|
2840
|
-
});
|
|
2841
|
-
const response = await this.containerStub.fetch(request);
|
|
2842
|
-
clearTimeout(timeout);
|
|
2844
|
+
const response = await this.fetchUpgradeWithRetry();
|
|
2843
2845
|
if (response.status !== 101) throw new Error(`WebSocket upgrade failed: ${response.status} ${response.statusText}`);
|
|
2844
2846
|
const ws = response.webSocket;
|
|
2845
2847
|
if (!ws) throw new Error("No WebSocket in upgrade response");
|
|
@@ -2858,13 +2860,63 @@ var ContainerControlConnection = class {
|
|
|
2858
2860
|
this.connected = true;
|
|
2859
2861
|
this.logger.debug("ContainerControlConnection established", { port: this.port });
|
|
2860
2862
|
} catch (error) {
|
|
2861
|
-
clearTimeout(timeout);
|
|
2862
2863
|
this.connected = false;
|
|
2863
2864
|
this.transport.abort(error);
|
|
2864
2865
|
this.logger.error("ContainerControlConnection failed", error instanceof Error ? error : new Error(String(error)));
|
|
2865
2866
|
throw error;
|
|
2866
2867
|
}
|
|
2867
2868
|
}
|
|
2869
|
+
/**
|
|
2870
|
+
* Issue WebSocket upgrade fetches, retrying transient 503 responses with
|
|
2871
|
+
* exponential backoff (3s → 6s → 12s → … capped at 30s) until either
|
|
2872
|
+
* the upgrade succeeds, a non-503 status is returned, or the retry budget
|
|
2873
|
+
* runs out. Mirrors `WebSocketTransport.fetchUpgradeWithRetry` so both
|
|
2874
|
+
* transports behave the same way during container startup.
|
|
2875
|
+
*/
|
|
2876
|
+
async fetchUpgradeWithRetry() {
|
|
2877
|
+
const retryTimeoutMs = this.retryTimeoutMs;
|
|
2878
|
+
const startTime = Date.now();
|
|
2879
|
+
let attempt = 0;
|
|
2880
|
+
while (true) {
|
|
2881
|
+
const response = await this.fetchUpgradeAttempt();
|
|
2882
|
+
if (response.status !== 503) return response;
|
|
2883
|
+
const remaining = retryTimeoutMs - (Date.now() - startTime);
|
|
2884
|
+
if (remaining <= MIN_TIME_FOR_RETRY_MS) return response;
|
|
2885
|
+
const delay = Math.min(3e3 * 2 ** attempt, MAX_RETRY_BACKOFF_MS);
|
|
2886
|
+
this.logger.info("ContainerControlConnection upgrade returned 503, retrying", {
|
|
2887
|
+
attempt: attempt + 1,
|
|
2888
|
+
delayMs: delay,
|
|
2889
|
+
remainingSec: Math.floor(remaining / 1e3)
|
|
2890
|
+
});
|
|
2891
|
+
await this.sleep(delay);
|
|
2892
|
+
attempt++;
|
|
2893
|
+
}
|
|
2894
|
+
}
|
|
2895
|
+
/**
|
|
2896
|
+
* Single WebSocket-upgrade fetch attempt. Owns its own AbortController so
|
|
2897
|
+
* each retry gets a fresh per-attempt connect timeout independent of the
|
|
2898
|
+
* total retry budget.
|
|
2899
|
+
*/
|
|
2900
|
+
async fetchUpgradeAttempt() {
|
|
2901
|
+
const controller = new AbortController();
|
|
2902
|
+
const timeout = setTimeout(() => controller.abort(), DEFAULT_CONNECT_TIMEOUT_MS);
|
|
2903
|
+
try {
|
|
2904
|
+
const url = `http://localhost:${this.port}/rpc`;
|
|
2905
|
+
const request = new Request(url, {
|
|
2906
|
+
headers: {
|
|
2907
|
+
Upgrade: "websocket",
|
|
2908
|
+
Connection: "Upgrade"
|
|
2909
|
+
},
|
|
2910
|
+
signal: controller.signal
|
|
2911
|
+
});
|
|
2912
|
+
return await this.containerStub.fetch(request);
|
|
2913
|
+
} finally {
|
|
2914
|
+
clearTimeout(timeout);
|
|
2915
|
+
}
|
|
2916
|
+
}
|
|
2917
|
+
sleep(ms) {
|
|
2918
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
2919
|
+
}
|
|
2868
2920
|
};
|
|
2869
2921
|
/**
|
|
2870
2922
|
* RPC transport that queues sends and blocks receives until a WebSocket
|
|
@@ -3093,7 +3145,8 @@ var ContainerControlClient = class {
|
|
|
3093
3145
|
this.connOptions = {
|
|
3094
3146
|
stub: options.stub,
|
|
3095
3147
|
port: options.port,
|
|
3096
|
-
logger: options.logger
|
|
3148
|
+
logger: options.logger,
|
|
3149
|
+
retryTimeoutMs: options.retryTimeoutMs
|
|
3097
3150
|
};
|
|
3098
3151
|
this.idleDisconnectMs = options.idleDisconnectMs ?? DEFAULT_IDLE_DISCONNECT_MS;
|
|
3099
3152
|
this.busyPollIntervalMs = options.busyPollIntervalMs ?? BUSY_POLL_INTERVAL_MS;
|
|
@@ -3226,7 +3279,15 @@ var ContainerControlClient = class {
|
|
|
3226
3279
|
get interpreter() {
|
|
3227
3280
|
return wrapStub(this.getConnection().rpc().interpreter, this.renewActivity);
|
|
3228
3281
|
}
|
|
3229
|
-
|
|
3282
|
+
/**
|
|
3283
|
+
* Update the 503 upgrade-retry budget. Applies to the current connection
|
|
3284
|
+
* (if any) and is remembered for any future connections created after the
|
|
3285
|
+
* client is torn down and reconnected.
|
|
3286
|
+
*/
|
|
3287
|
+
setRetryTimeoutMs(ms) {
|
|
3288
|
+
this.connOptions.retryTimeoutMs = ms;
|
|
3289
|
+
this.conn?.setRetryTimeoutMs(ms);
|
|
3290
|
+
}
|
|
3230
3291
|
getTransportMode() {
|
|
3231
3292
|
return "rpc";
|
|
3232
3293
|
}
|
|
@@ -4196,7 +4257,7 @@ function isLocalhostPattern(hostname) {
|
|
|
4196
4257
|
* This file is auto-updated by .github/changeset-version.ts during releases
|
|
4197
4258
|
* DO NOT EDIT MANUALLY - Changes will be overwritten on the next version bump
|
|
4198
4259
|
*/
|
|
4199
|
-
const SDK_VERSION = "0.9.
|
|
4260
|
+
const SDK_VERSION = "0.9.4";
|
|
4200
4261
|
|
|
4201
4262
|
//#endregion
|
|
4202
4263
|
//#region src/sandbox.ts
|
|
@@ -4528,6 +4589,7 @@ var Sandbox = class Sandbox extends Container {
|
|
|
4528
4589
|
stub: this,
|
|
4529
4590
|
port: 3e3,
|
|
4530
4591
|
logger: this.logger,
|
|
4592
|
+
retryTimeoutMs: this.computeRetryTimeoutMs(),
|
|
4531
4593
|
onActivity: () => {
|
|
4532
4594
|
this.renewActivityTimeout();
|
|
4533
4595
|
},
|
|
@@ -7506,4 +7568,4 @@ var Sandbox = class Sandbox extends Container {
|
|
|
7506
7568
|
|
|
7507
7569
|
//#endregion
|
|
7508
7570
|
export { DesktopInvalidOptionsError as A, CommandClient as C, BackupNotFoundError as D, BackupExpiredError as E, InvalidBackupConfigError as F, ProcessExitedBeforeReadyError as I, ProcessReadyTimeoutError as L, DesktopProcessCrashedError as M, DesktopStartFailedError as N, BackupRestoreError as O, DesktopUnavailableError as P, RPCTransportError as R, DesktopClient as S, BackupCreateError as T, UtilityClient as _, BucketMountError as a, GitClient as b, MissingCredentialsError as c, parseSSEStream as d, responseToAsyncIterable as f, SandboxClient as g, streamFile as h, proxyTerminal as i, DesktopNotStartedError as j, DesktopInvalidCoordinatesError as k, S3FSMountError as l, collectFile as m, getSandbox as n, BucketUnmountError as o, CodeInterpreter as p, proxyToSandbox as r, InvalidMountConfigError as s, Sandbox as t, asyncIterableToSSEStream as u, ProcessClient as v, BackupClient as w, FileClient as x, PortClient as y, SessionTerminatedError as z };
|
|
7509
|
-
//# sourceMappingURL=sandbox-
|
|
7571
|
+
//# sourceMappingURL=sandbox-CdWjEUHl.js.map
|