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.
- package/README.md +117 -20
- package/bin/space-data-module.js +263 -0
- package/docs/.nojekyll +1 -0
- package/docs/AGENTS.md +34 -0
- package/docs/architecture.svg +141 -0
- package/docs/browser-wasmedge-isomorphic.md +179 -0
- package/docs/flatsql-streaming-standard.md +341 -0
- package/docs/gpu-module-abi.md +193 -0
- package/docs/index.html +125 -0
- package/docs/isomorphic-pthreads.md +188 -0
- package/docs/isomorphic-sdn-runtime-plan.md +167 -0
- package/docs/language-runtime-matrix.md +82 -0
- package/docs/manifest-structure.svg +114 -0
- package/docs/module-bundle-runtime-plan.md +19 -0
- package/docs/module-lifecycle.svg +70 -0
- package/docs/module-publication-standard.md +540 -0
- package/docs/node-red-default-node-parity.md +88 -0
- package/docs/protocol-installation.md +196 -0
- package/docs/secrets-capability.md +152 -0
- package/docs/styles.css +288 -0
- package/docs/testing-harness.md +408 -0
- package/docs/tri-runtime-parity.md +132 -0
- package/docs/wallet-callback.html +2 -0
- package/package.json +25 -6
- package/schemas/HttpRequestAbi.fbs +41 -0
- package/schemas/HttpResponseAbi.fbs +36 -0
- package/schemas/PluginManifest.fbs +2 -1
- package/src/AGENTS.md +1 -1
- package/src/app/codec.js +548 -0
- package/src/app/index.js +6 -0
- package/src/browser.js +5 -0
- package/src/bundle/constants.js +1 -0
- package/src/bundle/index.js +15 -0
- package/src/bundle/sigdomain.js +179 -0
- package/src/bundle/signing.js +767 -0
- package/src/bundle/wasm.js +3 -2
- package/src/capabilities.js +3 -0
- package/src/compat/index.js +7 -0
- package/src/compat/sdnLegacy.js +449 -0
- package/src/compiler/compileModule.js +556 -55
- package/src/compiler/flatcSupport.js +41 -27
- package/src/compiler/index.d.ts +2 -0
- package/src/compiler/index.js +18 -0
- package/src/compiler/invokeGlue.js +1212 -183
- package/src/compiler/pthreadArtifactGuard.js +910 -0
- package/src/compiler/sdnShimGenerator.js +323 -0
- package/src/compiler/wasiThreadsToolchain.js +150 -0
- package/src/compliance/index.js +11 -1
- package/src/compliance/legacyWildcardPorts.js +228 -0
- package/src/compliance/pluginCompliance.js +1000 -96
- package/src/field-stream/index.d.ts +31 -0
- package/src/field-stream/index.js +119 -0
- package/src/flow/dependencyStreamBridge.js +234 -0
- package/src/flow/flatsqlLinkShim.js +304 -0
- package/src/flow/flowCodec.js +107 -0
- package/src/flow/flowCompiler.js +2900 -0
- package/src/flow/flowRuntimeHost.js +877 -0
- package/src/flow/index.d.ts +117 -0
- package/src/flow/index.js +31 -0
- package/src/flow/isomorphicFlowHost.js +384 -0
- package/src/flow/jsFlowRuntime.js +275 -0
- package/src/flow/normalize.js +294 -0
- package/src/flow/runtime-src/flow_runtime.cpp +1699 -0
- package/src/flow/vendor/sdn-flow/MethodRegistry.js +400 -0
- package/src/flow/vendor/sdn-flow/constants.js +39 -0
- package/src/flow/vendor/sdn-flow/index.js +29 -0
- package/src/flow/vendor/sdn-flow/normalize.js +506 -0
- package/src/flow/vendor/sdn-flow/wasmCompatibility.js +189 -0
- package/src/generated/http/cpp/HttpRequestAbi_generated.h +285 -0
- package/src/generated/http/cpp/HttpResponseAbi_generated.h +192 -0
- package/src/generated/http/sdn/http/http-header.js +53 -0
- package/src/generated/http/sdn/http/http-header.ts +67 -0
- package/src/generated/http/sdn/http/http-request.js +132 -0
- package/src/generated/http/sdn/http/http-request.ts +179 -0
- package/src/generated/http/sdn/http/http-response.js +144 -0
- package/src/generated/http/sdn/http/http-response.ts +168 -0
- package/src/generated/http/sdn/http.js +11 -0
- package/src/generated/http/sdn/http.ts +4 -0
- package/src/generated/orbpro/flow/backpressure-policy.d.ts +12 -0
- package/src/generated/orbpro/flow/backpressure-policy.d.ts.map +1 -0
- package/src/generated/orbpro/flow/backpressure-policy.js +17 -0
- package/src/generated/orbpro/flow/backpressure-policy.js.map +1 -0
- package/src/generated/orbpro/flow/backpressure-policy.ts +15 -0
- package/src/generated/orbpro/flow/flow-bundle-manifest.d.ts +142 -0
- package/src/generated/orbpro/flow/flow-bundle-manifest.d.ts.map +1 -0
- package/src/generated/orbpro/flow/flow-bundle-manifest.js +304 -0
- package/src/generated/orbpro/flow/flow-bundle-manifest.js.map +1 -0
- package/src/generated/orbpro/flow/flow-bundle-manifest.ts +399 -0
- package/src/generated/orbpro/flow/flow-edge.d.ts +113 -0
- package/src/generated/orbpro/flow/flow-edge.d.ts.map +1 -0
- package/src/generated/orbpro/flow/flow-edge.js +221 -0
- package/src/generated/orbpro/flow/flow-edge.js.map +1 -0
- package/src/generated/orbpro/flow/flow-edge.ts +292 -0
- package/src/generated/orbpro/flow/flow-node.d.ts +80 -0
- package/src/generated/orbpro/flow/flow-node.d.ts.map +1 -0
- package/src/generated/orbpro/flow/flow-node.js +158 -0
- package/src/generated/orbpro/flow/flow-node.js.map +1 -0
- package/src/generated/orbpro/flow/flow-node.ts +202 -0
- package/src/generated/orbpro/flow/flow-program.d.ts +164 -0
- package/src/generated/orbpro/flow/flow-program.d.ts.map +1 -0
- package/src/generated/orbpro/flow/flow-program.js +350 -0
- package/src/generated/orbpro/flow/flow-program.js.map +1 -0
- package/src/generated/orbpro/flow/flow-program.ts +477 -0
- package/src/generated/orbpro/flow/flow-trigger.d.ts +108 -0
- package/src/generated/orbpro/flow/flow-trigger.d.ts.map +1 -0
- package/src/generated/orbpro/flow/flow-trigger.js +207 -0
- package/src/generated/orbpro/flow/flow-trigger.js.map +1 -0
- package/src/generated/orbpro/flow/flow-trigger.ts +276 -0
- package/src/generated/orbpro/flow/node-kind.d.ts +13 -0
- package/src/generated/orbpro/flow/node-kind.d.ts.map +1 -0
- package/src/generated/orbpro/flow/node-kind.js +16 -0
- package/src/generated/orbpro/flow/node-kind.js.map +1 -0
- package/src/generated/orbpro/{invoke.ts → flow/node-kind.ts} +12 -2
- package/src/generated/orbpro/flow/plugin-version-binding.d.ts +52 -0
- package/src/generated/orbpro/flow/plugin-version-binding.d.ts.map +1 -0
- package/src/generated/orbpro/flow/plugin-version-binding.js +85 -0
- package/src/generated/orbpro/flow/plugin-version-binding.js.map +1 -0
- package/src/generated/orbpro/flow/plugin-version-binding.ts +121 -0
- package/src/generated/orbpro/flow/schema-hash-binding.d.ts +70 -0
- package/src/generated/orbpro/flow/schema-hash-binding.d.ts.map +1 -0
- package/src/generated/orbpro/flow/schema-hash-binding.js +143 -0
- package/src/generated/orbpro/flow/schema-hash-binding.js.map +1 -0
- package/src/generated/orbpro/flow/schema-hash-binding.ts +189 -0
- package/src/generated/orbpro/flow/trigger-binding.d.ts +71 -0
- package/src/generated/orbpro/flow/trigger-binding.d.ts.map +1 -0
- package/src/generated/orbpro/flow/trigger-binding.js +142 -0
- package/src/generated/orbpro/flow/trigger-binding.js.map +1 -0
- package/src/generated/orbpro/flow/trigger-binding.ts +181 -0
- package/src/generated/orbpro/flow/trigger-kind.d.ts +14 -0
- package/src/generated/orbpro/flow/trigger-kind.d.ts.map +1 -0
- package/src/generated/orbpro/flow/trigger-kind.js +17 -0
- package/src/generated/orbpro/flow/trigger-kind.js.map +1 -0
- package/src/generated/orbpro/flow/trigger-kind.ts +17 -0
- package/src/generated/orbpro/flow.d.ts +21 -0
- package/src/generated/orbpro/flow.d.ts.map +1 -0
- package/src/generated/orbpro/flow.js +23 -0
- package/src/generated/orbpro/flow.js.map +1 -0
- package/src/generated/orbpro/flow.ts +24 -0
- package/src/generated/orbpro/manifest/capability-kind.d.ts +2 -1
- package/src/generated/orbpro/manifest/capability-kind.js +1 -0
- package/src/generated/orbpro/manifest/capability-kind.ts +1 -0
- package/src/generated/orbpro/plugin/stream-invoke-request.d.ts +93 -0
- package/src/generated/orbpro/plugin/stream-invoke-request.js +160 -0
- package/src/generated/orbpro/plugin/stream-invoke-request.ts +211 -0
- package/src/generated/orbpro/plugin/stream-invoke-response.d.ts +99 -0
- package/src/generated/orbpro/plugin/stream-invoke-response.js +175 -0
- package/src/generated/orbpro/plugin/stream-invoke-response.ts +226 -0
- package/src/generated/orbpro/plugin.js +8 -0
- package/src/generated/orbpro/stream.d.ts +12 -0
- package/src/generated/orbpro/stream.js +14 -0
- package/src/generated/orbpro/stream.ts +15 -0
- package/src/generated/spacedatastandards/plg/EntryFunction.d.ts +52 -0
- package/src/generated/spacedatastandards/plg/EntryFunction.d.ts.map +1 -0
- package/src/generated/spacedatastandards/plg/EntryFunction.js +106 -0
- package/src/generated/spacedatastandards/plg/EntryFunction.ts +162 -0
- package/src/generated/spacedatastandards/plg/FlatBufferTypeRef.d.ts +90 -0
- package/src/generated/spacedatastandards/plg/FlatBufferTypeRef.d.ts.map +1 -0
- package/src/generated/spacedatastandards/plg/FlatBufferTypeRef.js +189 -0
- package/src/generated/spacedatastandards/plg/FlatBufferTypeRef.ts +270 -0
- package/src/generated/spacedatastandards/plg/PLG.d.ts +492 -0
- package/src/generated/spacedatastandards/plg/PLG.d.ts.map +1 -0
- package/src/generated/spacedatastandards/plg/PLG.js +1139 -0
- package/src/generated/spacedatastandards/plg/PLG.ts +1600 -0
- package/src/generated/spacedatastandards/plg/PLGAcceptedTypeSet.d.ts +63 -0
- package/src/generated/spacedatastandards/plg/PLGAcceptedTypeSet.d.ts.map +1 -0
- package/src/generated/spacedatastandards/plg/PLGAcceptedTypeSet.js +138 -0
- package/src/generated/spacedatastandards/plg/PLGAcceptedTypeSet.ts +189 -0
- package/src/generated/spacedatastandards/plg/PLGBuildArtifact.d.ts +41 -0
- package/src/generated/spacedatastandards/plg/PLGBuildArtifact.d.ts.map +1 -0
- package/src/generated/spacedatastandards/plg/PLGBuildArtifact.js +104 -0
- package/src/generated/spacedatastandards/plg/PLGBuildArtifact.ts +151 -0
- package/src/generated/spacedatastandards/plg/PLGFlowEdge.d.ts +68 -0
- package/src/generated/spacedatastandards/plg/PLGFlowEdge.d.ts.map +1 -0
- package/src/generated/spacedatastandards/plg/PLGFlowEdge.js +124 -0
- package/src/generated/spacedatastandards/plg/PLGFlowEdge.ts +184 -0
- package/src/generated/spacedatastandards/plg/PLGFlowEdgeContract.d.ts +58 -0
- package/src/generated/spacedatastandards/plg/PLGFlowEdgeContract.d.ts.map +1 -0
- package/src/generated/spacedatastandards/plg/PLGFlowEdgeContract.js +126 -0
- package/src/generated/spacedatastandards/plg/PLGFlowEdgeContract.ts +161 -0
- package/src/generated/spacedatastandards/plg/PLGFlowNode.d.ts +82 -0
- package/src/generated/spacedatastandards/plg/PLGFlowNode.d.ts.map +1 -0
- package/src/generated/spacedatastandards/plg/PLGFlowNode.js +164 -0
- package/src/generated/spacedatastandards/plg/PLGFlowNode.ts +244 -0
- package/src/generated/spacedatastandards/plg/PLGFlowTrigger.d.ts +55 -0
- package/src/generated/spacedatastandards/plg/PLGFlowTrigger.d.ts.map +1 -0
- package/src/generated/spacedatastandards/plg/PLGFlowTrigger.js +105 -0
- package/src/generated/spacedatastandards/plg/PLGFlowTrigger.ts +162 -0
- package/src/generated/spacedatastandards/plg/PLGFlowTriggerBinding.d.ts +42 -0
- package/src/generated/spacedatastandards/plg/PLGFlowTriggerBinding.d.ts.map +1 -0
- package/src/generated/spacedatastandards/plg/PLGFlowTriggerBinding.js +83 -0
- package/src/generated/spacedatastandards/plg/PLGFlowTriggerBinding.ts +127 -0
- package/src/generated/spacedatastandards/plg/PLGHostCapability.d.ts +36 -0
- package/src/generated/spacedatastandards/plg/PLGHostCapability.d.ts.map +1 -0
- package/src/generated/spacedatastandards/plg/PLGHostCapability.js +90 -0
- package/src/generated/spacedatastandards/plg/PLGHostCapability.ts +127 -0
- package/src/generated/spacedatastandards/plg/PLGMethodManifest.d.ts +53 -0
- package/src/generated/spacedatastandards/plg/PLGMethodManifest.d.ts.map +1 -0
- package/src/generated/spacedatastandards/plg/PLGMethodManifest.js +153 -0
- package/src/generated/spacedatastandards/plg/PLGMethodManifest.ts +210 -0
- package/src/generated/spacedatastandards/plg/PLGPortManifest.d.ts +70 -0
- package/src/generated/spacedatastandards/plg/PLGPortManifest.d.ts.map +1 -0
- package/src/generated/spacedatastandards/plg/PLGPortManifest.js +149 -0
- package/src/generated/spacedatastandards/plg/PLGPortManifest.ts +212 -0
- package/src/generated/spacedatastandards/plg/PLGProtocolSpec.d.ts +73 -0
- package/src/generated/spacedatastandards/plg/PLGProtocolSpec.d.ts.map +1 -0
- package/src/generated/spacedatastandards/plg/PLGProtocolSpec.js +199 -0
- package/src/generated/spacedatastandards/plg/PLGProtocolSpec.ts +292 -0
- package/src/generated/spacedatastandards/plg/PLGTimerSpec.d.ts +40 -0
- package/src/generated/spacedatastandards/plg/PLGTimerSpec.d.ts.map +1 -0
- package/src/generated/spacedatastandards/plg/PLGTimerSpec.js +103 -0
- package/src/generated/spacedatastandards/plg/PLGTimerSpec.ts +148 -0
- package/src/generated/spacedatastandards/plg/PluginCapability.d.ts +41 -0
- package/src/generated/spacedatastandards/plg/PluginCapability.d.ts.map +1 -0
- package/src/generated/spacedatastandards/plg/PluginCapability.js +82 -0
- package/src/generated/spacedatastandards/plg/{plugin-capability.ts → PluginCapability.ts} +55 -18
- package/src/generated/spacedatastandards/plg/PluginDependency.d.ts +42 -0
- package/src/generated/spacedatastandards/plg/PluginDependency.d.ts.map +1 -0
- package/src/generated/spacedatastandards/plg/PluginDependency.js +80 -0
- package/src/generated/spacedatastandards/plg/PluginDependency.ts +124 -0
- package/src/generated/spacedatastandards/plg/TAB.d.ts +85 -0
- package/src/generated/spacedatastandards/plg/TAB.d.ts.map +1 -0
- package/src/generated/spacedatastandards/plg/TAB.js +173 -0
- package/src/generated/spacedatastandards/plg/TAB.ts +228 -0
- package/src/generated/spacedatastandards/plg/bufferMutability.d.ts +18 -0
- package/src/generated/spacedatastandards/plg/bufferMutability.d.ts.map +1 -0
- package/src/generated/spacedatastandards/plg/bufferMutability.js +20 -0
- package/src/generated/spacedatastandards/plg/bufferMutability.ts +23 -0
- package/src/generated/spacedatastandards/plg/bufferOwnership.d.ts +18 -0
- package/src/generated/spacedatastandards/plg/bufferOwnership.d.ts.map +1 -0
- package/src/generated/spacedatastandards/plg/bufferOwnership.js +20 -0
- package/src/generated/spacedatastandards/plg/bufferOwnership.ts +23 -0
- package/src/generated/spacedatastandards/plg/drainBehavior.d.ts +20 -0
- package/src/generated/spacedatastandards/plg/drainBehavior.d.ts.map +1 -0
- package/src/generated/spacedatastandards/plg/drainBehavior.js +22 -0
- package/src/generated/spacedatastandards/plg/drainBehavior.ts +25 -0
- package/src/generated/spacedatastandards/plg/flowEdgeRoutePolicy.d.ts +10 -0
- package/src/generated/spacedatastandards/plg/flowEdgeRoutePolicy.d.ts.map +1 -0
- package/src/generated/spacedatastandards/plg/flowEdgeRoutePolicy.js +12 -0
- package/src/generated/spacedatastandards/plg/flowEdgeRoutePolicy.ts +13 -0
- package/src/generated/spacedatastandards/plg/hostCapabilityKind.d.ts +51 -0
- package/src/generated/spacedatastandards/plg/hostCapabilityKind.d.ts.map +1 -0
- package/src/generated/spacedatastandards/plg/hostCapabilityKind.js +53 -0
- package/src/generated/spacedatastandards/plg/hostCapabilityKind.ts +55 -0
- package/src/generated/spacedatastandards/plg/invokeSurfaceKind.d.ts +15 -0
- package/src/generated/spacedatastandards/plg/invokeSurfaceKind.d.ts.map +1 -0
- package/src/generated/spacedatastandards/plg/invokeSurfaceKind.js +17 -0
- package/src/generated/spacedatastandards/plg/invokeSurfaceKind.ts +19 -0
- package/src/generated/spacedatastandards/plg/main.d.ts +29 -0
- package/src/generated/spacedatastandards/plg/main.d.ts.map +1 -0
- package/src/generated/spacedatastandards/plg/main.js +30 -0
- package/src/generated/spacedatastandards/plg/main.ts +32 -0
- package/src/generated/spacedatastandards/plg/payloadWireFormat.d.ts +17 -0
- package/src/generated/spacedatastandards/plg/payloadWireFormat.d.ts.map +1 -0
- package/src/generated/spacedatastandards/plg/payloadWireFormat.js +19 -0
- package/src/generated/spacedatastandards/plg/payloadWireFormat.ts +21 -0
- package/src/generated/spacedatastandards/plg/pluginCategory.d.ts +82 -0
- package/src/generated/spacedatastandards/plg/pluginCategory.d.ts.map +1 -0
- package/src/generated/spacedatastandards/plg/pluginCategory.js +84 -0
- package/src/generated/spacedatastandards/plg/pluginCategory.ts +103 -0
- package/src/generated/spacedatastandards/plg/publicationState.d.ts +18 -0
- package/src/generated/spacedatastandards/plg/publicationState.d.ts.map +1 -0
- package/src/generated/spacedatastandards/plg/publicationState.js +20 -0
- package/src/generated/spacedatastandards/plg/purchaseTier.d.ts +18 -0
- package/src/generated/spacedatastandards/plg/purchaseTier.d.ts.map +1 -0
- package/src/generated/spacedatastandards/plg/purchaseTier.js +20 -0
- package/src/host/AGENTS.md +2 -2
- package/src/host/abi.js +53 -66
- package/src/host/browserHost.js +355 -8
- package/src/host/cpp/keyslotClient.hpp +231 -0
- package/src/host/cpp/secretsClient.hpp +583 -0
- package/src/host/hostcallWire.js +183 -0
- package/src/host/index.js +2 -0
- package/src/host/isomorphicLoader.js +44 -7
- package/src/host/nodeHost.js +227 -8
- package/src/host/sabHostcallChannel.js +206 -0
- package/src/host/timerDriver.js +203 -0
- package/src/host/wasiShim.js +41 -1
- package/src/host/wasiThreadBrowserWorker.mjs +48 -0
- package/src/host/wasiThreadHost.js +393 -0
- package/src/host/wasiThreadWorker.mjs +32 -0
- package/src/host/wasiThreadWorkerRuntime.js +93 -0
- package/src/http/index.js +339 -0
- package/src/index.d.ts +716 -10
- package/src/index.js +4 -0
- package/src/invoke/codec.js +1202 -128
- package/src/invoke/index.js +5 -1
- package/src/licensing/index.d.ts +2 -0
- package/src/licensing/index.js +2 -0
- package/src/licensing/records.js +287 -8
- package/src/manifest/codec.js +62 -14
- package/src/manifest/index.js +2 -0
- package/src/manifest/legacyToPlg.js +164 -25
- package/src/manifest/normalize.js +1 -0
- package/src/manifest/plgCodec.js +1303 -62
- package/src/manifest/typeRefs.js +162 -24
- package/src/runtime/compiledRuntimeAbi.js +47 -0
- package/src/runtime/compiledRuntimeAbi.json +33 -0
- package/src/runtime/index.d.ts +32 -0
- package/src/runtime/index.js +1 -0
- package/src/runtime-host/index.js +3 -0
- package/src/runtime-host/methodRegistry.js +55 -0
- package/src/standards/index.js +200 -56
- package/src/standards/sharedCatalog.js +16 -0
- package/src/testing/browserModuleHarness.js +604 -31
- package/src/testing/docker/wasmedge-parity.Dockerfile +39 -0
- package/src/testing/index.d.ts +151 -0
- package/src/testing/index.js +21 -0
- package/src/testing/native/wasmedge_emscripten_pthread_runner.c +25 -1
- package/src/testing/parityBrowserRunner.js +138 -0
- package/src/testing/parityHarness.js +616 -0
- package/src/testing/parityLanes.js +537 -0
- package/src/testing/processInvoke.js +29 -21
- package/src/testing/streamInvokeCodec.js +10 -175
- package/src/testing/wasmedgePin.json +6 -0
- package/src/testing/workerModuleHarness.js +242 -0
- package/src/testing/workerModuleHarnessWorker.js +176 -0
- package/src/transport/index.js +3 -0
- package/src/transport/pki.js +299 -11
- package/src/transport/records.js +16 -7
- package/src/utils/ecdsaDer.js +106 -0
- package/src/utils/wasmCrypto.js +0 -43
- package/templates/gpu-module/README.md +48 -0
- package/templates/gpu-module/include/space_data_gpu_abi.h +122 -0
- package/templates/gpu-module/manifest.json +84 -0
- package/schemas/PluginInvokeRequest.fbs +0 -18
- package/schemas/PluginInvokeResponse.fbs +0 -30
- package/schemas/spacedatastandards/PLG.fbs +0 -191
- package/src/generated/orbpro/invoke/plugin-invoke-request.d.ts +0 -51
- package/src/generated/orbpro/invoke/plugin-invoke-request.d.ts.map +0 -1
- package/src/generated/orbpro/invoke/plugin-invoke-request.js +0 -131
- package/src/generated/orbpro/invoke/plugin-invoke-request.js.map +0 -1
- package/src/generated/orbpro/invoke/plugin-invoke-request.ts +0 -173
- package/src/generated/orbpro/invoke/plugin-invoke-response.d.ts +0 -76
- package/src/generated/orbpro/invoke/plugin-invoke-response.d.ts.map +0 -1
- package/src/generated/orbpro/invoke/plugin-invoke-response.js +0 -184
- package/src/generated/orbpro/invoke/plugin-invoke-response.js.map +0 -1
- package/src/generated/orbpro/invoke/plugin-invoke-response.ts +0 -243
- package/src/generated/orbpro/invoke.d.ts +0 -3
- package/src/generated/orbpro/invoke.js +0 -5
- package/src/generated/spacedatastandards/plg/entry-function.js +0 -86
- package/src/generated/spacedatastandards/plg/entry-function.ts +0 -119
- package/src/generated/spacedatastandards/plg/index.js +0 -16
- package/src/generated/spacedatastandards/plg/index.ts +0 -11
- package/src/generated/spacedatastandards/plg/plg.js +0 -657
- package/src/generated/spacedatastandards/plg/plg.ts +0 -924
- package/src/generated/spacedatastandards/plg/plugin-capability.js +0 -66
- package/src/generated/spacedatastandards/plg/plugin-category.js +0 -15
- package/src/generated/spacedatastandards/plg/plugin-category.ts +0 -53
- package/src/generated/spacedatastandards/plg/plugin-dependency.js +0 -63
- package/src/generated/spacedatastandards/plg/plugin-dependency.ts +0 -86
- package/src/generated/spacedatastandards/plg/publication-state.js +0 -9
- package/src/generated/spacedatastandards/plg/purchase-tier.js +0 -9
- /package/src/generated/spacedatastandards/plg/{publication-state.ts → publicationState.ts} +0 -0
- /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
|
+
}
|