withruntime 0.8.4 → 0.10.0
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/BLAXEL.md +4 -4
- package/COMPATIBILITY.md +145 -0
- package/DAYTONA.md +13 -7
- package/E2B.md +34 -20
- package/README.md +22 -11
- package/README.src.md +22 -11
- package/VERCEL.md +13 -3
- package/compatibility-lock.json +357 -0
- package/dist/ai-harness/index.js +2 -2
- package/dist/api-defaults.d.ts +17 -0
- package/dist/api-defaults.js +22 -0
- package/dist/blaxel/errors.js +1 -1
- package/dist/blaxel/lookup.d.ts +3 -2
- package/dist/blaxel/lookup.js +3 -2
- package/dist/blaxel/pagination.d.ts +2 -2
- package/dist/blaxel/pagination.js +45 -17
- package/dist/blaxel/preview.d.ts +3 -2
- package/dist/blaxel/preview.js +16 -14
- package/dist/blaxel/process.d.ts +1 -1
- package/dist/blaxel/process.js +66 -11
- package/dist/blaxel/sandbox.d.ts +2 -0
- package/dist/blaxel/sandbox.js +2 -0
- package/dist/blaxel/snapshot.js +3 -5
- package/dist/cli-words.d.ts +27 -0
- package/dist/cli-words.js +135 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +351 -85
- package/dist/client.d.ts +33 -4
- package/dist/client.js +47 -12
- package/dist/cloudflare/identity.d.ts +7 -0
- package/dist/cloudflare/identity.js +13 -0
- package/dist/cloudflare/index.d.ts +303 -0
- package/dist/cloudflare/index.js +592 -0
- package/dist/cloudflare/worker.d.ts +419 -0
- package/dist/cloudflare/worker.js +447 -0
- package/dist/codesandbox/guest-service.d.ts +31 -0
- package/dist/codesandbox/guest-service.js +490 -0
- package/dist/codesandbox/index.d.ts +386 -0
- package/dist/codesandbox/index.js +1347 -0
- package/dist/compat/core.d.ts +40 -0
- package/dist/compat/core.js +238 -0
- package/dist/compat/files.d.ts +26 -0
- package/dist/compat/files.js +133 -0
- package/dist/compat/shell.d.ts +4 -0
- package/dist/compat/shell.js +165 -0
- package/dist/credentials.d.ts +6 -1
- package/dist/credentials.js +107 -38
- package/dist/daytona/context.js +2 -1
- package/dist/daytona/daytona.js +11 -4
- package/dist/daytona/filesystem.d.ts +17 -4
- package/dist/daytona/filesystem.js +121 -38
- package/dist/daytona/index.d.ts +1 -1
- package/dist/daytona/process.d.ts +1 -1
- package/dist/daytona/process.js +27 -4
- package/dist/daytona/sandbox.d.ts +1 -1
- package/dist/daytona/sandbox.js +16 -7
- package/dist/e2b/client.js +1 -1
- package/dist/e2b/code-interpreter.d.ts +4 -5
- package/dist/e2b/code-interpreter.js +54 -56
- package/dist/e2b/commands.d.ts +35 -12
- package/dist/e2b/commands.js +169 -73
- package/dist/e2b/errors.js +1 -1
- package/dist/e2b/filesystem.d.ts +8 -6
- package/dist/e2b/filesystem.js +127 -28
- package/dist/e2b/index.d.ts +1 -0
- package/dist/e2b/index.js +1 -0
- package/dist/e2b/pty.d.ts +24 -0
- package/dist/e2b/pty.js +80 -0
- package/dist/e2b/sandbox.d.ts +6 -4
- package/dist/e2b/sandbox.js +59 -25
- package/dist/errors.d.ts +8 -0
- package/dist/errors.js +15 -2
- package/dist/file-source.d.ts +16 -0
- package/dist/file-source.js +162 -0
- package/dist/freestyle/index.d.ts +309 -0
- package/dist/freestyle/index.js +343 -0
- package/dist/index.d.ts +3 -1
- package/dist/login.js +16 -10
- package/dist/mcp.js +2 -2
- package/dist/modal/index.d.ts +205 -0
- package/dist/modal/index.js +486 -0
- package/dist/network-cli.js +112 -44
- package/dist/openai-agents/index.js +18 -71
- package/dist/page.d.ts +1 -1
- package/dist/page.js +2 -2
- package/dist/products/audit.d.ts +3 -0
- package/dist/products/index.d.ts +14 -0
- package/dist/products/index.js +12 -0
- package/dist/products/interpreter.d.ts +11 -4
- package/dist/products/interpreter.js +33 -9
- package/dist/products/jobs.js +3 -2
- package/dist/products/limits.d.ts +10 -0
- package/dist/products/observability.d.ts +44 -0
- package/dist/products/observability.js +6 -0
- package/dist/products/previews.d.ts +18 -4
- package/dist/products/previews.js +14 -5
- package/dist/products/tailscale.d.ts +57 -0
- package/dist/products/tailscale.js +17 -0
- package/dist/products/volumes.d.ts +42 -0
- package/dist/products/volumes.js +36 -0
- package/dist/products/watch.d.ts +25 -4
- package/dist/products/watch.js +132 -18
- package/dist/proxy.js +3 -1
- package/dist/runloop/index.d.ts +326 -0
- package/dist/runloop/index.js +535 -0
- package/dist/runloop/pagination.d.ts +46 -0
- package/dist/runloop/pagination.js +82 -0
- package/dist/runloop/snapshots.d.ts +52 -0
- package/dist/runloop/snapshots.js +244 -0
- package/dist/sandbox.d.ts +76 -16
- package/dist/sandbox.js +696 -135
- package/dist/snapshots.d.ts +20 -5
- package/dist/snapshots.js +11 -1
- package/dist/sprites/index.d.ts +251 -0
- package/dist/sprites/index.js +588 -0
- package/dist/tar.d.ts +10 -1
- package/dist/tar.js +311 -35
- package/dist/tools/index.js +2 -1
- package/dist/transport.d.ts +23 -8
- package/dist/transport.js +247 -127
- package/dist/types.d.ts +52 -3
- package/dist/vercel/command.d.ts +1 -1
- package/dist/vercel/command.js +15 -3
- package/dist/vercel/errors.d.ts +2 -2
- package/dist/vercel/errors.js +19 -2
- package/dist/vercel/filesystem.d.ts +21 -18
- package/dist/vercel/filesystem.js +95 -48
- package/dist/vercel/sandbox.d.ts +8 -8
- package/dist/vercel/sandbox.js +159 -64
- package/dist/vercel/snapshot.d.ts +3 -2
- package/dist/vercel/snapshot.js +9 -5
- package/package.json +46 -3
package/VERCEL.md
CHANGED
|
@@ -16,9 +16,9 @@ from withruntime.vercel import sandbox # was: from vercel import sandbox
|
|
|
16
16
|
from withruntime.vercel.sandbox import sync as sandbox # was: from vercel.sandbox import sync as sandbox
|
|
17
17
|
```
|
|
18
18
|
|
|
19
|
-
The mapping was written against `@vercel/sandbox` 3.5.
|
|
19
|
+
The mapping was written against `@vercel/sandbox` 3.5.1 and `vercel-sandbox`
|
|
20
20
|
0.7.0 on PyPI (the `vercel.sandbox` module of `vercel` 0.11.4), checked
|
|
21
|
-
|
|
21
|
+
30 September 2026.
|
|
22
22
|
|
|
23
23
|
## Keys
|
|
24
24
|
|
|
@@ -73,7 +73,7 @@ are ignored.
|
|
|
73
73
|
| `domain(port)`, `update({ ports })` | The public preview of that port; ports added or removed. |
|
|
74
74
|
| `stop()`, `delete()`, `extendTimeout(ms)` | `pause` (persistent) or `stop`; `stop`; `extend`. |
|
|
75
75
|
| `update({ timeout, networkPolicy, snapshotExpiration })` | `extend` (later only), network rules, retention. |
|
|
76
|
-
| `snapshot()`, `Snapshot.get`, `Snapshot.list`, `snapshot.delete()` | A
|
|
76
|
+
| `snapshot()`, `Snapshot.get`, `Snapshot.list`, `snapshot.delete()` | A verified disk-only capture, then the source stops; restored snapshots start fresh processes; `snapshots.get`, `list`, `delete`. |
|
|
77
77
|
| Error classes | `APIError` with a `response` whose status is Runtime's and `json` of `{ error: { code, message } }`; also `code`, `hint` and `requestId`. |
|
|
78
78
|
| Python: `create_sandbox`, `run_process`, `create_process`, `box.fs` | The same mapping; operations await or work as context managers, which stop and by default destroy the sandbox; readers iterate by line. |
|
|
79
79
|
|
|
@@ -98,6 +98,16 @@ Each of these throws `NotSupportedError` before anything happens. Its
|
|
|
98
98
|
| `Drive`, `SandboxUser`, `defineSandboxProxy` | Runtime volumes; `sudo`; `sandbox.withruntime.previews`. |
|
|
99
99
|
| Listing by time, prefix or cursor (JavaScript) | List them all and filter the result yourself. (Python applies a name prefix and newest-first order itself.) |
|
|
100
100
|
|
|
101
|
+
Explicit snapshots require the released native disk-capture capability; a server
|
|
102
|
+
that does not confirm disk-only capture is refused. If capture succeeds but the
|
|
103
|
+
source cannot finish stopping, the error retains `snapshotId` and
|
|
104
|
+
`sourceSandboxId` so the saved filesystem remains recoverable. JavaScript exposes
|
|
105
|
+
them in `error.json.error.details` for API errors and directly on other errors;
|
|
106
|
+
Python exposes them in `error.data` for API errors and directly on other errors.
|
|
107
|
+
`snapshot_source_stop_timeout` means the source is still stopping after its wait;
|
|
108
|
+
a failed stop request keeps its original error code. These contracts remain
|
|
109
|
+
partial; controlled package comparisons do not prove hosted restoration.
|
|
110
|
+
|
|
101
111
|
Some differences are not refusals:
|
|
102
112
|
|
|
103
113
|
- A persistent sandbox keeps its memory and processes as well as its files
|
|
@@ -0,0 +1,357 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schemaVersion": 1,
|
|
3
|
+
"checkedAt": "2026-09-29",
|
|
4
|
+
"providers": [
|
|
5
|
+
{
|
|
6
|
+
"id": "e2b",
|
|
7
|
+
"status": "partial",
|
|
8
|
+
"upstreams": [
|
|
9
|
+
{
|
|
10
|
+
"registry": "npm",
|
|
11
|
+
"name": "e2b",
|
|
12
|
+
"version": "2.51.0",
|
|
13
|
+
"artifacts": {
|
|
14
|
+
"2.51.0": "sha512-P+50lx1nOYpgCFyE1xuz6JVN/TqJivMUiH7v+RW0CUSfb4+NCu8IkC5KruT2sNPgp6aexddQQ77+OZKGpZZJ+Q=="
|
|
15
|
+
},
|
|
16
|
+
"latestReview": {
|
|
17
|
+
"version": "2.52.0",
|
|
18
|
+
"artifacts": {
|
|
19
|
+
"2.52.0": "sha512-TmUZlAvQq8BbguodpA+BBdawR/x5uILMQtHcLkdaLUqevsDjDdh46IYYU8ZRYKsQ4OhWr4xhsFIPSg1kgf+O0w=="
|
|
20
|
+
},
|
|
21
|
+
"reviewedAt": "2026-10-01",
|
|
22
|
+
"disposition": "held-for-sdk-qualification",
|
|
23
|
+
"evidence": {
|
|
24
|
+
"sourceUrls": [
|
|
25
|
+
"https://registry.npmjs.org/e2b/2.52.0",
|
|
26
|
+
"https://registry.npmjs.org/e2b/-/e2b-2.52.0.tgz"
|
|
27
|
+
],
|
|
28
|
+
"artifactSha256": {
|
|
29
|
+
"2.52.0": "facbc53fa42757d94aa2be3433d779c7ab6b0afc780d4821a12a6d6815848c8e"
|
|
30
|
+
},
|
|
31
|
+
"changes": [
|
|
32
|
+
"dist/index.d.ts/index.mjs: HTTP1.1/2 selection, E2B_HTTP_VERSION, retry502/503 and connection failures, fork integer count 1..20, Dockerignore matching/precedence and invalid-pattern behavior changed. package.json changes protobuf/chalk/openapi-fetch floors. Installed transport/retry/fork/filesystem consumers not qualified; supported 2.51.0 unchanged.",
|
|
33
|
+
"Source digest dist/index.d.ts: 304acc9c8bbec8aeb69296719eb34986f987256e758aa7e220b551b9a7dcbd30 -> fa2e6eb09b6c6d3489056ee948248812e8879a23b6865561e5152f243bf6ca40.",
|
|
34
|
+
"Source digest dist/index.mjs: b75feeedb6543fee003533270b0f07fc1a9eb40315dfc0c44510e2dd8854b896 -> 343a41249ea8d48fe0a70fc986066d3ef97b6da2b71267211d21f77036efafea.",
|
|
35
|
+
"Source digest package.json: a2c759c4681b91b824aea7919f4661e498ec0e0b68d6cc333f4967f7b2b63f7b -> c5b699f80831b621178c83ea477d096bc1167e0083b6ba7a51d17f564207255f."
|
|
36
|
+
]
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
"registry": "npm",
|
|
42
|
+
"name": "@e2b/code-interpreter",
|
|
43
|
+
"version": "2.8.0",
|
|
44
|
+
"artifacts": {
|
|
45
|
+
"2.8.0": "sha512-tWFi8IJYV3V6jOVfQ8V5PkzockrYP+ndWB/jKiJvRATTmNAy8+S/7S+iSh2Lb2Hrul869G2adRiN2xW8peJTig=="
|
|
46
|
+
}
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
"registry": "pypi",
|
|
50
|
+
"name": "e2b",
|
|
51
|
+
"version": "2.51.0",
|
|
52
|
+
"artifacts": {
|
|
53
|
+
"e2b-2.51.0-py3-none-any.whl": "sha256-951d0fd069f017e760b338a435bdb83589b4bfb9574fc5203a7f777e9cb994c2",
|
|
54
|
+
"e2b-2.51.0.tar.gz": "sha256-902ee861b30c8ec3e46e7f84db8c993f30695872c7b4490efaad1627ec6e08ba"
|
|
55
|
+
},
|
|
56
|
+
"latestReview": {
|
|
57
|
+
"version": "2.52.0",
|
|
58
|
+
"artifacts": {
|
|
59
|
+
"e2b-2.52.0-py3-none-any.whl": "sha256-6f4b5084b09986db43e99c7405bae6b14dc56984a69bbb1dc0687f1c71515cfb",
|
|
60
|
+
"e2b-2.52.0.tar.gz": "sha256-58c0042609513799341d4c1837e2581a4a5e73d3d62c9f1c57495c5e23eedee2"
|
|
61
|
+
},
|
|
62
|
+
"reviewedAt": "2026-10-01",
|
|
63
|
+
"disposition": "held-for-sdk-qualification",
|
|
64
|
+
"evidence": {
|
|
65
|
+
"sourceUrls": [
|
|
66
|
+
"https://pypi.org/pypi/e2b/2.52.0/json",
|
|
67
|
+
"https://files.pythonhosted.org/packages/53/71/1a01b7e4486b5962eaade7dba7026876a1b4569e49b464e82912d8801e38/e2b-2.52.0-py3-none-any.whl",
|
|
68
|
+
"https://files.pythonhosted.org/packages/3c/c4/560e7de54cece3573086f09d304e595729964aa18593b437125d9f8bd926/e2b-2.52.0.tar.gz"
|
|
69
|
+
],
|
|
70
|
+
"artifactSha256": {
|
|
71
|
+
"e2b-2.52.0-py3-none-any.whl": "6f4b5084b09986db43e99c7405bae6b14dc56984a69bbb1dc0687f1c71515cfb",
|
|
72
|
+
"e2b-2.52.0.tar.gz": "58c0042609513799341d4c1837e2581a4a5e73d3d62c9f1c57495c5e23eedee2"
|
|
73
|
+
},
|
|
74
|
+
"changes": [
|
|
75
|
+
"e2b/connection_config.py/retry.py: HTTP1.1/2 selection and E2B_HTTP_VERSION; retries 502/503 and eligible network failures, excluding unsafe resource-creating replay. e2b/api clients replace pool shards with bounded least-in-flight shared pools, defaults 100 streams / 200 connections.",
|
|
76
|
+
"Fork count validation1..20 and template/dockerignore/fileIgnorePatterns matching/precedence changed. Installed sync/async transport/cleanup/retry/fork/filesystem consumers not qualified; supported 2.51.0 unchanged.",
|
|
77
|
+
"Source digest e2b/api/__init__.py: 00b09a79f25d01594c4b1ec5f14d3d0cc3ccc319958a2e1ca34ba91cdbf114b3 -> 640233a615a3c68752a2f2cecb1af919aebfc5e895bd4f09003aee61da38c7c0.",
|
|
78
|
+
"Source digest e2b/connection_config.py: 284aa3e7cc319432ca9147ddb7d9ab8cd315cf35283da7699eebe877375758a4 -> c165948133a2f174b5a490afa9502301d038d8097f91203b2c2174f451accf83.",
|
|
79
|
+
"Source digest e2b/retry.py: aa54aa8873fd44027a9c3ff790594d4583d2f415c0d3bd858566d2f0e15fa71f -> 40b1d7ea0732a721d77b31483e54f9f190e444cb798c54fc141856f52685e208.",
|
|
80
|
+
"Source digest e2b/template/dockerignore.py: None -> cba4ff9d7efa5ae987c4c0114770c114b5aefe2c18847e55d2bd811b9a1a088c."
|
|
81
|
+
]
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
},
|
|
85
|
+
{
|
|
86
|
+
"registry": "pypi",
|
|
87
|
+
"name": "e2b-code-interpreter",
|
|
88
|
+
"version": "2.10.0",
|
|
89
|
+
"artifacts": {
|
|
90
|
+
"e2b_code_interpreter-2.10.0-py3-none-any.whl": "sha256-6ba776122086261875bc6033ef2dc42ac6b6e22cefdffdfd19d30e93bb09786f",
|
|
91
|
+
"e2b_code_interpreter-2.10.0.tar.gz": "sha256-57fb7f9b9ad99ebbdf407619786fdb84e31537c2fbc8358c394aa0f0cbc1af28"
|
|
92
|
+
},
|
|
93
|
+
"latestReview": {
|
|
94
|
+
"version": "2.10.1",
|
|
95
|
+
"artifacts": {
|
|
96
|
+
"e2b_code_interpreter-2.10.1-py3-none-any.whl": "sha256-f4c9732699ee4b1c289acedac8bff66fccecc6ab374bf0b4ef88d5ad063e333d",
|
|
97
|
+
"e2b_code_interpreter-2.10.1.tar.gz": "sha256-94e504667788c6cbb175e5deaf1f68e8df474b670343fe1d72e2496b49d5a666"
|
|
98
|
+
},
|
|
99
|
+
"reviewedAt": "2026-10-01",
|
|
100
|
+
"disposition": "held-for-sdk-qualification",
|
|
101
|
+
"evidence": {
|
|
102
|
+
"sourceUrls": [
|
|
103
|
+
"https://pypi.org/pypi/e2b-code-interpreter/2.10.1/json",
|
|
104
|
+
"https://files.pythonhosted.org/packages/27/1f/0f9a4c4d9669afd5389e91bd96099a8eb1d1a32f9c67871cc56c4a8556b7/e2b_code_interpreter-2.10.1-py3-none-any.whl",
|
|
105
|
+
"https://files.pythonhosted.org/packages/38/e6/b01e60524e7e4d2e8ce634b3be6d00fe09c606f3d24a448b4a5c087d3bda/e2b_code_interpreter-2.10.1.tar.gz"
|
|
106
|
+
],
|
|
107
|
+
"artifactSha256": {
|
|
108
|
+
"e2b_code_interpreter-2.10.1-py3-none-any.whl": "f4c9732699ee4b1c289acedac8bff66fccecc6ab374bf0b4ef88d5ad063e333d",
|
|
109
|
+
"e2b_code_interpreter-2.10.1.tar.gz": "94e504667788c6cbb175e5deaf1f68e8df474b670343fe1d72e2496b49d5a666"
|
|
110
|
+
},
|
|
111
|
+
"changes": [
|
|
112
|
+
"code_interpreter_{sync,async}.py: Jupyter get_transport argument changes from http2=False to http_version=\"1.1\". pyproject.toml and PKG-INFO raise e2b floor to 2.52.0,<3.0.0. Installed Jupyter cancellation/base SDK consumers not qualified; supported 2.10.0 unchanged.",
|
|
113
|
+
"Source digest e2b_code_interpreter/code_interpreter_sync.py: 298d832fe93e488300ac3174f2de590cc16d3563bdcc4ec31439d28265b66426 -> a88ff6a0df5163bceea545d077be090dbc78c96e48354e304677b02799eec17e.",
|
|
114
|
+
"Source digest pyproject.toml: 6c395fdf75ddc89acabb94fd0e419fc31317e6f3fa297894cbe7e766f090322c -> ef2b569a82f2e6edf722939ab27ca476a292886655c2af8f9e75eb9cae287941."
|
|
115
|
+
]
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
]
|
|
120
|
+
},
|
|
121
|
+
{
|
|
122
|
+
"id": "daytona",
|
|
123
|
+
"status": "partial",
|
|
124
|
+
"upstreams": [
|
|
125
|
+
{
|
|
126
|
+
"registry": "npm",
|
|
127
|
+
"name": "@daytona/sdk",
|
|
128
|
+
"version": "0.220.0",
|
|
129
|
+
"artifacts": {
|
|
130
|
+
"0.220.0": "sha512-PJio3vbDwRApzlsK6AGO7r4CHJcF9PI5DWuUW2yUnA2MVJSh/jotS0onKBv6boC5F+oboljTibUMxrwVPIrOlQ=="
|
|
131
|
+
}
|
|
132
|
+
},
|
|
133
|
+
{
|
|
134
|
+
"registry": "pypi",
|
|
135
|
+
"name": "daytona",
|
|
136
|
+
"version": "0.220.0",
|
|
137
|
+
"artifacts": {
|
|
138
|
+
"daytona-0.220.0-py3-none-any.whl": "sha256-5f71299eaf3a446e6569ada69919fc49997c1b2c587845057394aab886f113c8",
|
|
139
|
+
"daytona-0.220.0.tar.gz": "sha256-eda82eac9b3601e757b1dbe3ec2d966b46a9e3038b69ce44a0d90e01dac8417a"
|
|
140
|
+
}
|
|
141
|
+
},
|
|
142
|
+
{
|
|
143
|
+
"registry": "npm",
|
|
144
|
+
"name": "@daytona/api-client",
|
|
145
|
+
"version": "0.220.0",
|
|
146
|
+
"artifacts": {
|
|
147
|
+
"0.220.0": "sha512-XaMEtiQCaIHc3T7y3HUqx1A5eWSnd+FJvhpSHDwP3Snu9Nnhy4t+K2LHBWgJQn9dGtWXsdOsbB9K0BqpmFJtyA=="
|
|
148
|
+
}
|
|
149
|
+
},
|
|
150
|
+
{
|
|
151
|
+
"registry": "npm",
|
|
152
|
+
"name": "@daytona/toolbox-api-client",
|
|
153
|
+
"version": "0.220.0",
|
|
154
|
+
"artifacts": {
|
|
155
|
+
"0.220.0": "sha512-Kn94AOxhGQil0XygOOR26SaCkndE4dOtxYS0hLbqrTxcP3H1uq1HGFGSRkHFQNkaR8eL9QwFUPSMqd0Vr3A64A=="
|
|
156
|
+
}
|
|
157
|
+
},
|
|
158
|
+
{
|
|
159
|
+
"registry": "npm",
|
|
160
|
+
"name": "@daytona/analytics-api-client",
|
|
161
|
+
"version": "0.220.0",
|
|
162
|
+
"artifacts": {
|
|
163
|
+
"0.220.0": "sha512-3BGYILzjo2aFTJhLd6XBXlNEQBSo9Zr2Nj31OdX9o50fMRVUwVydF6ekIGkPGSLwskz6b6xxg5BSS+f9dbrxCQ=="
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
]
|
|
167
|
+
},
|
|
168
|
+
{
|
|
169
|
+
"id": "vercel",
|
|
170
|
+
"status": "partial",
|
|
171
|
+
"upstreams": [
|
|
172
|
+
{
|
|
173
|
+
"registry": "npm",
|
|
174
|
+
"name": "@vercel/sandbox",
|
|
175
|
+
"version": "3.5.1",
|
|
176
|
+
"artifacts": {
|
|
177
|
+
"3.5.1": "sha512-VHItQtcv4FkSXET29b088p87MNPAIhRscF3ifrup2KkC8ix4hy4NpgCO9F3GI4yOsztgGtuV7bDx29Iufun2hQ=="
|
|
178
|
+
}
|
|
179
|
+
},
|
|
180
|
+
{
|
|
181
|
+
"registry": "pypi",
|
|
182
|
+
"name": "vercel",
|
|
183
|
+
"version": "0.11.4",
|
|
184
|
+
"artifacts": {
|
|
185
|
+
"vercel-0.11.4-py3-none-any.whl": "sha256-3ba3a0de2276a2b3daf590263082f6a82850dc77b35cf68f86a1e5bc9e83b6f1",
|
|
186
|
+
"vercel-0.11.4.tar.gz": "sha256-80038906615bf4182787af8354bce71b57d9fd5471a35ebca457d34ab5f50b2e"
|
|
187
|
+
}
|
|
188
|
+
},
|
|
189
|
+
{
|
|
190
|
+
"registry": "pypi",
|
|
191
|
+
"name": "vercel-sandbox",
|
|
192
|
+
"version": "0.7.0",
|
|
193
|
+
"artifacts": {
|
|
194
|
+
"vercel_sandbox-0.7.0-py3-none-any.whl": "sha256-f7eb897a1a5092fe8c38319ce803033b1a9ced8f414564a43a668432f91ffcd9",
|
|
195
|
+
"vercel_sandbox-0.7.0.tar.gz": "sha256-07d703790d0141dc75e0962baf35d666a6961bc1de913749137267a2550c81e2"
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
]
|
|
199
|
+
},
|
|
200
|
+
{
|
|
201
|
+
"id": "blaxel",
|
|
202
|
+
"status": "partial",
|
|
203
|
+
"upstreams": [
|
|
204
|
+
{
|
|
205
|
+
"registry": "npm",
|
|
206
|
+
"name": "@blaxel/core",
|
|
207
|
+
"version": "0.3.25",
|
|
208
|
+
"artifacts": {
|
|
209
|
+
"0.3.25": "sha512-K6aGUyIpgrPnkpwMOI/U/gbZwveOMu1Am04pkawZQjkp7NUa/roG0HC6NJPBp3AVVJY3CQtkGSWpAJ2DV4ZKpw=="
|
|
210
|
+
}
|
|
211
|
+
},
|
|
212
|
+
{
|
|
213
|
+
"registry": "pypi",
|
|
214
|
+
"name": "blaxel",
|
|
215
|
+
"version": "0.4.13",
|
|
216
|
+
"artifacts": {
|
|
217
|
+
"blaxel-0.4.13-py3-none-any.whl": "sha256-b8817718ca63a2b31a5026f98c7191d5ed8f2f4c1aafc2d4aa57491a560a2146",
|
|
218
|
+
"blaxel-0.4.13.tar.gz": "sha256-a036256792e85238724b8bce38fb7c0b4f661fe4c3ac576258a8be1736ac8483"
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
]
|
|
222
|
+
},
|
|
223
|
+
{
|
|
224
|
+
"id": "runloop",
|
|
225
|
+
"status": "partial",
|
|
226
|
+
"upstreams": [
|
|
227
|
+
{
|
|
228
|
+
"registry": "npm",
|
|
229
|
+
"name": "@runloop/api-client",
|
|
230
|
+
"version": "1.32.0",
|
|
231
|
+
"artifacts": {
|
|
232
|
+
"1.32.0": "sha512-aCNKjlGzLVEAFl8WA42LmgiYkdIkaocOlFK/cMGppijsM0AGS+1hkw/RxroQxyHlkIhjyRaqLv7m5ZNMGhks7Q=="
|
|
233
|
+
}
|
|
234
|
+
},
|
|
235
|
+
{
|
|
236
|
+
"registry": "pypi",
|
|
237
|
+
"name": "runloop-api-client",
|
|
238
|
+
"version": "1.32.0",
|
|
239
|
+
"artifacts": {
|
|
240
|
+
"runloop_api_client-1.32.0-py3-none-any.whl": "sha256-23c36910de7423f73aef91d4a963abea80a6b2f5b2df5bb8e439d788d5486cc7",
|
|
241
|
+
"runloop_api_client-1.32.0.tar.gz": "sha256-1f2077fb5a99b5ef30dbc1d96d47c1ca1d3f77895b9e186d985e47365fe85634"
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
]
|
|
245
|
+
},
|
|
246
|
+
{
|
|
247
|
+
"id": "codesandbox",
|
|
248
|
+
"status": "partial",
|
|
249
|
+
"upstreams": [
|
|
250
|
+
{
|
|
251
|
+
"registry": "npm",
|
|
252
|
+
"name": "@codesandbox/sdk",
|
|
253
|
+
"version": "2.4.2",
|
|
254
|
+
"artifacts": {
|
|
255
|
+
"2.4.2": "sha512-pwz/+xNPLiCEvIYLxk2VJwiAFuy28V3J6FuO+xIB5U3AV/EylHlm77Lsi/WNYeXoSljIlaLLU7IemAjw3ojNfg=="
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
]
|
|
259
|
+
},
|
|
260
|
+
{
|
|
261
|
+
"id": "sprites",
|
|
262
|
+
"status": "partial",
|
|
263
|
+
"upstreams": [
|
|
264
|
+
{
|
|
265
|
+
"registry": "npm",
|
|
266
|
+
"name": "@fly/sprites",
|
|
267
|
+
"version": "0.2.3",
|
|
268
|
+
"artifacts": {
|
|
269
|
+
"0.2.3": "sha512-LB3xmHpHLdVECTQej+Vyi/aFFTc/Otf8bZ8GwVe/Hhlx4kIFS0K+9O5B8ru8Llg+cEwvYmzyeV69vNZPpCt0fw=="
|
|
270
|
+
}
|
|
271
|
+
},
|
|
272
|
+
{
|
|
273
|
+
"registry": "pypi",
|
|
274
|
+
"name": "sprites-py",
|
|
275
|
+
"version": "0.7.1",
|
|
276
|
+
"artifacts": {
|
|
277
|
+
"sprites_py-0.7.1-py3-none-any.whl": "sha256-23774f8111c9a4fbb7007f8e305677734eb7616bebb6c668c394788399ff38a8",
|
|
278
|
+
"sprites_py-0.7.1.tar.gz": "sha256-c45596f3994376eb25dd7c4f988b3a6893dd8218502bacd7eedf2b20888d8456"
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
]
|
|
282
|
+
},
|
|
283
|
+
{
|
|
284
|
+
"id": "freestyle",
|
|
285
|
+
"status": "partial",
|
|
286
|
+
"upstreams": [
|
|
287
|
+
{
|
|
288
|
+
"registry": "npm",
|
|
289
|
+
"name": "freestyle",
|
|
290
|
+
"version": "0.2.16",
|
|
291
|
+
"artifacts": {
|
|
292
|
+
"0.2.16": "sha512-8pC7lh/R2PDanbs9Noc1Q7YlPl8Be8hHaQA/rpwFmELrcLTUAuCuxpoZ1Xm+7fuxqhJqJzO83bTTeLcSUoJ9SA=="
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
]
|
|
296
|
+
},
|
|
297
|
+
{
|
|
298
|
+
"id": "prime",
|
|
299
|
+
"status": "partial",
|
|
300
|
+
"upstreams": [
|
|
301
|
+
{
|
|
302
|
+
"registry": "pypi",
|
|
303
|
+
"name": "prime-sandboxes",
|
|
304
|
+
"version": "0.4.1",
|
|
305
|
+
"artifacts": {
|
|
306
|
+
"prime_sandboxes-0.4.1-py3-none-any.whl": "sha256-1a1bb96afacc66d690815be82c0b7af180ea141421b7d180b4a0adbada4f38f0",
|
|
307
|
+
"prime_sandboxes-0.4.1.tar.gz": "sha256-53f7577dc9070e3b8e30db360f9e3cce3bcc35f8765b26f24f64dbc3c7763b06"
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
]
|
|
311
|
+
},
|
|
312
|
+
{
|
|
313
|
+
"id": "modal",
|
|
314
|
+
"status": "partial",
|
|
315
|
+
"upstreams": [
|
|
316
|
+
{
|
|
317
|
+
"registry": "npm",
|
|
318
|
+
"name": "modal",
|
|
319
|
+
"version": "0.11.0",
|
|
320
|
+
"artifacts": {
|
|
321
|
+
"0.11.0": "sha512-Kvy2nejPkice2FI82p5e8TJrFDy0BaSYZjJVmvnTnu51bOH9Ok7IRtp8NavBQqMuXhbpbj6gRULwxsjNkweF6A=="
|
|
322
|
+
}
|
|
323
|
+
},
|
|
324
|
+
{
|
|
325
|
+
"registry": "pypi",
|
|
326
|
+
"name": "modal",
|
|
327
|
+
"version": "1.6.0",
|
|
328
|
+
"artifacts": {
|
|
329
|
+
"modal-1.6.0-py3-none-any.whl": "sha256-2f5981ba656570ad96379d29f0ddff876880708c84966024ce130e9e1794fa68",
|
|
330
|
+
"modal-1.6.0.tar.gz": "sha256-c5dd551b5e0a283f3c764476c0a4ebe5bdef1e4a69432fa27e1b1ad8ca5e0817"
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
]
|
|
334
|
+
},
|
|
335
|
+
{
|
|
336
|
+
"id": "cloudflare",
|
|
337
|
+
"status": "partial",
|
|
338
|
+
"upstreams": [
|
|
339
|
+
{
|
|
340
|
+
"registry": "npm",
|
|
341
|
+
"name": "@cloudflare/sandbox",
|
|
342
|
+
"version": "0.12.10",
|
|
343
|
+
"artifacts": {
|
|
344
|
+
"0.12.10": "sha512-245s6xEdR1v0Jti0YYd8ORWcTG/f/ksjJfpubvnbky0KxFC/ZDOpbpNKdtyiRBYZqmJGtEncYW7Cwge47tDrpg=="
|
|
345
|
+
},
|
|
346
|
+
"unsupported": {
|
|
347
|
+
"version": "1.0.0",
|
|
348
|
+
"artifacts": {
|
|
349
|
+
"1.0.0": "sha512-+TZVuCey6OBDTvPLWisq4Ie7/R5Zy3zFyYOFCNRpdEIyQsKq3xwzpctonE43DfZ+wYZvvu6QYpR138PayDjF+A=="
|
|
350
|
+
},
|
|
351
|
+
"reason": "1.0 removes getSandbox, the Sandbox class, exec, processes, sessions and preview proxying and keeps only Files, S3Mount and DirectoryBackup for the caller's own Durable Object; withruntime/cloudflare implements the 0.x API"
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
]
|
|
355
|
+
}
|
|
356
|
+
]
|
|
357
|
+
}
|
package/dist/ai-harness/index.js
CHANGED
|
@@ -19,6 +19,7 @@
|
|
|
19
19
|
* token. The key comes from RUNTIME_API_KEY or this machine's `runtime login`.
|
|
20
20
|
* Needs `@ai-sdk/harness` 1.x beside this package. */
|
|
21
21
|
import { HarnessCapabilityUnsupportedError, HarnessSandboxAuthenticationError, } from "@ai-sdk/harness";
|
|
22
|
+
import { AI_HARNESS_COMMAND_TIMEOUT_MS } from "../api-defaults.js";
|
|
22
23
|
import { Runtime } from "../client.js";
|
|
23
24
|
import { AuthenticationError, NotFoundError, PermissionDeniedError, RuntimeError, } from "../errors.js";
|
|
24
25
|
export const PROVIDER_ID = "runtime-sandbox";
|
|
@@ -27,7 +28,6 @@ export const PREVIEW_TOKEN_HEADER = "x-runtime-preview-token";
|
|
|
27
28
|
const TOKEN_QUERY = "runtime_preview_token";
|
|
28
29
|
const SESSION_NAME_PREFIX = "ai-harness-";
|
|
29
30
|
const MAX_COMMAND_MS = 86_400_000;
|
|
30
|
-
const DEFAULT_COMMAND_MS = 3_600_000;
|
|
31
31
|
/** Exit codes for a command that ended without one, as coreutils `timeout` and SIGKILL give. */
|
|
32
32
|
const TIMED_OUT_EXIT = 124;
|
|
33
33
|
const KILLED_EXIT = 137;
|
|
@@ -161,7 +161,7 @@ export class RuntimeSandboxSession {
|
|
|
161
161
|
? {}
|
|
162
162
|
: { cwd: this.#path(options.workingDirectory) }),
|
|
163
163
|
...(Object.keys(env).length ? { env } : {}),
|
|
164
|
-
timeoutMs: Math.min(MAX_COMMAND_MS, options.timeoutMs ?? this.settings.commandTimeoutMs ??
|
|
164
|
+
timeoutMs: Math.min(MAX_COMMAND_MS, options.timeoutMs ?? this.settings.commandTimeoutMs ?? AI_HARNESS_COMMAND_TIMEOUT_MS),
|
|
165
165
|
};
|
|
166
166
|
}
|
|
167
167
|
/** Runs `command` under `bash -c` and returns once it exits, with all of
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/** A server-side wait for a state (`GET /v1/sandboxes/{id}?waitFor=`). */
|
|
2
|
+
export declare const WAIT_FOR_TIMEOUT_SECONDS = 60;
|
|
3
|
+
/** A streamed exec's command limit when none is given: the API's longest. */
|
|
4
|
+
export declare const STREAMED_EXEC_TIMEOUT_MS = 86400000;
|
|
5
|
+
/** The lease keepAlive keeps ahead of now, and so the most it extends by. */
|
|
6
|
+
export declare const KEEP_ALIVE_MARGIN_SECONDS = 600;
|
|
7
|
+
/** A webhook watch runs until stopped. */
|
|
8
|
+
export declare const WEBHOOK_WATCH_TIMEOUT_MS = 0;
|
|
9
|
+
/** A job run's limit, and the time added to it for its sandbox to start. */
|
|
10
|
+
export declare const JOB_TIMEOUT_SECONDS = 1800;
|
|
11
|
+
export declare const JOB_START_SECONDS = 60;
|
|
12
|
+
/** A command the framework-free tools run without a timeout of its own. */
|
|
13
|
+
export declare const TOOL_EXEC_TIMEOUT_SECONDS = 300;
|
|
14
|
+
/** A command the AI SDK harness runs without a timeout of its own. */
|
|
15
|
+
export declare const AI_HARNESS_COMMAND_TIMEOUT_MS = 3600000;
|
|
16
|
+
/** A command the OpenAI Agents sandbox runs without a timeout of its own. */
|
|
17
|
+
export declare const OPENAI_AGENTS_EXEC_TIMEOUT_MS = 3600000;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/* Every value this SDK sends the API for a bounded time field when the caller
|
|
2
|
+
* names none, in one place. packages/cloud/tests/sdk-defaults.test.ts holds
|
|
3
|
+
* each inside the range the API's registry gives that field, and the same
|
|
4
|
+
* names in the Python, Go, Java and Ruby SDKs to theirs. The suffix is the
|
|
5
|
+
* unit; a new default goes here, under a name that test maps to its field. */
|
|
6
|
+
/** A server-side wait for a state (`GET /v1/sandboxes/{id}?waitFor=`). */
|
|
7
|
+
export const WAIT_FOR_TIMEOUT_SECONDS = 60;
|
|
8
|
+
/** A streamed exec's command limit when none is given: the API's longest. */
|
|
9
|
+
export const STREAMED_EXEC_TIMEOUT_MS = 86_400_000;
|
|
10
|
+
/** The lease keepAlive keeps ahead of now, and so the most it extends by. */
|
|
11
|
+
export const KEEP_ALIVE_MARGIN_SECONDS = 600;
|
|
12
|
+
/** A webhook watch runs until stopped. */
|
|
13
|
+
export const WEBHOOK_WATCH_TIMEOUT_MS = 0;
|
|
14
|
+
/** A job run's limit, and the time added to it for its sandbox to start. */
|
|
15
|
+
export const JOB_TIMEOUT_SECONDS = 1800;
|
|
16
|
+
export const JOB_START_SECONDS = 60;
|
|
17
|
+
/** A command the framework-free tools run without a timeout of its own. */
|
|
18
|
+
export const TOOL_EXEC_TIMEOUT_SECONDS = 300;
|
|
19
|
+
/** A command the AI SDK harness runs without a timeout of its own. */
|
|
20
|
+
export const AI_HARNESS_COMMAND_TIMEOUT_MS = 3_600_000;
|
|
21
|
+
/** A command the OpenAI Agents sandbox runs without a timeout of its own. */
|
|
22
|
+
export const OPENAI_AGENTS_EXEC_TIMEOUT_MS = 3_600_000;
|
package/dist/blaxel/errors.js
CHANGED
|
@@ -95,7 +95,7 @@ const BLAXEL_HINTS = {
|
|
|
95
95
|
sandbox_paused: "Call sandbox.unarchive(), then try again.",
|
|
96
96
|
not_running: "The sandbox is not running: call sandbox.unarchive() if it was archived, or make a new one with SandboxInstance.create if it was deleted.",
|
|
97
97
|
trial_busy: "The trial's sandboxes are all in use: delete one you no longer need (sandbox.delete()) or archive it (sandbox.archive()), then try again. Moving to paid credit is the account owner's decision.",
|
|
98
|
-
public_preview_not_allowed: "On the trial, share the port privately: sandbox.previews.create({ metadata: { name }, spec: { port, public: false } }) and a token from preview.tokens.create(expiresAt). A public preview needs a paid sandbox, which is the account owner's decision.",
|
|
98
|
+
public_preview_not_allowed: "On the trial, share the port privately: sandbox.previews.create({ metadata: { name }, spec: { port, public: false } }) and a token from preview.tokens.create(expiresAt) on a server supporting absolute preview deadlines. A public preview needs a paid sandbox, which is the account owner's decision.",
|
|
99
99
|
busy: AGAIN,
|
|
100
100
|
guest_busy: AGAIN,
|
|
101
101
|
rate_limited: AGAIN,
|
package/dist/blaxel/lookup.d.ts
CHANGED
|
@@ -32,6 +32,7 @@ export declare function findSandbox(client: Runtime, name: string): Promise<Runt
|
|
|
32
32
|
export declare function findByExternalId(client: Runtime, externalId: string): Promise<RuntimeSandbox>;
|
|
33
33
|
/** Runs a create or fork that names a sandbox. When the name is still held
|
|
34
34
|
* by a sandbox that is stopping (deleted a moment ago, by this client or
|
|
35
|
-
* another), waits for it to stop, up to 30 seconds, and runs it once more
|
|
36
|
-
*
|
|
35
|
+
* another), waits for it to stop, up to 30 seconds, and runs it once more.
|
|
36
|
+
* This reconciles Runtime's stopping-name conflicts. Blaxel 0.3.25 delegates
|
|
37
|
+
* createIfNotExists reconciliation to its control plane without client polling. */
|
|
37
38
|
export declare function whenNameFree<T>(client: Runtime, work: () => Promise<T>): Promise<T>;
|
package/dist/blaxel/lookup.js
CHANGED
|
@@ -54,8 +54,9 @@ export async function findByExternalId(client, externalId) {
|
|
|
54
54
|
}
|
|
55
55
|
/** Runs a create or fork that names a sandbox. When the name is still held
|
|
56
56
|
* by a sandbox that is stopping (deleted a moment ago, by this client or
|
|
57
|
-
* another), waits for it to stop, up to 30 seconds, and runs it once more
|
|
58
|
-
*
|
|
57
|
+
* another), waits for it to stop, up to 30 seconds, and runs it once more.
|
|
58
|
+
* This reconciles Runtime's stopping-name conflicts. Blaxel 0.3.25 delegates
|
|
59
|
+
* createIfNotExists reconciliation to its control plane without client polling. */
|
|
59
60
|
export async function whenNameFree(client, work) {
|
|
60
61
|
try {
|
|
61
62
|
return await work();
|
|
@@ -28,7 +28,7 @@ export type PaginatedList<T, TQuery extends CursorPaginationQuery = CursorPagina
|
|
|
28
28
|
/** Blaxel's own helper: the items of a list answer in any of its shapes. */
|
|
29
29
|
export declare function unwrapListData<T>(response: ListResponse<T>): T[];
|
|
30
30
|
/** Blaxel's own helper, for a list fetched by `fetchPage`. */
|
|
31
|
-
export declare function createPaginatedList<TRaw, TItem, TQuery extends CursorPaginationQuery>({ response, fetchPage, mapItem, query, }: {
|
|
31
|
+
export declare function createPaginatedList<TRaw, TItem, TQuery extends CursorPaginationQuery>({ response, fetchPage, mapItem, query, seenCursors, }: {
|
|
32
32
|
response: ListResponse<TRaw>;
|
|
33
33
|
fetchPage: (query?: TQuery) => Promise<ListResponse<TRaw>>;
|
|
34
34
|
mapItem: (item: TRaw) => TItem | Promise<TItem>;
|
|
@@ -36,4 +36,4 @@ export declare function createPaginatedList<TRaw, TItem, TQuery extends CursorPa
|
|
|
36
36
|
seenCursors?: Set<string>;
|
|
37
37
|
}): Promise<PaginatedList<TItem, TQuery>>;
|
|
38
38
|
/** A Runtime page, each item mapped, as Blaxel's paginated list. */
|
|
39
|
-
export declare function paginate<TRaw, TItem>(page: Page<TRaw>, map: (item: TRaw) => TItem): PaginatedList<TItem>;
|
|
39
|
+
export declare function paginate<TRaw, TItem>(page: Page<TRaw>, map: (item: TRaw) => TItem, seenCursors?: Set<string>): PaginatedList<TItem>;
|
|
@@ -8,30 +8,58 @@ export function unwrapListData(response) {
|
|
|
8
8
|
return response.data ?? [];
|
|
9
9
|
}
|
|
10
10
|
/** Blaxel's own helper, for a list fetched by `fetchPage`. */
|
|
11
|
-
export async function createPaginatedList({ response, fetchPage, mapItem, query, }) {
|
|
12
|
-
const meta = !response || Array.isArray(response)
|
|
11
|
+
export async function createPaginatedList({ response, fetchPage, mapItem, query, seenCursors, }) {
|
|
12
|
+
const meta = !response || Array.isArray(response)
|
|
13
|
+
? { hasMore: false }
|
|
14
|
+
: (response.meta ?? { hasMore: false });
|
|
13
15
|
const data = await Promise.all(unwrapListData(response).map(mapItem));
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
16
|
+
const cursors = new Set(seenCursors);
|
|
17
|
+
if (query?.cursor)
|
|
18
|
+
cursors.add(query.cursor);
|
|
19
|
+
return build(data, meta.nextCursor || undefined, async (cursor) => {
|
|
20
|
+
if (cursors.has(cursor))
|
|
21
|
+
throw new Error("Pagination returned a repeated cursor");
|
|
22
|
+
const nextQuery = { ...(query ?? {}), cursor };
|
|
23
|
+
const nextSeenCursors = new Set(cursors);
|
|
24
|
+
nextSeenCursors.add(cursor);
|
|
25
|
+
return createPaginatedList({
|
|
26
|
+
response: await fetchPage(nextQuery),
|
|
27
|
+
fetchPage,
|
|
28
|
+
mapItem,
|
|
29
|
+
query: nextQuery,
|
|
30
|
+
seenCursors: nextSeenCursors,
|
|
31
|
+
});
|
|
32
|
+
}, meta);
|
|
20
33
|
}
|
|
21
34
|
/** A Runtime page, each item mapped, as Blaxel's paginated list. */
|
|
22
|
-
export function paginate(page, map) {
|
|
23
|
-
return build(page.data.map(map), page.nextCursor ?? undefined, async () => {
|
|
24
|
-
|
|
25
|
-
|
|
35
|
+
export function paginate(page, map, seenCursors = new Set()) {
|
|
36
|
+
return build(page.data.map(map), page.nextCursor ?? undefined, async (cursor) => {
|
|
37
|
+
if (cursor && seenCursors.has(cursor))
|
|
38
|
+
throw new Error("Pagination returned a repeated cursor");
|
|
39
|
+
const nextSeenCursors = new Set(seenCursors);
|
|
40
|
+
if (cursor)
|
|
41
|
+
nextSeenCursors.add(cursor);
|
|
42
|
+
const next = await guard(() => page.next(cursor));
|
|
43
|
+
return next ? paginate(next, map, nextSeenCursors) : null;
|
|
26
44
|
});
|
|
27
45
|
}
|
|
28
|
-
function build(data, nextCursor, more
|
|
46
|
+
function build(data, nextCursor, more, meta = {
|
|
47
|
+
hasMore: nextCursor !== undefined,
|
|
48
|
+
...(nextCursor ? { nextCursor } : {}),
|
|
49
|
+
}) {
|
|
29
50
|
const list = {
|
|
30
51
|
data,
|
|
31
|
-
meta
|
|
32
|
-
hasMore
|
|
33
|
-
|
|
34
|
-
|
|
52
|
+
meta,
|
|
53
|
+
get hasMore() {
|
|
54
|
+
return Boolean(list.nextCursor);
|
|
55
|
+
},
|
|
56
|
+
get nextCursor() {
|
|
57
|
+
return meta.nextCursor || undefined;
|
|
58
|
+
},
|
|
59
|
+
nextPage: async () => {
|
|
60
|
+
const cursor = list.nextCursor;
|
|
61
|
+
return cursor ? more(cursor) : null;
|
|
62
|
+
},
|
|
35
63
|
async autoPagingEach(onItem) {
|
|
36
64
|
for await (const item of list)
|
|
37
65
|
if ((await onItem(item)) === false)
|
package/dist/blaxel/preview.d.ts
CHANGED
|
@@ -67,7 +67,8 @@ export declare class SandboxPreviewTokens {
|
|
|
67
67
|
constructor(preview: SandboxPreview, ctx: PreviewContext);
|
|
68
68
|
get previewName(): string;
|
|
69
69
|
get resourceName(): string;
|
|
70
|
-
/** A token
|
|
70
|
+
/** A token bounded by `expiresAt`; native signing floors milliseconds and
|
|
71
|
+
* caps it to the caller's session. Older servers refuse without a TTL fallback. */
|
|
71
72
|
create(expiresAt: Date): Promise<SandboxPreviewToken>;
|
|
72
73
|
list(): Promise<never>;
|
|
73
74
|
/** Revokes the preview's tokens. Runtime cannot revoke one token alone, so
|
|
@@ -98,7 +99,7 @@ export declare class SandboxPreviews {
|
|
|
98
99
|
/** The named preview, or a new one when there is none. */
|
|
99
100
|
createIfNotExists(preview: Preview, force?: boolean): Promise<SandboxPreview>;
|
|
100
101
|
get(previewName: string): Promise<SandboxPreview>;
|
|
101
|
-
/** Stops sharing the port; open connections
|
|
102
|
+
/** Stops sharing the port; its open connections are closed before this returns. */
|
|
102
103
|
delete(previewName: string): Promise<Preview>;
|
|
103
104
|
}
|
|
104
105
|
/** A private preview of `port` with a token that lasts a while, for
|