@vercel/sandbox 0.0.20 → 0.0.22

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.
@@ -1,4 +1,4 @@
1
1
 
2
- > @vercel/sandbox@0.0.20 build /home/runner/work/sandbox-sdk/sandbox-sdk/packages/sandbox
2
+ > @vercel/sandbox@0.0.22 build /home/runner/work/sandbox-sdk/sandbox-sdk/packages/sandbox
3
3
  > tsc
4
4
 
@@ -1,4 +1,4 @@
1
1
 
2
- > @vercel/sandbox@0.0.20 typecheck /home/runner/work/sandbox-sdk/sandbox-sdk/packages/sandbox
2
+ > @vercel/sandbox@0.0.22 typecheck /home/runner/work/sandbox-sdk/sandbox-sdk/packages/sandbox
3
3
  > tsc --noEmit
4
4
 
package/CHANGELOG.md CHANGED
@@ -1,5 +1,19 @@
1
1
  # @vercel/sandbox
2
2
 
3
+ ## 0.0.22
4
+
5
+ ### Patch Changes
6
+
7
+ - add AbortSignal support in public interface ([#137](https://github.com/vercel/sandbox-sdk/pull/137))
8
+
9
+ - add AbortSignal support to command.wait ([#136](https://github.com/vercel/sandbox-sdk/pull/136))
10
+
11
+ ## 0.0.21
12
+
13
+ ### Patch Changes
14
+
15
+ - Disable Undici body timeout ([#126](https://github.com/vercel/sandbox-sdk/pull/126))
16
+
3
17
  ## 0.0.20
4
18
 
5
19
  ### Patch Changes
@@ -15,18 +15,19 @@ export declare class APIClient extends BaseClient {
15
15
  protected request(path: string, params?: RequestParams): Promise<Response>;
16
16
  getSandbox(params: {
17
17
  sandboxId: string;
18
+ signal?: AbortSignal;
18
19
  }): Promise<Parsed<{
19
20
  sandbox: {
20
21
  region: string;
21
22
  status: "pending" | "running" | "stopping" | "stopped" | "failed";
23
+ timeout: number;
24
+ cwd: string;
22
25
  id: string;
23
26
  memory: number;
24
27
  vcpus: number;
25
28
  runtime: string;
26
- timeout: number;
27
29
  requestedAt: number;
28
30
  createdAt: number;
29
- cwd: string;
30
31
  updatedAt: number;
31
32
  duration?: number | undefined;
32
33
  startedAt?: number | undefined;
@@ -35,8 +36,8 @@ export declare class APIClient extends BaseClient {
35
36
  };
36
37
  routes: {
37
38
  url: string;
38
- subdomain: string;
39
39
  port: number;
40
+ subdomain: string;
40
41
  }[];
41
42
  }>>;
42
43
  createSandbox(params: WithPrivate<{
@@ -58,18 +59,19 @@ export declare class APIClient extends BaseClient {
58
59
  vcpus: number;
59
60
  };
60
61
  runtime?: "node22" | "python3.13" | (string & {});
62
+ signal?: AbortSignal;
61
63
  }>): Promise<Parsed<{
62
64
  sandbox: {
63
65
  region: string;
64
66
  status: "pending" | "running" | "stopping" | "stopped" | "failed";
67
+ timeout: number;
68
+ cwd: string;
65
69
  id: string;
66
70
  memory: number;
67
71
  vcpus: number;
68
72
  runtime: string;
69
- timeout: number;
70
73
  requestedAt: number;
71
74
  createdAt: number;
72
- cwd: string;
73
75
  updatedAt: number;
74
76
  duration?: number | undefined;
75
77
  startedAt?: number | undefined;
@@ -78,8 +80,8 @@ export declare class APIClient extends BaseClient {
78
80
  };
79
81
  routes: {
80
82
  url: string;
81
- subdomain: string;
82
83
  port: number;
84
+ subdomain: string;
83
85
  }[];
84
86
  }>>;
85
87
  runCommand(params: {
@@ -89,13 +91,14 @@ export declare class APIClient extends BaseClient {
89
91
  args: string[];
90
92
  env: Record<string, string>;
91
93
  sudo: boolean;
94
+ signal?: AbortSignal;
92
95
  }): Promise<Parsed<{
93
96
  command: {
94
97
  name: string;
95
98
  args: string[];
99
+ cwd: string;
96
100
  id: string;
97
101
  startedAt: number;
98
- cwd: string;
99
102
  sandboxId: string;
100
103
  exitCode: number | null;
101
104
  };
@@ -104,20 +107,24 @@ export declare class APIClient extends BaseClient {
104
107
  sandboxId: string;
105
108
  cmdId: string;
106
109
  wait: true;
110
+ signal?: AbortSignal;
107
111
  }): Promise<Parsed<z.infer<typeof CommandFinishedResponse>>>;
108
112
  getCommand(params: {
109
113
  sandboxId: string;
110
114
  cmdId: string;
111
115
  wait?: boolean;
116
+ signal?: AbortSignal;
112
117
  }): Promise<Parsed<z.infer<typeof CommandResponse>>>;
113
118
  mkDir(params: {
114
119
  sandboxId: string;
115
120
  path: string;
116
121
  cwd?: string;
122
+ signal?: AbortSignal;
117
123
  }): Promise<Parsed<{}>>;
118
124
  getFileWriter(params: {
119
125
  sandboxId: string;
120
126
  extractDir: string;
127
+ signal?: AbortSignal;
121
128
  }): {
122
129
  response: Promise<Response>;
123
130
  writer: FileWriter;
@@ -143,18 +150,19 @@ export declare class APIClient extends BaseClient {
143
150
  * @example 1540095775951
144
151
  */
145
152
  until?: number | Date;
153
+ signal?: AbortSignal;
146
154
  }): Promise<Parsed<{
147
155
  sandboxes: {
148
156
  region: string;
149
157
  status: "pending" | "running" | "stopping" | "stopped" | "failed";
158
+ timeout: number;
159
+ cwd: string;
150
160
  id: string;
151
161
  memory: number;
152
162
  vcpus: number;
153
163
  runtime: string;
154
- timeout: number;
155
164
  requestedAt: number;
156
165
  createdAt: number;
157
- cwd: string;
158
166
  updatedAt: number;
159
167
  duration?: number | undefined;
160
168
  startedAt?: number | undefined;
@@ -175,23 +183,26 @@ export declare class APIClient extends BaseClient {
175
183
  content: Buffer;
176
184
  }[];
177
185
  extractDir: string;
186
+ signal?: AbortSignal;
178
187
  }): Promise<void>;
179
188
  readFile(params: {
180
189
  sandboxId: string;
181
190
  path: string;
182
191
  cwd?: string;
192
+ signal?: AbortSignal;
183
193
  }): Promise<NodeJS.ReadableStream | null>;
184
194
  killCommand(params: {
185
195
  sandboxId: string;
186
196
  commandId: string;
187
197
  signal: number;
198
+ abortSignal?: AbortSignal;
188
199
  }): Promise<Parsed<{
189
200
  command: {
190
201
  name: string;
191
202
  args: string[];
203
+ cwd: string;
192
204
  id: string;
193
205
  startedAt: number;
194
- cwd: string;
195
206
  sandboxId: string;
196
207
  exitCode: number | null;
197
208
  };
@@ -205,5 +216,6 @@ export declare class APIClient extends BaseClient {
205
216
  };
206
217
  stopSandbox(params: {
207
218
  sandboxId: string;
219
+ signal?: AbortSignal;
208
220
  }): Promise<Parsed<z.infer<typeof SandboxResponse>>>;
209
221
  }
@@ -53,7 +53,9 @@ class APIClient extends base_client_1.BaseClient {
53
53
  });
54
54
  }
55
55
  async getSandbox(params) {
56
- return (0, base_client_1.parseOrThrow)(validators_1.SandboxAndRoutesResponse, await this.request(`/v1/sandboxes/${params.sandboxId}`));
56
+ return (0, base_client_1.parseOrThrow)(validators_1.SandboxAndRoutesResponse, await this.request(`/v1/sandboxes/${params.sandboxId}`, {
57
+ signal: params.signal,
58
+ }));
57
59
  }
58
60
  async createSandbox(params) {
59
61
  const privateParams = (0, types_1.getPrivateParams)(params);
@@ -68,6 +70,7 @@ class APIClient extends base_client_1.BaseClient {
68
70
  runtime: params.runtime,
69
71
  ...privateParams,
70
72
  }),
73
+ signal: params.signal,
71
74
  }));
72
75
  }
73
76
  async runCommand(params) {
@@ -80,17 +83,19 @@ class APIClient extends base_client_1.BaseClient {
80
83
  env: params.env,
81
84
  sudo: params.sudo,
82
85
  }),
86
+ signal: params.signal,
83
87
  }));
84
88
  }
85
89
  async getCommand(params) {
86
90
  return params.wait
87
- ? (0, base_client_1.parseOrThrow)(validators_1.CommandFinishedResponse, await this.request(`/v1/sandboxes/${params.sandboxId}/cmd/${params.cmdId}`, { query: { wait: "true" } }))
88
- : (0, base_client_1.parseOrThrow)(validators_1.CommandResponse, await this.request(`/v1/sandboxes/${params.sandboxId}/cmd/${params.cmdId}`));
91
+ ? (0, base_client_1.parseOrThrow)(validators_1.CommandFinishedResponse, await this.request(`/v1/sandboxes/${params.sandboxId}/cmd/${params.cmdId}`, { signal: params.signal, query: { wait: "true" } }))
92
+ : (0, base_client_1.parseOrThrow)(validators_1.CommandResponse, await this.request(`/v1/sandboxes/${params.sandboxId}/cmd/${params.cmdId}`, { signal: params.signal }));
89
93
  }
90
94
  async mkDir(params) {
91
95
  return (0, base_client_1.parseOrThrow)(validators_1.EmptyResponse, await this.request(`/v1/sandboxes/${params.sandboxId}/fs/mkdir`, {
92
96
  method: "POST",
93
97
  body: JSON.stringify({ path: params.path, cwd: params.cwd }),
98
+ signal: params.signal,
94
99
  }));
95
100
  }
96
101
  getFileWriter(params) {
@@ -104,6 +109,7 @@ class APIClient extends base_client_1.BaseClient {
104
109
  "x-cwd": params.extractDir,
105
110
  },
106
111
  body: await (0, consume_readable_1.consumeReadable)(writer.readable),
112
+ signal: params.signal,
107
113
  });
108
114
  })(),
109
115
  writer,
@@ -122,12 +128,14 @@ class APIClient extends base_client_1.BaseClient {
122
128
  : params.until?.getTime(),
123
129
  },
124
130
  method: "GET",
131
+ signal: params.signal,
125
132
  }));
126
133
  }
127
134
  async writeFiles(params) {
128
135
  const { writer, response } = this.getFileWriter({
129
136
  sandboxId: params.sandboxId,
130
137
  extractDir: params.extractDir,
138
+ signal: params.signal,
131
139
  });
132
140
  for (const file of params.files) {
133
141
  await writer.addFile({
@@ -146,6 +154,7 @@ class APIClient extends base_client_1.BaseClient {
146
154
  const response = await this.request(`/v1/sandboxes/${params.sandboxId}/fs/read`, {
147
155
  method: "POST",
148
156
  body: JSON.stringify({ path: params.path, cwd: params.cwd }),
157
+ signal: params.signal,
149
158
  });
150
159
  if (response.status === 404) {
151
160
  return null;
@@ -159,6 +168,7 @@ class APIClient extends base_client_1.BaseClient {
159
168
  return (0, base_client_1.parseOrThrow)(validators_1.CommandResponse, await this.request(`/v1/sandboxes/${params.sandboxId}/${params.commandId}/kill`, {
160
169
  method: "POST",
161
170
  body: JSON.stringify({ signal: params.signal }),
171
+ signal: params.abortSignal,
162
172
  }));
163
173
  }
164
174
  getLogs(params) {
@@ -200,7 +210,7 @@ class APIClient extends base_client_1.BaseClient {
200
210
  }
201
211
  async stopSandbox(params) {
202
212
  const url = `/v1/sandboxes/${params.sandboxId}/stop`;
203
- return (0, base_client_1.parseOrThrow)(validators_1.SandboxResponse, await this.request(url, { method: "POST" }));
213
+ return (0, base_client_1.parseOrThrow)(validators_1.SandboxResponse, await this.request(url, { method: "POST", signal: params.signal }));
204
214
  }
205
215
  }
206
216
  exports.APIClient = APIClient;
@@ -19,6 +19,7 @@ export declare class BaseClient {
19
19
  private fetch;
20
20
  private debug;
21
21
  private host;
22
+ private agent;
22
23
  constructor(params: {
23
24
  debug?: boolean;
24
25
  host: string;
@@ -6,6 +6,7 @@ exports.parseOrThrow = parseOrThrow;
6
6
  const api_error_1 = require("./api-error");
7
7
  const array_1 = require("../utils/array");
8
8
  const with_retry_1 = require("./with-retry");
9
+ const undici_1 = require("undici");
9
10
  /**
10
11
  * A base API client that provides a convenience wrapper for fetching where
11
12
  * we can pass query parameters as an object, support retries, debugging
@@ -17,6 +18,9 @@ class BaseClient {
17
18
  this.host = params.host;
18
19
  this.debug = params.debug ?? process.env.DEBUG_FETCH === "true";
19
20
  this.token = params.token;
21
+ this.agent = new undici_1.Agent({
22
+ bodyTimeout: 0, // disable body timeout to allow long logs streaming
23
+ });
20
24
  }
21
25
  async request(path, opts) {
22
26
  const url = new URL(path, this.host);
@@ -35,6 +39,9 @@ class BaseClient {
35
39
  headers: this.token
36
40
  ? { Authorization: `Bearer ${this.token}`, ...opts?.headers }
37
41
  : opts?.headers,
42
+ // @ts-expect-error Node.js' and undici's Agent have different types
43
+ dispatcher: this.agent,
44
+ signal: opts?.signal,
38
45
  });
39
46
  if (this.debug) {
40
47
  const duration = Date.now() - start;