space-data-module-sdk 0.8.4 → 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 +25 -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
@@ -0,0 +1,877 @@
1
+ /**
2
+ * JS host for compiled SDN flow artifacts (WS3.2) — the browser/node
3
+ * counterpart of the Go host (sdn-server internal/flowrt): the SAME
4
+ * runtime.wasm produced by the flow compiler composes linked-direct chains
5
+ * in the browser harness.
6
+ *
7
+ * Binds the space_data_module_runtime_* ABI (with `_`-prefixed fallbacks),
8
+ * reads/writes the descriptor structs byte-for-byte as abi.go does
9
+ * (dispatch 60B / dependency 72B / frame 48B / invocation 24B / node state
10
+ * 32B / ingress state 24B, all little-endian), and provides the drain loop:
11
+ * ready node -> begin invocation -> host handler OR linked-direct dispatch
12
+ * -> apply -> complete. Linked-direct nodes run entirely inside the
13
+ * artifact's linear memory; host-model nodes dispatch to the handler map
14
+ * (keys resolved as pluginId:methodId, then dependencyId, nodeId, methodId).
15
+ */
16
+
17
+ import { createBrowserWasiShim } from "../host/wasiShim.js";
18
+ import {
19
+ isPayloadSchemaHashValid,
20
+ normalizePayloadSchemaHash,
21
+ } from "../manifest/typeRefs.js";
22
+ import {
23
+ ENGINE_REF_ENTRY_SIZE,
24
+ instantiateFlatsqlLinkShim,
25
+ isEngineBodyRefToken,
26
+ readEngineRefEntry,
27
+ } from "./flatsqlLinkShim.js";
28
+
29
+ export const FLOW_INVALID_INDEX = 0xffffffff;
30
+
31
+ const FRAME_DESCRIPTOR_SIZE = 48;
32
+ const INVOCATION_DESCRIPTOR_SIZE = 24;
33
+ const DISPATCH_DESCRIPTOR_SIZE = 60;
34
+ const DEPENDENCY_DESCRIPTOR_SIZE = 72;
35
+ // FlowEdge: 16 u32/pointer slots + the OPAQUE byte-route flag. Kept beside the
36
+ // other strides so the browser host and the compiled table can never drift
37
+ // apart silently — a mismatch here reads every edge at the wrong offset.
38
+ const EDGE_DESCRIPTOR_SIZE = 68;
39
+ // ...and the stride alone is not enough, because an artifact compiled before
40
+ // the flag exists is 64 bytes and looks identical from the outside. The
41
+ // artifact states its descriptor generation; a host that disagrees REFUSES
42
+ // rather than reading garbage it cannot detect. Artifacts older than the
43
+ // export report nothing, which is generation 1.
44
+ const DESCRIPTOR_ABI_GENERATION = 2;
45
+ const NODE_STATE_SIZE = 32;
46
+ const INGRESS_STATE_SIZE = 24;
47
+ const ROUTING_STATE_SIZE = 32;
48
+
49
+ const WireFormatCode = Object.freeze({
50
+ flatbuffer: 0,
51
+ "aligned-binary": 1,
52
+ });
53
+ const OwnershipCode = Object.freeze({
54
+ "host-owned": 0,
55
+ "plugin-owned": 1,
56
+ transferred: 2,
57
+ });
58
+ const MutabilityCode = Object.freeze({
59
+ immutable: 0,
60
+ mutable: 1,
61
+ "single-writer-mutable": 1,
62
+ "append-only": 2,
63
+ });
64
+
65
+ function normalizeWireFormat(value) {
66
+ const normalized = String(value ?? "").toLowerCase().replace(/_/g, "-");
67
+ if (value === 1 || normalized === "aligned-binary") return "aligned-binary";
68
+ if (
69
+ value === 0 ||
70
+ value === undefined ||
71
+ value === null ||
72
+ normalized === "" ||
73
+ normalized === "flatbuffer"
74
+ ) {
75
+ return "flatbuffer";
76
+ }
77
+ throw new TypeError(`Unsupported frame wire format: ${String(value)}.`);
78
+ }
79
+
80
+ function normalizeOwnership(value) {
81
+ const normalized = String(value ?? "host-owned").toLowerCase().replace(/_/g, "-");
82
+ if (value === 1 || normalized === "plugin-owned" || normalized === "producer-owned") {
83
+ return "plugin-owned";
84
+ }
85
+ if (value === 2 || normalized === "transferred" || normalized === "shared") {
86
+ return "transferred";
87
+ }
88
+ if (value === 0 || normalized === "host-owned" || normalized === "borrowed") {
89
+ return "host-owned";
90
+ }
91
+ throw new TypeError(`Unsupported frame ownership: ${String(value)}.`);
92
+ }
93
+
94
+ function normalizeMutability(value) {
95
+ const normalized = String(value ?? "immutable").toLowerCase().replace(/_/g, "-");
96
+ if (value === 2 || normalized === "append-only") return "append-only";
97
+ if (value === 1 || normalized === "mutable" || normalized === "single-writer-mutable") {
98
+ return "single-writer-mutable";
99
+ }
100
+ if (value === 0 || normalized === "immutable") return "immutable";
101
+ throw new TypeError(`Unsupported frame mutability: ${String(value)}.`);
102
+ }
103
+
104
+ function isPowerOfTwo(value) {
105
+ return (
106
+ Number.isSafeInteger(value) &&
107
+ value > 0 &&
108
+ value <= 0xffff &&
109
+ (value & (value - 1)) === 0
110
+ );
111
+ }
112
+
113
+ function bytesEqual(left, right) {
114
+ if (left.length !== right.length) return false;
115
+ for (let index = 0; index < left.length; index += 1) {
116
+ if (left[index] !== right[index]) return false;
117
+ }
118
+ return true;
119
+ }
120
+
121
+ function typeRefMatchesDescriptor(typeRef = {}, descriptor, wireFormat) {
122
+ if (typeRef.schemaName && typeRef.schemaName !== descriptor.schemaName) return false;
123
+ if (typeRef.fileIdentifier && typeRef.fileIdentifier !== descriptor.fileIdentifier) return false;
124
+ if (typeRef.rootTypeName && typeRef.rootTypeName !== descriptor.rootTypeName) return false;
125
+ if (typeRef.schemaVersion && typeRef.schemaVersion !== descriptor.schemaVersion) return false;
126
+
127
+ const schemaHashInput = typeRef.schemaHash;
128
+ if (schemaHashInput !== undefined && schemaHashInput !== null) {
129
+ if (!isPayloadSchemaHashValid(schemaHashInput)) return false;
130
+ const schemaHash = normalizePayloadSchemaHash(schemaHashInput);
131
+ if (schemaHash?.length > 0 && !bytesEqual(schemaHash, descriptor.schemaHash)) return false;
132
+ }
133
+
134
+ if (wireFormat === "aligned-binary") {
135
+ if (!descriptor.alignedEligible) return false;
136
+ if (Number(typeRef.byteLength ?? 0) !== descriptor.alignedByteLength) return false;
137
+ if (Number(typeRef.requiredAlignment ?? 0) !== descriptor.alignedRequiredAlignment) {
138
+ return false;
139
+ }
140
+ if (
141
+ typeRef.fixedStringLength !== undefined &&
142
+ Number(typeRef.fixedStringLength) !== descriptor.alignedFixedStringLength
143
+ ) {
144
+ return false;
145
+ }
146
+ }
147
+ return true;
148
+ }
149
+
150
+ const textDecoder = new TextDecoder();
151
+ const textEncoder = new TextEncoder();
152
+
153
+ function assertDescriptorAbiGeneration(generation) {
154
+ if (generation === DESCRIPTOR_ABI_GENERATION) return;
155
+ throw new Error(
156
+ `flow artifact descriptor ABI generation ${generation} does not match this host's ` +
157
+ `${DESCRIPTOR_ABI_GENERATION}. Its edge descriptors are a different size, so reading ` +
158
+ "them here would return silently wrong types, ports and layouts. Recompile the flow " +
159
+ "with this SDK (v1 carries no back-compat shim for descriptor layouts).",
160
+ );
161
+ }
162
+
163
+ function exportFn(exports, name) {
164
+ const fn = exports[name] ?? exports[`_${name}`];
165
+ return typeof fn === "function" ? fn : null;
166
+ }
167
+
168
+ // Publication-protected artifacts (docs/module-publication-standard.md) append
169
+ // an SDS $REC record collection: payload || REC bytes || uint32le(REC length)
170
+ // || "$REC". Loaders strip the trailer before wasm compilation (loader
171
+ // expectation 6); signature/bundle-metadata verification stays a separate
172
+ // concern (bundle/signing.js verifyModuleArtifact).
173
+ const REC_TRAILER_FOOTER_LENGTH = 8;
174
+ const REC_TRAILER_MAGIC = [0x24, 0x52, 0x45, 0x43]; // "$REC"
175
+
176
+ export function stripPublicationTrailer(bytes) {
177
+ if (!(bytes instanceof Uint8Array) || bytes.length < REC_TRAILER_FOOTER_LENGTH) {
178
+ return bytes;
179
+ }
180
+ const footer = bytes.length - REC_TRAILER_FOOTER_LENGTH;
181
+ for (let i = 0; i < 4; i += 1) {
182
+ if (bytes[footer + 4 + i] !== REC_TRAILER_MAGIC[i]) return bytes;
183
+ }
184
+ const recLength =
185
+ (bytes[footer] |
186
+ (bytes[footer + 1] << 8) |
187
+ (bytes[footer + 2] << 16) |
188
+ (bytes[footer + 3] << 24)) >>>
189
+ 0;
190
+ const payloadLength = footer - recLength;
191
+ if (recLength === 0 || payloadLength < 0) return bytes;
192
+ return bytes.subarray(0, payloadLength);
193
+ }
194
+
195
+ export async function createFlowRuntimeHost(options = {}) {
196
+ let wasmModule = options.wasmModule ?? null;
197
+ if (!wasmModule) {
198
+ const source = options.wasmSource ?? options.wasmBytes;
199
+ if (!source) {
200
+ throw new TypeError("createFlowRuntimeHost requires wasmSource bytes or a wasmModule.");
201
+ }
202
+ const bytes = stripPublicationTrailer(
203
+ source instanceof Uint8Array ? source : new Uint8Array(source),
204
+ );
205
+ wasmModule = await WebAssembly.compile(bytes.slice().buffer);
206
+ }
207
+
208
+ const wasi = createBrowserWasiShim({
209
+ args: options.args ?? ["flow-runtime"],
210
+ env: options.env ?? {},
211
+ logOutput: options.logOutput === true,
212
+ });
213
+ const imports = { ...wasi.imports, ...(options.extraImports ?? {}) };
214
+ // Direct engine linkage (loop C.7): a LINKED flow artifact imports the live
215
+ // FlatSQL engine's function exports (module "flatsql") and the tiny
216
+ // memory-crossing shim (module "flatsql_link", instantiated here against
217
+ // the SAME engine memory) — the browser-native form of the server's
218
+ // VM.RegisterModule instance sharing.
219
+ const engineLink = options.engineLink ?? null;
220
+ if (engineLink) {
221
+ if (!engineLink.exports || !(engineLink.exports.memory instanceof WebAssembly.Memory)) {
222
+ throw new TypeError(
223
+ "createFlowRuntimeHost engineLink requires the live engine's exports (with memory).",
224
+ );
225
+ }
226
+ const shimInstance = await instantiateFlatsqlLinkShim(engineLink.exports);
227
+ imports.flatsql = engineLink.exports;
228
+ imports.flatsql_link = shimInstance.exports;
229
+ }
230
+ if (options.legacyHostImportCompat === true) {
231
+ // Legacy compiled-flow artifacts import a `sdn_flow_host` module; stub its
232
+ // dispatch entry (0 = caller wins) so they instantiate under plain
233
+ // WebAssembly.instantiate. Ported from orbpro-integration's
234
+ // withLegacyHostImportCompat; the module name + stub are ABI contracts.
235
+ imports.sdn_flow_host = {
236
+ dispatch_current_invocation: () => 0,
237
+ ...(imports.sdn_flow_host ?? {}),
238
+ };
239
+ }
240
+ const instance = await WebAssembly.instantiate(wasmModule, imports);
241
+ const exports = instance.exports;
242
+ const memory = exports.memory;
243
+ if (!(memory instanceof WebAssembly.Memory)) {
244
+ throw new Error("Flow artifact exports no memory.");
245
+ }
246
+ wasi.setMemory(memory);
247
+ exportFn(exports, "_initialize")?.();
248
+
249
+ if (engineLink) {
250
+ const linkInit = exportFn(exports, "sdn_flatsql_link_init");
251
+ if (!linkInit) {
252
+ throw new Error(
253
+ "engineLink was provided but the flow artifact exports no sdn_flatsql_link_init " +
254
+ "(compile the flow with engineLinkage: \"flatsql\").",
255
+ );
256
+ }
257
+ linkInit(engineLink.dbHandle | 0);
258
+ }
259
+
260
+ const malloc = exportFn(exports, "malloc");
261
+ if (!malloc) {
262
+ throw new Error("Flow artifact must export malloc for host-side frame allocation.");
263
+ }
264
+ const free = exportFn(exports, "free");
265
+ if (!free) {
266
+ throw new Error("Flow artifact must export free for host-side frame lifetime management.");
267
+ }
268
+
269
+ const call = (name, ...args) => {
270
+ const fn = exportFn(exports, `space_data_module_runtime_${name}`);
271
+ if (!fn) {
272
+ throw new Error(`Flow artifact missing export space_data_module_runtime_${name}`);
273
+ }
274
+ return fn(...args);
275
+ };
276
+ const view = () => new DataView(memory.buffer);
277
+ const bytesAt = (ptr, length) => new Uint8Array(memory.buffer, ptr, length).slice();
278
+
279
+ function readCString(ptr, maxLength = 1024) {
280
+ if (!ptr) return "";
281
+ const heap = new Uint8Array(memory.buffer);
282
+ let end = ptr;
283
+ const limit = Math.min(heap.length, ptr + maxLength);
284
+ while (end < limit && heap[end] !== 0) end++;
285
+ return textDecoder.decode(heap.subarray(ptr, end));
286
+ }
287
+
288
+ function writeBytes(ptr, bytes) {
289
+ new Uint8Array(memory.buffer).set(bytes, ptr);
290
+ }
291
+
292
+ function allocTracked(size, allocations, description) {
293
+ const ptr = malloc(size);
294
+ if (!ptr) throw new Error(`${description} malloc(${size}) failed in flow artifact`);
295
+ allocations.push(ptr);
296
+ return ptr;
297
+ }
298
+
299
+ function releaseAllocations(allocations) {
300
+ for (let index = allocations.length - 1; index >= 0; index -= 1) {
301
+ free(allocations[index]);
302
+ }
303
+ allocations.length = 0;
304
+ }
305
+
306
+ function allocAlignedBytes(bytes, alignment = 1, allocations = []) {
307
+ if (!isPowerOfTwo(alignment)) {
308
+ throw new RangeError(`Frame alignment ${alignment} must be a positive power of two.`);
309
+ }
310
+ if (bytes.length === 0) return 0;
311
+ const rawPtr = allocTracked(
312
+ bytes.length + alignment - 1,
313
+ allocations,
314
+ "aligned frame payload",
315
+ );
316
+ const ptr = Math.ceil(rawPtr / alignment) * alignment;
317
+ writeBytes(ptr, bytes);
318
+ return ptr;
319
+ }
320
+
321
+ function allocCString(text, allocations = []) {
322
+ const encoded = textEncoder.encode(String(text ?? ""));
323
+ const ptr = allocTracked(
324
+ encoded.length + 1,
325
+ allocations,
326
+ "frame port string",
327
+ );
328
+ writeBytes(ptr, encoded);
329
+ new Uint8Array(memory.buffer)[ptr + encoded.length] = 0;
330
+ return ptr;
331
+ }
332
+
333
+ function writeFrameDescriptor(ptr, frame) {
334
+ const v = view();
335
+ v.setUint32(ptr + 0, frame.ingressIndex ?? 0, true);
336
+ v.setUint32(ptr + 4, frame.typeDescriptorIdx ?? FLOW_INVALID_INDEX, true);
337
+ v.setUint32(ptr + 8, frame.portIdPtr ?? 0, true);
338
+ v.setUint32(ptr + 12, frame.alignment ?? 1, true);
339
+ v.setUint32(ptr + 16, frame.offset ?? 0, true);
340
+ v.setUint32(ptr + 20, frame.size ?? 0, true);
341
+ v.setUint32(ptr + 24, frame.streamId ?? 0, true);
342
+ v.setUint32(ptr + 28, frame.sequence ?? 0, true);
343
+ v.setBigUint64(ptr + 32, BigInt(frame.traceToken ?? 0), true);
344
+ v.setUint8(ptr + 40, frame.endOfStream ? 1 : 0);
345
+ v.setUint8(ptr + 41, frame.occupied === false ? 0 : 1);
346
+ v.setUint8(ptr + 42, frame.wireFormat ?? 0);
347
+ v.setUint8(ptr + 43, frame.ownership ?? 0);
348
+ v.setUint8(ptr + 44, frame.mutability ?? 0);
349
+ v.setUint8(ptr + 45, frame.lifetime ?? 0);
350
+ v.setUint16(ptr + 46, 0, true);
351
+ }
352
+
353
+ function readFrameDescriptor(ptr) {
354
+ const v = view();
355
+ return {
356
+ ingressIndex: v.getUint32(ptr + 0, true),
357
+ typeDescriptorIdx: v.getUint32(ptr + 4, true),
358
+ portIdPtr: v.getUint32(ptr + 8, true),
359
+ alignment: v.getUint32(ptr + 12, true),
360
+ offset: v.getUint32(ptr + 16, true),
361
+ size: v.getUint32(ptr + 20, true),
362
+ streamId: v.getUint32(ptr + 24, true),
363
+ sequence: v.getUint32(ptr + 28, true),
364
+ traceToken: v.getBigUint64(ptr + 32, true),
365
+ endOfStream: v.getUint8(ptr + 40) !== 0,
366
+ occupied: v.getUint8(ptr + 41) !== 0,
367
+ wireFormat: v.getUint8(ptr + 42),
368
+ ownership: v.getUint8(ptr + 43),
369
+ mutability: v.getUint8(ptr + 44),
370
+ lifetime: v.getUint8(ptr + 45),
371
+ };
372
+ }
373
+
374
+ function readU32Fields(ptr, names) {
375
+ const v = view();
376
+ const out = {};
377
+ names.forEach((name, i) => {
378
+ out[name] = v.getUint32(ptr + i * 4, true);
379
+ });
380
+ return out;
381
+ }
382
+
383
+ let nextExternalFrameId = 1n;
384
+
385
+ const host = {
386
+ instance,
387
+ memory,
388
+ descriptorAbiGeneration:
389
+ exportFn(exports, "space_data_module_runtime_get_descriptor_abi_generation")?.() >>> 0 || 1,
390
+ nodeCount: call("get_node_descriptor_count") >>> 0,
391
+ typeDescriptorCount: call("get_edge_descriptor_count") >>> 0,
392
+ edgeCount: call("get_route_edge_descriptor_count") >>> 0,
393
+ triggerCount: call("get_trigger_descriptor_count") >>> 0,
394
+ dependencyCount: call("get_dependency_descriptor_count") >>> 0,
395
+
396
+ resetState() {
397
+ call("reset_state");
398
+ },
399
+
400
+ readCString,
401
+
402
+ getNodeDispatchDescriptor(index) {
403
+ const base = call("get_node_dispatch_descriptors") >>> 0;
404
+ if (!base) throw new Error("no dispatch descriptors");
405
+ const d = readU32Fields(base + index * DISPATCH_DESCRIPTOR_SIZE, [
406
+ "nodeIdPtr", "nodeIndex", "dependencyIdPtr", "dependencyIndex",
407
+ "pluginIdPtr", "methodIdPtr", "dispatchModelPtr", "entrypointPtr",
408
+ "manifestBytesSymbolPtr", "manifestSizeSymbolPtr",
409
+ "initSymbolPtr", "destroySymbolPtr",
410
+ "mallocSymbolPtr", "freeSymbolPtr", "streamInvokeSymbolPtr",
411
+ ]);
412
+ return {
413
+ ...d,
414
+ nodeId: readCString(d.nodeIdPtr),
415
+ dependencyId: readCString(d.dependencyIdPtr),
416
+ pluginId: readCString(d.pluginIdPtr),
417
+ methodId: readCString(d.methodIdPtr),
418
+ dispatchModel: readCString(d.dispatchModelPtr),
419
+ };
420
+ },
421
+
422
+ getDependencyDescriptor(index) {
423
+ const base = call("get_dependency_descriptors") >>> 0;
424
+ if (!base) throw new Error("no dependency descriptors");
425
+ const d = readU32Fields(base + index * DEPENDENCY_DESCRIPTOR_SIZE, [
426
+ "dependencyIdPtr", "pluginIdPtr", "versionPtr", "sha256Ptr",
427
+ "signaturePtr", "signerPublicKeyPtr", "entrypointPtr",
428
+ "manifestBytesSymbolPtr", "manifestSizeSymbolPtr",
429
+ "initSymbolPtr", "destroySymbolPtr",
430
+ "mallocSymbolPtr", "freeSymbolPtr", "streamInvokeSymbolPtr",
431
+ "wasmBytesPtr", "wasmSize", "manifestBytesPtr", "manifestSize",
432
+ ]);
433
+ return {
434
+ ...d,
435
+ dependencyId: readCString(d.dependencyIdPtr),
436
+ pluginId: readCString(d.pluginIdPtr),
437
+ version: readCString(d.versionPtr),
438
+ sha256: readCString(d.sha256Ptr) || null,
439
+ signature: readCString(d.signaturePtr) || null,
440
+ signerPublicKey: readCString(d.signerPublicKeyPtr) || null,
441
+ };
442
+ },
443
+
444
+ getEdgeDescriptor(index) {
445
+ if (
446
+ !Number.isInteger(index) ||
447
+ index < 0 ||
448
+ index >= this.typeDescriptorCount
449
+ ) {
450
+ throw new RangeError(`edge descriptor index ${index} is out of range`);
451
+ }
452
+ assertDescriptorAbiGeneration(this.descriptorAbiGeneration);
453
+ const base = call("get_edge_descriptors") >>> 0;
454
+ if (!base) throw new Error("no edge descriptors");
455
+ const ptr = base + index * EDGE_DESCRIPTOR_SIZE;
456
+ const d = readU32Fields(ptr, [
457
+ "fromNode", "fromPortPtr", "toNode", "toPortPtr",
458
+ "schemaNamePtr", "fileIdentifierPtr", "schemaVersionPtr",
459
+ "schemaHashPtr", "schemaHashSize", "rootTypeNamePtr",
460
+ "canonicalFallbackAvailable", "alignedEligible", "alignedLayoutFields",
461
+ "alignedByteLength", "alignedFixedStringLength", "alignedRequiredAlignment",
462
+ "opaque",
463
+ ]);
464
+ return {
465
+ ...d,
466
+ fromPort: readCString(d.fromPortPtr),
467
+ toPort: readCString(d.toPortPtr),
468
+ schemaName: readCString(d.schemaNamePtr),
469
+ fileIdentifier: readCString(d.fileIdentifierPtr),
470
+ schemaVersion: readCString(d.schemaVersionPtr) || null,
471
+ schemaHash:
472
+ d.schemaHashPtr && d.schemaHashSize
473
+ ? bytesAt(d.schemaHashPtr, d.schemaHashSize)
474
+ : new Uint8Array(),
475
+ rootTypeName: readCString(d.rootTypeNamePtr),
476
+ };
477
+ },
478
+
479
+ getTypeDescriptor(index) {
480
+ return index < this.typeDescriptorCount
481
+ ? this.getEdgeDescriptor(index)
482
+ : null;
483
+ },
484
+
485
+ getRoutingState() {
486
+ const ptr = call("get_routing_state") >>> 0;
487
+ if (!ptr || ptr + ROUTING_STATE_SIZE > memory.buffer.byteLength) {
488
+ throw new Error("no routing state");
489
+ }
490
+ const v = view();
491
+ return {
492
+ alignedSharedRoutes: v.getBigUint64(ptr + 0, true),
493
+ alignedCopiedRoutes: v.getBigUint64(ptr + 8, true),
494
+ canonicalRoutes: v.getBigUint64(ptr + 16, true),
495
+ rejectedFrames: v.getBigUint64(ptr + 24, true),
496
+ };
497
+ },
498
+
499
+ getNodeState(index) {
500
+ const base = call("get_node_states") >>> 0;
501
+ if (!base) throw new Error("no node states");
502
+ const ptr = base + index * NODE_STATE_SIZE;
503
+ const v = view();
504
+ return {
505
+ invocationCount: v.getBigUint64(ptr + 0, true),
506
+ consumedFrames: v.getBigUint64(ptr + 8, true),
507
+ queuedFrames: v.getUint32(ptr + 16, true),
508
+ backlogRemaining: v.getUint32(ptr + 20, true),
509
+ lastStatus: v.getUint32(ptr + 24, true),
510
+ ready: v.getUint8(ptr + 28) !== 0,
511
+ yielded: v.getUint8(ptr + 29) !== 0,
512
+ };
513
+ },
514
+
515
+ getIngressState(index) {
516
+ const base = call("get_ingress_states") >>> 0;
517
+ if (!base) throw new Error("no ingress states");
518
+ const ptr = base + index * INGRESS_STATE_SIZE;
519
+ const v = view();
520
+ return {
521
+ totalReceived: v.getBigUint64(ptr + 0, true),
522
+ totalDropped: v.getBigUint64(ptr + 8, true),
523
+ queuedFrames: v.getUint32(ptr + 16, true),
524
+ };
525
+ },
526
+
527
+ /**
528
+ * Engine body-reference resolution (loop C.7 direct linkage): tokens with
529
+ * the "SDNE" magic reference an artifact materialized in ENGINE memory by
530
+ * a direct in-wasm query. The entry lives in the flow's exported ref
531
+ * table; the bytes are copied straight out of the engine's linear memory
532
+ * (the JS counterpart of the Go harvest under the store engine lock —
533
+ * single-threaded JS needs no lock). Returns null for unknown tokens.
534
+ */
535
+ resolveEngineBodyRef(token) {
536
+ if (!engineLink || !isEngineBodyRefToken(token)) return null;
537
+ const tablePtr = exportFn(exports, "sdn_flatsql_link_ref_table")?.() >>> 0;
538
+ const slots = exportFn(exports, "sdn_flatsql_link_ref_slots")?.() >>> 0;
539
+ if (!tablePtr || !slots) return null;
540
+ const v = view();
541
+ for (let i = 0; i < slots; i++) {
542
+ const entry = readEngineRefEntry(v, tablePtr + i * ENGINE_REF_ENTRY_SIZE);
543
+ if (!entry.used || entry.token !== BigInt(token)) continue;
544
+ const engineHeap = new Uint8Array(engineLink.exports.memory.buffer);
545
+ return {
546
+ ...entry,
547
+ bytes: engineHeap.slice(entry.enginePtr, entry.enginePtr + entry.size),
548
+ };
549
+ }
550
+ return null;
551
+ },
552
+
553
+ enqueueTrigger(triggerIndex) {
554
+ call("enqueue_trigger_frames", triggerIndex);
555
+ },
556
+
557
+ enqueueTriggerFrame(triggerIndex, frame = {}) {
558
+ const allocations = [];
559
+ try {
560
+ const payload =
561
+ frame.bytes instanceof Uint8Array
562
+ ? frame.bytes
563
+ : frame.bytes
564
+ ? new Uint8Array(frame.bytes)
565
+ : new Uint8Array(0);
566
+ const typeRef = frame.typeRef ?? {};
567
+ const wireFormat = normalizeWireFormat(typeRef.wireFormat ?? frame.wireFormat);
568
+ const alignment = Number(
569
+ frame.alignment ??
570
+ (wireFormat === "aligned-binary" ? typeRef.requiredAlignment : 1) ??
571
+ 1,
572
+ );
573
+ if (!isPowerOfTwo(alignment)) {
574
+ throw new RangeError(`Frame alignment ${alignment} must be a positive power of two.`);
575
+ }
576
+ if (
577
+ wireFormat === "aligned-binary" &&
578
+ Number(typeRef.byteLength ?? 0) !== payload.length
579
+ ) {
580
+ throw new RangeError(
581
+ `Aligned frame byteLength ${typeRef.byteLength ?? 0} does not match payload length ${payload.length}.`,
582
+ );
583
+ }
584
+ let typeDescriptorIdx = FLOW_INVALID_INDEX;
585
+ const explicitType =
586
+ wireFormat === "aligned-binary" ||
587
+ [
588
+ "schemaName", "fileIdentifier", "rootTypeName", "schemaVersion",
589
+ "schemaHash", "byteLength", "fixedStringLength", "requiredAlignment",
590
+ ].some((field) => typeRef[field] !== undefined && typeRef[field] !== null);
591
+ if (explicitType) {
592
+ for (let index = 0; index < this.typeDescriptorCount; index += 1) {
593
+ const descriptor = this.getEdgeDescriptor(index);
594
+ if (!typeRefMatchesDescriptor(typeRef, descriptor, wireFormat)) continue;
595
+ typeDescriptorIdx = index;
596
+ break;
597
+ }
598
+ if (typeDescriptorIdx === FLOW_INVALID_INDEX) {
599
+ throw new Error("Trigger frame does not match any compiled exact SDS identity.");
600
+ }
601
+ }
602
+ const ownershipName = normalizeOwnership(frame.ownership);
603
+ const mutabilityName = normalizeMutability(frame.mutability);
604
+ if (mutabilityName !== "immutable" && ownershipName !== "transferred") {
605
+ throw new Error("Mutable aligned frames require transferred ownership.");
606
+ }
607
+ const payloadPtr =
608
+ payload.length > 0
609
+ ? allocAlignedBytes(payload, alignment, allocations)
610
+ : 0;
611
+ const portPtr = frame.portId ? allocCString(frame.portId, allocations) : 0;
612
+ const framePtr = allocTracked(
613
+ FRAME_DESCRIPTOR_SIZE,
614
+ allocations,
615
+ "frame descriptor",
616
+ );
617
+ const frameId = BigInt(frame.frameId ?? frame.traceToken ?? nextExternalFrameId++);
618
+ writeFrameDescriptor(framePtr, {
619
+ typeDescriptorIdx,
620
+ portIdPtr: portPtr,
621
+ alignment,
622
+ offset: payloadPtr,
623
+ size: payload.length,
624
+ streamId: frame.streamId ?? 0,
625
+ sequence: frame.sequence ?? 0,
626
+ traceToken: frameId,
627
+ endOfStream: frame.endOfStream === true,
628
+ occupied: true,
629
+ wireFormat: WireFormatCode[wireFormat],
630
+ ownership: OwnershipCode[ownershipName],
631
+ mutability: MutabilityCode[mutabilityName],
632
+ });
633
+ const enqueued = call("enqueue_trigger_frame", triggerIndex, framePtr) | 0;
634
+ if (enqueued < 0) {
635
+ throw new Error(`Flow runtime rejected trigger frame (${enqueued}).`);
636
+ }
637
+ return enqueued;
638
+ } finally {
639
+ releaseAllocations(allocations);
640
+ }
641
+ },
642
+
643
+ /**
644
+ * Drain the flow: mirrors the Go host loop. handlers maps
645
+ * "pluginId:methodId" (or dependencyId / nodeId / methodId) to
646
+ * async ({nodeIndex, pluginId, methodId, dependencyId, nodeId, frames})
647
+ * -> { statusCode?, outputs?: [{portId, bytes, ...}] }.
648
+ */
649
+ async drain(handlers = {}, options = {}) {
650
+ const maxIterations = options.maxIterations ?? 1000;
651
+ const result = { iterations: 0, nodesInvoked: 0, handlersSkipped: 0 };
652
+ // In-wasm scheduler loop (loop C.5c): artifacts exporting
653
+ // space_data_module_runtime_drain_linked run all ready linked-direct
654
+ // nodes inside ONE call; the host loop then only services host-model
655
+ // nodes. Older artifacts fall back to per-node driving below.
656
+ const drainLinked = exportFn(exports, "space_data_module_runtime_drain_linked");
657
+
658
+ for (let i = 0; i < maxIterations; i++) {
659
+ if (drainLinked) {
660
+ const dispatched = drainLinked(maxIterations) | 0;
661
+ if (dispatched > 0) {
662
+ result.nodesInvoked += dispatched;
663
+ result.iterations += dispatched;
664
+ }
665
+ }
666
+ const nodeIndex = call("get_ready_node_index") >>> 0;
667
+ if (nodeIndex === FLOW_INVALID_INDEX) break;
668
+ result.iterations++;
669
+
670
+ const consumed = call("begin_node_invocation", nodeIndex, options.frameBudget ?? 64);
671
+ if (consumed < 0) {
672
+ call("complete_node_invocation", nodeIndex);
673
+ continue;
674
+ }
675
+ const descPtr = call("get_current_invocation_descriptor") >>> 0;
676
+ if (!descPtr || descPtr === FLOW_INVALID_INDEX) {
677
+ call("complete_node_invocation", nodeIndex);
678
+ continue;
679
+ }
680
+ const inv = readU32Fields(descPtr, [
681
+ "nodeIndex", "dispatchDescriptorIdx", "pluginIdPtr", "methodIdPtr",
682
+ "framesPtr", "frameCount",
683
+ ]);
684
+ const pluginId = readCString(inv.pluginIdPtr);
685
+ const methodId = readCString(inv.methodIdPtr);
686
+ let dependencyId = "";
687
+ let nodeId = "";
688
+ let dispatchModel = "";
689
+ if (inv.dispatchDescriptorIdx !== FLOW_INVALID_INDEX) {
690
+ const dd = this.getNodeDispatchDescriptor(inv.dispatchDescriptorIdx);
691
+ dependencyId = dd.dependencyId;
692
+ nodeId = dd.nodeId;
693
+ dispatchModel = dd.dispatchModel;
694
+ }
695
+
696
+ const handler =
697
+ handlers[`${pluginId}:${methodId}`] ??
698
+ handlers[dependencyId] ??
699
+ handlers[nodeId] ??
700
+ handlers[methodId] ??
701
+ null;
702
+
703
+ if (!handler) {
704
+ // No host handler: linked-direct nodes run entirely inside the
705
+ // artifact — do NOT copy their (possibly large) input frames out of
706
+ // linear memory just to discard them (loop C.5c copy elimination;
707
+ // mirrors the Go host's drain).
708
+ result.handlersSkipped++;
709
+ if (dispatchModel === "linked-direct") {
710
+ call("dispatch_current_invocation_direct", options.frameBudget ?? 64);
711
+ call("complete_node_invocation", nodeIndex);
712
+ result.nodesInvoked++;
713
+ continue;
714
+ }
715
+ call("complete_node_invocation", nodeIndex);
716
+ continue;
717
+ }
718
+
719
+ const frames = [];
720
+ for (let f = 0; f < inv.frameCount; f++) {
721
+ const fd = readFrameDescriptor(inv.framesPtr + f * FRAME_DESCRIPTOR_SIZE);
722
+ if (!fd.occupied) continue;
723
+ const typeDescriptor = this.getTypeDescriptor(fd.typeDescriptorIdx);
724
+ const wireFormat = fd.wireFormat === 1 ? "aligned-binary" : "flatbuffer";
725
+ const typeRef = typeDescriptor
726
+ ? {
727
+ schemaName: typeDescriptor.schemaName,
728
+ fileIdentifier: typeDescriptor.fileIdentifier,
729
+ ...(typeDescriptor.schemaVersion
730
+ ? { schemaVersion: typeDescriptor.schemaVersion }
731
+ : {}),
732
+ ...(typeDescriptor.schemaHash.length > 0
733
+ ? { schemaHash: typeDescriptor.schemaHash }
734
+ : {}),
735
+ rootTypeName: typeDescriptor.rootTypeName,
736
+ wireFormat,
737
+ ...(wireFormat === "aligned-binary"
738
+ ? {
739
+ byteLength: typeDescriptor.alignedByteLength,
740
+ ...(typeDescriptor.alignedFixedStringLength > 0
741
+ ? { fixedStringLength: typeDescriptor.alignedFixedStringLength }
742
+ : {}),
743
+ requiredAlignment: typeDescriptor.alignedRequiredAlignment,
744
+ }
745
+ : {}),
746
+ }
747
+ : null;
748
+ frames.push({
749
+ portId: readCString(fd.portIdPtr),
750
+ bytes: fd.size > 0 && fd.offset > 0 ? bytesAt(fd.offset, fd.size) : new Uint8Array(0),
751
+ typeRef,
752
+ wireFormat,
753
+ alignment: fd.alignment,
754
+ ownership: ["host-owned", "plugin-owned", "transferred"][fd.ownership] ?? "unknown",
755
+ mutability: ["immutable", "single-writer-mutable", "append-only"][fd.mutability] ?? "unknown",
756
+ frameId: fd.traceToken,
757
+ arenaGeneration: fd.ingressIndex,
758
+ streamId: fd.streamId,
759
+ sequence: fd.sequence,
760
+ endOfStream: fd.endOfStream,
761
+ });
762
+ }
763
+
764
+ let handlerResult;
765
+ try {
766
+ handlerResult = (await handler({
767
+ nodeIndex, pluginId, methodId, dependencyId, nodeId, frames,
768
+ })) ?? {};
769
+ } catch (error) {
770
+ handlerResult = { statusCode: -1, error };
771
+ }
772
+
773
+ const outputs = Array.isArray(handlerResult.outputs) ? handlerResult.outputs : [];
774
+ const allocations = [];
775
+ let framesPtr = 0;
776
+ try {
777
+ if (outputs.length > 0) {
778
+ framesPtr = allocTracked(
779
+ outputs.length * FRAME_DESCRIPTOR_SIZE,
780
+ allocations,
781
+ "invocation output descriptors",
782
+ );
783
+ outputs.forEach((out, idx) => {
784
+ const payload =
785
+ out.bytes instanceof Uint8Array
786
+ ? out.bytes
787
+ : new Uint8Array(out.bytes ?? []);
788
+ const outputTypeRef = out.typeRef ?? {};
789
+ const outputWireFormat = normalizeWireFormat(
790
+ outputTypeRef.wireFormat ?? out.wireFormat,
791
+ );
792
+ let typeDescriptorIdx = FLOW_INVALID_INDEX;
793
+ let hasOutgoingPort = false;
794
+ for (let edgeIndex = 0; edgeIndex < this.edgeCount; edgeIndex += 1) {
795
+ const edge = this.getEdgeDescriptor(edgeIndex);
796
+ if (edge.fromNode !== nodeIndex || edge.fromPort !== out.portId) continue;
797
+ hasOutgoingPort = true;
798
+ if (!typeRefMatchesDescriptor(outputTypeRef, edge, outputWireFormat)) continue;
799
+ typeDescriptorIdx = edgeIndex;
800
+ break;
801
+ }
802
+ if (hasOutgoingPort && typeDescriptorIdx === FLOW_INVALID_INDEX) {
803
+ throw new Error(
804
+ `Output frame on port "${out.portId ?? ""}" does not match the compiled exact SDS identity.`,
805
+ );
806
+ }
807
+ const alignment = Number(
808
+ out.alignment ??
809
+ (outputWireFormat === "aligned-binary"
810
+ ? outputTypeRef.requiredAlignment
811
+ : 1) ??
812
+ 1,
813
+ );
814
+ if (!isPowerOfTwo(alignment)) {
815
+ throw new RangeError(
816
+ `Frame alignment ${alignment} must be a positive power of two.`,
817
+ );
818
+ }
819
+ if (
820
+ outputWireFormat === "aligned-binary" &&
821
+ Number(outputTypeRef.byteLength ?? 0) !== payload.length
822
+ ) {
823
+ throw new RangeError(
824
+ `Aligned frame byteLength ${outputTypeRef.byteLength ?? 0} does not match payload length ${payload.length}.`,
825
+ );
826
+ }
827
+ const ownershipName = normalizeOwnership(out.ownership);
828
+ const mutabilityName = normalizeMutability(out.mutability);
829
+ if (mutabilityName !== "immutable" && ownershipName !== "transferred") {
830
+ throw new Error("Mutable aligned frames require transferred ownership.");
831
+ }
832
+ writeFrameDescriptor(framesPtr + idx * FRAME_DESCRIPTOR_SIZE, {
833
+ ingressIndex: call("get_current_invocation_generation") >>> 0,
834
+ typeDescriptorIdx,
835
+ portIdPtr: out.portId ? allocCString(out.portId, allocations) : 0,
836
+ alignment,
837
+ offset:
838
+ payload.length > 0
839
+ ? allocAlignedBytes(payload, alignment, allocations)
840
+ : 0,
841
+ size: payload.length,
842
+ streamId: out.streamId ?? 0,
843
+ sequence: out.sequence ?? 0,
844
+ traceToken: BigInt(out.frameId ?? nextExternalFrameId++),
845
+ endOfStream: out.endOfStream === true,
846
+ occupied: true,
847
+ wireFormat: WireFormatCode[outputWireFormat],
848
+ ownership: OwnershipCode[ownershipName],
849
+ mutability: MutabilityCode[mutabilityName],
850
+ lifetime: 1,
851
+ });
852
+ });
853
+ }
854
+ const applied = call(
855
+ "apply_node_invocation_result",
856
+ nodeIndex,
857
+ handlerResult.statusCode ?? 0,
858
+ handlerResult.backlogRemaining ?? 0,
859
+ handlerResult.yielded ? 1 : 0,
860
+ framesPtr,
861
+ outputs.length,
862
+ ) | 0;
863
+ if (applied < 0) {
864
+ throw new Error(`Flow runtime rejected invocation outputs (${applied}).`);
865
+ }
866
+ } finally {
867
+ releaseAllocations(allocations);
868
+ call("complete_node_invocation", nodeIndex);
869
+ }
870
+ result.nodesInvoked++;
871
+ }
872
+ return result;
873
+ },
874
+ };
875
+
876
+ return host;
877
+ }