@lunora/container 1.0.0-alpha.8 → 1.0.0-alpha.80
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 +24 -5
- package/dist/bridge.d.mts +43 -33
- package/dist/bridge.d.ts +43 -33
- package/dist/bridge.mjs +1 -79
- package/dist/do/index.d.mts +353 -91
- package/dist/do/index.d.ts +353 -91
- package/dist/do/index.mjs +1 -328
- package/dist/index.d.mts +584 -153
- package/dist/index.d.ts +584 -153
- package/dist/index.mjs +1 -2
- package/dist/otel.d.mts +217 -0
- package/dist/otel.d.ts +217 -0
- package/dist/otel.mjs +1 -0
- package/dist/packem_shared/CONTAINER_EXEC_PATH-7Hcd6-zs.mjs +1 -0
- package/dist/packem_shared/CUSTOM_INSTANCE_MIN_MEMORY_MIB_PER_VCPU-D8Hy9Rxv.mjs +1 -0
- package/dist/packem_shared/ContainerProxy-CfXjS6ZI.mjs +27 -0
- package/dist/packem_shared/DURABLE_OBJECT_POLICY_FORBIDDEN_KEYS-gYi8RBUO.mjs +1 -0
- package/dist/packem_shared/LunoraSandboxContainer-DPnhJUu1.mjs +1 -0
- package/dist/packem_shared/abort-deadline-jwbW9Ala.mjs +1 -0
- package/dist/packem_shared/createContainerContext-p6QxWjsm.mjs +1 -0
- package/dist/packem_shared/exec-BYLW70sR.mjs +1 -0
- package/dist/packem_shared/jurisdiction-DtE9s70w.mjs +1 -0
- package/dist/packem_shared/jurisdiction.d-BwpauCoI.d.mts +471 -0
- package/dist/packem_shared/jurisdiction.d-BwpauCoI.d.ts +471 -0
- package/dist/packem_shared/sampling-D21rpu_s.mjs +1 -0
- package/dist/packem_shared/sandbox-types.d-DXlHnsEg.d.mts +110 -0
- package/dist/packem_shared/sandbox-types.d-DXlHnsEg.d.ts +110 -0
- package/dist/sandbox/index.d.mts +66 -0
- package/dist/sandbox/index.d.ts +66 -0
- package/dist/sandbox/index.mjs +1 -0
- package/package.json +12 -2
- package/dist/packem_shared/ContainerProxy-DWqUX_re.mjs +0 -1474
- package/dist/packem_shared/containerBindingName-D5KTrblH.mjs +0 -218
- package/dist/packem_shared/createContainerContext-Cibbh7AE.mjs +0 -228
- package/dist/packem_shared/types.d-BlNwNY44.d.mts +0 -250
- package/dist/packem_shared/types.d-BlNwNY44.d.ts +0 -250
package/dist/index.d.mts
CHANGED
|
@@ -1,17 +1,131 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export type { B as BuildImageSource,
|
|
3
|
-
|
|
1
|
+
import { a as ContainerSpawnOptions, b as ContainerSnapshot, c as ContainerProcess, d as ContainerRuntimeInstanceType, e as ContainerSpawnRequest, S as SpawnResult, D as DurableObjectJurisdiction, f as DefaultScheduledContainerConfig, g as DurableObjectScheduledContainerConfig, C as ContainerDefinition, h as ContainerImageSource, N as NormalizedContainerImage } from "./packem_shared/jurisdiction.d-BwpauCoI.mjs";
|
|
2
|
+
export type { B as BuildImageSource, i as ContainerBackupStorage, j as ContainerConfig, k as ContainerConfigBase, l as ContainerInstanceType, m as ContainerNamedImageSource, n as ContainerReadinessCheck, o as ContainerRollout, p as CustomContainerInstanceType, q as NamedContainerInstanceType, R as RegistryImageSource } from "./packem_shared/jurisdiction.d-BwpauCoI.mjs";
|
|
3
|
+
import { b as ContainerBackupOptions, C as ContainerFileOptions, c as ContainerMountRequest, a as ContainerFileContent, d as ContainerSandboxControls } from "./packem_shared/sandbox-types.d-DXlHnsEg.mjs";
|
|
4
|
+
export type { e as ContainerFiles, f as ContainerMountCredentials } from "./packem_shared/sandbox-types.d-DXlHnsEg.mjs";
|
|
5
|
+
import { DirectoryBackupRecord, S3MountInspection, SandboxDirectoryEntry, SandboxFileStat } from '@cloudflare/sandbox';
|
|
6
|
+
export type { DirectoryBackupRecord, S3MountInspection, SandboxDirectoryEntry, SandboxFileStat } from '@cloudflare/sandbox';
|
|
7
|
+
/**
|
|
8
|
+
* Per-call options for `ContainerHandle.exec`.
|
|
9
|
+
*/
|
|
10
|
+
interface ContainerExecOptions {
|
|
11
|
+
/** Arguments passed to `command`, unshelled — the container must not concatenate them into a shell string. */
|
|
12
|
+
args?: ReadonlyArray<string>;
|
|
13
|
+
/** Working directory for the command, relative to the container's own root. */
|
|
14
|
+
cwd?: string;
|
|
15
|
+
/** Extra environment for this command only, merged over the container's env. */
|
|
16
|
+
env?: Readonly<Record<string, string>>;
|
|
17
|
+
/**
|
|
18
|
+
* Cap on the response body, in bytes. The whole `{code,stdout,stderr}`
|
|
19
|
+
* document has to be held in memory to be parsed, and a build box or job
|
|
20
|
+
* runner routinely writes tens of megabytes — a single unbounded `exec`
|
|
21
|
+
* that returns more than the isolate's memory limit kills the isolate and
|
|
22
|
+
* every other in-flight request sharing it, not just this call. So a
|
|
23
|
+
* runner that overruns the cap fails the call loudly rather than taking
|
|
24
|
+
* the shard down with it; raise this (or have the runner cap its own
|
|
25
|
+
* output) when a command legitimately produces more.
|
|
26
|
+
*
|
|
27
|
+
* Default {@link DEFAULT_EXEC_MAX_OUTPUT_BYTES} (1MB).
|
|
28
|
+
*/
|
|
29
|
+
maxOutputBytes?: number;
|
|
30
|
+
/**
|
|
31
|
+
* Abort the call. Composed with {@link ContainerExecOptions.timeoutMs} when
|
|
32
|
+
* both are given — whichever fires first wins.
|
|
33
|
+
*/
|
|
34
|
+
signal?: AbortSignal;
|
|
35
|
+
/**
|
|
36
|
+
* Give up after this many ms. Covers the whole call — the request *and*
|
|
37
|
+
* reading the response body, since `fetch` resolves on headers and a
|
|
38
|
+
* runner that answers `200` and then stalls mid-body would otherwise sit
|
|
39
|
+
* past the deadline. Sent to the container as well, so a well-behaved
|
|
40
|
+
* runner can kill the process rather than leak it when the caller walks
|
|
41
|
+
* away.
|
|
42
|
+
*/
|
|
43
|
+
timeoutMs?: number;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* The outcome of a `ContainerHandle.exec` call.
|
|
47
|
+
*
|
|
48
|
+
* A non-zero `code` is **not** an error: a command that ran and failed is a
|
|
49
|
+
* result, and the caller decides what to do with it. Only a failure to *run*
|
|
50
|
+
* the command — transport, a non-2xx from the runner, an unparseable body —
|
|
51
|
+
* throws.
|
|
52
|
+
*/
|
|
53
|
+
interface ContainerExecResult {
|
|
54
|
+
/** Process exit code. Non-zero means the command ran and failed. */
|
|
55
|
+
code: number;
|
|
56
|
+
/** Everything the command wrote to stderr. */
|
|
57
|
+
stderr: string;
|
|
58
|
+
/** Everything the command wrote to stdout. */
|
|
59
|
+
stdout: string;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* The route `ContainerHandle.exec` POSTs to. Namespaced under
|
|
63
|
+
* `/__lunora/` so it cannot collide with an application route the container
|
|
64
|
+
* already serves — the previous ad-hoc convention was a bare `/exec`, which an
|
|
65
|
+
* app could plausibly own for its own purposes.
|
|
66
|
+
*
|
|
67
|
+
* Exported because it is a *contract*, not an implementation detail: a
|
|
68
|
+
* container image has to serve exactly this route, and `@lunora/agent`'s
|
|
69
|
+
* human-in-the-loop gate has to recognise it. Both had it hard-coded as a
|
|
70
|
+
* second literal, which drifts silently — and on the gate's side, drift
|
|
71
|
+
* un-gates model-chosen command execution.
|
|
72
|
+
*/
|
|
73
|
+
declare const CONTAINER_EXEC_PATH = "/__lunora/exec";
|
|
74
|
+
/** Options for `handle.terminal()`. */
|
|
75
|
+
interface ContainerTerminalOptions extends Omit<ContainerSpawnOptions, "pty" | "signal" | "stdin"> {
|
|
76
|
+
/** Initial size. Defaults to the request's `?cols=&rows=` search params, else `80×24`. */
|
|
77
|
+
cols?: number;
|
|
78
|
+
/** The program to run. Defaults to `"sh"`. */
|
|
79
|
+
command?: string;
|
|
80
|
+
/** Initial size. Defaults to the request's `?cols=&rows=` search params, else `80×24`. */
|
|
81
|
+
rows?: number;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Options for explicitly starting an instance (mirrors `@cloudflare/containers`).
|
|
85
|
+
*/
|
|
4
86
|
interface ContainerStartOptions {
|
|
5
87
|
/** Override outbound internet access for this start. */
|
|
6
88
|
enableInternet?: boolean;
|
|
7
89
|
/** Override the container entrypoint. */
|
|
8
90
|
entrypoint?: string[];
|
|
9
|
-
/**
|
|
91
|
+
/**
|
|
92
|
+
* Per-instance environment. REPLACES the definition's `env`, `secrets` and
|
|
93
|
+
* `secretsStore` (the Secrets Store is not read), so pass every variable the
|
|
94
|
+
* container needs. It is persisted for the instance: every later start —
|
|
95
|
+
* including the implicit restart a `fetch`/`exec` triggers after the
|
|
96
|
+
* container slept, crashed or hit `hardTimeout` — uses it, until
|
|
97
|
+
* `destroy()`. The override cannot change while the container is running
|
|
98
|
+
* or still starting: a start whose `envVars` differ is rejected with
|
|
99
|
+
* `CONFLICT` in either case, so `stop()` it (and let any start in flight
|
|
100
|
+
* finish) first. So
|
|
101
|
+
* `start({ envVars: {} })` is a sandbox without the declared credentials,
|
|
102
|
+
* for as long as the instance exists.
|
|
103
|
+
*/
|
|
10
104
|
envVars?: Record<string, string>;
|
|
105
|
+
/**
|
|
106
|
+
* The image to start (`schedulingPolicy: "durable_object"` only): a key of
|
|
107
|
+
* the definition's `images`, or a Cloudflare-managed `"cloudflare/…"` image.
|
|
108
|
+
* Persisted like `envVars`, so the implicit restart after a sleep boots the
|
|
109
|
+
* same image. Mutually exclusive with `snapshot`.
|
|
110
|
+
*/
|
|
111
|
+
image?: string;
|
|
112
|
+
/**
|
|
113
|
+
* The instance size (`schedulingPolicy: "durable_object"` only). Persisted
|
|
114
|
+
* with `image`; defaults to the definition's `instanceType`, else `"lite"`.
|
|
115
|
+
*/
|
|
116
|
+
instanceType?: ContainerRuntimeInstanceType;
|
|
11
117
|
/** Metadata labels attached for metrics/observability. */
|
|
12
118
|
labels?: Record<string, string>;
|
|
119
|
+
/**
|
|
120
|
+
* Restore a filesystem saved by `snapshot()` instead of starting from an
|
|
121
|
+
* image (`schedulingPolicy: "durable_object"` only). Applies to this start
|
|
122
|
+
* only — a later restart after a sleep boots the image again.
|
|
123
|
+
*/
|
|
124
|
+
snapshot?: ContainerSnapshot;
|
|
13
125
|
}
|
|
14
|
-
/**
|
|
126
|
+
/**
|
|
127
|
+
* A container instance's runtime state, as returned by `getState()`. Structural — the platform adds fields over time.
|
|
128
|
+
*/
|
|
15
129
|
interface ContainerInstanceState {
|
|
16
130
|
[key: string]: unknown;
|
|
17
131
|
/** Process exit code, present once the instance has `stopped_with_code`. */
|
|
@@ -28,6 +142,34 @@ interface ContainerStubLike {
|
|
|
28
142
|
destroy?: () => Promise<void>;
|
|
29
143
|
fetch: (input: Request) => Promise<Response>;
|
|
30
144
|
getState?: () => Promise<ContainerInstanceState>;
|
|
145
|
+
lunoraBackup?: (directory: string, options?: ContainerBackupOptions) => Promise<DirectoryBackupRecord>;
|
|
146
|
+
lunoraDeleteBackup?: (backup: DirectoryBackupRecord) => Promise<void>;
|
|
147
|
+
/** The container DO's exec entry (`LunoraContainer.lunoraExec`), the only way a request reaches `/__lunora/exec`. */
|
|
148
|
+
lunoraExec?: (request: Request) => Promise<Response>;
|
|
149
|
+
lunoraInspectMount?: (path: string) => Promise<S3MountInspection>;
|
|
150
|
+
lunoraMkdir?: (path: string, options?: ContainerFileOptions & {
|
|
151
|
+
recursive?: boolean;
|
|
152
|
+
}) => Promise<void>;
|
|
153
|
+
lunoraMount?: (request: ContainerMountRequest) => Promise<void>;
|
|
154
|
+
lunoraReadDirectory?: (path: string, options?: ContainerFileOptions) => Promise<SandboxDirectoryEntry[]>;
|
|
155
|
+
lunoraReadFile?: (path: string, options?: ContainerFileOptions) => Promise<Response>;
|
|
156
|
+
lunoraRemove?: (path: string, options?: ContainerFileOptions & {
|
|
157
|
+
force?: boolean;
|
|
158
|
+
recursive?: boolean;
|
|
159
|
+
}) => Promise<void>;
|
|
160
|
+
lunoraRename?: (source: string, destination: string, options?: ContainerFileOptions) => Promise<void>;
|
|
161
|
+
lunoraRestore?: (backup: DirectoryBackupRecord, options?: {
|
|
162
|
+
directory?: string;
|
|
163
|
+
}) => Promise<void>;
|
|
164
|
+
/** The container DO's snapshot entry (`LunoraContainer.lunoraSnapshot`). */
|
|
165
|
+
lunoraSnapshot?: (options?: {
|
|
166
|
+
name?: string;
|
|
167
|
+
}) => Promise<ContainerSnapshot>;
|
|
168
|
+
/** The container DO's streaming-exec entry (`LunoraContainer.lunoraSpawn`). */
|
|
169
|
+
lunoraSpawn?: (request: ContainerSpawnRequest) => Promise<SpawnResult>;
|
|
170
|
+
lunoraStat?: (path: string, options?: ContainerFileOptions) => Promise<SandboxFileStat>;
|
|
171
|
+
lunoraUnmount?: (path: string) => Promise<void>;
|
|
172
|
+
lunoraWriteFile?: (path: string, content: ContainerFileContent, options?: ContainerFileOptions) => Promise<void>;
|
|
31
173
|
removeAllowedHost?: (hostname: string) => Promise<void>;
|
|
32
174
|
removeDeniedHost?: (hostname: string) => Promise<void>;
|
|
33
175
|
renewActivityTimeout?: () => Promise<void>;
|
|
@@ -37,80 +179,126 @@ interface ContainerStubLike {
|
|
|
37
179
|
stop?: (signal?: number | string) => Promise<void>;
|
|
38
180
|
}
|
|
39
181
|
/**
|
|
40
|
-
*
|
|
41
|
-
|
|
42
|
-
* @see https://developers.cloudflare.com/durable-objects/reference/data-location/
|
|
43
|
-
*/
|
|
44
|
-
type DurableObjectJurisdiction = "eu" | "fedramp" | "us";
|
|
45
|
-
/** What the client needs from a Durable Object namespace binding. */
|
|
182
|
+
* What the client needs from a Durable Object namespace binding.
|
|
183
|
+
*/
|
|
46
184
|
interface ContainerNamespaceLike {
|
|
47
185
|
get: (id: unknown) => ContainerStubLike;
|
|
48
186
|
idFromName: (name: string) => unknown;
|
|
49
187
|
/**
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
188
|
+
* Derive a jurisdiction-restricted subnamespace. Optional because older
|
|
189
|
+
* workers-types releases (and test doubles) may not expose it.
|
|
190
|
+
*/
|
|
53
191
|
jurisdiction?: (jurisdiction: DurableObjectJurisdiction) => ContainerNamespaceLike;
|
|
54
192
|
}
|
|
55
|
-
/**
|
|
193
|
+
/**
|
|
194
|
+
* A handle on one container instance (one Durable Object).
|
|
195
|
+
*/
|
|
56
196
|
interface ContainerHandle {
|
|
57
197
|
/**
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
198
|
+
* Run a command inside the container and return its exit code and output.
|
|
199
|
+
*
|
|
200
|
+
* A container is an HTTP server, so there is no platform-level exec to call:
|
|
201
|
+
* the command is POSTed to `/__lunora/exec` and the container app
|
|
202
|
+
* serves that route. What this method adds over hand-rolling that fetch is
|
|
203
|
+
* the **contract** — a pinned path, a typed request and response, and the
|
|
204
|
+
* distinction between "the command failed" (a `code`) and "the command could
|
|
205
|
+
* not be run" (a throw). Before it existed every caller invented its own
|
|
206
|
+
* `/exec` convention and read the raw body back as if it were output, which
|
|
207
|
+
* silently turned a runner's 500 into a successful-looking result.
|
|
208
|
+
*
|
|
209
|
+
* The container side must accept `{ args, command, cwd, env, timeoutMs }`
|
|
210
|
+
* and answer `{ code, stdout, stderr }` as JSON.
|
|
211
|
+
*/
|
|
212
|
+
exec: (command: string, options?: ContainerExecOptions) => Promise<ContainerExecResult>;
|
|
213
|
+
/**
|
|
214
|
+
* Send an HTTP (or WebSocket-upgrade) request to the container. A path
|
|
215
|
+
* string (`"/transcode"`) is resolved against a synthetic origin; a full
|
|
216
|
+
* `Request`/URL passes through unchanged.
|
|
217
|
+
*/
|
|
62
218
|
fetch: (input: Request | string, init?: RequestInit) => Promise<Response>;
|
|
63
219
|
/**
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
220
|
+
* Return a handle that routes every request to `targetPort` on the
|
|
221
|
+
* container instead of the definition's `defaultPort` — for multi-port
|
|
222
|
+
* containers (declare the ports in `requiredPorts`). Sets the
|
|
223
|
+
* `cf-container-target-port` header the way `@cloudflare/containers`'
|
|
224
|
+
* `switchPort` does, so it composes with `.get()`, `.any()`, and `.pool()`:
|
|
225
|
+
* `ctx.containers.app.get("u1").port(9090).fetch("/admin")`.
|
|
226
|
+
*/
|
|
71
227
|
port: (targetPort: number) => ContainerHandle;
|
|
72
228
|
}
|
|
73
229
|
/**
|
|
74
|
-
* A handle on a *named* instance (from `.get(name)`) — `fetch` plus explicit
|
|
75
|
-
* lifecycle control. The per-entity pattern (a sandbox per user, a room per
|
|
76
|
-
* game, a job runner per id) often needs to tear down or inspect the instance
|
|
77
|
-
* rather than wait for `sleepAfter`, so these wrap the container DO's
|
|
78
|
-
* `start`/`stop`/`destroy`/`getState`.
|
|
79
|
-
*/
|
|
230
|
+
* A handle on a *named* instance (from `.get(name)`) — `fetch` plus explicit
|
|
231
|
+
* lifecycle control. The per-entity pattern (a sandbox per user, a room per
|
|
232
|
+
* game, a job runner per id) often needs to tear down or inspect the instance
|
|
233
|
+
* rather than wait for `sleepAfter`, so these wrap the container DO's
|
|
234
|
+
* `start`/`stop`/`destroy`/`getState`.
|
|
235
|
+
*/
|
|
80
236
|
interface ContainerInstanceHandle extends ContainerHandle {
|
|
81
237
|
/** Stop and discard the instance (its ephemeral disk is lost). */
|
|
82
238
|
destroy: () => Promise<void>;
|
|
83
239
|
/**
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
240
|
+
* Adjust this instance's egress allow/deny lists at runtime — the dynamic
|
|
241
|
+
* counterpart to the static `allowedHosts`/`deniedHosts` config. Useful for
|
|
242
|
+
* per-tenant egress policy. Requires the worker to export `ContainerProxy`
|
|
243
|
+
* (codegen re-exports it from the generated container file whenever any
|
|
244
|
+
* container is defined, so the runtime controls always work).
|
|
245
|
+
*/
|
|
90
246
|
egress: ContainerEgressControls;
|
|
91
247
|
/** Read the instance's current runtime state. */
|
|
92
248
|
getState: () => Promise<ContainerInstanceState>;
|
|
93
249
|
/**
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
250
|
+
* Reset the instance's `sleepAfter` idle timer. The platform renews it on
|
|
251
|
+
* each proxied request, and because `@lunora/container` proxies WebSocket
|
|
252
|
+
* frames through the Durable Object, message traffic on an open socket
|
|
253
|
+
* renews it too (the WebSocket-keepalive gap of cloudflare/containers#147 is
|
|
254
|
+
* closed in the bundled base). This manual control is the escape hatch for
|
|
255
|
+
* keeping a container awake during activity that is neither an HTTP request
|
|
256
|
+
* nor a WS message — e.g. a long out-of-band job running inside it.
|
|
257
|
+
*/
|
|
102
258
|
renewActivityTimeout: () => Promise<void>;
|
|
259
|
+
/**
|
|
260
|
+
* Save the running container's filesystem and return a handle to restore it
|
|
261
|
+
* with `start({ snapshot })` — here or in another instance of the same
|
|
262
|
+
* container (`schedulingPolicy: "durable_object"` only; Cloudflare beta).
|
|
263
|
+
* Memory and processes are not captured.
|
|
264
|
+
*/
|
|
265
|
+
snapshot: (options?: {
|
|
266
|
+
name?: string;
|
|
267
|
+
}) => Promise<ContainerSnapshot>;
|
|
268
|
+
/**
|
|
269
|
+
* Start a process and stream it, rather than buffer it the way `exec`
|
|
270
|
+
* does: its stdout/stderr arrive as streams, `stdin` can be piped, and the
|
|
271
|
+
* process can be killed or (under `pty`) resized while it runs. Needs the
|
|
272
|
+
* runtime's native exec; the container is started first when it is not
|
|
273
|
+
* running, and kept awake until the process exits.
|
|
274
|
+
*/
|
|
275
|
+
spawn: (command: string, options?: ContainerSpawnOptions) => Promise<ContainerProcess>;
|
|
103
276
|
/** Explicitly start the instance, optionally with per-instance env/entrypoint. */
|
|
104
277
|
start: (options?: ContainerStartOptions) => Promise<void>;
|
|
105
278
|
/** Stop the instance (optionally with a signal); it can start again on the next request. */
|
|
106
279
|
stop: (signal?: number | string) => Promise<void>;
|
|
280
|
+
/**
|
|
281
|
+
* Answer a WebSocket upgrade `request` with a browser terminal: a shell
|
|
282
|
+
* (default `sh`) on a PTY, bridged to the socket. Binary frames are
|
|
283
|
+
* keystrokes, a text frame `{"cols":n,"rows":n}` resizes, and the socket
|
|
284
|
+
* closes when the shell exits. Authenticate the request first — whoever
|
|
285
|
+
* holds the socket has a shell in the container. Call it from a Worker
|
|
286
|
+
* route (see {@link getContainer}) and return the response as-is.
|
|
287
|
+
*/
|
|
288
|
+
terminal: (request: Request, options?: ContainerTerminalOptions) => Promise<Response>;
|
|
107
289
|
}
|
|
108
290
|
/**
|
|
109
|
-
*
|
|
110
|
-
*
|
|
111
|
-
*
|
|
112
|
-
|
|
113
|
-
|
|
291
|
+
* A named instance of a `defineContainer({ sandbox: true })` container: the
|
|
292
|
+
* {@link ContainerInstanceHandle} plus the Sandbox SDK helpers — structured
|
|
293
|
+
* file operations, directory backups to R2 and S3-compatible bucket mounts.
|
|
294
|
+
*/
|
|
295
|
+
interface SandboxContainerInstanceHandle extends ContainerInstanceHandle, ContainerSandboxControls {}
|
|
296
|
+
/**
|
|
297
|
+
* Runtime egress-firewall controls for a named instance (`handle.egress.*`).
|
|
298
|
+
* Each maps to the corresponding `@cloudflare/containers` `Container` RPC, so
|
|
299
|
+
* an app can tighten or relax a single instance's allowed/denied hosts after
|
|
300
|
+
* start without redeploying.
|
|
301
|
+
*/
|
|
114
302
|
interface ContainerEgressControls {
|
|
115
303
|
/** Add one hostname (or glob) to the allow-list. */
|
|
116
304
|
allow: (hostname: string) => Promise<void>;
|
|
@@ -125,86 +313,100 @@ interface ContainerEgressControls {
|
|
|
125
313
|
/** Replace the entire deny-list. */
|
|
126
314
|
setDenied: (hosts: ReadonlyArray<string>) => Promise<void>;
|
|
127
315
|
}
|
|
128
|
-
/**
|
|
316
|
+
/**
|
|
317
|
+
* The per-definition accessor exposed as `ctx.containers.<exportName>`.
|
|
318
|
+
*/
|
|
129
319
|
interface ContainerAccessor {
|
|
130
320
|
/**
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
321
|
+
* A random instance from a fixed pool of `count` (defaults to the
|
|
322
|
+
* definition's `maxInstances`, else 3 — mirroring `getRandom` from
|
|
323
|
+
* `@cloudflare/containers`). For stateless, interchangeable workloads.
|
|
324
|
+
*
|
|
325
|
+
* Like `.get()`, a path/URL-string fetch transparently retries the
|
|
326
|
+
* cold-start "instance is provisioning" transients (cloudflare/containers#45,
|
|
327
|
+
* #139); pass {@link InstanceRetryOptions} to tune or disable it.
|
|
328
|
+
*/
|
|
139
329
|
any: (count?: number, options?: InstanceRetryOptions) => ContainerHandle;
|
|
140
330
|
/**
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
331
|
+
* The instance for `name` — one container per entity (user, room, job…),
|
|
332
|
+
* with lifecycle control.
|
|
333
|
+
*
|
|
334
|
+
* A path/URL-string fetch transparently retries the platform's cold-start
|
|
335
|
+
* transients — "there is no Container instance available" / "container is
|
|
336
|
+
* not listening" while an instance is still provisioning
|
|
337
|
+
* (cloudflare/containers#45, #139) — on the *same* instance with backoff,
|
|
338
|
+
* since the request never reached the app. Pass {@link InstanceRetryOptions}
|
|
339
|
+
* to tune attempts/backoff or disable it (`{ attempts: 1 }`). A pre-built
|
|
340
|
+
* `Request` (possibly a one-shot stream body) is sent once, never retried.
|
|
341
|
+
*/
|
|
152
342
|
get: (name: string, options?: InstanceRetryOptions) => ContainerInstanceHandle;
|
|
153
343
|
/**
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
344
|
+
* A resilient handle over the pool: each `fetch` picks a random instance and,
|
|
345
|
+
* on a thrown error or a retryable response (5xx by default), retries on a
|
|
346
|
+
* freshly-picked instance with exponential backoff. Until Cloudflare ships
|
|
347
|
+
* native autoscaling + health-aware routing this is the recommended way to
|
|
348
|
+
* call a stateless container pool — it rides over a single cold/unhealthy
|
|
349
|
+
* instance instead of failing the whole request.
|
|
350
|
+
*
|
|
351
|
+
* Because a retry re-issues the request, pass a **replayable** body — a path
|
|
352
|
+
* string plus an `init.body` string/`ArrayBuffer` (re-created each attempt).
|
|
353
|
+
* A pre-built `Request` carrying a stream body can only be sent once, so it
|
|
354
|
+
* is not retry-safe here; use `.get()`/`.any()` for those.
|
|
355
|
+
*/
|
|
166
356
|
pool: (options?: PoolOptions) => ContainerHandle;
|
|
167
357
|
}
|
|
168
|
-
/**
|
|
358
|
+
/** `ctx.containers.<name>` for a `defineContainer({ sandbox: true })` container: `.get()` adds the sandbox helpers. */
|
|
359
|
+
interface SandboxContainerAccessor extends ContainerAccessor {
|
|
360
|
+
get: (name: string, options?: InstanceRetryOptions) => SandboxContainerInstanceHandle;
|
|
361
|
+
}
|
|
362
|
+
/**
|
|
363
|
+
* Tuning for a pooled, retrying container handle. See {@link ContainerAccessor.pool}.
|
|
364
|
+
*/
|
|
169
365
|
interface PoolOptions {
|
|
170
366
|
/** Total attempts before giving up (each on a freshly-picked instance). Default 3. */
|
|
171
367
|
attempts?: number;
|
|
172
368
|
/** Base backoff in ms between attempts; doubles each retry (0 disables the wait). Default 100. */
|
|
173
369
|
backoffMs?: number;
|
|
174
370
|
/**
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
371
|
+
* Upper bound on a single backoff sleep, in ms. The doubling delay is clamped
|
|
372
|
+
* to this ceiling so a large `attempts` count can't produce an unboundedly
|
|
373
|
+
* long wait. Default {@link DEFAULT_MAX_BACKOFF_MS} (30s).
|
|
374
|
+
*/
|
|
179
375
|
maxBackoffMs?: number;
|
|
180
376
|
/**
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
377
|
+
* Whether a *returned* response should be retried on another instance.
|
|
378
|
+
* Defaults to retrying any `5xx`. A thrown error (network/start failure) is
|
|
379
|
+
* always retried regardless of this predicate.
|
|
380
|
+
*
|
|
381
|
+
* Applies to `fetch` only. `exec` retries on the cold-start transients
|
|
382
|
+
* alone, because its caller never chose the request and a command that
|
|
383
|
+
* already ran must not be re-run just because the runner failed afterwards.
|
|
384
|
+
*/
|
|
185
385
|
retryOn?: (response: Response) => boolean;
|
|
186
386
|
/** Pool size to spread picks across. Defaults to the definition's `maxInstances`, else 3. */
|
|
187
387
|
size?: number;
|
|
188
388
|
}
|
|
189
389
|
/**
|
|
190
|
-
* Tuning for the cold-start retry on a `.get()`/`.any()` handle. The retry fires
|
|
191
|
-
* only on the platform's provisioning transients (no-instance / not-listening /
|
|
192
|
-
* rate-limited — see {@link isColdStartTransient}), which is why it's safe by
|
|
193
|
-
* default: those responses mean the request never reached the container.
|
|
194
|
-
*/
|
|
390
|
+
* Tuning for the cold-start retry on a `.get()`/`.any()` handle. The retry fires
|
|
391
|
+
* only on the platform's provisioning transients (no-instance / not-listening /
|
|
392
|
+
* rate-limited — see {@link isColdStartTransient}), which is why it's safe by
|
|
393
|
+
* default: those responses mean the request never reached the container.
|
|
394
|
+
*/
|
|
195
395
|
interface InstanceRetryOptions {
|
|
196
396
|
/**
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
397
|
+
* Total attempts on a cold-start transient before the last outcome is
|
|
398
|
+
* surfaced as-is. `1` disables the retry. Default
|
|
399
|
+
* {@link DEFAULT_COLD_START_ATTEMPTS}.
|
|
400
|
+
*/
|
|
201
401
|
attempts?: number;
|
|
202
402
|
/** Base backoff in ms between attempts; doubles each retry (0 disables the wait). Default {@link DEFAULT_COLD_START_BACKOFF_MS}. */
|
|
203
403
|
backoffMs?: number;
|
|
204
404
|
/** Upper bound on a single backoff sleep, in ms. Default {@link DEFAULT_MAX_BACKOFF_MS} (30s). */
|
|
205
405
|
maxBackoffMs?: number;
|
|
206
406
|
}
|
|
207
|
-
/**
|
|
407
|
+
/**
|
|
408
|
+
* Wiring info for one definition, emitted by codegen into the generated DO.
|
|
409
|
+
*/
|
|
208
410
|
interface ContainerBindingSpec {
|
|
209
411
|
/** Durable Object binding name, e.g. `CONTAINER_TRANSCODER`. */
|
|
210
412
|
binding: string;
|
|
@@ -214,70 +416,299 @@ interface ContainerBindingSpec {
|
|
|
214
416
|
maxInstances?: number;
|
|
215
417
|
}
|
|
216
418
|
/**
|
|
217
|
-
* Build the `ctx.containers` record from the Worker `env`. Called by the
|
|
218
|
-
* generated ShardDO with the specs codegen derived from
|
|
219
|
-
*
|
|
220
|
-
*
|
|
221
|
-
*
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
419
|
+
* Build the `ctx.containers` record from the Worker `env`. Called by the
|
|
420
|
+
* generated ShardDO with the specs codegen derived from `lunora/containers.ts`.
|
|
421
|
+
* A missing binding doesn't throw here — only when the handle is actually used —
|
|
422
|
+
* so one unprovisioned container never breaks unrelated functions.
|
|
423
|
+
*
|
|
424
|
+
* The last two arguments carry the dispatch's telemetry verdict onto every
|
|
425
|
+
* outbound container `fetch`, both read off the inbound request by the DO:
|
|
426
|
+
*
|
|
427
|
+
* - `traceparent` — the W3C trace context, so the container's own spans stitch
|
|
428
|
+
* under the Worker's trace rather than starting a disconnected one.
|
|
429
|
+
* - `sampleErrors` — the tail-bias toggle, so the container exports what THIS
|
|
430
|
+
* dispatch decided instead of falling back to its own environment and agreeing
|
|
431
|
+
* with the other tiers only by coincidence. `undefined` (an alarm, a
|
|
432
|
+
* subscription re-run, a non-Lunora caller propagated no verdict) omits the
|
|
433
|
+
* header and leaves the container on its own configuration.
|
|
434
|
+
*/
|
|
435
|
+
declare const createContainerContext: (env: Record<string, unknown>, specs: ReadonlyArray<ContainerBindingSpec>, jurisdiction?: DurableObjectJurisdiction, traceparent?: string, sampleErrors?: boolean) => Record<string, ContainerAccessor>;
|
|
436
|
+
/**
|
|
437
|
+
* A named container instance straight off the Worker `env`, for code that has
|
|
438
|
+
* no `ctx.containers` — typically an `httpRouter` route that opens a
|
|
439
|
+
* {@link ContainerInstanceHandle.terminal} or proxies a preview port, both of
|
|
440
|
+
* which must hand a WebSocket upgrade response back to the browser. The
|
|
441
|
+
* binding is derived from `exportName` exactly as codegen derives it. Pass
|
|
442
|
+
* {@link SandboxContainerInstanceHandle} as the type argument for a
|
|
443
|
+
* `sandbox: true` container.
|
|
444
|
+
*
|
|
445
|
+
* ```ts
|
|
446
|
+
* app.get("/terminal", async (c) => getContainer(c.env, "box", userId).terminal(c.req.raw));
|
|
447
|
+
* ```
|
|
448
|
+
*/
|
|
449
|
+
declare const getContainer: <Handle extends ContainerInstanceHandle = ContainerInstanceHandle>(env: Record<string, unknown>, exportName: string, name: string, options?: InstanceRetryOptions & {
|
|
450
|
+
jurisdiction?: DurableObjectJurisdiction;
|
|
451
|
+
}) => Handle;
|
|
452
|
+
/**
|
|
453
|
+
* A test handler: receives the request plus the targeted instance name.
|
|
454
|
+
*/
|
|
225
455
|
type ContainerTestHandler = (request: Request, instance: {
|
|
226
456
|
name: string;
|
|
227
457
|
}) => Promise<Response> | Response;
|
|
228
458
|
/**
|
|
229
|
-
* Docker-free test double for `ctx.containers`: each export name maps to a
|
|
230
|
-
* fetch handler that plays the container. Mirrors the real shape exactly, so
|
|
231
|
-
* action handlers under test can't tell the difference.
|
|
232
|
-
*
|
|
233
|
-
* ```ts
|
|
234
|
-
* const containers = createContainerTestContext({
|
|
235
|
-
* transcoder: (request) => new Response("ok"),
|
|
236
|
-
* });
|
|
237
|
-
* ```
|
|
238
|
-
*/
|
|
459
|
+
* Docker-free test double for `ctx.containers`: each export name maps to a
|
|
460
|
+
* fetch handler that plays the container. Mirrors the real shape exactly, so
|
|
461
|
+
* action handlers under test can't tell the difference.
|
|
462
|
+
*
|
|
463
|
+
* ```ts
|
|
464
|
+
* const containers = createContainerTestContext({
|
|
465
|
+
* transcoder: (request) => new Response("ok"),
|
|
466
|
+
* });
|
|
467
|
+
* ```
|
|
468
|
+
*/
|
|
239
469
|
declare const createContainerTestContext: (handlers: Record<string, ContainerTestHandler>) => Record<string, ContainerAccessor>;
|
|
470
|
+
/** Whether an image name is a Cloudflare-managed image (`cloudflare/debian-trixie`), which needs no `images` entry. */
|
|
471
|
+
declare const isManagedImage: (name: string) => boolean;
|
|
472
|
+
/**
|
|
473
|
+
* The default-policy keys the `durable_object` policy refuses — wrangler rejects
|
|
474
|
+
* `max_instances` under it, and a rollout has nothing to roll. One table, read by
|
|
475
|
+
* `defineContainer` and by codegen's static discovery.
|
|
476
|
+
*/
|
|
477
|
+
declare const DURABLE_OBJECT_POLICY_FORBIDDEN_KEYS: readonly ["maxInstances", "rollout"];
|
|
240
478
|
/**
|
|
241
|
-
* Normalize a `ContainerImageSource` into the shape wrangler wants: a
|
|
242
|
-
* Dockerfile path + build context for local builds, or a fully-qualified
|
|
243
|
-
* reference for pre-built images.
|
|
244
|
-
*
|
|
245
|
-
* A local-path string whose basename starts with `Dockerfile` (so
|
|
246
|
-
* `Dockerfile.dev` also counts) is used as-is with its directory as the build
|
|
247
|
-
* context; any other path is treated as the build-context directory and the
|
|
248
|
-
* Dockerfile is expected at
|
|
249
|
-
*/
|
|
479
|
+
* Normalize a `ContainerImageSource` into the shape wrangler wants: a
|
|
480
|
+
* Dockerfile path + build context for local builds, or a fully-qualified
|
|
481
|
+
* reference for pre-built images.
|
|
482
|
+
*
|
|
483
|
+
* A local-path string whose basename starts with `Dockerfile` (so
|
|
484
|
+
* `Dockerfile.dev` also counts) is used as-is with its directory as the build
|
|
485
|
+
* context; any other path is treated as the build-context directory and the
|
|
486
|
+
* Dockerfile is expected at `<dir>/Dockerfile`.
|
|
487
|
+
*/
|
|
250
488
|
declare const normalizeContainerImage: (image: ContainerImageSource) => NormalizedContainerImage;
|
|
251
489
|
/**
|
|
252
|
-
* The generated Container DO class name for a `lunora/containers.ts` export:
|
|
253
|
-
* `transcoder` → `TranscoderContainer`. wrangler's `containers[].class_name`
|
|
254
|
-
* and the Durable Object binding's `class_name` both reference it, so codegen
|
|
255
|
-
* and the config layer MUST derive it identically — always via this helper.
|
|
256
|
-
*/
|
|
490
|
+
* The generated Container DO class name for a `lunora/containers.ts` export:
|
|
491
|
+
* `transcoder` → `TranscoderContainer`. wrangler's `containers[].class_name`
|
|
492
|
+
* and the Durable Object binding's `class_name` both reference it, so codegen
|
|
493
|
+
* and the config layer MUST derive it identically — always via this helper.
|
|
494
|
+
*/
|
|
257
495
|
declare const containerClassName: (exportName: string) => string;
|
|
258
496
|
/**
|
|
259
|
-
* The Durable Object binding name for a container export: `transcoder` →
|
|
260
|
-
* `CONTAINER_TRANSCODER`, `imageResizer` → `CONTAINER_IMAGE_RESIZER`. The
|
|
261
|
-
* `CONTAINER_` prefix namespaces these away from `SHARD`/`SESSION`/`SCHEDULER`
|
|
262
|
-
* so a container export can never collide with the built-in bindings.
|
|
263
|
-
*/
|
|
497
|
+
* The Durable Object binding name for a container export: `transcoder` →
|
|
498
|
+
* `CONTAINER_TRANSCODER`, `imageResizer` → `CONTAINER_IMAGE_RESIZER`. The
|
|
499
|
+
* `CONTAINER_` prefix namespaces these away from `SHARD`/`SESSION`/`SCHEDULER`
|
|
500
|
+
* so a container export can never collide with the built-in bindings.
|
|
501
|
+
*/
|
|
264
502
|
declare const containerBindingName: (exportName: string) => string;
|
|
265
503
|
/**
|
|
266
|
-
* The local image tag a Railpack `{ build }` container is built and pushed
|
|
267
|
-
* under: `transcoder` → `lunora-transcoder:build`. The config reconciler writes
|
|
268
|
-
* it as the wrangler `containers[].image`, and `lunora deploy` builds that tag
|
|
269
|
-
* with Railpack and `wrangler containers push`es it before deploying — so all
|
|
270
|
-
* three derive the tag from this one helper and can never disagree.
|
|
271
|
-
*/
|
|
504
|
+
* The local image tag a Railpack `{ build }` container is built and pushed
|
|
505
|
+
* under: `transcoder` → `lunora-transcoder:build`. The config reconciler writes
|
|
506
|
+
* it as the wrangler `containers[].image`, and `lunora deploy` builds that tag
|
|
507
|
+
* with Railpack and `wrangler containers push`es it before deploying — so all
|
|
508
|
+
* three derive the tag from this one helper and can never disagree.
|
|
509
|
+
*/
|
|
272
510
|
declare const containerBuildTag: (exportName: string) => string;
|
|
273
|
-
|
|
274
|
-
|
|
511
|
+
/** Whether a registry reference is digest-pinned in the Cloudflare registry — the only kind a named image accepts. */
|
|
512
|
+
declare const isCloudflareRegistryDigest: (reference: unknown) => boolean;
|
|
513
|
+
/**
|
|
514
|
+
* `defineContainer` is part of the experimental `@lunora/container` API and may change without a major version bump.
|
|
515
|
+
*/
|
|
516
|
+
declare const defineContainer: {
|
|
517
|
+
(config: DefaultScheduledContainerConfig): DefaultScheduledContainerConfig & {
|
|
518
|
+
readonly isLunoraContainer: true;
|
|
519
|
+
};
|
|
520
|
+
(config: DurableObjectScheduledContainerConfig): DurableObjectScheduledContainerConfig & {
|
|
521
|
+
readonly isLunoraContainer: true;
|
|
522
|
+
};
|
|
523
|
+
};
|
|
524
|
+
/**
|
|
525
|
+
* True when a value is a `defineContainer` result (the runtime brand check).
|
|
526
|
+
*/
|
|
275
527
|
declare const isContainerDefinition: (value: unknown) => value is ContainerDefinition;
|
|
276
528
|
/**
|
|
277
|
-
* The container's full environment at instance start: the static `env` block
|
|
278
|
-
* plus every declared secret resolved from the Worker `env`. A declared secret
|
|
279
|
-
* missing from the Worker env fails fast — starting the container without a
|
|
280
|
-
* credential it was promised yields far worse errors downstream.
|
|
281
|
-
*/
|
|
529
|
+
* The container's full environment at instance start: the static `env` block
|
|
530
|
+
* plus every declared secret resolved from the Worker `env`. A declared secret
|
|
531
|
+
* missing from the Worker env fails fast — starting the container without a
|
|
532
|
+
* credential it was promised yields far worse errors downstream.
|
|
533
|
+
*/
|
|
282
534
|
declare const resolveContainerEnvVariables: (definition: ContainerDefinition, workerEnv: Record<string, unknown>, exportName?: string) => Record<string, string>;
|
|
283
|
-
|
|
535
|
+
/**
|
|
536
|
+
* Cloudflare's documented bounds for a custom container instance type
|
|
537
|
+
* (https://developers.cloudflare.com/containers/platform-details/limits/):
|
|
538
|
+
* 1–4 vCPU, up to 12 GiB memory, up to 20 GB disk at any memory size, and at
|
|
539
|
+
* least 3 GiB memory per vCPU. Below 1 vCPU, Cloudflare points at the named
|
|
540
|
+
* `lite` / `basic` instance types instead.
|
|
541
|
+
*
|
|
542
|
+
* The one copy of these numbers. `defineContainer` checks a `durable_object`
|
|
543
|
+
* container's runtime size against it, and `@lunora/config`'s wrangler validator
|
|
544
|
+
* checks `containers[].instance_type` against it (config already depends on this
|
|
545
|
+
* package, so the import runs one way). Pure data, Node-safe.
|
|
546
|
+
*/
|
|
547
|
+
/** Inclusive bounds for one dimension of a custom instance type. */
|
|
548
|
+
interface InstanceDimensionLimits {
|
|
549
|
+
readonly max: number;
|
|
550
|
+
readonly min: number;
|
|
551
|
+
}
|
|
552
|
+
/** Per-dimension bounds, keyed by the `CustomContainerInstanceType` field names. */
|
|
553
|
+
declare const CUSTOM_INSTANCE_TYPE_LIMITS: Readonly<{
|
|
554
|
+
diskMb: InstanceDimensionLimits;
|
|
555
|
+
memoryMib: InstanceDimensionLimits;
|
|
556
|
+
vcpu: InstanceDimensionLimits;
|
|
557
|
+
}>;
|
|
558
|
+
/** The memory floor per vCPU: 3 GiB. */
|
|
559
|
+
declare const CUSTOM_INSTANCE_MIN_MEMORY_MIB_PER_VCPU = 3072;
|
|
560
|
+
export { CONTAINER_EXEC_PATH, CUSTOM_INSTANCE_MIN_MEMORY_MIB_PER_VCPU, CUSTOM_INSTANCE_TYPE_LIMITS,
|
|
561
|
+
/**
|
|
562
|
+
* `@lunora/container` — Cloudflare Containers for Lunora.
|
|
563
|
+
*
|
|
564
|
+
* This root export is Node-safe (no Cloudflare runtime imports): the
|
|
565
|
+
* `defineContainer` authoring surface, the naming/normalization helpers
|
|
566
|
+
* codegen and `@lunora/config` share, the `ctx.containers` client wiring, and
|
|
567
|
+
* a Docker-free test double. The workerd-only `LunoraContainer` base class
|
|
568
|
+
* (which pulls in `@cloudflare/containers` → `cloudflare:workers`) lives
|
|
569
|
+
* behind the `@lunora/container/do` subpath.
|
|
570
|
+
*/
|
|
571
|
+
type ContainerAccessor, type ContainerBackupOptions,
|
|
572
|
+
/**
|
|
573
|
+
* `@lunora/container` — Cloudflare Containers for Lunora.
|
|
574
|
+
*
|
|
575
|
+
* This root export is Node-safe (no Cloudflare runtime imports): the
|
|
576
|
+
* `defineContainer` authoring surface, the naming/normalization helpers
|
|
577
|
+
* codegen and `@lunora/config` share, the `ctx.containers` client wiring, and
|
|
578
|
+
* a Docker-free test double. The workerd-only `LunoraContainer` base class
|
|
579
|
+
* (which pulls in `@cloudflare/containers` → `cloudflare:workers`) lives
|
|
580
|
+
* behind the `@lunora/container/do` subpath.
|
|
581
|
+
*/
|
|
582
|
+
type ContainerBindingSpec, type ContainerDefinition,
|
|
583
|
+
/**
|
|
584
|
+
* `@lunora/container` — Cloudflare Containers for Lunora.
|
|
585
|
+
*
|
|
586
|
+
* This root export is Node-safe (no Cloudflare runtime imports): the
|
|
587
|
+
* `defineContainer` authoring surface, the naming/normalization helpers
|
|
588
|
+
* codegen and `@lunora/config` share, the `ctx.containers` client wiring, and
|
|
589
|
+
* a Docker-free test double. The workerd-only `LunoraContainer` base class
|
|
590
|
+
* (which pulls in `@cloudflare/containers` → `cloudflare:workers`) lives
|
|
591
|
+
* behind the `@lunora/container/do` subpath.
|
|
592
|
+
*/
|
|
593
|
+
type ContainerEgressControls, type ContainerExecOptions, type ContainerExecResult, type ContainerFileContent, type ContainerFileOptions,
|
|
594
|
+
/**
|
|
595
|
+
* `@lunora/container` — Cloudflare Containers for Lunora.
|
|
596
|
+
*
|
|
597
|
+
* This root export is Node-safe (no Cloudflare runtime imports): the
|
|
598
|
+
* `defineContainer` authoring surface, the naming/normalization helpers
|
|
599
|
+
* codegen and `@lunora/config` share, the `ctx.containers` client wiring, and
|
|
600
|
+
* a Docker-free test double. The workerd-only `LunoraContainer` base class
|
|
601
|
+
* (which pulls in `@cloudflare/containers` → `cloudflare:workers`) lives
|
|
602
|
+
* behind the `@lunora/container/do` subpath.
|
|
603
|
+
*/
|
|
604
|
+
type ContainerHandle, type ContainerImageSource,
|
|
605
|
+
/**
|
|
606
|
+
* `@lunora/container` — Cloudflare Containers for Lunora.
|
|
607
|
+
*
|
|
608
|
+
* This root export is Node-safe (no Cloudflare runtime imports): the
|
|
609
|
+
* `defineContainer` authoring surface, the naming/normalization helpers
|
|
610
|
+
* codegen and `@lunora/config` share, the `ctx.containers` client wiring, and
|
|
611
|
+
* a Docker-free test double. The workerd-only `LunoraContainer` base class
|
|
612
|
+
* (which pulls in `@cloudflare/containers` → `cloudflare:workers`) lives
|
|
613
|
+
* behind the `@lunora/container/do` subpath.
|
|
614
|
+
*/
|
|
615
|
+
type ContainerInstanceHandle,
|
|
616
|
+
/**
|
|
617
|
+
* `@lunora/container` — Cloudflare Containers for Lunora.
|
|
618
|
+
*
|
|
619
|
+
* This root export is Node-safe (no Cloudflare runtime imports): the
|
|
620
|
+
* `defineContainer` authoring surface, the naming/normalization helpers
|
|
621
|
+
* codegen and `@lunora/config` share, the `ctx.containers` client wiring, and
|
|
622
|
+
* a Docker-free test double. The workerd-only `LunoraContainer` base class
|
|
623
|
+
* (which pulls in `@cloudflare/containers` → `cloudflare:workers`) lives
|
|
624
|
+
* behind the `@lunora/container/do` subpath.
|
|
625
|
+
*/
|
|
626
|
+
type ContainerInstanceState, type ContainerMountRequest,
|
|
627
|
+
/**
|
|
628
|
+
* `@lunora/container` — Cloudflare Containers for Lunora.
|
|
629
|
+
*
|
|
630
|
+
* This root export is Node-safe (no Cloudflare runtime imports): the
|
|
631
|
+
* `defineContainer` authoring surface, the naming/normalization helpers
|
|
632
|
+
* codegen and `@lunora/config` share, the `ctx.containers` client wiring, and
|
|
633
|
+
* a Docker-free test double. The workerd-only `LunoraContainer` base class
|
|
634
|
+
* (which pulls in `@cloudflare/containers` → `cloudflare:workers`) lives
|
|
635
|
+
* behind the `@lunora/container/do` subpath.
|
|
636
|
+
*/
|
|
637
|
+
type ContainerNamespaceLike, type ContainerProcess, type ContainerRuntimeInstanceType, type ContainerSandboxControls, type ContainerSnapshot, type ContainerSpawnOptions,
|
|
638
|
+
/**
|
|
639
|
+
* `@lunora/container` — Cloudflare Containers for Lunora.
|
|
640
|
+
*
|
|
641
|
+
* This root export is Node-safe (no Cloudflare runtime imports): the
|
|
642
|
+
* `defineContainer` authoring surface, the naming/normalization helpers
|
|
643
|
+
* codegen and `@lunora/config` share, the `ctx.containers` client wiring, and
|
|
644
|
+
* a Docker-free test double. The workerd-only `LunoraContainer` base class
|
|
645
|
+
* (which pulls in `@cloudflare/containers` → `cloudflare:workers`) lives
|
|
646
|
+
* behind the `@lunora/container/do` subpath.
|
|
647
|
+
*/
|
|
648
|
+
type ContainerStartOptions, type ContainerTerminalOptions,
|
|
649
|
+
/**
|
|
650
|
+
* `@lunora/container` — Cloudflare Containers for Lunora.
|
|
651
|
+
*
|
|
652
|
+
* This root export is Node-safe (no Cloudflare runtime imports): the
|
|
653
|
+
* `defineContainer` authoring surface, the naming/normalization helpers
|
|
654
|
+
* codegen and `@lunora/config` share, the `ctx.containers` client wiring, and
|
|
655
|
+
* a Docker-free test double. The workerd-only `LunoraContainer` base class
|
|
656
|
+
* (which pulls in `@cloudflare/containers` → `cloudflare:workers`) lives
|
|
657
|
+
* behind the `@lunora/container/do` subpath.
|
|
658
|
+
*/
|
|
659
|
+
type ContainerTestHandler, DURABLE_OBJECT_POLICY_FORBIDDEN_KEYS, type DefaultScheduledContainerConfig,
|
|
660
|
+
/**
|
|
661
|
+
* `@lunora/container` — Cloudflare Containers for Lunora.
|
|
662
|
+
*
|
|
663
|
+
* This root export is Node-safe (no Cloudflare runtime imports): the
|
|
664
|
+
* `defineContainer` authoring surface, the naming/normalization helpers
|
|
665
|
+
* codegen and `@lunora/config` share, the `ctx.containers` client wiring, and
|
|
666
|
+
* a Docker-free test double. The workerd-only `LunoraContainer` base class
|
|
667
|
+
* (which pulls in `@cloudflare/containers` → `cloudflare:workers`) lives
|
|
668
|
+
* behind the `@lunora/container/do` subpath.
|
|
669
|
+
*/
|
|
670
|
+
type DurableObjectJurisdiction, type DurableObjectScheduledContainerConfig, type InstanceDimensionLimits,
|
|
671
|
+
/**
|
|
672
|
+
* `@lunora/container` — Cloudflare Containers for Lunora.
|
|
673
|
+
*
|
|
674
|
+
* This root export is Node-safe (no Cloudflare runtime imports): the
|
|
675
|
+
* `defineContainer` authoring surface, the naming/normalization helpers
|
|
676
|
+
* codegen and `@lunora/config` share, the `ctx.containers` client wiring, and
|
|
677
|
+
* a Docker-free test double. The workerd-only `LunoraContainer` base class
|
|
678
|
+
* (which pulls in `@cloudflare/containers` → `cloudflare:workers`) lives
|
|
679
|
+
* behind the `@lunora/container/do` subpath.
|
|
680
|
+
*/
|
|
681
|
+
type InstanceRetryOptions, type NormalizedContainerImage,
|
|
682
|
+
/**
|
|
683
|
+
* `@lunora/container` — Cloudflare Containers for Lunora.
|
|
684
|
+
*
|
|
685
|
+
* This root export is Node-safe (no Cloudflare runtime imports): the
|
|
686
|
+
* `defineContainer` authoring surface, the naming/normalization helpers
|
|
687
|
+
* codegen and `@lunora/config` share, the `ctx.containers` client wiring, and
|
|
688
|
+
* a Docker-free test double. The workerd-only `LunoraContainer` base class
|
|
689
|
+
* (which pulls in `@cloudflare/containers` → `cloudflare:workers`) lives
|
|
690
|
+
* behind the `@lunora/container/do` subpath.
|
|
691
|
+
*/
|
|
692
|
+
type PoolOptions,
|
|
693
|
+
/**
|
|
694
|
+
* `@lunora/container` — Cloudflare Containers for Lunora.
|
|
695
|
+
*
|
|
696
|
+
* This root export is Node-safe (no Cloudflare runtime imports): the
|
|
697
|
+
* `defineContainer` authoring surface, the naming/normalization helpers
|
|
698
|
+
* codegen and `@lunora/config` share, the `ctx.containers` client wiring, and
|
|
699
|
+
* a Docker-free test double. The workerd-only `LunoraContainer` base class
|
|
700
|
+
* (which pulls in `@cloudflare/containers` → `cloudflare:workers`) lives
|
|
701
|
+
* behind the `@lunora/container/do` subpath.
|
|
702
|
+
*/
|
|
703
|
+
type SandboxContainerAccessor,
|
|
704
|
+
/**
|
|
705
|
+
* `@lunora/container` — Cloudflare Containers for Lunora.
|
|
706
|
+
*
|
|
707
|
+
* This root export is Node-safe (no Cloudflare runtime imports): the
|
|
708
|
+
* `defineContainer` authoring surface, the naming/normalization helpers
|
|
709
|
+
* codegen and `@lunora/config` share, the `ctx.containers` client wiring, and
|
|
710
|
+
* a Docker-free test double. The workerd-only `LunoraContainer` base class
|
|
711
|
+
* (which pulls in `@cloudflare/containers` → `cloudflare:workers`) lives
|
|
712
|
+
* behind the `@lunora/container/do` subpath.
|
|
713
|
+
*/
|
|
714
|
+
type SandboxContainerInstanceHandle, containerBindingName, containerBuildTag, containerClassName, createContainerContext, createContainerTestContext, defineContainer, getContainer, isCloudflareRegistryDigest, isContainerDefinition, isManagedImage, normalizeContainerImage, resolveContainerEnvVariables as resolveContainerEnvVars };
|