@mysten-incubation/devstack 0.1.1 → 0.2.0
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 +6 -3
- package/dashboard-ui/assets/grpc-a4usE3Nk.js +3 -0
- package/dashboard-ui/assets/index-B82Bh84P.css +1 -0
- package/dashboard-ui/assets/index-CRYJ4pru.js +1277 -0
- package/dashboard-ui/index.html +2 -2
- package/dist/api/define-capabilities.d.mts +1 -20
- package/dist/api/define-capabilities.mjs +15 -22
- package/dist/api/define-capabilities.mjs.map +1 -1
- package/dist/api/define-devstack-with.d.mts +7 -1
- package/dist/api/define-devstack-with.mjs.map +1 -1
- package/dist/api/define-devstack.mjs.map +1 -1
- package/dist/api/define-plugin.d.mts +2 -1
- package/dist/api/inference-network.d.mts +31 -17
- package/dist/api/inference-network.mjs +40 -43
- package/dist/api/inference-network.mjs.map +1 -1
- package/dist/api/load-config.mjs +88 -0
- package/dist/api/load-config.mjs.map +1 -0
- package/dist/api/mode-narrowed-factory.d.mts +1 -1
- package/dist/api/mode-narrowed-factory.mjs.map +1 -1
- package/dist/api/run-stack-internal.mjs +202 -0
- package/dist/api/run-stack-internal.mjs.map +1 -0
- package/dist/api/run-stack.d.mts +82 -31
- package/dist/api/run-stack.mjs +22 -141
- package/dist/api/run-stack.mjs.map +1 -1
- package/dist/build-integrations/dapp-kit/index.d.mts +61 -0
- package/dist/build-integrations/dapp-kit/index.mjs +58 -0
- package/dist/build-integrations/dapp-kit/index.mjs.map +1 -0
- package/dist/build-integrations/playwright/config.d.mts +1 -30
- package/dist/build-integrations/playwright/config.mjs +1 -27
- package/dist/build-integrations/playwright/config.mjs.map +1 -1
- package/dist/build-integrations/playwright/errors.d.mts +4 -7
- package/dist/build-integrations/playwright/errors.mjs.map +1 -1
- package/dist/build-integrations/playwright/global-setup.d.mts +42 -71
- package/dist/build-integrations/playwright/global-setup.mjs +142 -218
- package/dist/build-integrations/playwright/global-setup.mjs.map +1 -1
- package/dist/build-integrations/playwright/index.d.mts +2 -2
- package/dist/build-integrations/playwright/index.mjs +2 -2
- package/dist/build-integrations/playwright/stack-context.d.mts +3 -1
- package/dist/build-integrations/playwright/stack-context.mjs +4 -2
- package/dist/build-integrations/playwright/stack-context.mjs.map +1 -1
- package/dist/build-integrations/playwright/wallet-context.mjs +44 -19
- package/dist/build-integrations/playwright/wallet-context.mjs.map +1 -1
- package/dist/build-integrations/runtime/cold-start-url.mjs.map +1 -1
- package/dist/build-integrations/runtime/conventional-routes.mjs.map +1 -1
- package/dist/build-integrations/runtime/dapp-kit-slot.mjs.map +1 -1
- package/dist/build-integrations/runtime/discover.d.mts +6 -4
- package/dist/build-integrations/runtime/discover.mjs +15 -4
- package/dist/build-integrations/runtime/discover.mjs.map +1 -1
- package/dist/build-integrations/runtime/endpoint-registry.mjs.map +1 -1
- package/dist/build-integrations/runtime/errors.mjs.map +1 -1
- package/dist/build-integrations/runtime/read-stack-context.mjs +3 -3
- package/dist/build-integrations/runtime/read-stack-context.mjs.map +1 -1
- package/dist/build-integrations/runtime/resolve-discovery-env.d.mts +23 -7
- package/dist/build-integrations/runtime/resolve-discovery-env.mjs +25 -12
- package/dist/build-integrations/runtime/resolve-discovery-env.mjs.map +1 -1
- package/dist/build-integrations/runtime/stack-context.d.mts +2 -2
- package/dist/build-integrations/vite/index.d.mts +84 -19
- package/dist/build-integrations/vite/index.mjs +203 -28
- package/dist/build-integrations/vite/index.mjs.map +1 -1
- package/dist/build-integrations/vitest/config.d.mts +20 -2
- package/dist/build-integrations/vitest/config.mjs +16 -4
- package/dist/build-integrations/vitest/config.mjs.map +1 -1
- package/dist/build-integrations/vitest/env.d.mts +18 -10
- package/dist/build-integrations/vitest/env.mjs +11 -10
- package/dist/build-integrations/vitest/env.mjs.map +1 -1
- package/dist/build-integrations/vitest/errors.d.mts +7 -11
- package/dist/build-integrations/vitest/errors.mjs +3 -4
- package/dist/build-integrations/vitest/errors.mjs.map +1 -1
- package/dist/build-integrations/vitest/global-setup.d.mts +35 -0
- package/dist/build-integrations/vitest/global-setup.mjs +156 -0
- package/dist/build-integrations/vitest/global-setup.mjs.map +1 -0
- package/dist/build-integrations/vitest/index.d.mts +3 -2
- package/dist/build-integrations/vitest/index.mjs +3 -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 +5 -3
- package/dist/build-integrations/vitest/stack-context.mjs +3 -2
- package/dist/build-integrations/vitest/stack-context.mjs.map +1 -1
- package/dist/cli/bail.mjs.map +1 -1
- package/dist/cli/doctor-probes.mjs +1 -3
- package/dist/cli/doctor-probes.mjs.map +1 -1
- package/dist/cli/main.d.mts +23 -1
- package/dist/cli/main.mjs +63 -8
- package/dist/cli/main.mjs.map +1 -1
- package/dist/cli/prune-direct.mjs.map +1 -1
- package/dist/cli/snapshot-reader.mjs.map +1 -1
- package/dist/cli/up-lifecycle.mjs.map +1 -1
- package/dist/cli/wirings/apply.mjs +28 -21
- package/dist/cli/wirings/apply.mjs.map +1 -1
- package/dist/cli/wirings/codegen.mjs +108 -0
- package/dist/cli/wirings/codegen.mjs.map +1 -0
- package/dist/cli/wirings/config-loader.mjs +12 -62
- package/dist/cli/wirings/config-loader.mjs.map +1 -1
- package/dist/cli/wirings/dump-ids.mjs +86 -0
- package/dist/cli/wirings/dump-ids.mjs.map +1 -0
- package/dist/cli/wirings/engine-command.mjs +1 -1
- package/dist/cli/wirings/engine-command.mjs.map +1 -1
- package/dist/cli/wirings/identity.mjs +2 -2
- package/dist/cli/wirings/identity.mjs.map +1 -1
- package/dist/cli/wirings/provide-file-system.mjs.map +1 -1
- package/dist/cli/wirings/read-devstack-version.mjs +17 -0
- package/dist/cli/wirings/read-devstack-version.mjs.map +1 -0
- package/dist/cli/wirings/snapshot.mjs +27 -34
- package/dist/cli/wirings/snapshot.mjs.map +1 -1
- package/dist/cli/wirings/up-ipc.mjs +147 -0
- package/dist/cli/wirings/up-ipc.mjs.map +1 -0
- package/dist/cli/wirings/up.mjs +218 -198
- package/dist/cli/wirings/up.mjs.map +1 -1
- package/dist/cli/wirings/wipe.mjs +1 -1
- package/dist/cli/wirings/wipe.mjs.map +1 -1
- package/dist/contracts/chain-probe.d.mts +1 -1
- package/dist/contracts/chain-probe.mjs +1 -1
- package/dist/contracts/chain-probe.mjs.map +1 -1
- package/dist/contracts/codegenable.d.mts +60 -6
- package/dist/contracts/codegenable.mjs +28 -0
- package/dist/contracts/codegenable.mjs.map +1 -0
- package/dist/contracts/config-bindings.mjs +162 -0
- package/dist/contracts/config-bindings.mjs.map +1 -0
- package/dist/contracts/container-runtime.d.mts +23 -17
- package/dist/contracts/plugin-expander.mjs.map +1 -1
- package/dist/contracts/snapshotable.d.mts +5 -7
- package/dist/contracts/wallet-protocol.d.mts +2 -5
- package/dist/contracts/wallet-protocol.mjs +2 -5
- package/dist/contracts/wallet-protocol.mjs.map +1 -1
- package/dist/index.d.mts +21 -26
- package/dist/index.mjs +8 -9
- package/dist/orchestrators/boot.d.mts +28 -0
- package/dist/orchestrators/boot.mjs +440 -0
- package/dist/orchestrators/boot.mjs.map +1 -0
- package/dist/orchestrators/codegen/bindings.d.mts +13 -1
- package/dist/orchestrators/codegen/bindings.mjs +23 -9
- package/dist/orchestrators/codegen/bindings.mjs.map +1 -1
- package/dist/orchestrators/codegen/config-runtime.mjs +208 -0
- package/dist/orchestrators/codegen/config-runtime.mjs.map +1 -0
- package/dist/orchestrators/codegen/emit.mjs +1 -1
- package/dist/orchestrators/codegen/emit.mjs.map +1 -1
- package/dist/orchestrators/codegen/errors.mjs +21 -1
- package/dist/orchestrators/codegen/errors.mjs.map +1 -1
- package/dist/orchestrators/codegen/format.mjs +2 -0
- package/dist/orchestrators/codegen/format.mjs.map +1 -1
- package/dist/orchestrators/codegen/gitignore.mjs +30 -11
- package/dist/orchestrators/codegen/gitignore.mjs.map +1 -1
- package/dist/orchestrators/codegen/id-config.mjs +107 -0
- package/dist/orchestrators/codegen/id-config.mjs.map +1 -0
- package/dist/orchestrators/codegen/output-location.mjs +23 -32
- package/dist/orchestrators/codegen/output-location.mjs.map +1 -1
- package/dist/orchestrators/codegen/paths.mjs +8 -1
- package/dist/orchestrators/codegen/paths.mjs.map +1 -1
- package/dist/orchestrators/codegen/permissions.mjs.map +1 -1
- package/dist/orchestrators/codegen/service.mjs +286 -58
- package/dist/orchestrators/codegen/service.mjs.map +1 -1
- package/dist/orchestrators/layers.mjs +31 -0
- package/dist/orchestrators/layers.mjs.map +1 -0
- package/dist/orchestrators/lifecycle-prune/errors.mjs.map +1 -1
- package/dist/orchestrators/lifecycle-prune/index.mjs +8 -10
- package/dist/orchestrators/lifecycle-prune/index.mjs.map +1 -1
- package/dist/orchestrators/network-options.d.mts +52 -0
- package/dist/orchestrators/network-options.mjs +43 -0
- package/dist/orchestrators/network-options.mjs.map +1 -0
- package/dist/orchestrators/router/cleanup.mjs.map +1 -1
- package/dist/orchestrators/router/cors.mjs.map +1 -1
- package/dist/orchestrators/router/entrypoints.mjs.map +1 -1
- package/dist/orchestrators/router/errors.mjs.map +1 -1
- package/dist/orchestrators/router/file-provider.mjs.map +1 -1
- package/dist/orchestrators/router/hostname.mjs.map +1 -1
- package/dist/orchestrators/router/profile.mjs +1 -1
- package/dist/orchestrators/router/profile.mjs.map +1 -1
- package/dist/orchestrators/router/service.d.mts +2 -2
- package/dist/orchestrators/router/service.mjs +12 -27
- package/dist/orchestrators/router/service.mjs.map +1 -1
- package/dist/orchestrators/router/traefik-container.mjs +1 -1
- package/dist/orchestrators/router/traefik-container.mjs.map +1 -1
- package/dist/orchestrators/snapshot/capture.mjs +171 -195
- package/dist/orchestrators/snapshot/capture.mjs.map +1 -1
- package/dist/orchestrators/snapshot/descriptor.d.mts +1 -1
- package/dist/orchestrators/snapshot/descriptor.mjs +53 -11
- package/dist/orchestrators/snapshot/descriptor.mjs.map +1 -1
- package/dist/orchestrators/snapshot/identity-guard.mjs +3 -5
- package/dist/orchestrators/snapshot/identity-guard.mjs.map +1 -1
- package/dist/orchestrators/snapshot/image-bundle-tags.mjs +32 -101
- package/dist/orchestrators/snapshot/image-bundle-tags.mjs.map +1 -1
- package/dist/orchestrators/snapshot/index.mjs +1 -4
- package/dist/orchestrators/snapshot/integrity.mjs.map +1 -1
- package/dist/orchestrators/snapshot/interrupted-restore.mjs +116 -0
- package/dist/orchestrators/snapshot/interrupted-restore.mjs.map +1 -0
- package/dist/orchestrators/snapshot/phase-error.mjs.map +1 -1
- package/dist/orchestrators/snapshot/prune.mjs +40 -31
- package/dist/orchestrators/snapshot/prune.mjs.map +1 -1
- package/dist/orchestrators/snapshot/restore.mjs +221 -196
- package/dist/orchestrators/snapshot/restore.mjs.map +1 -1
- package/dist/orchestrators/snapshot/service.mjs +72 -62
- package/dist/orchestrators/snapshot/service.mjs.map +1 -1
- package/dist/orchestrators/snapshot/wipe.mjs +67 -56
- package/dist/orchestrators/snapshot/wipe.mjs.map +1 -1
- package/dist/plugins/account/codegen.mjs +3 -0
- package/dist/plugins/account/codegen.mjs.map +1 -1
- package/dist/plugins/account/errors.d.mts +2 -2
- package/dist/plugins/account/errors.mjs +1 -4
- package/dist/plugins/account/errors.mjs.map +1 -1
- package/dist/plugins/account/funding.mjs +3 -27
- package/dist/plugins/account/funding.mjs.map +1 -1
- package/dist/plugins/account/index.d.mts +3 -8
- package/dist/plugins/account/index.mjs +71 -35
- package/dist/plugins/account/index.mjs.map +1 -1
- package/dist/plugins/account/keypair.d.mts +8 -7
- package/dist/plugins/account/keypair.mjs +5 -18
- package/dist/plugins/account/keypair.mjs.map +1 -1
- package/dist/plugins/account/lease.mjs.map +1 -1
- package/dist/plugins/account/registry.d.mts +1 -46
- package/dist/plugins/account/registry.mjs.map +1 -1
- package/dist/plugins/account/service.d.mts +43 -34
- package/dist/plugins/account/service.mjs +9 -54
- package/dist/plugins/account/service.mjs.map +1 -1
- package/dist/plugins/account/snapshot.mjs.map +1 -1
- package/dist/plugins/account/variants/ephemeral.mjs.map +1 -1
- package/dist/plugins/account/variants/impersonate.mjs.map +1 -1
- package/dist/plugins/account/variants/signer.mjs.map +1 -1
- package/dist/plugins/action/discriminator.mjs.map +1 -1
- package/dist/plugins/action/errors.mjs +1 -4
- package/dist/plugins/action/errors.mjs.map +1 -1
- package/dist/plugins/action/execute.mjs +3 -4
- package/dist/plugins/action/execute.mjs.map +1 -1
- package/dist/plugins/action/index.d.mts +2 -2
- package/dist/plugins/action/index.mjs +7 -11
- package/dist/plugins/action/index.mjs.map +1 -1
- package/dist/plugins/action/service.d.mts +5 -7
- package/dist/plugins/action/service.mjs +2 -16
- package/dist/plugins/action/service.mjs.map +1 -1
- package/dist/plugins/coin/address-resolution.mjs.map +1 -1
- package/dist/plugins/coin/codegen.mjs +97 -16
- package/dist/plugins/coin/codegen.mjs.map +1 -1
- package/dist/plugins/coin/discovery.mjs.map +1 -1
- package/dist/plugins/coin/errors.mjs +1 -4
- package/dist/plugins/coin/errors.mjs.map +1 -1
- package/dist/plugins/coin/index.d.mts +4 -34
- package/dist/plugins/coin/index.mjs +47 -28
- package/dist/plugins/coin/index.mjs.map +1 -1
- package/dist/plugins/coin/metadata.d.mts +1 -0
- package/dist/plugins/coin/metadata.mjs +8 -9
- package/dist/plugins/coin/metadata.mjs.map +1 -1
- package/dist/plugins/coin/mint.mjs +7 -21
- package/dist/plugins/coin/mint.mjs.map +1 -1
- package/dist/plugins/coin/registry.mjs +33 -20
- package/dist/plugins/coin/registry.mjs.map +1 -1
- package/dist/plugins/coin/service.d.mts +1 -1
- package/dist/plugins/coin/service.mjs +1 -8
- package/dist/plugins/coin/service.mjs.map +1 -1
- package/dist/plugins/coin/snapshot.mjs.map +1 -1
- package/dist/plugins/coin/type-strings.mjs.map +1 -1
- package/dist/plugins/dashboard/domain.mjs +106 -167
- package/dist/plugins/dashboard/domain.mjs.map +1 -1
- package/dist/plugins/dashboard/index.mjs +13 -13
- package/dist/plugins/dashboard/index.mjs.map +1 -1
- package/dist/plugins/dashboard/origin-policy.mjs +3 -3
- package/dist/plugins/dashboard/origin-policy.mjs.map +1 -1
- package/dist/plugins/dashboard/routable.mjs.map +1 -1
- package/dist/plugins/dashboard/schema/builder.mjs.map +1 -1
- package/dist/plugins/dashboard/schema/enums.mjs.map +1 -1
- package/dist/plugins/dashboard/schema/root.mjs +23 -44
- package/dist/plugins/dashboard/schema/root.mjs.map +1 -1
- package/dist/plugins/dashboard/schema/types.mjs +37 -91
- package/dist/plugins/dashboard/schema/types.mjs.map +1 -1
- package/dist/plugins/dashboard/schema.mjs.map +1 -1
- package/dist/plugins/dashboard/server.mjs.map +1 -1
- package/dist/plugins/deepbook/codegen.d.mts +12 -11
- package/dist/plugins/deepbook/codegen.mjs +108 -11
- package/dist/plugins/deepbook/codegen.mjs.map +1 -1
- package/dist/plugins/deepbook/deploy.mjs +7 -14
- package/dist/plugins/deepbook/deploy.mjs.map +1 -1
- package/dist/plugins/deepbook/errors.mjs +4 -2
- package/dist/plugins/deepbook/errors.mjs.map +1 -1
- package/dist/plugins/deepbook/faucet-strategy.mjs +4 -10
- package/dist/plugins/deepbook/faucet-strategy.mjs.map +1 -1
- package/dist/plugins/deepbook/hash.mjs.map +1 -1
- package/dist/plugins/deepbook/index.d.mts +38 -34
- package/dist/plugins/deepbook/index.mjs +133 -64
- package/dist/plugins/deepbook/index.mjs.map +1 -1
- package/dist/plugins/deepbook/plugin-key.mjs.map +1 -1
- package/dist/plugins/deepbook/pyth/index.mjs +4 -8
- package/dist/plugins/deepbook/pyth/index.mjs.map +1 -1
- package/dist/plugins/deepbook/snapshot.mjs +0 -1
- package/dist/plugins/deepbook/snapshot.mjs.map +1 -1
- package/dist/plugins/deepbook/type-strings.mjs.map +1 -1
- package/dist/plugins/deepbook/types.d.mts +2 -1
- package/dist/plugins/deepbook/types.mjs.map +1 -1
- package/dist/plugins/faucet/dispatcher.d.mts +3 -3
- package/dist/plugins/faucet/dispatcher.mjs.map +1 -1
- package/dist/plugins/faucet/errors.mjs.map +1 -1
- package/dist/plugins/faucet/http.mjs +2 -10
- package/dist/plugins/faucet/http.mjs.map +1 -1
- package/dist/plugins/faucet/index.mjs +0 -1
- package/dist/plugins/faucet/index.mjs.map +1 -1
- package/dist/plugins/host-service/errors.d.mts +1 -3
- package/dist/plugins/host-service/errors.mjs +1 -2
- package/dist/plugins/host-service/errors.mjs.map +1 -1
- package/dist/plugins/host-service/index.d.mts +1 -2
- package/dist/plugins/host-service/index.mjs +11 -11
- package/dist/plugins/host-service/index.mjs.map +1 -1
- package/dist/plugins/host-service/routable.mjs.map +1 -1
- package/dist/plugins/host-service/service.mjs +13 -13
- package/dist/plugins/host-service/service.mjs.map +1 -1
- package/dist/plugins/internal/acquire-on-chain-artifact.mjs.map +1 -1
- package/dist/plugins/internal/codegen-helpers.mjs +2 -0
- package/dist/plugins/internal/codegen-helpers.mjs.map +1 -1
- package/dist/plugins/internal/funding-failure-error.mjs.map +1 -1
- package/dist/plugins/{postgres → internal/postgres-sidecar}/connection.mjs +1 -1
- package/dist/plugins/internal/postgres-sidecar/connection.mjs.map +1 -0
- package/dist/plugins/{postgres → internal/postgres-sidecar}/db-ensure.mjs +30 -16
- package/dist/plugins/internal/postgres-sidecar/db-ensure.mjs.map +1 -0
- package/dist/plugins/internal/postgres-sidecar/errors.mjs +21 -0
- package/dist/plugins/internal/postgres-sidecar/errors.mjs.map +1 -0
- package/dist/{substrate/runtime/scoped-multimap → plugins/internal/postgres-sidecar}/index.mjs +1 -0
- package/dist/plugins/internal/postgres-sidecar/service.mjs +121 -0
- package/dist/plugins/internal/postgres-sidecar/service.mjs.map +1 -0
- package/dist/plugins/package/build.mjs +2 -2
- package/dist/plugins/package/build.mjs.map +1 -1
- package/dist/plugins/package/codegen.d.mts +7 -14
- package/dist/plugins/package/codegen.mjs +187 -59
- package/dist/plugins/package/codegen.mjs.map +1 -1
- package/dist/plugins/package/dep-resolution.mjs +51 -3
- package/dist/plugins/package/dep-resolution.mjs.map +1 -1
- package/dist/plugins/package/errors.mjs +1 -4
- package/dist/plugins/package/errors.mjs.map +1 -1
- package/dist/plugins/package/git-source.d.mts +18 -0
- package/dist/plugins/package/git-source.mjs +119 -0
- package/dist/plugins/package/git-source.mjs.map +1 -0
- package/dist/plugins/package/index.d.mts +28 -19
- package/dist/plugins/package/index.mjs +107 -32
- package/dist/plugins/package/index.mjs.map +1 -1
- package/dist/plugins/package/mode-known.mjs +2 -2
- package/dist/plugins/package/mode-known.mjs.map +1 -1
- package/dist/plugins/package/mode-local.mjs +18 -35
- package/dist/plugins/package/mode-local.mjs.map +1 -1
- package/dist/plugins/package/publish-executor.mjs +13 -8
- package/dist/plugins/package/publish-executor.mjs.map +1 -1
- package/dist/plugins/package/publish-output.d.mts +1 -11
- package/dist/plugins/package/publish-output.mjs +1 -9
- package/dist/plugins/package/publish-output.mjs.map +1 -1
- package/dist/plugins/package/registry.d.mts +1 -1
- package/dist/plugins/package/registry.mjs +26 -14
- package/dist/plugins/package/registry.mjs.map +1 -1
- package/dist/plugins/package/service.mjs.map +1 -1
- package/dist/plugins/package/snapshot.mjs.map +1 -1
- package/dist/plugins/router-entrypoints.mjs +1 -3
- package/dist/plugins/router-entrypoints.mjs.map +1 -1
- package/dist/plugins/seal/bootstrap-assets/cargo-image.mjs +1 -2
- package/dist/plugins/seal/bootstrap-assets/cargo-image.mjs.map +1 -1
- package/dist/plugins/seal/bootstrap-assets/source-fetch.mjs +1 -6
- package/dist/plugins/seal/bootstrap-assets/source-fetch.mjs.map +1 -1
- package/dist/plugins/seal/codegen.d.mts +1 -5
- package/dist/plugins/seal/codegen.mjs +83 -12
- package/dist/plugins/seal/codegen.mjs.map +1 -1
- package/dist/plugins/seal/config-render.mjs +2 -6
- package/dist/plugins/seal/config-render.mjs.map +1 -1
- package/dist/plugins/seal/deploy.mjs +18 -29
- package/dist/plugins/seal/deploy.mjs.map +1 -1
- package/dist/plugins/seal/errors.d.mts +4 -5
- package/dist/plugins/seal/errors.mjs +1 -8
- package/dist/plugins/seal/errors.mjs.map +1 -1
- package/dist/plugins/seal/index.d.mts +7 -28
- package/dist/plugins/seal/index.mjs +69 -47
- package/dist/plugins/seal/index.mjs.map +1 -1
- package/dist/plugins/seal/key-manager.mjs.map +1 -1
- package/dist/plugins/seal/key-server.mjs +1 -6
- package/dist/plugins/seal/key-server.mjs.map +1 -1
- package/dist/plugins/seal/keygen.mjs +2 -3
- package/dist/plugins/seal/keygen.mjs.map +1 -1
- package/dist/plugins/seal/mode/fork-known.mjs.map +1 -1
- package/dist/plugins/seal/mode/live.mjs +1 -1
- package/dist/plugins/seal/mode/live.mjs.map +1 -1
- package/dist/plugins/seal/mode/local-keygen.mjs +4 -10
- package/dist/plugins/seal/mode/local-keygen.mjs.map +1 -1
- package/dist/plugins/seal/plugin-key.mjs.map +1 -1
- 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/snapshot.mjs +1 -2
- package/dist/plugins/seal/snapshot.mjs.map +1 -1
- package/dist/plugins/sui/auto-tick.mjs +5 -5
- package/dist/plugins/sui/auto-tick.mjs.map +1 -1
- package/dist/plugins/sui/chain-build-container.mjs +2 -2
- package/dist/plugins/sui/chain-build-container.mjs.map +1 -1
- package/dist/plugins/sui/chain-probe.mjs +4 -4
- package/dist/plugins/sui/chain-probe.mjs.map +1 -1
- package/dist/plugins/sui/codegen.d.mts +9 -7
- package/dist/plugins/sui/codegen.mjs +49 -46
- package/dist/plugins/sui/codegen.mjs.map +1 -1
- package/dist/plugins/sui/errors.d.mts +1 -1
- package/dist/plugins/sui/errors.mjs +1 -9
- package/dist/plugins/sui/errors.mjs.map +1 -1
- package/dist/{substrate/runtime/sui-execute → plugins/sui/exec}/index.d.mts +1 -1
- package/dist/{substrate/runtime/sui-execute → plugins/sui/exec}/index.mjs +3 -7
- package/dist/plugins/sui/exec/index.mjs.map +1 -0
- package/dist/{substrate/runtime/sui-execute → plugins/sui/exec}/sign-and-dispatch.mjs +1 -1
- package/dist/plugins/sui/exec/sign-and-dispatch.mjs.map +1 -0
- package/dist/plugins/sui/fork-faucet-strategy.mjs +2 -6
- package/dist/plugins/sui/fork-faucet-strategy.mjs.map +1 -1
- package/dist/plugins/sui/fork-orchestration.mjs +13 -23
- package/dist/plugins/sui/fork-orchestration.mjs.map +1 -1
- package/dist/plugins/sui/fork-transaction.mjs.map +1 -1
- package/dist/plugins/sui/index.d.mts +34 -83
- package/dist/plugins/sui/index.mjs +200 -68
- package/dist/plugins/sui/index.mjs.map +1 -1
- package/dist/{substrate/runtime/sui-ledger → plugins/sui/ledger}/object-ref.mjs +1 -1
- package/dist/plugins/sui/ledger/object-ref.mjs.map +1 -0
- package/dist/plugins/sui/local-faucet-strategy.mjs +1 -5
- package/dist/plugins/sui/local-faucet-strategy.mjs.map +1 -1
- package/dist/plugins/sui/log-attrs.mjs +11 -0
- package/dist/plugins/sui/log-attrs.mjs.map +1 -0
- package/dist/plugins/sui/mode/external.mjs +4 -12
- package/dist/plugins/sui/mode/external.mjs.map +1 -1
- package/dist/plugins/sui/mode/fork.mjs +19 -16
- package/dist/plugins/sui/mode/fork.mjs.map +1 -1
- package/dist/plugins/sui/mode/live.mjs +4 -17
- package/dist/plugins/sui/mode/live.mjs.map +1 -1
- package/dist/plugins/sui/mode/local.d.mts +1 -0
- package/dist/plugins/sui/mode/local.mjs +203 -61
- package/dist/plugins/sui/mode/local.mjs.map +1 -1
- package/dist/plugins/sui/mode/shared-boot.mjs +18 -23
- package/dist/plugins/sui/mode/shared-boot.mjs.map +1 -1
- package/dist/plugins/sui/mode/shared.d.mts +6 -7
- package/dist/plugins/sui/mode/shared.mjs.map +1 -1
- package/dist/plugins/sui/mode/spec.d.mts +23 -6
- package/dist/{substrate/runtime/sui-move-build → plugins/sui/move}/index.mjs +28 -30
- package/dist/plugins/sui/move/index.mjs.map +1 -0
- package/dist/plugins/sui/move-summary-runner.mjs +8 -4
- package/dist/plugins/sui/move-summary-runner.mjs.map +1 -1
- package/dist/{substrate/network.d.mts → plugins/sui/network-config.d.mts} +11 -10
- package/dist/plugins/sui/network-resolver.d.mts +6 -6
- package/dist/plugins/sui/routable.mjs.map +1 -1
- package/dist/plugins/sui/service.mjs +10 -6
- package/dist/plugins/sui/service.mjs.map +1 -1
- package/dist/plugins/sui/snapshot.mjs +10 -5
- package/dist/plugins/sui/snapshot.mjs.map +1 -1
- package/dist/plugins/wallet/codegen.d.mts +8 -6
- package/dist/plugins/wallet/codegen.mjs +4 -10
- package/dist/plugins/wallet/codegen.mjs.map +1 -1
- package/dist/plugins/wallet/errors.mjs +1 -4
- package/dist/plugins/wallet/errors.mjs.map +1 -1
- package/dist/plugins/wallet/index.d.mts +3 -6
- package/dist/plugins/wallet/index.mjs +16 -21
- package/dist/plugins/wallet/index.mjs.map +1 -1
- package/dist/plugins/wallet/origin-policy.mjs +3 -3
- package/dist/plugins/wallet/origin-policy.mjs.map +1 -1
- package/dist/plugins/wallet/pairing.mjs +6 -24
- package/dist/plugins/wallet/pairing.mjs.map +1 -1
- package/dist/plugins/wallet/protocol.mjs.map +1 -1
- package/dist/plugins/wallet/routable.mjs.map +1 -1
- package/dist/plugins/wallet/server.mjs +17 -24
- package/dist/plugins/wallet/server.mjs.map +1 -1
- package/dist/plugins/wallet/service.d.mts +2 -2
- package/dist/plugins/wallet/service.mjs +4 -15
- package/dist/plugins/wallet/service.mjs.map +1 -1
- package/dist/plugins/wallet/snapshot.mjs.map +1 -1
- package/dist/plugins/walrus/bootstrap-assets/cargo-image.mjs +1 -5
- package/dist/plugins/walrus/bootstrap-assets/cargo-image.mjs.map +1 -1
- package/dist/plugins/walrus/codegen.d.mts +2 -13
- package/dist/plugins/walrus/codegen.mjs +93 -28
- package/dist/plugins/walrus/codegen.mjs.map +1 -1
- package/dist/plugins/walrus/deploy-paths.mjs +2 -3
- package/dist/plugins/walrus/deploy-paths.mjs.map +1 -1
- package/dist/plugins/walrus/deploy.mjs +26 -19
- package/dist/plugins/walrus/deploy.mjs.map +1 -1
- package/dist/plugins/walrus/errors.mjs +1 -8
- package/dist/plugins/walrus/errors.mjs.map +1 -1
- package/dist/plugins/walrus/faucet-strategy.mjs +15 -1
- package/dist/plugins/walrus/faucet-strategy.mjs.map +1 -1
- package/dist/plugins/walrus/index.d.mts +13 -44
- package/dist/plugins/walrus/index.mjs +119 -122
- package/dist/plugins/walrus/index.mjs.map +1 -1
- package/dist/plugins/walrus/mode/known-deploy.mjs +6 -6
- package/dist/plugins/walrus/mode/known-deploy.mjs.map +1 -1
- package/dist/plugins/walrus/mode/local-cluster.d.mts +2 -2
- package/dist/plugins/walrus/mode/local-cluster.mjs +2 -10
- package/dist/plugins/walrus/mode/local-cluster.mjs.map +1 -1
- package/dist/plugins/walrus/plugin-key.mjs.map +1 -1
- package/dist/plugins/walrus/registry-publish.mjs.map +1 -1
- package/dist/plugins/walrus/routable.mjs.map +1 -1
- package/dist/plugins/walrus/service.mjs.map +1 -1
- package/dist/plugins/walrus/snapshot.mjs +3 -3
- package/dist/plugins/walrus/snapshot.mjs.map +1 -1
- package/dist/plugins/walrus/storage-nodes.mjs +53 -14
- package/dist/plugins/walrus/storage-nodes.mjs.map +1 -1
- package/dist/plugins/walrus/wal-swap.mjs +4 -8
- package/dist/plugins/walrus/wal-swap.mjs.map +1 -1
- package/dist/primitives/artifact-publisher.mjs.map +1 -1
- package/dist/primitives/cache.d.mts +1 -1
- package/dist/runtime/docker/client.mjs +47 -3
- package/dist/runtime/docker/client.mjs.map +1 -1
- package/dist/runtime/docker/container.mjs +37 -57
- package/dist/runtime/docker/container.mjs.map +1 -1
- package/dist/runtime/docker/errors.mjs.map +1 -1
- package/dist/runtime/docker/exec.mjs +2 -2
- package/dist/runtime/docker/exec.mjs.map +1 -1
- package/dist/runtime/docker/image.mjs +10 -11
- package/dist/runtime/docker/image.mjs.map +1 -1
- package/dist/runtime/docker/index.mjs +0 -1
- package/dist/runtime/docker/inspect-and-decode.mjs.map +1 -1
- package/dist/runtime/docker/inventory.mjs +9 -9
- package/dist/runtime/docker/inventory.mjs.map +1 -1
- package/dist/runtime/docker/labels.mjs +12 -1
- package/dist/runtime/docker/labels.mjs.map +1 -1
- package/dist/runtime/docker/network.mjs +6 -6
- package/dist/runtime/docker/network.mjs.map +1 -1
- package/dist/runtime/docker/render-run-args.mjs.map +1 -1
- package/dist/runtime/docker/service.mjs +31 -45
- package/dist/runtime/docker/service.mjs.map +1 -1
- package/dist/runtime/docker/sweep.mjs +14 -64
- package/dist/runtime/docker/sweep.mjs.map +1 -1
- package/dist/runtime/docker/volume.mjs +1 -1
- package/dist/runtime/docker/volume.mjs.map +1 -1
- package/dist/runtime/docker/wrap.mjs +14 -2
- package/dist/runtime/docker/wrap.mjs.map +1 -1
- package/dist/substrate/brand.d.mts +2 -5
- package/dist/substrate/brand.mjs +3 -2
- package/dist/substrate/brand.mjs.map +1 -1
- package/dist/substrate/cross-process.mjs +2 -16
- package/dist/substrate/cross-process.mjs.map +1 -1
- package/dist/substrate/event-time.mjs +0 -2
- package/dist/substrate/event-time.mjs.map +1 -1
- package/dist/substrate/events.d.mts +46 -16
- package/dist/substrate/identity.d.mts +11 -5
- package/dist/substrate/manifest.d.mts +33 -26
- package/dist/substrate/manifest.mjs +8 -3
- package/dist/substrate/manifest.mjs.map +1 -1
- package/dist/substrate/options.d.mts +33 -4
- package/dist/substrate/plugin-ctx.d.mts +70 -0
- package/dist/substrate/plugin-ctx.mjs +66 -0
- package/dist/substrate/plugin-ctx.mjs.map +1 -0
- package/dist/substrate/plugin.d.mts +46 -38
- package/dist/substrate/plugin.mjs +13 -9
- package/dist/substrate/plugin.mjs.map +1 -1
- package/dist/substrate/projection.d.mts +1 -1
- package/dist/substrate/runtime/atomic-write.mjs +3 -4
- package/dist/substrate/runtime/atomic-write.mjs.map +1 -1
- package/dist/substrate/runtime/cache/schema.mjs.map +1 -1
- package/dist/substrate/runtime/cache/service.mjs +50 -20
- package/dist/substrate/runtime/cache/service.mjs.map +1 -1
- package/dist/substrate/runtime/config-validation.mjs.map +1 -1
- package/dist/substrate/runtime/control-plane/domain.mjs +34 -12
- package/dist/substrate/runtime/control-plane/domain.mjs.map +1 -1
- package/dist/substrate/runtime/control-plane/service.mjs.map +1 -1
- package/dist/substrate/runtime/cross-process/command-channel/channel.mjs +14 -17
- package/dist/substrate/runtime/cross-process/command-channel/channel.mjs.map +1 -1
- package/dist/substrate/runtime/cross-process/command-channel/file-channel.mjs.map +1 -1
- 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.map +1 -1
- package/dist/substrate/runtime/cross-process/index.mjs +0 -2
- package/dist/substrate/runtime/cross-process/live-clock.mjs +1 -1
- package/dist/substrate/runtime/cross-process/live-clock.mjs.map +1 -1
- package/dist/substrate/runtime/cross-process/liveness.mjs +11 -18
- package/dist/substrate/runtime/cross-process/liveness.mjs.map +1 -1
- package/dist/substrate/runtime/cross-process/reclaim-stale-file.mjs +2 -2
- package/dist/substrate/runtime/cross-process/reclaim-stale-file.mjs.map +1 -1
- package/dist/substrate/runtime/cross-process/roster.mjs +17 -127
- package/dist/substrate/runtime/cross-process/roster.mjs.map +1 -1
- package/dist/substrate/runtime/cross-process/self-pid.mjs.map +1 -1
- package/dist/substrate/runtime/cross-process/stack-lock.mjs +29 -28
- package/dist/substrate/runtime/cross-process/stack-lock.mjs.map +1 -1
- package/dist/substrate/runtime/current-plugin.mjs.map +1 -1
- package/dist/substrate/runtime/errors.mjs +1 -13
- package/dist/substrate/runtime/errors.mjs.map +1 -1
- package/dist/substrate/runtime/format-unknown-error.mjs.map +1 -1
- package/dist/substrate/runtime/host-bind-mount-owner.mjs.map +1 -1
- package/dist/substrate/runtime/host-gateway.mjs.map +1 -1
- package/dist/substrate/runtime/host-tree-tar/index.mjs +15 -163
- package/dist/substrate/runtime/host-tree-tar/index.mjs.map +1 -1
- package/dist/substrate/runtime/http-probe.d.mts +1 -3
- package/dist/substrate/runtime/http-probe.mjs.map +1 -1
- package/dist/substrate/runtime/index.mjs +1 -6
- package/dist/substrate/runtime/lease-broker/service.mjs +5 -23
- package/dist/substrate/runtime/lease-broker/service.mjs.map +1 -1
- package/dist/substrate/runtime/lifecycle/dep-graph.mjs +3 -3
- package/dist/substrate/runtime/lifecycle/dep-graph.mjs.map +1 -1
- package/dist/substrate/runtime/lifecycle/graph-input-id.d.mts +1 -0
- package/dist/substrate/runtime/lifecycle/graph-input-id.mjs +133 -0
- package/dist/substrate/runtime/lifecycle/graph-input-id.mjs.map +1 -0
- package/dist/substrate/runtime/lifecycle/index.mjs +2 -2
- package/dist/substrate/runtime/lifecycle/plugin-registry.d.mts +1 -1
- package/dist/substrate/runtime/lifecycle/plugin-registry.mjs +22 -1
- package/dist/substrate/runtime/lifecycle/plugin-registry.mjs.map +1 -1
- package/dist/substrate/runtime/lifecycle/ready-gate.mjs +2 -15
- package/dist/substrate/runtime/lifecycle/ready-gate.mjs.map +1 -1
- package/dist/substrate/runtime/lifecycle/selective-restart.mjs +29 -25
- package/dist/substrate/runtime/lifecycle/selective-restart.mjs.map +1 -1
- package/dist/substrate/runtime/lifecycle/signals.mjs +1 -1
- package/dist/substrate/runtime/lifecycle/signals.mjs.map +1 -1
- package/dist/substrate/runtime/lifecycle/state-machine.mjs.map +1 -1
- package/dist/substrate/runtime/lifecycle/watch-attribution.d.mts +1 -1
- package/dist/substrate/runtime/lifecycle/watch-attribution.mjs +0 -1
- package/dist/substrate/runtime/lifecycle/watch-attribution.mjs.map +1 -1
- package/dist/substrate/runtime/managed-container.d.mts +5 -1
- package/dist/substrate/runtime/managed-container.mjs +8 -10
- package/dist/substrate/runtime/managed-container.mjs.map +1 -1
- package/dist/substrate/runtime/manifest/manifest.mjs +8 -30
- package/dist/substrate/runtime/manifest/manifest.mjs.map +1 -1
- package/dist/substrate/runtime/mode-errors.d.mts +1 -2
- package/dist/substrate/runtime/mode-errors.mjs.map +1 -1
- package/dist/substrate/runtime/observability/cascade-formatter.mjs +1 -11
- package/dist/substrate/runtime/observability/cascade-formatter.mjs.map +1 -1
- package/dist/substrate/runtime/observability/ignore-with-log.mjs.map +1 -1
- package/dist/substrate/runtime/observability/index.d.mts +1 -1
- package/dist/substrate/runtime/observability/index.mjs +4 -6
- package/dist/substrate/runtime/observability/log-attrs.mjs +46 -0
- package/dist/substrate/runtime/observability/log-attrs.mjs.map +1 -0
- package/dist/substrate/runtime/observability/log-store.mjs.map +1 -1
- package/dist/substrate/runtime/observability/logger.mjs +3 -3
- package/dist/substrate/runtime/observability/logger.mjs.map +1 -1
- package/dist/substrate/runtime/observability/output-truncate.mjs.map +1 -1
- package/dist/substrate/runtime/observability/pretty-error.mjs.map +1 -1
- package/dist/substrate/runtime/observability/process-lines.mjs.map +1 -1
- package/dist/substrate/runtime/observability/redaction.mjs.map +1 -1
- package/dist/substrate/runtime/observability/subprocess-capture.mjs +2 -2
- package/dist/substrate/runtime/observability/subprocess-capture.mjs.map +1 -1
- package/dist/substrate/runtime/passthrough-or-wrap.mjs.map +1 -1
- package/dist/substrate/runtime/paths.mjs +27 -9
- package/dist/substrate/runtime/paths.mjs.map +1 -1
- package/dist/substrate/runtime/phase-preserving-produce.mjs.map +1 -1
- package/dist/substrate/runtime/port-broker/service.mjs +10 -27
- package/dist/substrate/runtime/port-broker/service.mjs.map +1 -1
- package/dist/substrate/runtime/post-acquire-tasks.mjs.map +1 -1
- package/dist/substrate/runtime/probes.d.mts +2 -3
- package/dist/substrate/runtime/probes.mjs.map +1 -1
- package/dist/substrate/runtime/process-supervisor.mjs.map +1 -1
- package/dist/substrate/runtime/projection/operational-endpoints.mjs.map +1 -1
- package/dist/substrate/runtime/projection/state-ref.mjs.map +1 -1
- package/dist/substrate/runtime/projection/update.mjs +87 -11
- package/dist/substrate/runtime/projection/update.mjs.map +1 -1
- package/dist/substrate/runtime/random-suffix.mjs.map +1 -1
- package/dist/substrate/runtime/reconcile/fs-plan.mjs +146 -0
- package/dist/substrate/runtime/reconcile/fs-plan.mjs.map +1 -0
- package/dist/substrate/runtime/reconcile/graph.mjs +19 -0
- package/dist/substrate/runtime/reconcile/graph.mjs.map +1 -0
- package/dist/substrate/runtime/reconcile/index.mjs +5 -0
- package/dist/substrate/runtime/reconcile/label.mjs +41 -0
- package/dist/substrate/runtime/reconcile/label.mjs.map +1 -0
- package/dist/substrate/runtime/reconcile/spec.mjs +15 -0
- package/dist/substrate/runtime/reconcile/spec.mjs.map +1 -0
- package/dist/substrate/runtime/retry-policy.d.mts +2 -3
- package/dist/substrate/runtime/retry-policy.mjs.map +1 -1
- package/dist/substrate/runtime/routed-url.mjs.map +1 -1
- package/dist/substrate/runtime/runtime-decode.mjs.map +1 -1
- package/dist/substrate/runtime/scoped-http-server.mjs.map +1 -1
- package/dist/substrate/runtime/stage-and-swap/index.mjs +49 -12
- package/dist/substrate/runtime/stage-and-swap/index.mjs.map +1 -1
- package/dist/substrate/runtime/strategy-registry/chain-keyed-strategy-for.mjs.map +1 -1
- package/dist/substrate/runtime/strategy-registry/chain-probe-for.mjs.map +1 -1
- package/dist/substrate/runtime/strategy-registry/service.mjs +29 -17
- package/dist/substrate/runtime/strategy-registry/service.mjs.map +1 -1
- package/dist/substrate/runtime/subnet-broker.mjs.map +1 -1
- package/dist/substrate/runtime/supervisor/acquire-node.mjs +188 -56
- package/dist/substrate/runtime/supervisor/acquire-node.mjs.map +1 -1
- package/dist/substrate/runtime/supervisor/background-tasks.mjs +79 -65
- package/dist/substrate/runtime/supervisor/background-tasks.mjs.map +1 -1
- package/dist/substrate/runtime/supervisor/command-loop.mjs +82 -23
- package/dist/substrate/runtime/supervisor/command-loop.mjs.map +1 -1
- package/dist/substrate/runtime/supervisor/contribution-dispatcher.mjs +16 -0
- package/dist/substrate/runtime/supervisor/contribution-dispatcher.mjs.map +1 -0
- package/dist/substrate/runtime/supervisor/errors.mjs +11 -2
- package/dist/substrate/runtime/supervisor/errors.mjs.map +1 -1
- package/dist/substrate/runtime/supervisor/index.mjs +2 -0
- package/dist/substrate/runtime/supervisor/shutdown.mjs +6 -6
- package/dist/substrate/runtime/supervisor/shutdown.mjs.map +1 -1
- package/dist/substrate/runtime/supervisor/start-supervisor.mjs +60 -70
- package/dist/substrate/runtime/supervisor/start-supervisor.mjs.map +1 -1
- package/dist/substrate/runtime/supervisor/state.d.mts +1 -1
- package/dist/substrate/runtime/supervisor/state.mjs +1 -1
- package/dist/substrate/runtime/supervisor/state.mjs.map +1 -1
- package/dist/substrate/runtime/supervisor/teardown.mjs +10 -9
- package/dist/substrate/runtime/supervisor/teardown.mjs.map +1 -1
- package/dist/substrate/runtime/supervisor/wiring.mjs +6 -20
- package/dist/substrate/runtime/supervisor/wiring.mjs.map +1 -1
- package/dist/substrate/runtime/tar/reader.mjs +216 -0
- package/dist/substrate/runtime/tar/reader.mjs.map +1 -0
- package/dist/substrate/runtime/typed-env.mjs.map +1 -1
- package/dist/substrate/versioned-doc-schema.mjs.map +1 -1
- package/dist/substrate/versioned-doc-sync.mjs +5 -5
- package/dist/substrate/versioned-doc-sync.mjs.map +1 -1
- package/dist/surfaces/cli/command-tree.mjs +49 -7
- package/dist/surfaces/cli/command-tree.mjs.map +1 -1
- package/dist/surfaces/cli/commands/config.mjs +1 -1
- package/dist/surfaces/cli/commands/config.mjs.map +1 -1
- package/dist/surfaces/cli/commands/confirm-node.mjs.map +1 -1
- package/dist/surfaces/cli/commands/confirm.mjs.map +1 -1
- package/dist/surfaces/cli/commands/doctor.mjs +1 -1
- package/dist/surfaces/cli/commands/doctor.mjs.map +1 -1
- package/dist/surfaces/cli/commands/prune-picker-entry.mjs.map +1 -1
- package/dist/surfaces/cli/commands/prune-picker.mjs.map +1 -1
- package/dist/surfaces/cli/commands/prune.mjs +1 -1
- package/dist/surfaces/cli/commands/prune.mjs.map +1 -1
- package/dist/surfaces/cli/commands/snapshot.mjs +1 -1
- package/dist/surfaces/cli/commands/snapshot.mjs.map +1 -1
- package/dist/surfaces/cli/commands/status.mjs +1 -1
- package/dist/surfaces/cli/commands/status.mjs.map +1 -1
- package/dist/surfaces/cli/commands/supervisor-presence.mjs.map +1 -1
- package/dist/surfaces/cli/commands/wipe.mjs +3 -4
- package/dist/surfaces/cli/commands/wipe.mjs.map +1 -1
- package/dist/surfaces/cli/envelope.mjs.map +1 -1
- package/dist/surfaces/cli/errors.mjs.map +1 -1
- package/dist/surfaces/cli/flags.mjs.map +1 -1
- package/dist/surfaces/cli/index.mjs +45 -14
- package/dist/surfaces/cli/index.mjs.map +1 -1
- package/dist/surfaces/cli/output.mjs.map +1 -1
- package/dist/surfaces/cli/sysexits.mjs.map +1 -1
- package/dist/surfaces/tui/app.mjs +0 -21
- package/dist/surfaces/tui/app.mjs.map +1 -1
- package/dist/surfaces/tui/dashboard.mjs +0 -48
- package/dist/surfaces/tui/dashboard.mjs.map +1 -1
- package/dist/surfaces/tui/display-derivation.mjs +80 -16
- package/dist/surfaces/tui/display-derivation.mjs.map +1 -1
- package/dist/surfaces/tui/errors.mjs.map +1 -1
- package/dist/surfaces/tui/event-log.mjs +0 -9
- package/dist/surfaces/tui/event-log.mjs.map +1 -1
- package/dist/surfaces/tui/heartbeat.mjs.map +1 -1
- package/dist/surfaces/tui/index.mjs +2 -2
- package/dist/surfaces/tui/index.mjs.map +1 -1
- package/dist/surfaces/tui/input.mjs.map +1 -1
- package/dist/surfaces/tui/mode-detect.mjs.map +1 -1
- package/dist/surfaces/tui/mount-ink.mjs.map +1 -1
- package/dist/surfaces/tui/plain-renderer.mjs +26 -19
- package/dist/surfaces/tui/plain-renderer.mjs.map +1 -1
- package/dist/surfaces/tui/resource-table.mjs +8 -10
- package/dist/surfaces/tui/resource-table.mjs.map +1 -1
- package/images/postgres/Dockerfile +0 -1
- package/images/sui/Dockerfile +27 -54
- package/images/sui/entrypoint.sh +17 -179
- package/package.json +23 -15
- package/dashboard-ui/assets/index-Bmi1UtAg.js +0 -1356
- package/dashboard-ui/assets/index-D5EShVt4.js +0 -3
- package/dashboard-ui/assets/index-Deml9drg.css +0 -1
- package/dist/api/plugin-errors.d.mts +0 -7
- package/dist/api/plugin-errors.mjs +0 -10
- package/dist/api/plugin-errors.mjs.map +0 -1
- package/dist/cli/wirings/build-verb-layers.mjs +0 -42
- package/dist/cli/wirings/build-verb-layers.mjs.map +0 -1
- package/dist/contracts/capability-decl.d.mts +0 -40
- package/dist/orchestrators/built-in-plugin-layers.mjs +0 -54
- package/dist/orchestrators/built-in-plugin-layers.mjs.map +0 -1
- package/dist/orchestrators/run.mjs +0 -91
- package/dist/orchestrators/run.mjs.map +0 -1
- package/dist/orchestrators/runtime-composition.d.mts +0 -10
- package/dist/orchestrators/runtime-composition.mjs +0 -252
- package/dist/orchestrators/runtime-composition.mjs.map +0 -1
- package/dist/orchestrators/snapshot/capture-command.d.mts +0 -1
- package/dist/orchestrators/snapshot/capture-command.mjs +0 -25
- package/dist/orchestrators/snapshot/capture-command.mjs.map +0 -1
- package/dist/orchestrators/snapshot/pending-marker.mjs +0 -99
- package/dist/orchestrators/snapshot/pending-marker.mjs.map +0 -1
- package/dist/orchestrators/snapshot/recover-pending.mjs +0 -223
- package/dist/orchestrators/snapshot/recover-pending.mjs.map +0 -1
- package/dist/orchestrators/snapshot/state-document.d.mts +0 -1
- package/dist/orchestrators/snapshot/state-document.mjs +0 -58
- package/dist/orchestrators/snapshot/state-document.mjs.map +0 -1
- package/dist/plugins/account/spans.mjs +0 -16
- package/dist/plugins/account/spans.mjs.map +0 -1
- package/dist/plugins/account/variants/env.mjs +0 -24
- package/dist/plugins/account/variants/env.mjs.map +0 -1
- package/dist/plugins/account/variants/inline.mjs +0 -13
- package/dist/plugins/account/variants/inline.mjs.map +0 -1
- package/dist/plugins/account/variants/keystore.mjs +0 -91
- package/dist/plugins/account/variants/keystore.mjs.map +0 -1
- package/dist/plugins/action/spans.mjs +0 -11
- package/dist/plugins/action/spans.mjs.map +0 -1
- package/dist/plugins/coin/spans.mjs +0 -20
- package/dist/plugins/coin/spans.mjs.map +0 -1
- package/dist/plugins/deepbook/spans.mjs +0 -18
- package/dist/plugins/deepbook/spans.mjs.map +0 -1
- package/dist/plugins/faucet/spans.mjs +0 -12
- package/dist/plugins/faucet/spans.mjs.map +0 -1
- package/dist/plugins/package/spans.mjs +0 -14
- package/dist/plugins/package/spans.mjs.map +0 -1
- package/dist/plugins/postgres/codegen.mjs +0 -42
- package/dist/plugins/postgres/codegen.mjs.map +0 -1
- package/dist/plugins/postgres/connection.d.mts +0 -33
- package/dist/plugins/postgres/connection.mjs.map +0 -1
- package/dist/plugins/postgres/db-ensure.mjs.map +0 -1
- package/dist/plugins/postgres/errors.d.mts +0 -60
- package/dist/plugins/postgres/errors.mjs +0 -29
- package/dist/plugins/postgres/errors.mjs.map +0 -1
- package/dist/plugins/postgres/index.d.mts +0 -37
- package/dist/plugins/postgres/index.mjs +0 -68
- package/dist/plugins/postgres/index.mjs.map +0 -1
- package/dist/plugins/postgres/routable.mjs +0 -33
- package/dist/plugins/postgres/routable.mjs.map +0 -1
- package/dist/plugins/postgres/service.d.mts +0 -50
- package/dist/plugins/postgres/service.mjs +0 -179
- package/dist/plugins/postgres/service.mjs.map +0 -1
- package/dist/plugins/postgres/snapshot.mjs +0 -32
- package/dist/plugins/postgres/snapshot.mjs.map +0 -1
- package/dist/plugins/postgres/spans.mjs +0 -11
- package/dist/plugins/postgres/spans.mjs.map +0 -1
- package/dist/plugins/seal/spans.mjs +0 -18
- package/dist/plugins/seal/spans.mjs.map +0 -1
- package/dist/plugins/sui/spans.mjs +0 -17
- package/dist/plugins/sui/spans.mjs.map +0 -1
- package/dist/plugins/wallet/spans.mjs +0 -22
- package/dist/plugins/wallet/spans.mjs.map +0 -1
- package/dist/plugins/walrus/registry-publish.d.mts +0 -24
- package/dist/plugins/walrus/spans.mjs +0 -18
- package/dist/plugins/walrus/spans.mjs.map +0 -1
- package/dist/runtime/docker/logs.d.mts +0 -1
- package/dist/runtime/docker/logs.mjs +0 -34
- package/dist/runtime/docker/logs.mjs.map +0 -1
- package/dist/substrate/runtime/artifact-publisher/index.mjs +0 -86
- package/dist/substrate/runtime/artifact-publisher/index.mjs.map +0 -1
- package/dist/substrate/runtime/capability-sinks/index.d.mts +0 -1
- package/dist/substrate/runtime/capability-sinks/index.mjs +0 -3
- package/dist/substrate/runtime/capability-sinks/layer.d.mts +0 -1
- package/dist/substrate/runtime/capability-sinks/layer.mjs +0 -31
- package/dist/substrate/runtime/capability-sinks/layer.mjs.map +0 -1
- package/dist/substrate/runtime/capability-sinks/service.d.mts +0 -95
- package/dist/substrate/runtime/capability-sinks/service.mjs +0 -69
- package/dist/substrate/runtime/capability-sinks/service.mjs.map +0 -1
- package/dist/substrate/runtime/cross-process/lock.d.mts +0 -1
- package/dist/substrate/runtime/cross-process/lock.mjs +0 -23
- package/dist/substrate/runtime/cross-process/lock.mjs.map +0 -1
- package/dist/substrate/runtime/cross-process/snapshot-reservation.mjs +0 -113
- package/dist/substrate/runtime/cross-process/snapshot-reservation.mjs.map +0 -1
- package/dist/substrate/runtime/lifecycle/lifecycle-fact.mjs +0 -31
- package/dist/substrate/runtime/lifecycle/lifecycle-fact.mjs.map +0 -1
- package/dist/substrate/runtime/observability/formatter-registry.d.mts +0 -1
- package/dist/substrate/runtime/observability/formatter-registry.mjs +0 -48
- package/dist/substrate/runtime/observability/formatter-registry.mjs.map +0 -1
- package/dist/substrate/runtime/observability/span-store.d.mts +0 -1
- package/dist/substrate/runtime/observability/span-store.mjs +0 -110
- package/dist/substrate/runtime/observability/span-store.mjs.map +0 -1
- package/dist/substrate/runtime/observability/spans.d.mts +0 -1
- package/dist/substrate/runtime/observability/spans.mjs +0 -87
- package/dist/substrate/runtime/observability/spans.mjs.map +0 -1
- package/dist/substrate/runtime/projection/index.mjs +0 -4
- package/dist/substrate/runtime/projection/persisted.mjs +0 -213
- package/dist/substrate/runtime/projection/persisted.mjs.map +0 -1
- package/dist/substrate/runtime/scoped-multimap/service.mjs +0 -52
- package/dist/substrate/runtime/scoped-multimap/service.mjs.map +0 -1
- package/dist/substrate/runtime/scoped-ref-map/index.mjs +0 -2
- package/dist/substrate/runtime/scoped-ref-map/service.mjs +0 -83
- package/dist/substrate/runtime/scoped-ref-map/service.mjs.map +0 -1
- package/dist/substrate/runtime/state-store/index.mjs +0 -3
- package/dist/substrate/runtime/state-store/schema.d.mts +0 -1
- package/dist/substrate/runtime/state-store/schema.mjs +0 -41
- package/dist/substrate/runtime/state-store/schema.mjs.map +0 -1
- package/dist/substrate/runtime/state-store/service.d.mts +0 -1
- package/dist/substrate/runtime/state-store/service.mjs +0 -145
- package/dist/substrate/runtime/state-store/service.mjs.map +0 -1
- package/dist/substrate/runtime/sui-execute/index.mjs.map +0 -1
- package/dist/substrate/runtime/sui-execute/sign-and-dispatch.mjs.map +0 -1
- package/dist/substrate/runtime/sui-ledger/object-ref.mjs.map +0 -1
- package/dist/substrate/runtime/sui-move-build/index.mjs.map +0 -1
- package/dist/substrate/runtime/supervisor/dispatch-contributions.mjs +0 -151
- package/dist/substrate/runtime/supervisor/dispatch-contributions.mjs.map +0 -1
- package/dist/substrate/state-store.d.mts +0 -1
- /package/dist/orchestrators/{snapshot/pending-marker.d.mts → codegen/id-config.d.mts} +0 -0
- /package/dist/orchestrators/snapshot/{recover-pending.d.mts → interrupted-restore.d.mts} +0 -0
- /package/dist/{substrate/runtime/sui-execute → plugins/sui/exec}/sign-and-dispatch.d.mts +0 -0
- /package/dist/plugins/{postgres/snapshot.d.mts → sui/ledger/object-ref.d.mts} +0 -0
- /package/dist/{substrate/runtime/sui-move-build → plugins/sui/move}/index.d.mts +0 -0
- /package/dist/substrate/runtime/{state-store/index.d.mts → reconcile/graph.d.mts} +0 -0
- /package/dist/substrate/runtime/{cross-process/snapshot-reservation.d.mts → supervisor/contribution-dispatcher.d.mts} +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runtime-decode.mjs","names":[],"sources":["../../../src/substrate/runtime/runtime-decode.ts"],"sourcesContent":["// Compound Schema decode at trust boundaries — JSON / unknown →\n// typed values, with one parse/decode issue shape and typed error\n// projection. Reach for `decodeUnknown(Sync)` /\n// `decodeJsonText(Sync)` when you have a Schema and want to decode\n// a whole shape (multi-field, refinements, transforms).\n//\n// For one-field shape checks (\"port must be a positive integer\",\n// \"name must be a non-empty string\") that throw on bad input,\n// reach for the `expect*` helpers in `config-validation.ts` instead.\n\nimport { Effect, Schema } from 'effect';\n\nexport interface RuntimeDecodeIssue {\n\treadonly source: string;\n\treadonly message: string;\n\treadonly cause?: unknown;\n}\n\nexport type RuntimeDecodeErrorFactory<E> = (issue: RuntimeDecodeIssue) => E;\n\nexport interface DecodeOptions<E> {\n\treadonly source: string;\n\treadonly mkError: RuntimeDecodeErrorFactory<E>;\n\treadonly message?: string;\n}\n\nexport interface JsonArrayElementDecodeOptions<E> extends DecodeOptions<E> {\n\treadonly index?: number;\n\treadonly missingMessage?: string;\n}\n\nconst issue = <E>(\n\toptions: DecodeOptions<E>,\n\tmessage: string,\n\tcause?: unknown,\n): RuntimeDecodeIssue => ({\n\tsource: options.source,\n\tmessage: options.message ?? message,\n\t...(cause === undefined ? {} : { cause }),\n});\n\nexport const parseJsonText = <E>(\n\ttext: string,\n\toptions: DecodeOptions<E>,\n): Effect.Effect<unknown, E> =>\n\tEffect.try({\n\t\ttry: () => JSON.parse(text) as unknown,\n\t\tcatch: (cause) => options.mkError(issue(options, 'failed to parse JSON', cause)),\n\t});\n\nexport const parseJsonTextSync = <E>(text: string, options: DecodeOptions<E>): unknown => {\n\ttry {\n\t\treturn JSON.parse(text) as unknown;\n\t} catch (cause) {\n\t\tthrow options.mkError(issue(options, 'failed to parse JSON', cause));\n\t}\n};\n\nexport const decodeUnknown = <S extends Schema.Decoder<unknown>, E>(\n\tschema: S,\n\tvalue: unknown,\n\toptions: DecodeOptions<E>,\n): Effect.Effect<S['Type'], E> =>\n\tSchema.decodeUnknownEffect(schema)(value).pipe(\n\t\tEffect.mapError((cause) => options.mkError(issue(options, 'failed to decode value', cause))),\n\t);\n\nexport const decodeUnknownSync = <S extends Schema.Decoder<unknown>, E>(\n\tschema: S,\n\tvalue: unknown,\n\toptions: DecodeOptions<E>,\n): S['Type'] => {\n\ttry {\n\t\treturn Schema.decodeUnknownSync(schema)(value);\n\t} catch (cause) {\n\t\tthrow options.mkError(issue(options, 'failed to decode value', cause));\n\t}\n};\n\nexport const decodeJsonText = <S extends Schema.Decoder<unknown>, E>(\n\tschema: S,\n\ttext: string,\n\toptions: DecodeOptions<E>,\n): Effect.Effect<S['Type'], E> =>\n\tparseJsonText(text, options).pipe(\n\t\tEffect.flatMap((value) => decodeUnknown(schema, value, options)),\n\t);\n\nexport const decodeJsonTextSync = <S extends Schema.Decoder<unknown>, E>(\n\tschema: S,\n\ttext: string,\n\toptions: DecodeOptions<E>,\n): S['Type'] => decodeUnknownSync(schema, parseJsonTextSync(text, options), options);\n\nexport const decodeJsonArrayElementSync = <S extends Schema.Decoder<unknown>, E>(\n\tschema: S,\n\ttext: string,\n\toptions: JsonArrayElementDecodeOptions<E>,\n): S['Type'] => {\n\tconst index = options.index ?? 0;\n\tconst value = parseJsonTextSync(text, options);\n\tif (!Array.isArray(value) || value[index] === undefined) {\n\t\tthrow options.mkError(\n\t\t\tissue(\n\t\t\t\toptions,\n\t\t\t\toptions.missingMessage ?? `expected JSON array element at index ${index}`,\n\t\t\t\tvalue,\n\t\t\t),\n\t\t);\n\t}\n\treturn decodeUnknownSync(schema, value[index], options);\n};\n\nexport const decodeJsonLines = <S extends Schema.Decoder<unknown>, E>(\n\tschema: S,\n\ttext: string,\n\toptions: DecodeOptions<E>,\n): Effect.Effect<ReadonlyArray<S['Type']>, E> =>\n\tEffect.forEach(\n\t\ttext\n\t\t\t.split(/\\r?\\n/u)\n\t\t\t.map((line) => line.trim())\n\t\t\t.filter((line) => line.length > 0),\n\t\t(line, index) =>\n\t\t\tdecodeJsonText(schema, line, {\n\t\t\t\t...options,\n\t\t\t\tsource: `${options.source}:${index + 1}`,\n\t\t\t}),\n\t);\n"],"mappings":";;;;;;;;;;;;;AA+BA,MAAM,SACL,SACA,SACA,WACyB;CACzB,QAAQ,QAAQ;CAChB,SAAS,QAAQ,WAAW;CAC5B,GAAI,UAAU,KAAA,IAAY,
|
|
1
|
+
{"version":3,"file":"runtime-decode.mjs","names":[],"sources":["../../../src/substrate/runtime/runtime-decode.ts"],"sourcesContent":["// Compound Schema decode at trust boundaries — JSON / unknown →\n// typed values, with one parse/decode issue shape and typed error\n// projection. Reach for `decodeUnknown(Sync)` /\n// `decodeJsonText(Sync)` when you have a Schema and want to decode\n// a whole shape (multi-field, refinements, transforms).\n//\n// For one-field shape checks (\"port must be a positive integer\",\n// \"name must be a non-empty string\") that throw on bad input,\n// reach for the `expect*` helpers in `config-validation.ts` instead.\n\nimport { Effect, Schema } from 'effect';\n\nexport interface RuntimeDecodeIssue {\n\treadonly source: string;\n\treadonly message: string;\n\treadonly cause?: unknown;\n}\n\nexport type RuntimeDecodeErrorFactory<E> = (issue: RuntimeDecodeIssue) => E;\n\nexport interface DecodeOptions<E> {\n\treadonly source: string;\n\treadonly mkError: RuntimeDecodeErrorFactory<E>;\n\treadonly message?: string;\n}\n\nexport interface JsonArrayElementDecodeOptions<E> extends DecodeOptions<E> {\n\treadonly index?: number;\n\treadonly missingMessage?: string;\n}\n\nconst issue = <E>(\n\toptions: DecodeOptions<E>,\n\tmessage: string,\n\tcause?: unknown,\n): RuntimeDecodeIssue => ({\n\tsource: options.source,\n\tmessage: options.message ?? message,\n\t...(cause === undefined ? {} : { cause }),\n});\n\nexport const parseJsonText = <E>(\n\ttext: string,\n\toptions: DecodeOptions<E>,\n): Effect.Effect<unknown, E> =>\n\tEffect.try({\n\t\ttry: () => JSON.parse(text) as unknown,\n\t\tcatch: (cause) => options.mkError(issue(options, 'failed to parse JSON', cause)),\n\t});\n\nexport const parseJsonTextSync = <E>(text: string, options: DecodeOptions<E>): unknown => {\n\ttry {\n\t\treturn JSON.parse(text) as unknown;\n\t} catch (cause) {\n\t\tthrow options.mkError(issue(options, 'failed to parse JSON', cause));\n\t}\n};\n\nexport const decodeUnknown = <S extends Schema.Decoder<unknown>, E>(\n\tschema: S,\n\tvalue: unknown,\n\toptions: DecodeOptions<E>,\n): Effect.Effect<S['Type'], E> =>\n\tSchema.decodeUnknownEffect(schema)(value).pipe(\n\t\tEffect.mapError((cause) => options.mkError(issue(options, 'failed to decode value', cause))),\n\t);\n\nexport const decodeUnknownSync = <S extends Schema.Decoder<unknown>, E>(\n\tschema: S,\n\tvalue: unknown,\n\toptions: DecodeOptions<E>,\n): S['Type'] => {\n\ttry {\n\t\treturn Schema.decodeUnknownSync(schema)(value);\n\t} catch (cause) {\n\t\tthrow options.mkError(issue(options, 'failed to decode value', cause));\n\t}\n};\n\nexport const decodeJsonText = <S extends Schema.Decoder<unknown>, E>(\n\tschema: S,\n\ttext: string,\n\toptions: DecodeOptions<E>,\n): Effect.Effect<S['Type'], E> =>\n\tparseJsonText(text, options).pipe(\n\t\tEffect.flatMap((value) => decodeUnknown(schema, value, options)),\n\t);\n\nexport const decodeJsonTextSync = <S extends Schema.Decoder<unknown>, E>(\n\tschema: S,\n\ttext: string,\n\toptions: DecodeOptions<E>,\n): S['Type'] => decodeUnknownSync(schema, parseJsonTextSync(text, options), options);\n\nexport const decodeJsonArrayElementSync = <S extends Schema.Decoder<unknown>, E>(\n\tschema: S,\n\ttext: string,\n\toptions: JsonArrayElementDecodeOptions<E>,\n): S['Type'] => {\n\tconst index = options.index ?? 0;\n\tconst value = parseJsonTextSync(text, options);\n\tif (!Array.isArray(value) || value[index] === undefined) {\n\t\tthrow options.mkError(\n\t\t\tissue(\n\t\t\t\toptions,\n\t\t\t\toptions.missingMessage ?? `expected JSON array element at index ${index}`,\n\t\t\t\tvalue,\n\t\t\t),\n\t\t);\n\t}\n\treturn decodeUnknownSync(schema, value[index], options);\n};\n\nexport const decodeJsonLines = <S extends Schema.Decoder<unknown>, E>(\n\tschema: S,\n\ttext: string,\n\toptions: DecodeOptions<E>,\n): Effect.Effect<ReadonlyArray<S['Type']>, E> =>\n\tEffect.forEach(\n\t\ttext\n\t\t\t.split(/\\r?\\n/u)\n\t\t\t.map((line) => line.trim())\n\t\t\t.filter((line) => line.length > 0),\n\t\t(line, index) =>\n\t\t\tdecodeJsonText(schema, line, {\n\t\t\t\t...options,\n\t\t\t\tsource: `${options.source}:${index + 1}`,\n\t\t\t}),\n\t);\n"],"mappings":";;;;;;;;;;;;;AA+BA,MAAM,SACL,SACA,SACA,WACyB;CACzB,QAAQ,QAAQ;CAChB,SAAS,QAAQ,WAAW;CAC5B,GAAI,UAAU,KAAA,IAAY,CAAC,IAAI,EAAE,MAAM;AACxC;AAEA,MAAa,iBACZ,MACA,YAEA,OAAO,IAAI;CACV,WAAW,KAAK,MAAM,IAAI;CAC1B,QAAQ,UAAU,QAAQ,QAAQ,MAAM,SAAS,wBAAwB,KAAK,CAAC;AAChF,CAAC;AAEF,MAAa,qBAAwB,MAAc,YAAuC;CACzF,IAAI;EACH,OAAO,KAAK,MAAM,IAAI;CACvB,SAAS,OAAO;EACf,MAAM,QAAQ,QAAQ,MAAM,SAAS,wBAAwB,KAAK,CAAC;CACpE;AACD;AAEA,MAAa,iBACZ,QACA,OACA,YAEA,OAAO,oBAAoB,MAAM,CAAC,CAAC,KAAK,CAAC,CAAC,KACzC,OAAO,UAAU,UAAU,QAAQ,QAAQ,MAAM,SAAS,0BAA0B,KAAK,CAAC,CAAC,CAC5F;AAED,MAAa,qBACZ,QACA,OACA,YACe;CACf,IAAI;EACH,OAAO,OAAO,kBAAkB,MAAM,CAAC,CAAC,KAAK;CAC9C,SAAS,OAAO;EACf,MAAM,QAAQ,QAAQ,MAAM,SAAS,0BAA0B,KAAK,CAAC;CACtE;AACD;AAEA,MAAa,kBACZ,QACA,MACA,YAEA,cAAc,MAAM,OAAO,CAAC,CAAC,KAC5B,OAAO,SAAS,UAAU,cAAc,QAAQ,OAAO,OAAO,CAAC,CAChE;AAED,MAAa,sBACZ,QACA,MACA,YACe,kBAAkB,QAAQ,kBAAkB,MAAM,OAAO,GAAG,OAAO;AAEnF,MAAa,8BACZ,QACA,MACA,YACe;CACf,MAAM,QAAQ,QAAQ,SAAS;CAC/B,MAAM,QAAQ,kBAAkB,MAAM,OAAO;CAC7C,IAAI,CAAC,MAAM,QAAQ,KAAK,KAAK,MAAM,WAAW,KAAA,GAC7C,MAAM,QAAQ,QACb,MACC,SACA,QAAQ,kBAAkB,wCAAwC,SAClE,KACD,CACD;CAED,OAAO,kBAAkB,QAAQ,MAAM,QAAQ,OAAO;AACvD;AAEA,MAAa,mBACZ,QACA,MACA,YAEA,OAAO,QACN,KACE,MAAM,QAAQ,CAAC,CACf,KAAK,SAAS,KAAK,KAAK,CAAC,CAAC,CAC1B,QAAQ,SAAS,KAAK,SAAS,CAAC,IACjC,MAAM,UACN,eAAe,QAAQ,MAAM;CAC5B,GAAG;CACH,QAAQ,GAAG,QAAQ,OAAO,GAAG,QAAQ;AACtC,CAAC,CACH"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scoped-http-server.mjs","names":[],"sources":["../../../src/substrate/runtime/scoped-http-server.ts"],"sourcesContent":["// Scoped host HTTP server primitive.\n//\n// Generic ownership for in-process host HTTP listeners: bind, surface\n// listen failures through a caller-owned error mapper, and install a\n// scope finalizer that drops idle keepalive sockets before awaiting\n// close. Domain routing stays with the plugin that supplies the\n// Node request listener.\n\nimport { Effect } from 'effect';\nimport type { Scope } from 'effect';\nimport { createServer, type IncomingMessage, type Server, type ServerResponse } from 'node:http';\n\nexport type HttpRequestListener = (req: IncomingMessage, res: ServerResponse) => void;\n\nexport interface ScopedHttpServerOptions<E> {\n\treadonly bindAddress: string;\n\treadonly port: number;\n\treadonly listener: HttpRequestListener;\n\treadonly onListenError: (cause: unknown) => E;\n}\n\nexport interface ScopedHttpServerHandle {\n\treadonly url: string;\n\treadonly server: Server;\n\treadonly close: () => Effect.Effect<void>;\n}\n\n/** Best-effort graceful close. `closeAllConnections()` drops idle\n * keepalive sockets so `close()` resolves; older Node versions\n * without `closeAllConnections` rely on `close()` alone. */\nexport const gracefulCloseHttpServer = (server: Server): Effect.Effect<void> =>\n\tEffect.callback<void>((resume) => {\n\t\ttry {\n\t\t\tserver.closeAllConnections();\n\t\t} catch {\n\t\t\t// Older Node versions don't expose closeAllConnections;\n\t\t\t// `close()` alone will still terminate.\n\t\t}\n\t\tserver.close(() => resume(Effect.void));\n\t});\n\nexport const listenScopedHttpServer = <E>(\n\toptions: ScopedHttpServerOptions<E>,\n): Effect.Effect<ScopedHttpServerHandle, E, Scope.Scope> =>\n\tEffect.gen(function* () {\n\t\t// `acquireRelease` pairs the bound server with its close finalizer\n\t\t// atomically: the moment `listen` resolves, the graceful-close\n\t\t// finalizer is registered, so an interruption between bind and\n\t\t// finalizer registration
|
|
1
|
+
{"version":3,"file":"scoped-http-server.mjs","names":[],"sources":["../../../src/substrate/runtime/scoped-http-server.ts"],"sourcesContent":["// Scoped host HTTP server primitive.\n//\n// Generic ownership for in-process host HTTP listeners: bind, surface\n// listen failures through a caller-owned error mapper, and install a\n// scope finalizer that drops idle keepalive sockets before awaiting\n// close. Domain routing stays with the plugin that supplies the\n// Node request listener.\n\nimport { Effect } from 'effect';\nimport type { Scope } from 'effect';\nimport { createServer, type IncomingMessage, type Server, type ServerResponse } from 'node:http';\n\nexport type HttpRequestListener = (req: IncomingMessage, res: ServerResponse) => void;\n\nexport interface ScopedHttpServerOptions<E> {\n\treadonly bindAddress: string;\n\treadonly port: number;\n\treadonly listener: HttpRequestListener;\n\treadonly onListenError: (cause: unknown) => E;\n}\n\nexport interface ScopedHttpServerHandle {\n\treadonly url: string;\n\treadonly server: Server;\n\treadonly close: () => Effect.Effect<void>;\n}\n\n/** Best-effort graceful close. `closeAllConnections()` drops idle\n * keepalive sockets so `close()` resolves; older Node versions\n * without `closeAllConnections` rely on `close()` alone. */\nexport const gracefulCloseHttpServer = (server: Server): Effect.Effect<void> =>\n\tEffect.callback<void>((resume) => {\n\t\ttry {\n\t\t\tserver.closeAllConnections();\n\t\t} catch {\n\t\t\t// Older Node versions don't expose closeAllConnections;\n\t\t\t// `close()` alone will still terminate.\n\t\t}\n\t\tserver.close(() => resume(Effect.void));\n\t});\n\nexport const listenScopedHttpServer = <E>(\n\toptions: ScopedHttpServerOptions<E>,\n): Effect.Effect<ScopedHttpServerHandle, E, Scope.Scope> =>\n\tEffect.gen(function* () {\n\t\t// `acquireRelease` pairs the bound server with its close finalizer\n\t\t// atomically: the moment `listen` resolves, the graceful-close\n\t\t// finalizer is registered, so an interruption between bind and\n\t\t// finalizer registration cannot leak a listener holding the port.\n\t\tconst server = yield* Effect.acquireRelease(\n\t\t\tEffect.tryPromise({\n\t\t\t\ttry: () =>\n\t\t\t\t\tnew Promise<Server>((resolve, reject) => {\n\t\t\t\t\t\tconst srv = createServer(options.listener);\n\t\t\t\t\t\tconst onError = (err: Error) => reject(err);\n\t\t\t\t\t\tsrv.once('error', onError);\n\t\t\t\t\t\tsrv.listen(options.port, options.bindAddress, () => {\n\t\t\t\t\t\t\tsrv.removeListener('error', onError);\n\t\t\t\t\t\t\tresolve(srv);\n\t\t\t\t\t\t});\n\t\t\t\t\t}),\n\t\t\t\tcatch: options.onListenError,\n\t\t\t}),\n\t\t\t(srv) => gracefulCloseHttpServer(srv).pipe(Effect.uninterruptible),\n\t\t);\n\n\t\treturn {\n\t\t\turl: `http://${options.bindAddress}:${options.port}`,\n\t\t\tserver,\n\t\t\tclose: () => gracefulCloseHttpServer(server),\n\t\t};\n\t});\n"],"mappings":";;;;;;AA8BA,MAAa,2BAA2B,WACvC,OAAO,UAAgB,WAAW;CACjC,IAAI;EACH,OAAO,oBAAoB;CAC5B,QAAQ,CAGR;CACA,OAAO,YAAY,OAAO,OAAO,IAAI,CAAC;AACvC,CAAC;AAEF,MAAa,0BACZ,YAEA,OAAO,IAAI,aAAa;CAKvB,MAAM,SAAS,OAAO,OAAO,eAC5B,OAAO,WAAW;EACjB,WACC,IAAI,SAAiB,SAAS,WAAW;GACxC,MAAM,MAAM,aAAa,QAAQ,QAAQ;GACzC,MAAM,WAAW,QAAe,OAAO,GAAG;GAC1C,IAAI,KAAK,SAAS,OAAO;GACzB,IAAI,OAAO,QAAQ,MAAM,QAAQ,mBAAmB;IACnD,IAAI,eAAe,SAAS,OAAO;IACnC,QAAQ,GAAG;GACZ,CAAC;EACF,CAAC;EACF,OAAO,QAAQ;CAChB,CAAC,IACA,QAAQ,wBAAwB,GAAG,CAAC,CAAC,KAAK,OAAO,eAAe,CAClE;CAEA,OAAO;EACN,KAAK,UAAU,QAAQ,YAAY,GAAG,QAAQ;EAC9C;EACA,aAAa,wBAAwB,MAAM;CAC5C;AACD,CAAC"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { SpanAttr } from "../observability/spans.mjs";
|
|
2
1
|
import { acquireStackLock } from "../cross-process/stack-lock.mjs";
|
|
2
|
+
import { LogAttr } from "../observability/log-attrs.mjs";
|
|
3
3
|
import { Effect, FileSystem, Schema } from "effect";
|
|
4
4
|
import { dirname, isAbsolute, join, normalize, sep } from "node:path";
|
|
5
5
|
//#region src/substrate/runtime/stage-and-swap/index.ts
|
|
@@ -55,6 +55,35 @@ const errnoCode = (cause) => {
|
|
|
55
55
|
const directCause = cause.cause;
|
|
56
56
|
return codeOf(reasonCause) ?? codeOf(directCause) ?? codeOf(cause);
|
|
57
57
|
};
|
|
58
|
+
/**
|
|
59
|
+
* Roll a backed-up target back into place after a failed publish.
|
|
60
|
+
*
|
|
61
|
+
* The forward path renamed the live target away to `backupPath`; on any
|
|
62
|
+
* subsequent failure we must put it back at `targetPath` so the world looks
|
|
63
|
+
* exactly as it did at entry (contract item 5). The naive `rename(backupPath,
|
|
64
|
+
* targetPath)` throws `ENOTEMPTY`/`EEXIST` if `targetPath` is unexpectedly
|
|
65
|
+
* non-empty — e.g. a half-written staging tree that a prior interrupted run on
|
|
66
|
+
* a reused state-dir left behind, or a leftover `.bak.<id>`. That rollback
|
|
67
|
+
* bookkeeping failing is NOT a publish failure (the ORIGINAL `cause` is what we
|
|
68
|
+
* surface); it's recoverable cosmetic state.
|
|
69
|
+
*
|
|
70
|
+
* So: reap any pre-existing `targetPath` first (recursive+force, idempotent) so
|
|
71
|
+
* the rename can't collide, then rename. If the rename STILL fails we log a
|
|
72
|
+
* recoverable WARNING and swallow it — the caller's original error is the real
|
|
73
|
+
* outcome and we must not mask it with a `restore-backup` tag.
|
|
74
|
+
*/
|
|
75
|
+
const restoreBackupRename = (args) => Effect.gen(function* () {
|
|
76
|
+
const fs = yield* FileSystem.FileSystem;
|
|
77
|
+
yield* fs.remove(args.targetPath, {
|
|
78
|
+
recursive: true,
|
|
79
|
+
force: true
|
|
80
|
+
}).pipe(Effect.ignore);
|
|
81
|
+
yield* fs.rename(args.backupPath, args.targetPath).pipe(Effect.catch((cause) => Effect.logWarning("stage-and-swap rollback-backup restore did not complete").pipe(Effect.annotateLogs({
|
|
82
|
+
[LogAttr.stageAndSwapTargetPath]: args.targetPath,
|
|
83
|
+
[LogAttr.stageAndSwapStagingPath]: args.stagingPath,
|
|
84
|
+
[LogAttr.errorCode]: errnoCode(cause) ?? "unknown"
|
|
85
|
+
}))));
|
|
86
|
+
});
|
|
58
87
|
const normalizePreservedRelativePath = (relativePath) => {
|
|
59
88
|
const normalized = normalize(relativePath);
|
|
60
89
|
if (relativePath.length === 0 || isAbsolute(relativePath) || normalized === "." || normalized === ".." || normalized.startsWith(`..${sep}`)) return null;
|
|
@@ -128,10 +157,6 @@ const stageAndSwap = (args) => Effect.gen(function* () {
|
|
|
128
157
|
const { targetPath, build, preserveFromTarget = [], preserveOnPreseed = false, publishLockPath } = args;
|
|
129
158
|
const stagingPath = args.stagingPath ?? `${targetPath}.staging.${args.idSuffix}`;
|
|
130
159
|
const backupPath = args.backupPath ?? `${targetPath}.bak.${args.idSuffix}`;
|
|
131
|
-
yield* Effect.annotateCurrentSpan({
|
|
132
|
-
"devstack.stage-and-swap.target": targetPath,
|
|
133
|
-
"devstack.stage-and-swap.staging": stagingPath
|
|
134
|
-
});
|
|
135
160
|
yield* fs.remove(stagingPath, {
|
|
136
161
|
recursive: true,
|
|
137
162
|
force: true
|
|
@@ -161,19 +186,27 @@ const stageAndSwap = (args) => Effect.gen(function* () {
|
|
|
161
186
|
stagingPath,
|
|
162
187
|
preservedPaths: preserveFromTarget
|
|
163
188
|
}).pipe(Effect.catch((error) => Effect.gen(function* () {
|
|
164
|
-
yield*
|
|
189
|
+
yield* restoreBackupRename({
|
|
190
|
+
backupPath,
|
|
191
|
+
targetPath,
|
|
192
|
+
stagingPath
|
|
193
|
+
});
|
|
165
194
|
return yield* Effect.fail(error);
|
|
166
195
|
})));
|
|
167
196
|
}
|
|
168
197
|
yield* fs.rename(stagingPath, targetPath).pipe(Effect.catch((cause) => {
|
|
169
198
|
if (errnoCode(cause) === "EXDEV") return Effect.gen(function* () {
|
|
170
199
|
yield* Effect.logWarning("stage-and-swap cross-filesystem fallback").pipe(Effect.annotateLogs({
|
|
171
|
-
[
|
|
172
|
-
[
|
|
173
|
-
[
|
|
200
|
+
[LogAttr.stageAndSwapTargetPath]: targetPath,
|
|
201
|
+
[LogAttr.stageAndSwapStagingPath]: stagingPath,
|
|
202
|
+
[LogAttr.errorCode]: "EXDEV"
|
|
174
203
|
}));
|
|
175
204
|
yield* fs.copy(stagingPath, targetPath, { overwrite: false }).pipe(Effect.catch((copyCause) => Effect.gen(function* () {
|
|
176
|
-
if (targetExists) yield*
|
|
205
|
+
if (targetExists) yield* restoreBackupRename({
|
|
206
|
+
backupPath,
|
|
207
|
+
targetPath,
|
|
208
|
+
stagingPath
|
|
209
|
+
});
|
|
177
210
|
return yield* failStage("cross-filesystem-fallback", targetPath, stagingPath)(copyCause);
|
|
178
211
|
})));
|
|
179
212
|
yield* fs.remove(stagingPath, {
|
|
@@ -182,7 +215,11 @@ const stageAndSwap = (args) => Effect.gen(function* () {
|
|
|
182
215
|
}).pipe(Effect.ignore);
|
|
183
216
|
});
|
|
184
217
|
return Effect.gen(function* () {
|
|
185
|
-
if (targetExists) yield*
|
|
218
|
+
if (targetExists) yield* restoreBackupRename({
|
|
219
|
+
backupPath,
|
|
220
|
+
targetPath,
|
|
221
|
+
stagingPath
|
|
222
|
+
});
|
|
186
223
|
return yield* failStage("rename-into-target", targetPath, stagingPath)(cause);
|
|
187
224
|
});
|
|
188
225
|
}));
|
|
@@ -192,7 +229,7 @@ const stageAndSwap = (args) => Effect.gen(function* () {
|
|
|
192
229
|
force: true
|
|
193
230
|
}).pipe(Effect.ignore);
|
|
194
231
|
return result;
|
|
195
|
-
})
|
|
232
|
+
});
|
|
196
233
|
//#endregion
|
|
197
234
|
export { StageAndSwapError, stageAndSwap };
|
|
198
235
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":[],"sources":["../../../../src/substrate/runtime/stage-and-swap/index.ts"],"sourcesContent":["// Atomic stage-and-swap primitive.\n//\n// Architecture §\"Stage-and-swap rollback discipline is precious and\n// well-tested\": one tempdir, one rename for the whole publish.\n// Lifted to substrate so both snapshot AND codegen (per-cycle outer\n// swap) can consume — see ARCHITECTURE.md substrate roster + style\n// guide §19 (Open slot O14 closes with this lift).\n//\n// Contract:\n// 1. The caller provides a `targetPath` (the directory to publish).\n// 2. The orchestrator runs the build effect with a `stagingPath`\n// (a sibling under the same parent so the rename stays on the\n// same filesystem — POSIX rename atomicity is per-filesystem).\n// 3. If the build effect succeeds AND the rename succeeds, the\n// target now points at the new tree; external watchers never\n// observed a half-written intermediate.\n// 4. Optional `preserveFromTarget` paths are copied from the backed-up\n// target into staging immediately before publish.\n// 5. On any failure the staging directory is removed; the previous\n// target (if any) is restored verbatim from a same-parent\n// backup.\n// 6. Cross-filesystem fallback (`EXDEV` from rename) logs and falls\n// back to copy-then-rm — the architecture's documented exception.\n//\n// Discipline carried verbatim from the legacy `engine/snapshot/stage-\n// and-swap.ts` (distilled §17).\n\nimport { dirname, isAbsolute, join, normalize, sep } from 'node:path';\n\nimport { Effect, FileSystem, Schema } from 'effect';\n\nimport { acquireStackLock } from '../cross-process/stack-lock.ts';\nimport { SpanAttr } from '../observability/spans.ts';\n\n// -----------------------------------------------------------------------------\n// Errors\n// -----------------------------------------------------------------------------\n\n/** Tagged failure during a stage-and-swap step. `stage` discriminates\n * the precise failing step; the caller's underlying tag is preserved\n * via `cause` (the primitive does NOT wrap the user's error). */\nexport class StageAndSwapError extends Schema.TaggedErrorClass<StageAndSwapError>()(\n\t'StageAndSwapError',\n\t{\n\t\tstage: Schema.Literals([\n\t\t\t'mkdir-staging',\n\t\t\t'mkdir-backup',\n\t\t\t'build',\n\t\t\t'acquire-publish-lock',\n\t\t\t'backup-current',\n\t\t\t'preserve-target-paths',\n\t\t\t'rename-into-target',\n\t\t\t'restore-backup',\n\t\t\t'cleanup-staging',\n\t\t\t'cross-filesystem-fallback',\n\t\t]),\n\t\ttargetPath: Schema.String,\n\t\tstagingPath: Schema.String,\n\t\tcause: Schema.optional(Schema.Defect),\n\t},\n) {}\n\n// -----------------------------------------------------------------------------\n// Primitive\n// -----------------------------------------------------------------------------\n\nexport interface StageAndSwapPreservedPath {\n\treadonly relativePath: string;\n\treadonly kind: 'file' | 'directory';\n\t/** When `false`, the backed-up live copy is preserved into staging ONLY if\n\t * staging does not already carry the path — so a value the build already\n\t * placed there (e.g. a deploy cache untarred from the snapshot's host-tree)\n\t * WINS over the live copy. For a `directory` entry the skip is\n\t * all-or-nothing, not a per-file merge: if staging already has the dir, the\n\t * ENTIRE live copy is dropped, including any sub-path that existed only live\n\t * (post-snapshot drift) — the intended \"restore-to-snapshot wins\" semantic.\n\t * Defaults to `true` (always overwrite the staging copy with the live one). */\n\treadonly overwrite?: boolean;\n}\n\nconst failStage =\n\t<S extends StageAndSwapError['stage']>(\n\t\tstage: S,\n\t\ttargetPath: string,\n\t\tstagingPath: string,\n\t): ((cause: unknown) => Effect.Effect<never, StageAndSwapError>) =>\n\t(cause) =>\n\t\tEffect.fail(new StageAndSwapError({ stage, targetPath, stagingPath, cause }));\n\n/**\n * Extract the original Node errno `code` from a `FileSystem.rename` failure.\n *\n * Effect v4's `@effect/platform-node` wraps the raw `NodeJS.ErrnoException`\n * (`handleErrnoException` in `platform-node-shared/internal/utils.ts`) into a\n * `PlatformError` whose `reason` is a `SystemError`. The raw errno is preserved\n * as `reason.cause` (the unmodified Node error) — and the `PlatformError`\n * constructor additionally hoists that to the wrapper's own top-level `cause`.\n * So a genuine cross-filesystem rename surfaces the code at `reason.cause.code`\n * (and, equivalently, at `cause.cause.code`), NOT at the top-level `.code`.\n *\n * We probe every plausible location defensively: the nested SystemError cause,\n * the hoisted wrapper cause, and a bare-errno shape (in case a caller injects a\n * raw `NodeJS.ErrnoException` or the wrapping ever changes).\n */\nconst errnoCode = (cause: unknown): string | undefined => {\n\tconst codeOf = (value: unknown): string | undefined => {\n\t\tif (typeof value !== 'object' || value === null) return undefined;\n\t\tconst code = (value as { code?: unknown }).code;\n\t\treturn typeof code === 'string' ? code : undefined;\n\t};\n\tif (typeof cause !== 'object' || cause === null) return undefined;\n\tconst reasonCause = (cause as { reason?: { cause?: unknown } }).reason?.cause;\n\tconst directCause = (cause as { cause?: unknown }).cause;\n\treturn codeOf(reasonCause) ?? codeOf(directCause) ?? codeOf(cause);\n};\n\nconst normalizePreservedRelativePath = (relativePath: string): string | null => {\n\tconst normalized = normalize(relativePath);\n\tif (\n\t\trelativePath.length === 0 ||\n\t\tisAbsolute(relativePath) ||\n\t\tnormalized === '.' ||\n\t\tnormalized === '..' ||\n\t\tnormalized.startsWith(`..${sep}`)\n\t) {\n\t\treturn null;\n\t}\n\treturn normalized;\n};\n\nconst preserveTargetPaths = (args: {\n\treadonly backupPath: string;\n\treadonly targetPath: string;\n\treadonly stagingPath: string;\n\treadonly preservedPaths: ReadonlyArray<StageAndSwapPreservedPath>;\n}): Effect.Effect<void, StageAndSwapError, FileSystem.FileSystem> =>\n\tEffect.gen(function* () {\n\t\tconst fs = yield* FileSystem.FileSystem;\n\t\tfor (const preserved of args.preservedPaths) {\n\t\t\tconst relativePath = normalizePreservedRelativePath(preserved.relativePath);\n\t\t\tif (relativePath === null) {\n\t\t\t\treturn yield* failStage(\n\t\t\t\t\t'preserve-target-paths',\n\t\t\t\t\targs.targetPath,\n\t\t\t\t\targs.stagingPath,\n\t\t\t\t)(new Error(`unsafe preserved path: ${preserved.relativePath}`));\n\t\t\t}\n\t\t\tconst source = join(args.backupPath, relativePath);\n\t\t\tconst exists = yield* fs.exists(source).pipe(Effect.catch(() => Effect.succeed(false)));\n\t\t\tif (!exists) continue;\n\t\t\tconst target = join(args.stagingPath, relativePath);\n\t\t\t// `overwrite: false` — don't clobber a path the build already placed in\n\t\t\t// staging (e.g. a deploy cache the snapshot captured into the host-tree\n\t\t\t// tar): that captured copy is consistent with the restored chain, so it\n\t\t\t// WINS over the live copy. The live copy is only a fallback when staging\n\t\t\t// doesn't already carry it (e.g. a pre-capture snapshot).\n\t\t\tif (preserved.overwrite === false) {\n\t\t\t\tconst targetExists = yield* fs\n\t\t\t\t\t.exists(target)\n\t\t\t\t\t.pipe(Effect.catch(() => Effect.succeed(false)));\n\t\t\t\tif (targetExists) continue;\n\t\t\t}\n\t\t\tyield* fs\n\t\t\t\t.makeDirectory(dirname(target), { recursive: true })\n\t\t\t\t.pipe(Effect.catch(failStage('preserve-target-paths', args.targetPath, args.stagingPath)));\n\t\t\tyield* fs\n\t\t\t\t.copy(source, target, { overwrite: true })\n\t\t\t\t.pipe(Effect.catch(failStage('preserve-target-paths', args.targetPath, args.stagingPath)));\n\t\t}\n\t});\n\n/**\n * Build-then-swap. `build` is a user effect that populates `stagingPath`;\n * on success the helper:\n *\n * - backs up the current `targetPath` (if any) to `<targetPath>.bak.<pid>`,\n * - copies any selected `preserveFromTarget` paths from that backup\n * into staging,\n * - renames `stagingPath` → `targetPath`,\n * - removes the backup.\n *\n * On any failure the helper removes `stagingPath` and, if the backup\n * was taken, renames it back to `targetPath` so the world looks\n * exactly as it did at entry.\n *\n * The build effect's error type passes through unchanged — the\n * primitive returns `E | StageAndSwapError`. This is the\n * \"preserve the caller's error tag\" rule from distilled §17.\n *\n * IMPORTANT: stagingPath MUST be on the same filesystem as\n * targetPath. The helper picks it as a sibling under the same parent\n * (caller passes `parentDir`, we mint the names) — this is enforced\n * by the helper's signature shape.\n *\n * ## Two call shapes\n *\n * - Explicit-paths: callers that need bespoke sibling names (the\n * Seal plugin uses `.backup.` not `.bak.`; pre-existing tests use\n * literal `target.staging`/`target.bak`) pass both `stagingPath`\n * and `backupPath` directly.\n * - `idSuffix`: callers (codegen, snapshot) pass `idSuffix` and the\n * primitive mints `<targetPath>.staging.<idSuffix>` /\n * `<targetPath>.bak.<idSuffix>` so the staging/backup-naming\n * convention is owned in ONE place. Callers MUST NOT pass both\n * `idSuffix` and explicit paths.\n *\n * ## `preserveOnPreseed`\n *\n * When `true`, before the user's `build` runs the primitive copies the\n * current `targetPath` (if any) into `stagingPath` so `build` can\n * mutate that baseline incrementally. This subsumes the codegen\n * orchestrator's pre-seed dance (per-file no-touch idempotency relies\n * on seeing the previous target's mtimes). Cross-cutting with\n * `preserveFromTarget` is allowed: pre-seed clones the whole tree\n * BEFORE the build; `preserveFromTarget` cherry-picks paths AFTER the\n * build and BEFORE the swap (and reads from the backup, so the build\n * may have rewritten them in-tree). The two features answer different\n * questions and the primitive runs them in that order.\n */\nexport const stageAndSwap = <A, E>(\n\targs: {\n\t\treadonly targetPath: string;\n\t\treadonly build: Effect.Effect<A, E, FileSystem.FileSystem>;\n\t\treadonly preserveFromTarget?: ReadonlyArray<StageAndSwapPreservedPath>;\n\t\treadonly preserveOnPreseed?: boolean;\n\t\treadonly publishLockPath?: string;\n\t} & (\n\t\t| { readonly stagingPath: string; readonly backupPath: string; readonly idSuffix?: never }\n\t\t| { readonly idSuffix: string; readonly stagingPath?: never; readonly backupPath?: never }\n\t),\n): Effect.Effect<A, E | StageAndSwapError, FileSystem.FileSystem> =>\n\tEffect.gen(function* () {\n\t\tconst fs = yield* FileSystem.FileSystem;\n\t\tconst {\n\t\t\ttargetPath,\n\t\t\tbuild,\n\t\t\tpreserveFromTarget = [],\n\t\t\tpreserveOnPreseed = false,\n\t\t\tpublishLockPath,\n\t\t} = args;\n\t\tconst stagingPath =\n\t\t\targs.stagingPath ?? `${targetPath}.staging.${(args as { idSuffix: string }).idSuffix}`;\n\t\tconst backupPath =\n\t\t\targs.backupPath ?? `${targetPath}.bak.${(args as { idSuffix: string }).idSuffix}`;\n\t\tyield* Effect.annotateCurrentSpan({\n\t\t\t'devstack.stage-and-swap.target': targetPath,\n\t\t\t'devstack.stage-and-swap.staging': stagingPath,\n\t\t});\n\n\t\t// 0. Pre-clean the staging slot (a previous crash may have left\n\t\t// a sibling). recursive+force is idempotent.\n\t\tyield* fs.remove(stagingPath, { recursive: true, force: true }).pipe(Effect.ignore);\n\t\tyield* fs\n\t\t\t.makeDirectory(stagingPath, { recursive: true })\n\t\t\t.pipe(Effect.catch(failStage('mkdir-staging', targetPath, stagingPath)));\n\n\t\t// 0a. Optional pre-seed: when `preserveOnPreseed`, clone the\n\t\t// current target into staging so the build can edit it\n\t\t// incrementally (codegen needs this for per-file no-touch\n\t\t// idempotency). `preserveTimestamps: true` keeps mtimes\n\t\t// intact so HMR watchers (Vite/Turbopack — they trigger on\n\t\t// mtime, not content) stay quiet for unchanged outputs.\n\t\tif (preserveOnPreseed) {\n\t\t\tconst targetExistsForPreseed = yield* fs\n\t\t\t\t.exists(targetPath)\n\t\t\t\t.pipe(Effect.catch(() => Effect.succeed(false)));\n\t\t\tif (targetExistsForPreseed) {\n\t\t\t\tyield* fs.copy(targetPath, stagingPath, { overwrite: true, preserveTimestamps: true }).pipe(\n\t\t\t\t\tEffect.catch(failStage('mkdir-staging', targetPath, stagingPath)),\n\t\t\t\t\tEffect.onError(() =>\n\t\t\t\t\t\tfs.remove(stagingPath, { recursive: true, force: true }).pipe(Effect.ignore),\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\t// 1. Run the user's build inside the staging directory. On\n\t\t// failure clean up the staging dir (best-effort) BEFORE\n\t\t// re-raising — preserves the caller's error tag (no wrap).\n\t\tconst result = yield* build.pipe(\n\t\t\tEffect.onError(() =>\n\t\t\t\tfs.remove(stagingPath, { recursive: true, force: true }).pipe(Effect.ignore),\n\t\t\t),\n\t\t);\n\n\t\t// 2. Backup the current target and promote staging while holding\n\t\t// an optional caller-supplied lock. Restore uses this to block\n\t\t// command/event writers while the stack root path is absent.\n\t\tconst targetExists = yield* Effect.scoped(\n\t\t\tEffect.gen(function* () {\n\t\t\t\tif (publishLockPath !== undefined) {\n\t\t\t\t\tyield* acquireStackLock(publishLockPath).pipe(\n\t\t\t\t\t\tEffect.catch(failStage('acquire-publish-lock', targetPath, stagingPath)),\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\tconst targetExists = yield* fs\n\t\t\t\t\t.exists(targetPath)\n\t\t\t\t\t.pipe(Effect.catch(() => Effect.succeed(false)));\n\t\t\t\tif (targetExists) {\n\t\t\t\t\t// Move current → backup (atomic rename on same filesystem).\n\t\t\t\t\tyield* fs\n\t\t\t\t\t\t.rename(targetPath, backupPath)\n\t\t\t\t\t\t.pipe(Effect.catch(failStage('backup-current', targetPath, stagingPath)));\n\t\t\t\t\tyield* preserveTargetPaths({\n\t\t\t\t\t\tbackupPath,\n\t\t\t\t\t\ttargetPath,\n\t\t\t\t\t\tstagingPath,\n\t\t\t\t\t\tpreservedPaths: preserveFromTarget,\n\t\t\t\t\t}).pipe(\n\t\t\t\t\t\tEffect.catch((error) =>\n\t\t\t\t\t\t\tEffect.gen(function* () {\n\t\t\t\t\t\t\t\tyield* fs\n\t\t\t\t\t\t\t\t\t.rename(backupPath, targetPath)\n\t\t\t\t\t\t\t\t\t.pipe(Effect.catch(failStage('restore-backup', targetPath, stagingPath)));\n\t\t\t\t\t\t\t\treturn yield* Effect.fail(error);\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t),\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\t// 3. Promote staging → target. This is the atomic publish step.\n\t\t\t\tyield* fs.rename(stagingPath, targetPath).pipe(\n\t\t\t\t\tEffect.catch((cause) => {\n\t\t\t\t\t\t// A real Effect v4 `rename` failure is a PlatformError whose\n\t\t\t\t\t\t// raw Node errno lives at `reason.cause.code` (and the hoisted\n\t\t\t\t\t\t// `cause.cause.code`), NOT the top-level `.code` — see errnoCode.\n\t\t\t\t\t\tif (errnoCode(cause) === 'EXDEV') {\n\t\t\t\t\t\t\t// Cross-filesystem fallback — architecture's documented\n\t\t\t\t\t\t\t// exception. Log loudly; copy then rm. The atomicity\n\t\t\t\t\t\t\t// guarantee is LOST in this branch.\n\t\t\t\t\t\t\treturn Effect.gen(function* () {\n\t\t\t\t\t\t\t\tyield* Effect.logWarning('stage-and-swap cross-filesystem fallback').pipe(\n\t\t\t\t\t\t\t\t\tEffect.annotateLogs({\n\t\t\t\t\t\t\t\t\t\t[SpanAttr.stageAndSwapTargetPath]: targetPath,\n\t\t\t\t\t\t\t\t\t\t[SpanAttr.stageAndSwapStagingPath]: stagingPath,\n\t\t\t\t\t\t\t\t\t\t[SpanAttr.errorCode]: 'EXDEV',\n\t\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\tyield* fs.copy(stagingPath, targetPath, { overwrite: false }).pipe(\n\t\t\t\t\t\t\t\t\tEffect.catch((copyCause) =>\n\t\t\t\t\t\t\t\t\t\tEffect.gen(function* () {\n\t\t\t\t\t\t\t\t\t\t\t// Copy failed mid-fallback. Mirror the same-FS branch:\n\t\t\t\t\t\t\t\t\t\t\t// if we backed a target up, restore it verbatim before\n\t\t\t\t\t\t\t\t\t\t\t// surfacing the original tag (contract item 5).\n\t\t\t\t\t\t\t\t\t\t\tif (targetExists) {\n\t\t\t\t\t\t\t\t\t\t\t\tyield* fs\n\t\t\t\t\t\t\t\t\t\t\t\t\t.rename(backupPath, targetPath)\n\t\t\t\t\t\t\t\t\t\t\t\t\t.pipe(Effect.catch(failStage('restore-backup', targetPath, stagingPath)));\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\treturn yield* failStage(\n\t\t\t\t\t\t\t\t\t\t\t\t'cross-filesystem-fallback',\n\t\t\t\t\t\t\t\t\t\t\t\ttargetPath,\n\t\t\t\t\t\t\t\t\t\t\t\tstagingPath,\n\t\t\t\t\t\t\t\t\t\t\t)(copyCause);\n\t\t\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\tyield* fs.remove(stagingPath, { recursive: true, force: true }).pipe(Effect.ignore);\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\t\t\t\t\t\t// Same-filesystem rename failed. Restore backup if we took\n\t\t\t\t\t\t// one; surface the original tag.\n\t\t\t\t\t\treturn Effect.gen(function* () {\n\t\t\t\t\t\t\tif (targetExists) {\n\t\t\t\t\t\t\t\tyield* fs\n\t\t\t\t\t\t\t\t\t.rename(backupPath, targetPath)\n\t\t\t\t\t\t\t\t\t.pipe(Effect.catch(failStage('restore-backup', targetPath, stagingPath)));\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\treturn yield* failStage('rename-into-target', targetPath, stagingPath)(cause);\n\t\t\t\t\t\t});\n\t\t\t\t\t}),\n\t\t\t\t);\n\n\t\t\t\treturn targetExists;\n\t\t\t}),\n\t\t);\n\n\t\t// 4. Drop the backup. Failure here is observable but non-fatal:\n\t\t// the new target is live; an orphan backup is cosmetic.\n\t\tif (targetExists) {\n\t\t\tyield* fs.remove(backupPath, { recursive: true, force: true }).pipe(Effect.ignore);\n\t\t}\n\n\t\treturn result;\n\t}).pipe(Effect.withSpan('substrate.stage-and-swap'));\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.mjs","names":[],"sources":["../../../../src/substrate/runtime/stage-and-swap/index.ts"],"sourcesContent":["// Atomic stage-and-swap primitive.\n//\n// Architecture §\"Stage-and-swap rollback discipline is precious and\n// well-tested\": one tempdir, one rename for the whole publish.\n// Lifted to substrate so both snapshot AND codegen (per-cycle outer\n// swap) can consume — see ARCHITECTURE.md substrate roster + style\n// guide §19 (Open slot O14 closes with this lift).\n//\n// Contract:\n// 1. The caller provides a `targetPath` (the directory to publish).\n// 2. The orchestrator runs the build effect with a `stagingPath`\n// (a sibling under the same parent so the rename stays on the\n// same filesystem — POSIX rename atomicity is per-filesystem).\n// 3. If the build effect succeeds AND the rename succeeds, the\n// target now points at the new tree; external watchers never\n// observed a half-written intermediate.\n// 4. Optional `preserveFromTarget` paths are copied from the backed-up\n// target into staging immediately before publish.\n// 5. On any failure the staging directory is removed; the previous\n// target (if any) is restored verbatim from a same-parent\n// backup.\n// 6. Cross-filesystem fallback (`EXDEV` from rename) logs and falls\n// back to copy-then-rm — the architecture's documented exception.\n//\n// Atomic stage-and-swap discipline (distilled §17).\n\nimport { dirname, isAbsolute, join, normalize, sep } from 'node:path';\n\nimport { Effect, FileSystem, Schema } from 'effect';\n\nimport { acquireStackLock } from '../cross-process/stack-lock.ts';\nimport { LogAttr } from '../observability/log-attrs.ts';\n\n// -----------------------------------------------------------------------------\n// Errors\n// -----------------------------------------------------------------------------\n\n/** Tagged failure during a stage-and-swap step. `stage` discriminates\n * the precise failing step; the caller's underlying tag is preserved\n * via `cause` (the primitive does NOT wrap the user's error). */\nexport class StageAndSwapError extends Schema.TaggedErrorClass<StageAndSwapError>()(\n\t'StageAndSwapError',\n\t{\n\t\tstage: Schema.Literals([\n\t\t\t'mkdir-staging',\n\t\t\t'mkdir-backup',\n\t\t\t'build',\n\t\t\t'acquire-publish-lock',\n\t\t\t'backup-current',\n\t\t\t'preserve-target-paths',\n\t\t\t'rename-into-target',\n\t\t\t'restore-backup',\n\t\t\t'cleanup-staging',\n\t\t\t'cross-filesystem-fallback',\n\t\t]),\n\t\ttargetPath: Schema.String,\n\t\tstagingPath: Schema.String,\n\t\tcause: Schema.optional(Schema.Defect),\n\t},\n) {}\n\n// -----------------------------------------------------------------------------\n// Primitive\n// -----------------------------------------------------------------------------\n\nexport interface StageAndSwapPreservedPath {\n\treadonly relativePath: string;\n\t/** When `false`, the backed-up live copy is preserved into staging ONLY if\n\t * staging does not already carry the path — so a value the build already\n\t * placed there (e.g. a deploy cache untarred from the snapshot's host-tree)\n\t * WINS over the live copy. For a `directory` entry the skip is\n\t * all-or-nothing, not a per-file merge: if staging already has the dir, the\n\t * ENTIRE live copy is dropped, including any sub-path that existed only live\n\t * (post-snapshot drift) — the intended \"restore-to-snapshot wins\" semantic.\n\t * Defaults to `true` (always overwrite the staging copy with the live one). */\n\treadonly overwrite?: boolean;\n}\n\nconst failStage =\n\t<S extends StageAndSwapError['stage']>(\n\t\tstage: S,\n\t\ttargetPath: string,\n\t\tstagingPath: string,\n\t): ((cause: unknown) => Effect.Effect<never, StageAndSwapError>) =>\n\t(cause) =>\n\t\tEffect.fail(new StageAndSwapError({ stage, targetPath, stagingPath, cause }));\n\n/**\n * Extract the original Node errno `code` from a `FileSystem.rename` failure.\n *\n * Effect v4's `@effect/platform-node` wraps the raw `NodeJS.ErrnoException`\n * (`handleErrnoException` in `platform-node-shared/internal/utils.ts`) into a\n * `PlatformError` whose `reason` is a `SystemError`. The raw errno is preserved\n * as `reason.cause` (the unmodified Node error) — and the `PlatformError`\n * constructor additionally hoists that to the wrapper's own top-level `cause`.\n * So a genuine cross-filesystem rename surfaces the code at `reason.cause.code`\n * (and, equivalently, at `cause.cause.code`), NOT at the top-level `.code`.\n *\n * We probe every plausible location defensively: the nested SystemError cause,\n * the hoisted wrapper cause, and a bare-errno shape (in case a caller injects a\n * raw `NodeJS.ErrnoException` or the wrapping ever changes).\n */\nconst errnoCode = (cause: unknown): string | undefined => {\n\tconst codeOf = (value: unknown): string | undefined => {\n\t\tif (typeof value !== 'object' || value === null) return undefined;\n\t\tconst code = (value as { code?: unknown }).code;\n\t\treturn typeof code === 'string' ? code : undefined;\n\t};\n\tif (typeof cause !== 'object' || cause === null) return undefined;\n\tconst reasonCause = (cause as { reason?: { cause?: unknown } }).reason?.cause;\n\tconst directCause = (cause as { cause?: unknown }).cause;\n\treturn codeOf(reasonCause) ?? codeOf(directCause) ?? codeOf(cause);\n};\n\n/**\n * Roll a backed-up target back into place after a failed publish.\n *\n * The forward path renamed the live target away to `backupPath`; on any\n * subsequent failure we must put it back at `targetPath` so the world looks\n * exactly as it did at entry (contract item 5). The naive `rename(backupPath,\n * targetPath)` throws `ENOTEMPTY`/`EEXIST` if `targetPath` is unexpectedly\n * non-empty — e.g. a half-written staging tree that a prior interrupted run on\n * a reused state-dir left behind, or a leftover `.bak.<id>`. That rollback\n * bookkeeping failing is NOT a publish failure (the ORIGINAL `cause` is what we\n * surface); it's recoverable cosmetic state.\n *\n * So: reap any pre-existing `targetPath` first (recursive+force, idempotent) so\n * the rename can't collide, then rename. If the rename STILL fails we log a\n * recoverable WARNING and swallow it — the caller's original error is the real\n * outcome and we must not mask it with a `restore-backup` tag.\n */\nconst restoreBackupRename = (args: {\n\treadonly backupPath: string;\n\treadonly targetPath: string;\n\treadonly stagingPath: string;\n}): Effect.Effect<void, never, FileSystem.FileSystem> =>\n\tEffect.gen(function* () {\n\t\tconst fs = yield* FileSystem.FileSystem;\n\t\t// Reap a non-empty destination so the rollback rename can't ENOTEMPTY.\n\t\tyield* fs.remove(args.targetPath, { recursive: true, force: true }).pipe(Effect.ignore);\n\t\tyield* fs.rename(args.backupPath, args.targetPath).pipe(\n\t\t\tEffect.catch((cause) =>\n\t\t\t\tEffect.logWarning('stage-and-swap rollback-backup restore did not complete').pipe(\n\t\t\t\t\tEffect.annotateLogs({\n\t\t\t\t\t\t[LogAttr.stageAndSwapTargetPath]: args.targetPath,\n\t\t\t\t\t\t[LogAttr.stageAndSwapStagingPath]: args.stagingPath,\n\t\t\t\t\t\t[LogAttr.errorCode]: errnoCode(cause) ?? 'unknown',\n\t\t\t\t\t}),\n\t\t\t\t),\n\t\t\t),\n\t\t);\n\t});\n\nconst normalizePreservedRelativePath = (relativePath: string): string | null => {\n\tconst normalized = normalize(relativePath);\n\tif (\n\t\trelativePath.length === 0 ||\n\t\tisAbsolute(relativePath) ||\n\t\tnormalized === '.' ||\n\t\tnormalized === '..' ||\n\t\tnormalized.startsWith(`..${sep}`)\n\t) {\n\t\treturn null;\n\t}\n\treturn normalized;\n};\n\nconst preserveTargetPaths = (args: {\n\treadonly backupPath: string;\n\treadonly targetPath: string;\n\treadonly stagingPath: string;\n\treadonly preservedPaths: ReadonlyArray<StageAndSwapPreservedPath>;\n}): Effect.Effect<void, StageAndSwapError, FileSystem.FileSystem> =>\n\tEffect.gen(function* () {\n\t\tconst fs = yield* FileSystem.FileSystem;\n\t\tfor (const preserved of args.preservedPaths) {\n\t\t\tconst relativePath = normalizePreservedRelativePath(preserved.relativePath);\n\t\t\tif (relativePath === null) {\n\t\t\t\treturn yield* failStage(\n\t\t\t\t\t'preserve-target-paths',\n\t\t\t\t\targs.targetPath,\n\t\t\t\t\targs.stagingPath,\n\t\t\t\t)(new Error(`unsafe preserved path: ${preserved.relativePath}`));\n\t\t\t}\n\t\t\tconst source = join(args.backupPath, relativePath);\n\t\t\tconst exists = yield* fs.exists(source).pipe(Effect.catch(() => Effect.succeed(false)));\n\t\t\tif (!exists) continue;\n\t\t\tconst target = join(args.stagingPath, relativePath);\n\t\t\t// `overwrite: false` — don't clobber a path the build already placed in\n\t\t\t// staging (e.g. a deploy cache the snapshot captured into the host-tree\n\t\t\t// tar): that captured copy is consistent with the restored chain, so it\n\t\t\t// WINS over the live copy. The live copy is only a fallback when staging\n\t\t\t// doesn't already carry it (e.g. a pre-capture snapshot).\n\t\t\tif (preserved.overwrite === false) {\n\t\t\t\tconst targetExists = yield* fs\n\t\t\t\t\t.exists(target)\n\t\t\t\t\t.pipe(Effect.catch(() => Effect.succeed(false)));\n\t\t\t\tif (targetExists) continue;\n\t\t\t}\n\t\t\tyield* fs\n\t\t\t\t.makeDirectory(dirname(target), { recursive: true })\n\t\t\t\t.pipe(Effect.catch(failStage('preserve-target-paths', args.targetPath, args.stagingPath)));\n\t\t\tyield* fs\n\t\t\t\t.copy(source, target, { overwrite: true })\n\t\t\t\t.pipe(Effect.catch(failStage('preserve-target-paths', args.targetPath, args.stagingPath)));\n\t\t}\n\t});\n\n/**\n * Build-then-swap. `build` is a user effect that populates `stagingPath`;\n * on success the helper:\n *\n * - backs up the current `targetPath` (if any) to `<targetPath>.bak.<pid>`,\n * - copies any selected `preserveFromTarget` paths from that backup\n * into staging,\n * - renames `stagingPath` → `targetPath`,\n * - removes the backup.\n *\n * On any failure the helper removes `stagingPath` and, if the backup\n * was taken, renames it back to `targetPath` so the world looks\n * exactly as it did at entry.\n *\n * The build effect's error type passes through unchanged — the\n * primitive returns `E | StageAndSwapError`. This is the\n * \"preserve the caller's error tag\" rule from distilled §17.\n *\n * IMPORTANT: stagingPath MUST be on the same filesystem as\n * targetPath. The helper picks it as a sibling under the same parent\n * (caller passes `parentDir`, we mint the names) — this is enforced\n * by the helper's signature shape.\n *\n * ## Two call shapes\n *\n * - Explicit-paths: callers that need bespoke sibling names (the\n * Seal plugin uses `.backup.` not `.bak.`; pre-existing tests use\n * literal `target.staging`/`target.bak`) pass both `stagingPath`\n * and `backupPath` directly.\n * - `idSuffix`: callers (codegen, snapshot) pass `idSuffix` and the\n * primitive mints `<targetPath>.staging.<idSuffix>` /\n * `<targetPath>.bak.<idSuffix>` so the staging/backup-naming\n * convention is owned in ONE place. Callers MUST NOT pass both\n * `idSuffix` and explicit paths.\n *\n * ## `preserveOnPreseed`\n *\n * When `true`, before the user's `build` runs the primitive copies the\n * current `targetPath` (if any) into `stagingPath` so `build` can\n * mutate that baseline incrementally. This subsumes the codegen\n * orchestrator's pre-seed dance (per-file no-touch idempotency relies\n * on seeing the previous target's mtimes). Cross-cutting with\n * `preserveFromTarget` is allowed: pre-seed clones the whole tree\n * BEFORE the build; `preserveFromTarget` cherry-picks paths AFTER the\n * build and BEFORE the swap (and reads from the backup, so the build\n * may have rewritten them in-tree). The two features answer different\n * questions and the primitive runs them in that order.\n */\nexport const stageAndSwap = <A, E>(\n\targs: {\n\t\treadonly targetPath: string;\n\t\treadonly build: Effect.Effect<A, E, FileSystem.FileSystem>;\n\t\treadonly preserveFromTarget?: ReadonlyArray<StageAndSwapPreservedPath>;\n\t\treadonly preserveOnPreseed?: boolean;\n\t\treadonly publishLockPath?: string;\n\t} & (\n\t\t| { readonly stagingPath: string; readonly backupPath: string; readonly idSuffix?: never }\n\t\t| { readonly idSuffix: string; readonly stagingPath?: never; readonly backupPath?: never }\n\t),\n): Effect.Effect<A, E | StageAndSwapError, FileSystem.FileSystem> =>\n\tEffect.gen(function* () {\n\t\tconst fs = yield* FileSystem.FileSystem;\n\t\tconst {\n\t\t\ttargetPath,\n\t\t\tbuild,\n\t\t\tpreserveFromTarget = [],\n\t\t\tpreserveOnPreseed = false,\n\t\t\tpublishLockPath,\n\t\t} = args;\n\t\tconst stagingPath =\n\t\t\targs.stagingPath ?? `${targetPath}.staging.${(args as { idSuffix: string }).idSuffix}`;\n\t\tconst backupPath =\n\t\t\targs.backupPath ?? `${targetPath}.bak.${(args as { idSuffix: string }).idSuffix}`;\n\n\t\t// 0. Pre-clean the staging slot (a previous crash may have left\n\t\t// a sibling). recursive+force is idempotent.\n\t\tyield* fs.remove(stagingPath, { recursive: true, force: true }).pipe(Effect.ignore);\n\t\tyield* fs\n\t\t\t.makeDirectory(stagingPath, { recursive: true })\n\t\t\t.pipe(Effect.catch(failStage('mkdir-staging', targetPath, stagingPath)));\n\n\t\t// 0a. Optional pre-seed: when `preserveOnPreseed`, clone the\n\t\t// current target into staging so the build can edit it\n\t\t// incrementally (codegen needs this for per-file no-touch\n\t\t// idempotency). `preserveTimestamps: true` keeps mtimes\n\t\t// intact so HMR watchers (Vite/Turbopack — they trigger on\n\t\t// mtime, not content) stay quiet for unchanged outputs.\n\t\tif (preserveOnPreseed) {\n\t\t\tconst targetExistsForPreseed = yield* fs\n\t\t\t\t.exists(targetPath)\n\t\t\t\t.pipe(Effect.catch(() => Effect.succeed(false)));\n\t\t\tif (targetExistsForPreseed) {\n\t\t\t\tyield* fs.copy(targetPath, stagingPath, { overwrite: true, preserveTimestamps: true }).pipe(\n\t\t\t\t\tEffect.catch(failStage('mkdir-staging', targetPath, stagingPath)),\n\t\t\t\t\tEffect.onError(() =>\n\t\t\t\t\t\tfs.remove(stagingPath, { recursive: true, force: true }).pipe(Effect.ignore),\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\t// 1. Run the user's build inside the staging directory. On\n\t\t// failure clean up the staging dir (best-effort) BEFORE\n\t\t// re-raising — preserves the caller's error tag (no wrap).\n\t\tconst result = yield* build.pipe(\n\t\t\tEffect.onError(() =>\n\t\t\t\tfs.remove(stagingPath, { recursive: true, force: true }).pipe(Effect.ignore),\n\t\t\t),\n\t\t);\n\n\t\t// 2. Backup the current target and promote staging while holding\n\t\t// an optional caller-supplied lock. Restore uses this to block\n\t\t// command/event writers while the stack root path is absent.\n\t\tconst targetExists = yield* Effect.scoped(\n\t\t\tEffect.gen(function* () {\n\t\t\t\tif (publishLockPath !== undefined) {\n\t\t\t\t\tyield* acquireStackLock(publishLockPath).pipe(\n\t\t\t\t\t\tEffect.catch(failStage('acquire-publish-lock', targetPath, stagingPath)),\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\tconst targetExists = yield* fs\n\t\t\t\t\t.exists(targetPath)\n\t\t\t\t\t.pipe(Effect.catch(() => Effect.succeed(false)));\n\t\t\t\tif (targetExists) {\n\t\t\t\t\t// Move current → backup (atomic rename on same filesystem).\n\t\t\t\t\tyield* fs\n\t\t\t\t\t\t.rename(targetPath, backupPath)\n\t\t\t\t\t\t.pipe(Effect.catch(failStage('backup-current', targetPath, stagingPath)));\n\t\t\t\t\tyield* preserveTargetPaths({\n\t\t\t\t\t\tbackupPath,\n\t\t\t\t\t\ttargetPath,\n\t\t\t\t\t\tstagingPath,\n\t\t\t\t\t\tpreservedPaths: preserveFromTarget,\n\t\t\t\t\t}).pipe(\n\t\t\t\t\t\tEffect.catch((error) =>\n\t\t\t\t\t\t\tEffect.gen(function* () {\n\t\t\t\t\t\t\t\tyield* restoreBackupRename({ backupPath, targetPath, stagingPath });\n\t\t\t\t\t\t\t\treturn yield* Effect.fail(error);\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t),\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\t// 3. Promote staging → target. This is the atomic publish step.\n\t\t\t\tyield* fs.rename(stagingPath, targetPath).pipe(\n\t\t\t\t\tEffect.catch((cause) => {\n\t\t\t\t\t\t// A real Effect v4 `rename` failure is a PlatformError whose\n\t\t\t\t\t\t// raw Node errno lives at `reason.cause.code` (and the hoisted\n\t\t\t\t\t\t// `cause.cause.code`), NOT the top-level `.code` — see errnoCode.\n\t\t\t\t\t\tif (errnoCode(cause) === 'EXDEV') {\n\t\t\t\t\t\t\t// Cross-filesystem fallback — architecture's documented\n\t\t\t\t\t\t\t// exception. Log loudly; copy then rm. The atomicity\n\t\t\t\t\t\t\t// guarantee is LOST in this branch.\n\t\t\t\t\t\t\treturn Effect.gen(function* () {\n\t\t\t\t\t\t\t\tyield* Effect.logWarning('stage-and-swap cross-filesystem fallback').pipe(\n\t\t\t\t\t\t\t\t\tEffect.annotateLogs({\n\t\t\t\t\t\t\t\t\t\t[LogAttr.stageAndSwapTargetPath]: targetPath,\n\t\t\t\t\t\t\t\t\t\t[LogAttr.stageAndSwapStagingPath]: stagingPath,\n\t\t\t\t\t\t\t\t\t\t[LogAttr.errorCode]: 'EXDEV',\n\t\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\tyield* fs.copy(stagingPath, targetPath, { overwrite: false }).pipe(\n\t\t\t\t\t\t\t\t\tEffect.catch((copyCause) =>\n\t\t\t\t\t\t\t\t\t\tEffect.gen(function* () {\n\t\t\t\t\t\t\t\t\t\t\t// Copy failed mid-fallback. Mirror the same-FS branch:\n\t\t\t\t\t\t\t\t\t\t\t// if we backed a target up, restore it verbatim before\n\t\t\t\t\t\t\t\t\t\t\t// surfacing the original tag (contract item 5).\n\t\t\t\t\t\t\t\t\t\t\tif (targetExists) {\n\t\t\t\t\t\t\t\t\t\t\t\tyield* restoreBackupRename({ backupPath, targetPath, stagingPath });\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\treturn yield* failStage(\n\t\t\t\t\t\t\t\t\t\t\t\t'cross-filesystem-fallback',\n\t\t\t\t\t\t\t\t\t\t\t\ttargetPath,\n\t\t\t\t\t\t\t\t\t\t\t\tstagingPath,\n\t\t\t\t\t\t\t\t\t\t\t)(copyCause);\n\t\t\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\tyield* fs.remove(stagingPath, { recursive: true, force: true }).pipe(Effect.ignore);\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\t\t\t\t\t\t// Same-filesystem rename failed. Restore backup if we took\n\t\t\t\t\t\t// one; surface the original tag.\n\t\t\t\t\t\treturn Effect.gen(function* () {\n\t\t\t\t\t\t\tif (targetExists) {\n\t\t\t\t\t\t\t\tyield* restoreBackupRename({ backupPath, targetPath, stagingPath });\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\treturn yield* failStage('rename-into-target', targetPath, stagingPath)(cause);\n\t\t\t\t\t\t});\n\t\t\t\t\t}),\n\t\t\t\t);\n\n\t\t\t\treturn targetExists;\n\t\t\t}),\n\t\t);\n\n\t\t// 4. Drop the backup. Failure here is observable but non-fatal:\n\t\t// the new target is live; an orphan backup is cosmetic.\n\t\tif (targetExists) {\n\t\t\tyield* fs.remove(backupPath, { recursive: true, force: true }).pipe(Effect.ignore);\n\t\t}\n\n\t\treturn result;\n\t});\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chain-keyed-strategy-for.mjs","names":[],"sources":["../../../../src/substrate/runtime/strategy-registry/chain-keyed-strategy-for.ts"],"sourcesContent":["// `chainKeyedStrategyFor` — strategy-registry sugar for chain-keyed\n// strategy lookups. Mirrors `chainProbeFor`.\n//\n// The substrate is name-blind: the caller passes both the prefix and\n// the chain id, and the helper assembles `<prefix>:<chainId>` and\n// performs the registry lookup. The faucet plugin's\n// `FAUCET_CAPABILITY_KEY_PREFIX` is the single source of truth for the\n// faucet key shape; the substrate does NOT duplicate it.\n\nimport { Effect } from 'effect';\n\nimport type {
|
|
1
|
+
{"version":3,"file":"chain-keyed-strategy-for.mjs","names":[],"sources":["../../../../src/substrate/runtime/strategy-registry/chain-keyed-strategy-for.ts"],"sourcesContent":["// `chainKeyedStrategyFor` — strategy-registry sugar for chain-keyed\n// strategy lookups. Mirrors `chainProbeFor`.\n//\n// The substrate is name-blind: the caller passes both the prefix and\n// the chain id, and the helper assembles `<prefix>:<chainId>` and\n// performs the registry lookup. The faucet plugin's\n// `FAUCET_CAPABILITY_KEY_PREFIX` is the single source of truth for the\n// faucet key shape; the substrate does NOT duplicate it.\n\nimport { Effect } from 'effect';\n\nimport type { StrategyNotFoundError } from '../errors.ts';\nimport { StrategyRegistryService } from './service.ts';\n\n/**\n * Look up the strategy registered under `<prefix>:<chainId>` and surface\n * it with the caller's expected shape.\n *\n * The strategy shape `P` is a free generic — the plugin that owns the\n * capability prefix also owns its strategy contract, and callers pass\n * both at the call site:\n *\n * ```ts\n * import { FAUCET_CAPABILITY_KEY_PREFIX, type FaucetStrategy } from '../faucet/index.ts';\n *\n * const strategy = yield* chainKeyedStrategyFor<FaucetStrategy>(\n * FAUCET_CAPABILITY_KEY_PREFIX,\n * parts.chainId,\n * );\n * ```\n *\n * Failure shape is the substrate `StrategyNotFoundError`; callers that\n * want a plugin-flavored error project it via `Effect.catchTag` at the\n * call site.\n */\nexport const chainKeyedStrategyFor = <P>(\n\tprefix: string,\n\tchainId: string,\n): Effect.Effect<P, StrategyNotFoundError, StrategyRegistryService> =>\n\tEffect.gen(function* () {\n\t\tconst registry = yield* StrategyRegistryService;\n\t\tconst key = `${prefix}:${chainId}`;\n\t\treturn yield* registry.get<typeof key, P>(key);\n\t});\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;AAmCA,MAAa,yBACZ,QACA,YAEA,OAAO,IAAI,aAAa;CACvB,MAAM,WAAW,OAAO;CACxB,MAAM,MAAM,GAAG,OAAO,GAAG;CACzB,OAAO,OAAO,SAAS,IAAmB,GAAG;AAC9C,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chain-probe-for.mjs","names":[],"sources":["../../../../src/substrate/runtime/strategy-registry/chain-probe-for.ts"],"sourcesContent":["// `chainProbeFor` — strategy-registry sugar for the chain-probe lookup.\n//\n// Every plugin that produces an on-chain artifact (package, coin, seal,\n// walrus, action, ...) repeats the same 4-line dance: yield the\n// StrategyRegistryService, then `registry.get<...>(chainProbeCapabilityKey(chain))`\n// with the same generic args and the same trailing cast. The dance is\n// load-bearing exactly once (the cast threads `SuiProbeKey` through the\n// capability-key's `string` discriminator) — every other site is\n// boilerplate.\n//\n// This helper consolidates the pattern: one Effect, one R-channel\n// (`StrategyRegistryService`), one typed return (`ChainProbe<Key>`).\n// Call sites become a single `yield* chainProbeFor(sui.chain)`.\n\nimport { Effect } from 'effect';\n\nimport { chainProbeCapabilityKey, type ChainProbe } from '../../../contracts/chain-probe.ts';\nimport type {
|
|
1
|
+
{"version":3,"file":"chain-probe-for.mjs","names":[],"sources":["../../../../src/substrate/runtime/strategy-registry/chain-probe-for.ts"],"sourcesContent":["// `chainProbeFor` — strategy-registry sugar for the chain-probe lookup.\n//\n// Every plugin that produces an on-chain artifact (package, coin, seal,\n// walrus, action, ...) repeats the same 4-line dance: yield the\n// StrategyRegistryService, then `registry.get<...>(chainProbeCapabilityKey(chain))`\n// with the same generic args and the same trailing cast. The dance is\n// load-bearing exactly once (the cast threads `SuiProbeKey` through the\n// capability-key's `string` discriminator) — every other site is\n// boilerplate.\n//\n// This helper consolidates the pattern: one Effect, one R-channel\n// (`StrategyRegistryService`), one typed return (`ChainProbe<Key>`).\n// Call sites become a single `yield* chainProbeFor(sui.chain)`.\n\nimport { Effect } from 'effect';\n\nimport { chainProbeCapabilityKey, type ChainProbe } from '../../../contracts/chain-probe.ts';\nimport type { StrategyNotFoundError } from '../errors.ts';\nimport { StrategyRegistryService } from './service.ts';\n\n/**\n * Look up the chain-probe contributed by the chain owner (Sui's\n * `acquire` registers one per resolved chain id) and surface it with\n * the caller's expected key shape.\n *\n * `Key` defaults to `unknown` so call sites that don't care about the\n * probe key shape can omit the generic; sites that consume Sui probes\n * pass `SuiProbeKey` explicitly. The cast from the registry's\n * `unknown` payload to `ChainProbe<Key>` is centralised here — call\n * sites stop repeating it.\n */\nexport const chainProbeFor = <Key = unknown>(\n\tchain: string,\n): Effect.Effect<ChainProbe<Key>, StrategyNotFoundError, StrategyRegistryService> =>\n\tEffect.gen(function* () {\n\t\tconst registry = yield* StrategyRegistryService;\n\t\tconst probe = yield* registry.get<`chain-probe:${string}`, ChainProbe<Key>>(\n\t\t\tchainProbeCapabilityKey(chain),\n\t\t);\n\t\treturn probe;\n\t});\n"],"mappings":";;;;;;;;;;;;;;;AA+BA,MAAa,iBACZ,UAEA,OAAO,IAAI,aAAa;CAKvB,OAAO,QAHc,OADG,wBAAA,CACM,IAC7B,wBAAwB,KAAK,CAC9B;AAED,CAAC"}
|
|
@@ -1,8 +1,5 @@
|
|
|
1
|
-
import { SpanAttr } from "../observability/spans.mjs";
|
|
2
|
-
import { makeScopedMultimap } from "../scoped-multimap/service.mjs";
|
|
3
|
-
import "../scoped-multimap/index.mjs";
|
|
4
1
|
import { StrategyNotFoundError } from "../errors.mjs";
|
|
5
|
-
import { Context, Effect, Layer } from "effect";
|
|
2
|
+
import { Context, Effect, Layer, Ref } from "effect";
|
|
6
3
|
//#region src/substrate/runtime/strategy-registry/service.ts
|
|
7
4
|
var StrategyRegistryService = class extends Context.Service()("@devstack/substrate/StrategyRegistry") {};
|
|
8
5
|
/**
|
|
@@ -11,27 +8,42 @@ var StrategyRegistryService = class extends Context.Service()("@devstack/substra
|
|
|
11
8
|
* stack's registry, not a global one.
|
|
12
9
|
*/
|
|
13
10
|
const layerStrategyRegistry = Layer.effect(StrategyRegistryService, Effect.gen(function* () {
|
|
14
|
-
const
|
|
11
|
+
const ref = yield* Ref.make(/* @__PURE__ */ new Map());
|
|
12
|
+
const seqRef = yield* Ref.make(0);
|
|
13
|
+
const entriesFor = (key) => Ref.get(ref).pipe(Effect.map((current) => current.get(key) ?? []));
|
|
14
|
+
const keys = Ref.get(ref).pipe(Effect.map((current) => [...current.keys()]));
|
|
15
15
|
const register = (key, strategy, options) => Effect.gen(function* () {
|
|
16
16
|
const entry = {
|
|
17
17
|
strategy,
|
|
18
18
|
autoMounted: options?.autoMounted ?? false,
|
|
19
19
|
priority: options?.priority ?? 0
|
|
20
20
|
};
|
|
21
|
-
yield*
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
21
|
+
const seq = yield* Ref.updateAndGet(seqRef, (n) => n + 1);
|
|
22
|
+
yield* Ref.update(ref, (current) => {
|
|
23
|
+
const next = new Map(current);
|
|
24
|
+
const existing = next.get(key) ?? [];
|
|
25
|
+
next.set(key, [...existing, {
|
|
26
|
+
value: entry,
|
|
27
|
+
seq
|
|
28
|
+
}]);
|
|
29
|
+
return next;
|
|
28
30
|
});
|
|
29
|
-
|
|
31
|
+
yield* Effect.addFinalizer((_exit) => Ref.update(ref, (current) => {
|
|
32
|
+
const next = new Map(current);
|
|
33
|
+
const existing = next.get(key);
|
|
34
|
+
if (existing) {
|
|
35
|
+
const filtered = existing.filter((e) => e.seq !== seq);
|
|
36
|
+
if (filtered.length === 0) next.delete(key);
|
|
37
|
+
else next.set(key, filtered);
|
|
38
|
+
}
|
|
39
|
+
return next;
|
|
40
|
+
}));
|
|
41
|
+
}).pipe(Effect.uninterruptible);
|
|
30
42
|
const get = (key) => Effect.gen(function* () {
|
|
31
|
-
const entries = yield*
|
|
43
|
+
const entries = yield* entriesFor(key);
|
|
32
44
|
if (entries.length === 0) return yield* new StrategyNotFoundError({
|
|
33
45
|
capabilityKey: key,
|
|
34
|
-
registeredKeys: yield*
|
|
46
|
+
registeredKeys: yield* keys
|
|
35
47
|
});
|
|
36
48
|
let best = entries[0];
|
|
37
49
|
for (let i = 1; i < entries.length; i++) {
|
|
@@ -39,8 +51,8 @@ const layerStrategyRegistry = Layer.effect(StrategyRegistryService, Effect.gen(f
|
|
|
39
51
|
if (e.value.priority > best.value.priority || e.value.priority === best.value.priority && e.seq > best.seq) best = e;
|
|
40
52
|
}
|
|
41
53
|
return best.value.strategy;
|
|
42
|
-
})
|
|
43
|
-
const list = () =>
|
|
54
|
+
});
|
|
55
|
+
const list = () => keys;
|
|
44
56
|
return StrategyRegistryService.of({
|
|
45
57
|
get,
|
|
46
58
|
register,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"service.mjs","names":[],"sources":["../../../../src/substrate/runtime/strategy-registry/service.ts"],"sourcesContent":["// Strategy registry implementation.\n//\n// Architecture § StrategyContributor — generic capability-keyed\n// pub/sub for plugin-contributed strategies (faucet strategies,\n// network resolvers, account selection, etc.).\n//\n// Per-capability-key LIST of contributing plugins (a registry can\n// hold multiple contributions for the same key). Resolution is\n// ordered by registration time; the selector chooses among them.\n//\n// Scope-local. The registry is created per-stack-scope so parallel\n// stacks isolate. When the stack scope closes, the registry's\n// entries die with it (the architecture's \"scope-local, never\n// module-level\" rule).\n\nimport { Context, Effect, Layer, Scope } from 'effect';\n\nimport type { StrategyRegistry } from '../../../contracts/strategy-contributor.ts';\nimport { StrategyNotFoundError } from '../errors.ts';\
|
|
1
|
+
{"version":3,"file":"service.mjs","names":[],"sources":["../../../../src/substrate/runtime/strategy-registry/service.ts"],"sourcesContent":["// Strategy registry implementation.\n//\n// Architecture § StrategyContributor — generic capability-keyed\n// pub/sub for plugin-contributed strategies (faucet strategies,\n// network resolvers, account selection, etc.).\n//\n// Per-capability-key LIST of contributing plugins (a registry can\n// hold multiple contributions for the same key). Resolution is\n// ordered by registration time; the selector chooses among them.\n//\n// Scope-local. The registry is created per-stack-scope so parallel\n// stacks isolate. When the stack scope closes, the registry's\n// entries die with it (the architecture's \"scope-local, never\n// module-level\" rule).\n\nimport { Context, Effect, Layer, Ref, Scope } from 'effect';\n\nimport type { StrategyRegistry } from '../../../contracts/strategy-contributor.ts';\nimport { StrategyNotFoundError } from '../errors.ts';\n\n/** One registered strategy under a capability key. The store stamps\n * the registration `seq`; the payload carries the strategy + its\n * visibility/priority. We keep the LIST (not the single winner)\n * because:\n * 1. Renderers want to enumerate \"N contributors registered\".\n * 2. The selector is per-strategy and may inspect all of them.\n * 3. Auto-mounted vs user-supplied is a visibility distinction\n * consumers need to surface separately. */\ninterface Entry {\n\treadonly strategy: unknown;\n\treadonly autoMounted: boolean;\n\treadonly priority: number;\n}\n\n/** One stored entry: the caller's `Entry` plus the monotonic `seq` the\n * store stamped it with. The `seq` is the identity the finalizer drops\n * on and the winner-fold tiebreaks on.\n *\n * Why a per-key LIST tagged by a monotonic seq (rather than a single\n * value-per-key with prior-restore):\n *\n * - Parallel / sibling-scope safety. The naive \"remember the prior\n * value, restore it on close\" finalizer is only correct under\n * strict LIFO nesting. With sibling scopes it clobbers a still-live\n * registration: scope A installs `X`, sibling B overwrites `X`\n * (capturing A's value as its `prior`), then A closes first and its\n * finalizer — holding `prior = nothing` — DELETES `X`, dropping B's\n * live overlay.\n *\n * - The seq-tagged list makes every finalizer remove ONLY the entry\n * it added — it never touches a newer registration for the same\n * key. \"Who wins right now\" is a pure function of the surviving\n * entries (priority, then seq), so close order does not matter. */\ninterface StoredEntry {\n\treadonly value: Entry;\n\treadonly seq: number;\n}\n\ntype Store = ReadonlyMap<string, ReadonlyArray<StoredEntry>>;\n\nexport class StrategyRegistryService extends Context.Service<\n\tStrategyRegistryService,\n\tStrategyRegistry\n>()('@devstack/substrate/StrategyRegistry') {}\n\n/**\n * Layer. Constructed per-scope; the orchestrator hands the registry\n * to each plugin's acquire so contributions land on the right\n * stack's registry, not a global one.\n */\nexport const layerStrategyRegistry: Layer.Layer<StrategyRegistryService> = Layer.effect(\n\tStrategyRegistryService,\n\tEffect.gen(function* () {\n\t\t// Scope-local seq-tagged store. The backing `Ref`s are private to\n\t\t// this build effect, so they die with the stack scope (the\n\t\t// architecture's \"scope-local, never module-level\" rule). `seqRef`\n\t\t// stamps a fresh monotonic seq per registration; `ref` holds the\n\t\t// per-key LIST of surviving seq-tagged entries.\n\t\tconst ref = yield* Ref.make<Store>(new Map());\n\t\tconst seqRef = yield* Ref.make(0);\n\n\t\t// `entriesFor` — surviving entries under one key, in registration\n\t\t// order (ascending seq). Empty array when the key is absent.\n\t\tconst entriesFor = (key: string): Effect.Effect<ReadonlyArray<StoredEntry>> =>\n\t\t\tRef.get(ref).pipe(Effect.map((current) => current.get(key) ?? []));\n\n\t\t// `keys` — keys with at least one surviving entry.\n\t\tconst keys: Effect.Effect<ReadonlyArray<string>> = Ref.get(ref).pipe(\n\t\t\tEffect.map((current) => [...current.keys()]),\n\t\t);\n\n\t\tconst register: StrategyRegistry['register'] = <Key extends string, S>(\n\t\t\tkey: Key,\n\t\t\tstrategy: S,\n\t\t\toptions?: { readonly autoMounted?: boolean; readonly priority?: number },\n\t\t) =>\n\t\t\tEffect.gen(function* () {\n\t\t\t\tconst entry: Entry = {\n\t\t\t\t\tstrategy,\n\t\t\t\t\tautoMounted: options?.autoMounted ?? false,\n\t\t\t\t\tpriority: options?.priority ?? 0,\n\t\t\t\t};\n\t\t\t\t// Stamp a fresh monotonic seq, append the entry under `key`,\n\t\t\t\t// and wire a drop-by-seq finalizer onto the CALLER's scope.\n\t\t\t\t// The append + finalizer-wire pair is `uninterruptible`, so an\n\t\t\t\t// interrupt arriving between the two can't leak an entry past\n\t\t\t\t// scope close. The finalizer touches only the entry THIS\n\t\t\t\t// registration added — never a newer registration for the same\n\t\t\t\t// key — so sibling-scope close order is irrelevant.\n\t\t\t\tconst seq = yield* Ref.updateAndGet(seqRef, (n) => n + 1);\n\t\t\t\tyield* Ref.update(ref, (current) => {\n\t\t\t\t\tconst next = new Map(current);\n\t\t\t\t\tconst existing = next.get(key) ?? [];\n\t\t\t\t\tnext.set(key, [...existing, { value: entry, seq }]);\n\t\t\t\t\treturn next;\n\t\t\t\t});\n\t\t\t\tyield* Effect.addFinalizer((_exit) =>\n\t\t\t\t\tRef.update(ref, (current) => {\n\t\t\t\t\t\tconst next = new Map(current);\n\t\t\t\t\t\tconst existing = next.get(key);\n\t\t\t\t\t\tif (existing) {\n\t\t\t\t\t\t\tconst filtered = existing.filter((e) => e.seq !== seq);\n\t\t\t\t\t\t\tif (filtered.length === 0) next.delete(key);\n\t\t\t\t\t\t\telse next.set(key, filtered);\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn next;\n\t\t\t\t\t}),\n\t\t\t\t);\n\t\t\t}).pipe(Effect.uninterruptible) as Effect.Effect<void, never, Scope.Scope>;\n\n\t\tconst get: StrategyRegistry['get'] = <Key extends string, S>(key: Key) =>\n\t\t\tEffect.gen(function* () {\n\t\t\t\tconst entries = yield* entriesFor(key);\n\t\t\t\tif (entries.length === 0) {\n\t\t\t\t\tconst registeredKeys = yield* keys;\n\t\t\t\t\treturn yield* new StrategyNotFoundError({\n\t\t\t\t\t\tcapabilityKey: key,\n\t\t\t\t\t\tregisteredKeys,\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\t// Resolution policy:\n\t\t\t\t// 1. Higher priority wins.\n\t\t\t\t// 2. Tie on priority → later registration wins\n\t\t\t\t// (last-write-wins for user overrides of\n\t\t\t\t// built-ins — matches architecture § failure\n\t\t\t\t// modes \"two strategies with the same key and\n\t\t\t\t// same priority → last write wins\").\n\t\t\t\tlet best = entries[0]!;\n\t\t\t\tfor (let i = 1; i < entries.length; i++) {\n\t\t\t\t\tconst e = entries[i]!;\n\t\t\t\t\tif (\n\t\t\t\t\t\te.value.priority > best.value.priority ||\n\t\t\t\t\t\t(e.value.priority === best.value.priority && e.seq > best.seq)\n\t\t\t\t\t) {\n\t\t\t\t\t\tbest = e;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn best.value.strategy as S;\n\t\t\t});\n\n\t\tconst list: StrategyRegistry['list'] = () => keys;\n\n\t\treturn StrategyRegistryService.of({\n\t\t\tget: get as StrategyRegistry['get'],\n\t\t\tregister: register as StrategyRegistry['register'],\n\t\t\tlist,\n\t\t});\n\t}),\n);\n"],"mappings":";;;AA4DA,IAAa,0BAAb,cAA6C,QAAQ,QAGnD,CAAC,CAAC,sCAAsC,CAAC,CAAC,CAAC;;;;;;AAO7C,MAAa,wBAA8D,MAAM,OAChF,yBACA,OAAO,IAAI,aAAa;CAMvB,MAAM,MAAM,OAAO,IAAI,qBAAY,IAAI,IAAI,CAAC;CAC5C,MAAM,SAAS,OAAO,IAAI,KAAK,CAAC;CAIhC,MAAM,cAAc,QACnB,IAAI,IAAI,GAAG,CAAC,CAAC,KAAK,OAAO,KAAK,YAAY,QAAQ,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC;CAGlE,MAAM,OAA6C,IAAI,IAAI,GAAG,CAAC,CAAC,KAC/D,OAAO,KAAK,YAAY,CAAC,GAAG,QAAQ,KAAK,CAAC,CAAC,CAC5C;CAEA,MAAM,YACL,KACA,UACA,YAEA,OAAO,IAAI,aAAa;EACvB,MAAM,QAAe;GACpB;GACA,aAAa,SAAS,eAAe;GACrC,UAAU,SAAS,YAAY;EAChC;EAQA,MAAM,MAAM,OAAO,IAAI,aAAa,SAAS,MAAM,IAAI,CAAC;EACxD,OAAO,IAAI,OAAO,MAAM,YAAY;GACnC,MAAM,OAAO,IAAI,IAAI,OAAO;GAC5B,MAAM,WAAW,KAAK,IAAI,GAAG,KAAK,CAAC;GACnC,KAAK,IAAI,KAAK,CAAC,GAAG,UAAU;IAAE,OAAO;IAAO;GAAI,CAAC,CAAC;GAClD,OAAO;EACR,CAAC;EACD,OAAO,OAAO,cAAc,UAC3B,IAAI,OAAO,MAAM,YAAY;GAC5B,MAAM,OAAO,IAAI,IAAI,OAAO;GAC5B,MAAM,WAAW,KAAK,IAAI,GAAG;GAC7B,IAAI,UAAU;IACb,MAAM,WAAW,SAAS,QAAQ,MAAM,EAAE,QAAQ,GAAG;IACrD,IAAI,SAAS,WAAW,GAAG,KAAK,OAAO,GAAG;SACrC,KAAK,IAAI,KAAK,QAAQ;GAC5B;GACA,OAAO;EACR,CAAC,CACF;CACD,CAAC,CAAC,CAAC,KAAK,OAAO,eAAe;CAE/B,MAAM,OAAuD,QAC5D,OAAO,IAAI,aAAa;EACvB,MAAM,UAAU,OAAO,WAAW,GAAG;EACrC,IAAI,QAAQ,WAAW,GAEtB,OAAO,OAAO,IAAI,sBAAsB;GACvC,eAAe;GACf,gBAAA,OAH6B;EAI9B,CAAC;EASF,IAAI,OAAO,QAAQ;EACnB,KAAK,IAAI,IAAI,GAAG,IAAI,QAAQ,QAAQ,KAAK;GACxC,MAAM,IAAI,QAAQ;GAClB,IACC,EAAE,MAAM,WAAW,KAAK,MAAM,YAC7B,EAAE,MAAM,aAAa,KAAK,MAAM,YAAY,EAAE,MAAM,KAAK,KAE1D,OAAO;EAET;EACA,OAAO,KAAK,MAAM;CACnB,CAAC;CAEF,MAAM,aAAuC;CAE7C,OAAO,wBAAwB,GAAG;EAC5B;EACK;EACV;CACD,CAAC;AACF,CAAC,CACF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"subnet-broker.mjs","names":[],"sources":["../../../src/substrate/runtime/subnet-broker.ts"],"sourcesContent":["// Subnet-prefix derivation + EnsureNetworkSpec stamping — ONE canonical\n// implementation.\n//\n//
|
|
1
|
+
{"version":3,"file":"subnet-broker.mjs","names":[],"sources":["../../../src/substrate/runtime/subnet-broker.ts"],"sourcesContent":["// Subnet-prefix derivation + EnsureNetworkSpec stamping — ONE canonical\n// implementation.\n//\n// Multiple plugins (walrus, seal) need a deterministic Docker `/24`\n// subnet keyed off their stack identity so parallel local stacks don't\n// all collide on Docker's default IPAM pool. They share one FNV-1a\n// hash → IPv4 third-octet derivation; the only thing that varies is\n// the second-octet base offset (walrus uses `64`, seal uses `128`)\n// so they live in disjoint 64-wide bands inside `10.0.0.0/8`.\n//\n// Algorithm (DO NOT CHANGE without re-coordinating with every caller —\n// changing it shifts every parallel stack's assigned subnet, which\n// silently invalidates running containers and on-disk snapshots that\n// reference IPs by literal):\n//\n// 1. FNV-1a/32 over the UTF-16 code-unit sequence of `input`,\n// seeded `0x811c9dc5`, prime `0x01000193`, kept in unsigned\n// 32-bit space via `>>> 0`.\n// 2. Take the low `64 * 256 = 16384` buckets of the hash.\n// 3. Split the bucket into a second-octet add (`bucket / 256`,\n// 0..63) and a third-octet (`bucket % 256`, 0..255).\n// 4. Emit `'10.<secondOctetOffset + add>.<third>'`.\n//\n// The returned prefix is the `a.b.c` of an IPv4 `/24` — callers\n// append `.0/24` for the subnet and `.1` for the gateway.\n\nimport type { EnsureNetworkSpec } from '../../contracts/container-runtime.ts';\n\n/**\n * Derive a deterministic `/24` IPv4 subnet prefix from an identity\n * string, suitable for `EnsureNetworkSpec.subnet` requests.\n *\n * Uses FNV-1a/32 to bucket the input into one of 16384 slots inside\n * a 64-wide band of `10.0.0.0/8`. `secondOctetOffset` selects the\n * band — pick a value disjoint from every other caller (current\n * users: walrus `64`, seal `128`).\n *\n * @param input - opaque identity string. Callers should pack their\n * stack-identifying fields with a separator that cannot appear in\n * any field (`\\0` is the convention).\n * @param secondOctetOffset - lower-bound of the second IPv4 octet.\n * The derived second octet falls in `[offset, offset + 63]`.\n * @returns prefix string `'10.b.c'`. Append `.0/24` for the subnet\n * and `.1` for the gateway.\n */\nexport const deriveSubnetPrefix = (input: string, secondOctetOffset: number): string => {\n\tlet hash = 0x811c9dc5;\n\tfor (let i = 0; i < input.length; i += 1) {\n\t\thash ^= input.charCodeAt(i);\n\t\thash = Math.imul(hash, 0x01000193) >>> 0;\n\t}\n\tconst bucket = hash % (64 * 256);\n\tconst secondOctet = secondOctetOffset + Math.floor(bucket / 256);\n\tconst thirdOctet = bucket % 256;\n\treturn `10.${secondOctet}.${thirdOctet}`;\n};\n\n/**\n * Expand a `/24` prefix into the `{ subnet, gateway }` shape the\n * container-runtime `EnsureNetworkSpec` consumes.\n *\n * Convention: `<prefix>.0/24` for the subnet, `<prefix>.1` for the\n * gateway — the same pair walrus and seal both stamp on their\n * `ensureNetwork` requests. Folded here so the `/24` + `.1` literals\n * live in ONE place.\n */\nexport const subnetSpec = (\n\tprefix: string,\n): { readonly subnet: string; readonly gateway: string } => ({\n\tsubnet: `${prefix}.0/24`,\n\tgateway: `${prefix}.1`,\n});\n\n/**\n * Stamp the `{subnet, gateway}` pair derived from `subnetPrefix` onto\n * any `EnsureNetworkSpec`-shaped value. Both walrus and seal need the\n * same fold:\n *\n * {...spec, ...subnetSpec(prefix)}\n *\n * to widen a substrate-blind network spec into one that carries the\n * plugin's deterministic `/24` addressing — folded here so the literal\n * `Required<Pick<…, 'subnet' | 'gateway'>>` widening type lives in\n * ONE place.\n */\nexport const withSubnetAddressing = <Spec extends EnsureNetworkSpec>(\n\tspec: Spec,\n\tsubnetPrefix: string,\n): Spec & Required<Pick<EnsureNetworkSpec, 'subnet' | 'gateway'>> => ({\n\t...spec,\n\t...subnetSpec(subnetPrefix),\n});\n"],"mappings":";;;;;;;;;;;;;;;;;;AA6CA,MAAa,sBAAsB,OAAe,sBAAsC;CACvF,IAAI,OAAO;CACX,KAAK,IAAI,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK,GAAG;EACzC,QAAQ,MAAM,WAAW,CAAC;EAC1B,OAAO,KAAK,KAAK,MAAM,QAAU,MAAM;CACxC;CACA,MAAM,SAAS,QAAQ,KAAK;CAG5B,OAAO,MAFa,oBAAoB,KAAK,MAAM,SAAS,GAAG,EAEtC,GADN,SAAS;AAE7B;;;;;;;;;;AAWA,MAAa,cACZ,YAC4D;CAC5D,QAAQ,GAAG,OAAO;CAClB,SAAS,GAAG,OAAO;AACpB;;;;;;;;;;;;;AAcA,MAAa,wBACZ,MACA,kBACqE;CACrE,GAAG;CACH,GAAG,WAAW,YAAY;AAC3B"}
|