@supermachine/core 0.4.25
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/LICENSE +202 -0
- package/README.md +407 -0
- package/examples/01-hello.mjs +32 -0
- package/examples/02-pool.mjs +54 -0
- package/examples/03-snapshot-then-restore.mjs +54 -0
- package/examples/04-expose-tcp.mjs +80 -0
- package/examples/05-spawn-streaming.mjs +59 -0
- package/examples/README.md +43 -0
- package/index.d.ts +532 -0
- package/index.js +290 -0
- package/package.json +59 -0
package/index.d.ts
ADDED
|
@@ -0,0 +1,532 @@
|
|
|
1
|
+
/* tslint:disable */
|
|
2
|
+
/* eslint-disable */
|
|
3
|
+
|
|
4
|
+
/* auto-generated by scripts/gen-dts.js from napi-derive's TYPE_DEF_TMP_PATH output */
|
|
5
|
+
/* DO NOT EDIT — regenerate via `npm run build`. */
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* VM-shaped handle passed to a `warmup` callback. Only valid
|
|
9
|
+
* during the callback's lifetime — `exec` errors after return.
|
|
10
|
+
*/
|
|
11
|
+
export interface WarmupVm {
|
|
12
|
+
exec(options: ExecOptions): Promise<ExecOutput>
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* One staged host file → guest path mapping for `extraFiles`. See
|
|
17
|
+
* [`BuildOptions::extra_files`].
|
|
18
|
+
*/
|
|
19
|
+
export interface ExtraFileSpec {
|
|
20
|
+
/**
|
|
21
|
+
* Host filesystem path. File contents are read at bake time
|
|
22
|
+
* and folded into the snapshot's input-hash, so changes
|
|
23
|
+
* re-bake.
|
|
24
|
+
*/
|
|
25
|
+
hostPath: string
|
|
26
|
+
/** Where the file appears inside the guest's root filesystem. */
|
|
27
|
+
guestPath: string
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Options for [`Image.build`]. Mirrors `OciImageBuilder` in the
|
|
32
|
+
* Rust crate. All fields optional except `ref` (the OCI image
|
|
33
|
+
* reference).
|
|
34
|
+
*/
|
|
35
|
+
export interface BuildOptions {
|
|
36
|
+
/**
|
|
37
|
+
* OCI image reference, e.g. `"rust:1-slim"`,
|
|
38
|
+
* `"ghcr.io/owner/image@sha256:..."`.
|
|
39
|
+
*/
|
|
40
|
+
ref: string
|
|
41
|
+
/**
|
|
42
|
+
* Stable snapshot name. Defaults to a sha-derived name based
|
|
43
|
+
* on the image reference.
|
|
44
|
+
*/
|
|
45
|
+
name?: string
|
|
46
|
+
/**
|
|
47
|
+
* Guest memory in MiB. Default 256. Note: allocation is lazy
|
|
48
|
+
* (CoW page-fault); this is the guest-visible ceiling, not
|
|
49
|
+
* host commit.
|
|
50
|
+
*/
|
|
51
|
+
memoryMib?: number
|
|
52
|
+
/** vCPUs per VM. Default 1. */
|
|
53
|
+
vcpus?: number
|
|
54
|
+
/** `"always"` | `"missing"` | `"never"`. Default `"missing"`. */
|
|
55
|
+
pullPolicy?: string
|
|
56
|
+
/**
|
|
57
|
+
* Workload listener port. Default 80. Used by service-image
|
|
58
|
+
* bakes (see `listenerRequired`).
|
|
59
|
+
*/
|
|
60
|
+
guestPort?: number
|
|
61
|
+
/** Override the image's CMD/ENTRYPOINT. */
|
|
62
|
+
cmd?: Array<string>
|
|
63
|
+
/** Extra environment variables for the workload. */
|
|
64
|
+
env?: Record<string, string>
|
|
65
|
+
/**
|
|
66
|
+
* When `true`, wait for the workload's listener to bind before
|
|
67
|
+
* capturing the snapshot — v0.4.22 behavior. Default `false`
|
|
68
|
+
* uses the pre-exec trigger (v0.4.23+): fast bake, workload
|
|
69
|
+
* starts fresh on each restore. Set `true` for service-image
|
|
70
|
+
* bakes (nginx, redis) where you want the listener pre-bound.
|
|
71
|
+
*/
|
|
72
|
+
listenerRequired?: boolean
|
|
73
|
+
/**
|
|
74
|
+
* Directory for the snapshot artifact. Default
|
|
75
|
+
* `~/.local/supermachine-snapshots`.
|
|
76
|
+
*/
|
|
77
|
+
snapshotsDir?: string
|
|
78
|
+
/**
|
|
79
|
+
* Files to bake into the delta layer at fixed guest paths.
|
|
80
|
+
* Bytes read from `hostPath` at bake time; the host file's
|
|
81
|
+
* contents are folded into the snapshot's input-hash so any
|
|
82
|
+
* change re-bakes. Common pattern: ship per-snapshot
|
|
83
|
+
* kernel modules, certs, configuration files. Maps to
|
|
84
|
+
* `OciImageBuilder::with_extra_file`.
|
|
85
|
+
*/
|
|
86
|
+
extraFiles?: Array<ExtraFileSpec>
|
|
87
|
+
/**
|
|
88
|
+
* Stable tag for the warmup callback (see the `warmup`
|
|
89
|
+
* parameter on [`Image.build`]). Folded into the snapshot's
|
|
90
|
+
* cached fingerprint so changing the warmup body invalidates
|
|
91
|
+
* the previous warm snapshot. Default `"default"` — set a
|
|
92
|
+
* versioned tag (`"v1"`, `"v2"`) when you mutate the warmup.
|
|
93
|
+
* Ignored when no warmup function is provided.
|
|
94
|
+
*/
|
|
95
|
+
warmupTag?: string
|
|
96
|
+
/**
|
|
97
|
+
* Post-bake warmup callback. Receives a [`WarmupVm`] bound to a
|
|
98
|
+
* freshly-booted guest; run `vm.exec()` calls to populate state,
|
|
99
|
+
* then return. The bake captures the post-warmup snapshot.
|
|
100
|
+
*
|
|
101
|
+
* The Vm is invalidated after the callback returns.
|
|
102
|
+
*/
|
|
103
|
+
warmup?: (vm: WarmupVm) => Promise<void>
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
export interface PoolOptions {
|
|
107
|
+
/**
|
|
108
|
+
* Minimum idle VMs to keep warm. Spawned eagerly at pool
|
|
109
|
+
* build time. Default 1.
|
|
110
|
+
*/
|
|
111
|
+
min?: number
|
|
112
|
+
/**
|
|
113
|
+
* Maximum total VMs (active + idle). Pool grows up to this
|
|
114
|
+
* under load. Default 1.
|
|
115
|
+
*/
|
|
116
|
+
max?: number
|
|
117
|
+
/**
|
|
118
|
+
* Max wait for `acquire()` when the pool is saturated.
|
|
119
|
+
* Default 60_000 (60 s).
|
|
120
|
+
*
|
|
121
|
+
* Special value: pass `0` for "no timeout — block forever".
|
|
122
|
+
* Useful for batch workloads that prefer waiting over
|
|
123
|
+
* failing. Mirrors `PoolBuilder::no_acquire_timeout()` on the
|
|
124
|
+
* Rust side.
|
|
125
|
+
*/
|
|
126
|
+
acquireTimeoutMs?: number
|
|
127
|
+
/**
|
|
128
|
+
* Idle VM lifetime before janitor evicts above `min`. Defaults
|
|
129
|
+
* to no eviction.
|
|
130
|
+
*/
|
|
131
|
+
idleTimeoutMs?: number
|
|
132
|
+
/** If `true` (default), cycle-restore the VM on release. */
|
|
133
|
+
restoreOnRelease?: boolean
|
|
134
|
+
/**
|
|
135
|
+
* Runtime memory ceiling override for this pool's workers
|
|
136
|
+
* (in MiB). Defaults to the value baked into the snapshot.
|
|
137
|
+
* Pure runtime — doesn't re-bake. Pages are lazy-committed,
|
|
138
|
+
* so raising the ceiling above the baked value doesn't
|
|
139
|
+
* increase host commit unless the guest actually writes to
|
|
140
|
+
* the new pages.
|
|
141
|
+
*/
|
|
142
|
+
memoryMib?: number
|
|
143
|
+
/**
|
|
144
|
+
* Runtime vCPU count override for this pool's workers.
|
|
145
|
+
* Defaults to the value baked into the snapshot.
|
|
146
|
+
*/
|
|
147
|
+
vcpus?: number
|
|
148
|
+
/**
|
|
149
|
+
* Per-worker snapshot-restore timeout (ms). Default 30_000.
|
|
150
|
+
* Bump for slow disks or large RAM snapshots — restore time
|
|
151
|
+
* scales roughly linearly with snapshot size. Forwards to
|
|
152
|
+
* `VmConfig::with_restore_timeout` via PoolBuilder.
|
|
153
|
+
*/
|
|
154
|
+
restoreTimeoutMs?: number
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* Returned by [`Pool.stats`]. Pool observability for monitoring,
|
|
159
|
+
* autoscaling decisions, and capacity tuning.
|
|
160
|
+
*/
|
|
161
|
+
export interface PoolStats {
|
|
162
|
+
/** Total workers the pool has spawned (idle + checked-out). */
|
|
163
|
+
alive: number
|
|
164
|
+
/** Workers currently checked out via `acquire()`. */
|
|
165
|
+
inUse: number
|
|
166
|
+
/** Workers sitting in the idle queue. */
|
|
167
|
+
idle: number
|
|
168
|
+
/**
|
|
169
|
+
* Number of callers currently blocked in `acquire()` waiting
|
|
170
|
+
* for an idle worker to free up.
|
|
171
|
+
*/
|
|
172
|
+
waiting: number
|
|
173
|
+
/** Configured `min` from PoolOptions. */
|
|
174
|
+
min: number
|
|
175
|
+
/** Configured `max` from PoolOptions. */
|
|
176
|
+
max: number
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
/**
|
|
180
|
+
* One file → bytes mapping for `stageFilesMode` (variant of
|
|
181
|
+
* `stageFiles` that also lets you set the guest-side file mode,
|
|
182
|
+
* e.g. 0o755 for shipping executable scripts inline with an exec).
|
|
183
|
+
*/
|
|
184
|
+
export interface StagedFileMode {
|
|
185
|
+
guestPath: string
|
|
186
|
+
bytes: Buffer
|
|
187
|
+
/**
|
|
188
|
+
* Unix file mode (e.g. `0o755`, written as `493` if you can't
|
|
189
|
+
* use octal literals in your JS engine). When `null`, the
|
|
190
|
+
* agent uses 0o644 (same as the plain `stageFiles` entry).
|
|
191
|
+
*/
|
|
192
|
+
mode?: number
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
export interface ExecOptions {
|
|
196
|
+
argv: Array<string>
|
|
197
|
+
/**
|
|
198
|
+
* Files to stage at fixed paths inside the guest before the
|
|
199
|
+
* command runs. Mode defaults to 0o644. Use `stageFilesMode`
|
|
200
|
+
* instead when you need to set the executable bit (or any
|
|
201
|
+
* other mode).
|
|
202
|
+
*/
|
|
203
|
+
stageFiles?: Record<string, Buffer>
|
|
204
|
+
/**
|
|
205
|
+
* Like `stageFiles` but with explicit per-file Unix modes.
|
|
206
|
+
* Useful for shipping executable scripts (`0o755`) or
|
|
207
|
+
* read-only secrets (`0o400`). Entries here are unioned with
|
|
208
|
+
* `stageFiles` — same `guestPath` in both is undefined order;
|
|
209
|
+
* pick one.
|
|
210
|
+
*/
|
|
211
|
+
stageFilesMode?: Array<StagedFileMode>
|
|
212
|
+
timeoutMs?: number
|
|
213
|
+
env?: Record<string, string>
|
|
214
|
+
cwd?: string
|
|
215
|
+
chain?: Array<string>
|
|
216
|
+
/**
|
|
217
|
+
* Allocate a pseudo-terminal for the guest process. With
|
|
218
|
+
* `tty: true`, stdout/stdin pass through the pty master and
|
|
219
|
+
* stderr is empty (the pty merges fd 1 + fd 2). Use this for
|
|
220
|
+
* interactive REPLs, shells, or any process that expects a
|
|
221
|
+
* real terminal (e.g. progress bars that detect isatty).
|
|
222
|
+
*/
|
|
223
|
+
tty?: boolean
|
|
224
|
+
/**
|
|
225
|
+
* Initial window size for tty mode. Ignored when `tty` is
|
|
226
|
+
* false. Call `ExecChild.resize(cols, rows)` to change it
|
|
227
|
+
* later from the streaming `spawn()` path.
|
|
228
|
+
*/
|
|
229
|
+
winsize?: Winsize
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
/**
|
|
233
|
+
* Terminal window size for `ExecOptions.winsize`. Both fields are
|
|
234
|
+
* in character cells (not pixels). Use 0/0 to let the agent pick
|
|
235
|
+
* a default (80x24 in practice).
|
|
236
|
+
*/
|
|
237
|
+
export interface Winsize {
|
|
238
|
+
cols: number
|
|
239
|
+
rows: number
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
export interface ExecOutput {
|
|
243
|
+
stdout: Buffer
|
|
244
|
+
stderr: Buffer
|
|
245
|
+
exitCode: number
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
/**
|
|
249
|
+
* Result of [`ExecChild.wait`]. Mirrors `ExecOutcome` minus the
|
|
250
|
+
* stdout/stderr buffers (those were already streamed via
|
|
251
|
+
* `readStdout`/`readStderr`).
|
|
252
|
+
*/
|
|
253
|
+
export interface ExecWaitResult {
|
|
254
|
+
/** `-1` if killed by signal / timeout / agent disconnect. */
|
|
255
|
+
exitCode: number
|
|
256
|
+
/**
|
|
257
|
+
* `true` if the process exited because the spawn-time
|
|
258
|
+
* `timeoutMs` watchdog killed it.
|
|
259
|
+
*/
|
|
260
|
+
timedOut: boolean
|
|
261
|
+
/**
|
|
262
|
+
* Peak resident-set size in KiB during the process's life,
|
|
263
|
+
* as reported by the in-guest agent's wait4(rusage). `null`
|
|
264
|
+
* when not reported.
|
|
265
|
+
*/
|
|
266
|
+
peakRssKib?: number
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
/**
|
|
270
|
+
* A baked OCI image. Returned by [`Image.build`] (bakes or
|
|
271
|
+
* cache-hits) and by [`Image.fromSnapshot`].
|
|
272
|
+
*/
|
|
273
|
+
export declare class Image {
|
|
274
|
+
/**
|
|
275
|
+
* Build an image from an OCI reference, or return the cached
|
|
276
|
+
* snapshot if one already exists. Async: runs the bake
|
|
277
|
+
* pipeline on a libuv worker thread.
|
|
278
|
+
*
|
|
279
|
+
* **Cold first-time bake of `alpine:latest` on Apple Silicon
|
|
280
|
+
* takes ~400 ms**. Cache-hit is ~15 ms.
|
|
281
|
+
*
|
|
282
|
+
* `warmup` is an optional async callback that receives a [`Vm`]
|
|
283
|
+
* after the guest is booted. Use it to pre-populate guest
|
|
284
|
+
* state (compile a seed program, warm a page cache) — the
|
|
285
|
+
* bake captures the post-warmup snapshot, so restores land in
|
|
286
|
+
* the warm state. Pair with `warmupTag` in `options` to
|
|
287
|
+
* version-tag the warmup for cache invalidation.
|
|
288
|
+
*
|
|
289
|
+
* The Vm passed to the warmup is invalidated after the
|
|
290
|
+
* callback returns; holding a reference past return is safe
|
|
291
|
+
* (won't crash) but `vm.exec()` will error.
|
|
292
|
+
*
|
|
293
|
+
* We take `warmup` as a separate positional argument rather
|
|
294
|
+
* than as a field on `options` because napi-rs's async-fn
|
|
295
|
+
* support requires all parameters to be `Send`. Plain
|
|
296
|
+
* `JsFunction` isn't `Send`; here we use `AsyncTask` (which
|
|
297
|
+
* splits sync-setup from sync-compute) to keep the JsFunction
|
|
298
|
+
* → TSFn conversion on the JS thread while the bake runs on
|
|
299
|
+
* a worker. The JS shim in index.js wraps this back into a
|
|
300
|
+
* natural `Image.build({...})` API.
|
|
301
|
+
*/
|
|
302
|
+
static build(options: BuildOptions): Promise<Image>
|
|
303
|
+
/**
|
|
304
|
+
* Load an image from a previously-baked snapshot directory or
|
|
305
|
+
* `restore.snap` file path. No bake — just reads metadata.json
|
|
306
|
+
* and validates the snapshot file exists.
|
|
307
|
+
*/
|
|
308
|
+
static fromSnapshot(path: string): Promise<Image>
|
|
309
|
+
/**
|
|
310
|
+
* Create a VM pool for this image. `min`/`max` are the most
|
|
311
|
+
* important — `min=max=N` pre-spawns N VMs eagerly and caps
|
|
312
|
+
* total at N.
|
|
313
|
+
*
|
|
314
|
+
* Memory: each idle VM costs ~3 MiB host phys_footprint
|
|
315
|
+
* (measured). The `memoryMib` build option is a guest-visible
|
|
316
|
+
* ceiling, not host commit.
|
|
317
|
+
*/
|
|
318
|
+
pool(options?: PoolOptions | undefined | null): Promise<Pool>
|
|
319
|
+
/**
|
|
320
|
+
* On-disk snapshot directory backing this Image. Same as
|
|
321
|
+
* `supermachine::Image::snapshot_path` in Rust. Useful for
|
|
322
|
+
* diagnostics, log lines, or chaining a second image off the
|
|
323
|
+
* same snapshot via `Image.fromSnapshot`.
|
|
324
|
+
*/
|
|
325
|
+
get snapshotPath(): string
|
|
326
|
+
/** Guest memory (MiB) as baked into the snapshot's metadata. */
|
|
327
|
+
get memoryMib(): number
|
|
328
|
+
/** vCPU count as baked into the snapshot's metadata. */
|
|
329
|
+
get vcpus(): number
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
export declare class Pool {
|
|
333
|
+
/**
|
|
334
|
+
* Acquire a VM from the pool. Blocks (async) up to
|
|
335
|
+
* `acquireTimeoutMs`. ~0 ms warm-handoff / ~5 ms cycle-restore
|
|
336
|
+
* / ~22 ms spawn-from-disk.
|
|
337
|
+
*/
|
|
338
|
+
acquire(): Promise<Vm>
|
|
339
|
+
/** Best-effort pool shutdown. Pool also shuts down on GC. */
|
|
340
|
+
shutdown(): Promise<void>
|
|
341
|
+
/**
|
|
342
|
+
* Snapshot of the pool's current state. Cheap (~1 µs, just a
|
|
343
|
+
* mutex lock) — safe to poll frequently for monitoring /
|
|
344
|
+
* autoscaling decisions.
|
|
345
|
+
*/
|
|
346
|
+
stats(): PoolStats
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
/**
|
|
350
|
+
* Streaming exec handle returned by [`Vm.spawn`]. Pull-style API:
|
|
351
|
+
* caller polls `readStdout()` / `readStderr()` for chunks, writes
|
|
352
|
+
* to stdin via `writeStdin()`, sends signals via `signal()`, and
|
|
353
|
+
* awaits exit via `wait()`. Mirrors the Rust `ExecChild`.
|
|
354
|
+
*
|
|
355
|
+
* Pull-style was chosen over Node `ReadableStream`/`WritableStream`
|
|
356
|
+
* for two reasons: (1) the underlying Rust types are sync
|
|
357
|
+
* `Read`/`Write`, so wrapping in stream adapters would require
|
|
358
|
+
* per-chunk napi roundtrips anyway, and (2) pull-style is the
|
|
359
|
+
* minimum-surface-area API that covers all use cases (LLM-style
|
|
360
|
+
* streaming output, interactive REPLs, anything you can build
|
|
361
|
+
* with `for await (const chunk of pull()) ...`).
|
|
362
|
+
*/
|
|
363
|
+
export declare class ExecChild {
|
|
364
|
+
/**
|
|
365
|
+
* Write a chunk to the process's stdin. Returns when the
|
|
366
|
+
* bytes have been queued on the host-side socket; the guest
|
|
367
|
+
* agent forwards them to the process asynchronously. Multiple
|
|
368
|
+
* calls append.
|
|
369
|
+
*/
|
|
370
|
+
writeStdin(bytes: Buffer): Promise<void>
|
|
371
|
+
/** Close stdin (send EOF to the process). Idempotent. */
|
|
372
|
+
closeStdin(): Promise<void>
|
|
373
|
+
/**
|
|
374
|
+
* Read up to `maxBytes` (default 64 KiB) from stdout. Returns
|
|
375
|
+
* an empty Buffer when stdout has closed (process exited and
|
|
376
|
+
* drained); the caller's `for await` loop should terminate on
|
|
377
|
+
* `buf.length === 0`.
|
|
378
|
+
*
|
|
379
|
+
* Blocks the libuv worker thread; the JS event loop stays
|
|
380
|
+
* free for other work.
|
|
381
|
+
*/
|
|
382
|
+
readStdout(maxBytes?: number | undefined | null): Promise<Buffer>
|
|
383
|
+
/** Same as [`readStdout`] for stderr. */
|
|
384
|
+
readStderr(maxBytes?: number | undefined | null): Promise<Buffer>
|
|
385
|
+
/**
|
|
386
|
+
* Resize the pty (tty mode only). No-op when the process was
|
|
387
|
+
* spawned without `tty: true` — the guest agent ignores RESIZE
|
|
388
|
+
* frames if no pty is attached. Use this from the JS side to
|
|
389
|
+
* react to host terminal resize events (e.g. SIGWINCH on
|
|
390
|
+
* process.stdout).
|
|
391
|
+
*/
|
|
392
|
+
resize(cols: number, rows: number): Promise<void>
|
|
393
|
+
/**
|
|
394
|
+
* Send a signal to the guest-side process. Common values:
|
|
395
|
+
* 1=SIGHUP, 2=SIGINT, 9=SIGKILL, 15=SIGTERM.
|
|
396
|
+
*/
|
|
397
|
+
signal(signum: number): Promise<void>
|
|
398
|
+
/**
|
|
399
|
+
* Wait for the guest-side process to exit and return its
|
|
400
|
+
* status. Consumes the underlying ExecChild — subsequent
|
|
401
|
+
* calls error with "already waited". Drains any unread
|
|
402
|
+
* stdout/stderr (caller should pull them out FIRST if they
|
|
403
|
+
* care about full output).
|
|
404
|
+
*/
|
|
405
|
+
wait(): Promise<ExecWaitResult>
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
/**
|
|
409
|
+
* VM handle. Drop or `release()` to return to the pool. With Node
|
|
410
|
+
* 20+, use the `using` keyword + `Symbol.asyncDispose`.
|
|
411
|
+
*/
|
|
412
|
+
export declare class Vm {
|
|
413
|
+
/** Run a process inside the guest via the in-guest exec agent. */
|
|
414
|
+
exec(options: ExecOptions): Promise<ExecOutput>
|
|
415
|
+
/** Return the VM to the pool. Idempotent. */
|
|
416
|
+
release(): Promise<void>
|
|
417
|
+
/**
|
|
418
|
+
* Alias for `release()`. Wired up to `Symbol.asyncDispose` in
|
|
419
|
+
* the JS shim for the TC39 explicit-resource-management
|
|
420
|
+
* `using` keyword (Node 20+).
|
|
421
|
+
*/
|
|
422
|
+
dispose(): Promise<void>
|
|
423
|
+
/**
|
|
424
|
+
* Write `bytes` to `path` inside the guest. Native vsock RPC,
|
|
425
|
+
* ~100 µs round-trip. Complement to `exec({stageFiles})` —
|
|
426
|
+
* use this when you want to drop a file without running a
|
|
427
|
+
* command (or between commands on the same vm).
|
|
428
|
+
*
|
|
429
|
+
* 4 MiB default cap on file size; stream larger files via
|
|
430
|
+
* `exec` with `stageFiles` instead.
|
|
431
|
+
*/
|
|
432
|
+
writeFile(path: string, bytes: Buffer): Promise<void>
|
|
433
|
+
/**
|
|
434
|
+
* Read `path` from inside the guest, return bytes. Native
|
|
435
|
+
* vsock RPC, ~100 µs round-trip. 4 MiB default cap; stream
|
|
436
|
+
* larger files via `exec` + redirect to a host path.
|
|
437
|
+
*/
|
|
438
|
+
readFile(path: string): Promise<Buffer>
|
|
439
|
+
/**
|
|
440
|
+
* Spawn a process inside the guest and return a streaming
|
|
441
|
+
* [`ExecChild`] handle. Unlike `exec()` which collects
|
|
442
|
+
* stdout/stderr into Buffers, `spawn()` lets you write to
|
|
443
|
+
* stdin / read from stdout/stderr incrementally — useful for
|
|
444
|
+
* LLM-style streaming, long-running daemons, interactive REPLs.
|
|
445
|
+
*
|
|
446
|
+
* Important: ExecOptions.timeoutMs is IGNORED in spawn mode —
|
|
447
|
+
* the caller controls cancellation via `child.signal(9)`. The
|
|
448
|
+
* timeout watchdog only applies to the collect-mode `exec()`.
|
|
449
|
+
*/
|
|
450
|
+
spawn(options: ExecOptions): Promise<ExecChild>
|
|
451
|
+
/**
|
|
452
|
+
* Capture a snapshot of this VM's current state and return a
|
|
453
|
+
* new `Image` pointing at it. Equivalent to `Vm::snapshot` in
|
|
454
|
+
* the Rust crate. The guest is paused for the capture
|
|
455
|
+
* (typically 10s of ms; bounded by disk write time for large
|
|
456
|
+
* RAM). The Vm remains usable after — handy for the
|
|
457
|
+
* "warm up + snapshot + keep working" pattern.
|
|
458
|
+
*
|
|
459
|
+
* Returns a fresh Image; build a pool from it via `image.pool()`
|
|
460
|
+
* to spawn workers that restore from the captured state.
|
|
461
|
+
*/
|
|
462
|
+
snapshot(destDir: string): Promise<Image>
|
|
463
|
+
/**
|
|
464
|
+
* Send `signum` to the guest's workload PID-1 (the process
|
|
465
|
+
* the image's CMD/ENTRYPOINT launched at boot). Mirrors
|
|
466
|
+
* `supermachine::Vm::workload_signal`.
|
|
467
|
+
*
|
|
468
|
+
* Distinct from `ExecChild.signal`, which targets a process
|
|
469
|
+
* spawned via `vm.spawn()`. Use this for graceful service
|
|
470
|
+
* shutdown of baked service images (e.g. SIGTERM to nginx
|
|
471
|
+
* before tearing down the VM).
|
|
472
|
+
*/
|
|
473
|
+
workloadSignal(signum: number): Promise<void>
|
|
474
|
+
/**
|
|
475
|
+
* On-disk path of this Vm's per-acquire vsock mux socket.
|
|
476
|
+
* Stable for the lifetime of the Vm; goes away on `release()`.
|
|
477
|
+
* Use this as an escape hatch when you want to bring your own
|
|
478
|
+
* client (e.g. open a raw UnixStream from `node:net` and speak
|
|
479
|
+
* a custom protocol to a workload listening inside the guest).
|
|
480
|
+
*
|
|
481
|
+
* Throws if called on the warmup vm — the bake driver owns
|
|
482
|
+
* the warmup vm's sockets.
|
|
483
|
+
*/
|
|
484
|
+
get vsockPath(): string
|
|
485
|
+
/**
|
|
486
|
+
* On-disk path of this Vm's per-acquire exec control socket.
|
|
487
|
+
* Same lifetime as `vsockPath`. Mostly an escape hatch for
|
|
488
|
+
* users wiring up a non-libuv RPC client; the napi binding's
|
|
489
|
+
* own `exec`/`spawn`/`writeFile`/`readFile` go through this
|
|
490
|
+
* internally.
|
|
491
|
+
*/
|
|
492
|
+
get execPath(): string
|
|
493
|
+
/**
|
|
494
|
+
* Bind `127.0.0.1:hostPort` and proxy connections into the
|
|
495
|
+
* guest's vsock mux. Returns a [`TcpForwarder`] handle; drop
|
|
496
|
+
* it (or call `forwarder.stop()`) to stop accepting new
|
|
497
|
+
* connections. In-flight connections survive `stop()` and
|
|
498
|
+
* close naturally.
|
|
499
|
+
*
|
|
500
|
+
* Pass `hostPort = 0` to let the OS pick a free port; read
|
|
501
|
+
* the actual bound port back via `forwarder.localAddr`.
|
|
502
|
+
*
|
|
503
|
+
* Note: `guestPort` is currently advisory. The Rust crate's
|
|
504
|
+
* `expose_tcp` ignores it and routes all forwarded
|
|
505
|
+
* connections into whatever the in-guest TSI mux accepts;
|
|
506
|
+
* per-guest-port routing is on the roadmap. Pass the port
|
|
507
|
+
* you semantically want — it's plumbed through so the
|
|
508
|
+
* signature stays stable when the routing fix lands.
|
|
509
|
+
*/
|
|
510
|
+
exposeTcp(hostPort: number, guestPort: number): Promise<TcpForwarder>
|
|
511
|
+
}
|
|
512
|
+
|
|
513
|
+
/**
|
|
514
|
+
* Active TCP→vsock forwarder. Returned by [`Vm.exposeTcp`]; owns
|
|
515
|
+
* the host-side TcpListener accept-loop thread. Drop it (or call
|
|
516
|
+
* `stop()`) to stop accepting new connections. In-flight
|
|
517
|
+
* connections continue independently until they close naturally.
|
|
518
|
+
*/
|
|
519
|
+
export declare class TcpForwarder {
|
|
520
|
+
/**
|
|
521
|
+
* The address the forwarder is bound to, e.g. `"127.0.0.1:54321"`.
|
|
522
|
+
* Useful when you asked for `hostPort = 0` and want the
|
|
523
|
+
* OS-assigned port back.
|
|
524
|
+
*/
|
|
525
|
+
get localAddr(): string
|
|
526
|
+
/**
|
|
527
|
+
* Stop accepting new connections. Idempotent. Equivalent to
|
|
528
|
+
* dropping the forwarder, but returns when the accept thread
|
|
529
|
+
* has actually exited (vs Drop, which detaches the join).
|
|
530
|
+
*/
|
|
531
|
+
stop(): Promise<void>
|
|
532
|
+
}
|