@eryx-org/eryx 0.0.0 → 0.15.1

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.
Files changed (63) hide show
  1. package/README.md +281 -4
  2. package/eryx-sandbox.conditional-host-import-0.wasm +0 -0
  3. package/eryx-sandbox.conditional-host-import-1.wasm +0 -0
  4. package/eryx-sandbox.conditional-suspending-1-i32-to-i32.wasm +0 -0
  5. package/eryx-sandbox.core.wasm +0 -0
  6. package/eryx-sandbox.core10.wasm +0 -0
  7. package/eryx-sandbox.core11.wasm +0 -0
  8. package/eryx-sandbox.core12.wasm +0 -0
  9. package/eryx-sandbox.core13.wasm +0 -0
  10. package/eryx-sandbox.core2.wasm +0 -0
  11. package/eryx-sandbox.core3.wasm +0 -0
  12. package/eryx-sandbox.core4.wasm +0 -0
  13. package/eryx-sandbox.core5.wasm +0 -0
  14. package/eryx-sandbox.core6.wasm +0 -0
  15. package/eryx-sandbox.core7.wasm +0 -0
  16. package/eryx-sandbox.core8.wasm +0 -0
  17. package/eryx-sandbox.core9.wasm +0 -0
  18. package/eryx-sandbox.d.ts +185 -0
  19. package/eryx-sandbox.js +55329 -0
  20. package/index.d.ts +331 -0
  21. package/index.js +698 -0
  22. package/instance.js +174 -0
  23. package/interfaces/eryx-net-tcp.d.ts +39 -0
  24. package/interfaces/eryx-net-tls.d.ts +33 -0
  25. package/interfaces/wasi-cli-environment.d.ts +3 -0
  26. package/interfaces/wasi-cli-exit.d.ts +3 -0
  27. package/interfaces/wasi-cli-stderr.d.ts +3 -0
  28. package/interfaces/wasi-cli-stdin.d.ts +3 -0
  29. package/interfaces/wasi-cli-stdout.d.ts +3 -0
  30. package/interfaces/wasi-cli-terminal-input.d.ts +8 -0
  31. package/interfaces/wasi-cli-terminal-output.d.ts +8 -0
  32. package/interfaces/wasi-cli-terminal-stderr.d.ts +3 -0
  33. package/interfaces/wasi-cli-terminal-stdin.d.ts +3 -0
  34. package/interfaces/wasi-cli-terminal-stdout.d.ts +3 -0
  35. package/interfaces/wasi-clocks-monotonic-clock.d.ts +8 -0
  36. package/interfaces/wasi-clocks-wall-clock.d.ts +7 -0
  37. package/interfaces/wasi-filesystem-preopens.d.ts +3 -0
  38. package/interfaces/wasi-filesystem-types.d.ts +288 -0
  39. package/interfaces/wasi-io-error.d.ts +8 -0
  40. package/interfaces/wasi-io-poll.d.ts +10 -0
  41. package/interfaces/wasi-io-streams.d.ts +51 -0
  42. package/interfaces/wasi-random-random.d.ts +2 -0
  43. package/interfaces/wasi-sockets-instance-network.d.ts +3 -0
  44. package/interfaces/wasi-sockets-ip-name-lookup.d.ts +21 -0
  45. package/interfaces/wasi-sockets-network.d.ts +92 -0
  46. package/interfaces/wasi-sockets-tcp-create-socket.d.ts +8 -0
  47. package/interfaces/wasi-sockets-tcp.d.ts +127 -0
  48. package/interfaces/wasi-sockets-udp-create-socket.d.ts +8 -0
  49. package/interfaces/wasi-sockets-udp.d.ts +93 -0
  50. package/package.json +69 -3
  51. package/python-stdlib.tar.gz +0 -0
  52. package/shims/callbacks.d.ts +45 -0
  53. package/shims/callbacks.js +469 -0
  54. package/shims/ip.js +46 -0
  55. package/shims/net-fetch.js +264 -0
  56. package/shims/net-node.js +236 -0
  57. package/shims/net.d.ts +84 -0
  58. package/shims/net.js +260 -0
  59. package/shims/preview2-node.js +35 -0
  60. package/shims/raw-json.js +111 -0
  61. package/shims/sockets.js +53 -0
  62. package/stdlib-loader.js +174 -0
  63. package/worker.js +100 -0
package/README.md CHANGED
@@ -1,7 +1,284 @@
1
1
  # @eryx-org/eryx
2
2
 
3
- A Python sandbox powered by WebAssembly, for browser and Node.js. This is the
4
- new name of [`@bsull/eryx`](https://www.npmjs.com/package/@bsull/eryx).
3
+ A Python sandbox powered by WebAssembly, for browser and Node.js.
5
4
 
6
- This 0.0.0 is a placeholder, published so the release workflow could be set
7
- up; it has no code. Use the latest version.
5
+ Eryx runs **CPython 3.14** inside a WASM sandbox with full isolation — no network, no filesystem, no system access unless you explicitly allow it. Variables persist across calls, state can be snapshotted/restored, and execution can be traced line-by-line.
6
+
7
+ ## Install
8
+
9
+ ```bash
10
+ npm install @eryx-org/eryx
11
+ ```
12
+
13
+ **Requirements:** Chrome 133+ or Node.js 24+ (requires [JSPI](https://v8.dev/blog/jspi); Node.js 24–25 need `--experimental-wasm-jspi`, Node.js 26+ has it on by default).
14
+
15
+ ## Usage
16
+
17
+ ```js
18
+ import { Sandbox } from "@eryx-org/eryx";
19
+
20
+ const sandbox = new Sandbox();
21
+ const result = await sandbox.execute('print("Hello from Python!")');
22
+ console.log(result.stdout); // "Hello from Python!"
23
+ ```
24
+
25
+ ### Returning a structured result
26
+
27
+ Assign a variable named `result` and it is JSON-serialized and returned as
28
+ `result.result` — a structured channel separate from `stdout`:
29
+
30
+ ```js
31
+ const result = await sandbox.execute('result = {"answer": 42, "items": [1, 2, 3]}');
32
+ console.log(result.result); // { answer: 42, items: [ 1, 2, 3 ] }
33
+ ```
34
+
35
+ If the value is not JSON-serializable, `result.result` is `undefined` and
36
+ `result.resultError` explains why (execution still succeeds). Use
37
+ `sandbox.setResultVariable("name")` to capture a different variable name.
38
+
39
+ ### Persistent state
40
+
41
+ Variables, functions, and imports persist across `execute()` calls:
42
+
43
+ ```js
44
+ await sandbox.execute("x = 42");
45
+ await sandbox.execute("import math");
46
+ const result = await sandbox.execute("print(math.sqrt(x))");
47
+ console.log(result.stdout); // "6.48074069840786"
48
+ ```
49
+
50
+ ### Snapshots
51
+
52
+ Save and restore interpreter state:
53
+
54
+ ```js
55
+ await sandbox.execute("data = [1, 2, 3]");
56
+ const snapshot = await sandbox.snapshotState();
57
+
58
+ await sandbox.clearState();
59
+ await sandbox.restoreState(snapshot);
60
+
61
+ const result = await sandbox.execute("print(data)");
62
+ console.log(result.stdout); // "[1, 2, 3]"
63
+ ```
64
+
65
+ ### Callbacks
66
+
67
+ Sandboxed code can `await` functions you provide, called with its keyword
68
+ arguments. They can be async, and what they return must be JSON:
69
+
70
+ ```js
71
+ import { Sandbox } from "@eryx-org/eryx";
72
+
73
+ const sandbox = new Sandbox({
74
+ callbacks: {
75
+ get_weather: {
76
+ description: "Get current weather for a city", // shown by list_callbacks()
77
+ handler: async ({ city }) => ({ temp: 72, unit: "F", city }),
78
+ },
79
+ now: () => Date.now(), // no description
80
+ },
81
+ });
82
+ await sandbox.execute(`
83
+ weather = await get_weather(city="NYC")
84
+ print(f"Temperature in {weather['city']}: {weather['temp']}°{weather['unit']}")
85
+ `);
86
+ ```
87
+
88
+ If a callback throws, the code gets a `RuntimeError` with its message
89
+ (`"RangeError: no such city"`). `BigInt`s are returned exactly, and so is a
90
+ value wrapped in `JSON.rawJSON` (`JSON.rawJSON("1.0")` stays a float).
91
+
92
+ This is the same `callbacks` option as eryx.run's client,
93
+ [`@eryx-org/eryx-run`](https://www.npmjs.com/package/@eryx-org/eryx-run),
94
+ which runs the code on eryx.run instead. Both share their error classes and
95
+ `ExecuteResult`, so code written against one works with the other.
96
+
97
+ `traceHandler` and `outputHandler` can be set per sandbox too, or for every
98
+ sandbox with `setTraceHandler()` and `setOutputHandler()`.
99
+
100
+ ### Networking
101
+
102
+ Networking is off by default. Enable it with a host policy (same rules as the Rust crate's `NetConfig`; localhost and private ranges stay blocked unless you override `blockedHosts`, IP addresses are checked against `blockedNetworks`, and in Node.js so are the addresses a name resolves to, with `allowedNetworks` and `internalHosts` as exceptions). At most `maxConnections` (default 10) are open at once, timeouts are capped by `connectTimeoutMs` and `ioTimeoutMs`, and connections are closed when each call into the sandbox finishes. Browsers resolve names themselves, so a name that points at a private address can't be refused there: use `allowedHosts` rather than `allowAllHosts` in browsers.
103
+
104
+ ```js
105
+ import { Sandbox, setNetConfig } from "@eryx-org/eryx";
106
+
107
+ const sandbox = new Sandbox({ netConfig: { allowedHosts: ["api.github.com", "*.example.com"] } });
108
+ await sandbox.execute(`
109
+ import json, urllib.request
110
+ repo = json.load(urllib.request.urlopen("https://api.github.com/repos/eryx-org/eryx"))
111
+ print(repo["stargazers_count"])
112
+ `);
113
+
114
+ // Or set the default that sandboxes created afterwards start with.
115
+ setNetConfig({ allowedHosts: ["api.github.com"] });
116
+ ```
117
+
118
+ Each sandbox has its own policy: `netConfig` sets it at creation, and `sandbox.setNetConfig()` replaces it for connections opened afterwards. A sandbox without `netConfig` copies the default from the module-level `setNetConfig()` when it is created, so a later `setNetConfig()` call changes only sandboxes created after it (and the default sandbox behind the module-level `execute()`).
119
+
120
+ In Node.js, sandboxed code gets real TCP and TLS sockets. Browsers can't open sockets, so there each request is replayed through `fetch()`: only HTTP(S) works, one request per connection, and the server must allow cross-origin requests.
121
+
122
+ ### Callback replay & suspension
123
+
124
+ Journal callback results so a re-run of the same script replays them instead of calling your handler again, and let a handler suspend execution until it can answer:
125
+
126
+ ```js
127
+ import { Sandbox, SuspendCallback } from "@eryx-org/eryx";
128
+
129
+ const sandbox = new Sandbox({
130
+ callbacks: {
131
+ approve: ({ action }) => {
132
+ if (!isApproved(action)) throw new SuspendCallback("awaiting approval"); // halts the script
133
+ return true;
134
+ },
135
+ },
136
+ });
137
+ const first = await sandbox.executeWithJournal(code);
138
+ if (first.suspended) {
139
+ save(first.journal); // a JSON string; store it as-is to resume later
140
+ }
141
+
142
+ // Later: completed callbacks replay from the journal; the rest run live.
143
+ const resumed = await sandbox.executeWithJournal(code, { journal: load() });
144
+ ```
145
+
146
+ See the [Callback Replay & Suspension guide](https://docs.eryx.run/latest/guide/callback-replay.html) for the matching rules and caveats.
147
+
148
+ ### Streaming output
149
+
150
+ Get stdout/stderr in real-time instead of waiting for execution to complete:
151
+
152
+ ```js
153
+ import { Sandbox, setOutputHandler } from "@eryx-org/eryx";
154
+
155
+ setOutputHandler((stream, data) => {
156
+ const prefix = stream === 0 ? "stdout" : "stderr";
157
+ process.stdout.write(`[${prefix}] ${data}`);
158
+ });
159
+
160
+ const sandbox = new Sandbox();
161
+ await sandbox.execute(`
162
+ for i in range(5):
163
+ print(f"Step {i}")
164
+ `);
165
+ ```
166
+
167
+ ### Errors
168
+
169
+ A run that fails rejects with the same errors as eryx.run's client: code that
170
+ raises rejects with a `PythonExceptionError`, whose `message` is the
171
+ traceback and whose `stdout` and `stderr` hold the output before it, and a
172
+ run past `timeoutMs` with a `TimeoutError`. Both are `EryxError`s, and say
173
+ how long the run took (`durationMs`) and how many callback calls it made
174
+ (`callbackInvocations`), as a result does.
175
+
176
+ ```js
177
+ import { PythonExceptionError } from "@eryx-org/eryx";
178
+
179
+ try {
180
+ await sandbox.execute("raise ValueError('bad input')");
181
+ } catch (e) {
182
+ if (e instanceof PythonExceptionError) console.log(e.stderr); // ends with the traceback
183
+ }
184
+ ```
185
+
186
+ ### Timeouts and memory
187
+
188
+ Timeouts are opt-in in JavaScript. Unlike the Rust crate and the Python bindings, which stop an execution after 30 seconds by default, nothing interrupts a call here unless you ask, so `while True: pass` never returns. Pass `timeoutMs` to run the sandbox in its own Worker (`worker_threads` in Node.js) that is terminated when a call runs too long:
189
+
190
+ ```js
191
+ import { Sandbox, TimeoutError } from "@eryx-org/eryx";
192
+
193
+ const sandbox = new Sandbox({ timeoutMs: 5_000 });
194
+ try {
195
+ await sandbox.execute("while True: pass");
196
+ } catch (e) {
197
+ console.log(e instanceof TimeoutError); // true
198
+ }
199
+ ```
200
+
201
+ The call rejects with a `TimeoutError` (or `executeWithJournal()` reports it as `outcome.error`) and the sandbox starts over with fresh Python state; the next successful result has `stateWasReset: true`. Callbacks, output and networking still run on the creating thread. The Worker costs about 70 MB on top of the sandbox's own memory, and the sandbox's `_fileTree` isn't available. `close()` terminates the Worker at once; otherwise it lives until the sandbox is garbage collected.
202
+
203
+ There is no memory limit, with or without `timeoutMs` (the Rust crate and the Python bindings cap memory at 128 MB by default). A sandbox's memory grows as its code allocates, up to the WebAssembly 4 GiB maximum or what the JavaScript engine allows, and its in-memory filesystem has no size cap either. Run untrusted code that might allocate without bound in a process you can afford to lose.
204
+
205
+ ### Node.js and the WASI shims
206
+
207
+ Under Node.js, eryx loads the in-memory (browser) build of `@bytecodealliance/preview2-shim`, because the Node.js build backs WASI with the real filesystem. Each sandbox gets its own in-memory filesystem, so state set through the shim's module-wide functions (such as `_setFileData()`) never reaches a sandbox.
208
+
209
+ ### Vite / webpack
210
+
211
+ The package works with Vite and webpack. For Vite, you'll need cross-origin isolation headers for `SharedArrayBuffer`:
212
+
213
+ ```js
214
+ // vite.config.ts
215
+ export default defineConfig({
216
+ server: {
217
+ headers: {
218
+ "Cross-Origin-Opener-Policy": "same-origin",
219
+ "Cross-Origin-Embedder-Policy": "require-corp",
220
+ },
221
+ },
222
+ });
223
+ ```
224
+
225
+ ## API
226
+
227
+ ### `Sandbox`
228
+
229
+ | Method | Returns | Description |
230
+ |--------|---------|-------------|
231
+ | `new Sandbox(options?)` | `Sandbox` | Create an isolated sandbox; `options` can set its `callbacks`, `traceHandler`, `outputHandler`, `netConfig` and `timeoutMs` |
232
+ | `execute(code)` | `Promise<ExecuteResult>` | Run Python code: `stdout`, `stderr`, `result`, `durationMs`, `callbackInvocations`, ... |
233
+ | `executeWithJournal(code, { journal? })` | `Promise<ReplayOutcome>` | Run with callback journaling/replay |
234
+ | `setResultVariable(name)` | `Promise<void>` | Change the captured result variable |
235
+ | `setNetConfig(config)` | `void` | Replace this sandbox's network policy (`null` disables networking) |
236
+ | `close()` | `void` | Close connections, stop a `timeoutMs` Worker, reject later calls (also `using`) |
237
+ | `snapshotState()` | `Promise<StateSnapshot>` | Serialize interpreter state (`data`) and name the globals left out (`skippedGlobals`) |
238
+ | `restoreState(snapshot)` | `Promise<void>` | Restore from a snapshot or its `data` |
239
+ | `clearState()` | `Promise<void>` | Reset all user state |
240
+
241
+ Each `Sandbox` is its own WebAssembly instance, with its own interpreter, filesystem, network connections, callbacks and journal; code in one can't see another's state. The compiled code is shared, but each instance has its own memory (about 20 MB idle on Node.js 24). Call `sandbox.close()` (or declare it with `using`) when you're done; a sandbox that is only dropped is freed whenever the garbage collector gets to it. The module-level `execute()`, `executeWithJournal()` and `setResultVariable()` use one default sandbox, created on first use.
242
+
243
+ Calls on one sandbox run one at a time, in call order: a call made while another is running waits for it to finish. So don't await `execute()` on the same sandbox from inside one of its callbacks, since it would wait on the execution that called it. Different sandboxes run independently.
244
+
245
+ ### Handlers and errors
246
+
247
+ | Export | Description |
248
+ |----------|-------------|
249
+ | `setTraceHandler(fn)` | Receive line-level execution trace events (default) |
250
+ | `setOutputHandler(fn)` | Receive streaming stdout/stderr (default) |
251
+ | `SuspendCallback` | Throw from a callback to suspend execution |
252
+ | `EryxError`, `PythonExceptionError`, `TimeoutError`, ... | The errors a run rejects with, shared with `@eryx-org/eryx-run` |
253
+
254
+ ## Moving from `@bsull/eryx`
255
+
256
+ This package was `@bsull/eryx`. Apart from the name:
257
+
258
+ - `callbacks` is an object of functions by name. `setCallbacks()`,
259
+ `setCallbackHandler()` and the `callbackHandler` option are gone, and
260
+ callbacks are per sandbox (the module-level `execute()` has none).
261
+ Handlers take the arguments as an object and return a value, not JSON
262
+ text.
263
+ - A callback that throws an `Error` raises in Python, as one that throws
264
+ anything else did; it no longer halts the run. `SuspendCallback` still
265
+ does.
266
+ - Code that raises rejects with a `PythonExceptionError` (`stdout` and
267
+ `stderr` are strings), and `TimeoutError` is `@eryx-org/eryx-run`'s, with
268
+ `message` rather than a `timeoutMs` constructor argument.
269
+ - Results also have `durationMs`, `callbackInvocations` and
270
+ `unsavedVariables` (always empty here).
271
+
272
+ ## How it works
273
+
274
+ Eryx compiles CPython 3.14 to WebAssembly (WASI) using [componentize-py](https://github.com/bytecodealliance/componentize-py), then pre-initializes the interpreter so startup is fast. The JavaScript bindings are generated by [jco](https://github.com/bytecodealliance/jco) and use JSPI for async interop.
275
+
276
+ ## Links
277
+
278
+ - [Documentation](https://docs.eryx.run)
279
+ - [GitHub](https://github.com/eryx-org/eryx)
280
+ - [Live demo](https://demo.eryx.run)
281
+
282
+ ## License
283
+
284
+ MIT OR Apache-2.0
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
@@ -0,0 +1,185 @@
1
+ // world root:component/root
2
+ export interface CallbackInfo {
3
+ name: string,
4
+ description: string,
5
+ parametersSchemaJson: string,
6
+ }
7
+ export interface ExecutionOptions {
8
+ pythonTracing: boolean,
9
+ reuseEmptyCallbacks: boolean,
10
+ }
11
+ export interface ExecuteOutput {
12
+ stdout: Uint8Array,
13
+ stderr: Uint8Array,
14
+ resultJson: string,
15
+ resultError: string,
16
+ }
17
+ export interface ExecuteError {
18
+ message: string,
19
+ stdout: Uint8Array,
20
+ stderr: Uint8Array,
21
+ }
22
+ export interface StateSnapshot {
23
+ data: Uint8Array,
24
+ skippedGlobals: Array<string>,
25
+ }
26
+ import type * as EryxNetTcp from './interfaces/eryx-net-tcp.js'; // eryx:net/tcp@0.1.0
27
+ import type * as EryxNetTls from './interfaces/eryx-net-tls.js'; // eryx:net/tls@0.1.0
28
+ import type * as WasiCliEnvironment from './interfaces/wasi-cli-environment.js'; // wasi:cli/environment@0.2.0
29
+ import type * as WasiCliExit from './interfaces/wasi-cli-exit.js'; // wasi:cli/exit@0.2.0
30
+ import type * as WasiCliStderr from './interfaces/wasi-cli-stderr.js'; // wasi:cli/stderr@0.2.0
31
+ import type * as WasiCliStdin from './interfaces/wasi-cli-stdin.js'; // wasi:cli/stdin@0.2.0
32
+ import type * as WasiCliStdout from './interfaces/wasi-cli-stdout.js'; // wasi:cli/stdout@0.2.0
33
+ import type * as WasiCliTerminalInput from './interfaces/wasi-cli-terminal-input.js'; // wasi:cli/terminal-input@0.2.0
34
+ import type * as WasiCliTerminalOutput from './interfaces/wasi-cli-terminal-output.js'; // wasi:cli/terminal-output@0.2.0
35
+ import type * as WasiCliTerminalStderr from './interfaces/wasi-cli-terminal-stderr.js'; // wasi:cli/terminal-stderr@0.2.0
36
+ import type * as WasiCliTerminalStdin from './interfaces/wasi-cli-terminal-stdin.js'; // wasi:cli/terminal-stdin@0.2.0
37
+ import type * as WasiCliTerminalStdout from './interfaces/wasi-cli-terminal-stdout.js'; // wasi:cli/terminal-stdout@0.2.0
38
+ import type * as WasiClocksMonotonicClock from './interfaces/wasi-clocks-monotonic-clock.js'; // wasi:clocks/monotonic-clock@0.2.0
39
+ import type * as WasiClocksWallClock from './interfaces/wasi-clocks-wall-clock.js'; // wasi:clocks/wall-clock@0.2.0
40
+ import type * as WasiFilesystemPreopens from './interfaces/wasi-filesystem-preopens.js'; // wasi:filesystem/preopens@0.2.0
41
+ import type * as WasiFilesystemTypes from './interfaces/wasi-filesystem-types.js'; // wasi:filesystem/types@0.2.0
42
+ import type * as WasiIoError from './interfaces/wasi-io-error.js'; // wasi:io/error@0.2.0
43
+ import type * as WasiIoPoll from './interfaces/wasi-io-poll.js'; // wasi:io/poll@0.2.0
44
+ import type * as WasiIoStreams from './interfaces/wasi-io-streams.js'; // wasi:io/streams@0.2.0
45
+ import type * as WasiRandomRandom from './interfaces/wasi-random-random.js'; // wasi:random/random@0.2.0
46
+ import type * as WasiSocketsInstanceNetwork from './interfaces/wasi-sockets-instance-network.js'; // wasi:sockets/instance-network@0.2.0
47
+ import type * as WasiSocketsIpNameLookup from './interfaces/wasi-sockets-ip-name-lookup.js'; // wasi:sockets/ip-name-lookup@0.2.0
48
+ import type * as WasiSocketsNetwork from './interfaces/wasi-sockets-network.js'; // wasi:sockets/network@0.2.0
49
+ import type * as WasiSocketsTcpCreateSocket from './interfaces/wasi-sockets-tcp-create-socket.js'; // wasi:sockets/tcp-create-socket@0.2.0
50
+ import type * as WasiSocketsTcp from './interfaces/wasi-sockets-tcp.js'; // wasi:sockets/tcp@0.2.0
51
+ import type * as WasiSocketsUdpCreateSocket from './interfaces/wasi-sockets-udp-create-socket.js'; // wasi:sockets/udp-create-socket@0.2.0
52
+ import type * as WasiSocketsUdp from './interfaces/wasi-sockets-udp.js'; // wasi:sockets/udp@0.2.0
53
+ export interface ImportObject {
54
+ invoke: {
55
+ /**
56
+ * @throws {string} To return the error of the result, throw it, or an `Error` that has it as its `payload`.
57
+ */
58
+ "default"(name: string, argumentsJson: string): Promise<string>,
59
+ },
60
+ sleep: {
61
+ "default"(durationNs: bigint): Promise<void>,
62
+ },
63
+ "list-callbacks": {
64
+ "default"(): Array<CallbackInfo>,
65
+ },
66
+ "get-execution-options": {
67
+ "default"(): ExecutionOptions,
68
+ },
69
+ "report-trace": {
70
+ "default"(lineno: number, eventJson: string, contextJson: string): void,
71
+ },
72
+ "report-output": {
73
+ "default"(streamId: number, data: Uint8Array): void,
74
+ },
75
+ "eryx:net/tcp@0.1.0": typeof EryxNetTcp,
76
+ "eryx:net/tls@0.1.0": typeof EryxNetTls,
77
+ "wasi:cli/environment@0.2.0": typeof WasiCliEnvironment,
78
+ "wasi:cli/exit@0.2.0": typeof WasiCliExit,
79
+ "wasi:cli/stderr@0.2.0": typeof WasiCliStderr,
80
+ "wasi:cli/stdin@0.2.0": typeof WasiCliStdin,
81
+ "wasi:cli/stdout@0.2.0": typeof WasiCliStdout,
82
+ "wasi:cli/terminal-input@0.2.0": typeof WasiCliTerminalInput,
83
+ "wasi:cli/terminal-output@0.2.0": typeof WasiCliTerminalOutput,
84
+ "wasi:cli/terminal-stderr@0.2.0": typeof WasiCliTerminalStderr,
85
+ "wasi:cli/terminal-stdin@0.2.0": typeof WasiCliTerminalStdin,
86
+ "wasi:cli/terminal-stdout@0.2.0": typeof WasiCliTerminalStdout,
87
+ "wasi:clocks/monotonic-clock@0.2.0": typeof WasiClocksMonotonicClock,
88
+ "wasi:clocks/wall-clock@0.2.0": typeof WasiClocksWallClock,
89
+ "wasi:filesystem/preopens@0.2.0": typeof WasiFilesystemPreopens,
90
+ "wasi:filesystem/types@0.2.0": typeof WasiFilesystemTypes,
91
+ "wasi:io/error@0.2.0": typeof WasiIoError,
92
+ "wasi:io/poll@0.2.0": typeof WasiIoPoll,
93
+ "wasi:io/streams@0.2.0": typeof WasiIoStreams,
94
+ "wasi:random/random@0.2.0": typeof WasiRandomRandom,
95
+ "wasi:sockets/instance-network@0.2.0": typeof WasiSocketsInstanceNetwork,
96
+ "wasi:sockets/ip-name-lookup@0.2.0": typeof WasiSocketsIpNameLookup,
97
+ "wasi:sockets/network@0.2.0": typeof WasiSocketsNetwork,
98
+ "wasi:sockets/tcp-create-socket@0.2.0": typeof WasiSocketsTcpCreateSocket,
99
+ "wasi:sockets/tcp@0.2.0": typeof WasiSocketsTcp,
100
+ "wasi:sockets/udp-create-socket@0.2.0": typeof WasiSocketsUdpCreateSocket,
101
+ "wasi:sockets/udp@0.2.0": typeof WasiSocketsUdp,
102
+ }
103
+ export interface Root {
104
+ /**
105
+ * @throws {Error & { payload: ExecuteError }} The error of the result, as the `payload` of the thrown error.
106
+ */
107
+ execute(code: string): Promise<ExecuteOutput>,
108
+ /**
109
+ * @throws {Error & { payload: string }} The error of the result, as the `payload` of the thrown error.
110
+ */
111
+ snapshotState(): Promise<StateSnapshot>,
112
+ /**
113
+ * @throws {Error & { payload: string }} The error of the result, as the `payload` of the thrown error.
114
+ */
115
+ restoreState(data: Uint8Array): Promise<void>,
116
+ clearState(): Promise<void>,
117
+ finalizePreinit(): void,
118
+ setResultVariable(name: string): Promise<void>,
119
+ /** Permanently stop this instance and dispose guest-owned host resources. */
120
+ readonly _util: { stop(): void; whenIdle(): Promise<void>; /** Test whether a value is a declared WIT result error from this instance. */
121
+ isComponentError(value: unknown): value is Error & { readonly payload: unknown }; };
122
+ }
123
+ export type Result<T, E> = { tag: 'ok', val: T } | { tag: 'err', val: E };
124
+
125
+ /**
126
+ * Options accepted by `instantiate`.
127
+ */
128
+ export interface InstantiateOptions {
129
+ /**
130
+ * Called with each trap of this instance as it happens, in whichever
131
+ * task: including one a guest left running, which no call of the host's
132
+ * would otherwise fail for. Not called for stopping the instance, which
133
+ * it may do itself.
134
+ */
135
+ onTrap?: (error: WebAssembly.RuntimeError) => void;
136
+ /** Runtime overrides for this instance. */
137
+ shim?: {
138
+ /** Platform globals used instead of those on `globalThis`. */
139
+ globals?: {
140
+ /**
141
+ * The WebAssembly implementation used by this instance,
142
+ * including by the default `instantiateCore`. Defaults to
143
+ * `globalThis.WebAssembly`.
144
+ */
145
+ WebAssembly?: typeof WebAssembly;
146
+ };
147
+ };
148
+ }
149
+
150
+
151
+ /**
152
+ * Instantiates this component with the provided imports and
153
+ * returns a map of all the exports of the component.
154
+ *
155
+ * This function is intended to be similar to the
156
+ * `WebAssembly.Instantiate` constructor. The second `imports`
157
+ * argument is the "import object" for wasm, except here it
158
+ * uses component-model-layer types instead of core wasm
159
+ * integers/numbers/etc.
160
+ *
161
+ * The first argument to this function, `getCoreModule`, is
162
+ * used to compile core wasm modules within the component.
163
+ * Components are composed of core wasm modules and this callback
164
+ * will be invoked per core wasm module. The caller of this
165
+ * function is responsible for reading the core wasm module
166
+ * identified by `path` and returning its compiled
167
+ * `WebAssembly.Module` object. This would use the
168
+ * `WebAssembly.Module` constructor on the web, for example.
169
+ *
170
+ * The optional `options` argument configures instantiation; see
171
+ * `InstantiateOptions`.
172
+ */
173
+ export function instantiate(
174
+ getCoreModule: (path: string) => WebAssembly.Module,
175
+ imports: ImportObject,
176
+ instantiateCore?: (module: WebAssembly.Module, imports: Record<string, any>) => WebAssembly.Instance,
177
+ options?: InstantiateOptions
178
+ ): Root;
179
+ export function instantiate(
180
+ getCoreModule: (path: string) => WebAssembly.Module | Promise<WebAssembly.Module>,
181
+ imports: ImportObject,
182
+ instantiateCore?: (module: WebAssembly.Module, imports: Record<string, any>) => WebAssembly.Instance | Promise<WebAssembly.Instance>,
183
+ options?: InstantiateOptions
184
+ ): Root | Promise<Root>;
185
+