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,393 @@
|
|
|
1
|
+
// Isomorphic wasi-threads spawn host.
|
|
2
|
+
//
|
|
3
|
+
// A wasm32-wasip1-threads (isomorphic-pthreads) artifact imports
|
|
4
|
+
// `wasi.thread-spawn` and exports `wasi_thread_start`. When the guest calls
|
|
5
|
+
// pthread_create it invokes `wasi.thread-spawn(startArg)`; the host must run a
|
|
6
|
+
// NEW OS thread that instantiates the SAME module over the SAME shared memory
|
|
7
|
+
// and calls `wasi_thread_start(tid, startArg)`. This module provides that host
|
|
8
|
+
// in BOTH environments:
|
|
9
|
+
// - Node: a `node:worker_threads` Worker (src/host/wasiThreadWorker.mjs),
|
|
10
|
+
// created lazily per spawn.
|
|
11
|
+
// - Browser: a WARM POOL of classic Blob-URL Workers (inlined below), started
|
|
12
|
+
// and confirmed ready during host creation, then dispatched to per spawn.
|
|
13
|
+
// Thread join/exit synchronization is done by the guest over shared-memory
|
|
14
|
+
// atomics (memory.atomic.wait/notify); the host only needs to start the thread.
|
|
15
|
+
//
|
|
16
|
+
// Why the browser needs a warm pool (correction of the earlier C6-era note):
|
|
17
|
+
// - Nested Workers created under COOP/COEP DO share a single imported
|
|
18
|
+
// WebAssembly.Memory by reference — a nested worker's atomic writes ARE
|
|
19
|
+
// visible to the joining thread. Shared memory was never the problem.
|
|
20
|
+
// (Proven headless + headed: nested-sab-microtest2/3/4.)
|
|
21
|
+
// - The deadlock was STARTUP timing, not memory. The guest runs synchronous
|
|
22
|
+
// WASM from pthread_create straight through pthread_join (memory.atomic.wait)
|
|
23
|
+
// WITHOUT ever yielding this thread's event loop. A Worker created LAZILY at
|
|
24
|
+
// pthread_create time needs the parent's event loop to run its startup, but
|
|
25
|
+
// the parent is already blocked in the join — so the lazily-spawned worker
|
|
26
|
+
// never starts and the join blocks forever.
|
|
27
|
+
// - Fix: PRE-START the workers here (while this thread's event loop is still
|
|
28
|
+
// free), confirm each is ready, and only postMessage work to an
|
|
29
|
+
// already-running worker at spawn time. A message posted to a live worker is
|
|
30
|
+
// delivered even while this thread is blocked in the synchronous join, so
|
|
31
|
+
// the pooled worker runs the guest thread and notifies the join. (Proven.)
|
|
32
|
+
//
|
|
33
|
+
// See docs/isomorphic-pthreads.md and docs/browser-wasmedge-isomorphic.md.
|
|
34
|
+
|
|
35
|
+
const IS_NODE =
|
|
36
|
+
typeof process !== "undefined" &&
|
|
37
|
+
!!process.release &&
|
|
38
|
+
process.release.name === "node";
|
|
39
|
+
|
|
40
|
+
const BROWSER_WORKER_URL = new URL(
|
|
41
|
+
"./wasiThreadBrowserWorker.mjs",
|
|
42
|
+
import.meta.url,
|
|
43
|
+
);
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Does the compiled module require the wasi-threads host (i.e. does it import
|
|
47
|
+
* `wasi.thread-spawn`)? Single-thread artifacts do not, so the host is only
|
|
48
|
+
* wired up for genuinely-threaded modules.
|
|
49
|
+
*/
|
|
50
|
+
export function isWasiThreadsModule(wasmModule) {
|
|
51
|
+
return WebAssembly.Module.imports(wasmModule).some(
|
|
52
|
+
(entry) => entry.module === "wasi" && entry.name === "thread-spawn",
|
|
53
|
+
);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// How long to wait for a pooled worker to confirm readiness before giving up and
|
|
57
|
+
// disabling browser threading entirely. Warm-pool startup is a handful of
|
|
58
|
+
// postMessage round-trips + one instantiation each; on a genuinely cross-origin
|
|
59
|
+
// isolated context that completes in well under a second. This deadline is kept
|
|
60
|
+
// SHORT on purpose: when arming is contended or a worker never confirms, the
|
|
61
|
+
// guest must commit to its proven sequential path FAST (threadSpawn -> -1) rather
|
|
62
|
+
// than leave the caller's compute watchdog to absorb a multi-second stall. Arming
|
|
63
|
+
// also short-circuits the instant ANY worker reports not-ready (see armBrowserPool),
|
|
64
|
+
// so the honest bound on a failed arming decision is one worker's first turn, not
|
|
65
|
+
// this whole window.
|
|
66
|
+
const BROWSER_POOL_PROBE_TIMEOUT_MS = 1500;
|
|
67
|
+
|
|
68
|
+
// Arm the browser warm pool: probe every created worker and resolve a single
|
|
69
|
+
// all-or-nothing decision. Resolves true ONLY when every worker confirms
|
|
70
|
+
// {t:"ready", ok:true}; resolves false the instant ANY worker reports not-ready,
|
|
71
|
+
// errors, or misses the probe deadline — a committed, fast sequential fallback,
|
|
72
|
+
// never a wait for the slowest loser. The per-worker onmessage handler installed
|
|
73
|
+
// here is PERSISTENT: after arming it keeps dispatching {t:"exit"} (idle return)
|
|
74
|
+
// and {t:"error"} (guest fault surfacing) for the life of the pool.
|
|
75
|
+
function armBrowserPool(
|
|
76
|
+
created,
|
|
77
|
+
{ wasmModule, memory, hostcallChannel, timeoutMs, onExit },
|
|
78
|
+
) {
|
|
79
|
+
return new Promise((resolve) => {
|
|
80
|
+
let remaining = created.length;
|
|
81
|
+
let settled = false;
|
|
82
|
+
const timers = [];
|
|
83
|
+
const finish = (ok) => {
|
|
84
|
+
if (settled) {
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
settled = true;
|
|
88
|
+
for (const timer of timers) {
|
|
89
|
+
clearTimeout(timer);
|
|
90
|
+
}
|
|
91
|
+
resolve(ok);
|
|
92
|
+
};
|
|
93
|
+
for (const worker of created) {
|
|
94
|
+
const timer = setTimeout(() => finish(false), timeoutMs);
|
|
95
|
+
timers.push(timer);
|
|
96
|
+
worker.onmessage = (event) => {
|
|
97
|
+
const message = event.data || {};
|
|
98
|
+
if (message.t === "ready") {
|
|
99
|
+
clearTimeout(timer);
|
|
100
|
+
if (message.ok === true) {
|
|
101
|
+
remaining -= 1;
|
|
102
|
+
if (remaining === 0) {
|
|
103
|
+
finish(true);
|
|
104
|
+
}
|
|
105
|
+
} else {
|
|
106
|
+
// One worker that cannot instantiate the module over the shared
|
|
107
|
+
// memory disables the whole pool — decide NOW, do not wait out the
|
|
108
|
+
// rest of the probes.
|
|
109
|
+
finish(false);
|
|
110
|
+
}
|
|
111
|
+
} else if (message.t === "exit") {
|
|
112
|
+
onExit(worker, message.tid);
|
|
113
|
+
} else if (message.t === "error") {
|
|
114
|
+
// eslint-disable-next-line no-console
|
|
115
|
+
console.error(
|
|
116
|
+
"[wasi-thread] pooled worker guest error:",
|
|
117
|
+
message.error,
|
|
118
|
+
);
|
|
119
|
+
}
|
|
120
|
+
};
|
|
121
|
+
worker.onerror = (error) => {
|
|
122
|
+
clearTimeout(timer);
|
|
123
|
+
// eslint-disable-next-line no-console
|
|
124
|
+
console.error(
|
|
125
|
+
"[wasi-thread] pooled worker error:",
|
|
126
|
+
error?.message ?? error,
|
|
127
|
+
);
|
|
128
|
+
finish(false);
|
|
129
|
+
};
|
|
130
|
+
worker.postMessage({
|
|
131
|
+
t: "probe",
|
|
132
|
+
wasmModule,
|
|
133
|
+
memory,
|
|
134
|
+
hostcallChannel: hostcallChannel ?? null,
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
function isSharedMemoryBacked(memory) {
|
|
141
|
+
return (
|
|
142
|
+
typeof SharedArrayBuffer === "function" &&
|
|
143
|
+
!!memory &&
|
|
144
|
+
memory.buffer instanceof SharedArrayBuffer
|
|
145
|
+
);
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
function detectHardwareConcurrency() {
|
|
149
|
+
if (
|
|
150
|
+
typeof navigator !== "undefined" &&
|
|
151
|
+
Number.isFinite(navigator.hardwareConcurrency)
|
|
152
|
+
) {
|
|
153
|
+
return navigator.hardwareConcurrency;
|
|
154
|
+
}
|
|
155
|
+
if (
|
|
156
|
+
typeof self !== "undefined" &&
|
|
157
|
+
self.navigator &&
|
|
158
|
+
Number.isFinite(self.navigator.hardwareConcurrency)
|
|
159
|
+
) {
|
|
160
|
+
return self.navigator.hardwareConcurrency;
|
|
161
|
+
}
|
|
162
|
+
return 1;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
/**
|
|
166
|
+
* Create the `wasi.thread-spawn` host for a wasi-threads module. Returns the
|
|
167
|
+
* import function plus liveness/cleanup helpers.
|
|
168
|
+
*
|
|
169
|
+
* @param {Object} options
|
|
170
|
+
* @param {WebAssembly.Module} options.wasmModule compiled module the workers re-instantiate.
|
|
171
|
+
* @param {WebAssembly.Memory} options.memory shared imported memory.
|
|
172
|
+
* @param {number} [options.requestedThreads] upper bound on how many guest
|
|
173
|
+
* threads the module will ask for (browser warm-pool sizing). Defaults to the
|
|
174
|
+
* host's hardware concurrency.
|
|
175
|
+
* @param {object} [options.hostcallChannel] request-isolated channel owned by
|
|
176
|
+
* the controlling host. Required when pthread workers import the generic
|
|
177
|
+
* module-host ABI.
|
|
178
|
+
* @param {boolean} [options.requiresHostcalls] whether worker instances import
|
|
179
|
+
* the generic module-host ABI.
|
|
180
|
+
* @param {boolean} [options.enableBrowserThreads] explicit successful host
|
|
181
|
+
* capability negotiation for an owning cross-origin-isolated worker harness.
|
|
182
|
+
* @returns {Promise<{ threadSpawn: Function, activeThreadCount: () => number, spawnCount: () => number, distinctOsThreadCount: () => number, terminateAll: () => Promise<void> }>}
|
|
183
|
+
*/
|
|
184
|
+
export async function createWasiThreadSpawn({
|
|
185
|
+
wasmModule,
|
|
186
|
+
memory,
|
|
187
|
+
requestedThreads,
|
|
188
|
+
hostcallChannel,
|
|
189
|
+
requiresHostcalls = false,
|
|
190
|
+
enableBrowserThreads,
|
|
191
|
+
} = {}) {
|
|
192
|
+
let nextTid = 0;
|
|
193
|
+
let spawnCount = 0;
|
|
194
|
+
if (requiresHostcalls && !hostcallChannel) {
|
|
195
|
+
return {
|
|
196
|
+
threadSpawn: () => -1,
|
|
197
|
+
activeThreadCount: () => 0,
|
|
198
|
+
spawnCount: () => 0,
|
|
199
|
+
distinctOsThreadCount: () => 0,
|
|
200
|
+
async terminateAll() {},
|
|
201
|
+
};
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
if (IS_NODE) {
|
|
205
|
+
// NODE: lazy per-spawn worker_threads. Node workers start on their own OS
|
|
206
|
+
// thread independently of the parent's event loop, so lazy creation at
|
|
207
|
+
// pthread_create time is fine here — there is no startup-vs-join deadlock.
|
|
208
|
+
const workers = new Set();
|
|
209
|
+
const osThreadIds = new Set();
|
|
210
|
+
const workerThreads = await import("node:worker_threads");
|
|
211
|
+
const NodeWorker = workerThreads.Worker;
|
|
212
|
+
const nodeWorkerUrl = new URL("./wasiThreadWorker.mjs", import.meta.url);
|
|
213
|
+
|
|
214
|
+
const threadSpawn = (startArg) => {
|
|
215
|
+
const tid = (nextTid += 1);
|
|
216
|
+
try {
|
|
217
|
+
const worker = new NodeWorker(nodeWorkerUrl, {
|
|
218
|
+
workerData: {
|
|
219
|
+
wasmModule,
|
|
220
|
+
memory,
|
|
221
|
+
tid,
|
|
222
|
+
startArg,
|
|
223
|
+
hostcallChannel: hostcallChannel ?? null,
|
|
224
|
+
},
|
|
225
|
+
});
|
|
226
|
+
// Node exposes the OS-thread id per Worker — distinct ids are direct
|
|
227
|
+
// evidence that pthread_create ran real concurrent threads.
|
|
228
|
+
if (typeof worker.threadId === "number") {
|
|
229
|
+
osThreadIds.add(worker.threadId);
|
|
230
|
+
}
|
|
231
|
+
worker.on("error", (error) => {
|
|
232
|
+
// A worker crash cannot be surfaced to the guest synchronously; log it
|
|
233
|
+
// so a hung pthread_join is diagnosable rather than silent.
|
|
234
|
+
// eslint-disable-next-line no-console
|
|
235
|
+
console.error("[wasi-thread] worker error:", error);
|
|
236
|
+
});
|
|
237
|
+
worker.once("exit", () => workers.delete(worker));
|
|
238
|
+
workers.add(worker);
|
|
239
|
+
spawnCount += 1;
|
|
240
|
+
return tid;
|
|
241
|
+
} catch {
|
|
242
|
+
// Signal spawn failure to the guest: wasi.thread-spawn returns a
|
|
243
|
+
// negative value, pthread_create returns EAGAIN, and the module's
|
|
244
|
+
// sequential fallback runs the stripe inline. Never abort.
|
|
245
|
+
return -1;
|
|
246
|
+
}
|
|
247
|
+
};
|
|
248
|
+
|
|
249
|
+
return {
|
|
250
|
+
threadSpawn,
|
|
251
|
+
activeThreadCount: () => workers.size,
|
|
252
|
+
spawnCount: () => spawnCount,
|
|
253
|
+
distinctOsThreadCount: () => osThreadIds.size,
|
|
254
|
+
async terminateAll() {
|
|
255
|
+
for (const worker of workers) {
|
|
256
|
+
try {
|
|
257
|
+
await worker.terminate?.();
|
|
258
|
+
} catch {
|
|
259
|
+
// best effort
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
workers.clear();
|
|
263
|
+
},
|
|
264
|
+
};
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
// BROWSER: warm pool. A guest thread needs a Worker that shares the SAME
|
|
268
|
+
// SharedArrayBuffer-backed memory; nested workers DO share it by reference.
|
|
269
|
+
// The only hazard is lazy startup during the guest's synchronous, no-yield
|
|
270
|
+
// pthread_create->pthread_join window, so we pre-start the pool here and only
|
|
271
|
+
// ever dispatch to an already-running worker.
|
|
272
|
+
const idleWorkers = [];
|
|
273
|
+
const busyByTid = new Map();
|
|
274
|
+
const poolWorkers = [];
|
|
275
|
+
// Threading stays disabled (threadSpawn returns -1 -> guest runs inline) unless
|
|
276
|
+
// the entire pool comes up green. Any probe failure/timeout disables it.
|
|
277
|
+
let poolDisabled = true;
|
|
278
|
+
|
|
279
|
+
const browserThreadsEnabled =
|
|
280
|
+
enableBrowserThreads ??
|
|
281
|
+
(globalThis.__SDM_ENABLE_BROWSER_WASI_THREADS__ === true);
|
|
282
|
+
const armed =
|
|
283
|
+
browserThreadsEnabled === true &&
|
|
284
|
+
globalThis.crossOriginIsolated === true &&
|
|
285
|
+
isSharedMemoryBacked(memory);
|
|
286
|
+
|
|
287
|
+
const hardwareConcurrency = detectHardwareConcurrency();
|
|
288
|
+
const requested = Number.isFinite(requestedThreads)
|
|
289
|
+
? Math.floor(requestedThreads)
|
|
290
|
+
: hardwareConcurrency;
|
|
291
|
+
// N = min(hardwareConcurrency - 1, requested). The main compute thread is one
|
|
292
|
+
// core; the pool provides the rest. Clamped at >= 0 (a 1-core host gets no
|
|
293
|
+
// pool and runs the proven sequential path).
|
|
294
|
+
const poolSize = armed
|
|
295
|
+
? Math.max(0, Math.min(Math.floor(hardwareConcurrency) - 1, requested))
|
|
296
|
+
: 0;
|
|
297
|
+
|
|
298
|
+
const returnWorkerToIdle = (worker, tid) => {
|
|
299
|
+
if (tid !== undefined && tid !== null) {
|
|
300
|
+
busyByTid.delete(tid);
|
|
301
|
+
}
|
|
302
|
+
if (
|
|
303
|
+
!poolDisabled &&
|
|
304
|
+
poolWorkers.includes(worker) &&
|
|
305
|
+
!idleWorkers.includes(worker)
|
|
306
|
+
) {
|
|
307
|
+
idleWorkers.push(worker);
|
|
308
|
+
}
|
|
309
|
+
};
|
|
310
|
+
|
|
311
|
+
if (poolSize > 0) {
|
|
312
|
+
const created = [];
|
|
313
|
+
for (let i = 0; i < poolSize; i += 1) {
|
|
314
|
+
created.push(new Worker(BROWSER_WORKER_URL, { type: "module" }));
|
|
315
|
+
}
|
|
316
|
+
const armed = await armBrowserPool(created, {
|
|
317
|
+
wasmModule,
|
|
318
|
+
memory,
|
|
319
|
+
hostcallChannel,
|
|
320
|
+
timeoutMs: BROWSER_POOL_PROBE_TIMEOUT_MS,
|
|
321
|
+
onExit: returnWorkerToIdle,
|
|
322
|
+
});
|
|
323
|
+
if (armed) {
|
|
324
|
+
poolDisabled = false;
|
|
325
|
+
for (const worker of created) {
|
|
326
|
+
poolWorkers.push(worker);
|
|
327
|
+
idleWorkers.push(worker);
|
|
328
|
+
}
|
|
329
|
+
} else {
|
|
330
|
+
// Any failure disables browser threading entirely: threadSpawn returns -1,
|
|
331
|
+
// the guest's pthread_create returns EAGAIN, and the module runs its whole
|
|
332
|
+
// grid inline (correct, deterministic, non-hanging). Every created worker
|
|
333
|
+
// is torn down — including ones that DID confirm ready — so no orphaned
|
|
334
|
+
// nested worker lingers to contend with the sequential retry's pool.
|
|
335
|
+
for (const worker of created) {
|
|
336
|
+
try {
|
|
337
|
+
worker.terminate();
|
|
338
|
+
} catch {
|
|
339
|
+
// best effort
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
const threadSpawn = (startArg) => {
|
|
346
|
+
if (poolDisabled) {
|
|
347
|
+
return -1;
|
|
348
|
+
}
|
|
349
|
+
const worker = idleWorkers.pop();
|
|
350
|
+
if (!worker) {
|
|
351
|
+
// Pool exhausted (guest asked for more concurrent threads than the pool
|
|
352
|
+
// holds): decline this one so the guest runs the stripe inline. Correct
|
|
353
|
+
// and non-hanging; the already-dispatched threads still run in parallel.
|
|
354
|
+
return -1;
|
|
355
|
+
}
|
|
356
|
+
const tid = (nextTid += 1);
|
|
357
|
+
busyByTid.set(tid, worker);
|
|
358
|
+
try {
|
|
359
|
+
// Dispatch to a PRE-STARTED worker: its event loop is already live on its
|
|
360
|
+
// own thread, so this postMessage is delivered even while THIS thread then
|
|
361
|
+
// blocks in the guest's synchronous pthread_join (memory.atomic.wait).
|
|
362
|
+
worker.postMessage({ t: "run", tid, startArg });
|
|
363
|
+
} catch {
|
|
364
|
+
busyByTid.delete(tid);
|
|
365
|
+
idleWorkers.push(worker);
|
|
366
|
+
return -1;
|
|
367
|
+
}
|
|
368
|
+
spawnCount += 1;
|
|
369
|
+
return tid;
|
|
370
|
+
};
|
|
371
|
+
|
|
372
|
+
return {
|
|
373
|
+
threadSpawn,
|
|
374
|
+
activeThreadCount: () => busyByTid.size,
|
|
375
|
+
spawnCount: () => spawnCount,
|
|
376
|
+
// No OS-thread ids in the browser; the count of distinct pooled Worker
|
|
377
|
+
// threads is the honest analogue.
|
|
378
|
+
distinctOsThreadCount: () => poolWorkers.length,
|
|
379
|
+
async terminateAll() {
|
|
380
|
+
poolDisabled = true;
|
|
381
|
+
for (const worker of poolWorkers) {
|
|
382
|
+
try {
|
|
383
|
+
worker.terminate();
|
|
384
|
+
} catch {
|
|
385
|
+
// best effort
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
poolWorkers.length = 0;
|
|
389
|
+
idleWorkers.length = 0;
|
|
390
|
+
busyByTid.clear();
|
|
391
|
+
},
|
|
392
|
+
};
|
|
393
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
// Node worker_threads entry for a spawned wasi-threads guest thread.
|
|
2
|
+
//
|
|
3
|
+
// The wasi-threads contract: when the guest calls pthread_create it invokes the
|
|
4
|
+
// host `wasi.thread-spawn` import, which must run a NEW OS thread that
|
|
5
|
+
// instantiates the SAME module over the SAME shared linear memory and calls
|
|
6
|
+
// `wasi_thread_start(tid, startArg)`. This file is that OS thread (a Node
|
|
7
|
+
// worker). Thread lifecycle/join synchronization happens entirely over shared
|
|
8
|
+
// memory atomics (memory.atomic.wait/notify emitted by the guest) — no
|
|
9
|
+
// messages are needed for correctness.
|
|
10
|
+
|
|
11
|
+
import { workerData } from "node:worker_threads";
|
|
12
|
+
|
|
13
|
+
import { createWasiThreadWorkerRuntime } from "./wasiThreadWorkerRuntime.js";
|
|
14
|
+
|
|
15
|
+
const { wasmModule, memory, tid, startArg, hostcallChannel } = workerData;
|
|
16
|
+
const runtime = createWasiThreadWorkerRuntime({
|
|
17
|
+
wasmModule,
|
|
18
|
+
memory,
|
|
19
|
+
hostcallChannel,
|
|
20
|
+
});
|
|
21
|
+
const instance = runtime.instantiate();
|
|
22
|
+
|
|
23
|
+
try {
|
|
24
|
+
instance.exports.wasi_thread_start(tid, startArg);
|
|
25
|
+
} catch (error) {
|
|
26
|
+
// WASI proc_exit surfaces as WasiExitError; a clean thread return is normal.
|
|
27
|
+
if (!(error && error.name === "WasiExitError")) {
|
|
28
|
+
throw error;
|
|
29
|
+
}
|
|
30
|
+
} finally {
|
|
31
|
+
runtime.close();
|
|
32
|
+
}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import { createHostcallBridge, DEFAULT_HOSTCALL_IMPORT_MODULE } from "./abi.js";
|
|
2
|
+
import {
|
|
3
|
+
createSabHostcallBuffer,
|
|
4
|
+
createSabHostcallClientDispatch,
|
|
5
|
+
} from "./sabHostcallChannel.js";
|
|
6
|
+
import { createBrowserWasiShim } from "./wasiShim.js";
|
|
7
|
+
|
|
8
|
+
const THREAD_HOSTCALL_MESSAGE = "sdm.thread-hostcall";
|
|
9
|
+
|
|
10
|
+
function requiresHostcallBridge(wasmModule) {
|
|
11
|
+
return WebAssembly.Module.imports(wasmModule).some(
|
|
12
|
+
(entry) => entry.module === DEFAULT_HOSTCALL_IMPORT_MODULE,
|
|
13
|
+
);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
function createThreadHostcallDispatch(options) {
|
|
17
|
+
if (!options || typeof options !== "object") {
|
|
18
|
+
throw new Error(
|
|
19
|
+
"A threaded guest that imports space_data_module_host requires an owning hostcall channel.",
|
|
20
|
+
);
|
|
21
|
+
}
|
|
22
|
+
const channelName = String(options.channelName ?? "").trim();
|
|
23
|
+
const token = String(options.token ?? "").trim();
|
|
24
|
+
if (!channelName || !token) {
|
|
25
|
+
throw new Error("The owning thread-hostcall channel name and token are required.");
|
|
26
|
+
}
|
|
27
|
+
if (typeof BroadcastChannel !== "function") {
|
|
28
|
+
throw new Error("BroadcastChannel is required for nested pthread hostcalls.");
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const buffer = createSabHostcallBuffer({
|
|
32
|
+
maxResponseBytes: options.maxResponseBytes,
|
|
33
|
+
});
|
|
34
|
+
const channel = new BroadcastChannel(channelName);
|
|
35
|
+
let nextRequestId = 1;
|
|
36
|
+
const dispatch = createSabHostcallClientDispatch({
|
|
37
|
+
buffer,
|
|
38
|
+
timeoutMs: options.timeoutMs,
|
|
39
|
+
postRequest(request) {
|
|
40
|
+
channel.postMessage({
|
|
41
|
+
type: THREAD_HOSTCALL_MESSAGE,
|
|
42
|
+
token,
|
|
43
|
+
requestId: nextRequestId++,
|
|
44
|
+
buffer,
|
|
45
|
+
...request,
|
|
46
|
+
});
|
|
47
|
+
},
|
|
48
|
+
});
|
|
49
|
+
return {
|
|
50
|
+
dispatch,
|
|
51
|
+
close() {
|
|
52
|
+
channel.close();
|
|
53
|
+
},
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export function createWasiThreadWorkerRuntime({
|
|
58
|
+
wasmModule,
|
|
59
|
+
memory,
|
|
60
|
+
hostcallChannel,
|
|
61
|
+
} = {}) {
|
|
62
|
+
const wasi = createBrowserWasiShim({});
|
|
63
|
+
wasi.setMemory(memory);
|
|
64
|
+
let instance = null;
|
|
65
|
+
let hostcalls = null;
|
|
66
|
+
const imports = {
|
|
67
|
+
...wasi.imports,
|
|
68
|
+
env: { memory },
|
|
69
|
+
wasi: { "thread-spawn": () => -1 },
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
if (requiresHostcallBridge(wasmModule)) {
|
|
73
|
+
hostcalls = createThreadHostcallDispatch(hostcallChannel);
|
|
74
|
+
const bridge = createHostcallBridge({
|
|
75
|
+
dispatch: hostcalls.dispatch,
|
|
76
|
+
getMemory: () => instance?.exports?.memory ?? memory,
|
|
77
|
+
});
|
|
78
|
+
Object.assign(imports, bridge.imports);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
return {
|
|
82
|
+
instantiate() {
|
|
83
|
+
instance = new WebAssembly.Instance(wasmModule, imports);
|
|
84
|
+
wasi.setMemory(instance.exports.memory ?? memory);
|
|
85
|
+
return instance;
|
|
86
|
+
},
|
|
87
|
+
close() {
|
|
88
|
+
hostcalls?.close();
|
|
89
|
+
},
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
export const WASI_THREAD_HOSTCALL_MESSAGE = THREAD_HOSTCALL_MESSAGE;
|