space-data-module-sdk 0.5.15 → 0.5.19

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 (45) hide show
  1. package/README.md +51 -0
  2. package/package.json +13 -4
  3. package/schemas/HostStorageAbi.fbs +53 -0
  4. package/src/browser.js +6 -0
  5. package/src/bundle/codec.js +1 -1
  6. package/src/compiler/compileModule.js +3 -0
  7. package/src/compliance/pluginCompliance.js +1 -2
  8. package/src/generated/orbpro/invoke/plugin-invoke-request.js +1 -1
  9. package/src/generated/orbpro/invoke/plugin-invoke-response.js +1 -1
  10. package/src/generated/orbpro/manifest/accepted-type-set.js +1 -1
  11. package/src/generated/orbpro/manifest/build-artifact.js +1 -1
  12. package/src/generated/orbpro/manifest/host-capability.js +1 -1
  13. package/src/generated/orbpro/manifest/method-manifest.js +1 -1
  14. package/src/generated/orbpro/manifest/plugin-manifest.js +1 -1
  15. package/src/generated/orbpro/manifest/port-manifest.js +1 -1
  16. package/src/generated/orbpro/manifest/protocol-spec.js +1 -1
  17. package/src/generated/orbpro/manifest/timer-spec.js +1 -1
  18. package/src/generated/orbpro/module/canonicalization-rule.js +1 -1
  19. package/src/generated/orbpro/module/module-bundle-entry.js +1 -1
  20. package/src/generated/orbpro/module/module-bundle.js +1 -1
  21. package/src/generated/orbpro/stream/flat-buffer-type-ref.js +1 -1
  22. package/src/generated/orbpro/stream/typed-arena-buffer.js +1 -1
  23. package/src/host/browserEdgeShims.js +355 -0
  24. package/src/host/browserHost.js +399 -0
  25. package/src/host/index.js +4 -0
  26. package/src/host/isomorphicLoader.js +101 -0
  27. package/src/host/wasiShim.js +275 -0
  28. package/src/index.d.ts +364 -0
  29. package/src/index.js +1 -0
  30. package/src/invoke/codec.js +1 -1
  31. package/src/manifest/codec.js +1 -1
  32. package/src/manifest/typeRefs.js +49 -12
  33. package/src/runtime-host/flatsqlRuntimeStore.js +217 -0
  34. package/src/runtime-host/index.js +21 -0
  35. package/src/runtime-host/moduleRegistry.js +92 -0
  36. package/src/runtime-host/runtimeRegionStore.js +245 -0
  37. package/src/testing/browserModuleHarness.js +275 -0
  38. package/src/testing/buildWasmEdgeRunner.js +41 -2
  39. package/src/testing/index.d.ts +173 -2
  40. package/src/testing/index.js +5 -0
  41. package/src/testing/moduleHarness.js +102 -1
  42. package/src/testing/native/wasmedge_emscripten_pthread_runner.c +2319 -209
  43. package/src/testing/processInvoke.js +250 -9
  44. package/src/testing/streamInvokeCodec.js +175 -0
  45. package/src/transport/records.js +19 -6
@@ -0,0 +1,275 @@
1
+ /**
2
+ * Browser-compatible WASI preview1 shim.
3
+ *
4
+ * Provides the wasi_snapshot_preview1 import namespace so that standalone
5
+ * WASI modules (the same .wasm that runs in WasmEdge) can be instantiated
6
+ * directly in the browser via WebAssembly.instantiate().
7
+ *
8
+ * Covers the 11 imports observed across all SDN plugin standalone builds:
9
+ * clock_time_get, fd_write, fd_read, fd_close, fd_seek, fd_fdstat_get,
10
+ * environ_sizes_get, environ_get, proc_exit, args_get, args_sizes_get
11
+ */
12
+
13
+ const ERRNO_SUCCESS = 0;
14
+ const ERRNO_BADF = 8;
15
+ const ERRNO_INVAL = 28;
16
+ const ERRNO_NOSYS = 52;
17
+ const ERRNO_SPIPE = 70;
18
+
19
+ const CLOCKID_REALTIME = 0;
20
+ const CLOCKID_MONOTONIC = 1;
21
+
22
+ const FILETYPE_CHARACTER_DEVICE = 2;
23
+
24
+ export class WasiExitError extends Error {
25
+ constructor(code) {
26
+ super(`WASI exit with code ${code}`);
27
+ this.name = "WasiExitError";
28
+ this.code = code;
29
+ }
30
+ }
31
+
32
+ export function createBrowserWasiShim(options = {}) {
33
+ const args = options.args ?? [];
34
+ const env = options.env ?? {};
35
+ const stdinBytes = new Uint8Array(options.stdinBytes ?? []);
36
+ const logOutput = options.logOutput === true;
37
+ const performanceApi = options.performance ?? globalThis.performance ?? {
38
+ now: () => Date.now(),
39
+ timeOrigin: 0,
40
+ };
41
+ const stdoutChunks = [];
42
+ const stderrChunks = [];
43
+ let stdinOffset = 0;
44
+
45
+ let memory = null;
46
+
47
+ function setMemory(mem) {
48
+ memory = mem;
49
+ }
50
+
51
+ function getMemory() {
52
+ return memory;
53
+ }
54
+
55
+ function mem8() {
56
+ return new Uint8Array(memory.buffer);
57
+ }
58
+ function view() {
59
+ return new DataView(memory.buffer);
60
+ }
61
+
62
+ // --- Environment encoding helpers ---
63
+
64
+ const envEntries = Object.entries(env).map(([k, v]) => `${k}=${v}`);
65
+ const encodedEnvEntries = envEntries.map((e) => new TextEncoder().encode(e));
66
+ const encodedArgs = args.map((a) => new TextEncoder().encode(a));
67
+
68
+ // --- WASI functions ---
69
+
70
+ function clock_time_get(clockId, _precisionBigInt, resultPtr) {
71
+ let nanos;
72
+ if (clockId === CLOCKID_REALTIME) {
73
+ nanos = BigInt(
74
+ Math.round((performanceApi.timeOrigin + performanceApi.now()) * 1e6),
75
+ );
76
+ } else if (clockId === CLOCKID_MONOTONIC) {
77
+ nanos = BigInt(Math.round(performanceApi.now() * 1e6));
78
+ } else {
79
+ return ERRNO_INVAL;
80
+ }
81
+ view().setBigUint64(resultPtr, nanos, true);
82
+ return ERRNO_SUCCESS;
83
+ }
84
+
85
+ function fd_write(fd, iovsPtr, iovsLen, nwrittenPtr) {
86
+ if (fd !== 1 && fd !== 2) return ERRNO_BADF;
87
+
88
+ const target = fd === 1 ? stdoutChunks : stderrChunks;
89
+ let totalWritten = 0;
90
+ const dv = view();
91
+ const bytes = mem8();
92
+
93
+ for (let i = 0; i < iovsLen; i++) {
94
+ const base = iovsPtr + i * 8;
95
+ const ptr = dv.getUint32(base, true);
96
+ const len = dv.getUint32(base + 4, true);
97
+ target.push(bytes.slice(ptr, ptr + len));
98
+ totalWritten += len;
99
+ }
100
+
101
+ dv.setUint32(nwrittenPtr, totalWritten, true);
102
+ return ERRNO_SUCCESS;
103
+ }
104
+
105
+ function fd_read(fd, iovsPtr, iovsLen, nreadPtr) {
106
+ if (fd !== 0) {
107
+ view().setUint32(nreadPtr, 0, true);
108
+ return ERRNO_BADF;
109
+ }
110
+
111
+ const dv = view();
112
+ const bytes = mem8();
113
+ let totalRead = 0;
114
+
115
+ for (let i = 0; i < iovsLen; i += 1) {
116
+ if (stdinOffset >= stdinBytes.length) {
117
+ break;
118
+ }
119
+ const base = iovsPtr + i * 8;
120
+ const ptr = dv.getUint32(base, true);
121
+ const len = dv.getUint32(base + 4, true);
122
+ const remaining = stdinBytes.length - stdinOffset;
123
+ const count = Math.min(len, remaining);
124
+ bytes.set(stdinBytes.subarray(stdinOffset, stdinOffset + count), ptr);
125
+ stdinOffset += count;
126
+ totalRead += count;
127
+ }
128
+
129
+ dv.setUint32(nreadPtr, totalRead, true);
130
+ return ERRNO_SUCCESS;
131
+ }
132
+
133
+ function fd_close(fd) {
134
+ if (fd <= 2) return ERRNO_SUCCESS;
135
+ return ERRNO_BADF;
136
+ }
137
+
138
+ function fd_seek(fd, _offsetLo, _whence, _resultPtr) {
139
+ if (fd <= 2) return ERRNO_SPIPE;
140
+ return ERRNO_BADF;
141
+ }
142
+
143
+ function fd_fdstat_get(fd, bufPtr) {
144
+ if (fd > 2) return ERRNO_BADF;
145
+ const dv = view();
146
+ // filetype (u8) at offset 0 — CHARACTER_DEVICE
147
+ dv.setUint8(bufPtr, FILETYPE_CHARACTER_DEVICE);
148
+ // fdflags (u16) at offset 2
149
+ dv.setUint16(bufPtr + 2, 0, true);
150
+ // rights_base (u64) at offset 8
151
+ dv.setBigUint64(bufPtr + 8, 0n, true);
152
+ // rights_inheriting (u64) at offset 16
153
+ dv.setBigUint64(bufPtr + 16, 0n, true);
154
+ return ERRNO_SUCCESS;
155
+ }
156
+
157
+ function environ_sizes_get(countPtr, bufSizePtr) {
158
+ const dv = view();
159
+ dv.setUint32(countPtr, encodedEnvEntries.length, true);
160
+ let totalSize = 0;
161
+ for (const entry of encodedEnvEntries) {
162
+ totalSize += entry.length + 1; // null terminator
163
+ }
164
+ dv.setUint32(bufSizePtr, totalSize, true);
165
+ return ERRNO_SUCCESS;
166
+ }
167
+
168
+ function environ_get(environPtr, environBufPtr) {
169
+ const dv = view();
170
+ const bytes = mem8();
171
+ let bufOffset = environBufPtr;
172
+
173
+ for (let i = 0; i < encodedEnvEntries.length; i++) {
174
+ dv.setUint32(environPtr + i * 4, bufOffset, true);
175
+ bytes.set(encodedEnvEntries[i], bufOffset);
176
+ bufOffset += encodedEnvEntries[i].length;
177
+ bytes[bufOffset] = 0; // null terminator
178
+ bufOffset += 1;
179
+ }
180
+ return ERRNO_SUCCESS;
181
+ }
182
+
183
+ function args_sizes_get(argcPtr, argvBufSizePtr) {
184
+ const dv = view();
185
+ dv.setUint32(argcPtr, encodedArgs.length, true);
186
+ let totalSize = 0;
187
+ for (const arg of encodedArgs) {
188
+ totalSize += arg.length + 1;
189
+ }
190
+ dv.setUint32(argvBufSizePtr, totalSize, true);
191
+ return ERRNO_SUCCESS;
192
+ }
193
+
194
+ function args_get(argvPtr, argvBufPtr) {
195
+ const dv = view();
196
+ const bytes = mem8();
197
+ let bufOffset = argvBufPtr;
198
+
199
+ for (let i = 0; i < encodedArgs.length; i++) {
200
+ dv.setUint32(argvPtr + i * 4, bufOffset, true);
201
+ bytes.set(encodedArgs[i], bufOffset);
202
+ bufOffset += encodedArgs[i].length;
203
+ bytes[bufOffset] = 0;
204
+ bufOffset += 1;
205
+ }
206
+ return ERRNO_SUCCESS;
207
+ }
208
+
209
+ function proc_exit(code) {
210
+ if (logOutput) {
211
+ flushOutput();
212
+ }
213
+ throw new WasiExitError(code);
214
+ }
215
+
216
+ // --- Output helpers ---
217
+
218
+ function flushOutput() {
219
+ if (stdoutChunks.length > 0) {
220
+ const combined = concatChunks(stdoutChunks);
221
+ if (logOutput) {
222
+ const text = new TextDecoder().decode(combined);
223
+ if (text) console.log(text);
224
+ }
225
+ stdoutChunks.length = 0;
226
+ }
227
+ if (stderrChunks.length > 0) {
228
+ const combined = concatChunks(stderrChunks);
229
+ if (logOutput) {
230
+ const text = new TextDecoder().decode(combined);
231
+ if (text) console.warn(text);
232
+ }
233
+ stderrChunks.length = 0;
234
+ }
235
+ }
236
+
237
+ function concatChunks(chunks) {
238
+ let totalLen = 0;
239
+ for (const chunk of chunks) totalLen += chunk.length;
240
+ const result = new Uint8Array(totalLen);
241
+ let offset = 0;
242
+ for (const chunk of chunks) {
243
+ result.set(chunk, offset);
244
+ offset += chunk.length;
245
+ }
246
+ return result;
247
+ }
248
+
249
+ return {
250
+ imports: {
251
+ wasi_snapshot_preview1: {
252
+ clock_time_get,
253
+ fd_write,
254
+ fd_read,
255
+ fd_close,
256
+ fd_seek,
257
+ fd_fdstat_get,
258
+ environ_sizes_get,
259
+ environ_get,
260
+ args_sizes_get,
261
+ args_get,
262
+ proc_exit,
263
+ },
264
+ },
265
+ setMemory,
266
+ getMemory,
267
+ flushOutput,
268
+ get stdout() {
269
+ return concatChunks(stdoutChunks);
270
+ },
271
+ get stderr() {
272
+ return concatChunks(stderrChunks);
273
+ },
274
+ };
275
+ }
package/src/index.d.ts CHANGED
@@ -258,6 +258,144 @@ export function loadComplianceConfig(
258
258
  rootDirectory: string,
259
259
  ): Promise<{ path: string; config: Record<string, unknown> } | null>;
260
260
  export function getWasmExportNames(wasmBytes: Uint8Array): string[];
261
+
262
+ // --- Runtime Host ---
263
+
264
+ export interface RowHandle {
265
+ schemaFileId: string;
266
+ rowId: number;
267
+ }
268
+
269
+ export interface RuntimeRowView {
270
+ handle: RowHandle;
271
+ payload: unknown;
272
+ }
273
+
274
+ export interface RuntimeRowQueryResult {
275
+ columns: string[];
276
+ rows: unknown[][];
277
+ rowCount: number;
278
+ }
279
+
280
+ export interface FlatSqlRuntimeStore {
281
+ appendRow(options: { schemaFileId: string; payload?: unknown }): RowHandle;
282
+ listRows(schemaFileId?: string | null): RuntimeRowView[];
283
+ query(sql: string): RuntimeRowQueryResult;
284
+ resolveRow(handle: RowHandle): RuntimeRowView | null;
285
+ }
286
+
287
+ export interface RuntimeRegionDescriptor {
288
+ regionId: number;
289
+ layoutId: string;
290
+ recordByteLength: number;
291
+ alignment: number;
292
+ recordCount: number;
293
+ }
294
+
295
+ export interface RuntimeRegionRecord {
296
+ regionId: number;
297
+ recordIndex: number;
298
+ layoutId: string;
299
+ recordByteLength: number;
300
+ alignment: number;
301
+ byteLength: number;
302
+ bytes: Uint8Array;
303
+ }
304
+
305
+ export interface RuntimeRegionExternalRecordView {
306
+ regionId: number;
307
+ recordIndex: number;
308
+ layoutId: string;
309
+ recordByteLength: number;
310
+ alignment: number;
311
+ byteOffset?: number;
312
+ buffer?: ArrayBufferLike;
313
+ elementType?: string;
314
+ elementCount?: number;
315
+ strideElements?: number;
316
+ [key: string]: unknown;
317
+ }
318
+
319
+ export interface RuntimeRegionRecordViewRequest {
320
+ regionId: number;
321
+ recordIndex: number;
322
+ }
323
+
324
+ export interface RuntimeRegionStore {
325
+ allocateRegion(options: {
326
+ layoutId: string;
327
+ recordByteLength: number;
328
+ alignment?: number;
329
+ initialRecords?: Array<Uint8Array | ArrayBuffer | ArrayBufferView | null | undefined>;
330
+ }): RuntimeRegionDescriptor;
331
+ registerExternalRegion(options: {
332
+ layoutId: string;
333
+ recordByteLength: number;
334
+ alignment?: number;
335
+ recordCount?: number;
336
+ getRecordCount?: (regionId: number) => number;
337
+ resolveRecordView?: (query: {
338
+ regionId: number;
339
+ recordIndex: number;
340
+ layoutId: string;
341
+ recordByteLength: number;
342
+ alignment: number;
343
+ }) =>
344
+ | Omit<
345
+ RuntimeRegionExternalRecordView,
346
+ "regionId" | "recordIndex" | "layoutId" | "recordByteLength" | "alignment"
347
+ >
348
+ | null
349
+ | undefined;
350
+ }): RuntimeRegionDescriptor;
351
+ setRegionRecordCount(regionId: number, recordCount: number): RuntimeRegionDescriptor | null;
352
+ describeRegion(regionId: number): RuntimeRegionDescriptor | null;
353
+ resolveRecord(options: RuntimeRegionRecordViewRequest): RuntimeRegionRecord | null;
354
+ resolveRecordView(
355
+ options: RuntimeRegionRecordViewRequest,
356
+ ): RuntimeRegionRecord | RuntimeRegionExternalRecordView | null;
357
+ }
358
+
359
+ export interface InstalledRuntimeModule {
360
+ moduleId: string;
361
+ metadata: unknown;
362
+ methodIds: string[];
363
+ }
364
+
365
+ export interface RuntimeModuleRegistry {
366
+ installModule(definition: {
367
+ moduleId: string;
368
+ methods?: Record<string, (...args: unknown[]) => unknown>;
369
+ metadata?: unknown;
370
+ }): InstalledRuntimeModule;
371
+ invokeModule(
372
+ moduleId: string,
373
+ methodId: string,
374
+ ...args: unknown[]
375
+ ): Promise<unknown>;
376
+ listModules(): InstalledRuntimeModule[];
377
+ loadModule(moduleId: string): {
378
+ moduleId: string;
379
+ methods: Record<string, (...args: unknown[]) => unknown>;
380
+ metadata: unknown;
381
+ } | null;
382
+ unloadModule(moduleId: string): boolean;
383
+ }
384
+
385
+ export interface RuntimeHost {
386
+ rows: FlatSqlRuntimeStore;
387
+ regions: RuntimeRegionStore;
388
+ moduleRegistry: RuntimeModuleRegistry;
389
+ }
390
+
391
+ export function createFlatSqlRuntimeStore(): FlatSqlRuntimeStore;
392
+ export function createRuntimeRegionStore(): RuntimeRegionStore;
393
+ export function createModuleRegistry(): RuntimeModuleRegistry;
394
+ export function createRuntimeHost(options?: {
395
+ rows?: FlatSqlRuntimeStore;
396
+ regions?: RuntimeRegionStore;
397
+ moduleRegistry?: RuntimeModuleRegistry;
398
+ }): RuntimeHost;
261
399
  export function getWasmExportNamesFromFile(wasmPath: string): Promise<string[]>;
262
400
 
263
401
  // --- Auth ---
@@ -678,6 +816,7 @@ export {
678
816
  createPublicationProtectionDemoSummary,
679
817
  createModuleHarness,
680
818
  createPluginInvokeProcessClient,
819
+ createWasmEdgeStreamProcessClient,
681
820
  describeCapabilityRuntimeSurface,
682
821
  generateManifestHarnessPlan,
683
822
  materializeHarnessScenario,
@@ -898,6 +1037,62 @@ export interface HostcallBridge {
898
1037
  getLastResponseJson(): unknown;
899
1038
  }
900
1039
 
1040
+ export interface BrowserFilesystemShim {
1041
+ filesystemRoot?: string;
1042
+ resolvePath(path?: string): string;
1043
+ readFile(
1044
+ path: string,
1045
+ options?: { encoding?: string | null },
1046
+ ): Promise<string | Uint8Array>;
1047
+ writeFile(
1048
+ path: string,
1049
+ value: Uint8Array | ArrayBuffer | ArrayBufferView | string,
1050
+ options?: { encoding?: string | null },
1051
+ ): Promise<{ path: string }>;
1052
+ appendFile(
1053
+ path: string,
1054
+ value: Uint8Array | ArrayBuffer | ArrayBufferView | string,
1055
+ options?: { encoding?: string | null },
1056
+ ): Promise<{ path: string }>;
1057
+ deleteFile(path: string): Promise<{ path: string }>;
1058
+ mkdir(
1059
+ path: string,
1060
+ options?: { recursive?: boolean },
1061
+ ): Promise<{ path: string }>;
1062
+ readdir(path?: string): Promise<NodeHostFilesystemEntry[]>;
1063
+ stat(path: string): Promise<NodeHostFilesystemStat>;
1064
+ rename(
1065
+ fromPath: string,
1066
+ toPath: string,
1067
+ ): Promise<{ from: string; to: string }>;
1068
+ }
1069
+
1070
+ export interface BrowserEdgeShims {
1071
+ fetch?: (...args: any[]) => Promise<any>;
1072
+ WebSocket?: any;
1073
+ crypto?: any;
1074
+ performance?: {
1075
+ now(): number;
1076
+ timeOrigin: number;
1077
+ };
1078
+ filesystem?: BrowserFilesystemShim;
1079
+ }
1080
+
1081
+ export interface BrowserHostOptions {
1082
+ capabilities?: string[];
1083
+ edgeShims?: BrowserEdgeShims;
1084
+ contextStore?: Map<string, Map<string, unknown>>;
1085
+ fetch?: (...args: any[]) => Promise<any>;
1086
+ WebSocket?: any;
1087
+ crypto?: any;
1088
+ performance?: {
1089
+ now(): number;
1090
+ timeOrigin: number;
1091
+ };
1092
+ filesystem?: BrowserFilesystemShim;
1093
+ filesystemRoot?: string;
1094
+ }
1095
+
901
1096
  export interface NodeHostOptions {
902
1097
  manifest?: PluginManifest;
903
1098
  grantedCapabilities?: string[];
@@ -933,6 +1128,12 @@ export class HostFilesystemScopeError extends Error {
933
1128
  filesystemRoot: string | null;
934
1129
  }
935
1130
 
1131
+ export class BrowserFilesystemScopeError extends Error {
1132
+ code: string;
1133
+ requestedPath: string | null;
1134
+ filesystemRoot: string | null;
1135
+ }
1136
+
936
1137
  export class NodeHost {
937
1138
  runtimeTarget: string;
938
1139
  filesystemRoot: string;
@@ -1183,14 +1384,93 @@ export class NodeHost {
1183
1384
  invoke(operation: string, params?: Record<string, any>): Promise<any>;
1184
1385
  }
1185
1386
 
1387
+ export class BrowserHost {
1388
+ runtimeTarget: string;
1389
+ filesystemRoot: string;
1390
+ clock: {
1391
+ now(): number;
1392
+ monotonicNow(): number;
1393
+ nowIso(): string;
1394
+ };
1395
+ random: {
1396
+ bytes(length: number): Uint8Array;
1397
+ };
1398
+ timers: {
1399
+ delay(ms: number): Promise<void>;
1400
+ };
1401
+ schedule: {
1402
+ parse(expression: string): CronSchedule;
1403
+ matches(expression: string | CronSchedule, date?: Date | number | string): boolean;
1404
+ next(expression: string | CronSchedule, from?: Date | number | string): Date;
1405
+ };
1406
+ http: {
1407
+ request<TBody = unknown>(options: NodeHostHttpRequest): Promise<NodeHostHttpResponse<TBody>>;
1408
+ };
1409
+ websocket: {
1410
+ exchange<TBody = unknown>(options: {
1411
+ url: string;
1412
+ protocols?: string | string[];
1413
+ message?: Uint8Array | ArrayBuffer | ArrayBufferView | string | null;
1414
+ responseType?: "bytes" | "utf8" | "json";
1415
+ timeoutMs?: number;
1416
+ expectResponse?: boolean;
1417
+ }): Promise<NodeHostWebSocketResponse<TBody>>;
1418
+ };
1419
+ context: {
1420
+ get(scope: string, key: string): unknown;
1421
+ set(scope: string, key: string, value: unknown): void;
1422
+ delete(scope: string, key: string): void;
1423
+ listKeys(scope: string): string[];
1424
+ listScopes(): string[];
1425
+ };
1426
+ crypto: {
1427
+ sha256(data: Uint8Array | ArrayBuffer | ArrayBufferView | string): Promise<Uint8Array>;
1428
+ sha512(data: Uint8Array | ArrayBuffer | ArrayBufferView | string): Promise<Uint8Array>;
1429
+ aesGcmEncrypt(options: {
1430
+ key: Uint8Array | ArrayBuffer | ArrayBufferView;
1431
+ plaintext: Uint8Array | ArrayBuffer | ArrayBufferView;
1432
+ iv?: Uint8Array | ArrayBuffer | ArrayBufferView;
1433
+ }): Promise<{ ciphertext: Uint8Array; iv: Uint8Array | ArrayBuffer | ArrayBufferView }>;
1434
+ aesGcmDecrypt(options: {
1435
+ key: Uint8Array | ArrayBuffer | ArrayBufferView;
1436
+ ciphertext: Uint8Array | ArrayBuffer | ArrayBufferView;
1437
+ iv: Uint8Array | ArrayBuffer | ArrayBufferView;
1438
+ }): Promise<Uint8Array>;
1439
+ };
1440
+ filesystem: BrowserFilesystemShim;
1441
+ constructor(options?: BrowserHostOptions);
1442
+ listCapabilities(): string[];
1443
+ listSupportedCapabilities(): string[];
1444
+ listOperations(): string[];
1445
+ hasCapability(capability: string): boolean;
1446
+ assertCapability(capability: string, operation?: string | null): void;
1447
+ }
1448
+
1186
1449
  export const NodeHostSupportedCapabilities: readonly string[];
1187
1450
  export const NodeHostSupportedOperations: readonly string[];
1451
+ export const BrowserHostSupportedCapabilities: readonly string[];
1452
+ export const BrowserHostSupportedOperations: readonly string[];
1188
1453
  export const DEFAULT_HOSTCALL_IMPORT_MODULE: string;
1189
1454
  export const HOSTCALL_STATUS_OK: number;
1190
1455
  export const HOSTCALL_STATUS_ERROR: number;
1191
1456
  export const NodeHostSyncHostcallOperations: readonly string[];
1192
1457
 
1193
1458
  export function createNodeHost(options?: NodeHostOptions): NodeHost;
1459
+ export function createBrowserHost(options?: BrowserHostOptions): BrowserHost;
1460
+ export function createMemoryFilesystemEdgeShim(options?: {
1461
+ filesystemRoot?: string;
1462
+ }): BrowserFilesystemShim;
1463
+ export function createBrowserEdgeShims(options?: {
1464
+ fetch?: (...args: any[]) => Promise<any>;
1465
+ WebSocket?: any;
1466
+ crypto?: any;
1467
+ performance?: {
1468
+ now(): number;
1469
+ timeOrigin: number;
1470
+ };
1471
+ filesystem?: BrowserFilesystemShim;
1472
+ filesystemRoot?: string;
1473
+ }): BrowserEdgeShims;
1194
1474
  export function parseCronExpression(expression: string): CronSchedule;
1195
1475
  export function matchesCronExpression(
1196
1476
  expression: string | CronSchedule,
@@ -1222,6 +1502,90 @@ export function createNodeHostSyncHostcallBridge(options: {
1222
1502
  maxRequestBytes?: number;
1223
1503
  maxResponseBytes?: number;
1224
1504
  }): HostcallBridge;
1505
+ export class WasiExitError extends Error {
1506
+ code: number;
1507
+ }
1508
+ export interface BrowserWasiShim {
1509
+ imports: Record<string, Record<string, (...args: number[]) => number>>;
1510
+ setMemory(mem: { buffer: ArrayBuffer | SharedArrayBuffer }): void;
1511
+ getMemory(): { buffer: ArrayBuffer | SharedArrayBuffer } | null;
1512
+ flushOutput(): void;
1513
+ stdout: Uint8Array;
1514
+ stderr: Uint8Array;
1515
+ }
1516
+ export function createBrowserWasiShim(options?: {
1517
+ args?: string[];
1518
+ env?: Record<string, string>;
1519
+ stdinBytes?: Uint8Array | ArrayBuffer | ArrayBufferView;
1520
+ logOutput?: boolean;
1521
+ performance?: {
1522
+ now(): number;
1523
+ timeOrigin: number;
1524
+ };
1525
+ }): BrowserWasiShim;
1526
+ export interface BrowserModuleHarness {
1527
+ runtime: {
1528
+ kind: "browser";
1529
+ profile: string;
1530
+ surface: string;
1531
+ };
1532
+ instance: WebAssembly.Instance;
1533
+ module: WebAssembly.Module;
1534
+ host: BrowserHost;
1535
+ bridge: HostcallBridge | null;
1536
+ wasi: BrowserWasiShim;
1537
+ invokeRaw(
1538
+ requestBytes: Uint8Array | ArrayBuffer | ArrayBufferView,
1539
+ ): Promise<Uint8Array>;
1540
+ invoke(request: {
1541
+ methodId?: string | null;
1542
+ inputs?: HarnessInputFrame[];
1543
+ }): Promise<{
1544
+ statusCode: number;
1545
+ errorCode?: string | null;
1546
+ errorMessage?: string | null;
1547
+ outputs: HarnessInputFrame[];
1548
+ }>;
1549
+ readManifest(): Uint8Array | null;
1550
+ destroy(): void;
1551
+ }
1552
+ export function detectArtifactProfile(wasmModule: WebAssembly.Module): string;
1553
+ export function createBrowserModuleHarness(options?: {
1554
+ wasmSource: Uint8Array | ArrayBuffer | string | WebAssembly.Module | unknown;
1555
+ host?: BrowserHost;
1556
+ hostOptions?: BrowserHostOptions;
1557
+ args?: string[];
1558
+ env?: Record<string, string>;
1559
+ surface?: "direct" | "command";
1560
+ performance?: {
1561
+ now(): number;
1562
+ timeOrigin: number;
1563
+ };
1564
+ logOutput?: boolean;
1565
+ }): Promise<BrowserModuleHarness>;
1566
+ export function loadModule(options?: {
1567
+ wasmSource: Uint8Array | ArrayBuffer | string | WebAssembly.Module | unknown;
1568
+ host?: BrowserHost;
1569
+ hostOptions?: BrowserHostOptions;
1570
+ args?: string[];
1571
+ env?: Record<string, string | undefined>;
1572
+ surface?: "direct" | "command";
1573
+ runtimeKind?: "wasmedge" | "process";
1574
+ wasmEdgeBinary?: string;
1575
+ wasmEdgeRunnerBinary?: string;
1576
+ enableThreads?: boolean;
1577
+ hostProfile?: "runtime-host";
1578
+ modules?: RuntimeHostTestModuleDefinition[];
1579
+ defaultModuleId?: string;
1580
+ metadata?: unknown;
1581
+ command?: string;
1582
+ cwd?: string;
1583
+ }): Promise<BrowserModuleHarness | ModuleHarness>;
1584
+ export function inspectModule(source: Uint8Array | ArrayBuffer | WebAssembly.Module): Promise<{
1585
+ profile: string;
1586
+ exports: string[];
1587
+ imports: WebAssembly.ModuleImportDescriptor[];
1588
+ }>;
1225
1589
 
1226
1590
  // --- Runtime constants ---
1227
1591
 
package/src/index.js CHANGED
@@ -7,6 +7,7 @@ export * from "./bundle/index.js";
7
7
  export * from "./capabilities.js";
8
8
  export * from "./standards/index.js";
9
9
  export * from "./host/index.js";
10
+ export * from "./runtime-host/index.js";
10
11
  export * from "./invoke/index.js";
11
12
  export * from "./testing/index.js";
12
13
  export * from "./deployment/index.js";
@@ -1,4 +1,4 @@
1
- import * as flatbuffers from "flatbuffers";
1
+ import * as flatbuffers from "flatbuffers/mjs/flatbuffers.js";
2
2
 
3
3
  import {
4
4
  PluginInvokeRequest,
@@ -1,4 +1,4 @@
1
- import * as flatbuffers from "flatbuffers";
1
+ import * as flatbuffers from "flatbuffers/mjs/flatbuffers.js";
2
2
 
3
3
  import {
4
4
  CapabilityKind,