space-data-module-sdk 0.2.7 → 0.2.8

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/README.md CHANGED
@@ -143,6 +143,20 @@ The detailed edge cases and the current WASI-vs-host portability boundary are
143
143
  documented in
144
144
  [`docs/testing-harness.md`](./docs/testing-harness.md).
145
145
 
146
+ If a manifest declares `runtimeTargets: ["wasi"]`, this SDK now treats that as
147
+ "standalone WASI, no host wrapper required." In practice that currently means:
148
+
149
+ - the artifact must declare the `command` invoke surface
150
+ - declared capabilities must stay within the pure WASI subset:
151
+ `logging`, `clock`, `random`, `filesystem`, `pipe`
152
+ - hosted protocols may only use `wasi-pipe` transport
153
+
154
+ For maximum server-side portability with guest-owned network services, use
155
+ `runtimeTargets: ["wasmedge"]`. That target is intended for WasmEdge
156
+ environments with socket/TLS extensions, while plain `wasi` remains the strict
157
+ no-wrapper baseline. The Node-RED-oriented parity map lives in
158
+ [`docs/node-red-default-node-parity.md`](./docs/node-red-default-node-parity.md).
159
+
146
160
  ## Install
147
161
 
148
162
  ```bash
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "space-data-module-sdk",
3
- "version": "0.2.7",
3
+ "version": "0.2.8",
4
4
  "description": "Module SDK for building, validating, signing, and deploying WebAssembly modules on the Space Data Network.",
5
5
  "type": "module",
6
6
  "types": "./src/index.d.ts",
@@ -179,6 +179,7 @@ table PluginManifest {
179
179
  build_artifacts: [BuildArtifact];
180
180
  abi_version: uint32 = 1;
181
181
  invoke_surfaces: [InvokeSurface];
182
+ runtime_targets: [string];
182
183
  }
183
184
 
184
185
  root_type PluginManifest;
@@ -5,6 +5,7 @@ import {
5
5
  loadManifestFromFile,
6
6
  loadComplianceConfig,
7
7
  RecommendedCapabilityIds,
8
+ StandaloneWasiCapabilityIds,
8
9
  resolveManifestFiles,
9
10
  validatePluginArtifact,
10
11
  validatePluginManifest,
@@ -49,8 +50,8 @@ export {
49
50
  loadManifestFromFile,
50
51
  loadComplianceConfig,
51
52
  RecommendedCapabilityIds,
53
+ StandaloneWasiCapabilityIds,
52
54
  resolveManifestFiles,
53
55
  validatePluginArtifact,
54
56
  validatePluginManifest,
55
57
  };
56
-
@@ -52,7 +52,16 @@ export const RecommendedCapabilityIds = Object.freeze([
52
52
  "render_hooks",
53
53
  ]);
54
54
 
55
+ export const StandaloneWasiCapabilityIds = Object.freeze([
56
+ "logging",
57
+ "clock",
58
+ "random",
59
+ "filesystem",
60
+ "pipe",
61
+ ]);
62
+
55
63
  const RecommendedCapabilitySet = new Set(RecommendedCapabilityIds);
64
+ const StandaloneWasiCapabilitySet = new Set(StandaloneWasiCapabilityIds);
56
65
  const RecommendedRuntimeTargets = Object.freeze(Object.values(RuntimeTarget));
57
66
  const RecommendedRuntimeTargetSet = new Set(RecommendedRuntimeTargets);
58
67
  const DrainPolicySet = new Set(Object.values(DrainPolicy));
@@ -83,6 +92,9 @@ const BrowserIncompatibleCapabilitySet = new Set([
83
92
  "entity_access",
84
93
  "render_hooks",
85
94
  ]);
95
+ const StandaloneWasiProtocolTransportKindSet = new Set([
96
+ ProtocolTransportKind.WASI_PIPE,
97
+ ]);
86
98
  const IgnoredDirectoryNames = new Set([
87
99
  ".git",
88
100
  ".hg",
@@ -963,6 +975,66 @@ function validateRuntimeTargets(runtimeTargets, declaredCapabilities, issues, so
963
975
  }
964
976
  }
965
977
 
978
+ function validateStandaloneWasiTarget(
979
+ manifest,
980
+ normalizedInvokeSurfaces,
981
+ declaredCapabilities,
982
+ issues,
983
+ sourceName,
984
+ ) {
985
+ const runtimeTargets = Array.isArray(manifest?.runtimeTargets)
986
+ ? manifest.runtimeTargets
987
+ : [];
988
+ if (!runtimeTargets.includes(RuntimeTarget.WASI)) {
989
+ return;
990
+ }
991
+
992
+ if (!normalizedInvokeSurfaces.includes(InvokeSurface.COMMAND)) {
993
+ pushIssue(
994
+ issues,
995
+ "error",
996
+ "missing-wasi-command-surface",
997
+ 'Artifacts targeting the canonical "wasi" runtime must declare the "command" invoke surface so they can run as standalone WASI programs without host wrappers.',
998
+ `${sourceName}.invokeSurfaces`,
999
+ );
1000
+ }
1001
+
1002
+ if (Array.isArray(declaredCapabilities)) {
1003
+ for (const capability of declaredCapabilities) {
1004
+ if (!StandaloneWasiCapabilitySet.has(capability)) {
1005
+ pushIssue(
1006
+ issues,
1007
+ "error",
1008
+ "capability-wasi-standalone-conflict",
1009
+ `Capability "${capability}" is not available to a standalone WASI artifact without host wrappers.`,
1010
+ `${sourceName}.capabilities`,
1011
+ );
1012
+ }
1013
+ }
1014
+ }
1015
+
1016
+ if (!Array.isArray(manifest?.protocols)) {
1017
+ return;
1018
+ }
1019
+ manifest.protocols.forEach((protocol, index) => {
1020
+ const normalizedTransportKind = normalizeProtocolTransportKind(
1021
+ protocol?.transportKind,
1022
+ );
1023
+ if (
1024
+ normalizedTransportKind &&
1025
+ !StandaloneWasiProtocolTransportKindSet.has(normalizedTransportKind)
1026
+ ) {
1027
+ pushIssue(
1028
+ issues,
1029
+ "error",
1030
+ "protocol-wasi-standalone-conflict",
1031
+ `Protocol "${protocol?.protocolId ?? "protocol"}" uses transportKind "${protocol?.transportKind}", which requires a host wrapper rather than a standalone WASI runtime.`,
1032
+ `${sourceName}.protocols[${index}].transportKind`,
1033
+ );
1034
+ }
1035
+ });
1036
+ }
1037
+
966
1038
  function validateInvokeSurfaces(invokeSurfaces, issues, sourceName) {
967
1039
  if (invokeSurfaces === undefined) {
968
1040
  return [];
@@ -1086,7 +1158,11 @@ export function validatePluginManifest(manifest, options = {}) {
1086
1158
  issues,
1087
1159
  sourceName,
1088
1160
  );
1089
- validateInvokeSurfaces(manifest.invokeSurfaces, issues, sourceName);
1161
+ const normalizedInvokeSurfaces = validateInvokeSurfaces(
1162
+ manifest.invokeSurfaces,
1163
+ issues,
1164
+ sourceName,
1165
+ );
1090
1166
 
1091
1167
  if (!Array.isArray(manifest.externalInterfaces)) {
1092
1168
  pushIssue(
@@ -1227,6 +1303,14 @@ export function validatePluginManifest(manifest, options = {}) {
1227
1303
  }
1228
1304
  }
1229
1305
 
1306
+ validateStandaloneWasiTarget(
1307
+ manifest,
1308
+ normalizedInvokeSurfaces,
1309
+ declaredCapabilities,
1310
+ issues,
1311
+ sourceName,
1312
+ );
1313
+
1230
1314
  if (manifest.schemasUsed !== undefined && !Array.isArray(manifest.schemasUsed)) {
1231
1315
  pushIssue(
1232
1316
  issues,
@@ -40,6 +40,9 @@ export declare class PluginManifest implements flatbuffers.IUnpackableObject<Plu
40
40
  invokeSurfaces(index: number): InvokeSurface | null;
41
41
  invokeSurfacesLength(): number;
42
42
  invokeSurfacesArray(): Uint8Array | null;
43
+ runtimeTargets(index: number): string | null;
44
+ runtimeTargets(index: number, optionalEncoding: flatbuffers.Encoding): string | Uint8Array | null;
45
+ runtimeTargetsLength(): number;
43
46
  static startPluginManifest(builder: flatbuffers.Builder): void;
44
47
  static addPluginId(builder: flatbuffers.Builder, pluginIdOffset: flatbuffers.Offset): void;
45
48
  static addName(builder: flatbuffers.Builder, nameOffset: flatbuffers.Offset): void;
@@ -67,10 +70,13 @@ export declare class PluginManifest implements flatbuffers.IUnpackableObject<Plu
67
70
  static addInvokeSurfaces(builder: flatbuffers.Builder, invokeSurfacesOffset: flatbuffers.Offset): void;
68
71
  static createInvokeSurfacesVector(builder: flatbuffers.Builder, data: InvokeSurface[]): flatbuffers.Offset;
69
72
  static startInvokeSurfacesVector(builder: flatbuffers.Builder, numElems: number): void;
73
+ static addRuntimeTargets(builder: flatbuffers.Builder, runtimeTargetsOffset: flatbuffers.Offset): void;
74
+ static createRuntimeTargetsVector(builder: flatbuffers.Builder, data: flatbuffers.Offset[]): flatbuffers.Offset;
75
+ static startRuntimeTargetsVector(builder: flatbuffers.Builder, numElems: number): void;
70
76
  static endPluginManifest(builder: flatbuffers.Builder): flatbuffers.Offset;
71
77
  static finishPluginManifestBuffer(builder: flatbuffers.Builder, offset: flatbuffers.Offset): void;
72
78
  static finishSizePrefixedPluginManifestBuffer(builder: flatbuffers.Builder, offset: flatbuffers.Offset): void;
73
- static createPluginManifest(builder: flatbuffers.Builder, pluginIdOffset: flatbuffers.Offset, nameOffset: flatbuffers.Offset, versionOffset: flatbuffers.Offset, pluginFamily: PluginFamily, methodsOffset: flatbuffers.Offset, capabilitiesOffset: flatbuffers.Offset, timersOffset: flatbuffers.Offset, protocolsOffset: flatbuffers.Offset, schemasUsedOffset: flatbuffers.Offset, buildArtifactsOffset: flatbuffers.Offset, abiVersion: number, invokeSurfacesOffset: flatbuffers.Offset): flatbuffers.Offset;
79
+ static createPluginManifest(builder: flatbuffers.Builder, pluginIdOffset: flatbuffers.Offset, nameOffset: flatbuffers.Offset, versionOffset: flatbuffers.Offset, pluginFamily: PluginFamily, methodsOffset: flatbuffers.Offset, capabilitiesOffset: flatbuffers.Offset, timersOffset: flatbuffers.Offset, protocolsOffset: flatbuffers.Offset, schemasUsedOffset: flatbuffers.Offset, buildArtifactsOffset: flatbuffers.Offset, abiVersion: number, invokeSurfacesOffset: flatbuffers.Offset, runtimeTargetsOffset: flatbuffers.Offset): flatbuffers.Offset;
74
80
  unpack(): PluginManifestT;
75
81
  unpackTo(_o: PluginManifestT): void;
76
82
  }
@@ -87,7 +93,8 @@ export declare class PluginManifestT implements flatbuffers.IGeneratedObject {
87
93
  buildArtifacts: (BuildArtifactT)[];
88
94
  abiVersion: number;
89
95
  invokeSurfaces: (InvokeSurface)[];
90
- constructor(pluginId?: string | Uint8Array | null, name?: string | Uint8Array | null, version?: string | Uint8Array | null, pluginFamily?: PluginFamily, methods?: (MethodManifestT)[], capabilities?: (HostCapabilityT)[], timers?: (TimerSpecT)[], protocols?: (ProtocolSpecT)[], schemasUsed?: (FlatBufferTypeRefT)[], buildArtifacts?: (BuildArtifactT)[], abiVersion?: number, invokeSurfaces?: (InvokeSurface)[]);
96
+ runtimeTargets: string[];
97
+ constructor(pluginId?: string | Uint8Array | null, name?: string | Uint8Array | null, version?: string | Uint8Array | null, pluginFamily?: PluginFamily, methods?: (MethodManifestT)[], capabilities?: (HostCapabilityT)[], timers?: (TimerSpecT)[], protocols?: (ProtocolSpecT)[], schemasUsed?: (FlatBufferTypeRefT)[], buildArtifacts?: (BuildArtifactT)[], abiVersion?: number, invokeSurfaces?: (InvokeSurface)[], runtimeTargets?: string[]);
91
98
  pack(builder: flatbuffers.Builder): flatbuffers.Offset;
92
99
  }
93
- //# sourceMappingURL=plugin-manifest.d.ts.map
100
+ //# sourceMappingURL=plugin-manifest.d.ts.map
@@ -109,8 +109,16 @@ export class PluginManifest {
109
109
  const offset = this.bb.__offset(this.bb_pos, 26);
110
110
  return offset ? new Uint8Array(this.bb.bytes().buffer, this.bb.bytes().byteOffset + this.bb.__vector(this.bb_pos + offset), this.bb.__vector_len(this.bb_pos + offset)) : null;
111
111
  }
112
+ runtimeTargets(index, optionalEncoding) {
113
+ const offset = this.bb.__offset(this.bb_pos, 28);
114
+ return offset ? this.bb.__string(this.bb.__vector(this.bb_pos + offset) + index * 4, optionalEncoding) : null;
115
+ }
116
+ runtimeTargetsLength() {
117
+ const offset = this.bb.__offset(this.bb_pos, 28);
118
+ return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0;
119
+ }
112
120
  static startPluginManifest(builder) {
113
- builder.startObject(12);
121
+ builder.startObject(13);
114
122
  }
115
123
  static addPluginId(builder, pluginIdOffset) {
116
124
  builder.addFieldOffset(0, pluginIdOffset, 0);
@@ -218,6 +226,19 @@ export class PluginManifest {
218
226
  static startInvokeSurfacesVector(builder, numElems) {
219
227
  builder.startVector(1, numElems, 1);
220
228
  }
229
+ static addRuntimeTargets(builder, runtimeTargetsOffset) {
230
+ builder.addFieldOffset(12, runtimeTargetsOffset, 0);
231
+ }
232
+ static createRuntimeTargetsVector(builder, data) {
233
+ builder.startVector(4, data.length, 4);
234
+ for (let i = data.length - 1; i >= 0; i--) {
235
+ builder.addOffset(data[i]);
236
+ }
237
+ return builder.endVector();
238
+ }
239
+ static startRuntimeTargetsVector(builder, numElems) {
240
+ builder.startVector(4, numElems, 4);
241
+ }
221
242
  static endPluginManifest(builder) {
222
243
  const offset = builder.endObject();
223
244
  builder.requiredField(offset, 4); // plugin_id
@@ -229,7 +250,7 @@ export class PluginManifest {
229
250
  static finishSizePrefixedPluginManifestBuffer(builder, offset) {
230
251
  builder.finish(offset, 'PMAN', true);
231
252
  }
232
- static createPluginManifest(builder, pluginIdOffset, nameOffset, versionOffset, pluginFamily, methodsOffset, capabilitiesOffset, timersOffset, protocolsOffset, schemasUsedOffset, buildArtifactsOffset, abiVersion, invokeSurfacesOffset) {
253
+ static createPluginManifest(builder, pluginIdOffset, nameOffset, versionOffset, pluginFamily, methodsOffset, capabilitiesOffset, timersOffset, protocolsOffset, schemasUsedOffset, buildArtifactsOffset, abiVersion, invokeSurfacesOffset, runtimeTargetsOffset) {
233
254
  PluginManifest.startPluginManifest(builder);
234
255
  PluginManifest.addPluginId(builder, pluginIdOffset);
235
256
  PluginManifest.addName(builder, nameOffset);
@@ -243,10 +264,11 @@ export class PluginManifest {
243
264
  PluginManifest.addBuildArtifacts(builder, buildArtifactsOffset);
244
265
  PluginManifest.addAbiVersion(builder, abiVersion);
245
266
  PluginManifest.addInvokeSurfaces(builder, invokeSurfacesOffset);
267
+ PluginManifest.addRuntimeTargets(builder, runtimeTargetsOffset);
246
268
  return PluginManifest.endPluginManifest(builder);
247
269
  }
248
270
  unpack() {
249
- return new PluginManifestT(this.pluginId(), this.name(), this.version(), this.pluginFamily(), this.bb.createObjList(this.methods.bind(this), this.methodsLength()), this.bb.createObjList(this.capabilities.bind(this), this.capabilitiesLength()), this.bb.createObjList(this.timers.bind(this), this.timersLength()), this.bb.createObjList(this.protocols.bind(this), this.protocolsLength()), this.bb.createObjList(this.schemasUsed.bind(this), this.schemasUsedLength()), this.bb.createObjList(this.buildArtifacts.bind(this), this.buildArtifactsLength()), this.abiVersion(), this.bb.createScalarList(this.invokeSurfaces.bind(this), this.invokeSurfacesLength()));
271
+ return new PluginManifestT(this.pluginId(), this.name(), this.version(), this.pluginFamily(), this.bb.createObjList(this.methods.bind(this), this.methodsLength()), this.bb.createObjList(this.capabilities.bind(this), this.capabilitiesLength()), this.bb.createObjList(this.timers.bind(this), this.timersLength()), this.bb.createObjList(this.protocols.bind(this), this.protocolsLength()), this.bb.createObjList(this.schemasUsed.bind(this), this.schemasUsedLength()), this.bb.createObjList(this.buildArtifacts.bind(this), this.buildArtifactsLength()), this.abiVersion(), this.bb.createScalarList(this.invokeSurfaces.bind(this), this.invokeSurfacesLength()), this.bb.createScalarList(this.runtimeTargets.bind(this), this.runtimeTargetsLength()));
250
272
  }
251
273
  unpackTo(_o) {
252
274
  _o.pluginId = this.pluginId();
@@ -261,6 +283,7 @@ export class PluginManifest {
261
283
  _o.buildArtifacts = this.bb.createObjList(this.buildArtifacts.bind(this), this.buildArtifactsLength());
262
284
  _o.abiVersion = this.abiVersion();
263
285
  _o.invokeSurfaces = this.bb.createScalarList(this.invokeSurfaces.bind(this), this.invokeSurfacesLength());
286
+ _o.runtimeTargets = this.bb.createScalarList(this.runtimeTargets.bind(this), this.runtimeTargetsLength());
264
287
  }
265
288
  }
266
289
  export class PluginManifestT {
@@ -276,7 +299,8 @@ export class PluginManifestT {
276
299
  buildArtifacts;
277
300
  abiVersion;
278
301
  invokeSurfaces;
279
- constructor(pluginId = null, name = null, version = null, pluginFamily = PluginFamily.ANALYSIS, methods = [], capabilities = [], timers = [], protocols = [], schemasUsed = [], buildArtifacts = [], abiVersion = 1, invokeSurfaces = []) {
302
+ runtimeTargets;
303
+ constructor(pluginId = null, name = null, version = null, pluginFamily = PluginFamily.ANALYSIS, methods = [], capabilities = [], timers = [], protocols = [], schemasUsed = [], buildArtifacts = [], abiVersion = 1, invokeSurfaces = [], runtimeTargets = []) {
280
304
  this.pluginId = pluginId;
281
305
  this.name = name;
282
306
  this.version = version;
@@ -289,6 +313,7 @@ export class PluginManifestT {
289
313
  this.buildArtifacts = buildArtifacts;
290
314
  this.abiVersion = abiVersion;
291
315
  this.invokeSurfaces = invokeSurfaces;
316
+ this.runtimeTargets = runtimeTargets;
292
317
  }
293
318
  pack(builder) {
294
319
  const pluginId = (this.pluginId !== null ? builder.createString(this.pluginId) : 0);
@@ -301,7 +326,8 @@ export class PluginManifestT {
301
326
  const schemasUsed = PluginManifest.createSchemasUsedVector(builder, builder.createObjectOffsetList(this.schemasUsed));
302
327
  const buildArtifacts = PluginManifest.createBuildArtifactsVector(builder, builder.createObjectOffsetList(this.buildArtifacts));
303
328
  const invokeSurfaces = PluginManifest.createInvokeSurfacesVector(builder, this.invokeSurfaces);
304
- return PluginManifest.createPluginManifest(builder, pluginId, name, version, this.pluginFamily, methods, capabilities, timers, protocols, schemasUsed, buildArtifacts, this.abiVersion, invokeSurfaces);
329
+ const runtimeTargets = PluginManifest.createRuntimeTargetsVector(builder, builder.createObjectOffsetList(this.runtimeTargets));
330
+ return PluginManifest.createPluginManifest(builder, pluginId, name, version, this.pluginFamily, methods, capabilities, timers, protocols, schemasUsed, buildArtifacts, this.abiVersion, invokeSurfaces, runtimeTargets);
305
331
  }
306
332
  }
307
- //# sourceMappingURL=plugin-manifest.js.map
333
+ //# sourceMappingURL=plugin-manifest.js.map
@@ -145,8 +145,20 @@ invokeSurfacesArray():Uint8Array|null {
145
145
  return offset ? new Uint8Array(this.bb!.bytes().buffer, this.bb!.bytes().byteOffset + this.bb!.__vector(this.bb_pos + offset), this.bb!.__vector_len(this.bb_pos + offset)) : null;
146
146
  }
147
147
 
148
+ runtimeTargets(index: number):string|null
149
+ runtimeTargets(index: number, optionalEncoding:flatbuffers.Encoding):string|Uint8Array|null
150
+ runtimeTargets(index: number, optionalEncoding?:any):string|Uint8Array|null {
151
+ const offset = this.bb!.__offset(this.bb_pos, 28);
152
+ return offset ? this.bb!.__string(this.bb!.__vector(this.bb_pos + offset) + index * 4, optionalEncoding) : null;
153
+ }
154
+
155
+ runtimeTargetsLength():number {
156
+ const offset = this.bb!.__offset(this.bb_pos, 28);
157
+ return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0;
158
+ }
159
+
148
160
  static startPluginManifest(builder:flatbuffers.Builder) {
149
- builder.startObject(12);
161
+ builder.startObject(13);
150
162
  }
151
163
 
152
164
  static addPluginId(builder:flatbuffers.Builder, pluginIdOffset:flatbuffers.Offset) {
@@ -281,6 +293,22 @@ static startInvokeSurfacesVector(builder:flatbuffers.Builder, numElems:number) {
281
293
  builder.startVector(1, numElems, 1);
282
294
  }
283
295
 
296
+ static addRuntimeTargets(builder:flatbuffers.Builder, runtimeTargetsOffset:flatbuffers.Offset) {
297
+ builder.addFieldOffset(12, runtimeTargetsOffset, 0);
298
+ }
299
+
300
+ static createRuntimeTargetsVector(builder:flatbuffers.Builder, data:flatbuffers.Offset[]):flatbuffers.Offset {
301
+ builder.startVector(4, data.length, 4);
302
+ for (let i = data.length - 1; i >= 0; i--) {
303
+ builder.addOffset(data[i]!);
304
+ }
305
+ return builder.endVector();
306
+ }
307
+
308
+ static startRuntimeTargetsVector(builder:flatbuffers.Builder, numElems:number) {
309
+ builder.startVector(4, numElems, 4);
310
+ }
311
+
284
312
  static endPluginManifest(builder:flatbuffers.Builder):flatbuffers.Offset {
285
313
  const offset = builder.endObject();
286
314
  builder.requiredField(offset, 4) // plugin_id
@@ -295,7 +323,7 @@ static finishSizePrefixedPluginManifestBuffer(builder:flatbuffers.Builder, offse
295
323
  builder.finish(offset, 'PMAN', true);
296
324
  }
297
325
 
298
- static createPluginManifest(builder:flatbuffers.Builder, pluginIdOffset:flatbuffers.Offset, nameOffset:flatbuffers.Offset, versionOffset:flatbuffers.Offset, pluginFamily:PluginFamily, methodsOffset:flatbuffers.Offset, capabilitiesOffset:flatbuffers.Offset, timersOffset:flatbuffers.Offset, protocolsOffset:flatbuffers.Offset, schemasUsedOffset:flatbuffers.Offset, buildArtifactsOffset:flatbuffers.Offset, abiVersion:number, invokeSurfacesOffset:flatbuffers.Offset):flatbuffers.Offset {
326
+ static createPluginManifest(builder:flatbuffers.Builder, pluginIdOffset:flatbuffers.Offset, nameOffset:flatbuffers.Offset, versionOffset:flatbuffers.Offset, pluginFamily:PluginFamily, methodsOffset:flatbuffers.Offset, capabilitiesOffset:flatbuffers.Offset, timersOffset:flatbuffers.Offset, protocolsOffset:flatbuffers.Offset, schemasUsedOffset:flatbuffers.Offset, buildArtifactsOffset:flatbuffers.Offset, abiVersion:number, invokeSurfacesOffset:flatbuffers.Offset, runtimeTargetsOffset:flatbuffers.Offset):flatbuffers.Offset {
299
327
  PluginManifest.startPluginManifest(builder);
300
328
  PluginManifest.addPluginId(builder, pluginIdOffset);
301
329
  PluginManifest.addName(builder, nameOffset);
@@ -309,6 +337,7 @@ static createPluginManifest(builder:flatbuffers.Builder, pluginIdOffset:flatbuff
309
337
  PluginManifest.addBuildArtifacts(builder, buildArtifactsOffset);
310
338
  PluginManifest.addAbiVersion(builder, abiVersion);
311
339
  PluginManifest.addInvokeSurfaces(builder, invokeSurfacesOffset);
340
+ PluginManifest.addRuntimeTargets(builder, runtimeTargetsOffset);
312
341
  return PluginManifest.endPluginManifest(builder);
313
342
  }
314
343
 
@@ -325,7 +354,8 @@ unpack(): PluginManifestT {
325
354
  this.bb!.createObjList<FlatBufferTypeRef, FlatBufferTypeRefT>(this.schemasUsed.bind(this), this.schemasUsedLength()),
326
355
  this.bb!.createObjList<BuildArtifact, BuildArtifactT>(this.buildArtifacts.bind(this), this.buildArtifactsLength()),
327
356
  this.abiVersion(),
328
- this.bb!.createScalarList<InvokeSurface>(this.invokeSurfaces.bind(this), this.invokeSurfacesLength())
357
+ this.bb!.createScalarList<InvokeSurface>(this.invokeSurfaces.bind(this), this.invokeSurfacesLength()),
358
+ this.bb!.createScalarList<string>(this.runtimeTargets.bind(this), this.runtimeTargetsLength())
329
359
  );
330
360
  }
331
361
 
@@ -343,6 +373,7 @@ unpackTo(_o: PluginManifestT): void {
343
373
  _o.buildArtifacts = this.bb!.createObjList<BuildArtifact, BuildArtifactT>(this.buildArtifacts.bind(this), this.buildArtifactsLength());
344
374
  _o.abiVersion = this.abiVersion();
345
375
  _o.invokeSurfaces = this.bb!.createScalarList<InvokeSurface>(this.invokeSurfaces.bind(this), this.invokeSurfacesLength());
376
+ _o.runtimeTargets = this.bb!.createScalarList<string>(this.runtimeTargets.bind(this), this.runtimeTargetsLength());
346
377
  }
347
378
  }
348
379
 
@@ -359,7 +390,8 @@ constructor(
359
390
  public schemasUsed: (FlatBufferTypeRefT)[] = [],
360
391
  public buildArtifacts: (BuildArtifactT)[] = [],
361
392
  public abiVersion: number = 1,
362
- public invokeSurfaces: (InvokeSurface)[] = []
393
+ public invokeSurfaces: (InvokeSurface)[] = [],
394
+ public runtimeTargets: string[] = []
363
395
  ){}
364
396
 
365
397
 
@@ -374,6 +406,10 @@ pack(builder:flatbuffers.Builder): flatbuffers.Offset {
374
406
  const schemasUsed = PluginManifest.createSchemasUsedVector(builder, builder.createObjectOffsetList(this.schemasUsed));
375
407
  const buildArtifacts = PluginManifest.createBuildArtifactsVector(builder, builder.createObjectOffsetList(this.buildArtifacts));
376
408
  const invokeSurfaces = PluginManifest.createInvokeSurfacesVector(builder, this.invokeSurfaces);
409
+ const runtimeTargets = PluginManifest.createRuntimeTargetsVector(
410
+ builder,
411
+ builder.createObjectOffsetList(this.runtimeTargets),
412
+ );
377
413
 
378
414
  return PluginManifest.createPluginManifest(builder,
379
415
  pluginId,
@@ -387,7 +423,8 @@ pack(builder:flatbuffers.Builder): flatbuffers.Offset {
387
423
  schemasUsed,
388
424
  buildArtifacts,
389
425
  this.abiVersion,
390
- invokeSurfaces
426
+ invokeSurfaces,
427
+ runtimeTargets
391
428
  );
392
429
  }
393
430
  }
package/src/index.d.ts CHANGED
@@ -223,6 +223,7 @@ export interface ComplianceReport {
223
223
  }
224
224
 
225
225
  export const RecommendedCapabilityIds: readonly string[];
226
+ export const StandaloneWasiCapabilityIds: readonly string[];
226
227
 
227
228
  export function validatePluginManifest(
228
229
  manifest: unknown,
@@ -1098,6 +1099,7 @@ export const RuntimeTarget: {
1098
1099
  NODE: string;
1099
1100
  BROWSER: string;
1100
1101
  WASI: string;
1102
+ WASMEDGE: string;
1101
1103
  SERVER: string;
1102
1104
  DESKTOP: string;
1103
1105
  EDGE: string;
@@ -392,12 +392,6 @@ export function toEmbeddedPluginManifest(input = {}) {
392
392
  "externalInterfaces are not yet representable in the embedded FlatBuffer manifest schema and were omitted from the compiled artifact.",
393
393
  );
394
394
  }
395
- if (Array.isArray(input.runtimeTargets) && input.runtimeTargets.length > 0) {
396
- warnings.push(
397
- "runtimeTargets are not yet representable in the embedded FlatBuffer manifest schema and were omitted from the compiled artifact.",
398
- );
399
- }
400
-
401
395
  const capabilities = Array.isArray(input.capabilities)
402
396
  ? input.capabilities
403
397
  .map((entry) => toHostCapabilityT(entry, warnings))
@@ -428,6 +422,13 @@ export function toEmbeddedPluginManifest(input = {}) {
428
422
  : [],
429
423
  Number(input.abiVersion ?? 1),
430
424
  normalizeInvokeSurfaces(input.invokeSurfaces),
425
+ Array.isArray(input.runtimeTargets)
426
+ ? input.runtimeTargets
427
+ .map((value) =>
428
+ typeof value === "string" ? value.trim() : String(value ?? "").trim(),
429
+ )
430
+ .filter(Boolean)
431
+ : [],
431
432
  ),
432
433
  warnings,
433
434
  };
@@ -38,6 +38,7 @@ export const RuntimeTarget = Object.freeze({
38
38
  NODE: "node",
39
39
  BROWSER: "browser",
40
40
  WASI: "wasi",
41
+ WASMEDGE: "wasmedge",
41
42
  SERVER: "server",
42
43
  DESKTOP: "desktop",
43
44
  EDGE: "edge",
@@ -33,6 +33,8 @@ export interface HarnessRawScenario {
33
33
  export interface CapabilityRuntimeSurface {
34
34
  capability: string;
35
35
  wasi: boolean;
36
+ standaloneWasi: boolean;
37
+ wasmedge: boolean;
36
38
  syncHostcall: boolean;
37
39
  nodeHostApi: boolean;
38
40
  notes: string[];
@@ -6,6 +6,8 @@ const CapabilitySurfaceMatrix = Object.freeze({
6
6
  logging: Object.freeze({
7
7
  capability: "logging",
8
8
  wasi: true,
9
+ standaloneWasi: true,
10
+ wasmedge: true,
9
11
  syncHostcall: false,
10
12
  nodeHostApi: true,
11
13
  notes: [
@@ -16,6 +18,8 @@ const CapabilitySurfaceMatrix = Object.freeze({
16
18
  clock: Object.freeze({
17
19
  capability: "clock",
18
20
  wasi: true,
21
+ standaloneWasi: true,
22
+ wasmedge: true,
19
23
  syncHostcall: true,
20
24
  nodeHostApi: true,
21
25
  notes: [
@@ -26,6 +30,8 @@ const CapabilitySurfaceMatrix = Object.freeze({
26
30
  random: Object.freeze({
27
31
  capability: "random",
28
32
  wasi: true,
33
+ standaloneWasi: true,
34
+ wasmedge: true,
29
35
  syncHostcall: false,
30
36
  nodeHostApi: true,
31
37
  notes: [
@@ -36,6 +42,8 @@ const CapabilitySurfaceMatrix = Object.freeze({
36
42
  timers: Object.freeze({
37
43
  capability: "timers",
38
44
  wasi: false,
45
+ standaloneWasi: false,
46
+ wasmedge: false,
39
47
  syncHostcall: false,
40
48
  nodeHostApi: true,
41
49
  notes: [
@@ -46,6 +54,8 @@ const CapabilitySurfaceMatrix = Object.freeze({
46
54
  schedule_cron: Object.freeze({
47
55
  capability: "schedule_cron",
48
56
  wasi: false,
57
+ standaloneWasi: false,
58
+ wasmedge: false,
49
59
  syncHostcall: true,
50
60
  nodeHostApi: true,
51
61
  notes: [
@@ -55,6 +65,8 @@ const CapabilitySurfaceMatrix = Object.freeze({
55
65
  filesystem: Object.freeze({
56
66
  capability: "filesystem",
57
67
  wasi: true,
68
+ standaloneWasi: true,
69
+ wasmedge: true,
58
70
  syncHostcall: true,
59
71
  nodeHostApi: true,
60
72
  notes: [
@@ -65,6 +77,8 @@ const CapabilitySurfaceMatrix = Object.freeze({
65
77
  pipe: Object.freeze({
66
78
  capability: "pipe",
67
79
  wasi: true,
80
+ standaloneWasi: true,
81
+ wasmedge: true,
68
82
  syncHostcall: false,
69
83
  nodeHostApi: false,
70
84
  notes: [
@@ -75,71 +89,94 @@ const CapabilitySurfaceMatrix = Object.freeze({
75
89
  network: Object.freeze({
76
90
  capability: "network",
77
91
  wasi: false,
92
+ standaloneWasi: false,
93
+ wasmedge: true,
78
94
  syncHostcall: false,
79
95
  nodeHostApi: true,
80
96
  notes: [
81
97
  "The coarse network capability maps to host-side HTTP/TCP/UDP/TLS/WebSocket services today.",
82
98
  "Pure WASI guests cannot reach that surface through the current sync hostcall ABI.",
99
+ "WasmEdge provides non-blocking socket-oriented extensions that can serve as the standard server-side max-WASI target.",
83
100
  ],
84
101
  }),
85
102
  http: Object.freeze({
86
103
  capability: "http",
87
104
  wasi: false,
105
+ standaloneWasi: false,
106
+ wasmedge: true,
88
107
  syncHostcall: false,
89
108
  nodeHostApi: true,
90
109
  notes: [
91
110
  "HTTP is currently available from the Node host API only.",
92
111
  "Pure WASM guests cannot reach it through the current sync hostcall ABI.",
112
+ "Treat WasmEdge socket and TLS extensions as the no-wrapper server-side target for guest HTTP implementations.",
93
113
  ],
94
114
  }),
95
115
  websocket: Object.freeze({
96
116
  capability: "websocket",
97
117
  wasi: false,
118
+ standaloneWasi: false,
119
+ wasmedge: false,
98
120
  syncHostcall: false,
99
121
  nodeHostApi: true,
100
122
  notes: [
101
123
  "WebSocket exchange is async and host-only today.",
124
+ "For no-wrapper parity, target guest WebSocket libraries built on WasmEdge sockets/TLS instead of a host API.",
102
125
  ],
103
126
  }),
104
127
  mqtt: Object.freeze({
105
128
  capability: "mqtt",
106
129
  wasi: false,
130
+ standaloneWasi: false,
131
+ wasmedge: false,
107
132
  syncHostcall: false,
108
133
  nodeHostApi: true,
109
134
  notes: [
110
135
  "MQTT publish/subscribe is async and host-only today.",
136
+ "For no-wrapper parity, target guest MQTT libraries built on WasmEdge sockets/TLS instead of a host API.",
111
137
  ],
112
138
  }),
113
139
  tcp: Object.freeze({
114
140
  capability: "tcp",
115
141
  wasi: false,
142
+ standaloneWasi: false,
143
+ wasmedge: true,
116
144
  syncHostcall: false,
117
145
  nodeHostApi: true,
118
146
  notes: [
119
147
  "TCP request support exists in the Node host API only today.",
148
+ "WasmEdge socket extensions provide a viable no-wrapper server-side target for guest TCP logic.",
120
149
  ],
121
150
  }),
122
151
  udp: Object.freeze({
123
152
  capability: "udp",
124
153
  wasi: false,
154
+ standaloneWasi: false,
155
+ wasmedge: true,
125
156
  syncHostcall: false,
126
157
  nodeHostApi: true,
127
158
  notes: [
128
159
  "UDP request support exists in the Node host API only today.",
160
+ "WasmEdge socket extensions provide a viable no-wrapper server-side target for guest UDP logic.",
129
161
  ],
130
162
  }),
131
163
  tls: Object.freeze({
132
164
  capability: "tls",
133
165
  wasi: false,
166
+ standaloneWasi: false,
167
+ wasmedge: true,
134
168
  syncHostcall: false,
135
169
  nodeHostApi: true,
136
170
  notes: [
137
171
  "TLS request support exists in the Node host API only today.",
172
+ "WasmEdge TLS support provides a practical no-wrapper server-side target for guest HTTPS/TLS logic.",
138
173
  ],
139
174
  }),
140
175
  context_read: Object.freeze({
141
176
  capability: "context_read",
142
177
  wasi: false,
178
+ standaloneWasi: false,
179
+ wasmedge: false,
143
180
  syncHostcall: false,
144
181
  nodeHostApi: true,
145
182
  notes: [
@@ -149,6 +186,8 @@ const CapabilitySurfaceMatrix = Object.freeze({
149
186
  context_write: Object.freeze({
150
187
  capability: "context_write",
151
188
  wasi: false,
189
+ standaloneWasi: false,
190
+ wasmedge: false,
152
191
  syncHostcall: false,
153
192
  nodeHostApi: true,
154
193
  notes: [
@@ -158,6 +197,8 @@ const CapabilitySurfaceMatrix = Object.freeze({
158
197
  crypto_hash: Object.freeze({
159
198
  capability: "crypto_hash",
160
199
  wasi: false,
200
+ standaloneWasi: false,
201
+ wasmedge: false,
161
202
  syncHostcall: false,
162
203
  nodeHostApi: true,
163
204
  notes: [
@@ -167,6 +208,8 @@ const CapabilitySurfaceMatrix = Object.freeze({
167
208
  crypto_sign: Object.freeze({
168
209
  capability: "crypto_sign",
169
210
  wasi: false,
211
+ standaloneWasi: false,
212
+ wasmedge: false,
170
213
  syncHostcall: false,
171
214
  nodeHostApi: true,
172
215
  notes: [
@@ -176,6 +219,8 @@ const CapabilitySurfaceMatrix = Object.freeze({
176
219
  crypto_verify: Object.freeze({
177
220
  capability: "crypto_verify",
178
221
  wasi: false,
222
+ standaloneWasi: false,
223
+ wasmedge: false,
179
224
  syncHostcall: false,
180
225
  nodeHostApi: true,
181
226
  notes: [
@@ -185,6 +230,8 @@ const CapabilitySurfaceMatrix = Object.freeze({
185
230
  crypto_encrypt: Object.freeze({
186
231
  capability: "crypto_encrypt",
187
232
  wasi: false,
233
+ standaloneWasi: false,
234
+ wasmedge: false,
188
235
  syncHostcall: false,
189
236
  nodeHostApi: true,
190
237
  notes: [
@@ -194,6 +241,8 @@ const CapabilitySurfaceMatrix = Object.freeze({
194
241
  crypto_decrypt: Object.freeze({
195
242
  capability: "crypto_decrypt",
196
243
  wasi: false,
244
+ standaloneWasi: false,
245
+ wasmedge: false,
197
246
  syncHostcall: false,
198
247
  nodeHostApi: true,
199
248
  notes: [
@@ -203,6 +252,8 @@ const CapabilitySurfaceMatrix = Object.freeze({
203
252
  crypto_key_agreement: Object.freeze({
204
253
  capability: "crypto_key_agreement",
205
254
  wasi: false,
255
+ standaloneWasi: false,
256
+ wasmedge: false,
206
257
  syncHostcall: false,
207
258
  nodeHostApi: true,
208
259
  notes: [
@@ -212,6 +263,8 @@ const CapabilitySurfaceMatrix = Object.freeze({
212
263
  crypto_kdf: Object.freeze({
213
264
  capability: "crypto_kdf",
214
265
  wasi: false,
266
+ standaloneWasi: false,
267
+ wasmedge: false,
215
268
  syncHostcall: false,
216
269
  nodeHostApi: true,
217
270
  notes: [
@@ -221,6 +274,8 @@ const CapabilitySurfaceMatrix = Object.freeze({
221
274
  process_exec: Object.freeze({
222
275
  capability: "process_exec",
223
276
  wasi: false,
277
+ standaloneWasi: false,
278
+ wasmedge: false,
224
279
  syncHostcall: false,
225
280
  nodeHostApi: true,
226
281
  notes: [
@@ -324,6 +379,8 @@ export function describeCapabilityRuntimeSurface(capability) {
324
379
  return {
325
380
  capability: known.capability,
326
381
  wasi: known.wasi,
382
+ standaloneWasi: known.standaloneWasi,
383
+ wasmedge: known.wasmedge,
327
384
  syncHostcall: known.syncHostcall,
328
385
  nodeHostApi: known.nodeHostApi,
329
386
  notes: [...known.notes],
@@ -332,6 +389,8 @@ export function describeCapabilityRuntimeSurface(capability) {
332
389
  return {
333
390
  capability: normalized,
334
391
  wasi: false,
392
+ standaloneWasi: false,
393
+ wasmedge: false,
335
394
  syncHostcall: false,
336
395
  nodeHostApi: false,
337
396
  notes: [