@mysten-incubation/devstack 0.0.1 → 0.1.1
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 +8 -4
- package/dashboard-ui/assets/geist-cyrillic-ext-wght-normal-DjL33-gN.woff2 +0 -0
- package/dashboard-ui/assets/geist-cyrillic-wght-normal-BEAKL7Jp.woff2 +0 -0
- package/dashboard-ui/assets/geist-latin-ext-wght-normal-DC-KSUi6.woff2 +0 -0
- package/dashboard-ui/assets/geist-latin-wght-normal-BgDaEnEv.woff2 +0 -0
- package/dashboard-ui/assets/geist-mono-cyrillic-ext-wght-normal-I4S5GZfc.woff2 +0 -0
- package/dashboard-ui/assets/geist-mono-cyrillic-wght-normal-BmXc_FBt.woff2 +0 -0
- package/dashboard-ui/assets/geist-mono-latin-ext-wght-normal-DrnZ1wKl.woff2 +0 -0
- package/dashboard-ui/assets/geist-mono-latin-wght-normal-B_7UjwxQ.woff2 +0 -0
- package/dashboard-ui/assets/geist-mono-symbols2-wght-normal-GZpp1pK2.woff2 +0 -0
- package/dashboard-ui/assets/geist-mono-vietnamese-wght-normal-D8KDMBhC.woff2 +0 -0
- package/dashboard-ui/assets/geist-vietnamese-wght-normal-6IgcOCM7.woff2 +0 -0
- package/dashboard-ui/assets/index-Bmi1UtAg.js +1356 -0
- package/dashboard-ui/assets/index-D5EShVt4.js +3 -0
- package/dashboard-ui/assets/index-Deml9drg.css +1 -0
- package/dashboard-ui/index.html +13 -0
- package/dist/api/define-capabilities.d.mts +14 -3
- package/dist/api/define-capabilities.mjs +18 -1
- package/dist/api/define-capabilities.mjs.map +1 -1
- package/dist/api/define-devstack.d.mts +1 -1
- package/dist/api/define-devstack.mjs +6 -26
- package/dist/api/define-devstack.mjs.map +1 -1
- package/dist/api/define-plugin.d.mts +1 -0
- package/dist/api/define-plugin.mjs +2 -0
- package/dist/api/inference-network.d.mts +132 -0
- package/dist/api/inference-network.mjs +105 -16
- package/dist/api/inference-network.mjs.map +1 -1
- package/dist/api/plugin-errors.d.mts +7 -0
- package/dist/api/run-stack.d.mts +20 -9
- package/dist/api/run-stack.mjs +56 -29
- package/dist/api/run-stack.mjs.map +1 -1
- package/dist/build-integrations/playwright/config.d.mts +6 -4
- package/dist/build-integrations/playwright/config.mjs +5 -3
- package/dist/build-integrations/playwright/config.mjs.map +1 -1
- package/dist/build-integrations/playwright/errors.d.mts +1 -1
- package/dist/build-integrations/playwright/global-setup.d.mts +43 -17
- package/dist/build-integrations/playwright/global-setup.mjs +250 -13
- package/dist/build-integrations/playwright/global-setup.mjs.map +1 -1
- package/dist/build-integrations/playwright/index.d.mts +5 -3
- package/dist/build-integrations/playwright/index.mjs +4 -2
- package/dist/build-integrations/playwright/stack-context.d.mts +0 -1
- package/dist/build-integrations/playwright/stack-context.mjs +24 -63
- package/dist/build-integrations/playwright/stack-context.mjs.map +1 -1
- package/dist/build-integrations/playwright/wallet-context.d.mts +7 -10
- package/dist/build-integrations/playwright/wallet-context.mjs +8 -13
- package/dist/build-integrations/playwright/wallet-context.mjs.map +1 -1
- package/dist/build-integrations/runtime/cold-start-url.d.mts +5 -0
- package/dist/build-integrations/runtime/cold-start-url.mjs +4 -3
- package/dist/build-integrations/runtime/cold-start-url.mjs.map +1 -1
- package/dist/build-integrations/runtime/conventional-routes.d.mts +51 -0
- package/dist/build-integrations/runtime/conventional-routes.mjs +92 -0
- package/dist/build-integrations/runtime/conventional-routes.mjs.map +1 -0
- package/dist/build-integrations/runtime/discover.d.mts +38 -30
- package/dist/build-integrations/runtime/discover.mjs +73 -70
- package/dist/build-integrations/runtime/discover.mjs.map +1 -1
- package/dist/build-integrations/runtime/endpoint-registry.d.mts +3 -1
- package/dist/build-integrations/runtime/endpoint-registry.mjs +3 -1
- package/dist/build-integrations/runtime/endpoint-registry.mjs.map +1 -1
- package/dist/build-integrations/runtime/index.d.mts +7 -2
- package/dist/build-integrations/runtime/index.mjs +9 -2
- package/dist/build-integrations/runtime/manifest-types.d.mts +2 -0
- package/dist/build-integrations/runtime/manifest-types.mjs +3 -0
- package/dist/build-integrations/runtime/playwright-stack-context-slot.d.mts +29 -0
- package/dist/build-integrations/runtime/playwright-stack-context-slot.mjs +10 -0
- package/dist/build-integrations/runtime/playwright-stack-context-slot.mjs.map +1 -0
- package/dist/build-integrations/runtime/read-stack-context.d.mts +1 -1
- package/dist/build-integrations/runtime/read-stack-context.mjs +10 -4
- package/dist/build-integrations/runtime/read-stack-context.mjs.map +1 -1
- package/dist/build-integrations/runtime/resolve-discovery-env.d.mts +48 -0
- package/dist/build-integrations/runtime/resolve-discovery-env.mjs +42 -0
- package/dist/build-integrations/runtime/resolve-discovery-env.mjs.map +1 -0
- package/dist/build-integrations/runtime/stack-context.d.mts +1 -1
- package/dist/build-integrations/runtime/wallet-paths.mjs +2 -0
- package/dist/build-integrations/vite/index.d.mts +51 -0
- package/dist/build-integrations/vite/index.mjs +73 -0
- package/dist/build-integrations/vite/index.mjs.map +1 -0
- package/dist/build-integrations/vitest/env.d.mts +4 -3
- package/dist/build-integrations/vitest/env.mjs +6 -4
- package/dist/build-integrations/vitest/env.mjs.map +1 -1
- package/dist/build-integrations/vitest/errors.d.mts +25 -4
- package/dist/build-integrations/vitest/errors.mjs +15 -2
- package/dist/build-integrations/vitest/errors.mjs.map +1 -1
- package/dist/build-integrations/vitest/index.d.mts +2 -2
- package/dist/build-integrations/vitest/index.mjs +3 -3
- package/dist/build-integrations/vitest/setup.d.mts +4 -2
- package/dist/build-integrations/vitest/setup.mjs +2 -2
- package/dist/build-integrations/vitest/setup.mjs.map +1 -1
- package/dist/build-integrations/vitest/stack-context.d.mts +0 -1
- package/dist/build-integrations/vitest/stack-context.mjs +33 -13
- package/dist/build-integrations/vitest/stack-context.mjs.map +1 -1
- package/dist/cli/bail.mjs +23 -0
- package/dist/cli/bail.mjs.map +1 -0
- package/dist/{surfaces/cli/commands → cli}/doctor-probes.mjs +26 -16
- package/dist/cli/doctor-probes.mjs.map +1 -0
- package/dist/cli/main.d.mts +15 -1
- package/dist/cli/main.mjs +166 -482
- package/dist/cli/main.mjs.map +1 -1
- package/dist/cli/prune-direct.mjs +31 -201
- package/dist/cli/prune-direct.mjs.map +1 -1
- package/dist/cli/snapshot-reader.mjs +14 -11
- package/dist/cli/snapshot-reader.mjs.map +1 -1
- package/dist/cli/up-lifecycle.mjs +4 -1
- package/dist/cli/up-lifecycle.mjs.map +1 -1
- package/dist/cli/wirings/apply.mjs +95 -0
- package/dist/cli/wirings/apply.mjs.map +1 -0
- package/dist/cli/wirings/build-verb-layers.mjs +42 -0
- package/dist/cli/wirings/build-verb-layers.mjs.map +1 -0
- package/dist/cli/wirings/config-loader.mjs +69 -0
- package/dist/cli/wirings/config-loader.mjs.map +1 -0
- package/dist/cli/wirings/engine-command.mjs +30 -0
- package/dist/cli/wirings/engine-command.mjs.map +1 -0
- package/dist/cli/wirings/identity.mjs +72 -0
- package/dist/cli/wirings/identity.mjs.map +1 -0
- package/dist/cli/wirings/provide-file-system.mjs +7 -0
- package/dist/cli/wirings/provide-file-system.mjs.map +1 -0
- package/dist/cli/wirings/snapshot.mjs +177 -0
- package/dist/cli/wirings/snapshot.mjs.map +1 -0
- package/dist/cli/wirings/up.mjs +287 -0
- package/dist/cli/wirings/up.mjs.map +1 -0
- package/dist/cli/wirings/wipe.mjs +40 -0
- package/dist/cli/wirings/wipe.mjs.map +1 -0
- package/dist/contracts/capability-decl.d.mts +0 -2
- package/dist/contracts/codegenable.d.mts +43 -0
- package/dist/contracts/container-runtime.d.mts +26 -1
- package/dist/contracts/faucet-strategy.d.mts +25 -0
- package/dist/contracts/funding-strategy.d.mts +42 -0
- package/dist/contracts/plugin-expander.mjs +60 -0
- package/dist/contracts/plugin-expander.mjs.map +1 -0
- package/dist/contracts/projection.d.mts +5 -3
- package/dist/contracts/renderer.d.mts +23 -0
- package/dist/contracts/routable.d.mts +14 -1
- package/dist/contracts/snapshotable.d.mts +25 -3
- package/dist/contracts/wallet-protocol.d.mts +52 -0
- package/dist/contracts/wallet-protocol.mjs +52 -0
- package/dist/contracts/wallet-protocol.mjs.map +1 -0
- package/dist/index.d.mts +26 -25
- package/dist/index.mjs +20 -13
- package/dist/{runtime → orchestrators}/built-in-plugin-layers.mjs +10 -5
- package/dist/orchestrators/built-in-plugin-layers.mjs.map +1 -0
- package/dist/orchestrators/codegen/bindings.d.mts +1 -2
- package/dist/orchestrators/codegen/bindings.mjs +52 -186
- package/dist/orchestrators/codegen/bindings.mjs.map +1 -1
- package/dist/orchestrators/codegen/emit.mjs +19 -1
- package/dist/orchestrators/codegen/emit.mjs.map +1 -1
- package/dist/orchestrators/codegen/errors.mjs +8 -3
- package/dist/orchestrators/codegen/errors.mjs.map +1 -1
- package/dist/orchestrators/codegen/format.mjs +47 -39
- package/dist/orchestrators/codegen/format.mjs.map +1 -1
- package/dist/orchestrators/codegen/gitignore.mjs +3 -1
- package/dist/orchestrators/codegen/gitignore.mjs.map +1 -1
- package/dist/orchestrators/codegen/output-location.mjs +41 -0
- package/dist/orchestrators/codegen/output-location.mjs.map +1 -0
- package/dist/orchestrators/codegen/paths.d.mts +1 -1
- package/dist/orchestrators/codegen/paths.mjs +40 -14
- package/dist/orchestrators/codegen/paths.mjs.map +1 -1
- package/dist/orchestrators/codegen/permissions.mjs +3 -1
- package/dist/orchestrators/codegen/permissions.mjs.map +1 -1
- package/dist/orchestrators/codegen/service.mjs +157 -105
- package/dist/orchestrators/codegen/service.mjs.map +1 -1
- package/dist/orchestrators/lifecycle-prune/errors.mjs +31 -0
- package/dist/orchestrators/lifecycle-prune/errors.mjs.map +1 -0
- package/dist/orchestrators/lifecycle-prune/index.mjs +350 -0
- package/dist/orchestrators/lifecycle-prune/index.mjs.map +1 -0
- package/dist/orchestrators/router/cleanup.mjs +26 -27
- package/dist/orchestrators/router/cleanup.mjs.map +1 -1
- package/dist/orchestrators/router/entrypoints.mjs +2 -2
- package/dist/orchestrators/router/entrypoints.mjs.map +1 -1
- package/dist/orchestrators/router/file-provider.mjs +14 -5
- package/dist/orchestrators/router/file-provider.mjs.map +1 -1
- package/dist/orchestrators/router/hostname.mjs +19 -55
- package/dist/orchestrators/router/hostname.mjs.map +1 -1
- package/dist/orchestrators/router/index.mjs +11 -0
- package/dist/orchestrators/router/profile.mjs +2 -2
- package/dist/orchestrators/router/sentinels.mjs +26 -0
- package/dist/orchestrators/router/sentinels.mjs.map +1 -0
- package/dist/orchestrators/router/service.mjs +40 -37
- package/dist/orchestrators/router/service.mjs.map +1 -1
- package/dist/orchestrators/router/traefik-container.mjs +27 -16
- package/dist/orchestrators/router/traefik-container.mjs.map +1 -1
- package/dist/{substrate/runtime → orchestrators}/run.mjs +26 -21
- package/dist/orchestrators/run.mjs.map +1 -0
- package/dist/orchestrators/runtime-composition.d.mts +1 -1
- package/dist/orchestrators/runtime-composition.mjs +123 -39
- package/dist/orchestrators/runtime-composition.mjs.map +1 -1
- package/dist/orchestrators/snapshot/capture-command.d.mts +1 -0
- package/dist/orchestrators/snapshot/capture-command.mjs +25 -0
- package/dist/orchestrators/snapshot/capture-command.mjs.map +1 -0
- package/dist/orchestrators/snapshot/capture.mjs +42 -28
- package/dist/orchestrators/snapshot/capture.mjs.map +1 -1
- package/dist/orchestrators/snapshot/descriptor.mjs +35 -10
- package/dist/orchestrators/snapshot/descriptor.mjs.map +1 -1
- package/dist/orchestrators/snapshot/identity-guard.mjs +1 -1
- package/dist/orchestrators/snapshot/index.mjs +13 -0
- package/dist/orchestrators/snapshot/integrity.d.mts +1 -1
- package/dist/orchestrators/snapshot/integrity.mjs +73 -17
- package/dist/orchestrators/snapshot/integrity.mjs.map +1 -1
- package/dist/orchestrators/snapshot/pending-marker.d.mts +1 -0
- package/dist/orchestrators/snapshot/pending-marker.mjs +99 -0
- package/dist/orchestrators/snapshot/pending-marker.mjs.map +1 -0
- package/dist/orchestrators/snapshot/phase-error.mjs +23 -0
- package/dist/orchestrators/snapshot/phase-error.mjs.map +1 -0
- package/dist/orchestrators/snapshot/prune.mjs +20 -55
- package/dist/orchestrators/snapshot/prune.mjs.map +1 -1
- package/dist/orchestrators/snapshot/recover-pending.d.mts +1 -0
- package/dist/orchestrators/snapshot/recover-pending.mjs +223 -0
- package/dist/orchestrators/snapshot/recover-pending.mjs.map +1 -0
- package/dist/orchestrators/snapshot/restore.mjs +118 -84
- package/dist/orchestrators/snapshot/restore.mjs.map +1 -1
- package/dist/orchestrators/snapshot/service.mjs +53 -56
- package/dist/orchestrators/snapshot/service.mjs.map +1 -1
- package/dist/orchestrators/snapshot/state-document.d.mts +1 -0
- package/dist/orchestrators/snapshot/state-document.mjs +47 -7
- package/dist/orchestrators/snapshot/state-document.mjs.map +1 -1
- package/dist/orchestrators/snapshot/wipe.mjs +67 -10
- package/dist/orchestrators/snapshot/wipe.mjs.map +1 -1
- package/dist/plugins/account/codegen.mjs +9 -8
- package/dist/plugins/account/codegen.mjs.map +1 -1
- package/dist/plugins/account/errors.d.mts +33 -6
- package/dist/plugins/account/errors.mjs.map +1 -1
- package/dist/plugins/account/funding.d.mts +29 -19
- package/dist/plugins/account/funding.mjs +84 -66
- package/dist/plugins/account/funding.mjs.map +1 -1
- package/dist/plugins/account/index.d.mts +2 -4
- package/dist/plugins/account/index.mjs +64 -31
- package/dist/plugins/account/index.mjs.map +1 -1
- package/dist/plugins/account/keypair.mjs +6 -9
- package/dist/plugins/account/keypair.mjs.map +1 -1
- package/dist/plugins/account/lease.mjs +1 -0
- package/dist/plugins/account/lease.mjs.map +1 -1
- package/dist/plugins/account/registry.d.mts +14 -1
- package/dist/plugins/account/registry.mjs +18 -18
- package/dist/plugins/account/registry.mjs.map +1 -1
- package/dist/plugins/account/service.d.mts +23 -4
- package/dist/plugins/account/service.mjs +83 -45
- package/dist/plugins/account/service.mjs.map +1 -1
- package/dist/plugins/account/snapshot.mjs +2 -5
- package/dist/plugins/account/snapshot.mjs.map +1 -1
- package/dist/plugins/account/spans.mjs +16 -0
- package/dist/plugins/account/spans.mjs.map +1 -0
- package/dist/plugins/account/variants/keystore.mjs +6 -8
- package/dist/plugins/account/variants/keystore.mjs.map +1 -1
- package/dist/plugins/action/build-context.d.mts +3 -2
- package/dist/plugins/action/errors.d.mts +16 -12
- package/dist/plugins/action/errors.mjs.map +1 -1
- package/dist/plugins/action/execute.mjs +65 -103
- package/dist/plugins/action/execute.mjs.map +1 -1
- package/dist/plugins/action/index.d.mts +0 -2
- package/dist/plugins/action/index.mjs +17 -13
- package/dist/plugins/action/index.mjs.map +1 -1
- package/dist/plugins/action/service.mjs +38 -35
- package/dist/plugins/action/service.mjs.map +1 -1
- package/dist/plugins/action/spans.mjs +11 -0
- package/dist/plugins/action/spans.mjs.map +1 -0
- package/dist/plugins/coin/codegen.mjs +9 -8
- package/dist/plugins/coin/codegen.mjs.map +1 -1
- package/dist/plugins/coin/discovery.mjs +8 -4
- package/dist/plugins/coin/discovery.mjs.map +1 -1
- package/dist/plugins/coin/index.d.mts +11 -29
- package/dist/plugins/coin/index.mjs +56 -27
- package/dist/plugins/coin/index.mjs.map +1 -1
- package/dist/plugins/coin/metadata.mjs +8 -15
- package/dist/plugins/coin/metadata.mjs.map +1 -1
- package/dist/plugins/coin/mint.d.mts +30 -11
- package/dist/plugins/coin/mint.mjs +78 -74
- package/dist/plugins/coin/mint.mjs.map +1 -1
- package/dist/plugins/coin/registry.mjs +4 -7
- package/dist/plugins/coin/registry.mjs.map +1 -1
- package/dist/plugins/coin/service.d.mts +39 -1
- package/dist/plugins/coin/service.mjs +11 -4
- package/dist/plugins/coin/service.mjs.map +1 -1
- package/dist/plugins/coin/spans.mjs +20 -0
- package/dist/plugins/coin/spans.mjs.map +1 -0
- package/dist/plugins/dashboard/domain.mjs +402 -0
- package/dist/plugins/dashboard/domain.mjs.map +1 -0
- package/dist/plugins/dashboard/index.d.mts +29 -0
- package/dist/plugins/dashboard/index.mjs +91 -0
- package/dist/plugins/dashboard/index.mjs.map +1 -0
- package/dist/plugins/dashboard/origin-policy.mjs +36 -0
- package/dist/plugins/dashboard/origin-policy.mjs.map +1 -0
- package/dist/plugins/dashboard/routable.mjs +27 -0
- package/dist/plugins/dashboard/routable.mjs.map +1 -0
- package/dist/plugins/dashboard/schema/builder.mjs +21 -0
- package/dist/plugins/dashboard/schema/builder.mjs.map +1 -0
- package/dist/plugins/dashboard/schema/enums.mjs +72 -0
- package/dist/plugins/dashboard/schema/enums.mjs.map +1 -0
- package/dist/plugins/dashboard/schema/root.mjs +351 -0
- package/dist/plugins/dashboard/schema/root.mjs.map +1 -0
- package/dist/plugins/dashboard/schema/types.mjs +508 -0
- package/dist/plugins/dashboard/schema/types.mjs.map +1 -0
- package/dist/plugins/dashboard/schema.mjs +11 -0
- package/dist/plugins/dashboard/schema.mjs.map +1 -0
- package/dist/plugins/dashboard/server.mjs +166 -0
- package/dist/plugins/dashboard/server.mjs.map +1 -0
- package/dist/plugins/deepbook/deploy.mjs +53 -115
- package/dist/plugins/deepbook/deploy.mjs.map +1 -1
- package/dist/plugins/deepbook/errors.mjs +1 -0
- package/dist/plugins/deepbook/errors.mjs.map +1 -1
- package/dist/plugins/deepbook/faucet-strategy.mjs +47 -34
- package/dist/plugins/deepbook/faucet-strategy.mjs.map +1 -1
- package/dist/plugins/deepbook/hash.mjs +9 -0
- package/dist/plugins/deepbook/hash.mjs.map +1 -0
- package/dist/plugins/deepbook/index.d.mts +1 -10
- package/dist/plugins/deepbook/index.mjs +25 -22
- package/dist/plugins/deepbook/index.mjs.map +1 -1
- package/dist/plugins/deepbook/pyth/index.mjs +26 -55
- package/dist/plugins/deepbook/pyth/index.mjs.map +1 -1
- package/dist/plugins/deepbook/snapshot.mjs +17 -29
- package/dist/plugins/deepbook/snapshot.mjs.map +1 -1
- package/dist/plugins/deepbook/spans.mjs +18 -0
- package/dist/plugins/deepbook/spans.mjs.map +1 -0
- package/dist/plugins/deepbook/type-strings.mjs +65 -0
- package/dist/plugins/deepbook/type-strings.mjs.map +1 -0
- package/dist/plugins/deepbook/types.d.mts +2 -3
- package/dist/plugins/deepbook/types.mjs.map +1 -1
- package/dist/plugins/faucet/dispatcher.d.mts +21 -2
- package/dist/plugins/faucet/dispatcher.mjs +1 -2
- package/dist/plugins/faucet/dispatcher.mjs.map +1 -1
- package/dist/plugins/faucet/errors.d.mts +11 -24
- package/dist/plugins/faucet/errors.mjs.map +1 -1
- package/dist/plugins/faucet/http.mjs +33 -14
- package/dist/plugins/faucet/http.mjs.map +1 -1
- package/dist/plugins/faucet/index.d.mts +15 -5
- package/dist/plugins/faucet/index.mjs +3 -0
- package/dist/plugins/faucet/index.mjs.map +1 -1
- package/dist/plugins/faucet/spans.mjs +12 -0
- package/dist/plugins/faucet/spans.mjs.map +1 -0
- package/dist/plugins/host-service/errors.d.mts +1 -1
- package/dist/plugins/host-service/index.mjs +34 -8
- package/dist/plugins/host-service/index.mjs.map +1 -1
- package/dist/plugins/host-service/routable.mjs +2 -1
- package/dist/plugins/host-service/routable.mjs.map +1 -1
- package/dist/plugins/host-service/service.d.mts +21 -0
- package/dist/plugins/host-service/service.mjs +136 -81
- package/dist/plugins/host-service/service.mjs.map +1 -1
- package/dist/plugins/internal/acquire-on-chain-artifact.mjs +23 -0
- package/dist/plugins/internal/acquire-on-chain-artifact.mjs.map +1 -0
- package/dist/plugins/internal/codegen-helpers.mjs +18 -0
- package/dist/plugins/internal/codegen-helpers.mjs.map +1 -0
- package/dist/plugins/internal/funding-failure-error.mjs +32 -0
- package/dist/plugins/internal/funding-failure-error.mjs.map +1 -0
- package/dist/plugins/package/build.mjs +1 -1
- package/dist/plugins/package/build.mjs.map +1 -1
- package/dist/plugins/package/codegen.mjs +26 -0
- package/dist/plugins/package/codegen.mjs.map +1 -1
- package/dist/plugins/package/errors.d.mts +16 -6
- package/dist/plugins/package/errors.mjs.map +1 -1
- package/dist/plugins/package/index.d.mts +0 -4
- package/dist/plugins/package/index.mjs +27 -21
- package/dist/plugins/package/index.mjs.map +1 -1
- package/dist/plugins/package/mode-known.mjs +26 -12
- package/dist/plugins/package/mode-known.mjs.map +1 -1
- package/dist/plugins/package/mode-local.mjs +47 -41
- package/dist/plugins/package/mode-local.mjs.map +1 -1
- package/dist/plugins/package/publish-executor.mjs +55 -114
- package/dist/plugins/package/publish-executor.mjs.map +1 -1
- package/dist/plugins/package/registry.mjs +2 -1
- package/dist/plugins/package/registry.mjs.map +1 -1
- package/dist/plugins/package/service.mjs.map +1 -1
- package/dist/plugins/package/spans.mjs +14 -0
- package/dist/plugins/package/spans.mjs.map +1 -0
- package/dist/plugins/postgres/db-ensure.mjs +19 -12
- package/dist/plugins/postgres/db-ensure.mjs.map +1 -1
- package/dist/plugins/postgres/errors.d.mts +5 -0
- package/dist/plugins/postgres/errors.mjs.map +1 -1
- package/dist/plugins/postgres/index.mjs +10 -17
- package/dist/plugins/postgres/index.mjs.map +1 -1
- package/dist/plugins/postgres/service.mjs +58 -24
- package/dist/plugins/postgres/service.mjs.map +1 -1
- package/dist/plugins/postgres/snapshot.mjs.map +1 -1
- package/dist/plugins/postgres/spans.mjs +11 -0
- package/dist/plugins/postgres/spans.mjs.map +1 -0
- package/dist/plugins/router-entrypoints.mjs +4 -4
- package/dist/plugins/router-entrypoints.mjs.map +1 -1
- package/dist/plugins/seal/bootstrap-assets/cargo-image.mjs +15 -13
- package/dist/plugins/seal/bootstrap-assets/cargo-image.mjs.map +1 -1
- package/dist/plugins/seal/bootstrap-assets/source-fetch.mjs +15 -19
- package/dist/plugins/seal/bootstrap-assets/source-fetch.mjs.map +1 -1
- package/dist/plugins/seal/codegen.d.mts +2 -3
- package/dist/plugins/seal/codegen.mjs.map +1 -1
- package/dist/plugins/seal/config-render.mjs +35 -8
- package/dist/plugins/seal/config-render.mjs.map +1 -1
- package/dist/plugins/seal/deploy.mjs +31 -39
- package/dist/plugins/seal/deploy.mjs.map +1 -1
- package/dist/plugins/seal/errors.d.mts +1 -3
- package/dist/plugins/seal/errors.mjs +7 -1
- package/dist/plugins/seal/errors.mjs.map +1 -1
- package/dist/plugins/seal/index.d.mts +1 -6
- package/dist/plugins/seal/index.mjs +40 -14
- package/dist/plugins/seal/index.mjs.map +1 -1
- package/dist/plugins/seal/key-manager.d.mts +1 -9
- package/dist/plugins/seal/key-manager.mjs +2 -18
- package/dist/plugins/seal/key-manager.mjs.map +1 -1
- package/dist/plugins/seal/key-server.mjs +37 -36
- package/dist/plugins/seal/key-server.mjs.map +1 -1
- package/dist/plugins/seal/keygen.mjs +16 -17
- package/dist/plugins/seal/keygen.mjs.map +1 -1
- package/dist/plugins/seal/mode/fork-known.mjs +36 -14
- package/dist/plugins/seal/mode/fork-known.mjs.map +1 -1
- package/dist/plugins/seal/mode/live.d.mts +6 -4
- package/dist/plugins/seal/mode/live.mjs +14 -21
- package/dist/plugins/seal/mode/live.mjs.map +1 -1
- package/dist/plugins/seal/mode/local-keygen.mjs +57 -21
- package/dist/plugins/seal/mode/local-keygen.mjs.map +1 -1
- package/dist/plugins/seal/registry-publish.mjs +1 -0
- package/dist/plugins/seal/registry-publish.mjs.map +1 -1
- package/dist/plugins/seal/routable.mjs.map +1 -1
- package/dist/plugins/seal/service.mjs.map +1 -1
- package/dist/plugins/seal/spans.mjs +18 -0
- package/dist/plugins/seal/spans.mjs.map +1 -0
- package/dist/plugins/sui/auto-tick.mjs +17 -23
- package/dist/plugins/sui/auto-tick.mjs.map +1 -1
- package/dist/plugins/sui/chain-build-container.mjs +18 -0
- package/dist/plugins/sui/chain-build-container.mjs.map +1 -0
- package/dist/plugins/sui/chain-probe.d.mts +5 -5
- package/dist/plugins/sui/chain-probe.mjs +28 -58
- package/dist/plugins/sui/chain-probe.mjs.map +1 -1
- package/dist/plugins/sui/codegen.mjs +26 -0
- package/dist/plugins/sui/codegen.mjs.map +1 -1
- package/dist/plugins/sui/errors.d.mts +2 -29
- package/dist/plugins/sui/errors.mjs +1 -3
- package/dist/plugins/sui/errors.mjs.map +1 -1
- package/dist/plugins/sui/fork-faucet-strategy.d.mts +1 -0
- package/dist/plugins/sui/fork-faucet-strategy.mjs +55 -0
- package/dist/plugins/sui/fork-faucet-strategy.mjs.map +1 -0
- package/dist/plugins/sui/fork-orchestration.d.mts +1 -0
- package/dist/plugins/sui/fork-orchestration.mjs +170 -2
- package/dist/plugins/sui/fork-orchestration.mjs.map +1 -1
- package/dist/plugins/sui/fork-transaction.d.mts +2 -0
- package/dist/plugins/sui/fork-transaction.mjs +92 -28
- package/dist/plugins/sui/fork-transaction.mjs.map +1 -1
- package/dist/plugins/sui/index.d.mts +33 -70
- package/dist/plugins/sui/index.mjs +58 -35
- package/dist/plugins/sui/index.mjs.map +1 -1
- package/dist/plugins/{faucet/strategies/sui-local.mjs → sui/local-faucet-strategy.mjs} +10 -7
- package/dist/plugins/sui/local-faucet-strategy.mjs.map +1 -0
- package/dist/plugins/sui/mode/external.mjs +7 -13
- package/dist/plugins/sui/mode/external.mjs.map +1 -1
- package/dist/plugins/sui/mode/fork.mjs +136 -59
- package/dist/plugins/sui/mode/fork.mjs.map +1 -1
- package/dist/plugins/sui/mode/live.mjs +10 -16
- package/dist/plugins/sui/mode/live.mjs.map +1 -1
- package/dist/plugins/sui/mode/local.mjs +37 -36
- package/dist/plugins/sui/mode/local.mjs.map +1 -1
- package/dist/plugins/sui/mode/shared-boot.mjs +38 -115
- package/dist/plugins/sui/mode/shared-boot.mjs.map +1 -1
- package/dist/plugins/sui/mode/shared.d.mts +1 -5
- package/dist/plugins/sui/mode/shared.mjs.map +1 -1
- package/dist/plugins/sui/mode/spec.d.mts +18 -0
- package/dist/plugins/sui/move-summary-runner.mjs +207 -0
- package/dist/plugins/sui/move-summary-runner.mjs.map +1 -0
- package/dist/plugins/sui/network-resolver.d.mts +4 -3
- package/dist/plugins/sui/service.mjs.map +1 -1
- package/dist/plugins/sui/snapshot.mjs +3 -0
- package/dist/plugins/sui/snapshot.mjs.map +1 -1
- package/dist/plugins/sui/spans.mjs +17 -0
- package/dist/plugins/sui/spans.mjs.map +1 -0
- package/dist/plugins/wallet/codegen.d.mts +0 -1
- package/dist/plugins/wallet/codegen.mjs +8 -9
- package/dist/plugins/wallet/codegen.mjs.map +1 -1
- package/dist/plugins/wallet/index.d.mts +6 -8
- package/dist/plugins/wallet/index.mjs +46 -35
- package/dist/plugins/wallet/index.mjs.map +1 -1
- package/dist/plugins/wallet/origin-policy.mjs +12 -28
- package/dist/plugins/wallet/origin-policy.mjs.map +1 -1
- package/dist/plugins/wallet/pairing.mjs +6 -4
- package/dist/plugins/wallet/pairing.mjs.map +1 -1
- package/dist/plugins/wallet/protocol.d.mts +1 -0
- package/dist/plugins/wallet/protocol.mjs +5 -44
- package/dist/plugins/wallet/protocol.mjs.map +1 -1
- package/dist/plugins/wallet/routable.mjs +2 -8
- package/dist/plugins/wallet/routable.mjs.map +1 -1
- package/dist/plugins/wallet/server.mjs +36 -44
- package/dist/plugins/wallet/server.mjs.map +1 -1
- package/dist/plugins/wallet/service.d.mts +1 -5
- package/dist/plugins/wallet/service.mjs +22 -18
- package/dist/plugins/wallet/service.mjs.map +1 -1
- package/dist/plugins/wallet/spans.mjs +22 -0
- package/dist/plugins/wallet/spans.mjs.map +1 -0
- package/dist/plugins/walrus/bootstrap-assets/cargo-image.mjs +33 -8
- package/dist/plugins/walrus/bootstrap-assets/cargo-image.mjs.map +1 -1
- package/dist/plugins/walrus/codegen.d.mts +3 -3
- package/dist/plugins/walrus/codegen.mjs.map +1 -1
- package/dist/plugins/walrus/deploy-paths.mjs +21 -5
- package/dist/plugins/walrus/deploy-paths.mjs.map +1 -1
- package/dist/plugins/walrus/deploy.mjs +67 -69
- package/dist/plugins/walrus/deploy.mjs.map +1 -1
- package/dist/plugins/walrus/errors.mjs +1 -0
- package/dist/plugins/walrus/errors.mjs.map +1 -1
- package/dist/plugins/walrus/faucet-strategy.mjs +12 -7
- package/dist/plugins/walrus/faucet-strategy.mjs.map +1 -1
- package/dist/plugins/walrus/index.d.mts +2 -13
- package/dist/plugins/walrus/index.mjs +18 -23
- package/dist/plugins/walrus/index.mjs.map +1 -1
- package/dist/plugins/walrus/mode/known-deploy.mjs +7 -5
- package/dist/plugins/walrus/mode/known-deploy.mjs.map +1 -1
- package/dist/plugins/walrus/mode/local-cluster.mjs +26 -7
- package/dist/plugins/walrus/mode/local-cluster.mjs.map +1 -1
- package/dist/plugins/walrus/registry-publish.mjs.map +1 -1
- package/dist/plugins/walrus/routable.mjs +7 -23
- package/dist/plugins/walrus/routable.mjs.map +1 -1
- package/dist/plugins/walrus/service.mjs.map +1 -1
- package/dist/plugins/walrus/spans.mjs +18 -0
- package/dist/plugins/walrus/spans.mjs.map +1 -0
- package/dist/plugins/walrus/storage-nodes.d.mts +6 -2
- package/dist/plugins/walrus/storage-nodes.mjs +15 -8
- package/dist/plugins/walrus/storage-nodes.mjs.map +1 -1
- package/dist/plugins/walrus/wal-swap.mjs +58 -15
- package/dist/plugins/walrus/wal-swap.mjs.map +1 -1
- package/dist/primitives/artifact-publisher.d.mts +1 -1
- package/dist/primitives/artifact-publisher.mjs +15 -0
- package/dist/primitives/artifact-publisher.mjs.map +1 -0
- package/dist/runtime/docker/client.mjs +17 -4
- package/dist/runtime/docker/client.mjs.map +1 -1
- package/dist/runtime/docker/container.mjs +219 -132
- package/dist/runtime/docker/container.mjs.map +1 -1
- package/dist/runtime/docker/errors.mjs +0 -6
- package/dist/runtime/docker/errors.mjs.map +1 -1
- package/dist/runtime/docker/exec.mjs +21 -18
- package/dist/runtime/docker/exec.mjs.map +1 -1
- package/dist/runtime/docker/image.mjs +36 -13
- package/dist/runtime/docker/image.mjs.map +1 -1
- package/dist/runtime/docker/index.mjs +14 -0
- package/dist/runtime/docker/inspect-and-decode.mjs +51 -0
- package/dist/runtime/docker/inspect-and-decode.mjs.map +1 -0
- package/dist/runtime/docker/inventory.mjs +14 -11
- package/dist/runtime/docker/inventory.mjs.map +1 -1
- package/dist/runtime/docker/labels.mjs +38 -5
- package/dist/runtime/docker/labels.mjs.map +1 -1
- package/dist/runtime/docker/logs.d.mts +1 -1
- package/dist/runtime/docker/logs.mjs.map +1 -1
- package/dist/runtime/docker/network.mjs +83 -47
- package/dist/runtime/docker/network.mjs.map +1 -1
- package/dist/runtime/docker/render-run-args.mjs +82 -0
- package/dist/runtime/docker/render-run-args.mjs.map +1 -0
- package/dist/runtime/docker/service.d.mts +1 -1
- package/dist/runtime/docker/service.mjs +12 -7
- package/dist/runtime/docker/service.mjs.map +1 -1
- package/dist/runtime/docker/sweep.mjs +118 -43
- package/dist/runtime/docker/sweep.mjs.map +1 -1
- package/dist/runtime/docker/volume.mjs +2 -0
- package/dist/runtime/docker/volume.mjs.map +1 -1
- package/dist/runtime/docker/wrap.mjs +30 -1
- package/dist/runtime/docker/wrap.mjs.map +1 -1
- package/dist/substrate/cross-process.mjs +14 -8
- package/dist/substrate/cross-process.mjs.map +1 -1
- package/dist/substrate/event-time.mjs +33 -0
- package/dist/substrate/event-time.mjs.map +1 -0
- package/dist/substrate/events.d.mts +28 -8
- package/dist/substrate/identity.d.mts +2 -1
- package/dist/substrate/manifest.d.mts +68 -5
- package/dist/substrate/manifest.mjs +34 -5
- package/dist/substrate/manifest.mjs.map +1 -1
- package/dist/substrate/network.d.mts +3 -5
- package/dist/substrate/options.d.mts +0 -2
- package/dist/substrate/plugin.d.mts +13 -0
- package/dist/substrate/plugin.mjs +4 -2
- package/dist/substrate/plugin.mjs.map +1 -1
- package/dist/substrate/projection.d.mts +35 -3
- package/dist/substrate/runtime/artifact-publisher/index.mjs +19 -9
- package/dist/substrate/runtime/artifact-publisher/index.mjs.map +1 -1
- package/dist/substrate/runtime/atomic-write.mjs +97 -32
- package/dist/substrate/runtime/atomic-write.mjs.map +1 -1
- package/dist/substrate/runtime/cache/index.mjs +3 -0
- package/dist/substrate/runtime/cache/schema.mjs +2 -2
- package/dist/substrate/runtime/cache/schema.mjs.map +1 -1
- package/dist/substrate/runtime/cache/service.mjs +9 -7
- package/dist/substrate/runtime/cache/service.mjs.map +1 -1
- package/dist/substrate/runtime/capability-sinks/index.d.mts +1 -1
- package/dist/substrate/runtime/capability-sinks/index.mjs +3 -0
- package/dist/substrate/runtime/capability-sinks/layer.mjs +1 -1
- package/dist/substrate/runtime/capability-sinks/service.d.mts +61 -2
- package/dist/substrate/runtime/capability-sinks/service.mjs +21 -26
- package/dist/substrate/runtime/capability-sinks/service.mjs.map +1 -1
- package/dist/substrate/runtime/config-validation.d.mts +1 -13
- package/dist/substrate/runtime/config-validation.mjs +2 -91
- package/dist/substrate/runtime/config-validation.mjs.map +1 -1
- package/dist/substrate/runtime/container-runtime.d.mts +1 -0
- package/dist/substrate/runtime/container-runtime.mjs +2 -0
- package/dist/substrate/runtime/control-plane/domain.mjs +101 -0
- package/dist/substrate/runtime/control-plane/domain.mjs.map +1 -0
- package/dist/substrate/runtime/control-plane/service.mjs +7 -0
- package/dist/substrate/runtime/control-plane/service.mjs.map +1 -0
- package/dist/substrate/runtime/cross-process/command-channel/channel.mjs +46 -19
- package/dist/substrate/runtime/cross-process/command-channel/channel.mjs.map +1 -1
- package/dist/substrate/runtime/cross-process/command-channel/file-channel.mjs +30 -12
- package/dist/substrate/runtime/cross-process/command-channel/file-channel.mjs.map +1 -1
- package/dist/substrate/runtime/cross-process/command-channel/index.mjs +5 -0
- package/dist/substrate/runtime/cross-process/command-channel/protocol.mjs +11 -2
- package/dist/substrate/runtime/cross-process/command-channel/protocol.mjs.map +1 -1
- package/dist/substrate/runtime/cross-process/command-channel/runtime-control-lock.mjs +1 -1
- package/dist/substrate/runtime/cross-process/index.mjs +11 -0
- package/dist/substrate/runtime/cross-process/live-clock.mjs +34 -0
- package/dist/substrate/runtime/cross-process/live-clock.mjs.map +1 -0
- package/dist/substrate/runtime/cross-process/liveness.mjs +52 -10
- package/dist/substrate/runtime/cross-process/liveness.mjs.map +1 -1
- package/dist/substrate/runtime/cross-process/lock.d.mts +1 -0
- package/dist/substrate/runtime/cross-process/lock.mjs +23 -0
- package/dist/substrate/runtime/cross-process/lock.mjs.map +1 -0
- package/dist/substrate/runtime/cross-process/reclaim-stale-file.mjs +64 -0
- package/dist/substrate/runtime/cross-process/reclaim-stale-file.mjs.map +1 -0
- package/dist/substrate/runtime/cross-process/roster.mjs +97 -83
- package/dist/substrate/runtime/cross-process/roster.mjs.map +1 -1
- package/dist/substrate/runtime/cross-process/self-pid.mjs +8 -0
- package/dist/substrate/runtime/cross-process/self-pid.mjs.map +1 -0
- package/dist/substrate/runtime/cross-process/snapshot-reservation.mjs +24 -28
- package/dist/substrate/runtime/cross-process/snapshot-reservation.mjs.map +1 -1
- package/dist/substrate/runtime/cross-process/stack-lock.mjs +41 -20
- package/dist/substrate/runtime/cross-process/stack-lock.mjs.map +1 -1
- package/dist/substrate/runtime/current-plugin.mjs +2 -2
- package/dist/substrate/runtime/current-plugin.mjs.map +1 -1
- package/dist/substrate/runtime/errors.mjs +12 -6
- package/dist/substrate/runtime/errors.mjs.map +1 -1
- package/dist/substrate/runtime/format-unknown-error.mjs +30 -0
- package/dist/substrate/runtime/format-unknown-error.mjs.map +1 -0
- package/dist/substrate/runtime/host-bind-mount-owner.mjs +10 -0
- package/dist/substrate/runtime/host-bind-mount-owner.mjs.map +1 -0
- package/dist/substrate/runtime/host-gateway.mjs +20 -0
- package/dist/substrate/runtime/host-gateway.mjs.map +1 -0
- package/dist/substrate/runtime/host-tree-tar/index.mjs +61 -50
- package/dist/substrate/runtime/host-tree-tar/index.mjs.map +1 -1
- package/dist/substrate/runtime/http-probe.d.mts +1 -1
- package/dist/substrate/runtime/index.mjs +14 -0
- package/dist/substrate/runtime/lease-broker/index.d.mts +1 -1
- package/dist/substrate/runtime/lease-broker/index.mjs +2 -0
- package/dist/substrate/runtime/lease-broker/service.d.mts +1 -64
- package/dist/substrate/runtime/lease-broker/service.mjs +1 -1
- package/dist/substrate/runtime/lease-broker/service.mjs.map +1 -1
- package/dist/substrate/runtime/lifecycle/dep-graph.mjs +22 -3
- package/dist/substrate/runtime/lifecycle/dep-graph.mjs.map +1 -1
- package/dist/substrate/runtime/lifecycle/index.mjs +9 -0
- package/dist/substrate/runtime/lifecycle/lifecycle-fact.mjs.map +1 -1
- package/dist/substrate/runtime/lifecycle/plugin-registry.mjs +20 -3
- package/dist/substrate/runtime/lifecycle/plugin-registry.mjs.map +1 -1
- package/dist/substrate/runtime/lifecycle/selective-restart.mjs +1 -1
- package/dist/substrate/runtime/lifecycle/signals.mjs +5 -5
- package/dist/substrate/runtime/lifecycle/signals.mjs.map +1 -1
- package/dist/substrate/runtime/lifecycle/state-machine.mjs +1 -1
- package/dist/substrate/runtime/managed-container.d.mts +19 -1
- package/dist/substrate/runtime/managed-container.mjs +20 -1
- package/dist/substrate/runtime/managed-container.mjs.map +1 -1
- package/dist/substrate/runtime/manifest/index.mjs +3 -0
- package/dist/substrate/runtime/manifest/manifest.mjs +15 -11
- package/dist/substrate/runtime/manifest/manifest.mjs.map +1 -1
- package/dist/substrate/runtime/mode-errors.mjs +20 -0
- package/dist/substrate/runtime/mode-errors.mjs.map +1 -0
- package/dist/substrate/runtime/observability/cascade-formatter.mjs +9 -13
- package/dist/substrate/runtime/observability/cascade-formatter.mjs.map +1 -1
- package/dist/substrate/runtime/observability/formatter-registry.mjs +19 -36
- package/dist/substrate/runtime/observability/formatter-registry.mjs.map +1 -1
- package/dist/substrate/runtime/observability/ignore-with-log.d.mts +1 -0
- package/dist/substrate/runtime/observability/ignore-with-log.mjs +17 -0
- package/dist/substrate/runtime/observability/ignore-with-log.mjs.map +1 -0
- package/dist/substrate/runtime/observability/index.d.mts +1 -1
- package/dist/substrate/runtime/observability/index.mjs +13 -0
- package/dist/substrate/runtime/observability/log-store.d.mts +1 -0
- package/dist/substrate/runtime/observability/log-store.mjs +175 -0
- package/dist/substrate/runtime/observability/log-store.mjs.map +1 -0
- package/dist/substrate/runtime/observability/logger.d.mts +2 -1
- package/dist/substrate/runtime/observability/logger.mjs +5 -9
- package/dist/substrate/runtime/observability/logger.mjs.map +1 -1
- package/dist/substrate/runtime/observability/output-truncate.mjs +35 -0
- package/dist/substrate/runtime/observability/output-truncate.mjs.map +1 -0
- package/dist/substrate/runtime/observability/pretty-error.mjs +9 -12
- package/dist/substrate/runtime/observability/pretty-error.mjs.map +1 -1
- package/dist/substrate/runtime/observability/redaction.d.mts +2 -13
- package/dist/substrate/runtime/observability/redaction.mjs +8 -14
- package/dist/substrate/runtime/observability/redaction.mjs.map +1 -1
- package/dist/substrate/runtime/observability/span-store.d.mts +1 -0
- package/dist/substrate/runtime/observability/span-store.mjs +110 -0
- package/dist/substrate/runtime/observability/span-store.mjs.map +1 -0
- package/dist/substrate/runtime/observability/spans.mjs +14 -14
- package/dist/substrate/runtime/observability/spans.mjs.map +1 -1
- package/dist/substrate/runtime/observability/subprocess-capture.mjs +1 -1
- package/dist/substrate/runtime/passthrough-or-wrap.mjs +33 -0
- package/dist/substrate/runtime/passthrough-or-wrap.mjs.map +1 -0
- package/dist/substrate/runtime/paths.d.mts +1 -1
- package/dist/substrate/runtime/paths.mjs +4 -3
- package/dist/substrate/runtime/paths.mjs.map +1 -1
- package/dist/substrate/runtime/phase-preserving-produce.mjs +40 -0
- package/dist/substrate/runtime/phase-preserving-produce.mjs.map +1 -0
- package/dist/substrate/runtime/port-broker/index.mjs +3 -0
- package/dist/substrate/runtime/port-broker/service.mjs +170 -126
- package/dist/substrate/runtime/port-broker/service.mjs.map +1 -1
- package/dist/substrate/runtime/post-acquire-tasks.mjs +1 -1
- package/dist/substrate/runtime/post-acquire-tasks.mjs.map +1 -1
- package/dist/substrate/runtime/probes.d.mts +7 -5
- package/dist/substrate/runtime/probes.mjs +3 -1
- package/dist/substrate/runtime/probes.mjs.map +1 -1
- package/dist/substrate/runtime/projection/index.mjs +4 -0
- package/dist/substrate/runtime/projection/operational-endpoints.mjs +1 -2
- package/dist/substrate/runtime/projection/operational-endpoints.mjs.map +1 -1
- package/dist/substrate/runtime/projection/persisted.mjs +33 -15
- package/dist/substrate/runtime/projection/persisted.mjs.map +1 -1
- package/dist/substrate/runtime/projection/state-ref.mjs +26 -2
- package/dist/substrate/runtime/projection/state-ref.mjs.map +1 -1
- package/dist/substrate/runtime/projection/update.mjs +88 -24
- package/dist/substrate/runtime/projection/update.mjs.map +1 -1
- package/dist/substrate/runtime/random-suffix.mjs +11 -0
- package/dist/substrate/runtime/random-suffix.mjs.map +1 -0
- package/dist/substrate/runtime/retry-policy.d.mts +59 -1
- package/dist/substrate/runtime/retry-policy.mjs +66 -1
- package/dist/substrate/runtime/retry-policy.mjs.map +1 -1
- package/dist/substrate/runtime/routed-url.d.mts +1 -0
- package/dist/substrate/runtime/routed-url.mjs +79 -0
- package/dist/substrate/runtime/routed-url.mjs.map +1 -0
- package/dist/substrate/runtime/runtime-decode.d.mts +1 -1
- package/dist/substrate/runtime/runtime-decode.mjs.map +1 -1
- package/dist/substrate/runtime/scoped-http-server.mjs +2 -3
- package/dist/substrate/runtime/scoped-http-server.mjs.map +1 -1
- package/dist/substrate/runtime/scoped-multimap/index.mjs +2 -0
- package/dist/substrate/runtime/scoped-multimap/service.mjs +52 -0
- package/dist/substrate/runtime/scoped-multimap/service.mjs.map +1 -0
- package/dist/substrate/runtime/scoped-ref-map/index.mjs +2 -0
- package/dist/substrate/runtime/scoped-ref-map/service.mjs +2 -2
- package/dist/substrate/runtime/scoped-ref-map/service.mjs.map +1 -1
- package/dist/substrate/runtime/stage-and-swap/index.mjs +72 -4
- package/dist/substrate/runtime/stage-and-swap/index.mjs.map +1 -1
- package/dist/substrate/runtime/state-store/index.d.mts +1 -0
- package/dist/substrate/runtime/state-store/index.mjs +3 -0
- package/dist/substrate/runtime/state-store/schema.d.mts +1 -0
- package/dist/substrate/runtime/state-store/schema.mjs +19 -14
- package/dist/substrate/runtime/state-store/schema.mjs.map +1 -1
- package/dist/substrate/runtime/state-store/service.d.mts +1 -0
- package/dist/substrate/runtime/state-store/service.mjs +145 -0
- package/dist/substrate/runtime/state-store/service.mjs.map +1 -0
- package/dist/substrate/runtime/strategy-registry/chain-keyed-strategy-for.d.mts +1 -0
- package/dist/substrate/runtime/strategy-registry/chain-keyed-strategy-for.mjs +33 -0
- package/dist/substrate/runtime/strategy-registry/chain-keyed-strategy-for.mjs.map +1 -0
- package/dist/substrate/runtime/strategy-registry/chain-probe-for.mjs +1 -1
- package/dist/substrate/runtime/strategy-registry/chain-probe-for.mjs.map +1 -1
- package/dist/substrate/runtime/strategy-registry/index.mjs +4 -0
- package/dist/substrate/runtime/strategy-registry/service.mjs +19 -33
- package/dist/substrate/runtime/strategy-registry/service.mjs.map +1 -1
- package/dist/substrate/runtime/subnet-broker.mjs +60 -0
- package/dist/substrate/runtime/subnet-broker.mjs.map +1 -0
- package/dist/substrate/runtime/sui-execute/index.d.mts +21 -1
- package/dist/substrate/runtime/sui-execute/index.mjs +84 -20
- package/dist/substrate/runtime/sui-execute/index.mjs.map +1 -1
- package/dist/substrate/runtime/sui-execute/sign-and-dispatch.d.mts +1 -0
- package/dist/substrate/runtime/sui-execute/sign-and-dispatch.mjs +32 -0
- package/dist/substrate/runtime/sui-execute/sign-and-dispatch.mjs.map +1 -0
- package/dist/substrate/runtime/sui-ledger/object-ref.mjs +32 -0
- package/dist/substrate/runtime/sui-ledger/object-ref.mjs.map +1 -0
- package/dist/substrate/runtime/sui-move-build/index.mjs +93 -19
- package/dist/substrate/runtime/sui-move-build/index.mjs.map +1 -1
- package/dist/substrate/runtime/supervisor/acquire-node.mjs +181 -0
- package/dist/substrate/runtime/supervisor/acquire-node.mjs.map +1 -0
- package/dist/substrate/runtime/supervisor/background-tasks.mjs +144 -0
- package/dist/substrate/runtime/supervisor/background-tasks.mjs.map +1 -0
- package/dist/substrate/runtime/supervisor/command-loop.mjs +68 -0
- package/dist/substrate/runtime/supervisor/command-loop.mjs.map +1 -0
- package/dist/substrate/runtime/supervisor/dispatch-contributions.mjs +151 -0
- package/dist/substrate/runtime/supervisor/dispatch-contributions.mjs.map +1 -0
- package/dist/substrate/runtime/supervisor/errors.d.mts +1 -0
- package/dist/substrate/runtime/supervisor/errors.mjs +9 -0
- package/dist/substrate/runtime/supervisor/errors.mjs.map +1 -0
- package/dist/substrate/runtime/supervisor/index.d.mts +1 -0
- package/dist/substrate/runtime/supervisor/index.mjs +3 -0
- package/dist/substrate/runtime/supervisor/shutdown.mjs +51 -0
- package/dist/substrate/runtime/supervisor/shutdown.mjs.map +1 -0
- package/dist/substrate/runtime/supervisor/start-supervisor.d.mts +1 -0
- package/dist/substrate/runtime/supervisor/start-supervisor.mjs +250 -0
- package/dist/substrate/runtime/supervisor/start-supervisor.mjs.map +1 -0
- package/dist/substrate/runtime/supervisor/state.d.mts +1 -0
- package/dist/substrate/runtime/supervisor/state.mjs +22 -0
- package/dist/substrate/runtime/supervisor/state.mjs.map +1 -0
- package/dist/substrate/runtime/supervisor/teardown.mjs +57 -0
- package/dist/substrate/runtime/supervisor/teardown.mjs.map +1 -0
- package/dist/substrate/runtime/supervisor/types.d.mts +1 -0
- package/dist/substrate/runtime/supervisor/wiring.mjs +133 -0
- package/dist/substrate/runtime/supervisor/wiring.mjs.map +1 -0
- package/dist/substrate/runtime/typed-env.mjs +8 -0
- package/dist/substrate/runtime/typed-env.mjs.map +1 -0
- package/dist/substrate/state-store.d.mts +1 -0
- package/dist/substrate/versioned-doc-schema.mjs +17 -0
- package/dist/substrate/versioned-doc-schema.mjs.map +1 -0
- package/dist/substrate/versioned-doc-sync.mjs +94 -0
- package/dist/substrate/versioned-doc-sync.mjs.map +1 -0
- package/dist/surfaces/cli/command-tree.mjs.map +1 -1
- package/dist/surfaces/cli/commands/index.mjs +9 -0
- package/dist/surfaces/cli/commands/prune-picker-entry.mjs +13 -0
- package/dist/surfaces/cli/commands/prune-picker-entry.mjs.map +1 -0
- package/dist/surfaces/cli/commands/prune-picker.mjs +3 -2
- package/dist/surfaces/cli/commands/prune-picker.mjs.map +1 -1
- package/dist/surfaces/cli/commands/prune.mjs +34 -17
- package/dist/surfaces/cli/commands/prune.mjs.map +1 -1
- package/dist/surfaces/cli/commands/status.mjs +2 -2
- package/dist/surfaces/cli/commands/status.mjs.map +1 -1
- package/dist/surfaces/cli/commands/supervisor-presence.mjs +5 -3
- package/dist/surfaces/cli/commands/supervisor-presence.mjs.map +1 -1
- package/dist/surfaces/cli/commands/wipe.mjs +38 -4
- package/dist/surfaces/cli/commands/wipe.mjs.map +1 -1
- package/dist/surfaces/cli/errors.mjs +1 -1
- package/dist/surfaces/cli/errors.mjs.map +1 -1
- package/dist/surfaces/cli/flags.mjs +0 -1
- package/dist/surfaces/cli/flags.mjs.map +1 -1
- package/dist/surfaces/cli/index.mjs +98 -18
- package/dist/surfaces/cli/index.mjs.map +1 -1
- package/dist/surfaces/cli/output.mjs +1 -0
- package/dist/surfaces/cli/output.mjs.map +1 -1
- package/dist/surfaces/cli/sysexits.mjs +2 -1
- package/dist/surfaces/cli/sysexits.mjs.map +1 -1
- package/dist/surfaces/tui/app.mjs +25 -3
- package/dist/surfaces/tui/app.mjs.map +1 -1
- package/dist/surfaces/tui/display-derivation.mjs +23 -74
- package/dist/surfaces/tui/display-derivation.mjs.map +1 -1
- package/dist/surfaces/tui/event-log.mjs +35 -23
- package/dist/surfaces/tui/event-log.mjs.map +1 -1
- package/dist/surfaces/tui/input.mjs +5 -1
- package/dist/surfaces/tui/input.mjs.map +1 -1
- package/dist/surfaces/tui/plain-renderer.mjs +70 -34
- package/dist/surfaces/tui/plain-renderer.mjs.map +1 -1
- package/package.json +24 -4
- package/dist/contracts/liveness-classifier.d.mts +0 -19
- package/dist/contracts/network-resolver.d.mts +0 -15
- package/dist/contracts/network-resolver.mjs +0 -7
- package/dist/contracts/network-resolver.mjs.map +0 -1
- package/dist/orchestrators/codegen/extras.mjs +0 -16
- package/dist/orchestrators/codegen/extras.mjs.map +0 -1
- package/dist/plugins/deepbook/routable.mjs +0 -21
- package/dist/plugins/deepbook/routable.mjs.map +0 -1
- package/dist/plugins/faucet/service.d.mts +0 -20
- package/dist/plugins/faucet/strategies/sui-local.d.mts +0 -23
- package/dist/plugins/faucet/strategies/sui-local.mjs.map +0 -1
- package/dist/plugins/sui/seed-objects.d.mts +0 -18
- package/dist/plugins/sui/seed-objects.mjs +0 -25
- package/dist/plugins/sui/seed-objects.mjs.map +0 -1
- package/dist/runtime/built-in-plugin-layers.mjs.map +0 -1
- package/dist/substrate/runtime/context-helpers.mjs +0 -32
- package/dist/substrate/runtime/context-helpers.mjs.map +0 -1
- package/dist/substrate/runtime/run.mjs.map +0 -1
- package/dist/substrate/runtime/strategy-registry/faucet-capability-for.mjs +0 -30
- package/dist/substrate/runtime/strategy-registry/faucet-capability-for.mjs.map +0 -1
- package/dist/substrate/runtime/supervisor.d.mts +0 -1
- package/dist/substrate/runtime/supervisor.mjs +0 -831
- package/dist/substrate/runtime/supervisor.mjs.map +0 -1
- package/dist/surfaces/cli/commands/doctor-probes.mjs.map +0 -1
- /package/dist/{substrate/runtime/strategy-registry/faucet-capability-for.d.mts → plugins/faucet/http.d.mts} +0 -0
|
@@ -1,47 +1,7 @@
|
|
|
1
1
|
import { decodeUnknown } from "../../substrate/runtime/runtime-decode.mjs";
|
|
2
|
-
import {
|
|
2
|
+
import { formatUnknownError } from "../../substrate/runtime/format-unknown-error.mjs";
|
|
3
|
+
import { Effect } from "effect";
|
|
3
4
|
//#region src/plugins/sui/chain-probe.ts
|
|
4
|
-
/** Validated subset of `client.core.getObject(...).object`. We
|
|
5
|
-
* narrow to the fields verify probes actually consult — the SDK
|
|
6
|
-
* exposes more (digest, content, json, display) but those are
|
|
7
|
-
* out of scope here. */
|
|
8
|
-
const ObjectOwnerSchema = Schema.Union([
|
|
9
|
-
Schema.Struct({
|
|
10
|
-
$kind: Schema.Literal("AddressOwner"),
|
|
11
|
-
AddressOwner: Schema.String
|
|
12
|
-
}),
|
|
13
|
-
Schema.Struct({
|
|
14
|
-
$kind: Schema.Literal("Shared"),
|
|
15
|
-
Shared: Schema.Struct({ initialSharedVersion: Schema.String })
|
|
16
|
-
}),
|
|
17
|
-
Schema.Struct({
|
|
18
|
-
$kind: Schema.Literal("Immutable"),
|
|
19
|
-
Immutable: Schema.Literal(true)
|
|
20
|
-
}),
|
|
21
|
-
Schema.Struct({
|
|
22
|
-
$kind: Schema.Literal("ConsensusAddressOwner"),
|
|
23
|
-
ConsensusAddressOwner: Schema.Unknown
|
|
24
|
-
}),
|
|
25
|
-
Schema.Struct({
|
|
26
|
-
$kind: Schema.Literal("Parent"),
|
|
27
|
-
Parent: Schema.Unknown
|
|
28
|
-
}),
|
|
29
|
-
Schema.Struct({
|
|
30
|
-
$kind: Schema.Literal("Unknown"),
|
|
31
|
-
Unknown: Schema.Unknown
|
|
32
|
-
})
|
|
33
|
-
]);
|
|
34
|
-
/** Validated SDK response shape: `{ object: { objectId, type, ... } }`.
|
|
35
|
-
* Substrate-redesign note: today's code validates `version` as a
|
|
36
|
-
* string but it's semantically a bigint — branded type recommendation
|
|
37
|
-
* carried in the Opportunities section. */
|
|
38
|
-
const SuiObjectShapeSchema = Schema.Struct({
|
|
39
|
-
objectId: Schema.String,
|
|
40
|
-
type: Schema.String,
|
|
41
|
-
version: Schema.String,
|
|
42
|
-
owner: ObjectOwnerSchema
|
|
43
|
-
});
|
|
44
|
-
Schema.Struct({ object: SuiObjectShapeSchema });
|
|
45
5
|
/** Construct the chain-probe instance for a resolved Sui client +
|
|
46
6
|
* chain id. The result implements the contract's `ChainProbe<Key>`
|
|
47
7
|
* shape; the Sui plugin emits this via a StrategyContributorDecl
|
|
@@ -53,7 +13,7 @@ const makeSuiChainProbe = (sdk, chain) => ({ get: (key, schema, mode) => Effect.
|
|
|
53
13
|
_tag: "ChainProbeError",
|
|
54
14
|
reason: isNotFound(cause) ? "not-found" : "transient",
|
|
55
15
|
chain,
|
|
56
|
-
detail:
|
|
16
|
+
detail: formatUnknownError(cause)
|
|
57
17
|
})
|
|
58
18
|
}).pipe(Effect.catch((err) => mode === "lenient" && (err.reason === "not-found" || err.reason === "transient") ? Effect.succeed(null) : Effect.fail(err)));
|
|
59
19
|
if (raw === null) return null;
|
|
@@ -65,7 +25,7 @@ const makeSuiChainProbe = (sdk, chain) => ({ get: (key, schema, mode) => Effect.
|
|
|
65
25
|
_tag: "ChainProbeError",
|
|
66
26
|
reason: "decode-failed",
|
|
67
27
|
chain,
|
|
68
|
-
detail:
|
|
28
|
+
detail: formatUnknownError(issue.cause ?? issue)
|
|
69
29
|
})
|
|
70
30
|
});
|
|
71
31
|
}) });
|
|
@@ -81,22 +41,32 @@ const projectTransactionPayload = (raw) => {
|
|
|
81
41
|
if (envelope.$kind === "FailedTransaction") return envelope.FailedTransaction ?? null;
|
|
82
42
|
return raw;
|
|
83
43
|
};
|
|
84
|
-
/** Heuristic: SDK errors carrying "not found"
|
|
85
|
-
*
|
|
86
|
-
* transient. The substrate's lenient-retry profile re-runs the
|
|
87
|
-
*
|
|
44
|
+
/** Heuristic: SDK errors carrying object/transaction-shape "not found"
|
|
45
|
+
* markers are treated as terminal not-found; everything else is
|
|
46
|
+
* transient. The substrate's lenient-retry profile re-runs the probe
|
|
47
|
+
* on a transient bucket; not-found is terminal.
|
|
48
|
+
*
|
|
49
|
+
* Limitation: `@mysten/sui` does NOT surface a structured status code
|
|
50
|
+
* on its SDK errors — the substrate only sees an `Error` message. We
|
|
51
|
+
* therefore narrow the substring matches as much as possible to avoid
|
|
52
|
+
* misclassifying network-layer "endpoint does not exist" or generic
|
|
53
|
+
* "not found" prose as terminal:
|
|
54
|
+
*
|
|
55
|
+
* - We require the matched phrase to refer to the OBJECT or
|
|
56
|
+
* TRANSACTION rather than the endpoint. Concretely we look for the
|
|
57
|
+
* SDK's canonical "object not found" / "object does not exist" /
|
|
58
|
+
* "no such object" wording and the equivalent "transaction not
|
|
59
|
+
* found" / "transaction does not exist" wording.
|
|
60
|
+
* - We DO NOT match the bare substring "not found" alone (that
|
|
61
|
+
* catches "endpoint does not exist", DNS prose, etc. — all of
|
|
62
|
+
* which are network-layer transients).
|
|
63
|
+
*
|
|
64
|
+
* If `@mysten/sui` surfaces a structured error class with an
|
|
65
|
+
* `httpStatus` (or equivalent) in the future, swap this for an
|
|
66
|
+
* exact 404 / -32000 check. */
|
|
88
67
|
const isNotFound = (cause) => {
|
|
89
68
|
const msg = cause?.message?.toLowerCase() ?? "";
|
|
90
|
-
return
|
|
91
|
-
};
|
|
92
|
-
const stringifyCause = (cause) => {
|
|
93
|
-
if (cause instanceof Error) return cause.message;
|
|
94
|
-
if (typeof cause === "string") return cause;
|
|
95
|
-
try {
|
|
96
|
-
return JSON.stringify(cause);
|
|
97
|
-
} catch {
|
|
98
|
-
return String(cause);
|
|
99
|
-
}
|
|
69
|
+
return /\bobject\b.*\bnot found\b/u.test(msg) || /\bobject\b.*\bdoes not exist\b/u.test(msg) || /\bno such object\b/u.test(msg) || /\btransaction\b.*\bnot found\b/u.test(msg) || /\btransaction\b.*\bdoes not exist\b/u.test(msg);
|
|
100
70
|
};
|
|
101
71
|
//#endregion
|
|
102
72
|
export { makeSuiChainProbe };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chain-probe.mjs","names":[],"sources":["../../../src/plugins/sui/chain-probe.ts"],"sourcesContent":["// Sui plugin — ChainProbe capability implementation.\n//\n// Architecture §9: ChainProbe is a contract, NOT a primitive. Sui\n// provides the only in-tree implementation; the substrate dispatches\n// to it via the StrategyContributor registry under\n// `chain-probe:<chainId>`.\n//\n// Lenient mode: returns null for both \"not found\" AND transient RPC\n// failure — verify pipelines re-derive on the next cycle rather than\n// fail boot. Strict mode: distinguishes via tagged error.\n//\n// Why lenient is the default in this plugin's wiring: artifact publisher verify is\n// the dominant consumer; artifact publisher's lenient-retry profile (15 attempts,\n// 90s budget) is calibrated against lenient semantics. A strict\n// surface exists for explicit \"I want to know if the chain is\n// reachable\" callers (the doctor command, debugging).\n\nimport { Effect, Schema } from 'effect';\n\nimport type {\n\tChainProbe,\n\tChainProbeError,\n\tChainProbeMode,\n\tChainProbeSchema,\n} from '../../contracts/chain-probe.ts';\nimport { decodeUnknown } from '../../substrate/runtime/runtime-decode.ts';\n\n/**\n * Sui's chain-key shape — discriminated so the probe can dispatch\n * between object reads, tx reads, and the (forthcoming) batch\n * variant on one method.\n */\nexport type SuiProbeKey =\n\t| { readonly kind: 'object'; readonly objectId: string }\n\t| { readonly kind: 'transaction'; readonly digest: string };\n\n/** Validated subset of `client.core.getObject(...).object`. We\n * narrow to the fields verify probes actually consult — the SDK\n * exposes more (digest, content, json, display) but those are\n * out of scope here. */\nconst ObjectOwnerSchema = Schema.Union([\n\tSchema.Struct({\n\t\t$kind: Schema.Literal('AddressOwner'),\n\t\tAddressOwner: Schema.String,\n\t}),\n\tSchema.Struct({\n\t\t$kind: Schema.Literal('Shared'),\n\t\tShared: Schema.Struct({ initialSharedVersion: Schema.String }),\n\t}),\n\tSchema.Struct({\n\t\t$kind: Schema.Literal('Immutable'),\n\t\tImmutable: Schema.Literal(true),\n\t}),\n\tSchema.Struct({\n\t\t$kind: Schema.Literal('ConsensusAddressOwner'),\n\t\tConsensusAddressOwner: Schema.Unknown,\n\t}),\n\tSchema.Struct({\n\t\t$kind: Schema.Literal('Parent'),\n\t\tParent: Schema.Unknown,\n\t}),\n\tSchema.Struct({\n\t\t$kind: Schema.Literal('Unknown'),\n\t\tUnknown: Schema.Unknown,\n\t}),\n]);\n\n/** Validated SDK response shape: `{ object: { objectId, type, ... } }`.\n * Substrate-redesign note: today's code validates `version` as a\n * string but it's semantically a bigint — branded type recommendation\n * carried in the Opportunities section. */\nexport const SuiObjectShapeSchema = Schema.Struct({\n\tobjectId: Schema.String,\n\ttype: Schema.String,\n\tversion: Schema.String,\n\towner: ObjectOwnerSchema,\n});\n\nexport const SuiGetObjectResponseSchema = Schema.Struct({\n\tobject: SuiObjectShapeSchema,\n});\n\n/** Plugin-internal SDK shim — the type the plugin's acquire body\n * hands to the probe factory + the account's sign/execute closure.\n * Kept narrow so we don't pull `@mysten/sui` types into the substrate.\n *\n * Exposes the four surfaces consumers actually use:\n *\n * - `getObject` / `getTransaction` — the lenient chain probe.\n * - `executeTransaction` — the account plugin's submit path\n * (txBytes + caller-signed signatures).\n * - `waitForTransaction` — post-submit finality wait.\n *\n * Plus an OPAQUE `client` field — the underlying `SuiGrpcClient`\n * reference. The package plugin's publish-tx builder hands this to\n * `Transaction.build({ client })` (the SDK resolves gas + object\n * versions through it). We type as `unknown` so the substrate stays\n * free of a direct `@mysten/sui/client` type import; the consumer\n * casts at the boundary (mirrors the same opacity decision in the\n * Coin plugin's `MintSdkShim.client`). */\nexport interface SuiSdkShim {\n\treadonly core: {\n\t\treadonly getObject: (args: {\n\t\t\treadonly objectId: string;\n\t\t\treadonly include?: {\n\t\t\t\treadonly content?: boolean;\n\t\t\t\treadonly json?: boolean;\n\t\t\t};\n\t\t}) => Promise<unknown>;\n\t\treadonly getTransaction: (args: { readonly digest: string }) => Promise<unknown>;\n\t\treadonly getBalance: (args: {\n\t\t\treadonly owner: string;\n\t\t\treadonly coinType?: string;\n\t\t}) => Promise<unknown>;\n\t\treadonly listCoins: (args: {\n\t\t\treadonly owner: string;\n\t\t\treadonly coinType?: string;\n\t\t\treadonly limit?: number;\n\t\t\treadonly cursor?: string | null;\n\t\t}) => Promise<{\n\t\t\treadonly objects: ReadonlyArray<{\n\t\t\t\treadonly objectId: string;\n\t\t\t\treadonly version: string;\n\t\t\t\treadonly digest: string;\n\t\t\t\treadonly balance: string;\n\t\t\t}>;\n\t\t\treadonly hasNextPage: boolean;\n\t\t\treadonly cursor: string | null;\n\t\t}>;\n\t\treadonly executeTransaction: (args: {\n\t\t\treadonly transaction: Uint8Array;\n\t\t\treadonly signatures: ReadonlyArray<string>;\n\t\t\treadonly include?: {\n\t\t\t\treadonly effects?: boolean;\n\t\t\t\treadonly objectTypes?: boolean;\n\t\t\t};\n\t\t}) => Promise<unknown>;\n\t\treadonly waitForTransaction: (args: {\n\t\t\treadonly digest: string;\n\t\t\treadonly timeout?: number;\n\t\t}) => Promise<unknown>;\n\t};\n\t/** Opaque client reference for `Transaction.build({ client })`.\n\t * The Sui barrel wires the resolved `SuiGrpcClient` through; the\n\t * shim layer doesn't type-narrow it (mirrors `MintSdkShim.client`). */\n\treadonly client: unknown;\n}\n\n/** Construct the chain-probe instance for a resolved Sui client +\n * chain id. The result implements the contract's `ChainProbe<Key>`\n * shape; the Sui plugin emits this via a StrategyContributorDecl\n * keyed by `chain-probe:<chainId>`. */\nexport const makeSuiChainProbe = (sdk: SuiSdkShim, chain: string): ChainProbe<SuiProbeKey> => ({\n\tget: <Shape>(\n\t\tkey: SuiProbeKey,\n\t\tschema: ChainProbeSchema<Shape>,\n\t\tmode: ChainProbeMode,\n\t): Effect.Effect<Shape | null, ChainProbeError> =>\n\t\tEffect.gen(function* () {\n\t\t\tconst raw: unknown = yield* Effect.tryPromise({\n\t\t\t\ttry: () =>\n\t\t\t\t\tkey.kind === 'object'\n\t\t\t\t\t\t? sdk.core.getObject({ objectId: key.objectId })\n\t\t\t\t\t\t: sdk.core.getTransaction({ digest: key.digest }),\n\t\t\t\tcatch: (cause): ChainProbeError => ({\n\t\t\t\t\t_tag: 'ChainProbeError',\n\t\t\t\t\treason: isNotFound(cause) ? 'not-found' : 'transient',\n\t\t\t\t\tchain,\n\t\t\t\t\tdetail: stringifyCause(cause),\n\t\t\t\t}),\n\t\t\t}).pipe(\n\t\t\t\t// Lenient mode coerces both not-found and transient into a\n\t\t\t\t// null result. Strict mode lets the error propagate.\n\t\t\t\tEffect.catch(\n\t\t\t\t\t(err): Effect.Effect<unknown, ChainProbeError> =>\n\t\t\t\t\t\tmode === 'lenient' && (err.reason === 'not-found' || err.reason === 'transient')\n\t\t\t\t\t\t\t? Effect.succeed(null)\n\t\t\t\t\t\t\t: Effect.fail(err),\n\t\t\t\t),\n\t\t\t);\n\t\t\tif (raw === null) return null;\n\t\t\tconst payload = projectProbePayload(key, raw);\n\t\t\tif (payload === null) return null;\n\n\t\t\t// Decode against the caller-supplied Schema. A decode failure\n\t\t\t// is structured (NOT silent undefined) — this is the\n\t\t\t// load-bearing learning from deepbook.\n\t\t\tconst decoded = yield* decodeUnknown(schema, payload, {\n\t\t\t\tsource: `chain probe ${chain}`,\n\t\t\t\tmkError: (issue): ChainProbeError => ({\n\t\t\t\t\t_tag: 'ChainProbeError',\n\t\t\t\t\treason: 'decode-failed',\n\t\t\t\t\tchain,\n\t\t\t\t\tdetail: stringifyCause(issue.cause ?? issue),\n\t\t\t\t}),\n\t\t\t});\n\t\t\treturn decoded;\n\t\t}),\n});\n\nconst projectProbePayload = (key: SuiProbeKey, raw: unknown): unknown | null => {\n\tif (key.kind === 'transaction') return projectTransactionPayload(raw);\n\tif (typeof raw !== 'object' || raw === null || !('object' in raw)) return raw;\n\n\treturn (raw as { readonly object?: unknown }).object ?? null;\n};\n\nconst projectTransactionPayload = (raw: unknown): unknown | null => {\n\tif (typeof raw !== 'object' || raw === null) return raw;\n\tconst envelope = raw as {\n\t\treadonly $kind?: 'Transaction' | 'FailedTransaction';\n\t\treadonly Transaction?: unknown;\n\t\treadonly FailedTransaction?: unknown;\n\t};\n\tif (envelope.$kind === 'Transaction') return envelope.Transaction ?? null;\n\tif (envelope.$kind === 'FailedTransaction') return envelope.FailedTransaction ?? null;\n\treturn raw;\n};\n\n/** Heuristic: SDK errors carrying \"not found\" / \"Not exist\" in\n * the message are treated as not-found; everything else is\n * transient. The substrate's lenient-retry profile re-runs the\n * probe on a transient bucket; not-found is terminal. */\nconst isNotFound = (cause: unknown): boolean => {\n\tconst msg = (cause as { message?: string })?.message?.toLowerCase() ?? '';\n\treturn (\n\t\tmsg.includes('not found') ||\n\t\tmsg.includes('does not exist') ||\n\t\tmsg.includes('no such object') ||\n\t\tmsg.includes('not exist')\n\t);\n};\n\nconst stringifyCause = (cause: unknown): string => {\n\tif (cause instanceof Error) return cause.message;\n\tif (typeof cause === 'string') return cause;\n\ttry {\n\t\treturn JSON.stringify(cause);\n\t} catch {\n\t\treturn String(cause);\n\t}\n};\n"],"mappings":";;;;;;;AAwCA,MAAM,oBAAoB,OAAO,MAAM;CACtC,OAAO,OAAO;EACb,OAAO,OAAO,QAAQ,eAAe;EACrC,cAAc,OAAO;EACrB,CAAC;CACF,OAAO,OAAO;EACb,OAAO,OAAO,QAAQ,SAAS;EAC/B,QAAQ,OAAO,OAAO,EAAE,sBAAsB,OAAO,QAAQ,CAAC;EAC9D,CAAC;CACF,OAAO,OAAO;EACb,OAAO,OAAO,QAAQ,YAAY;EAClC,WAAW,OAAO,QAAQ,KAAK;EAC/B,CAAC;CACF,OAAO,OAAO;EACb,OAAO,OAAO,QAAQ,wBAAwB;EAC9C,uBAAuB,OAAO;EAC9B,CAAC;CACF,OAAO,OAAO;EACb,OAAO,OAAO,QAAQ,SAAS;EAC/B,QAAQ,OAAO;EACf,CAAC;CACF,OAAO,OAAO;EACb,OAAO,OAAO,QAAQ,UAAU;EAChC,SAAS,OAAO;EAChB,CAAC;CACF,CAAC;;;;;AAMF,MAAa,uBAAuB,OAAO,OAAO;CACjD,UAAU,OAAO;CACjB,MAAM,OAAO;CACb,SAAS,OAAO;CAChB,OAAO;CACP,CAAC;AAEwC,OAAO,OAAO,EACvD,QAAQ,sBACR,CAAC;;;;;AAwEF,MAAa,qBAAqB,KAAiB,WAA4C,EAC9F,MACC,KACA,QACA,SAEA,OAAO,IAAI,aAAa;CACvB,MAAM,MAAe,OAAO,OAAO,WAAW;EAC7C,WACC,IAAI,SAAS,WACV,IAAI,KAAK,UAAU,EAAE,UAAU,IAAI,UAAU,CAAC,GAC9C,IAAI,KAAK,eAAe,EAAE,QAAQ,IAAI,QAAQ,CAAC;EACnD,QAAQ,WAA4B;GACnC,MAAM;GACN,QAAQ,WAAW,MAAM,GAAG,cAAc;GAC1C;GACA,QAAQ,eAAe,MAAM;GAC7B;EACD,CAAC,CAAC,KAGF,OAAO,OACL,QACA,SAAS,cAAc,IAAI,WAAW,eAAe,IAAI,WAAW,eACjE,OAAO,QAAQ,KAAK,GACpB,OAAO,KAAK,IAAI,CACpB,CACD;AACD,KAAI,QAAQ,KAAM,QAAO;CACzB,MAAM,UAAU,oBAAoB,KAAK,IAAI;AAC7C,KAAI,YAAY,KAAM,QAAO;AAc7B,QAAO,OATgB,cAAc,QAAQ,SAAS;EACrD,QAAQ,eAAe;EACvB,UAAU,WAA4B;GACrC,MAAM;GACN,QAAQ;GACR;GACA,QAAQ,eAAe,MAAM,SAAS,MAAM;GAC5C;EACD,CAAC;EAED,EACH;AAED,MAAM,uBAAuB,KAAkB,QAAiC;AAC/E,KAAI,IAAI,SAAS,cAAe,QAAO,0BAA0B,IAAI;AACrE,KAAI,OAAO,QAAQ,YAAY,QAAQ,QAAQ,EAAE,YAAY,KAAM,QAAO;AAE1E,QAAQ,IAAsC,UAAU;;AAGzD,MAAM,6BAA6B,QAAiC;AACnE,KAAI,OAAO,QAAQ,YAAY,QAAQ,KAAM,QAAO;CACpD,MAAM,WAAW;AAKjB,KAAI,SAAS,UAAU,cAAe,QAAO,SAAS,eAAe;AACrE,KAAI,SAAS,UAAU,oBAAqB,QAAO,SAAS,qBAAqB;AACjF,QAAO;;;;;;AAOR,MAAM,cAAc,UAA4B;CAC/C,MAAM,MAAO,OAAgC,SAAS,aAAa,IAAI;AACvE,QACC,IAAI,SAAS,YAAY,IACzB,IAAI,SAAS,iBAAiB,IAC9B,IAAI,SAAS,iBAAiB,IAC9B,IAAI,SAAS,YAAY;;AAI3B,MAAM,kBAAkB,UAA2B;AAClD,KAAI,iBAAiB,MAAO,QAAO,MAAM;AACzC,KAAI,OAAO,UAAU,SAAU,QAAO;AACtC,KAAI;AACH,SAAO,KAAK,UAAU,MAAM;SACrB;AACP,SAAO,OAAO,MAAM"}
|
|
1
|
+
{"version":3,"file":"chain-probe.mjs","names":[],"sources":["../../../src/plugins/sui/chain-probe.ts"],"sourcesContent":["// Sui plugin — ChainProbe capability implementation.\n//\n// Architecture §9: ChainProbe is a contract, NOT a primitive. Sui\n// provides the only in-tree implementation; the substrate dispatches\n// to it via the StrategyContributor registry under\n// `chain-probe:<chainId>`.\n//\n// Lenient mode: returns null for both \"not found\" AND transient RPC\n// failure — verify pipelines re-derive on the next cycle rather than\n// fail boot. Strict mode: distinguishes via tagged error.\n//\n// Why lenient is the default in this plugin's wiring: artifact publisher verify is\n// the dominant consumer; artifact publisher's lenient-retry profile (15 attempts,\n// 90s budget) is calibrated against lenient semantics. A strict\n// surface exists for explicit \"I want to know if the chain is\n// reachable\" callers (the doctor command, debugging).\n\nimport { Effect } from 'effect';\nimport type { ClientWithCoreApi } from '@mysten/sui/client';\n\nimport type {\n\tChainProbe,\n\tChainProbeError,\n\tChainProbeMode,\n\tChainProbeSchema,\n} from '../../contracts/chain-probe.ts';\nimport { decodeUnknown } from '../../substrate/runtime/runtime-decode.ts';\nimport { formatUnknownError } from '../../substrate/runtime/format-unknown-error.ts';\n\n/**\n * Sui's chain-key shape — discriminated so the probe can dispatch\n * between object reads, tx reads, and the (forthcoming) batch\n * variant on one method.\n */\nexport type SuiProbeKey =\n\t| { readonly kind: 'object'; readonly objectId: string }\n\t| { readonly kind: 'transaction'; readonly digest: string };\n\n// Note: this probe decodes against the CALLER-supplied `schema`\n// argument (see `makeSuiChainProbe`), never a local literal. Earlier\n// revisions also exported `SuiObjectShapeSchema` /\n// `SuiGetObjectResponseSchema` to \"document the SDK shape\", but they\n// had zero consumers (the contract's `ChainProbeSchema<Shape>` is what\n// validates), so per STYLE_GUIDE §5 (no orphan exports) they were\n// removed. Re-add a concrete object schema only if a caller actually\n// decodes through it.\n\n/** Plugin-internal SDK shim — the type the plugin's acquire body\n * hands to the probe factory + the account's sign/execute closure.\n * Kept narrow so we don't pull `@mysten/sui` types into the substrate.\n *\n * Exposes the four surfaces consumers actually use:\n *\n * - `getObject` / `getTransaction` — the lenient chain probe.\n * - `executeTransaction` — the account plugin's submit path\n * (txBytes + caller-signed signatures).\n * - `waitForTransaction` — post-submit finality wait.\n *\n * Plus an OPAQUE `client` field — the underlying `SuiGrpcClient`\n * reference. The package plugin's publish-tx builder hands this to\n * `Transaction.build({ client })` (the SDK resolves gas + object\n * versions through it). We type as `unknown` so the substrate stays\n * free of a direct `@mysten/sui/client` type import; the consumer\n * casts at the boundary (mirrors the same opacity decision in the\n * Coin plugin's `MintSdkShim.client`). */\nexport interface SuiSdkShim {\n\treadonly core: {\n\t\treadonly getObject: (args: {\n\t\t\treadonly objectId: string;\n\t\t\treadonly include?: {\n\t\t\t\treadonly content?: boolean;\n\t\t\t\treadonly json?: boolean;\n\t\t\t};\n\t\t}) => Promise<unknown>;\n\t\treadonly getTransaction: (args: { readonly digest: string }) => Promise<unknown>;\n\t\treadonly getBalance: (args: {\n\t\t\treadonly owner: string;\n\t\t\treadonly coinType?: string;\n\t\t}) => Promise<unknown>;\n\t\treadonly listCoins: (args: {\n\t\t\treadonly owner: string;\n\t\t\treadonly coinType?: string;\n\t\t\treadonly limit?: number;\n\t\t\treadonly cursor?: string | null;\n\t\t}) => Promise<{\n\t\t\treadonly objects: ReadonlyArray<{\n\t\t\t\treadonly objectId: string;\n\t\t\t\treadonly version: string;\n\t\t\t\treadonly digest: string;\n\t\t\t\treadonly balance: string;\n\t\t\t}>;\n\t\t\treadonly hasNextPage: boolean;\n\t\t\treadonly cursor: string | null;\n\t\t}>;\n\t\treadonly executeTransaction: (args: {\n\t\t\treadonly transaction: Uint8Array;\n\t\t\treadonly signatures: ReadonlyArray<string>;\n\t\t\treadonly include?: {\n\t\t\t\treadonly effects?: boolean;\n\t\t\t\treadonly objectTypes?: boolean;\n\t\t\t};\n\t\t}) => Promise<unknown>;\n\t\treadonly waitForTransaction: (args: {\n\t\t\treadonly digest: string;\n\t\t\treadonly timeout?: number;\n\t\t}) => Promise<unknown>;\n\t};\n\t/** Client reference for `Transaction.build({ client })` and every\n\t * `client.core.*` call. The Sui barrel wires the resolved\n\t * `SuiGrpcClient` through; consumers cast no further. */\n\treadonly client: ClientWithCoreApi;\n}\n\n/** Construct the chain-probe instance for a resolved Sui client +\n * chain id. The result implements the contract's `ChainProbe<Key>`\n * shape; the Sui plugin emits this via a StrategyContributorDecl\n * keyed by `chain-probe:<chainId>`. */\nexport const makeSuiChainProbe = (sdk: SuiSdkShim, chain: string): ChainProbe<SuiProbeKey> => ({\n\tget: <Shape>(\n\t\tkey: SuiProbeKey,\n\t\tschema: ChainProbeSchema<Shape>,\n\t\tmode: ChainProbeMode,\n\t): Effect.Effect<Shape | null, ChainProbeError> =>\n\t\tEffect.gen(function* () {\n\t\t\tconst raw: unknown = yield* Effect.tryPromise({\n\t\t\t\ttry: () =>\n\t\t\t\t\tkey.kind === 'object'\n\t\t\t\t\t\t? sdk.core.getObject({ objectId: key.objectId })\n\t\t\t\t\t\t: sdk.core.getTransaction({ digest: key.digest }),\n\t\t\t\tcatch: (cause): ChainProbeError => ({\n\t\t\t\t\t_tag: 'ChainProbeError',\n\t\t\t\t\treason: isNotFound(cause) ? 'not-found' : 'transient',\n\t\t\t\t\tchain,\n\t\t\t\t\tdetail: formatUnknownError(cause),\n\t\t\t\t}),\n\t\t\t}).pipe(\n\t\t\t\t// Lenient mode coerces both not-found and transient into a\n\t\t\t\t// null result. Strict mode lets the error propagate.\n\t\t\t\tEffect.catch(\n\t\t\t\t\t(err): Effect.Effect<unknown, ChainProbeError> =>\n\t\t\t\t\t\tmode === 'lenient' && (err.reason === 'not-found' || err.reason === 'transient')\n\t\t\t\t\t\t\t? Effect.succeed(null)\n\t\t\t\t\t\t\t: Effect.fail(err),\n\t\t\t\t),\n\t\t\t);\n\t\t\tif (raw === null) return null;\n\t\t\tconst payload = projectProbePayload(key, raw);\n\t\t\tif (payload === null) return null;\n\n\t\t\t// Decode against the caller-supplied Schema. A decode failure\n\t\t\t// is structured (NOT silent undefined) — this is the\n\t\t\t// load-bearing learning from deepbook.\n\t\t\tconst decoded = yield* decodeUnknown(schema, payload, {\n\t\t\t\tsource: `chain probe ${chain}`,\n\t\t\t\tmkError: (issue): ChainProbeError => ({\n\t\t\t\t\t_tag: 'ChainProbeError',\n\t\t\t\t\treason: 'decode-failed',\n\t\t\t\t\tchain,\n\t\t\t\t\tdetail: formatUnknownError(issue.cause ?? issue),\n\t\t\t\t}),\n\t\t\t});\n\t\t\treturn decoded;\n\t\t}),\n});\n\nconst projectProbePayload = (key: SuiProbeKey, raw: unknown): unknown | null => {\n\tif (key.kind === 'transaction') return projectTransactionPayload(raw);\n\tif (typeof raw !== 'object' || raw === null || !('object' in raw)) return raw;\n\n\treturn (raw as { readonly object?: unknown }).object ?? null;\n};\n\nconst projectTransactionPayload = (raw: unknown): unknown | null => {\n\tif (typeof raw !== 'object' || raw === null) return raw;\n\tconst envelope = raw as {\n\t\treadonly $kind?: 'Transaction' | 'FailedTransaction';\n\t\treadonly Transaction?: unknown;\n\t\treadonly FailedTransaction?: unknown;\n\t};\n\tif (envelope.$kind === 'Transaction') return envelope.Transaction ?? null;\n\tif (envelope.$kind === 'FailedTransaction') return envelope.FailedTransaction ?? null;\n\treturn raw;\n};\n\n/** Heuristic: SDK errors carrying object/transaction-shape \"not found\"\n * markers are treated as terminal not-found; everything else is\n * transient. The substrate's lenient-retry profile re-runs the probe\n * on a transient bucket; not-found is terminal.\n *\n * Limitation: `@mysten/sui` does NOT surface a structured status code\n * on its SDK errors — the substrate only sees an `Error` message. We\n * therefore narrow the substring matches as much as possible to avoid\n * misclassifying network-layer \"endpoint does not exist\" or generic\n * \"not found\" prose as terminal:\n *\n * - We require the matched phrase to refer to the OBJECT or\n * TRANSACTION rather than the endpoint. Concretely we look for the\n * SDK's canonical \"object not found\" / \"object does not exist\" /\n * \"no such object\" wording and the equivalent \"transaction not\n * found\" / \"transaction does not exist\" wording.\n * - We DO NOT match the bare substring \"not found\" alone (that\n * catches \"endpoint does not exist\", DNS prose, etc. — all of\n * which are network-layer transients).\n *\n * If `@mysten/sui` surfaces a structured error class with an\n * `httpStatus` (or equivalent) in the future, swap this for an\n * exact 404 / -32000 check. */\nconst isNotFound = (cause: unknown): boolean => {\n\tconst msg = (cause as { message?: string })?.message?.toLowerCase() ?? '';\n\treturn (\n\t\t// SDK-side `getObject` / `getTransaction` not-found markers.\n\t\t/\\bobject\\b.*\\bnot found\\b/u.test(msg) ||\n\t\t/\\bobject\\b.*\\bdoes not exist\\b/u.test(msg) ||\n\t\t/\\bno such object\\b/u.test(msg) ||\n\t\t// SDK-side `getTransaction` not-found markers — terminal for\n\t\t// this probe (the queried digest will never materialise).\n\t\t/\\btransaction\\b.*\\bnot found\\b/u.test(msg) ||\n\t\t/\\btransaction\\b.*\\bdoes not exist\\b/u.test(msg)\n\t);\n};\n"],"mappings":";;;;;;;;AAqHA,MAAa,qBAAqB,KAAiB,WAA4C,EAC9F,MACC,KACA,QACA,SAEA,OAAO,IAAI,aAAa;CACvB,MAAM,MAAe,OAAO,OAAO,WAAW;EAC7C,WACC,IAAI,SAAS,WACV,IAAI,KAAK,UAAU,EAAE,UAAU,IAAI,UAAU,CAAC,GAC9C,IAAI,KAAK,eAAe,EAAE,QAAQ,IAAI,QAAQ,CAAC;EACnD,QAAQ,WAA4B;GACnC,MAAM;GACN,QAAQ,WAAW,MAAM,GAAG,cAAc;GAC1C;GACA,QAAQ,mBAAmB,MAAM;GACjC;EACD,CAAC,CAAC,KAGF,OAAO,OACL,QACA,SAAS,cAAc,IAAI,WAAW,eAAe,IAAI,WAAW,eACjE,OAAO,QAAQ,KAAK,GACpB,OAAO,KAAK,IAAI,CACpB,CACD;AACD,KAAI,QAAQ,KAAM,QAAO;CACzB,MAAM,UAAU,oBAAoB,KAAK,IAAI;AAC7C,KAAI,YAAY,KAAM,QAAO;AAc7B,QAAO,OATgB,cAAc,QAAQ,SAAS;EACrD,QAAQ,eAAe;EACvB,UAAU,WAA4B;GACrC,MAAM;GACN,QAAQ;GACR;GACA,QAAQ,mBAAmB,MAAM,SAAS,MAAM;GAChD;EACD,CAAC;EAED,EACH;AAED,MAAM,uBAAuB,KAAkB,QAAiC;AAC/E,KAAI,IAAI,SAAS,cAAe,QAAO,0BAA0B,IAAI;AACrE,KAAI,OAAO,QAAQ,YAAY,QAAQ,QAAQ,EAAE,YAAY,KAAM,QAAO;AAE1E,QAAQ,IAAsC,UAAU;;AAGzD,MAAM,6BAA6B,QAAiC;AACnE,KAAI,OAAO,QAAQ,YAAY,QAAQ,KAAM,QAAO;CACpD,MAAM,WAAW;AAKjB,KAAI,SAAS,UAAU,cAAe,QAAO,SAAS,eAAe;AACrE,KAAI,SAAS,UAAU,oBAAqB,QAAO,SAAS,qBAAqB;AACjF,QAAO;;;;;;;;;;;;;;;;;;;;;;;;;AA0BR,MAAM,cAAc,UAA4B;CAC/C,MAAM,MAAO,OAAgC,SAAS,aAAa,IAAI;AACvE,QAEC,6BAA6B,KAAK,IAAI,IACtC,kCAAkC,KAAK,IAAI,IAC3C,sBAAsB,KAAK,IAAI,IAG/B,kCAAkC,KAAK,IAAI,IAC3C,uCAAuC,KAAK,IAAI"}
|
|
@@ -1,5 +1,26 @@
|
|
|
1
1
|
import { Effect } from "effect";
|
|
2
2
|
//#region src/plugins/sui/codegen.ts
|
|
3
|
+
/** Aggregate projection: fold the emitted `suiNetwork` shape into
|
|
4
|
+
* the cross-plugin `services.ts` aggregate at `services.sui`. The
|
|
5
|
+
* orchestrator stays plugin-name-blind; this projector owns the
|
|
6
|
+
* `{ rpc, faucet, graphql }` shape decision. */
|
|
7
|
+
const projectSuiNetworkServices = (exported) => {
|
|
8
|
+
const network = exported["suiNetwork"];
|
|
9
|
+
if (typeof network !== "object" || network === null) return null;
|
|
10
|
+
const record = network;
|
|
11
|
+
const rpcUrl = stringField(record, "rpcUrl");
|
|
12
|
+
const faucetUrl = stringField(record, "faucetUrl");
|
|
13
|
+
const graphqlUrl = stringField(record, "graphqlUrl");
|
|
14
|
+
return { sui: {
|
|
15
|
+
rpc: { url: rpcUrl ?? "" },
|
|
16
|
+
faucet: faucetUrl === null ? null : { url: faucetUrl },
|
|
17
|
+
graphql: graphqlUrl === null ? null : { url: graphqlUrl }
|
|
18
|
+
} };
|
|
19
|
+
};
|
|
20
|
+
const stringField = (record, key) => {
|
|
21
|
+
const value = record[key];
|
|
22
|
+
return typeof value === "string" && value.length > 0 ? value : null;
|
|
23
|
+
};
|
|
3
24
|
/** Construct the Codegenable contribution. Emit is byte-deterministic
|
|
4
25
|
* on unchanged input (architecture: no mtime churn on no-op
|
|
5
26
|
* cycles). */
|
|
@@ -7,6 +28,11 @@ const makeCodegenable = (resolved) => ({
|
|
|
7
28
|
kind: "codegenable",
|
|
8
29
|
emitterName: "sui-network",
|
|
9
30
|
outputPath: "sui/network.ts",
|
|
31
|
+
aggregate: {
|
|
32
|
+
kind: "sui-network",
|
|
33
|
+
bucket: "services.ts",
|
|
34
|
+
project: projectSuiNetworkServices
|
|
35
|
+
},
|
|
10
36
|
emit: (ctx) => Effect.sync(() => {
|
|
11
37
|
const bindings = {
|
|
12
38
|
chain: resolved.chain,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"codegen.mjs","names":[],"sources":["../../../src/plugins/sui/codegen.ts"],"sourcesContent":["// Sui plugin — Codegenable contribution.\n//\n// Architecture §6: plugins emit typed `CodegenableDecl`s; the\n// codegen orchestrator stages files into the user's source tree\n// WITHOUT naming the plugin. Sui's contribution is network\n// metadata: the active RPC endpoint, the chain id, and (when\n// applicable) the resolved known-package ids.\n//\n// Downstream consumers — chain-aware code (e.g. SDK boots, wallet\n// pickers, frontend RPC selectors) — `import { suiNetwork } from\n// '<staging>/sui/network'`; the generated module owns that exported\n// value's type.\n\nimport { Effect } from 'effect';\n\nimport type { CodegenableDecl } from '../../contracts/codegenable.ts';\nimport type { ResolvedSuiNetwork } from './network-resolver.ts';\n\n/** The typed shape the emitted file exports. */\nexport interface SuiNetworkBindings {\n\treadonly chain: string;\n\treadonly mode: 'local' | 'local-rpc' | 'live' | 'fork';\n\treadonly rpcUrl: string;\n\treadonly faucetUrl: string | null;\n\treadonly graphqlUrl: string | null;\n\t/** Fork-only — upstream identity for known-package lookups. */\n\treadonly forkUpstream: string | null;\n}\n\n/** Construct the Codegenable contribution. Emit is byte-deterministic\n * on unchanged input (architecture: no mtime churn on no-op\n * cycles). */\nexport const makeCodegenable = (resolved: ResolvedSuiNetwork): CodegenableDecl<'sui-network'> => ({\n\tkind: 'codegenable',\n\temitterName: 'sui-network',\n\toutputPath: 'sui/network.ts',\n\temit: (ctx) =>\n\t\tEffect.sync(() => {\n\t\t\tconst bindings: SuiNetworkBindings = {\n\t\t\t\tchain: resolved.chain,\n\t\t\t\tmode: resolved.mode,\n\t\t\t\trpcUrl: resolved.rpc,\n\t\t\t\tfaucetUrl: resolved.faucet ?? null,\n\t\t\t\tgraphqlUrl: resolved.graphql ?? null,\n\t\t\t\tforkUpstream: resolved.forkUpstream ?? null,\n\t\t\t};\n\t\t\tctx.exportConst('suiNetwork', bindings);\n\t\t\treturn ctx.done();\n\t\t}),\n});\n"],"mappings":";;;;;
|
|
1
|
+
{"version":3,"file":"codegen.mjs","names":[],"sources":["../../../src/plugins/sui/codegen.ts"],"sourcesContent":["// Sui plugin — Codegenable contribution.\n//\n// Architecture §6: plugins emit typed `CodegenableDecl`s; the\n// codegen orchestrator stages files into the user's source tree\n// WITHOUT naming the plugin. Sui's contribution is network\n// metadata: the active RPC endpoint, the chain id, and (when\n// applicable) the resolved known-package ids.\n//\n// Downstream consumers — chain-aware code (e.g. SDK boots, wallet\n// pickers, frontend RPC selectors) — `import { suiNetwork } from\n// '<staging>/sui/network'`; the generated module owns that exported\n// value's type.\n\nimport { Effect } from 'effect';\n\nimport type { CodegenableDecl } from '../../contracts/codegenable.ts';\nimport type { ResolvedSuiNetwork } from './network-resolver.ts';\n\n/** The typed shape the emitted file exports. */\nexport interface SuiNetworkBindings {\n\treadonly chain: string;\n\treadonly mode: 'local' | 'local-rpc' | 'live' | 'fork';\n\treadonly rpcUrl: string;\n\treadonly faucetUrl: string | null;\n\treadonly graphqlUrl: string | null;\n\t/** Fork-only — upstream identity for known-package lookups. */\n\treadonly forkUpstream: string | null;\n}\n\n/** Aggregate projection: fold the emitted `suiNetwork` shape into\n * the cross-plugin `services.ts` aggregate at `services.sui`. The\n * orchestrator stays plugin-name-blind; this projector owns the\n * `{ rpc, faucet, graphql }` shape decision. */\nconst projectSuiNetworkServices = (\n\texported: Readonly<Record<string, unknown>>,\n): Readonly<Record<string, unknown>> | null => {\n\tconst network = exported['suiNetwork'];\n\tif (typeof network !== 'object' || network === null) return null;\n\tconst record = network as Readonly<Record<string, unknown>>;\n\tconst rpcUrl = stringField(record, 'rpcUrl');\n\tconst faucetUrl = stringField(record, 'faucetUrl');\n\tconst graphqlUrl = stringField(record, 'graphqlUrl');\n\treturn {\n\t\tsui: {\n\t\t\trpc: { url: rpcUrl ?? '' },\n\t\t\tfaucet: faucetUrl === null ? null : { url: faucetUrl },\n\t\t\tgraphql: graphqlUrl === null ? null : { url: graphqlUrl },\n\t\t},\n\t};\n};\n\nconst stringField = (record: Readonly<Record<string, unknown>>, key: string): string | null => {\n\tconst value = record[key];\n\treturn typeof value === 'string' && value.length > 0 ? value : null;\n};\n\n/** Construct the Codegenable contribution. Emit is byte-deterministic\n * on unchanged input (architecture: no mtime churn on no-op\n * cycles). */\nexport const makeCodegenable = (resolved: ResolvedSuiNetwork): CodegenableDecl<'sui-network'> => ({\n\tkind: 'codegenable',\n\temitterName: 'sui-network',\n\toutputPath: 'sui/network.ts',\n\taggregate: {\n\t\tkind: 'sui-network',\n\t\tbucket: 'services.ts',\n\t\tproject: projectSuiNetworkServices,\n\t},\n\temit: (ctx) =>\n\t\tEffect.sync(() => {\n\t\t\tconst bindings: SuiNetworkBindings = {\n\t\t\t\tchain: resolved.chain,\n\t\t\t\tmode: resolved.mode,\n\t\t\t\trpcUrl: resolved.rpc,\n\t\t\t\tfaucetUrl: resolved.faucet ?? null,\n\t\t\t\tgraphqlUrl: resolved.graphql ?? null,\n\t\t\t\tforkUpstream: resolved.forkUpstream ?? null,\n\t\t\t};\n\t\t\tctx.exportConst('suiNetwork', bindings);\n\t\t\treturn ctx.done();\n\t\t}),\n});\n"],"mappings":";;;;;;AAiCA,MAAM,6BACL,aAC8C;CAC9C,MAAM,UAAU,SAAS;AACzB,KAAI,OAAO,YAAY,YAAY,YAAY,KAAM,QAAO;CAC5D,MAAM,SAAS;CACf,MAAM,SAAS,YAAY,QAAQ,SAAS;CAC5C,MAAM,YAAY,YAAY,QAAQ,YAAY;CAClD,MAAM,aAAa,YAAY,QAAQ,aAAa;AACpD,QAAO,EACN,KAAK;EACJ,KAAK,EAAE,KAAK,UAAU,IAAI;EAC1B,QAAQ,cAAc,OAAO,OAAO,EAAE,KAAK,WAAW;EACtD,SAAS,eAAe,OAAO,OAAO,EAAE,KAAK,YAAY;EACzD,EACD;;AAGF,MAAM,eAAe,QAA2C,QAA+B;CAC9F,MAAM,QAAQ,OAAO;AACrB,QAAO,OAAO,UAAU,YAAY,MAAM,SAAS,IAAI,QAAQ;;;;;AAMhE,MAAa,mBAAmB,cAAkE;CACjG,MAAM;CACN,aAAa;CACb,YAAY;CACZ,WAAW;EACV,MAAM;EACN,QAAQ;EACR,SAAS;EACT;CACD,OAAO,QACN,OAAO,WAAW;EACjB,MAAM,WAA+B;GACpC,OAAO,SAAS;GAChB,MAAM,SAAS;GACf,QAAQ,SAAS;GACjB,WAAW,SAAS,UAAU;GAC9B,YAAY,SAAS,WAAW;GAChC,cAAc,SAAS,gBAAgB;GACvC;AACD,MAAI,YAAY,cAAc,SAAS;AACvC,SAAO,IAAI,MAAM;GAChB;CACH"}
|
|
@@ -40,35 +40,8 @@ interface ForkUnsupportedError {
|
|
|
40
40
|
readonly surface: string;
|
|
41
41
|
readonly hint: string;
|
|
42
42
|
}
|
|
43
|
-
/** Raised when fork meta-config drifts between supervisor boots.
|
|
44
|
-
* Carries previous + current snapshots so the doctor / TUI can
|
|
45
|
-
* diff them. Consumed inside Sui's fork acquire — does NOT cross
|
|
46
|
-
* plugin boundaries (the recipe is "wipe and re-apply"). */
|
|
47
|
-
interface SeedManifestMismatchError {
|
|
48
|
-
readonly _tag: 'SeedManifestMismatchError';
|
|
49
|
-
readonly previous: {
|
|
50
|
-
readonly upstream: string;
|
|
51
|
-
readonly checkpoint?: string;
|
|
52
|
-
readonly configHash: string;
|
|
53
|
-
};
|
|
54
|
-
readonly current: {
|
|
55
|
-
readonly upstream: string;
|
|
56
|
-
readonly checkpoint?: string;
|
|
57
|
-
readonly configHash: string;
|
|
58
|
-
};
|
|
59
|
-
readonly hint: string;
|
|
60
|
-
}
|
|
61
|
-
/** Raised when the funds-ready gate times out against a real
|
|
62
|
-
* faucet. Plugin-internal — Sui contributes this strategy and
|
|
63
|
-
* consumes its own error. */
|
|
64
|
-
interface SuiFundsReadyError {
|
|
65
|
-
readonly _tag: 'SuiFundsReadyError';
|
|
66
|
-
readonly attempts: number;
|
|
67
|
-
readonly lastBody?: string;
|
|
68
|
-
readonly hint: string;
|
|
69
|
-
}
|
|
70
43
|
/** Union of every error a Sui-plugin caller may encounter. */
|
|
71
|
-
type SuiError = SuiPluginError | SuiCliError | SuiConfigError | ForkUnsupportedError
|
|
44
|
+
type SuiError = SuiPluginError | SuiCliError | SuiConfigError | ForkUnsupportedError;
|
|
72
45
|
//#endregion
|
|
73
|
-
export { ForkUnsupportedError,
|
|
46
|
+
export { ForkUnsupportedError, SuiCliError, SuiConfigError, SuiError, SuiPluginError };
|
|
74
47
|
//# sourceMappingURL=errors.d.mts.map
|
|
@@ -18,9 +18,7 @@ const SUI_ERROR_TAGS = [
|
|
|
18
18
|
"SuiPluginError",
|
|
19
19
|
"SuiCliError",
|
|
20
20
|
"SuiConfigError",
|
|
21
|
-
"ForkUnsupportedError"
|
|
22
|
-
"SeedManifestMismatchError",
|
|
23
|
-
"SuiFundsReadyError"
|
|
21
|
+
"ForkUnsupportedError"
|
|
24
22
|
];
|
|
25
23
|
//#endregion
|
|
26
24
|
export { SUI_ERROR_TAGS, forkUnsupportedError, suiConfigError, suiPluginError };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.mjs","names":[],"sources":["../../../src/plugins/sui/errors.ts"],"sourcesContent":["// Sui plugin — typed errors.\n//\n// Distilled-doc finding: today's codebase centralises EVERY tagged\n// error in one engine file, but consumer boundaries cross service\n// lines. The architecture lets us redistribute: errors raised AND\n// consumed inside the Sui plugin live here. Cross-service errors\n// (`ForkIncompatibleError
|
|
1
|
+
{"version":3,"file":"errors.mjs","names":[],"sources":["../../../src/plugins/sui/errors.ts"],"sourcesContent":["// Sui plugin — typed errors.\n//\n// Distilled-doc finding: today's codebase centralises EVERY tagged\n// error in one engine file, but consumer boundaries cross service\n// lines. The architecture lets us redistribute: errors raised AND\n// consumed inside the Sui plugin live here. Cross-service errors\n// (`ForkIncompatibleError`) live with the plugin that consumes them\n// — Walrus/Seal/Deepbook own `ForkIncompatibleError`.\n//\n// Effect v4: errors are plain interfaces with a `_tag` discriminator\n// — we don't subclass an Effect base class; `Effect.catchTag` /\n// `catchTags` match on `_tag` literal. See architecture § Effect.\n\nimport { defineConfigError, type ConfigIssue } from '../../substrate/runtime/config-validation.ts';\n\n/** Phases for `SuiError`. Closed sum — keeps the cause-walker's\n * display table small. Add a phase only after editing the\n * catalog in the plugin doc. */\nexport type SuiPhase =\n\t| 'image-build'\n\t| 'port-allocate'\n\t| 'container-start'\n\t| 'rpc-probe'\n\t| 'faucet-probe'\n\t| 'graphql-probe'\n\t| 'fork-status-probe'\n\t| 'chain-id-fetch'\n\t| 'wait-funds-ready'\n\t| 'fork-impersonate'\n\t| 'fork-advance-clock'\n\t| 'fork-advance-checkpoint'\n\t| 'fork-lock'\n\t| 'fork-data-dir'\n\t| 'move-build'\n\t| 'move-publish';\n\n/** Generic Sui plugin error. Raised by the plugin's acquire body\n * and its admin surface (`advanceClock`, `impersonate`, …). */\nexport interface SuiPluginError {\n\treadonly _tag: 'SuiPluginError';\n\treadonly phase: SuiPhase;\n\treadonly message: string;\n\treadonly cause?: unknown;\n}\n\nexport const suiPluginError = (\n\tphase: SuiPhase,\n\tmessage: string,\n\tcause?: unknown,\n): SuiPluginError => ({ _tag: 'SuiPluginError', phase, message, cause });\n\nexport interface SuiConfigError extends ConfigIssue {\n\treadonly _tag: 'SuiConfigError';\n}\n\nexport const suiConfigError = defineConfigError('SuiConfigError');\n\n/** Move-build / sui-cli error. Carries the sub-process capture\n * envelope (exit + stderr + stdout). The plugin doc lists 11\n * shell-shaped phases today; we tighten to a much smaller set\n * and use `op` as a free-form column.\n *\n * Stub: the closed-vs-open phase decision is deferred to the\n * cli-driver implementation pass. */\nexport interface SuiCliError {\n\treadonly _tag: 'SuiCliError';\n\treadonly op: 'build' | 'publish' | 'summary' | 'scrub' | 'spawn';\n\treadonly exitCode?: number;\n\treadonly stderr?: string;\n\treadonly stdout?: string;\n\treadonly cause?: unknown;\n}\n\nexport const suiCliError = (\n\top: SuiCliError['op'],\n\tparts: Omit<SuiCliError, '_tag' | 'op'>,\n): SuiCliError => ({ _tag: 'SuiCliError', op, ...parts });\n\n/** Synchronous refusal raised by the fork SDK guard. The guard\n * intercepts at property-access time so the wire call never\n * happens — failing fast lets callers branch on this without\n * awaiting a transport-level reject. */\nexport interface ForkUnsupportedError {\n\treadonly _tag: 'ForkUnsupportedError';\n\treadonly surface: string;\n\treadonly hint: string;\n}\n\nexport const forkUnsupportedError = (surface: string, hint: string): ForkUnsupportedError => ({\n\t_tag: 'ForkUnsupportedError',\n\tsurface,\n\thint,\n});\n\n/** Union of every error a Sui-plugin caller may encounter. */\nexport type SuiError =\n\t| SuiPluginError\n\t| SuiCliError\n\t| SuiConfigError\n\t| ForkUnsupportedError;\n\n/** Error tags this plugin contributes — surfaced to the cause\n * walker via `PluginErrorContribution`. */\nexport const SUI_ERROR_TAGS: ReadonlyArray<SuiError['_tag']> = [\n\t'SuiPluginError',\n\t'SuiCliError',\n\t'SuiConfigError',\n\t'ForkUnsupportedError',\n] as const;\n"],"mappings":";;AA6CA,MAAa,kBACZ,OACA,SACA,WACqB;CAAE,MAAM;CAAkB;CAAO;CAAS;CAAO;AAMvE,MAAa,iBAAiB,kBAAkB,iBAAiB;AAiCjE,MAAa,wBAAwB,SAAiB,UAAwC;CAC7F,MAAM;CACN;CACA;CACA;;;AAWD,MAAa,iBAAkD;CAC9D;CACA;CACA;CACA;CACA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { };
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { leaseKey } from "../../substrate/runtime/lease-broker/service.mjs";
|
|
2
|
+
import "../../substrate/runtime/lease-broker/index.mjs";
|
|
3
|
+
import { formatUnknownError } from "../../substrate/runtime/format-unknown-error.mjs";
|
|
4
|
+
import { SuiSpans } from "./spans.mjs";
|
|
5
|
+
import { FORK_IMPERSONATION_GAS_BUDGET, buildForkImpersonationTransactionBytes, selectSufficientForkCoin } from "./fork-transaction.mjs";
|
|
6
|
+
import { faucetBodyError } from "../faucet/errors.mjs";
|
|
7
|
+
import "../faucet/index.mjs";
|
|
8
|
+
import { Effect } from "effect";
|
|
9
|
+
import { Transaction } from "@mysten/sui/transactions";
|
|
10
|
+
//#region src/plugins/sui/fork-faucet-strategy.ts
|
|
11
|
+
const sentinelUrl = (whale) => `fork-impersonation://${whale}`;
|
|
12
|
+
const bodyError = (whale, address, amount, message) => faucetBodyError({
|
|
13
|
+
url: sentinelUrl(whale),
|
|
14
|
+
address,
|
|
15
|
+
amount,
|
|
16
|
+
status: 0,
|
|
17
|
+
reason: "failure-status",
|
|
18
|
+
message
|
|
19
|
+
});
|
|
20
|
+
const withSerialization = (serialization, effect) => {
|
|
21
|
+
if (serialization === void 0) return effect;
|
|
22
|
+
return Effect.scoped(Effect.gen(function* () {
|
|
23
|
+
yield* serialization.broker.acquire(leaseKey(serialization.key), serialization.owner);
|
|
24
|
+
yield* effect;
|
|
25
|
+
})).pipe(Effect.withSpan("devstack.plugin.sui.forkFaucet.serializedRequest", { attributes: {
|
|
26
|
+
[SuiSpans.localFaucetLeaseKey]: serialization.key,
|
|
27
|
+
[SuiSpans.localFaucetLeaseOwner]: serialization.owner
|
|
28
|
+
} }));
|
|
29
|
+
};
|
|
30
|
+
/** Build a SUI fork-faucet strategy that funds via whale impersonation. */
|
|
31
|
+
const suiForkFaucetStrategy = (opts) => ({ request: ({ address, amount }) => {
|
|
32
|
+
const gasClient = opts.sdk.core;
|
|
33
|
+
const mapErr = (cause) => bodyError(opts.whale, address, amount, `sui fork faucet: ${cause.message}`);
|
|
34
|
+
const transfer = Effect.gen(function* () {
|
|
35
|
+
if (amount <= 0n) return;
|
|
36
|
+
if (amount > opts.perRequestCapMist) return yield* Effect.fail(bodyError(opts.whale, address, amount, `sui fork faucet: requested ${amount} MIST exceeds the per-request cap ${opts.perRequestCapMist} MIST (whale ${opts.whale}).`));
|
|
37
|
+
const { coin } = yield* selectSufficientForkCoin(gasClient, opts.whale, amount + FORK_IMPERSONATION_GAS_BUDGET).pipe(Effect.mapError(mapErr));
|
|
38
|
+
const tx = new Transaction();
|
|
39
|
+
tx.setSender(opts.whale);
|
|
40
|
+
const [funded] = tx.splitCoins(tx.gas, [tx.pure.u64(amount)]);
|
|
41
|
+
tx.transferObjects([funded], address);
|
|
42
|
+
const bytes = yield* buildForkImpersonationTransactionBytes(tx, opts.whale, gasClient, coin).pipe(Effect.mapError(mapErr));
|
|
43
|
+
const submitted = yield* opts.fork.impersonate(opts.whale, bytes).pipe(Effect.mapError(mapErr));
|
|
44
|
+
if (!submitted.success) return yield* Effect.fail(bodyError(opts.whale, address, amount, `sui fork faucet: impersonation tx ${submitted.digest} failed on-chain.`));
|
|
45
|
+
yield* Effect.tryPromise({
|
|
46
|
+
try: () => opts.sdk.core.waitForTransaction({ digest: submitted.digest }),
|
|
47
|
+
catch: (cause) => bodyError(opts.whale, address, amount, `sui fork faucet: waitForTransaction(${submitted.digest}) failed: ${formatUnknownError(cause)}`)
|
|
48
|
+
});
|
|
49
|
+
});
|
|
50
|
+
return withSerialization(opts.serialization, transfer).pipe(Effect.withSpan("devstack.plugin.sui.forkFaucet.request", { attributes: { [SuiSpans.forkFaucetWhale]: opts.whale } }));
|
|
51
|
+
} });
|
|
52
|
+
//#endregion
|
|
53
|
+
export { suiForkFaucetStrategy };
|
|
54
|
+
|
|
55
|
+
//# sourceMappingURL=fork-faucet-strategy.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fork-faucet-strategy.mjs","names":[],"sources":["../../../src/plugins/sui/fork-faucet-strategy.ts"],"sourcesContent":["// SUI fork-faucet strategy — impersonation-based funding.\n//\n// Fork networks have no real faucet. This strategy funds a recipient by\n// IMPERSONATING a large-reserve \"whale\" address on the forked upstream\n// and transferring SUI from it: it builds `splitCoins(tx.gas, [amount])`\n// + `transferObjects([coin], recipient)` with the whale as sender, runs\n// it through the SAME impersonation path the package/action plugins use\n// (`buildForkImpersonationTransactionBytes` -> `fork.impersonate`, with\n// empty signatures), and waits for finality.\n//\n// It is registered into the `faucet:request:<chainId>` strategy registry\n// from `sui/index.ts` exactly like the local-faucet HTTP strategy, so\n// ephemeral-account auto-funding and cross-cutting SUI funding \"just\n// work\" in fork mode. (Dependency direction faucet <- sui: the sui\n// plugin imports the faucet contract/error types, never the reverse.)\n//\n// Error channel: account funding only catches FaucetUnreachable |\n// FaucetExhausted | FaucetBodyError (see account/funding.ts). The\n// impersonation path fails with SuiPluginError, so every internal\n// failure is mapped to FaucetBodyError here — otherwise it would escape\n// funding's `catchTags` and surface as an unhandled error.\n//\n// Concurrency: every request selects one sufficient whale SUI coin as\n// both gas payment and split source. Concurrent requests would race the\n// same coin version, so requests serialize on a chain-scoped lease.\n\nimport { Effect } from 'effect';\n\nimport { Transaction } from '@mysten/sui/transactions';\n\nimport { formatUnknownError } from '../../substrate/runtime/format-unknown-error.ts';\nimport { leaseKey, type LeaseBroker } from '../../substrate/runtime/lease-broker/index.ts';\nimport { faucetBodyError, type FaucetBodyError, type FaucetStrategy } from '../faucet/index.ts';\n\nimport type { SuiSdkShim } from './chain-probe.ts';\nimport type { SuiPluginError } from './errors.ts';\nimport {\n\tFORK_IMPERSONATION_GAS_BUDGET,\n\tbuildForkImpersonationTransactionBytes,\n\tselectSufficientForkCoin,\n\ttype ForkImpersonationGasClient,\n} from './fork-transaction.ts';\nimport type { ForkAdminSurface } from './mode/shared.ts';\nimport { SuiSpans } from './spans.ts';\n\n/** Serialization for the shared whale funding coin (mirrors\n * `SuiLocalFaucetSerialization` in `local-faucet-strategy.ts`). */\nexport interface SuiForkFaucetSerialization {\n\treadonly broker: LeaseBroker;\n\treadonly key: string;\n\treadonly owner: string;\n}\n\nexport interface SuiForkFaucetStrategyOptions {\n\t/** Address impersonated as the funding source. Must hold a large SUI\n\t * coin in the fork (auto-seeded + validated at boot). */\n\treadonly whale: string;\n\t/** Fork admin surface (`client.fork`) — submits the impersonation tx. */\n\treadonly fork: ForkAdminSurface;\n\t/** SDK shim (`client.sdk`) — `.core` selects the whale gas coin and\n\t * waits for finality. */\n\treadonly sdk: SuiSdkShim;\n\t/** Upper bound per request (MIST). Requests above this are rejected. */\n\treadonly perRequestCapMist: bigint;\n\t/** Serialize requests so concurrent funds don't race the whale coin. */\n\treadonly serialization?: SuiForkFaucetSerialization;\n}\n\nconst sentinelUrl = (whale: string): string => `fork-impersonation://${whale}`;\n\nconst bodyError = (\n\twhale: string,\n\taddress: string,\n\tamount: bigint,\n\tmessage: string,\n): FaucetBodyError =>\n\tfaucetBodyError({\n\t\turl: sentinelUrl(whale),\n\t\taddress,\n\t\tamount,\n\t\tstatus: 0,\n\t\treason: 'failure-status',\n\t\tmessage,\n\t});\n\nconst withSerialization = (\n\tserialization: SuiForkFaucetSerialization | undefined,\n\teffect: Effect.Effect<void, FaucetBodyError>,\n): Effect.Effect<void, FaucetBodyError> => {\n\tif (serialization === undefined) {\n\t\treturn effect;\n\t}\n\treturn Effect.scoped(\n\t\tEffect.gen(function* () {\n\t\t\tyield* serialization.broker.acquire(leaseKey(serialization.key), serialization.owner);\n\t\t\tyield* effect;\n\t\t}),\n\t).pipe(\n\t\tEffect.withSpan('devstack.plugin.sui.forkFaucet.serializedRequest', {\n\t\t\tattributes: {\n\t\t\t\t[SuiSpans.localFaucetLeaseKey]: serialization.key,\n\t\t\t\t[SuiSpans.localFaucetLeaseOwner]: serialization.owner,\n\t\t\t},\n\t\t}),\n\t);\n};\n\n/** Build a SUI fork-faucet strategy that funds via whale impersonation. */\nexport const suiForkFaucetStrategy = (opts: SuiForkFaucetStrategyOptions): FaucetStrategy => ({\n\trequest: ({ address, amount }) => {\n\t\tconst gasClient: ForkImpersonationGasClient = opts.sdk.core;\n\t\t// Internal SuiPluginError -> FaucetBodyError so account funding's\n\t\t// catchTags handle it; carry the actionable root message through.\n\t\tconst mapErr = (cause: SuiPluginError): FaucetBodyError =>\n\t\t\tbodyError(opts.whale, address, amount, `sui fork faucet: ${cause.message}`);\n\n\t\tconst transfer = Effect.gen(function* () {\n\t\t\tif (amount <= 0n) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (amount > opts.perRequestCapMist) {\n\t\t\t\treturn yield* Effect.fail(\n\t\t\t\t\tbodyError(\n\t\t\t\t\t\topts.whale,\n\t\t\t\t\t\taddress,\n\t\t\t\t\t\tamount,\n\t\t\t\t\t\t`sui fork faucet: requested ${amount} MIST exceeds the per-request cap ` +\n\t\t\t\t\t\t\t`${opts.perRequestCapMist} MIST (whale ${opts.whale}).`,\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t}\n\n\t\t\t// A sufficient whale SUI coin (first past any dust) pays gas AND sources the split, so\n\t\t\t// it must cover amount + the impersonation gas budget.\n\t\t\tconst { coin } = yield* selectSufficientForkCoin(\n\t\t\t\tgasClient,\n\t\t\t\topts.whale,\n\t\t\t\tamount + FORK_IMPERSONATION_GAS_BUDGET,\n\t\t\t).pipe(Effect.mapError(mapErr));\n\n\t\t\tconst tx = new Transaction();\n\t\t\ttx.setSender(opts.whale);\n\t\t\tconst [funded] = tx.splitCoins(tx.gas, [tx.pure.u64(amount)]);\n\t\t\ttx.transferObjects([funded], address);\n\n\t\t\tconst bytes = yield* buildForkImpersonationTransactionBytes(\n\t\t\t\ttx,\n\t\t\t\topts.whale,\n\t\t\t\tgasClient,\n\t\t\t\tcoin,\n\t\t\t).pipe(Effect.mapError(mapErr));\n\n\t\t\tconst submitted = yield* opts.fork\n\t\t\t\t.impersonate(opts.whale, bytes)\n\t\t\t\t.pipe(Effect.mapError(mapErr));\n\t\t\tif (!submitted.success) {\n\t\t\t\treturn yield* Effect.fail(\n\t\t\t\t\tbodyError(\n\t\t\t\t\t\topts.whale,\n\t\t\t\t\t\taddress,\n\t\t\t\t\t\tamount,\n\t\t\t\t\t\t`sui fork faucet: impersonation tx ${submitted.digest} failed on-chain.`,\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tyield* Effect.tryPromise({\n\t\t\t\ttry: () => opts.sdk.core.waitForTransaction({ digest: submitted.digest }),\n\t\t\t\tcatch: (cause): FaucetBodyError =>\n\t\t\t\t\tbodyError(\n\t\t\t\t\t\topts.whale,\n\t\t\t\t\t\taddress,\n\t\t\t\t\t\tamount,\n\t\t\t\t\t\t`sui fork faucet: waitForTransaction(${submitted.digest}) failed: ${formatUnknownError(cause)}`,\n\t\t\t\t\t),\n\t\t\t});\n\t\t});\n\n\t\treturn withSerialization(opts.serialization, transfer).pipe(\n\t\t\tEffect.withSpan('devstack.plugin.sui.forkFaucet.request', {\n\t\t\t\tattributes: { [SuiSpans.forkFaucetWhale]: opts.whale },\n\t\t\t}),\n\t\t);\n\t},\n});\n"],"mappings":";;;;;;;;;;AAoEA,MAAM,eAAe,UAA0B,wBAAwB;AAEvE,MAAM,aACL,OACA,SACA,QACA,YAEA,gBAAgB;CACf,KAAK,YAAY,MAAM;CACvB;CACA;CACA,QAAQ;CACR,QAAQ;CACR;CACA,CAAC;AAEH,MAAM,qBACL,eACA,WAC0C;AAC1C,KAAI,kBAAkB,KAAA,EACrB,QAAO;AAER,QAAO,OAAO,OACb,OAAO,IAAI,aAAa;AACvB,SAAO,cAAc,OAAO,QAAQ,SAAS,cAAc,IAAI,EAAE,cAAc,MAAM;AACrF,SAAO;GACN,CACF,CAAC,KACD,OAAO,SAAS,oDAAoD,EACnE,YAAY;GACV,SAAS,sBAAsB,cAAc;GAC7C,SAAS,wBAAwB,cAAc;EAChD,EACD,CAAC,CACF;;;AAIF,MAAa,yBAAyB,UAAwD,EAC7F,UAAU,EAAE,SAAS,aAAa;CACjC,MAAM,YAAwC,KAAK,IAAI;CAGvD,MAAM,UAAU,UACf,UAAU,KAAK,OAAO,SAAS,QAAQ,oBAAoB,MAAM,UAAU;CAE5E,MAAM,WAAW,OAAO,IAAI,aAAa;AACxC,MAAI,UAAU,GACb;AAED,MAAI,SAAS,KAAK,kBACjB,QAAO,OAAO,OAAO,KACpB,UACC,KAAK,OACL,SACA,QACA,8BAA8B,OAAO,oCACjC,KAAK,kBAAkB,eAAe,KAAK,MAAM,IACrD,CACD;EAKF,MAAM,EAAE,SAAS,OAAO,yBACvB,WACA,KAAK,OACL,SAAS,8BACT,CAAC,KAAK,OAAO,SAAS,OAAO,CAAC;EAE/B,MAAM,KAAK,IAAI,aAAa;AAC5B,KAAG,UAAU,KAAK,MAAM;EACxB,MAAM,CAAC,UAAU,GAAG,WAAW,GAAG,KAAK,CAAC,GAAG,KAAK,IAAI,OAAO,CAAC,CAAC;AAC7D,KAAG,gBAAgB,CAAC,OAAO,EAAE,QAAQ;EAErC,MAAM,QAAQ,OAAO,uCACpB,IACA,KAAK,OACL,WACA,KACA,CAAC,KAAK,OAAO,SAAS,OAAO,CAAC;EAE/B,MAAM,YAAY,OAAO,KAAK,KAC5B,YAAY,KAAK,OAAO,MAAM,CAC9B,KAAK,OAAO,SAAS,OAAO,CAAC;AAC/B,MAAI,CAAC,UAAU,QACd,QAAO,OAAO,OAAO,KACpB,UACC,KAAK,OACL,SACA,QACA,qCAAqC,UAAU,OAAO,mBACtD,CACD;AAGF,SAAO,OAAO,WAAW;GACxB,WAAW,KAAK,IAAI,KAAK,mBAAmB,EAAE,QAAQ,UAAU,QAAQ,CAAC;GACzE,QAAQ,UACP,UACC,KAAK,OACL,SACA,QACA,uCAAuC,UAAU,OAAO,YAAY,mBAAmB,MAAM,GAC7F;GACF,CAAC;GACD;AAEF,QAAO,kBAAkB,KAAK,eAAe,SAAS,CAAC,KACtD,OAAO,SAAS,0CAA0C,EACzD,YAAY,GAAG,SAAS,kBAAkB,KAAK,OAAO,EACtD,CAAC,CACF;GAEF"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import { Effect, Scope } from "effect";
|
|
@@ -1,5 +1,170 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { SpanAttr } from "../../substrate/runtime/observability/spans.mjs";
|
|
2
|
+
import { selfPid } from "../../substrate/runtime/cross-process/self-pid.mjs";
|
|
3
|
+
import { atomicWriteJsonSync } from "../../substrate/runtime/atomic-write.mjs";
|
|
4
|
+
import { parseVersionedDocumentBodyOrNull } from "../../substrate/versioned-doc-sync.mjs";
|
|
5
|
+
import { isPidAlive, processStartTime } from "../../substrate/runtime/cross-process/liveness.mjs";
|
|
6
|
+
import { acquireStackLock } from "../../substrate/runtime/cross-process/stack-lock.mjs";
|
|
7
|
+
import { mintRandomSuffix } from "../../substrate/runtime/random-suffix.mjs";
|
|
8
|
+
import { forkUnsupportedError, suiPluginError } from "./errors.mjs";
|
|
9
|
+
import "../../substrate/runtime/cross-process/index.mjs";
|
|
10
|
+
import { Effect, Schedule, Schema } from "effect";
|
|
11
|
+
import { readFileSync, unlinkSync } from "node:fs";
|
|
12
|
+
import { join } from "node:path";
|
|
13
|
+
import { hostname } from "node:os";
|
|
2
14
|
//#region src/plugins/sui/fork-orchestration.ts
|
|
15
|
+
/** Heartbeat cadence — refresh `startedAt` every 10s. Matches the
|
|
16
|
+
* roster's `heartbeatIntervalMillis`. The heartbeat keeps the holder's
|
|
17
|
+
* `startedAt`/`startTime` fresh for diagnostics and so a peer that DOES
|
|
18
|
+
* later add a foreign-host liveness signal has recent data; with the
|
|
19
|
+
* current conservative foreign-host policy (always-alive) it is not a
|
|
20
|
+
* reclaim gate, mirroring the roster heartbeat fiber. */
|
|
21
|
+
const FORK_HOLDER_HEARTBEAT_INTERVAL_MILLIS = 1e4;
|
|
22
|
+
/** Brief acquire timeout for the holder critical section. The OS lock
|
|
23
|
+
* is held only across a read → liveness-check → write, never across
|
|
24
|
+
* I/O — a tight budget keeps peers reacting quickly to a release. */
|
|
25
|
+
const FORK_HOLDER_LOCK_TIMEOUT_MILLIS = 5e3;
|
|
26
|
+
const ForkLockHolderSchema = Schema.Struct({
|
|
27
|
+
pid: Schema.Number,
|
|
28
|
+
host: Schema.String,
|
|
29
|
+
instanceId: Schema.String,
|
|
30
|
+
startedAt: Schema.Number,
|
|
31
|
+
startTime: Schema.NullOr(Schema.Number)
|
|
32
|
+
});
|
|
33
|
+
/** Holder file lives inside the data dir so it travels with the dir's
|
|
34
|
+
* lifecycle (wipe removes it). */
|
|
35
|
+
const forkHolderPath = (dataDir) => join(dataDir, "holder.json");
|
|
36
|
+
/** Is an existing holder alive? Mirrors `liveness.checkHolderLiveness`
|
|
37
|
+
* exactly (the `RosterHolder` shape doesn't fit — that carries
|
|
38
|
+
* `hostname`/`heartbeatAt`, not our `host`/`startedAt` — so we
|
|
39
|
+
* replicate its logic against the `ForkLockHolder` fields):
|
|
40
|
+
*
|
|
41
|
+
* - Foreign-host → ALWAYS ALIVE. Cross-host pid comparison is
|
|
42
|
+
* meaningless, and comparing our `Date.now()` to the holder's
|
|
43
|
+
* `startedAt` (a different host's clock) is clock-skew-unsafe — a
|
|
44
|
+
* >~20s skew on an NFS root could reclaim a LIVE foreign holder and
|
|
45
|
+
* produce dual-writer RocksDB corruption. The NFS-safe trade is to
|
|
46
|
+
* never auto-reclaim a foreign holder; a truly-abandoned one needs
|
|
47
|
+
* manual cleanup (`rm <dataDir>/holder.json`).
|
|
48
|
+
* - Same-host → pid must be live AND its start-time must match, so a
|
|
49
|
+
* crashed-then-recycled pid (an abandoned dir whose pid the kernel
|
|
50
|
+
* handed to an unrelated process) no longer reads as "in use".
|
|
51
|
+
*
|
|
52
|
+
* A `null` start-time on either side is handled conservatively the
|
|
53
|
+
* same way roster does — ALIVE — because we have nothing to dispute
|
|
54
|
+
* the recorded identity with (mismatching a probed stamp against a
|
|
55
|
+
* recorded `null`, or vice versa, would falsely harvest a live
|
|
56
|
+
* holder). */
|
|
57
|
+
const isForkHolderAlive = (holder) => {
|
|
58
|
+
if (holder.host !== hostname()) return true;
|
|
59
|
+
if (!isPidAlive(holder.pid)) return false;
|
|
60
|
+
const probedStart = processStartTime(holder.pid);
|
|
61
|
+
if (probedStart === null) return true;
|
|
62
|
+
if (holder.startTime === null) return true;
|
|
63
|
+
return probedStart === holder.startTime;
|
|
64
|
+
};
|
|
65
|
+
const readForkHolder = (path) => parseVersionedDocumentBodyOrNull(safeReadHolderRaw(path), ForkLockHolderSchema, "sui-fork.holder");
|
|
66
|
+
/** Read the holder file's bytes, returning `''` (→ parses to null) on
|
|
67
|
+
* any I/O error. A missing/unreadable holder means "no live claim";
|
|
68
|
+
* the caller writes its own. Sync read is correct here — we are
|
|
69
|
+
* inside the brief OS-lock critical section, same non-yielding
|
|
70
|
+
* discipline as the cross-process roster reader. */
|
|
71
|
+
const safeReadHolderRaw = (path) => {
|
|
72
|
+
try {
|
|
73
|
+
return readFileSync(path, "utf8");
|
|
74
|
+
} catch {
|
|
75
|
+
return "";
|
|
76
|
+
}
|
|
77
|
+
};
|
|
78
|
+
const ownForkHolder = () => {
|
|
79
|
+
const pid = selfPid();
|
|
80
|
+
return {
|
|
81
|
+
pid,
|
|
82
|
+
host: hostname(),
|
|
83
|
+
instanceId: mintRandomSuffix(8),
|
|
84
|
+
startedAt: Date.now(),
|
|
85
|
+
startTime: processStartTime(pid)
|
|
86
|
+
};
|
|
87
|
+
};
|
|
88
|
+
/** Run `body` under a BRIEFLY-held `stack.lock`. The lock serializes
|
|
89
|
+
* the holder file's read → liveness-check → write critical section so
|
|
90
|
+
* two claimers never both decide the dir is free. Released the moment
|
|
91
|
+
* `body` completes — never held across the fork's lifetime. */
|
|
92
|
+
const underStackLock = (stackLockFile, holderPath, body) => Effect.scoped(Effect.gen(function* () {
|
|
93
|
+
yield* acquireStackLock(stackLockFile, FORK_HOLDER_LOCK_TIMEOUT_MILLIS).pipe(Effect.mapError((cause) => suiPluginError("fork-lock", `sui fork mode: failed to acquire stack lock for data dir ${holderPath}: ${cause._tag}`, cause)));
|
|
94
|
+
return yield* body;
|
|
95
|
+
}));
|
|
96
|
+
/** The brief critical section: under `stack.lock`, read any existing
|
|
97
|
+
* holder; if a LIVE one is present, fail with an actionable error;
|
|
98
|
+
* otherwise claim by writing our own holder atomically. Returns the
|
|
99
|
+
* holder we wrote so the heartbeat fiber can refresh it. */
|
|
100
|
+
const claimForkHolder = (stackLockFile, holderPath) => underStackLock(stackLockFile, holderPath, Effect.gen(function* () {
|
|
101
|
+
const existing = readForkHolder(holderPath);
|
|
102
|
+
if (existing !== null && isForkHolderAlive(existing)) return yield* Effect.fail(suiPluginError("fork-lock", `sui fork mode: fork data dir ${holderPath} is in use by pid ${existing.pid} on ${existing.host}; stop that stack or use a different fork key.`));
|
|
103
|
+
const self = ownForkHolder();
|
|
104
|
+
yield* writeForkHolder(holderPath, self);
|
|
105
|
+
return self;
|
|
106
|
+
}));
|
|
107
|
+
/** Heartbeat: under the brief lock, re-stamp `startedAt` IF the holder
|
|
108
|
+
* on disk is still ours. A peer that reclaimed us (same-host recycled-
|
|
109
|
+
* pid takeover) owns the file now; we must not clobber its claim, so a
|
|
110
|
+
* mismatched `instanceId` makes this a no-op. */
|
|
111
|
+
const refreshForkHolder = (stackLockFile, holderPath, self) => underStackLock(stackLockFile, holderPath, Effect.gen(function* () {
|
|
112
|
+
const current = readForkHolder(holderPath);
|
|
113
|
+
if (current !== null && current.instanceId !== self.instanceId) return;
|
|
114
|
+
yield* writeForkHolder(holderPath, {
|
|
115
|
+
...self,
|
|
116
|
+
startedAt: Date.now()
|
|
117
|
+
});
|
|
118
|
+
}));
|
|
119
|
+
/** Scope-finalizer release: unlink the holder file ONLY if it is still
|
|
120
|
+
* ours. A finalizer that unconditionally `unlinkSync`d by path would,
|
|
121
|
+
* after a legitimate same-host reclaim (our pid crashed-and-recycled,
|
|
122
|
+
* a peer took over), delete the PEER's holder and unprotect a dir the
|
|
123
|
+
* peer is actively writing. Re-reading and matching `instanceId` makes
|
|
124
|
+
* the release a no-op once we no longer own the file. A missing/
|
|
125
|
+
* unreadable holder is already-gone — also a no-op. Best-effort: a
|
|
126
|
+
* crash that skips this is recovered by the next peer's same-host
|
|
127
|
+
* liveness check. */
|
|
128
|
+
const releaseOwnForkHolder = (holderPath, self) => {
|
|
129
|
+
const current = readForkHolder(holderPath);
|
|
130
|
+
if (current !== null && current.instanceId !== self.instanceId) return;
|
|
131
|
+
try {
|
|
132
|
+
unlinkSync(holderPath);
|
|
133
|
+
} catch {}
|
|
134
|
+
};
|
|
135
|
+
const writeForkHolder = (path, holder) => Effect.try({
|
|
136
|
+
try: () => atomicWriteJsonSync(path, holder),
|
|
137
|
+
catch: (cause) => suiPluginError("fork-lock", `sui fork mode: failed to write fork data-dir holder ${path}.`, cause)
|
|
138
|
+
});
|
|
139
|
+
/**
|
|
140
|
+
* Acquire the data-dir holder for the lifetime of the surrounding
|
|
141
|
+
* scope.
|
|
142
|
+
*
|
|
143
|
+
* 1. Briefly take `stack.lock`, read any existing holder, fail if a
|
|
144
|
+
* live peer holds it, else write our own holder. Release the OS
|
|
145
|
+
* lock immediately (the claim outlives the lock).
|
|
146
|
+
* 2. Fork a scope-bound heartbeat fiber that re-takes the brief lock
|
|
147
|
+
* every `FORK_HOLDER_HEARTBEAT_INTERVAL_MILLIS` and refreshes
|
|
148
|
+
* `startedAt` (only while the file is still ours). A heartbeat
|
|
149
|
+
* failure is non-fatal — log and retry next tick (same policy as
|
|
150
|
+
* the roster heartbeat fiber).
|
|
151
|
+
* 3. Register a finalizer that removes our holder file on scope
|
|
152
|
+
* close (wipe / restart / Ctrl-C) — but ONLY if the on-disk holder
|
|
153
|
+
* is still ours, so a legitimate peer reclaim is never clobbered.
|
|
154
|
+
* A crash that skips the finalizer is recovered same-host by the
|
|
155
|
+
* next peer's liveness check (foreign-host needs manual cleanup —
|
|
156
|
+
* the NFS-safe trade in `isForkHolderAlive`).
|
|
157
|
+
*/
|
|
158
|
+
const acquireForkDataDirHolder = (stackLockFile, dataDir) => Effect.gen(function* () {
|
|
159
|
+
const holderPath = forkHolderPath(dataDir);
|
|
160
|
+
const self = yield* claimForkHolder(stackLockFile, holderPath);
|
|
161
|
+
yield* Effect.addFinalizer(() => Effect.sync(() => releaseOwnForkHolder(holderPath, self)));
|
|
162
|
+
yield* refreshForkHolder(stackLockFile, holderPath, self).pipe(Effect.catch((err) => Effect.logWarning("sui fork data-dir holder heartbeat failed; next tick will retry").pipe(Effect.annotateLogs({
|
|
163
|
+
[SpanAttr.phase]: err.phase,
|
|
164
|
+
[SpanAttr.errorMessage]: err.message
|
|
165
|
+
})))).pipe(Effect.repeat(Schedule.spaced(`${FORK_HOLDER_HEARTBEAT_INTERVAL_MILLIS} millis`)), Effect.forkScoped);
|
|
166
|
+
return self;
|
|
167
|
+
}).pipe(Effect.withSpan("devstack.plugin.sui.fork.acquireDataDirHolder"));
|
|
3
168
|
/** Surfaces that the sui-fork binary explicitly panics on. New
|
|
4
169
|
* upstream additions fail OPEN by default — architecture
|
|
5
170
|
* invariant. */
|
|
@@ -8,6 +173,9 @@ const FORK_UNSUPPORTED_SURFACES = [
|
|
|
8
173
|
"listBalances",
|
|
9
174
|
"getCoinInfo"
|
|
10
175
|
];
|
|
176
|
+
/** Wrap a Sui SDK shim with the fork guard. Property access for a
|
|
177
|
+
* blocklisted surface SYNCHRONOUSLY throws — the wire call never
|
|
178
|
+
* happens, so the fork binary stays up. */
|
|
11
179
|
const wrapWithForkGuard = (sdk) => {
|
|
12
180
|
const guardedCore = new Proxy(sdk.core, { get(target, prop, receiver) {
|
|
13
181
|
if (typeof prop === "string" && FORK_UNSUPPORTED_SURFACES.includes(prop)) throw forkUnsupportedError(`client.core.${prop}`, "fork mode does not implement this SDK surface — use the impersonation helper or read state via ChainProbe.");
|
|
@@ -19,6 +187,6 @@ const wrapWithForkGuard = (sdk) => {
|
|
|
19
187
|
};
|
|
20
188
|
};
|
|
21
189
|
//#endregion
|
|
22
|
-
export { FORK_UNSUPPORTED_SURFACES, wrapWithForkGuard };
|
|
190
|
+
export { FORK_UNSUPPORTED_SURFACES, acquireForkDataDirHolder, wrapWithForkGuard };
|
|
23
191
|
|
|
24
192
|
//# sourceMappingURL=fork-orchestration.mjs.map
|