wasm-platform-kit 0.0.0-stage → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +224 -2
  3. package/assets/wasi/LICENSE +220 -0
  4. package/assets/wasi/cli.d.ts +43 -0
  5. package/assets/wasi/cli.js +147 -0
  6. package/assets/wasi/clocks.d.ts +3 -0
  7. package/assets/wasi/clocks.js +55 -0
  8. package/assets/wasi/common.d.ts +5 -0
  9. package/assets/wasi/common.js +16 -0
  10. package/assets/wasi/config.d.ts +2 -0
  11. package/assets/wasi/config.js +7 -0
  12. package/assets/wasi/environment.d.ts +5 -0
  13. package/assets/wasi/environment.js +24 -0
  14. package/assets/wasi/filesystem.d.ts +117 -0
  15. package/assets/wasi/filesystem.js +341 -0
  16. package/assets/wasi/helpers/cli.d.ts +7 -0
  17. package/assets/wasi/helpers/cli.js +25 -0
  18. package/assets/wasi/helpers/filesystem.d.ts +6 -0
  19. package/assets/wasi/helpers/filesystem.js +10 -0
  20. package/assets/wasi/http.d.ts +13 -0
  21. package/assets/wasi/http.js +953 -0
  22. package/assets/wasi/in-memory-filesystem.d.ts +38 -0
  23. package/assets/wasi/in-memory-filesystem.js +620 -0
  24. package/assets/wasi/in-memory-http.d.ts +8 -0
  25. package/assets/wasi/in-memory-http.js +11 -0
  26. package/assets/wasi/in-memory-sockets.d.ts +34 -0
  27. package/assets/wasi/in-memory-sockets.js +294 -0
  28. package/assets/wasi/index.d.ts +7 -0
  29. package/assets/wasi/index.js +7 -0
  30. package/assets/wasi/io.d.ts +67 -0
  31. package/assets/wasi/io.js +366 -0
  32. package/assets/wasi/opfs-filesystem.d.ts +52 -0
  33. package/assets/wasi/opfs-filesystem.js +262 -0
  34. package/assets/wasi/random.d.ts +4 -0
  35. package/assets/wasi/random.js +51 -0
  36. package/assets/wasi/sockets.d.ts +9 -0
  37. package/assets/wasi/sockets.js +85 -0
  38. package/browser.mjs +209 -0
  39. package/client.mjs +138 -0
  40. package/index.d.ts +199 -0
  41. package/install.d.ts +22 -0
  42. package/install.mjs +176 -0
  43. package/native-registration.mjs +70 -0
  44. package/node.mjs +332 -0
  45. package/package.json +66 -4
  46. package/policy.mjs +433 -0
  47. package/worker.mjs +389 -0
@@ -0,0 +1,55 @@
1
+ import { checkedU64 } from "./common.js";
2
+ import { pollableCreate } from "./io.js";
3
+ const MAX_TIMEOUT_MS = 0x7fffffff;
4
+ function timeout(durationNs) {
5
+ let remainingMs = Number((durationNs + 999999n) / 1000000n);
6
+ return new Promise((resolve) => {
7
+ const next = () => {
8
+ if (remainingMs <= 0) {
9
+ resolve();
10
+ return;
11
+ }
12
+ const delay = Math.min(remainingMs, MAX_TIMEOUT_MS);
13
+ remainingMs -= delay;
14
+ setTimeout(next, delay);
15
+ };
16
+ next();
17
+ });
18
+ }
19
+ export const monotonicClock = {
20
+ resolution() {
21
+ // usually we dont get sub-millisecond accuracy in the browser
22
+ // Note: is there a better way to determine this?
23
+ return BigInt(1e6);
24
+ },
25
+ now() {
26
+ // performance.now() is in milliseconds, but we want nanoseconds
27
+ return BigInt(Math.floor(performance.now() * 1e6));
28
+ },
29
+ subscribeInstant(instant) {
30
+ instant = checkedU64(instant, "instant");
31
+ const now = monotonicClock.now();
32
+ if (instant <= now) {
33
+ return pollableCreate();
34
+ }
35
+ return monotonicClock.subscribeDuration(instant - now);
36
+ },
37
+ subscribeDuration(duration) {
38
+ duration = checkedU64(duration, "duration");
39
+ if (duration === 0n) {
40
+ return pollableCreate();
41
+ }
42
+ return pollableCreate(timeout(duration));
43
+ },
44
+ };
45
+ export const wallClock = {
46
+ now() {
47
+ let now = Date.now(); // in milliseconds
48
+ const seconds = BigInt(Math.floor(now / 1e3));
49
+ const nanoseconds = (now % 1e3) * 1e6;
50
+ return { seconds, nanoseconds };
51
+ },
52
+ resolution() {
53
+ return { seconds: 0n, nanoseconds: 1e6 };
54
+ },
55
+ };
@@ -0,0 +1,5 @@
1
+ export declare const MAX_U64: bigint;
2
+ /** Validate and return a WebAssembly u64 value. */
3
+ export declare function checkedU64(value: bigint, name: string): bigint;
4
+ /** Convert a WebAssembly u64 value to a lossless JavaScript number. */
5
+ export declare function checkedU64AsNumber(value: bigint, name: string): number;
@@ -0,0 +1,16 @@
1
+ export const MAX_U64 = (1n << 64n) - 1n;
2
+ /** Validate and return a WebAssembly u64 value. */
3
+ export function checkedU64(value, name) {
4
+ if (typeof value !== "bigint" || value < 0n || value > MAX_U64) {
5
+ throw new TypeError(`${name} must be a valid u64`);
6
+ }
7
+ return value;
8
+ }
9
+ /** Convert a WebAssembly u64 value to a lossless JavaScript number. */
10
+ export function checkedU64AsNumber(value, name) {
11
+ checkedU64(value, name);
12
+ if (value > BigInt(Number.MAX_SAFE_INTEGER)) {
13
+ throw new RangeError(`${name} exceeds JavaScript's safe integer range`);
14
+ }
15
+ return Number(value);
16
+ }
@@ -0,0 +1,2 @@
1
+ export declare function _setCwd(cwd: string): void;
2
+ export declare function _getCwd(): string;
@@ -0,0 +1,7 @@
1
+ let _cwd = "/";
2
+ export function _setCwd(cwd) {
3
+ _cwd = cwd;
4
+ }
5
+ export function _getCwd() {
6
+ return _cwd;
7
+ }
@@ -0,0 +1,5 @@
1
+ import type { environment as EnvironmentNamespace } from "../../types/cli.js";
2
+ export declare function _setEnv(envObj: Record<string, string>): void;
3
+ export declare function _setArgs(args: string[]): void;
4
+ export declare function _setCwd(cwd: string): void;
5
+ export declare const environment: typeof EnvironmentNamespace;
@@ -0,0 +1,24 @@
1
+ import { _setCwd as fsSetCwd } from "./config.js";
2
+ let _env = [];
3
+ let _args = [];
4
+ let _cwd = "/";
5
+ export function _setEnv(envObj) {
6
+ _env = Object.entries(envObj);
7
+ }
8
+ export function _setArgs(args) {
9
+ _args = args;
10
+ }
11
+ export function _setCwd(cwd) {
12
+ fsSetCwd((_cwd = cwd));
13
+ }
14
+ export const environment = {
15
+ getEnvironment() {
16
+ return _env;
17
+ },
18
+ getArguments() {
19
+ return _args;
20
+ },
21
+ initialCwd() {
22
+ return _cwd;
23
+ },
24
+ };
@@ -0,0 +1,117 @@
1
+ import { types as TypesNamespace, preopens as PreopensNamespace } from "../../types/filesystem.js";
2
+ import type { FileData } from "./in-memory-filesystem.js";
3
+ export { _setCwd } from "./config.js";
4
+ export { InMemoryFilesystemAdapter } from "./in-memory-filesystem.js";
5
+ export type { FileData, FileDataEntry } from "./in-memory-filesystem.js";
6
+ export { OpfsFilesystemAdapter, loadOpfsCapability } from "./opfs-filesystem.js";
7
+ export type { OpfsCapability } from "./opfs-filesystem.js";
8
+ type Filesize = TypesNamespace.Filesize;
9
+ type OpenFlags = TypesNamespace.OpenFlags;
10
+ type PathFlags = TypesNamespace.PathFlags;
11
+ export interface BrowserDirectoryEntryStream {
12
+ readDirectoryEntry(): TypesNamespace.DirectoryEntry | undefined;
13
+ }
14
+ export interface BrowserFilesystemDescriptor extends Omit<TypesNamespace.Descriptor, "isSameObject" | "linkAt" | "openAt" | "readDirectory" | "renameAt"> {
15
+ readDirectory(): BrowserDirectoryEntryStream;
16
+ linkAt(oldPathFlags: PathFlags, oldPath: string, newDescriptor: BrowserFilesystemDescriptor, newPath: string): void;
17
+ openAt(pathFlags: PathFlags, path: string, openFlags: OpenFlags, flags: TypesNamespace.DescriptorFlags): BrowserFilesystemDescriptor;
18
+ renameAt(oldPath: string, newDescriptor: BrowserFilesystemDescriptor, newPath: string): void;
19
+ isSameObject(other: BrowserFilesystemDescriptor): boolean;
20
+ /**
21
+ * Advisory locking, for host application code holding a descriptor directly
22
+ * (not part of the WASI guest-facing surface). Adapters that support it should
23
+ * implement all five; `tryLock*` return whether the lock was acquired instead
24
+ * of throwing.
25
+ */
26
+ lockShared?(): void;
27
+ lockExclusive?(): void;
28
+ tryLockShared?(): boolean;
29
+ tryLockExclusive?(): boolean;
30
+ unlock?(): void;
31
+ }
32
+ export interface BrowserFilesystemAdapter<Capability = unknown> {
33
+ getRoot(capability: Capability): BrowserFilesystemDescriptor;
34
+ dispose?(): void | Promise<void>;
35
+ }
36
+ export interface BrowserFilesystemConfig<Capability> {
37
+ adapter: BrowserFilesystemAdapter<Capability>;
38
+ preopens: Record<string, Capability>;
39
+ }
40
+ declare class DirectoryEntryStream implements TypesNamespace.DirectoryEntryStream {
41
+ #private;
42
+ static _create(implementation: BrowserDirectoryEntryStream): DirectoryEntryStream;
43
+ readDirectoryEntry(): TypesNamespace.DirectoryEntry | undefined;
44
+ }
45
+ declare class Descriptor implements TypesNamespace.Descriptor {
46
+ #private;
47
+ _getImplementation(descriptor: Descriptor): BrowserFilesystemDescriptor;
48
+ static _create(implementation: BrowserFilesystemDescriptor): Descriptor;
49
+ readViaStream(offset: Filesize): import("../../types/interfaces/wasi-io-streams.js").InputStream;
50
+ writeViaStream(offset: Filesize): import("../../types/interfaces/wasi-io-streams.js").OutputStream;
51
+ appendViaStream(): import("../../types/interfaces/wasi-io-streams.js").OutputStream;
52
+ advise(offset: Filesize, length: Filesize, advice: TypesNamespace.Advice): void;
53
+ syncData(): void;
54
+ getFlags(): TypesNamespace.DescriptorFlags;
55
+ getType(): TypesNamespace.DescriptorType;
56
+ setSize(size: Filesize): void;
57
+ setTimes(dataAccessTimestamp: TypesNamespace.NewTimestamp, dataModificationTimestamp: TypesNamespace.NewTimestamp): void;
58
+ read(length: Filesize, offset: Filesize): [Uint8Array<ArrayBufferLike>, boolean];
59
+ write(buffer: Uint8Array, offset: Filesize): bigint;
60
+ readDirectory(): DirectoryEntryStream;
61
+ sync(): void;
62
+ createDirectoryAt(path: string): void;
63
+ stat(): TypesNamespace.DescriptorStat;
64
+ statAt(pathFlags: PathFlags, path: string): TypesNamespace.DescriptorStat;
65
+ setTimesAt(pathFlags: PathFlags, path: string, dataAccessTimestamp: TypesNamespace.NewTimestamp, dataModificationTimestamp: TypesNamespace.NewTimestamp): void;
66
+ linkAt(oldPathFlags: PathFlags, oldPath: string, newDescriptor: TypesNamespace.Descriptor, newPath: string): void;
67
+ openAt(pathFlags: PathFlags, path: string, openFlags: OpenFlags, flags: TypesNamespace.DescriptorFlags): Descriptor;
68
+ readlinkAt(path: string): string;
69
+ removeDirectoryAt(path: string): void;
70
+ renameAt(oldPath: string, newDescriptor: TypesNamespace.Descriptor, newPath: string): void;
71
+ symlinkAt(oldPath: string, newPath: string): void;
72
+ unlinkFileAt(path: string): void;
73
+ isSameObject(other: TypesNamespace.Descriptor): boolean;
74
+ metadataHash(): TypesNamespace.MetadataHashValue;
75
+ metadataHashAt(pathFlags: PathFlags, path: string): TypesNamespace.MetadataHashValue;
76
+ lockShared(): void | undefined;
77
+ lockExclusive(): void | undefined;
78
+ tryLockShared(): boolean;
79
+ tryLockExclusive(): boolean;
80
+ unlock(): void | undefined;
81
+ }
82
+ export declare const preopens: typeof PreopensNamespace;
83
+ /** Create isolated filesystem namespaces backed by an application-selected adapter. */
84
+ export declare function createFilesystem<Capability>({ adapter, preopens: configuredPreopens, }: BrowserFilesystemConfig<Capability>): {
85
+ types: typeof TypesNamespace;
86
+ preopens: typeof PreopensNamespace;
87
+ dispose(): void | Promise<void>;
88
+ };
89
+ export declare function _setFileData(fileData: FileData): void;
90
+ export declare function _getFileData(): string;
91
+ /**
92
+ * Replace all preopens with the given set.
93
+ * @param preopensConfig - Map of virtual paths to file data entries
94
+ */
95
+ export declare function _setPreopens(preopensConfig: Record<string, FileData>): void;
96
+ /**
97
+ * Add a single preopen mapping.
98
+ * @param virtualPath - The virtual path visible to the guest
99
+ * @param fileData - The file data object representing the directory
100
+ */
101
+ export declare function _addPreopen(virtualPath: string, fileData: FileData): void;
102
+ /**
103
+ * Add a single preopen backed by a custom adapter (e.g. `OpfsFilesystemAdapter`) instead of the
104
+ * default in-memory one. Lets a host wire an alternative `BrowserFilesystemAdapter` into the
105
+ * top-level `wasi:filesystem/preopens` singleton that transpiled components import statically.
106
+ * @param virtualPath - The virtual path visible to the guest
107
+ * @param adapter - The adapter that will back this preopen
108
+ * @param capability - The adapter-specific capability to load as the preopen's root
109
+ */
110
+ export declare function _addPreopenWithAdapter<Capability>(virtualPath: string, adapter: BrowserFilesystemAdapter<Capability>, capability: Capability): void;
111
+ /** Clear all preopens, giving the guest no filesystem access. */
112
+ export declare function _clearPreopens(): void;
113
+ /** Get current preopens configuration. */
114
+ export declare function _getPreopens(): [Descriptor, string][];
115
+ /** Reject host paths because browser filesystems require explicit capabilities. */
116
+ export declare function _createPreopenDescriptor(hostPreopen: string): void;
117
+ export declare const types: typeof TypesNamespace;
@@ -0,0 +1,341 @@
1
+ import { environment } from "./environment.js";
2
+ import { InMemoryFilesystemAdapter } from "./in-memory-filesystem.js";
3
+ import { _setCwd } from "./config.js";
4
+ export { _setCwd } from "./config.js";
5
+ export { InMemoryFilesystemAdapter } from "./in-memory-filesystem.js";
6
+ export { OpfsFilesystemAdapter, loadOpfsCapability } from "./opfs-filesystem.js";
7
+ class DirectoryEntryStream {
8
+ #implementation;
9
+ static _create(implementation) {
10
+ const stream = new DirectoryEntryStream();
11
+ stream.#implementation = implementation;
12
+ return stream;
13
+ }
14
+ readDirectoryEntry() {
15
+ return this.#implementation.readDirectoryEntry();
16
+ }
17
+ }
18
+ const directoryEntryStreamCreate = DirectoryEntryStream._create;
19
+ // @ts-expect-error - Deleting static method
20
+ delete DirectoryEntryStream._create;
21
+ class Descriptor {
22
+ #implementation;
23
+ _getImplementation(descriptor) {
24
+ return descriptor.#implementation;
25
+ }
26
+ static _create(implementation) {
27
+ const descriptor = new Descriptor();
28
+ descriptor.#implementation = implementation;
29
+ return descriptor;
30
+ }
31
+ readViaStream(offset) {
32
+ return this.#implementation.readViaStream(offset);
33
+ }
34
+ writeViaStream(offset) {
35
+ return this.#implementation.writeViaStream(offset);
36
+ }
37
+ appendViaStream() {
38
+ return this.#implementation.appendViaStream();
39
+ }
40
+ advise(offset, length, advice) {
41
+ return this.#implementation.advise(offset, length, advice);
42
+ }
43
+ syncData() {
44
+ return this.#implementation.syncData();
45
+ }
46
+ getFlags() {
47
+ return this.#implementation.getFlags();
48
+ }
49
+ getType() {
50
+ return this.#implementation.getType();
51
+ }
52
+ setSize(size) {
53
+ return this.#implementation.setSize(size);
54
+ }
55
+ setTimes(dataAccessTimestamp, dataModificationTimestamp) {
56
+ return this.#implementation.setTimes(dataAccessTimestamp, dataModificationTimestamp);
57
+ }
58
+ read(length, offset) {
59
+ return this.#implementation.read(length, offset);
60
+ }
61
+ write(buffer, offset) {
62
+ return this.#implementation.write(buffer, offset);
63
+ }
64
+ readDirectory() {
65
+ return directoryEntryStreamCreate(this.#implementation.readDirectory());
66
+ }
67
+ sync() {
68
+ return this.#implementation.sync();
69
+ }
70
+ createDirectoryAt(path) {
71
+ return this.#implementation.createDirectoryAt(path);
72
+ }
73
+ stat() {
74
+ return this.#implementation.stat();
75
+ }
76
+ statAt(pathFlags, path) {
77
+ return this.#implementation.statAt(pathFlags, path);
78
+ }
79
+ setTimesAt(pathFlags, path, dataAccessTimestamp, dataModificationTimestamp) {
80
+ return this.#implementation.setTimesAt(pathFlags, path, dataAccessTimestamp, dataModificationTimestamp);
81
+ }
82
+ linkAt(oldPathFlags, oldPath, newDescriptor, newPath) {
83
+ return this.#implementation.linkAt(oldPathFlags, oldPath, descriptorGetImplementation(newDescriptor), newPath);
84
+ }
85
+ openAt(pathFlags, path, openFlags, flags) {
86
+ return descriptorCreate(this.#implementation.openAt(pathFlags, path, openFlags, flags));
87
+ }
88
+ readlinkAt(path) {
89
+ return this.#implementation.readlinkAt(path);
90
+ }
91
+ removeDirectoryAt(path) {
92
+ return this.#implementation.removeDirectoryAt(path);
93
+ }
94
+ renameAt(oldPath, newDescriptor, newPath) {
95
+ return this.#implementation.renameAt(oldPath, descriptorGetImplementation(newDescriptor), newPath);
96
+ }
97
+ symlinkAt(oldPath, newPath) {
98
+ return this.#implementation.symlinkAt(oldPath, newPath);
99
+ }
100
+ unlinkFileAt(path) {
101
+ return this.#implementation.unlinkFileAt(path);
102
+ }
103
+ isSameObject(other) {
104
+ return this.#implementation.isSameObject(descriptorGetImplementation(other));
105
+ }
106
+ metadataHash() {
107
+ return this.#implementation.metadataHash();
108
+ }
109
+ metadataHashAt(pathFlags, path) {
110
+ return this.#implementation.metadataHashAt(pathFlags, path);
111
+ }
112
+ lockShared() {
113
+ return this.#implementation.lockShared?.();
114
+ }
115
+ lockExclusive() {
116
+ return this.#implementation.lockExclusive?.();
117
+ }
118
+ tryLockShared() {
119
+ return this.#implementation.tryLockShared?.() ?? false;
120
+ }
121
+ tryLockExclusive() {
122
+ return this.#implementation.tryLockExclusive?.() ?? false;
123
+ }
124
+ unlock() {
125
+ return this.#implementation.unlock?.();
126
+ }
127
+ }
128
+ const descriptorGetImplementation = Descriptor.prototype._getImplementation;
129
+ // @ts-expect-error - Deleting prototype method
130
+ delete Descriptor.prototype._getImplementation;
131
+ const descriptorCreate = Descriptor._create;
132
+ // @ts-expect-error - Deleting static method
133
+ delete Descriptor._create;
134
+ const defaultAdapter = new InMemoryFilesystemAdapter();
135
+ let _fileData = { dir: {} };
136
+ let _preopens = [];
137
+ let _rootPreopen = null;
138
+ export const preopens = {
139
+ getDirectories() {
140
+ return _preopens;
141
+ },
142
+ };
143
+ /** Create isolated filesystem namespaces backed by an application-selected adapter. */
144
+ export function createFilesystem({ adapter, preopens: configuredPreopens, }) {
145
+ const entries = Object.entries(configuredPreopens).map(([guestPath, capability]) => [descriptorCreate(adapter.getRoot(capability)), guestPath]);
146
+ let disposed = false;
147
+ let disposal;
148
+ return {
149
+ types,
150
+ preopens: {
151
+ getDirectories() {
152
+ if (disposed) {
153
+ throw new Error("filesystem adapter has been disposed");
154
+ }
155
+ return [...entries];
156
+ },
157
+ },
158
+ dispose() {
159
+ if (disposed) {
160
+ return disposal;
161
+ }
162
+ disposed = true;
163
+ disposal = adapter.dispose?.();
164
+ return disposal;
165
+ },
166
+ };
167
+ }
168
+ export function _setFileData(fileData) {
169
+ _fileData = fileData;
170
+ if (_rootPreopen) {
171
+ _rootPreopen[0] = descriptorCreate(defaultAdapter.getRoot(fileData));
172
+ }
173
+ else {
174
+ _setPreopens({ "/": fileData });
175
+ }
176
+ const cwd = environment.initialCwd();
177
+ _setCwd(cwd || "/");
178
+ }
179
+ export function _getFileData() {
180
+ return JSON.stringify(_fileData);
181
+ }
182
+ /**
183
+ * Replace all preopens with the given set.
184
+ * @param preopensConfig - Map of virtual paths to file data entries
185
+ */
186
+ export function _setPreopens(preopensConfig) {
187
+ _preopens = [];
188
+ _rootPreopen = null;
189
+ for (const [virtualPath, fileData] of Object.entries(preopensConfig)) {
190
+ _addPreopen(virtualPath, fileData);
191
+ }
192
+ }
193
+ /**
194
+ * Add a single preopen mapping.
195
+ * @param virtualPath - The virtual path visible to the guest
196
+ * @param fileData - The file data object representing the directory
197
+ */
198
+ export function _addPreopen(virtualPath, fileData) {
199
+ const descriptor = descriptorCreate(defaultAdapter.getRoot(fileData));
200
+ const entry = [descriptor, virtualPath];
201
+ _preopens.push(entry);
202
+ if (virtualPath === "/") {
203
+ _rootPreopen = entry;
204
+ }
205
+ }
206
+ /**
207
+ * Add a single preopen backed by a custom adapter (e.g. `OpfsFilesystemAdapter`) instead of the
208
+ * default in-memory one. Lets a host wire an alternative `BrowserFilesystemAdapter` into the
209
+ * top-level `wasi:filesystem/preopens` singleton that transpiled components import statically.
210
+ * @param virtualPath - The virtual path visible to the guest
211
+ * @param adapter - The adapter that will back this preopen
212
+ * @param capability - The adapter-specific capability to load as the preopen's root
213
+ */
214
+ export function _addPreopenWithAdapter(virtualPath, adapter, capability) {
215
+ const descriptor = descriptorCreate(adapter.getRoot(capability));
216
+ const entry = [descriptor, virtualPath];
217
+ _preopens.push(entry);
218
+ if (virtualPath === "/") {
219
+ _rootPreopen = entry;
220
+ }
221
+ }
222
+ /** Clear all preopens, giving the guest no filesystem access. */
223
+ export function _clearPreopens() {
224
+ _preopens = [];
225
+ _rootPreopen = null;
226
+ }
227
+ /** Get current preopens configuration. */
228
+ export function _getPreopens() {
229
+ return [..._preopens];
230
+ }
231
+ /** Reject host paths because browser filesystems require explicit capabilities. */
232
+ export function _createPreopenDescriptor(hostPreopen) {
233
+ throw new TypeError(`browser preopen ${JSON.stringify(hostPreopen)} is a host path; configure browser file data or an adapter instead`);
234
+ }
235
+ export const types = {
236
+ Descriptor,
237
+ DirectoryEntryStream,
238
+ filesystemErrorCode: (err) => {
239
+ let message;
240
+ if ("payload" in err) {
241
+ message = err.payload;
242
+ }
243
+ else if ("message" in err) {
244
+ message = err.message;
245
+ }
246
+ return convertFsError(message);
247
+ },
248
+ };
249
+ function convertFsError(e) {
250
+ switch (e.code) {
251
+ case "EACCES":
252
+ return "access";
253
+ case "EAGAIN":
254
+ case "EWOULDBLOCK":
255
+ return "would-block";
256
+ case "EALREADY":
257
+ return "already";
258
+ case "EBADF":
259
+ return "bad-descriptor";
260
+ case "EBUSY":
261
+ return "busy";
262
+ case "EDEADLK":
263
+ return "deadlock";
264
+ case "EDQUOT":
265
+ return "quota";
266
+ case "EEXIST":
267
+ return "exist";
268
+ case "EFBIG":
269
+ return "file-too-large";
270
+ case "EILSEQ":
271
+ return "illegal-byte-sequence";
272
+ case "EINPROGRESS":
273
+ return "in-progress";
274
+ case "EINTR":
275
+ return "interrupted";
276
+ case "EINVAL":
277
+ return "invalid";
278
+ case "EIO":
279
+ return "io";
280
+ case "EISDIR":
281
+ return "is-directory";
282
+ case "ELOOP":
283
+ return "loop";
284
+ case "EMLINK":
285
+ return "too-many-links";
286
+ case "EMSGSIZE":
287
+ return "message-size";
288
+ case "ENAMETOOLONG":
289
+ return "name-too-long";
290
+ case "ENODEV":
291
+ return "no-device";
292
+ case "ENOENT":
293
+ return "no-entry";
294
+ case "ENOLCK":
295
+ return "no-lock";
296
+ case "ENOMEM":
297
+ return "insufficient-memory";
298
+ case "ENOSPC":
299
+ return "insufficient-space";
300
+ case "ENOTDIR":
301
+ case "ERR_FS_EISDIR":
302
+ return "not-directory";
303
+ case "ENOTEMPTY":
304
+ return "not-empty";
305
+ case "ENOTRECOVERABLE":
306
+ return "not-recoverable";
307
+ case "ENOTSUP":
308
+ return "unsupported";
309
+ case "ENOTTY":
310
+ return "no-tty";
311
+ // windows gives this error for badly structured `//` reads
312
+ // this seems like a slightly better error than unknown given
313
+ // that it's a common footgun
314
+ case -4094:
315
+ case "ENXIO":
316
+ return "no-such-device";
317
+ case "EOVERFLOW":
318
+ return "overflow";
319
+ case "EPERM":
320
+ return "not-permitted";
321
+ case "EPIPE":
322
+ return "pipe";
323
+ case "EROFS":
324
+ return "read-only";
325
+ case "ESPIPE":
326
+ return "invalid-seek";
327
+ case "ETXTBSY":
328
+ return "text-file-busy";
329
+ case "EXDEV":
330
+ return "cross-device";
331
+ case "UNKNOWN":
332
+ switch (e.errno) {
333
+ case -4094:
334
+ return "no-such-device";
335
+ default:
336
+ throw e;
337
+ }
338
+ default:
339
+ throw e;
340
+ }
341
+ }
@@ -0,0 +1,7 @@
1
+ import { type InputStreamHandler } from "../io.js";
2
+ /**
3
+ * Build an `InputStreamHandler` that serves a fixed buffer, then reports `closed`.
4
+ *
5
+ * Pass the result to `createCli({ stdin })` or `_setStdin` to feed a guest a fixed stdin.
6
+ */
7
+ export declare function bufferedInputStream(input: Uint8Array | string): InputStreamHandler;
@@ -0,0 +1,25 @@
1
+ import { pollableCreate } from "../io.js";
2
+ /**
3
+ * Build an `InputStreamHandler` that serves a fixed buffer, then reports `closed`.
4
+ *
5
+ * Pass the result to `createCli({ stdin })` or `_setStdin` to feed a guest a fixed stdin.
6
+ */
7
+ export function bufferedInputStream(input) {
8
+ const bytes = typeof input === "string" ? new TextEncoder().encode(input) : input;
9
+ let offset = 0;
10
+ return {
11
+ blockingRead(len) {
12
+ if (offset >= bytes.length) {
13
+ throw { tag: "closed" };
14
+ }
15
+ const remaining = bytes.length - offset;
16
+ const toRead = len < BigInt(remaining) ? Number(len) : remaining;
17
+ const chunk = bytes.slice(offset, offset + toRead);
18
+ offset += toRead;
19
+ return chunk;
20
+ },
21
+ subscribe() {
22
+ return pollableCreate();
23
+ },
24
+ };
25
+ }
@@ -0,0 +1,6 @@
1
+ import { type WriteFileAtOptions } from "../../common/helpers/filesystem.js";
2
+ export type { WriteFileAtOptions };
3
+ /** Write bytes into a preopened directory's tree from host JS, without a guest. */
4
+ export declare function writeFileAt(virtualPath: string, path: string, data: Uint8Array, options?: WriteFileAtOptions): void;
5
+ /** Read the full contents of a file under a preopened directory from host JS, without a guest. */
6
+ export declare function readFileAt(virtualPath: string, path: string): Uint8Array;
@@ -0,0 +1,10 @@
1
+ import { _getPreopens } from "../filesystem.js";
2
+ import { writeFileAt as writeFileAtImpl, readFileAt as readFileAtImpl, } from "../../common/helpers/filesystem.js";
3
+ /** Write bytes into a preopened directory's tree from host JS, without a guest. */
4
+ export function writeFileAt(virtualPath, path, data, options = {}) {
5
+ writeFileAtImpl(_getPreopens(), virtualPath, path, data, options);
6
+ }
7
+ /** Read the full contents of a file under a preopened directory from host JS, without a guest. */
8
+ export function readFileAt(virtualPath, path) {
9
+ return readFileAtImpl(_getPreopens(), virtualPath, path);
10
+ }
@@ -0,0 +1,13 @@
1
+ import type { incomingHandler as IncomingHandlerNamespace, outgoingHandler as OutgoingHandlerNamespace, types as TypesNamespace } from "../../types/http.js";
2
+ export { InMemoryHttpClient } from "./in-memory-http.js";
3
+ /** Enable or disable Fetch `ReadableStream` request bodies. Disabled by default. */
4
+ export declare function _setRequestStreaming(enabled: boolean): void;
5
+ export declare const outgoingHandler: typeof OutgoingHandlerNamespace;
6
+ export declare const incomingHandler: typeof IncomingHandlerNamespace;
7
+ export type WasiIncomingHandler = (request: TypesNamespace.IncomingRequest, responseOut: TypesNamespace.ResponseOutparam) => void | Promise<void>;
8
+ export type WebIncomingHandler = (request: Request) => Response | Promise<Response>;
9
+ /** Create a `wasi:http/incoming-handler` namespace backed by a Web Request handler. */
10
+ export declare function createIncomingHandler(handler: WebIncomingHandler): typeof IncomingHandlerNamespace;
11
+ /** Translate a browser Request through a WASI handler with a synchronously readable body. */
12
+ export declare function handleIncomingRequest(request: Request, handler: WasiIncomingHandler): Promise<Response>;
13
+ export declare const types: typeof TypesNamespace;