space-data-module-sdk 0.8.3 → 0.8.5

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 (354) hide show
  1. package/README.md +117 -20
  2. package/bin/space-data-module.js +263 -0
  3. package/docs/.nojekyll +1 -0
  4. package/docs/AGENTS.md +34 -0
  5. package/docs/architecture.svg +141 -0
  6. package/docs/browser-wasmedge-isomorphic.md +179 -0
  7. package/docs/flatsql-streaming-standard.md +341 -0
  8. package/docs/gpu-module-abi.md +193 -0
  9. package/docs/index.html +125 -0
  10. package/docs/isomorphic-pthreads.md +188 -0
  11. package/docs/isomorphic-sdn-runtime-plan.md +167 -0
  12. package/docs/language-runtime-matrix.md +82 -0
  13. package/docs/manifest-structure.svg +114 -0
  14. package/docs/module-bundle-runtime-plan.md +19 -0
  15. package/docs/module-lifecycle.svg +70 -0
  16. package/docs/module-publication-standard.md +540 -0
  17. package/docs/node-red-default-node-parity.md +88 -0
  18. package/docs/protocol-installation.md +196 -0
  19. package/docs/secrets-capability.md +152 -0
  20. package/docs/styles.css +288 -0
  21. package/docs/testing-harness.md +408 -0
  22. package/docs/tri-runtime-parity.md +132 -0
  23. package/docs/wallet-callback.html +2 -0
  24. package/package.json +26 -6
  25. package/schemas/HttpRequestAbi.fbs +41 -0
  26. package/schemas/HttpResponseAbi.fbs +36 -0
  27. package/schemas/PluginManifest.fbs +2 -1
  28. package/src/AGENTS.md +1 -1
  29. package/src/app/codec.js +548 -0
  30. package/src/app/index.js +6 -0
  31. package/src/browser.js +5 -0
  32. package/src/bundle/constants.js +1 -0
  33. package/src/bundle/index.js +15 -0
  34. package/src/bundle/sigdomain.js +179 -0
  35. package/src/bundle/signing.js +767 -0
  36. package/src/bundle/wasm.js +3 -2
  37. package/src/capabilities.js +3 -0
  38. package/src/compat/index.js +7 -0
  39. package/src/compat/sdnLegacy.js +449 -0
  40. package/src/compiler/compileModule.js +556 -55
  41. package/src/compiler/flatcSupport.js +41 -27
  42. package/src/compiler/index.d.ts +2 -0
  43. package/src/compiler/index.js +18 -0
  44. package/src/compiler/invokeGlue.js +1212 -183
  45. package/src/compiler/pthreadArtifactGuard.js +910 -0
  46. package/src/compiler/sdnShimGenerator.js +323 -0
  47. package/src/compiler/wasiThreadsToolchain.js +150 -0
  48. package/src/compliance/index.js +11 -1
  49. package/src/compliance/legacyWildcardPorts.js +228 -0
  50. package/src/compliance/pluginCompliance.js +1000 -96
  51. package/src/field-stream/index.d.ts +31 -0
  52. package/src/field-stream/index.js +119 -0
  53. package/src/flow/dependencyStreamBridge.js +234 -0
  54. package/src/flow/flatsqlLinkShim.js +304 -0
  55. package/src/flow/flowCodec.js +107 -0
  56. package/src/flow/flowCompiler.js +2900 -0
  57. package/src/flow/flowRuntimeHost.js +877 -0
  58. package/src/flow/index.d.ts +117 -0
  59. package/src/flow/index.js +31 -0
  60. package/src/flow/isomorphicFlowHost.js +384 -0
  61. package/src/flow/jsFlowRuntime.js +275 -0
  62. package/src/flow/normalize.js +294 -0
  63. package/src/flow/runtime-src/flow_runtime.cpp +1699 -0
  64. package/src/flow/vendor/sdn-flow/MethodRegistry.js +400 -0
  65. package/src/flow/vendor/sdn-flow/constants.js +39 -0
  66. package/src/flow/vendor/sdn-flow/index.js +29 -0
  67. package/src/flow/vendor/sdn-flow/normalize.js +506 -0
  68. package/src/flow/vendor/sdn-flow/wasmCompatibility.js +189 -0
  69. package/src/generated/http/cpp/HttpRequestAbi_generated.h +285 -0
  70. package/src/generated/http/cpp/HttpResponseAbi_generated.h +192 -0
  71. package/src/generated/http/sdn/http/http-header.js +53 -0
  72. package/src/generated/http/sdn/http/http-header.ts +67 -0
  73. package/src/generated/http/sdn/http/http-request.js +132 -0
  74. package/src/generated/http/sdn/http/http-request.ts +179 -0
  75. package/src/generated/http/sdn/http/http-response.js +144 -0
  76. package/src/generated/http/sdn/http/http-response.ts +168 -0
  77. package/src/generated/http/sdn/http.js +11 -0
  78. package/src/generated/http/sdn/http.ts +4 -0
  79. package/src/generated/orbpro/flow/backpressure-policy.d.ts +12 -0
  80. package/src/generated/orbpro/flow/backpressure-policy.d.ts.map +1 -0
  81. package/src/generated/orbpro/flow/backpressure-policy.js +17 -0
  82. package/src/generated/orbpro/flow/backpressure-policy.js.map +1 -0
  83. package/src/generated/orbpro/flow/backpressure-policy.ts +15 -0
  84. package/src/generated/orbpro/flow/flow-bundle-manifest.d.ts +142 -0
  85. package/src/generated/orbpro/flow/flow-bundle-manifest.d.ts.map +1 -0
  86. package/src/generated/orbpro/flow/flow-bundle-manifest.js +304 -0
  87. package/src/generated/orbpro/flow/flow-bundle-manifest.js.map +1 -0
  88. package/src/generated/orbpro/flow/flow-bundle-manifest.ts +399 -0
  89. package/src/generated/orbpro/flow/flow-edge.d.ts +113 -0
  90. package/src/generated/orbpro/flow/flow-edge.d.ts.map +1 -0
  91. package/src/generated/orbpro/flow/flow-edge.js +221 -0
  92. package/src/generated/orbpro/flow/flow-edge.js.map +1 -0
  93. package/src/generated/orbpro/flow/flow-edge.ts +292 -0
  94. package/src/generated/orbpro/flow/flow-node.d.ts +80 -0
  95. package/src/generated/orbpro/flow/flow-node.d.ts.map +1 -0
  96. package/src/generated/orbpro/flow/flow-node.js +158 -0
  97. package/src/generated/orbpro/flow/flow-node.js.map +1 -0
  98. package/src/generated/orbpro/flow/flow-node.ts +202 -0
  99. package/src/generated/orbpro/flow/flow-program.d.ts +164 -0
  100. package/src/generated/orbpro/flow/flow-program.d.ts.map +1 -0
  101. package/src/generated/orbpro/flow/flow-program.js +350 -0
  102. package/src/generated/orbpro/flow/flow-program.js.map +1 -0
  103. package/src/generated/orbpro/flow/flow-program.ts +477 -0
  104. package/src/generated/orbpro/flow/flow-trigger.d.ts +108 -0
  105. package/src/generated/orbpro/flow/flow-trigger.d.ts.map +1 -0
  106. package/src/generated/orbpro/flow/flow-trigger.js +207 -0
  107. package/src/generated/orbpro/flow/flow-trigger.js.map +1 -0
  108. package/src/generated/orbpro/flow/flow-trigger.ts +276 -0
  109. package/src/generated/orbpro/flow/node-kind.d.ts +13 -0
  110. package/src/generated/orbpro/flow/node-kind.d.ts.map +1 -0
  111. package/src/generated/orbpro/flow/node-kind.js +16 -0
  112. package/src/generated/orbpro/flow/node-kind.js.map +1 -0
  113. package/src/generated/orbpro/{invoke.ts → flow/node-kind.ts} +12 -2
  114. package/src/generated/orbpro/flow/plugin-version-binding.d.ts +52 -0
  115. package/src/generated/orbpro/flow/plugin-version-binding.d.ts.map +1 -0
  116. package/src/generated/orbpro/flow/plugin-version-binding.js +85 -0
  117. package/src/generated/orbpro/flow/plugin-version-binding.js.map +1 -0
  118. package/src/generated/orbpro/flow/plugin-version-binding.ts +121 -0
  119. package/src/generated/orbpro/flow/schema-hash-binding.d.ts +70 -0
  120. package/src/generated/orbpro/flow/schema-hash-binding.d.ts.map +1 -0
  121. package/src/generated/orbpro/flow/schema-hash-binding.js +143 -0
  122. package/src/generated/orbpro/flow/schema-hash-binding.js.map +1 -0
  123. package/src/generated/orbpro/flow/schema-hash-binding.ts +189 -0
  124. package/src/generated/orbpro/flow/trigger-binding.d.ts +71 -0
  125. package/src/generated/orbpro/flow/trigger-binding.d.ts.map +1 -0
  126. package/src/generated/orbpro/flow/trigger-binding.js +142 -0
  127. package/src/generated/orbpro/flow/trigger-binding.js.map +1 -0
  128. package/src/generated/orbpro/flow/trigger-binding.ts +181 -0
  129. package/src/generated/orbpro/flow/trigger-kind.d.ts +14 -0
  130. package/src/generated/orbpro/flow/trigger-kind.d.ts.map +1 -0
  131. package/src/generated/orbpro/flow/trigger-kind.js +17 -0
  132. package/src/generated/orbpro/flow/trigger-kind.js.map +1 -0
  133. package/src/generated/orbpro/flow/trigger-kind.ts +17 -0
  134. package/src/generated/orbpro/flow.d.ts +21 -0
  135. package/src/generated/orbpro/flow.d.ts.map +1 -0
  136. package/src/generated/orbpro/flow.js +23 -0
  137. package/src/generated/orbpro/flow.js.map +1 -0
  138. package/src/generated/orbpro/flow.ts +24 -0
  139. package/src/generated/orbpro/manifest/capability-kind.d.ts +2 -1
  140. package/src/generated/orbpro/manifest/capability-kind.js +1 -0
  141. package/src/generated/orbpro/manifest/capability-kind.ts +1 -0
  142. package/src/generated/orbpro/plugin/stream-invoke-request.d.ts +93 -0
  143. package/src/generated/orbpro/plugin/stream-invoke-request.js +160 -0
  144. package/src/generated/orbpro/plugin/stream-invoke-request.ts +211 -0
  145. package/src/generated/orbpro/plugin/stream-invoke-response.d.ts +99 -0
  146. package/src/generated/orbpro/plugin/stream-invoke-response.js +175 -0
  147. package/src/generated/orbpro/plugin/stream-invoke-response.ts +226 -0
  148. package/src/generated/orbpro/plugin.js +8 -0
  149. package/src/generated/orbpro/stream.d.ts +12 -0
  150. package/src/generated/orbpro/stream.js +14 -0
  151. package/src/generated/orbpro/stream.ts +15 -0
  152. package/src/generated/spacedatastandards/plg/EntryFunction.d.ts +52 -0
  153. package/src/generated/spacedatastandards/plg/EntryFunction.d.ts.map +1 -0
  154. package/src/generated/spacedatastandards/plg/EntryFunction.js +106 -0
  155. package/src/generated/spacedatastandards/plg/EntryFunction.ts +162 -0
  156. package/src/generated/spacedatastandards/plg/FlatBufferTypeRef.d.ts +90 -0
  157. package/src/generated/spacedatastandards/plg/FlatBufferTypeRef.d.ts.map +1 -0
  158. package/src/generated/spacedatastandards/plg/FlatBufferTypeRef.js +189 -0
  159. package/src/generated/spacedatastandards/plg/FlatBufferTypeRef.ts +270 -0
  160. package/src/generated/spacedatastandards/plg/PLG.d.ts +492 -0
  161. package/src/generated/spacedatastandards/plg/PLG.d.ts.map +1 -0
  162. package/src/generated/spacedatastandards/plg/PLG.js +1139 -0
  163. package/src/generated/spacedatastandards/plg/PLG.ts +1600 -0
  164. package/src/generated/spacedatastandards/plg/PLGAcceptedTypeSet.d.ts +63 -0
  165. package/src/generated/spacedatastandards/plg/PLGAcceptedTypeSet.d.ts.map +1 -0
  166. package/src/generated/spacedatastandards/plg/PLGAcceptedTypeSet.js +138 -0
  167. package/src/generated/spacedatastandards/plg/PLGAcceptedTypeSet.ts +189 -0
  168. package/src/generated/spacedatastandards/plg/PLGBuildArtifact.d.ts +41 -0
  169. package/src/generated/spacedatastandards/plg/PLGBuildArtifact.d.ts.map +1 -0
  170. package/src/generated/spacedatastandards/plg/PLGBuildArtifact.js +104 -0
  171. package/src/generated/spacedatastandards/plg/PLGBuildArtifact.ts +151 -0
  172. package/src/generated/spacedatastandards/plg/PLGFlowEdge.d.ts +68 -0
  173. package/src/generated/spacedatastandards/plg/PLGFlowEdge.d.ts.map +1 -0
  174. package/src/generated/spacedatastandards/plg/PLGFlowEdge.js +124 -0
  175. package/src/generated/spacedatastandards/plg/PLGFlowEdge.ts +184 -0
  176. package/src/generated/spacedatastandards/plg/PLGFlowEdgeContract.d.ts +58 -0
  177. package/src/generated/spacedatastandards/plg/PLGFlowEdgeContract.d.ts.map +1 -0
  178. package/src/generated/spacedatastandards/plg/PLGFlowEdgeContract.js +126 -0
  179. package/src/generated/spacedatastandards/plg/PLGFlowEdgeContract.ts +161 -0
  180. package/src/generated/spacedatastandards/plg/PLGFlowNode.d.ts +82 -0
  181. package/src/generated/spacedatastandards/plg/PLGFlowNode.d.ts.map +1 -0
  182. package/src/generated/spacedatastandards/plg/PLGFlowNode.js +164 -0
  183. package/src/generated/spacedatastandards/plg/PLGFlowNode.ts +244 -0
  184. package/src/generated/spacedatastandards/plg/PLGFlowTrigger.d.ts +55 -0
  185. package/src/generated/spacedatastandards/plg/PLGFlowTrigger.d.ts.map +1 -0
  186. package/src/generated/spacedatastandards/plg/PLGFlowTrigger.js +105 -0
  187. package/src/generated/spacedatastandards/plg/PLGFlowTrigger.ts +162 -0
  188. package/src/generated/spacedatastandards/plg/PLGFlowTriggerBinding.d.ts +42 -0
  189. package/src/generated/spacedatastandards/plg/PLGFlowTriggerBinding.d.ts.map +1 -0
  190. package/src/generated/spacedatastandards/plg/PLGFlowTriggerBinding.js +83 -0
  191. package/src/generated/spacedatastandards/plg/PLGFlowTriggerBinding.ts +127 -0
  192. package/src/generated/spacedatastandards/plg/PLGHostCapability.d.ts +36 -0
  193. package/src/generated/spacedatastandards/plg/PLGHostCapability.d.ts.map +1 -0
  194. package/src/generated/spacedatastandards/plg/PLGHostCapability.js +90 -0
  195. package/src/generated/spacedatastandards/plg/PLGHostCapability.ts +127 -0
  196. package/src/generated/spacedatastandards/plg/PLGMethodManifest.d.ts +53 -0
  197. package/src/generated/spacedatastandards/plg/PLGMethodManifest.d.ts.map +1 -0
  198. package/src/generated/spacedatastandards/plg/PLGMethodManifest.js +153 -0
  199. package/src/generated/spacedatastandards/plg/PLGMethodManifest.ts +210 -0
  200. package/src/generated/spacedatastandards/plg/PLGPortManifest.d.ts +70 -0
  201. package/src/generated/spacedatastandards/plg/PLGPortManifest.d.ts.map +1 -0
  202. package/src/generated/spacedatastandards/plg/PLGPortManifest.js +149 -0
  203. package/src/generated/spacedatastandards/plg/PLGPortManifest.ts +212 -0
  204. package/src/generated/spacedatastandards/plg/PLGProtocolSpec.d.ts +73 -0
  205. package/src/generated/spacedatastandards/plg/PLGProtocolSpec.d.ts.map +1 -0
  206. package/src/generated/spacedatastandards/plg/PLGProtocolSpec.js +199 -0
  207. package/src/generated/spacedatastandards/plg/PLGProtocolSpec.ts +292 -0
  208. package/src/generated/spacedatastandards/plg/PLGTimerSpec.d.ts +40 -0
  209. package/src/generated/spacedatastandards/plg/PLGTimerSpec.d.ts.map +1 -0
  210. package/src/generated/spacedatastandards/plg/PLGTimerSpec.js +103 -0
  211. package/src/generated/spacedatastandards/plg/PLGTimerSpec.ts +148 -0
  212. package/src/generated/spacedatastandards/plg/PluginCapability.d.ts +41 -0
  213. package/src/generated/spacedatastandards/plg/PluginCapability.d.ts.map +1 -0
  214. package/src/generated/spacedatastandards/plg/PluginCapability.js +82 -0
  215. package/src/generated/spacedatastandards/plg/{plugin-capability.ts → PluginCapability.ts} +55 -18
  216. package/src/generated/spacedatastandards/plg/PluginDependency.d.ts +42 -0
  217. package/src/generated/spacedatastandards/plg/PluginDependency.d.ts.map +1 -0
  218. package/src/generated/spacedatastandards/plg/PluginDependency.js +80 -0
  219. package/src/generated/spacedatastandards/plg/PluginDependency.ts +124 -0
  220. package/src/generated/spacedatastandards/plg/TAB.d.ts +85 -0
  221. package/src/generated/spacedatastandards/plg/TAB.d.ts.map +1 -0
  222. package/src/generated/spacedatastandards/plg/TAB.js +173 -0
  223. package/src/generated/spacedatastandards/plg/TAB.ts +228 -0
  224. package/src/generated/spacedatastandards/plg/bufferMutability.d.ts +18 -0
  225. package/src/generated/spacedatastandards/plg/bufferMutability.d.ts.map +1 -0
  226. package/src/generated/spacedatastandards/plg/bufferMutability.js +20 -0
  227. package/src/generated/spacedatastandards/plg/bufferMutability.ts +23 -0
  228. package/src/generated/spacedatastandards/plg/bufferOwnership.d.ts +18 -0
  229. package/src/generated/spacedatastandards/plg/bufferOwnership.d.ts.map +1 -0
  230. package/src/generated/spacedatastandards/plg/bufferOwnership.js +20 -0
  231. package/src/generated/spacedatastandards/plg/bufferOwnership.ts +23 -0
  232. package/src/generated/spacedatastandards/plg/drainBehavior.d.ts +20 -0
  233. package/src/generated/spacedatastandards/plg/drainBehavior.d.ts.map +1 -0
  234. package/src/generated/spacedatastandards/plg/drainBehavior.js +22 -0
  235. package/src/generated/spacedatastandards/plg/drainBehavior.ts +25 -0
  236. package/src/generated/spacedatastandards/plg/flowEdgeRoutePolicy.d.ts +10 -0
  237. package/src/generated/spacedatastandards/plg/flowEdgeRoutePolicy.d.ts.map +1 -0
  238. package/src/generated/spacedatastandards/plg/flowEdgeRoutePolicy.js +12 -0
  239. package/src/generated/spacedatastandards/plg/flowEdgeRoutePolicy.ts +13 -0
  240. package/src/generated/spacedatastandards/plg/hostCapabilityKind.d.ts +51 -0
  241. package/src/generated/spacedatastandards/plg/hostCapabilityKind.d.ts.map +1 -0
  242. package/src/generated/spacedatastandards/plg/hostCapabilityKind.js +53 -0
  243. package/src/generated/spacedatastandards/plg/hostCapabilityKind.ts +55 -0
  244. package/src/generated/spacedatastandards/plg/invokeSurfaceKind.d.ts +15 -0
  245. package/src/generated/spacedatastandards/plg/invokeSurfaceKind.d.ts.map +1 -0
  246. package/src/generated/spacedatastandards/plg/invokeSurfaceKind.js +17 -0
  247. package/src/generated/spacedatastandards/plg/invokeSurfaceKind.ts +19 -0
  248. package/src/generated/spacedatastandards/plg/main.d.ts +29 -0
  249. package/src/generated/spacedatastandards/plg/main.d.ts.map +1 -0
  250. package/src/generated/spacedatastandards/plg/main.js +30 -0
  251. package/src/generated/spacedatastandards/plg/main.ts +32 -0
  252. package/src/generated/spacedatastandards/plg/payloadWireFormat.d.ts +17 -0
  253. package/src/generated/spacedatastandards/plg/payloadWireFormat.d.ts.map +1 -0
  254. package/src/generated/spacedatastandards/plg/payloadWireFormat.js +19 -0
  255. package/src/generated/spacedatastandards/plg/payloadWireFormat.ts +21 -0
  256. package/src/generated/spacedatastandards/plg/pluginCategory.d.ts +82 -0
  257. package/src/generated/spacedatastandards/plg/pluginCategory.d.ts.map +1 -0
  258. package/src/generated/spacedatastandards/plg/pluginCategory.js +84 -0
  259. package/src/generated/spacedatastandards/plg/pluginCategory.ts +103 -0
  260. package/src/generated/spacedatastandards/plg/publicationState.d.ts +18 -0
  261. package/src/generated/spacedatastandards/plg/publicationState.d.ts.map +1 -0
  262. package/src/generated/spacedatastandards/plg/publicationState.js +20 -0
  263. package/src/generated/spacedatastandards/plg/purchaseTier.d.ts +18 -0
  264. package/src/generated/spacedatastandards/plg/purchaseTier.d.ts.map +1 -0
  265. package/src/generated/spacedatastandards/plg/purchaseTier.js +20 -0
  266. package/src/host/AGENTS.md +2 -2
  267. package/src/host/abi.js +53 -66
  268. package/src/host/browserHost.js +355 -8
  269. package/src/host/cpp/keyslotClient.hpp +231 -0
  270. package/src/host/cpp/secretsClient.hpp +583 -0
  271. package/src/host/hostcallWire.js +183 -0
  272. package/src/host/index.js +2 -0
  273. package/src/host/isomorphicLoader.js +44 -7
  274. package/src/host/nodeHost.js +227 -8
  275. package/src/host/sabHostcallChannel.js +206 -0
  276. package/src/host/timerDriver.js +203 -0
  277. package/src/host/wasiShim.js +41 -1
  278. package/src/host/wasiThreadBrowserWorker.mjs +48 -0
  279. package/src/host/wasiThreadHost.js +393 -0
  280. package/src/host/wasiThreadWorker.mjs +32 -0
  281. package/src/host/wasiThreadWorkerRuntime.js +93 -0
  282. package/src/http/index.js +339 -0
  283. package/src/index.d.ts +716 -10
  284. package/src/index.js +4 -0
  285. package/src/invoke/codec.js +1202 -128
  286. package/src/invoke/index.js +5 -1
  287. package/src/licensing/index.d.ts +2 -0
  288. package/src/licensing/index.js +2 -0
  289. package/src/licensing/records.js +287 -8
  290. package/src/manifest/codec.js +62 -14
  291. package/src/manifest/index.js +2 -0
  292. package/src/manifest/legacyToPlg.js +164 -25
  293. package/src/manifest/normalize.js +1 -0
  294. package/src/manifest/plgCodec.js +1303 -62
  295. package/src/manifest/typeRefs.js +162 -24
  296. package/src/runtime/compiledRuntimeAbi.js +47 -0
  297. package/src/runtime/compiledRuntimeAbi.json +33 -0
  298. package/src/runtime/index.d.ts +32 -0
  299. package/src/runtime/index.js +1 -0
  300. package/src/runtime-host/index.js +3 -0
  301. package/src/runtime-host/methodRegistry.js +55 -0
  302. package/src/standards/index.js +200 -56
  303. package/src/standards/sharedCatalog.js +16 -0
  304. package/src/testing/browserModuleHarness.js +604 -31
  305. package/src/testing/docker/wasmedge-parity.Dockerfile +39 -0
  306. package/src/testing/index.d.ts +151 -0
  307. package/src/testing/index.js +21 -0
  308. package/src/testing/native/wasmedge_emscripten_pthread_runner.c +25 -1
  309. package/src/testing/parityBrowserRunner.js +138 -0
  310. package/src/testing/parityHarness.js +616 -0
  311. package/src/testing/parityLanes.js +537 -0
  312. package/src/testing/processInvoke.js +29 -21
  313. package/src/testing/streamInvokeCodec.js +10 -175
  314. package/src/testing/wasmedgePin.json +6 -0
  315. package/src/testing/workerModuleHarness.js +242 -0
  316. package/src/testing/workerModuleHarnessWorker.js +176 -0
  317. package/src/transport/index.js +3 -0
  318. package/src/transport/pki.js +299 -11
  319. package/src/transport/records.js +16 -7
  320. package/src/utils/ecdsaDer.js +106 -0
  321. package/src/utils/wasmCrypto.js +0 -43
  322. package/templates/gpu-module/README.md +48 -0
  323. package/templates/gpu-module/include/space_data_gpu_abi.h +122 -0
  324. package/templates/gpu-module/manifest.json +84 -0
  325. package/schemas/PluginInvokeRequest.fbs +0 -18
  326. package/schemas/PluginInvokeResponse.fbs +0 -30
  327. package/schemas/spacedatastandards/PLG.fbs +0 -191
  328. package/src/generated/orbpro/invoke/plugin-invoke-request.d.ts +0 -51
  329. package/src/generated/orbpro/invoke/plugin-invoke-request.d.ts.map +0 -1
  330. package/src/generated/orbpro/invoke/plugin-invoke-request.js +0 -131
  331. package/src/generated/orbpro/invoke/plugin-invoke-request.js.map +0 -1
  332. package/src/generated/orbpro/invoke/plugin-invoke-request.ts +0 -173
  333. package/src/generated/orbpro/invoke/plugin-invoke-response.d.ts +0 -76
  334. package/src/generated/orbpro/invoke/plugin-invoke-response.d.ts.map +0 -1
  335. package/src/generated/orbpro/invoke/plugin-invoke-response.js +0 -184
  336. package/src/generated/orbpro/invoke/plugin-invoke-response.js.map +0 -1
  337. package/src/generated/orbpro/invoke/plugin-invoke-response.ts +0 -243
  338. package/src/generated/orbpro/invoke.d.ts +0 -3
  339. package/src/generated/orbpro/invoke.js +0 -5
  340. package/src/generated/spacedatastandards/plg/entry-function.js +0 -86
  341. package/src/generated/spacedatastandards/plg/entry-function.ts +0 -119
  342. package/src/generated/spacedatastandards/plg/index.js +0 -16
  343. package/src/generated/spacedatastandards/plg/index.ts +0 -11
  344. package/src/generated/spacedatastandards/plg/plg.js +0 -657
  345. package/src/generated/spacedatastandards/plg/plg.ts +0 -924
  346. package/src/generated/spacedatastandards/plg/plugin-capability.js +0 -66
  347. package/src/generated/spacedatastandards/plg/plugin-category.js +0 -15
  348. package/src/generated/spacedatastandards/plg/plugin-category.ts +0 -53
  349. package/src/generated/spacedatastandards/plg/plugin-dependency.js +0 -63
  350. package/src/generated/spacedatastandards/plg/plugin-dependency.ts +0 -86
  351. package/src/generated/spacedatastandards/plg/publication-state.js +0 -9
  352. package/src/generated/spacedatastandards/plg/purchase-tier.js +0 -9
  353. /package/src/generated/spacedatastandards/plg/{publication-state.ts → publicationState.ts} +0 -0
  354. /package/src/generated/spacedatastandards/plg/{purchase-tier.ts → purchaseTier.ts} +0 -0
@@ -27,6 +27,14 @@ import {
27
27
  getInvokeCppSchemaHeaders,
28
28
  } from "./flatcSupport.js";
29
29
  import { runWithEmceptionLock } from "./emceptionNode.js";
30
+ import {
31
+ assertPthreadArtifact,
32
+ assertPthreadFlagsPresent,
33
+ assertSequentialArtifact,
34
+ assertSequentialFlagsAbsent,
35
+ PTHREAD_FINAL_LINK_FLAGS,
36
+ } from "./pthreadArtifactGuard.js";
37
+ import { resolveWasiThreadsToolchain } from "./wasiThreadsToolchain.js";
30
38
  import { encodePluginManifest, toEmbeddedPluginManifest } from "../manifest/index.js";
31
39
  import {
32
40
  DefaultInvokeExports,
@@ -48,8 +56,10 @@ import {
48
56
  SDS_GUEST_LINK_METADATA_ENTRY_ID,
49
57
  SDS_GUEST_LINK_OBJECT_ENTRY_ID,
50
58
  SDS_GUEST_LINK_SECTION_NAME,
59
+ SDS_MANIFEST_SECTION_NAME,
51
60
  } from "../bundle/constants.js";
52
61
  import {
62
+ appendWasmCustomSection,
53
63
  decodeUnsignedLeb128,
54
64
  parseWasmModuleSections,
55
65
  } from "../bundle/wasm.js";
@@ -64,12 +74,51 @@ import { getWasmWallet } from "../utils/wasmCrypto.js";
64
74
 
65
75
  const C_IDENTIFIER = /^[A-Za-z_][A-Za-z0-9_]*$/;
66
76
  const execFileAsync = promisify(execFile);
77
+ const EMSCRIPTEN_MEMORY_GROWTH_NOTIFY_SHIM = `
78
+ extern "C" __attribute__((weak)) void emscripten_notify_memory_growth(int) {}
79
+ `;
67
80
 
68
81
  export const ModuleThreadModel = Object.freeze({
69
82
  SINGLE_THREAD: "single-thread",
70
83
  EMSCRIPTEN_PTHREADS: "emscripten-pthreads",
84
+ // Inherently-sequential guests that must still be built by the sanctioned
85
+ // clang wasm32-wasip1-threads toolchain. NOT an optimisation and NOT
86
+ // inferable: see resolveThreadModel + assertSequentialArtifact.
87
+ WASI_SEQUENTIAL: "wasi-sequential",
71
88
  });
72
89
 
90
+ // The wasi-sequential model is a DECLARATION, never a deduction. A module that
91
+ // selects it is asserting "this guest can never spawn a thread", which the
92
+ // emitted artifact is then held to by assertSequentialArtifact. Because that
93
+ // assertion is a permanent architectural claim about the guest, the manifest
94
+ // must carry a machine-readable reason for it.
95
+ const SEQUENTIAL_JUSTIFICATION_MIN_LENGTH = 24;
96
+ const SEQUENTIAL_JUSTIFICATION_KINDS = Object.freeze([
97
+ // The algorithm carries state from item k-1 into item k (e.g. a stateful codec).
98
+ "inherently-sequential-algorithm",
99
+ // The guest is a pure transform with no work to fan out.
100
+ "pure-transform",
101
+ // Threading exists, but only ACROSS independent invocations, driven by the caller.
102
+ "caller-level-parallelism",
103
+ ]);
104
+
105
+ function resolveGuestLinkCapabilities(manifest, explicitCapabilities) {
106
+ const source = Array.isArray(explicitCapabilities)
107
+ ? explicitCapabilities
108
+ : (Array.isArray(manifest?.capabilities) ? manifest.capabilities : []);
109
+ const capabilities = [];
110
+ const seen = new Set();
111
+ for (const capability of source) {
112
+ const id = String(
113
+ typeof capability === "string" ? capability : capability?.capability ?? "",
114
+ ).trim();
115
+ if (!id || seen.has(id)) continue;
116
+ seen.add(id);
117
+ capabilities.push(id);
118
+ }
119
+ return capabilities;
120
+ }
121
+
73
122
  function selectCompiler(language) {
74
123
  const normalized = String(language ?? "c").trim().toLowerCase();
75
124
  if (normalized === "c++" || normalized === "cpp" || normalized === "cxx") {
@@ -90,28 +139,180 @@ function ensureExportableMethodIds(manifest) {
90
139
  }
91
140
  }
92
141
 
142
+ function usesPthreadCompileFlags(options = {}) {
143
+ return (
144
+ options.threadModel === ModuleThreadModel.EMSCRIPTEN_PTHREADS ||
145
+ options.sharedMemory === true
146
+ );
147
+ }
148
+
149
+ // wasm-ld's default main stack is 64 KiB. That is far too small for guests with
150
+ // large caller-allocated frames: the vendored CCSDS 124 reference codec has a
151
+ // MEASURED worst-case call chain of ~631 KB on wasm32
152
+ // (ccsds124_decompress -> _packet_internal 335,888 B -> bit_insert 262,144 B)
153
+ // and traps with "memory access out of bounds" on its first input under the
154
+ // default.
155
+ //
156
+ // This must be an explicit, validated number rather than a default anyone can
157
+ // drift off: the stack size is a link-time constant baked into the single
158
+ // artifact, so pinning it is what makes the overflow boundary identical in
159
+ // every runtime.
160
+ const MIN_STACK_SIZE_BYTES = 64 * 1024;
161
+ const MAX_STACK_SIZE_BYTES = 1024 * 1024 * 1024;
162
+
163
+ function resolveStackSize(stackSize) {
164
+ if (stackSize === undefined || stackSize === null) {
165
+ return null;
166
+ }
167
+ if (typeof stackSize !== "number" || !Number.isInteger(stackSize)) {
168
+ throw new Error(
169
+ `stackSize must be an integer number of bytes, got ${JSON.stringify(stackSize)}.`,
170
+ );
171
+ }
172
+ if (stackSize < MIN_STACK_SIZE_BYTES || stackSize > MAX_STACK_SIZE_BYTES) {
173
+ throw new Error(
174
+ `stackSize ${stackSize} is out of range — expected ${MIN_STACK_SIZE_BYTES}..${MAX_STACK_SIZE_BYTES} bytes.`,
175
+ );
176
+ }
177
+ if (stackSize % 16 !== 0) {
178
+ throw new Error(
179
+ `stackSize ${stackSize} must be a multiple of 16 (wasm stack alignment).`,
180
+ );
181
+ }
182
+ return stackSize;
183
+ }
184
+
93
185
  function buildCompilerArgs(exportedSymbols, options = {}) {
94
186
  const linkerExports = exportedSymbols.map(
95
187
  (symbol) => "-Wl,--export=" + symbol,
96
188
  );
97
- const extraArgs = [];
98
- const threadArgs = [];
99
- if (options.threadModel === ModuleThreadModel.EMSCRIPTEN_PTHREADS) {
100
- threadArgs.push("-pthread");
189
+ // wasi-sequential: the SAME clang toolchain and the same target as the
190
+ // pthreads model, but WITHOUT the wasi-threads contract. It must own an
191
+ // unshared memory: an artifact that imports env.memory while exporting no
192
+ // wasi_thread_start is an incomplete wasi-threads contract, and WasmEdge
193
+ // refuses to instantiate it ("unknown import: env.memory"). Held to that
194
+ // shape by assertSequentialArtifact.
195
+ if (options.threadModel === ModuleThreadModel.WASI_SEQUENTIAL) {
196
+ const sequentialArgs = ["-O3", "-mbulk-memory"];
197
+ if (options.noEntry === true) {
198
+ sequentialArgs.push("-mexec-model=reactor");
199
+ }
200
+ const sequentialStackSize = resolveStackSize(options.stackSize);
201
+ if (sequentialStackSize !== null) {
202
+ sequentialArgs.push(`-Wl,-z,stack-size=${sequentialStackSize}`);
203
+ }
204
+ if (options.allowUndefinedImports === true) {
205
+ sequentialArgs.push("-Wl,--allow-undefined");
206
+ }
207
+ sequentialArgs.push(...linkerExports);
208
+ // Defensive invariant, mirroring assertPthreadFlagsPresent: a future edit
209
+ // that reuses PTHREAD_FINAL_LINK_FLAGS here must fail at flag time, not
210
+ // ship a "sequential" guest that needs cross-origin isolation to load.
211
+ assertSequentialFlagsAbsent(sequentialArgs, { threadModel: options.threadModel });
212
+ return sequentialArgs;
101
213
  }
102
- if (options.allowUndefinedImports === true) {
103
- extraArgs.push("-s", "ERROR_ON_UNDEFINED_SYMBOLS=0", "-Wl,--allow-undefined");
104
- }
105
- const args = [
106
- "-O2",
107
- ...threadArgs,
108
- "-s",
109
- "STANDALONE_WASM=1",
110
- ...extraArgs,
111
- ...linkerExports,
112
- ];
214
+
215
+ const isPthreads = options.threadModel === ModuleThreadModel.EMSCRIPTEN_PTHREADS;
216
+ if (isPthreads) {
217
+ // Non-bypassable enforced pthreads final-LINK flag set (source of truth:
218
+ // PTHREAD_FINAL_LINK_FLAGS). These are wasi-threads (wasm-ld) flags, NOT
219
+ // Emscripten -s settings: they import a shared memory and select the
220
+ // atomics/bulk-memory features so the artifact is a wasi-threads wasm
221
+ // (imports wasi.thread-spawn, exports wasi_thread_start) that threads in
222
+ // both the browser (via a SharedArrayBuffer/Worker shim) and WasmEdge. The
223
+ // toolchain args (--target/--sysroot/-resource-dir) are prepended by
224
+ // compileWithWasiThreads. The emitted wasm is validated by
225
+ // assertPthreadArtifact() in compileModuleFromSource.
226
+ const pthreadArgs = ["-O3"];
227
+ if (options.noEntry === true) {
228
+ // No command surface → emit a wasi REACTOR: exports `_initialize` (which
229
+ // runs global constructors + WASI init) and NO `_start`. This makes the
230
+ // artifact directly invocable exactly like the single-thread build. Plain
231
+ // `-Wl,--no-entry` is wrong for wasi-clang: it still links crt1-command,
232
+ // whose `_start` traps (unreachable) at the missing user `main`, leaving
233
+ // the module uninitialized and un-invocable for the direct surface.
234
+ pthreadArgs.push("-mexec-model=reactor");
235
+ }
236
+ pthreadArgs.push(...PTHREAD_FINAL_LINK_FLAGS);
237
+ const pthreadStackSize = resolveStackSize(options.stackSize);
238
+ if (pthreadStackSize !== null) {
239
+ pthreadArgs.push(`-Wl,-z,stack-size=${pthreadStackSize}`);
240
+ }
241
+ if (options.allowUndefinedImports === true) {
242
+ pthreadArgs.push("-Wl,--allow-undefined");
243
+ }
244
+ pthreadArgs.push(...linkerExports);
245
+ // Defensive invariant: the pthreads model must never lose a mandated flag.
246
+ assertPthreadFlagsPresent(pthreadArgs, { threadModel: options.threadModel });
247
+ return pthreadArgs;
248
+ }
249
+ // Single-thread / Emscripten-shared-memory-browser path (emception or system
250
+ // emscripten). Uses Emscripten -s settings.
251
+ const args = ["-O3"];
113
252
  if (options.noEntry === true) {
114
- args.splice(1, 0, "--no-entry");
253
+ args.push("--no-entry");
254
+ }
255
+ // Bulk-memory ops: memcpy/memset in module code lower to native
256
+ // memory.copy/memory.fill instead of byte loops — WITHOUT this, large
257
+ // aligned-stream frames crawl (~10 MB/s) under interpreted hosts
258
+ // (loop C.5 wirespeed gate). Baseline wasm feature, supported by every
259
+ // target host (WasmEdge + all browsers).
260
+ args.push("-mbulk-memory");
261
+ if (usesPthreadCompileFlags(options)) {
262
+ args.push("-pthread");
263
+ }
264
+ args.push("-s", "STANDALONE_WASM=1");
265
+ if (options.importedMemory === true) {
266
+ args.push("-s", "IMPORTED_MEMORY=1");
267
+ }
268
+ if (options.sharedMemory === true) {
269
+ args.push("-s", "SHARED_MEMORY=1");
270
+ }
271
+ if (options.allowUndefinedImports === true) {
272
+ args.push("-s", "ERROR_ON_UNDEFINED_SYMBOLS=0", "-Wl,--allow-undefined");
273
+ }
274
+ args.push("-s", "ALLOW_MEMORY_GROWTH=1");
275
+ args.push(...linkerExports);
276
+ return args;
277
+ }
278
+
279
+ function buildSourceCompilerArgs(options = {}) {
280
+ const isPthreads = options.threadModel === ModuleThreadModel.EMSCRIPTEN_PTHREADS;
281
+ // -mbulk-memory: see buildCompilerArgs — memcpy/memset become native
282
+ // memory.copy/memory.fill (loop C.5).
283
+ const args = ["-O3", "-mbulk-memory", "-DNDEBUG"];
284
+ if (options.threadModel === ModuleThreadModel.WASI_SEQUENTIAL) {
285
+ // -fno-exceptions for the same reason as the pthreads model: the wasi
286
+ // libc++ is built without exception support, so the generated C++ invoke
287
+ // bridge otherwise fails to link on __cxa_allocate_exception.
288
+ //
289
+ // But deliberately NO -matomics and NO -pthread: a sequential guest must
290
+ // not emit atomics, or the artifact acquires the shared-memory shape that
291
+ // assertSequentialArtifact rejects.
292
+ args.push("-fno-exceptions");
293
+ for (const define of Array.isArray(options.defines) ? options.defines : []) {
294
+ const text = String(define ?? "").trim();
295
+ if (/^[A-Za-z_][A-Za-z0-9_]*(=[^\s]*)?$/.test(text)) {
296
+ args.push(`-D${text}`);
297
+ }
298
+ }
299
+ return args;
300
+ }
301
+ if (isPthreads) {
302
+ // wasi-threads object compile: enable atomics and disable C++ exceptions
303
+ // (the wasi-threads libc++ is built without exception support, so throwing
304
+ // code otherwise fails to link on __cxa_throw / __cxa_allocate_exception).
305
+ args.push("-matomics", "-fno-exceptions", "-pthread");
306
+ } else if (usesPthreadCompileFlags(options)) {
307
+ args.push("-pthread");
308
+ }
309
+ // Caller-supplied preprocessor defines (e.g. SDN_FLATSQL_LINKED=1 for the
310
+ // engine-linked guest-link object variant, loop C.7). NAME or NAME=VALUE.
311
+ for (const define of Array.isArray(options.defines) ? options.defines : []) {
312
+ const text = String(define ?? "").trim();
313
+ if (/^[A-Za-z_][A-Za-z0-9_]*(=[^\s]*)?$/.test(text)) {
314
+ args.push(`-D${text}`);
315
+ }
115
316
  }
116
317
  return args;
117
318
  }
@@ -127,11 +328,58 @@ function normalizeThreadModel(value) {
127
328
  if (normalized === ModuleThreadModel.EMSCRIPTEN_PTHREADS) {
128
329
  return ModuleThreadModel.EMSCRIPTEN_PTHREADS;
129
330
  }
331
+ if (normalized === ModuleThreadModel.WASI_SEQUENTIAL) {
332
+ return ModuleThreadModel.WASI_SEQUENTIAL;
333
+ }
130
334
  throw new Error(
131
- `Unsupported threadModel "${value}". Expected "${ModuleThreadModel.SINGLE_THREAD}" or "${ModuleThreadModel.EMSCRIPTEN_PTHREADS}".`,
335
+ `Unsupported threadModel "${value}". Expected one of ` +
336
+ `"${ModuleThreadModel.SINGLE_THREAD}", "${ModuleThreadModel.EMSCRIPTEN_PTHREADS}", ` +
337
+ `"${ModuleThreadModel.WASI_SEQUENTIAL}".`,
132
338
  );
133
339
  }
134
340
 
341
+ /**
342
+ * The wasi-sequential model must be justified in the manifest, in a
343
+ * machine-readable form, or the compile fails. "It happens not to thread today"
344
+ * is not a reason — the guest is being permanently exempted from the threading
345
+ * contract, and a future edit that adds a thread must fail loudly rather than
346
+ * silently re-shape the artifact.
347
+ *
348
+ * manifest.sequentialJustification = { kind, detail }
349
+ */
350
+ function assertSequentialJustification(manifest) {
351
+ const justification = manifest?.sequentialJustification;
352
+ const declare =
353
+ 'Declare manifest.sequentialJustification = { "kind": <one of ' +
354
+ `${JSON.stringify(SEQUENTIAL_JUSTIFICATION_KINDS)}>, "detail": "<why this guest can never spawn a thread>" }.`;
355
+
356
+ if (justification === undefined || justification === null) {
357
+ throw new Error(
358
+ `threadModel "${ModuleThreadModel.WASI_SEQUENTIAL}" requires an explicit justification. ${declare}`,
359
+ );
360
+ }
361
+ if (typeof justification !== "object" || Array.isArray(justification)) {
362
+ throw new Error(
363
+ `manifest.sequentialJustification must be an object, got ${Array.isArray(justification) ? "an array" : typeof justification}. ${declare}`,
364
+ );
365
+ }
366
+ const kind = String(justification.kind ?? "").trim();
367
+ if (!SEQUENTIAL_JUSTIFICATION_KINDS.includes(kind)) {
368
+ throw new Error(
369
+ `manifest.sequentialJustification.kind ${JSON.stringify(kind)} is not recognised. ` +
370
+ `Expected one of ${JSON.stringify(SEQUENTIAL_JUSTIFICATION_KINDS)}.`,
371
+ );
372
+ }
373
+ const detail = String(justification.detail ?? "").trim();
374
+ if (detail.length < SEQUENTIAL_JUSTIFICATION_MIN_LENGTH) {
375
+ throw new Error(
376
+ `manifest.sequentialJustification.detail must be a substantive explanation ` +
377
+ `(at least ${SEQUENTIAL_JUSTIFICATION_MIN_LENGTH} characters), got ${detail.length}. ${declare}`,
378
+ );
379
+ }
380
+ return { kind, detail };
381
+ }
382
+
135
383
  function resolveThreadModel({ manifest, threadModel } = {}) {
136
384
  const explicit = normalizeThreadModel(threadModel);
137
385
  if (explicit) {
@@ -142,26 +390,59 @@ function resolveThreadModel({ manifest, threadModel } = {}) {
142
390
  .map((target) => String(target ?? "").trim().toLowerCase())
143
391
  .filter(Boolean)
144
392
  : [];
145
- if (runtimeTargets.includes(RuntimeTarget.BROWSER)) {
146
- return ModuleThreadModel.SINGLE_THREAD;
147
- }
393
+
394
+ // BROWSER MUST NOT IMPLY EMCC.
395
+ //
396
+ // This test used to run BEFORE the wasmedge test and return SINGLE_THREAD,
397
+ // which routes to Emscripten. The effect was that the MORE isomorphic a
398
+ // module declared itself to be, the worse it was treated: a manifest saying
399
+ // runtimeTargets ["browser","wasmedge"] matched on "browser" first and was
400
+ // silently compiled by emcc, even though it had explicitly asked to run under
401
+ // WasmEdge. Targeting a browser says nothing about whether a guest threads —
402
+ // it is a deployment fact, not a concurrency fact — so it must never select a
403
+ // toolchain.
148
404
  if (runtimeTargets.includes(RuntimeTarget.WASMEDGE)) {
149
405
  return ModuleThreadModel.EMSCRIPTEN_PTHREADS;
150
406
  }
407
+ if (runtimeTargets.includes(RuntimeTarget.BROWSER)) {
408
+ throw new Error(
409
+ "Cannot infer a thread model from runtimeTargets [browser]: targeting a " +
410
+ "browser does not say whether the guest threads, and it must never imply " +
411
+ "the Emscripten toolchain. Declare threadModel explicitly — " +
412
+ `"${ModuleThreadModel.EMSCRIPTEN_PTHREADS}" (real wasi-threads), ` +
413
+ `"${ModuleThreadModel.WASI_SEQUENTIAL}" (clang wasi, provably never spawns a thread; ` +
414
+ "requires manifest.sequentialJustification), or " +
415
+ `"${ModuleThreadModel.SINGLE_THREAD}" (legacy Emscripten).`,
416
+ );
417
+ }
151
418
  return ModuleThreadModel.SINGLE_THREAD;
152
419
  }
153
420
 
154
- function requiresSystemEmscripten(threadModel) {
155
- return threadModel === ModuleThreadModel.EMSCRIPTEN_PTHREADS;
421
+ function requiresSystemEmscripten(threadModel, options = {}) {
422
+ return (
423
+ threadModel === ModuleThreadModel.EMSCRIPTEN_PTHREADS ||
424
+ options.sharedMemory === true
425
+ );
156
426
  }
157
427
 
158
- function guestLinkSymbolPrefix(pluginId) {
428
+ // Guest-link symbols are namespaced by the FULL lowercase-hex encoding of the
429
+ // pluginId's UTF-8 bytes. Hex encoding is injective, so distinct pluginIds always
430
+ // map to distinct prefixes. Do NOT truncate: a prior `.slice(0, 24)` (12 bytes)
431
+ // collided real plugin ids that share a 12-byte stem — e.g. `com.orbpro.iss-source`
432
+ // and `com.orbpro.intelsat-source` both truncated to hex("com.orbpro.i")
433
+ // (`636f6d2e6f726270726f2e69`), which would silently merge/clash their symbols at
434
+ // `wasm-ld -r` compose time. Wasm symbol names have no meaningful length limit, so
435
+ // the full hex is safe. The emitted prefix (and the per-method `methodSymbols`) is
436
+ // recorded in the guest-link metadata; that metadata is the AUTHORITATIVE source
437
+ // consumers read at compose time (see src/flow/flowCompiler.js) — consumers must
438
+ // never re-derive the prefix from pluginId, which keeps already-committed artifacts
439
+ // (including any that carry a legacy truncated prefix) compatible.
440
+ export function guestLinkSymbolPrefix(pluginId) {
159
441
  const normalized = String(pluginId ?? "module");
160
- const ascii = Array.from(new TextEncoder().encode(normalized))
442
+ const hex = Array.from(new TextEncoder().encode(normalized))
161
443
  .map((byte) => byte.toString(16).padStart(2, "0"))
162
- .join("")
163
- .slice(0, 24);
164
- return `sdm_guest_${ascii}_`;
444
+ .join("");
445
+ return `sdm_guest_${hex}_`;
165
446
  }
166
447
 
167
448
  function parseStrongDefinedIdentifiers(nmOutput = "") {
@@ -345,6 +626,9 @@ function createGuestLinkBundleEntries(guestLink) {
345
626
  methodIds: Object.keys(guestLink.methodSymbols ?? {}),
346
627
  language: guestLink.language,
347
628
  threadModel: guestLink.threadModel ?? ModuleThreadModel.SINGLE_THREAD,
629
+ ...(Array.isArray(guestLink.capabilities)
630
+ ? { capabilities: [...guestLink.capabilities] }
631
+ : {}),
348
632
  },
349
633
  description: "Guest-link metadata for monolithic flow linking.",
350
634
  },
@@ -448,6 +732,8 @@ async function compileWithEmception(options = {}) {
448
732
  "-c",
449
733
  sourcePath,
450
734
  `-I${workDir}`,
735
+ `-I${runtimeIncludeDir}`,
736
+ ...buildSourceCompilerArgs(compileOptions),
451
737
  "-o",
452
738
  sourceObjectPath,
453
739
  ],
@@ -476,7 +762,9 @@ async function compileWithEmception(options = {}) {
476
762
  "-c",
477
763
  sourcePath,
478
764
  `-I${workDir}`,
765
+ `-I${runtimeIncludeDir}`,
479
766
  ...guestLink.renameArgs,
767
+ ...buildSourceCompilerArgs(compileOptions),
480
768
  "-o",
481
769
  linkObjectPath,
482
770
  ];
@@ -541,6 +829,7 @@ async function compileWithEmception(options = {}) {
541
829
  methodSymbols: guestLink.methodSymbols,
542
830
  threadModel:
543
831
  compileOptions.threadModel ?? ModuleThreadModel.SINGLE_THREAD,
832
+ capabilities: compileOptions.guestLinkCapabilities,
544
833
  objectBytes: linkObjectBytes,
545
834
  },
546
835
  };
@@ -634,9 +923,8 @@ async function compileWithSystemEmscripten(options = {}) {
634
923
  "-c",
635
924
  sourcePath,
636
925
  `-I${tempDir}`,
637
- ...(compileOptions.threadModel === ModuleThreadModel.EMSCRIPTEN_PTHREADS
638
- ? ["-pthread"]
639
- : []),
926
+ `-I${runtimeIncludeDir}`,
927
+ ...buildSourceCompilerArgs(compileOptions),
640
928
  "-o",
641
929
  sourceObjectPath,
642
930
  ];
@@ -655,10 +943,9 @@ async function compileWithSystemEmscripten(options = {}) {
655
943
  "-c",
656
944
  sourcePath,
657
945
  `-I${tempDir}`,
658
- ...(compileOptions.threadModel === ModuleThreadModel.EMSCRIPTEN_PTHREADS
659
- ? ["-pthread"]
660
- : []),
946
+ `-I${runtimeIncludeDir}`,
661
947
  ...guestLink.renameArgs,
948
+ ...buildSourceCompilerArgs(compileOptions),
662
949
  "-o",
663
950
  linkObjectPath,
664
951
  ];
@@ -669,9 +956,7 @@ async function compileWithSystemEmscripten(options = {}) {
669
956
  "-std=c++17",
670
957
  `-I${tempDir}`,
671
958
  `-I${runtimeIncludeDir}`,
672
- ...(compileOptions.threadModel === ModuleThreadModel.EMSCRIPTEN_PTHREADS
673
- ? ["-pthread"]
674
- : []),
959
+ ...(usesPthreadCompileFlags(compileOptions) ? ["-pthread"] : []),
675
960
  "-o",
676
961
  manifestObjectPath,
677
962
  ]);
@@ -681,9 +966,7 @@ async function compileWithSystemEmscripten(options = {}) {
681
966
  "-std=c++17",
682
967
  `-I${tempDir}`,
683
968
  `-I${runtimeIncludeDir}`,
684
- ...(compileOptions.threadModel === ModuleThreadModel.EMSCRIPTEN_PTHREADS
685
- ? ["-pthread"]
686
- : []),
969
+ ...(usesPthreadCompileFlags(compileOptions) ? ["-pthread"] : []),
687
970
  "-o",
688
971
  invokeObjectPath,
689
972
  ]);
@@ -709,6 +992,161 @@ async function compileWithSystemEmscripten(options = {}) {
709
992
  symbolPrefix: guestLink.prefix,
710
993
  methodSymbols: guestLink.methodSymbols,
711
994
  threadModel: compileOptions.threadModel,
995
+ capabilities: compileOptions.guestLinkCapabilities,
996
+ objectBytes: linkObjectBytes,
997
+ },
998
+ };
999
+ } catch (error) {
1000
+ await rm(tempDir, { recursive: true, force: true });
1001
+ throw error;
1002
+ }
1003
+ }
1004
+
1005
+ async function runWasiCompiler(command, args, options = {}) {
1006
+ try {
1007
+ await execFileAsync(command, args, {
1008
+ cwd: options.cwd,
1009
+ maxBuffer: 32 * 1024 * 1024,
1010
+ });
1011
+ } catch (error) {
1012
+ if (error?.code === "ENOENT") {
1013
+ throw new Error(
1014
+ `Compilation failed: wasi-threads driver "${command}" was not found on PATH.`,
1015
+ );
1016
+ }
1017
+ const stderr = typeof error?.stderr === "string" ? error.stderr.trim() : "";
1018
+ const stdout = typeof error?.stdout === "string" ? error.stdout.trim() : "";
1019
+ const detail = stderr || stdout || error?.message || "unknown error";
1020
+ throw new Error(`Compilation failed with ${command} (wasi-threads): ${detail}`);
1021
+ }
1022
+ }
1023
+
1024
+ // Builds the isomorphic-pthreads artifact with the wasi-threads toolchain
1025
+ // (clang --target=wasm32-wasip1-threads). Emits a wasi-threads wasm (imports
1026
+ // wasi.thread-spawn, exports wasi_thread_start over an imported shared memory)
1027
+ // that threads under WasmEdge and, via a SharedArrayBuffer/Worker shim, the
1028
+ // browser — NOT an Emscripten Web-Worker build. See wasiThreadsToolchain.js and
1029
+ // docs/isomorphic-pthreads.md.
1030
+ async function compileWithWasiThreads(options = {}) {
1031
+ const {
1032
+ manifest,
1033
+ language,
1034
+ sourceExtension,
1035
+ sourceCode,
1036
+ manifestSource,
1037
+ invokeHeaderSource,
1038
+ invokeSource,
1039
+ exportedSymbols,
1040
+ outputPath,
1041
+ compileOptions,
1042
+ } = options;
1043
+ const toolchain = resolveWasiThreadsToolchain();
1044
+ const isCpp = String(language ?? "").toLowerCase().startsWith("c++");
1045
+ const sourceDriver = isCpp ? toolchain.clangxx : toolchain.clang;
1046
+ const cppDriver = toolchain.clangxx;
1047
+
1048
+ const tempDir = await mkdtemp(
1049
+ path.join(os.tmpdir(), "space-data-module-sdk-compile-"),
1050
+ );
1051
+ const resolvedOutputPath = path.resolve(
1052
+ outputPath ?? path.join(tempDir, "module.wasm"),
1053
+ );
1054
+ const runtimeIncludeDir = path.join(tempDir, "flatbuffers-runtime");
1055
+ const sourcePath = path.join(tempDir, `module.${sourceExtension}`);
1056
+ const manifestSourcePath = path.join(tempDir, "plugin-manifest-exports.cpp");
1057
+ const invokeHeaderPath = path.join(tempDir, "space_data_module_invoke.h");
1058
+ const invokeSourcePath = path.join(tempDir, "plugin-invoke-bridge.cpp");
1059
+ const sourceObjectPath = path.join(tempDir, "module.o");
1060
+ const linkObjectPath = path.join(tempDir, "module-link.o");
1061
+ const manifestObjectPath = path.join(tempDir, "plugin-manifest-exports.o");
1062
+ const invokeObjectPath = path.join(tempDir, "plugin-invoke-bridge.o");
1063
+ const wasmOutputPath = path.join(tempDir, "module.wasm");
1064
+
1065
+ try {
1066
+ const { runtimeHeaders, schemaHeaders } = await getInvokeCppSupportFiles();
1067
+ const linkArgs = buildCompilerArgs(exportedSymbols, compileOptions);
1068
+ await writeFilesToDirectory(runtimeIncludeDir, runtimeHeaders);
1069
+ await writeFilesToDirectory(tempDir, schemaHeaders);
1070
+ await writeFile(sourcePath, sourceCode);
1071
+ await writeFile(manifestSourcePath, manifestSource);
1072
+ await writeFile(invokeHeaderPath, invokeHeaderSource);
1073
+ await writeFile(invokeSourcePath, invokeSource);
1074
+
1075
+ const includeArgs = [`-I${tempDir}`, `-I${runtimeIncludeDir}`];
1076
+ const sourceCompilerArgs = buildSourceCompilerArgs(compileOptions);
1077
+
1078
+ await runWasiCompiler(sourceDriver, [
1079
+ ...toolchain.toolchainArgs,
1080
+ "-c",
1081
+ sourcePath,
1082
+ ...includeArgs,
1083
+ ...(isCpp ? ["-std=c++17"] : []),
1084
+ ...sourceCompilerArgs,
1085
+ "-o",
1086
+ sourceObjectPath,
1087
+ ]);
1088
+
1089
+ const sourceObjectBytes = new Uint8Array(await readFile(sourceObjectPath));
1090
+ const guestLink = deriveGuestLinkRenameArgs({
1091
+ objectBytes: sourceObjectBytes,
1092
+ pluginId: manifest?.pluginId,
1093
+ methodIds: Array.isArray(manifest?.methods)
1094
+ ? manifest.methods.map((method) => String(method?.methodId ?? ""))
1095
+ : [],
1096
+ });
1097
+
1098
+ await runWasiCompiler(sourceDriver, [
1099
+ ...toolchain.toolchainArgs,
1100
+ "-c",
1101
+ sourcePath,
1102
+ ...includeArgs,
1103
+ ...(isCpp ? ["-std=c++17"] : []),
1104
+ ...guestLink.renameArgs,
1105
+ ...sourceCompilerArgs,
1106
+ "-o",
1107
+ linkObjectPath,
1108
+ ]);
1109
+
1110
+ for (const [srcPath, objPath] of [
1111
+ [manifestSourcePath, manifestObjectPath],
1112
+ [invokeSourcePath, invokeObjectPath],
1113
+ ]) {
1114
+ await runWasiCompiler(cppDriver, [
1115
+ ...toolchain.toolchainArgs,
1116
+ "-c",
1117
+ srcPath,
1118
+ "-std=c++17",
1119
+ ...includeArgs,
1120
+ ...sourceCompilerArgs,
1121
+ "-o",
1122
+ objPath,
1123
+ ]);
1124
+ }
1125
+
1126
+ await runWasiCompiler(cppDriver, [
1127
+ ...toolchain.toolchainArgs,
1128
+ sourceObjectPath,
1129
+ manifestObjectPath,
1130
+ invokeObjectPath,
1131
+ ...linkArgs,
1132
+ "-o",
1133
+ wasmOutputPath,
1134
+ ]);
1135
+
1136
+ const wasmBytes = new Uint8Array(await readFile(wasmOutputPath));
1137
+ const linkObjectBytes = new Uint8Array(await readFile(linkObjectPath));
1138
+ await writeFile(resolvedOutputPath, wasmBytes);
1139
+ return {
1140
+ wasmBytes,
1141
+ outputPath: resolvedOutputPath,
1142
+ tempDir,
1143
+ guestLink: {
1144
+ format: "wasm-object",
1145
+ language,
1146
+ symbolPrefix: guestLink.prefix,
1147
+ methodSymbols: guestLink.methodSymbols,
1148
+ threadModel: compileOptions.threadModel,
1149
+ capabilities: compileOptions.guestLinkCapabilities,
712
1150
  objectBytes: linkObjectBytes,
713
1151
  },
714
1152
  };
@@ -727,7 +1165,14 @@ export async function compileModuleFromSource(options = {}) {
727
1165
 
728
1166
  ensureExportableMethodIds(manifest);
729
1167
 
730
- const validation = await validateArtifactWithStandards({ manifest });
1168
+ const standardsOptions = {
1169
+ catalog: options.catalog,
1170
+ standardsRoot: options.standardsRoot,
1171
+ };
1172
+ const validation = await validateArtifactWithStandards({
1173
+ manifest,
1174
+ ...standardsOptions,
1175
+ });
731
1176
  if (!validation.ok) {
732
1177
  const error = new Error("Manifest validation failed.");
733
1178
  error.report = validation;
@@ -737,17 +1182,20 @@ export async function compileModuleFromSource(options = {}) {
737
1182
  const compiler = selectCompiler(options.language);
738
1183
  const invokeSurfaces = resolveInvokeSurfaces(manifest);
739
1184
  const includeCommandMain = invokeSurfaces.includes(InvokeSurface.COMMAND);
740
- const { manifest: embeddedManifest, warnings } = toEmbeddedPluginManifest(
741
- manifest,
742
- );
1185
+ const { warnings } = toEmbeddedPluginManifest(manifest);
743
1186
  const manifestSource = generateEmbeddedManifestSource({
744
- manifest: embeddedManifest,
745
- });
746
- const invokeHeaderSource = generateInvokeSupportHeader();
747
- const invokeSource = generateInvokeSupportSource({
1187
+ // Embed the canonical raw PLG shape so fields that do not exist in the
1188
+ // legacy PMAN object model (notably schemaVersion) remain byte-identical
1189
+ // to the signed custom-section manifest.
748
1190
  manifest,
749
- includeCommandMain,
750
1191
  });
1192
+ const invokeHeaderSource = generateInvokeSupportHeader();
1193
+ const invokeSource =
1194
+ EMSCRIPTEN_MEMORY_GROWTH_NOTIFY_SHIM +
1195
+ generateInvokeSupportSource({
1196
+ manifest,
1197
+ includeCommandMain,
1198
+ });
751
1199
 
752
1200
  const exportedSymbols = [
753
1201
  "plugin_get_manifest_flatbuffer",
@@ -774,10 +1222,27 @@ export async function compileModuleFromSource(options = {}) {
774
1222
  ...options,
775
1223
  noEntry: includeCommandMain !== true,
776
1224
  threadModel,
1225
+ guestLinkCapabilities: resolveGuestLinkCapabilities(
1226
+ manifest,
1227
+ options.guestLinkCapabilities,
1228
+ ),
777
1229
  };
778
- const compileFunction = requiresSystemEmscripten(threadModel)
779
- ? compileWithSystemEmscripten
780
- : compileWithEmception;
1230
+ if (threadModel === ModuleThreadModel.WASI_SEQUENTIAL) {
1231
+ // Fails the compile when the manifest has not justified the exemption.
1232
+ assertSequentialJustification(manifest);
1233
+ }
1234
+ // BOTH wasi models use the sanctioned clang wasm32-wasip1-threads toolchain.
1235
+ // The difference is the link shape and which artifact guard applies.
1236
+ const useWasiThreads =
1237
+ threadModel === ModuleThreadModel.EMSCRIPTEN_PTHREADS ||
1238
+ threadModel === ModuleThreadModel.WASI_SEQUENTIAL;
1239
+ const useSystemEmscripten =
1240
+ !useWasiThreads && requiresSystemEmscripten(threadModel, compileOptions);
1241
+ const compileFunction = useWasiThreads
1242
+ ? compileWithWasiThreads
1243
+ : useSystemEmscripten
1244
+ ? compileWithSystemEmscripten
1245
+ : compileWithEmception;
781
1246
  const result = await compileFunction({
782
1247
  manifest,
783
1248
  language: compiler.language,
@@ -791,20 +1256,49 @@ export async function compileModuleFromSource(options = {}) {
791
1256
  outputPath: options.outputPath,
792
1257
  compileOptions,
793
1258
  });
794
- wasmBytes = result.wasmBytes;
1259
+ wasmBytes = appendWasmCustomSection(
1260
+ result.wasmBytes,
1261
+ SDS_MANIFEST_SECTION_NAME,
1262
+ encodePluginManifest(manifest),
1263
+ );
795
1264
  resolvedOutputPath = result.outputPath;
1265
+ await writeFile(resolvedOutputPath, wasmBytes);
796
1266
  tempDir = result.tempDir;
797
1267
 
1268
+ // Enforce the isomorphic-pthreads guardrail on the EMITTED artifact: a build
1269
+ // that claims the pthreads thread model but did not emit a shared-memory /
1270
+ // atomics wasm must FAIL the compile here rather than ship. See
1271
+ // docs/isomorphic-pthreads.md.
1272
+ let threadFeatures = null;
1273
+ if (threadModel === ModuleThreadModel.EMSCRIPTEN_PTHREADS) {
1274
+ threadFeatures = assertPthreadArtifact(wasmBytes, {
1275
+ source: resolvedOutputPath,
1276
+ });
1277
+ } else if (threadModel === ModuleThreadModel.WASI_SEQUENTIAL) {
1278
+ // Mirror guard. The target is passed so that SDN_WASI_TARGET cannot be used
1279
+ // to quietly build a plain wasm32-wasip1 object under the sequential model:
1280
+ // it is a concurrency exemption, not a toolchain exemption.
1281
+ threadFeatures = assertSequentialArtifact(wasmBytes, {
1282
+ source: resolvedOutputPath,
1283
+ target: resolveWasiThreadsToolchain().target,
1284
+ });
1285
+ }
1286
+
798
1287
  // Validate the compiled artifact
799
1288
  const report = await validateArtifactWithStandards({
800
1289
  manifest,
801
1290
  wasmPath: resolvedOutputPath,
1291
+ ...standardsOptions,
802
1292
  });
803
1293
 
804
1294
  return {
805
- compiler: requiresSystemEmscripten(threadModel)
806
- ? "em++ (system emscripten pthreads)"
807
- : "em++ (emception)",
1295
+ compiler: useWasiThreads
1296
+ ? threadModel === ModuleThreadModel.WASI_SEQUENTIAL
1297
+ ? "wasm32-wasi-clang++ (wasi-sequential)"
1298
+ : "wasm32-wasi-clang++ (wasi-threads)"
1299
+ : useSystemEmscripten
1300
+ ? "em++ (system emscripten pthreads)"
1301
+ : "em++ (emception)",
808
1302
  language: compiler.language,
809
1303
  threadModel,
810
1304
  outputPath: resolvedOutputPath,
@@ -812,6 +1306,7 @@ export async function compileModuleFromSource(options = {}) {
812
1306
  wasmBytes,
813
1307
  guestLink: result.guestLink,
814
1308
  manifestWarnings: warnings,
1309
+ threadFeatures,
815
1310
  report,
816
1311
  };
817
1312
  }
@@ -892,6 +1387,10 @@ export async function protectModuleArtifact(options = {}) {
892
1387
  manifestHashHex,
893
1388
  authorization: signedAuthorization,
894
1389
  };
1390
+ const publicationNoticeOptions = {
1391
+ publishTimestamp: options.publishTimestamp,
1392
+ publishTimestampMs: options.publishTimestampMs,
1393
+ };
895
1394
 
896
1395
  let singleFileBundle = null;
897
1396
  let singleFileBundleRecords = null;
@@ -928,6 +1427,7 @@ export async function protectModuleArtifact(options = {}) {
928
1427
  const encryptedBaseBytes = base64ToBytes(encryptedBase.protectedBlobBase64);
929
1428
  const parsedEncryptedBase = extractPublicationRecordCollection(encryptedBaseBytes);
930
1429
  publicationNotice = await createPublicationNotice({
1430
+ ...publicationNoticeOptions,
931
1431
  payloadBytes: parsedEncryptedBase.payloadBytes,
932
1432
  artifactId,
933
1433
  programId,
@@ -958,6 +1458,7 @@ export async function protectModuleArtifact(options = {}) {
958
1458
  });
959
1459
  } else {
960
1460
  publicationNotice = await createPublicationNotice({
1461
+ ...publicationNoticeOptions,
961
1462
  payloadBytes: bundleBytes,
962
1463
  artifactId,
963
1464
  programId,