@polyengine/wasi 0.1.0-pre.g633468a
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 +23 -0
- package/esm/cli.js +160 -0
- package/esm/cli_stdio.js +203 -0
- package/esm/clocks.js +84 -0
- package/esm/filesystem.js +83 -0
- package/esm/filesystem_node.js +463 -0
- package/esm/filesystem_web.js +315 -0
- package/esm/http.js +663 -0
- package/esm/internal/cli_shared.js +26 -0
- package/esm/internal/fs_provider.js +795 -0
- package/esm/internal/sockets_02.js +992 -0
- package/esm/internal/sockets_03.js +969 -0
- package/esm/internal/sockets_platform.js +530 -0
- package/esm/internal/sockets_shared.js +268 -0
- package/esm/io.js +643 -0
- package/esm/mod.js +80 -0
- package/esm/package.json +3 -0
- package/esm/random.js +96 -0
- package/esm/sockets.js +172 -0
- package/package.json +98 -0
- package/types/cli.d.ts +44 -0
- package/types/cli_stdio.d.ts +31 -0
- package/types/clocks.d.ts +8 -0
- package/types/filesystem.d.ts +30 -0
- package/types/filesystem_node.d.ts +16 -0
- package/types/filesystem_web.d.ts +61 -0
- package/types/http.d.ts +169 -0
- package/types/internal/cli_shared.d.ts +26 -0
- package/types/internal/fs_provider.d.ts +174 -0
- package/types/internal/sockets_02.d.ts +37 -0
- package/types/internal/sockets_03.d.ts +12 -0
- package/types/internal/sockets_platform.d.ts +112 -0
- package/types/internal/sockets_shared.d.ts +256 -0
- package/types/io.d.ts +177 -0
- package/types/mod.d.ts +31 -0
- package/types/random.d.ts +17 -0
- package/types/sockets.d.ts +22 -0
|
@@ -0,0 +1,256 @@
|
|
|
1
|
+
import { ComponentException, Stream } from "@polyengine/runtime/embedder";
|
|
2
|
+
import type { NetAddr } from "./sockets_platform.js";
|
|
3
|
+
export type { NetAddr };
|
|
4
|
+
/** `wasi:sockets/types@0.3`'s `ip-address-family` enum. */
|
|
5
|
+
export type IpAddressFamily = "ipv4" | "ipv6";
|
|
6
|
+
/** `ipv4-address` = `tuple<u8, u8, u8, u8>`. */
|
|
7
|
+
export type Ipv4Address = [number, number, number, number];
|
|
8
|
+
/** `ipv6-address` = `tuple<u16 × 8>`. */
|
|
9
|
+
export type Ipv6Address = [
|
|
10
|
+
number,
|
|
11
|
+
number,
|
|
12
|
+
number,
|
|
13
|
+
number,
|
|
14
|
+
number,
|
|
15
|
+
number,
|
|
16
|
+
number,
|
|
17
|
+
number
|
|
18
|
+
];
|
|
19
|
+
export interface Ipv4SocketAddress {
|
|
20
|
+
port: number;
|
|
21
|
+
address: Ipv4Address;
|
|
22
|
+
}
|
|
23
|
+
export interface Ipv6SocketAddress {
|
|
24
|
+
port: number;
|
|
25
|
+
flowInfo: number;
|
|
26
|
+
address: Ipv6Address;
|
|
27
|
+
scopeId: number;
|
|
28
|
+
}
|
|
29
|
+
/** The `ip-socket-address` variant, in `{ kind, value }` form (A10). */
|
|
30
|
+
export type IpSocketAddress = {
|
|
31
|
+
kind: "ipv4";
|
|
32
|
+
value: Ipv4SocketAddress;
|
|
33
|
+
} | {
|
|
34
|
+
kind: "ipv6";
|
|
35
|
+
value: Ipv6SocketAddress;
|
|
36
|
+
};
|
|
37
|
+
/** The address-only `ip-address` variant (ip-name-lookup's vocabulary). */
|
|
38
|
+
export type IpAddress = {
|
|
39
|
+
kind: "ipv4";
|
|
40
|
+
value: Ipv4Address;
|
|
41
|
+
} | {
|
|
42
|
+
kind: "ipv6";
|
|
43
|
+
value: Ipv6Address;
|
|
44
|
+
};
|
|
45
|
+
/** `wasi:sockets/ip-name-lookup@0.3`'s own `error-code` variant. */
|
|
46
|
+
export type NameLookupErrorCode = {
|
|
47
|
+
kind: "access-denied";
|
|
48
|
+
} | {
|
|
49
|
+
kind: "invalid-argument";
|
|
50
|
+
} | {
|
|
51
|
+
kind: "name-unresolvable";
|
|
52
|
+
} | {
|
|
53
|
+
kind: "temporary-resolver-failure";
|
|
54
|
+
} | {
|
|
55
|
+
kind: "permanent-resolver-failure";
|
|
56
|
+
} | {
|
|
57
|
+
kind: "other";
|
|
58
|
+
value?: string;
|
|
59
|
+
};
|
|
60
|
+
/**
|
|
61
|
+
* The `error-code` variant. Every case is listed so callers can switch
|
|
62
|
+
* exhaustively against the real WIT vocabulary.
|
|
63
|
+
*/
|
|
64
|
+
export type SocketErrorCode = {
|
|
65
|
+
kind: "access-denied";
|
|
66
|
+
} | {
|
|
67
|
+
kind: "not-supported";
|
|
68
|
+
} | {
|
|
69
|
+
kind: "invalid-argument";
|
|
70
|
+
} | {
|
|
71
|
+
kind: "out-of-memory";
|
|
72
|
+
} | {
|
|
73
|
+
kind: "timeout";
|
|
74
|
+
} | {
|
|
75
|
+
kind: "invalid-state";
|
|
76
|
+
} | {
|
|
77
|
+
kind: "address-not-bindable";
|
|
78
|
+
} | {
|
|
79
|
+
kind: "address-in-use";
|
|
80
|
+
} | {
|
|
81
|
+
kind: "remote-unreachable";
|
|
82
|
+
} | {
|
|
83
|
+
kind: "connection-refused";
|
|
84
|
+
} | {
|
|
85
|
+
kind: "connection-broken";
|
|
86
|
+
} | {
|
|
87
|
+
kind: "connection-reset";
|
|
88
|
+
} | {
|
|
89
|
+
kind: "connection-aborted";
|
|
90
|
+
} | {
|
|
91
|
+
kind: "datagram-too-large";
|
|
92
|
+
} | {
|
|
93
|
+
kind: "other";
|
|
94
|
+
value?: string;
|
|
95
|
+
};
|
|
96
|
+
/**
|
|
97
|
+
* The datagram payload ceiling, matching wasmtime-wasi's
|
|
98
|
+
* `MAX_UDP_DATAGRAM_SIZE` (`u16::MAX`). Larger sends fail
|
|
99
|
+
* `datagram-too-large` before reaching the OS; receives use a buffer of
|
|
100
|
+
* this size so no datagram the OS delivers is ever truncated.
|
|
101
|
+
*/
|
|
102
|
+
export declare const MAX_UDP_DATAGRAM_SIZE = 65535;
|
|
103
|
+
/**
|
|
104
|
+
* A WIT `err` the branded way (contracts/embedder-api.md, "Error model"):
|
|
105
|
+
* an unbranded throw would become a trap naming the import instead of a
|
|
106
|
+
* guest-visible err.
|
|
107
|
+
*/
|
|
108
|
+
export declare function componentError(payload: SocketErrorCode, detail: string): ComponentException<SocketErrorCode>;
|
|
109
|
+
/** Render the address part of `addr` as a Deno hostname string. */
|
|
110
|
+
export declare function ipHostname(addr: IpSocketAddress): string;
|
|
111
|
+
/**
|
|
112
|
+
* Parse a Deno `NetAddr` back into a WIT `ip-socket-address`.
|
|
113
|
+
*
|
|
114
|
+
* Handles the compressed (`::1`), full, IPv4-embedded (`::ffff:127.0.0.1` —
|
|
115
|
+
* what a dual-stack socket reports for IPv4 senders), and zoned
|
|
116
|
+
* (`fe80::1%3`) hostname spellings. A zone parses as the numeric scope-id
|
|
117
|
+
* when it is numeric and drops to 0 otherwise (interface names are not
|
|
118
|
+
* representable in the WIT shape); flow-info is not observable and is
|
|
119
|
+
* always 0.
|
|
120
|
+
*/
|
|
121
|
+
export declare function parseNetAddr(addr: NetAddr): IpSocketAddress;
|
|
122
|
+
/**
|
|
123
|
+
* Whether `addr` may cross this socket's family boundary: same family, and
|
|
124
|
+
* never an IPv4-mapped or deprecated IPv4-compatible IPv6 address.
|
|
125
|
+
*/
|
|
126
|
+
export declare function isValidAddressFamily(family: IpAddressFamily, addr: IpSocketAddress): boolean;
|
|
127
|
+
export declare function isUnspecified(addr: IpSocketAddress): boolean;
|
|
128
|
+
/** Same endpoint: family, address, and port (udp connected-mode filter). */
|
|
129
|
+
export declare function sameSocketAddress(a: IpSocketAddress, b: IpSocketAddress): boolean;
|
|
130
|
+
/** `e instanceof Deno.errors[name]`, tolerating hosts/versions lacking the class. */
|
|
131
|
+
export declare function isDenoError(e: unknown, name: string): boolean;
|
|
132
|
+
/**
|
|
133
|
+
* Map a platform failure onto the WIT `error-code` vocabulary, mirroring
|
|
134
|
+
* wasmtime-wasi's io-error table where the platform exposes the
|
|
135
|
+
* distinction — Deno's error classes first, then Node-style `code`
|
|
136
|
+
* strings, then the plain-`Error` spellings Deno leaves unclassified. An
|
|
137
|
+
* already-branded error passes through unchanged — the codec and the
|
|
138
|
+
* capability re-detection throw branded errors from inside the same try
|
|
139
|
+
* blocks that guard the platform calls, and re-wrapping one would demote
|
|
140
|
+
* its payload to `other`.
|
|
141
|
+
*/
|
|
142
|
+
export declare function mapPlatformError(e: unknown, what: string): ComponentException<SocketErrorCode>;
|
|
143
|
+
/** `result<_, error-code>` as a value (the payload of tcp send/receive futures). */
|
|
144
|
+
export type SocketResult = {
|
|
145
|
+
kind: "ok";
|
|
146
|
+
} | {
|
|
147
|
+
kind: "err";
|
|
148
|
+
value: SocketErrorCode;
|
|
149
|
+
};
|
|
150
|
+
export declare const RESULT_OK: SocketResult;
|
|
151
|
+
export declare const RESULT_INVALID_STATE: SocketResult;
|
|
152
|
+
/** The err side of a `SocketResult`, mapped from a platform failure. */
|
|
153
|
+
export declare function resultErrOf(e: unknown, what: string): SocketResult;
|
|
154
|
+
export interface SocketsOptions {
|
|
155
|
+
/**
|
|
156
|
+
* Observe every `wasi:sockets` entry point the guest reaches, in call
|
|
157
|
+
* order (`"udp-socket.create"`, `"tcp-socket.connect"`, …). For host-side
|
|
158
|
+
* test assertions — a relay-only scenario can assert zero calls, an exam
|
|
159
|
+
* can read back the guest's exact driving sequence. No default cost: when
|
|
160
|
+
* absent, nothing is recorded.
|
|
161
|
+
*/
|
|
162
|
+
onCall?: (call: string) => void;
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* The host-implemented `udp-socket` resource surface: a plain class with
|
|
166
|
+
* camelCase methods and the WIT `static` as a JS static
|
|
167
|
+
* (contracts/embedder-api.md, "Resources"). The runtime calls
|
|
168
|
+
* `[Symbol.dispose]` when the guest drops its last handle; that closes the
|
|
169
|
+
* OS socket, settling any still-pending `receive` as a branded err.
|
|
170
|
+
*/
|
|
171
|
+
export interface UdpSocket {
|
|
172
|
+
bind(localAddress: IpSocketAddress): void;
|
|
173
|
+
connect(remoteAddress: IpSocketAddress): Promise<void>;
|
|
174
|
+
disconnect(): void;
|
|
175
|
+
send(data: Uint8Array, remoteAddress: IpSocketAddress | undefined): Promise<void>;
|
|
176
|
+
receive(): Promise<[Uint8Array, IpSocketAddress]>;
|
|
177
|
+
getLocalAddress(): IpSocketAddress;
|
|
178
|
+
getRemoteAddress(): IpSocketAddress;
|
|
179
|
+
getAddressFamily(): IpAddressFamily;
|
|
180
|
+
getUnicastHopLimit(): number;
|
|
181
|
+
setUnicastHopLimit(value: number): void;
|
|
182
|
+
getReceiveBufferSize(): bigint;
|
|
183
|
+
setReceiveBufferSize(value: bigint): void;
|
|
184
|
+
getSendBufferSize(): bigint;
|
|
185
|
+
setSendBufferSize(value: bigint): void;
|
|
186
|
+
[Symbol.dispose](): void;
|
|
187
|
+
}
|
|
188
|
+
/** The `udp-socket` resource class a fragment carries. */
|
|
189
|
+
export interface UdpSocketClass {
|
|
190
|
+
create(addressFamily: IpAddressFamily): UdpSocket;
|
|
191
|
+
}
|
|
192
|
+
/**
|
|
193
|
+
* What tcp `send` accepts: the lifted `Stream<u8>` handle the runtime
|
|
194
|
+
* dispatches (its async iterator yields `Uint8Array` chunks), or any
|
|
195
|
+
* natural byte-chunk producer for direct/test use.
|
|
196
|
+
*/
|
|
197
|
+
export type TcpSendSource = Stream<number> | AsyncIterable<Uint8Array | number[]> | Iterable<Uint8Array | number[]>;
|
|
198
|
+
/** What tcp `receive` returns in stream position: chunks of bytes. */
|
|
199
|
+
export type TcpByteStream = AsyncIterable<Uint8Array> | Iterable<Uint8Array>;
|
|
200
|
+
/**
|
|
201
|
+
* What tcp `listen` returns: the perpetual accept stream. `cancel` is the
|
|
202
|
+
* A13 producer-cancellation hook the runtime's pump invokes when the
|
|
203
|
+
* guest drops the stream while the loop is parked in accept(); direct
|
|
204
|
+
* (non-runtime) consumers may call it themselves to stop accepting.
|
|
205
|
+
*/
|
|
206
|
+
export type TcpAcceptStream = AsyncIterable<TcpSocket> & {
|
|
207
|
+
cancel(): void;
|
|
208
|
+
};
|
|
209
|
+
/**
|
|
210
|
+
* The host-implemented `tcp-socket` resource surface (client + listener
|
|
211
|
+
* halves — module header). `send` is a WIT sync func returning
|
|
212
|
+
* `future<result>`: the async method's promise is lowered as the future
|
|
213
|
+
* source (amendment A12), so the guest's call returns immediately and the
|
|
214
|
+
* future settles when transmission completes. `receive`'s tuple carries
|
|
215
|
+
* the byte stream and the future that reports FIN (`ok`) vs abnormal
|
|
216
|
+
* close (`err`). `listen` returns the perpetual accept stream — an
|
|
217
|
+
* async iterable of connected `TcpSocket` resources, lowered as
|
|
218
|
+
* `stream<own<tcp-socket>>` (amendment A13: elements the guest never
|
|
219
|
+
* takes are destroyed, closing their connections). Dropping the guest
|
|
220
|
+
* handle does NOT close a socket with live pumps or a live accept stream
|
|
221
|
+
* (the WIT's shared-ownership note); the OS socket closes when the
|
|
222
|
+
* handle and every derived stream are all retired.
|
|
223
|
+
*/
|
|
224
|
+
export interface TcpSocket {
|
|
225
|
+
bind(localAddress: IpSocketAddress): void;
|
|
226
|
+
connect(remoteAddress: IpSocketAddress): Promise<void>;
|
|
227
|
+
listen(): Promise<TcpAcceptStream>;
|
|
228
|
+
send(data: TcpSendSource): Promise<SocketResult>;
|
|
229
|
+
receive(): [TcpByteStream, Promise<SocketResult>];
|
|
230
|
+
getLocalAddress(): IpSocketAddress;
|
|
231
|
+
getRemoteAddress(): IpSocketAddress;
|
|
232
|
+
getAddressFamily(): IpAddressFamily;
|
|
233
|
+
getIsListening(): boolean;
|
|
234
|
+
setListenBacklogSize(value: bigint): void;
|
|
235
|
+
getKeepAliveEnabled(): boolean;
|
|
236
|
+
setKeepAliveEnabled(value: boolean): void;
|
|
237
|
+
getKeepAliveIdleTime(): bigint;
|
|
238
|
+
setKeepAliveIdleTime(value: bigint): void;
|
|
239
|
+
getKeepAliveInterval(): bigint;
|
|
240
|
+
setKeepAliveInterval(value: bigint): void;
|
|
241
|
+
getKeepAliveCount(): number;
|
|
242
|
+
setKeepAliveCount(value: number): void;
|
|
243
|
+
getHopLimit(): number;
|
|
244
|
+
setHopLimit(value: number): void;
|
|
245
|
+
getReceiveBufferSize(): bigint;
|
|
246
|
+
setReceiveBufferSize(value: bigint): void;
|
|
247
|
+
getSendBufferSize(): bigint;
|
|
248
|
+
setSendBufferSize(value: bigint): void;
|
|
249
|
+
[Symbol.dispose](): void;
|
|
250
|
+
}
|
|
251
|
+
/** The `tcp-socket` resource class a fragment carries. */
|
|
252
|
+
export interface TcpSocketClass {
|
|
253
|
+
create(addressFamily: IpAddressFamily): TcpSocket;
|
|
254
|
+
}
|
|
255
|
+
/** The family's wildcard address, port 0 (tcp listen's implicit bind). */
|
|
256
|
+
export declare function wildcardAddress(family: IpAddressFamily): IpSocketAddress;
|
package/types/io.d.ts
ADDED
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
/** A p2 `stream-error` value (variant): `closed` or `last-operation-failed`. */
|
|
2
|
+
export type StreamErrorValue = {
|
|
3
|
+
kind: "closed";
|
|
4
|
+
} | {
|
|
5
|
+
kind: "last-operation-failed";
|
|
6
|
+
value: IoError;
|
|
7
|
+
};
|
|
8
|
+
/**
|
|
9
|
+
* `wasi:io/error.error` — the generic downcastable error resource
|
|
10
|
+
* (io.wit:23). This shim never produces one organically (streams fail with
|
|
11
|
+
* `closed` only, never `last-operation-failed`); the class exists so the
|
|
12
|
+
* resource *type* is a legal import target and so a future producer of one
|
|
13
|
+
* has somewhere to construct it.
|
|
14
|
+
*/
|
|
15
|
+
export declare class IoError {
|
|
16
|
+
#private;
|
|
17
|
+
constructor(message?: string);
|
|
18
|
+
toDebugString(): string;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* A pollable over host-supplied readiness.
|
|
22
|
+
*
|
|
23
|
+
* WIT-facing surface: `ready()` and `block()` (the latter parks the
|
|
24
|
+
* calling wasm frame when unready — @suspending, embedder-api.md A2:
|
|
25
|
+
* the class prototype is the brand authority).
|
|
26
|
+
*
|
|
27
|
+
* Host-facing surface: the constructor and `waitPromise()`. `ready` must
|
|
28
|
+
* be cheap and side-effect-free; `wait` returns a promise that settles
|
|
29
|
+
* when readiness MAY have changed — block/poll re-check and re-wait in a
|
|
30
|
+
* loop, so spurious wakes are fine and `wait` is called repeatedly (return
|
|
31
|
+
* the CURRENT epoch's promise each call; the promise-swap pattern — settle
|
|
32
|
+
* and re-arm on every event — is the intended producer shape). The default
|
|
33
|
+
* (no arguments) is an always-ready pollable, the honest shape for
|
|
34
|
+
* type-only linkage and never-backpressured sinks.
|
|
35
|
+
*/
|
|
36
|
+
export declare class Pollable {
|
|
37
|
+
#private;
|
|
38
|
+
constructor(ready?: () => boolean, wait?: () => Promise<void>);
|
|
39
|
+
/**
|
|
40
|
+
* A pollable that becomes ready at `deadline` (nanoseconds on the
|
|
41
|
+
* caller's clock). One in-flight sleep is shared by concurrent waiters
|
|
42
|
+
* and RE-ARMED after every settle with the delta recomputed:
|
|
43
|
+
* `ready()` consults the clock, so an early-firing sleep (timer slop,
|
|
44
|
+
* or the engine's setTimeout ceiling below) hands the wait loop a
|
|
45
|
+
* fresh sleep for the remainder instead of a permanently-resolved
|
|
46
|
+
* promise — the cached-forever arm was a hot microtask livelock for
|
|
47
|
+
* any deadline past the ceiling (block/poll re-check `ready()` and
|
|
48
|
+
* re-await; awaiting an already-settled promise never yields to the
|
|
49
|
+
* timer that would make it ready).
|
|
50
|
+
*
|
|
51
|
+
* Engines clamp setTimeout delays above 2^31-1 ms to ~0 (node/Deno
|
|
52
|
+
* warn and use 1 ms), so far deadlines sleep in ceiling-sized chunks;
|
|
53
|
+
* each chunk end re-checks the clock and re-arms.
|
|
54
|
+
*/
|
|
55
|
+
static timer(deadlineNs: bigint, nowNs: () => bigint): Pollable;
|
|
56
|
+
ready(): boolean;
|
|
57
|
+
/** Parks the calling wasm frame until ready (sync fast path when
|
|
58
|
+
* already ready — no suspension, per-declaration marking only adds the
|
|
59
|
+
* engine's continuation hop). */
|
|
60
|
+
block(): void | Promise<void>;
|
|
61
|
+
/** Host-facing (not part of the WIT resource surface): the current
|
|
62
|
+
* epoch's wake promise, raced by `poll`. */
|
|
63
|
+
waitPromise(): Promise<void>;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* `wasi:io/poll.poll` — indices of the ready pollables, parking the
|
|
67
|
+
* calling frame until at least one is ready. Sync fast path: if anything
|
|
68
|
+
* is ready right now, the indices return without a suspension.
|
|
69
|
+
*
|
|
70
|
+
* The explicit annotation is JSR's no-slow-types rule (the `suspending`
|
|
71
|
+
* wrapper would otherwise leave this public symbol's type inferred).
|
|
72
|
+
*/
|
|
73
|
+
export declare const poll: (pollables: readonly Pollable[]) => number[] | Promise<number[]>;
|
|
74
|
+
/**
|
|
75
|
+
* Buffer-backed input stream: serves `read`/`blocking-read` synchronously
|
|
76
|
+
* from an in-memory buffer supplied at construction (default empty,
|
|
77
|
+
* matching stdin's default in this package). Blocking degenerates to the
|
|
78
|
+
* sync read because the buffer is always immediately available.
|
|
79
|
+
*/
|
|
80
|
+
export declare class InputStream {
|
|
81
|
+
#private;
|
|
82
|
+
constructor(buf?: Uint8Array);
|
|
83
|
+
read(len: bigint): Uint8Array;
|
|
84
|
+
/** Park-capable (A14): the buffer-backed base never parks. */
|
|
85
|
+
blockingRead(len: bigint): Uint8Array | Promise<Uint8Array>;
|
|
86
|
+
skip(len: bigint): bigint;
|
|
87
|
+
/** Park-capable (A14): the buffer-backed base never parks. */
|
|
88
|
+
blockingSkip(len: bigint): bigint | Promise<bigint>;
|
|
89
|
+
subscribe(): Pollable;
|
|
90
|
+
[Symbol.dispose](): void;
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Buffer-backed output stream over a byte sink. `checkWrite` always
|
|
94
|
+
* reports a large permit (the sink never truly backs up), so the
|
|
95
|
+
* synchronous fast path is always taken and `blocking-*` methods
|
|
96
|
+
* degenerate to their non-blocking counterparts.
|
|
97
|
+
*/
|
|
98
|
+
export declare class OutputStream {
|
|
99
|
+
#private;
|
|
100
|
+
constructor(sink: (chunk: Uint8Array) => void);
|
|
101
|
+
checkWrite(): bigint;
|
|
102
|
+
write(contents: Uint8Array): void;
|
|
103
|
+
/** Park-capable (A14): the never-backpressured base never parks. */
|
|
104
|
+
blockingWriteAndFlush(contents: Uint8Array): void | Promise<void>;
|
|
105
|
+
flush(): void;
|
|
106
|
+
/** Park-capable (A14): the never-backpressured base never parks. */
|
|
107
|
+
blockingFlush(): void | Promise<void>;
|
|
108
|
+
subscribe(): Pollable;
|
|
109
|
+
writeZeroes(len: bigint): void;
|
|
110
|
+
/** Park-capable (A14): the never-backpressured base never parks. */
|
|
111
|
+
blockingWriteZeroesAndFlush(len: bigint): void | Promise<void>;
|
|
112
|
+
splice(src: InputStream, len: bigint): bigint;
|
|
113
|
+
/** Park-capable (A14): the never-backpressured base never parks. */
|
|
114
|
+
blockingSplice(src: InputStream, len: bigint): bigint | Promise<bigint>;
|
|
115
|
+
[Symbol.dispose](): void;
|
|
116
|
+
}
|
|
117
|
+
/** Default high-water mark for the async-backed streams below: how many
|
|
118
|
+
* buffered bytes pause a `FedInputStream`'s feed, and the byte budget a
|
|
119
|
+
* `SinkOutputStream`'s `check-write` reports. */
|
|
120
|
+
export declare const STREAM_HIGH_WATER = 65536;
|
|
121
|
+
/** An async byte sink; the returned promise settling = the chunk drained. */
|
|
122
|
+
export type ByteSink = (chunk: Uint8Array) => void | Promise<void>;
|
|
123
|
+
/**
|
|
124
|
+
* The p2 `input-stream` surface over an asynchronously-fed buffer: the
|
|
125
|
+
* generic bridge from any `AsyncIterable<Uint8Array>` (host stdin, an
|
|
126
|
+
* OPFS file read) to p2 stream semantics. `read` on an empty open stream
|
|
127
|
+
* returns an empty list (p2's non-blocking contract), `blocking-read`
|
|
128
|
+
* parks until bytes or EOF (A14/A2 mark relay — duck-typed against the
|
|
129
|
+
* registered `InputStream`, the marks relay from that prototype), and
|
|
130
|
+
* EOF-with-drained-buffer is the `closed` stream-error. The feed pauses
|
|
131
|
+
* past the high-water mark (no unbounded buffering).
|
|
132
|
+
*/
|
|
133
|
+
export declare class FedInputStream {
|
|
134
|
+
#private;
|
|
135
|
+
constructor(source: AsyncIterable<Uint8Array>, highWater?: number);
|
|
136
|
+
read(len: bigint): Uint8Array;
|
|
137
|
+
/** Parks (A14/A2 mark relay from the registered prototype). */
|
|
138
|
+
blockingRead(len: bigint): Uint8Array | Promise<Uint8Array>;
|
|
139
|
+
skip(len: bigint): bigint;
|
|
140
|
+
blockingSkip(len: bigint): bigint | Promise<bigint>;
|
|
141
|
+
subscribe(): Pollable;
|
|
142
|
+
[Symbol.dispose](): void;
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* The p2 `output-stream` surface over an async sink, with a real byte
|
|
146
|
+
* budget: `check-write` reports the remaining permit (writing past it is
|
|
147
|
+
* the guest's contract violation and traps via unbranded throw),
|
|
148
|
+
* `blocking-flush`/`blocking-write-and-flush` park until the sink
|
|
149
|
+
* drained everything (A14/A2 mark relay), `subscribe` wakes when budget
|
|
150
|
+
* frees. A sink failure surfaces as the `last-operation-failed`
|
|
151
|
+
* stream-error carrying an `IoError`.
|
|
152
|
+
*/
|
|
153
|
+
export declare class SinkOutputStream {
|
|
154
|
+
#private;
|
|
155
|
+
constructor(sink: ByteSink, highWater?: number);
|
|
156
|
+
checkWrite(): bigint;
|
|
157
|
+
write(contents: Uint8Array): void;
|
|
158
|
+
flush(): void;
|
|
159
|
+
/** Parks until the sink drained everything (A14/A2 mark relay). */
|
|
160
|
+
blockingFlush(): void | Promise<void>;
|
|
161
|
+
/** Parks until this write (and everything before it) drained. */
|
|
162
|
+
blockingWriteAndFlush(contents: Uint8Array): void | Promise<void>;
|
|
163
|
+
subscribe(): Pollable;
|
|
164
|
+
writeZeroes(len: bigint): void;
|
|
165
|
+
blockingWriteZeroesAndFlush(len: bigint): void | Promise<void>;
|
|
166
|
+
splice(src: {
|
|
167
|
+
read(len: bigint): Uint8Array;
|
|
168
|
+
}, len: bigint): bigint;
|
|
169
|
+
blockingSplice(src: {
|
|
170
|
+
read(len: bigint): Uint8Array;
|
|
171
|
+
}, len: bigint): bigint | Promise<bigint>;
|
|
172
|
+
[Symbol.dispose](): void;
|
|
173
|
+
}
|
|
174
|
+
/** `wasi:io@0.2` provider fragment (track key). */
|
|
175
|
+
export declare function io(): {
|
|
176
|
+
imports: Record<string, unknown>;
|
|
177
|
+
};
|
package/types/mod.d.ts
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { type CliCaptured, type CliOptions } from "./cli.js";
|
|
2
|
+
import { type ClocksOptions } from "./clocks.js";
|
|
3
|
+
import { type RandomOptions } from "./random.js";
|
|
4
|
+
export { type CliCaptured, type CliOptions } from "./cli.js";
|
|
5
|
+
export { ExitError } from "./internal/cli_shared.js";
|
|
6
|
+
export { type ClocksOptions } from "./clocks.js";
|
|
7
|
+
export { type RandomOptions } from "./random.js";
|
|
8
|
+
export interface WasiOptions {
|
|
9
|
+
cli?: CliOptions;
|
|
10
|
+
clocks?: ClocksOptions;
|
|
11
|
+
random?: RandomOptions;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* The merged imports record plus the one piece of host-observable state a
|
|
15
|
+
* caller needs back out (contract wording: "expose captured output on the
|
|
16
|
+
* returned handle"). `captured` is a plain extra property, not a WIT
|
|
17
|
+
* interface-id key, so it never participates in `ImportResolver`'s
|
|
18
|
+
* track/exact matching (`parseInterfaceId("captured")` has no `@`, and it is
|
|
19
|
+
* excluded from the unversioned-track bookkeeping because it contains
|
|
20
|
+
* neither `:` nor `/` — see `runtime/src/embedder/version.ts`
|
|
21
|
+
* `#register`).
|
|
22
|
+
*/
|
|
23
|
+
export interface WasiImports extends Record<string, unknown> {
|
|
24
|
+
readonly captured: CliCaptured;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Build the merged `wasi:*` imports fragment for `instantiate`.
|
|
28
|
+
*
|
|
29
|
+
* Usage: `instantiate(artifacts, { ...wasi(), ...moreImports })`.
|
|
30
|
+
*/
|
|
31
|
+
export declare function wasi(options?: WasiOptions): WasiImports;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export interface RandomOptions {
|
|
2
|
+
/** Override the deterministic default `insecure-seed` value. */
|
|
3
|
+
insecureSeed?: readonly [bigint, bigint];
|
|
4
|
+
/**
|
|
5
|
+
* Replace the CSPRNG (virtualization: tests selectively stubbing
|
|
6
|
+
* randomness while keeping the WIT shapes). Must return EXACTLY `len`
|
|
7
|
+
* bytes — the @0.2 contract's no-short-reads rule is enforced here, so
|
|
8
|
+
* a misbehaving source is a loud host error, not a guest corruption.
|
|
9
|
+
* Serves `random`, `insecure`, and `get-*-u64` alike; `insecure-seed`
|
|
10
|
+
* stays governed by `insecureSeed`.
|
|
11
|
+
*/
|
|
12
|
+
source?: (len: number) => Uint8Array;
|
|
13
|
+
}
|
|
14
|
+
/** `wasi:random@0.2` + `@0.3` provider fragment (two track keys). */
|
|
15
|
+
export declare function random(options?: RandomOptions): {
|
|
16
|
+
imports: Record<string, unknown>;
|
|
17
|
+
};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { IpAddress, SocketsOptions, TcpSocketClass, UdpSocketClass } from "./internal/sockets_shared.js";
|
|
2
|
+
export { type IpAddress, type IpAddressFamily, ipHostname, type IpSocketAddress, type Ipv4Address, type Ipv4SocketAddress, type Ipv6Address, type Ipv6SocketAddress, isUnspecified, isValidAddressFamily, mapPlatformError, MAX_UDP_DATAGRAM_SIZE, type NameLookupErrorCode, type NetAddr, parseNetAddr, sameSocketAddress, type SocketErrorCode, type SocketResult, type SocketsOptions, type TcpAcceptStream, type TcpByteStream, type TcpSendSource, type TcpSocket, type TcpSocketClass, type UdpSocket, type UdpSocketClass, wildcardAddress, } from "./internal/sockets_shared.js";
|
|
3
|
+
export { Network, type SocketErrorCode02, SocketIoError, } from "./internal/sockets_02.js";
|
|
4
|
+
export declare const SOCKETS_TYPES_INTERFACE = "wasi:sockets/types@0.3";
|
|
5
|
+
/** What `sockets()` returns: the imports fragment plus the fragment's classes. */
|
|
6
|
+
export interface SocketsShim {
|
|
7
|
+
imports: Record<string, unknown>;
|
|
8
|
+
/** The 0.3 track's resource classes (exposed for direct/test use). */
|
|
9
|
+
UdpSocket: UdpSocketClass;
|
|
10
|
+
TcpSocket: TcpSocketClass;
|
|
11
|
+
/** 0.3 `ip-name-lookup.resolve-addresses` (exposed for direct/test use). */
|
|
12
|
+
resolveAddresses: (name: string) => Promise<IpAddress[]>;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* The `wasi:sockets` provider fragment, BOTH tracks (module header):
|
|
16
|
+
* `types@0.3` + `ip-name-lookup@0.3` (internal/sockets_03.ts) and the
|
|
17
|
+
* seven poll-shaped `@0.2` interfaces (internal/sockets_02.ts). Track
|
|
18
|
+
* keys — one provider serves every 0.2.x / 0.3.x the resolver folds onto
|
|
19
|
+
* its track. Resource classes are built per fragment so the `onCall`
|
|
20
|
+
* observer is scoped to it.
|
|
21
|
+
*/
|
|
22
|
+
export declare function sockets(options?: SocketsOptions): SocketsShim;
|