@rikalabs/akter 0.1.0-alpha.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/CHANGELOG.md +15 -0
- package/LICENSE +202 -0
- package/NOTICE +8 -0
- package/README.md +116 -0
- package/dist/actor/codecs.d.ts +77 -0
- package/dist/actor/codecs.js +87 -0
- package/dist/actor/connections.d.ts +34 -0
- package/dist/actor/connections.js +145 -0
- package/dist/actor/definition.d.ts +893 -0
- package/dist/actor/definition.js +147 -0
- package/dist/actor/descriptor.d.ts +172 -0
- package/dist/actor/descriptor.js +367 -0
- package/dist/actor/handles.d.ts +77 -0
- package/dist/actor/handles.js +265 -0
- package/dist/actor/jobs.d.ts +10 -0
- package/dist/actor/jobs.js +137 -0
- package/dist/actor/layers.d.ts +41 -0
- package/dist/actor/layers.js +177 -0
- package/dist/actor/reads.d.ts +47 -0
- package/dist/actor/reads.js +224 -0
- package/dist/actor/served.d.ts +120 -0
- package/dist/actor/served.js +72 -0
- package/dist/actor/turns.d.ts +13 -0
- package/dist/actor/turns.js +332 -0
- package/dist/actor/workflows.d.ts +16 -0
- package/dist/actor/workflows.js +37 -0
- package/dist/client/calls.d.ts +47 -0
- package/dist/client/calls.js +425 -0
- package/dist/client/clock.d.ts +56 -0
- package/dist/client/clock.js +119 -0
- package/dist/client/fleet-page.d.ts +15 -0
- package/dist/client/fleet-page.js +13 -0
- package/dist/client/fleet.d.ts +29 -0
- package/dist/client/fleet.js +51 -0
- package/dist/client/index.d.ts +17 -0
- package/dist/client/index.js +6 -0
- package/dist/client/make.d.ts +157 -0
- package/dist/client/make.js +221 -0
- package/dist/client/offline/queue.d.ts +118 -0
- package/dist/client/offline/queue.js +292 -0
- package/dist/client/offline/store.d.ts +74 -0
- package/dist/client/offline/store.js +78 -0
- package/dist/client/optimistic.d.ts +57 -0
- package/dist/client/optimistic.js +136 -0
- package/dist/client/report.d.ts +2 -0
- package/dist/client/report.js +8 -0
- package/dist/client/sessions/connection.d.ts +118 -0
- package/dist/client/sessions/connection.js +162 -0
- package/dist/client/sessions/feed.d.ts +42 -0
- package/dist/client/sessions/feed.js +43 -0
- package/dist/client/sessions/sse.d.ts +47 -0
- package/dist/client/sessions/sse.js +112 -0
- package/dist/client/sessions/stream.d.ts +28 -0
- package/dist/client/sessions/stream.js +35 -0
- package/dist/client/sessions/watch.d.ts +34 -0
- package/dist/client/sessions/watch.js +40 -0
- package/dist/client/transport.d.ts +37 -0
- package/dist/client/transport.js +66 -0
- package/dist/contexts/command.d.ts +132 -0
- package/dist/contexts/command.js +20 -0
- package/dist/contexts/connection.d.ts +68 -0
- package/dist/contexts/connection.js +0 -0
- package/dist/contexts/job.d.ts +49 -0
- package/dist/contexts/job.js +0 -0
- package/dist/contexts/workflow.d.ts +147 -0
- package/dist/contexts/workflow.js +22 -0
- package/dist/errors/actor.d.ts +200 -0
- package/dist/errors/actor.js +271 -0
- package/dist/errors/content.d.ts +19 -0
- package/dist/errors/content.js +14 -0
- package/dist/errors/database.d.ts +22 -0
- package/dist/errors/database.js +23 -0
- package/dist/errors/events.d.ts +17 -0
- package/dist/errors/events.js +14 -0
- package/dist/errors/subscription.d.ts +12 -0
- package/dist/errors/subscription.js +8 -0
- package/dist/errors/workflow.d.ts +28 -0
- package/dist/errors/workflow.js +17 -0
- package/dist/handles/actors.d.ts +17 -0
- package/dist/handles/actors.js +7 -0
- package/dist/handles/content.d.ts +59 -0
- package/dist/handles/content.js +36 -0
- package/dist/handles/intents.d.ts +164 -0
- package/dist/handles/intents.js +214 -0
- package/dist/handles/run.d.ts +31 -0
- package/dist/handles/run.js +21 -0
- package/dist/handles/workflow.d.ts +27 -0
- package/dist/handles/workflow.js +23 -0
- package/dist/identity/caller.d.ts +105 -0
- package/dist/identity/caller.js +68 -0
- package/dist/identity/child.d.ts +18 -0
- package/dist/identity/child.js +39 -0
- package/dist/identity/command.d.ts +19 -0
- package/dist/identity/command.js +21 -0
- package/dist/identity/connection.d.ts +24 -0
- package/dist/identity/connection.js +29 -0
- package/dist/identity/content.d.ts +18 -0
- package/dist/identity/content.js +12 -0
- package/dist/identity/digest.d.ts +4 -0
- package/dist/identity/digest.js +5 -0
- package/dist/identity/execution.d.ts +32 -0
- package/dist/identity/execution.js +63 -0
- package/dist/identity/mint.d.ts +51 -0
- package/dist/identity/mint.js +76 -0
- package/dist/identity/version.d.ts +2 -0
- package/dist/identity/version.js +3 -0
- package/dist/index.d.ts +159 -0
- package/dist/index.js +97 -0
- package/dist/members/blob.d.ts +43 -0
- package/dist/members/blob.js +29 -0
- package/dist/members/command.d.ts +109 -0
- package/dist/members/command.js +61 -0
- package/dist/members/connection.d.ts +55 -0
- package/dist/members/connection.js +49 -0
- package/dist/members/event.d.ts +36 -0
- package/dist/members/event.js +24 -0
- package/dist/members/job.d.ts +157 -0
- package/dist/members/job.js +67 -0
- package/dist/members/payload.d.ts +93 -0
- package/dist/members/payload.js +145 -0
- package/dist/members/reducer.d.ts +64 -0
- package/dist/members/reducer.js +27 -0
- package/dist/members/stream.d.ts +36 -0
- package/dist/members/stream.js +14 -0
- package/dist/members/subscription.d.ts +182 -0
- package/dist/members/subscription.js +91 -0
- package/dist/members/workflow.d.ts +99 -0
- package/dist/members/workflow.js +2 -0
- package/dist/policies/access.d.ts +35 -0
- package/dist/policies/access.js +6 -0
- package/dist/policies/command.d.ts +127 -0
- package/dist/policies/command.js +45 -0
- package/dist/policies/job.d.ts +28 -0
- package/dist/policies/job.js +60 -0
- package/dist/policies/schedules.d.ts +33 -0
- package/dist/policies/schedules.js +131 -0
- package/dist/protocol/frames.d.ts +66 -0
- package/dist/protocol/frames.js +55 -0
- package/dist/protocol/inspection.d.ts +807 -0
- package/dist/protocol/inspection.js +243 -0
- package/dist/protocol/wire.d.ts +184 -0
- package/dist/protocol/wire.js +150 -0
- package/dist/runtime/actors.d.ts +155 -0
- package/dist/runtime/actors.js +4 -0
- package/dist/runtime/admission.d.ts +34 -0
- package/dist/runtime/admission.js +72 -0
- package/dist/runtime/adoption/backfill.d.ts +27 -0
- package/dist/runtime/adoption/backfill.js +144 -0
- package/dist/runtime/adoption/enforce.d.ts +55 -0
- package/dist/runtime/adoption/enforce.js +241 -0
- package/dist/runtime/adoption/observe.d.ts +43 -0
- package/dist/runtime/adoption/observe.js +139 -0
- package/dist/runtime/adoption/plan.d.ts +45 -0
- package/dist/runtime/adoption/plan.js +192 -0
- package/dist/runtime/adoption/startup.d.ts +32 -0
- package/dist/runtime/adoption/startup.js +76 -0
- package/dist/runtime/adoption/status.d.ts +23 -0
- package/dist/runtime/adoption/status.js +47 -0
- package/dist/runtime/adoption/target.d.ts +33 -0
- package/dist/runtime/adoption/target.js +49 -0
- package/dist/runtime/connections/holder.d.ts +221 -0
- package/dist/runtime/connections/holder.js +816 -0
- package/dist/runtime/connections/owner.d.ts +263 -0
- package/dist/runtime/connections/owner.js +896 -0
- package/dist/runtime/connections/protocol.d.ts +441 -0
- package/dist/runtime/connections/protocol.js +222 -0
- package/dist/runtime/connections/reads.d.ts +24 -0
- package/dist/runtime/connections/reads.js +19 -0
- package/dist/runtime/connections/streams.d.ts +62 -0
- package/dist/runtime/connections/streams.js +128 -0
- package/dist/runtime/connections/transport.d.ts +40 -0
- package/dist/runtime/connections/transport.js +68 -0
- package/dist/runtime/connections/watch.d.ts +52 -0
- package/dist/runtime/connections/watch.js +159 -0
- package/dist/runtime/content/grant.d.ts +34 -0
- package/dist/runtime/content/grant.js +58 -0
- package/dist/runtime/content/store.d.ts +63 -0
- package/dist/runtime/content/store.js +294 -0
- package/dist/runtime/cron/key.d.ts +2 -0
- package/dist/runtime/cron/key.js +2 -0
- package/dist/runtime/cron/schedule.d.ts +69 -0
- package/dist/runtime/cron/schedule.js +144 -0
- package/dist/runtime/database/bounded.d.ts +43 -0
- package/dist/runtime/database/bounded.js +108 -0
- package/dist/runtime/database/connection.d.ts +8 -0
- package/dist/runtime/database/connection.js +18 -0
- package/dist/runtime/database/coordination.d.ts +19 -0
- package/dist/runtime/database/coordination.js +72 -0
- package/dist/runtime/database/flock.d.ts +10 -0
- package/dist/runtime/database/flock.js +60 -0
- package/dist/runtime/database/gate.d.ts +26 -0
- package/dist/runtime/database/gate.js +54 -0
- package/dist/runtime/database/keepalive.d.ts +11 -0
- package/dist/runtime/database/keepalive.js +22 -0
- package/dist/runtime/database/migrations.d.ts +177 -0
- package/dist/runtime/database/migrations.js +1018 -0
- package/dist/runtime/database/neki/migrations.d.ts +31 -0
- package/dist/runtime/database/neki/migrations.js +276 -0
- package/dist/runtime/database/neki/session.d.ts +23 -0
- package/dist/runtime/database/neki/session.js +31 -0
- package/dist/runtime/database/pglite.d.ts +21 -0
- package/dist/runtime/database/pglite.js +74 -0
- package/dist/runtime/database/replica.d.ts +41 -0
- package/dist/runtime/database/replica.js +51 -0
- package/dist/runtime/database/shards.d.ts +21 -0
- package/dist/runtime/database/shards.js +37 -0
- package/dist/runtime/database/snapshot.d.ts +7 -0
- package/dist/runtime/database/snapshot.js +7 -0
- package/dist/runtime/database/tenancy.d.ts +69 -0
- package/dist/runtime/database/tenancy.js +145 -0
- package/dist/runtime/database/transient.d.ts +10 -0
- package/dist/runtime/database/transient.js +25 -0
- package/dist/runtime/drain.d.ts +132 -0
- package/dist/runtime/drain.js +109 -0
- package/dist/runtime/entity/mailbox.d.ts +86 -0
- package/dist/runtime/entity/mailbox.js +121 -0
- package/dist/runtime/entity/register.d.ts +424 -0
- package/dist/runtime/entity/register.js +669 -0
- package/dist/runtime/events/append.d.ts +192 -0
- package/dist/runtime/events/append.js +128 -0
- package/dist/runtime/events/cursor.d.ts +2 -0
- package/dist/runtime/events/cursor.js +5 -0
- package/dist/runtime/events/replay.d.ts +20 -0
- package/dist/runtime/events/replay.js +45 -0
- package/dist/runtime/feeds.d.ts +26 -0
- package/dist/runtime/feeds.js +100 -0
- package/dist/runtime/fleet/checks.d.ts +17 -0
- package/dist/runtime/fleet/checks.js +106 -0
- package/dist/runtime/fleet/maintainer.d.ts +38 -0
- package/dist/runtime/fleet/maintainer.js +383 -0
- package/dist/runtime/fleet/pgoutput.d.ts +41 -0
- package/dist/runtime/fleet/pgoutput.js +102 -0
- package/dist/runtime/fleet/setup.d.ts +36 -0
- package/dist/runtime/fleet/setup.js +58 -0
- package/dist/runtime/fleet/subscribe.d.ts +42 -0
- package/dist/runtime/fleet/subscribe.js +147 -0
- package/dist/runtime/index.d.ts +66 -0
- package/dist/runtime/index.js +37 -0
- package/dist/runtime/inspector/http.d.ts +19 -0
- package/dist/runtime/inspector/http.js +36 -0
- package/dist/runtime/inspector/layer.d.ts +46 -0
- package/dist/runtime/inspector/layer.js +180 -0
- package/dist/runtime/inspector/queries.d.ts +711 -0
- package/dist/runtime/inspector/queries.js +494 -0
- package/dist/runtime/jobs/attempt.d.ts +254 -0
- package/dist/runtime/jobs/attempt.js +413 -0
- package/dist/runtime/jobs/isolation.d.ts +20 -0
- package/dist/runtime/jobs/isolation.js +10 -0
- package/dist/runtime/jobs/progress.d.ts +95 -0
- package/dist/runtime/jobs/progress.js +144 -0
- package/dist/runtime/layer.d.ts +260 -0
- package/dist/runtime/layer.js +876 -0
- package/dist/runtime/members.d.ts +381 -0
- package/dist/runtime/members.js +8 -0
- package/dist/runtime/operators/audit.d.ts +64 -0
- package/dist/runtime/operators/audit.js +56 -0
- package/dist/runtime/operators/auth.d.ts +29 -0
- package/dist/runtime/operators/auth.js +42 -0
- package/dist/runtime/operators/export.d.ts +68 -0
- package/dist/runtime/operators/export.js +137 -0
- package/dist/runtime/operators/grants.d.ts +45 -0
- package/dist/runtime/operators/grants.js +40 -0
- package/dist/runtime/operators/repair.d.ts +206 -0
- package/dist/runtime/operators/repair.js +226 -0
- package/dist/runtime/operators/routes.d.ts +35 -0
- package/dist/runtime/operators/routes.js +190 -0
- package/dist/runtime/operators/seed.d.ts +123 -0
- package/dist/runtime/operators/seed.js +123 -0
- package/dist/runtime/payloads/versions.d.ts +65 -0
- package/dist/runtime/payloads/versions.js +240 -0
- package/dist/runtime/peering/authority.d.ts +42 -0
- package/dist/runtime/peering/authority.js +132 -0
- package/dist/runtime/peering/credentials.d.ts +21 -0
- package/dist/runtime/peering/credentials.js +13 -0
- package/dist/runtime/peering/transport.d.ts +51 -0
- package/dist/runtime/peering/transport.js +175 -0
- package/dist/runtime/queries.d.ts +18 -0
- package/dist/runtime/queries.js +169 -0
- package/dist/runtime/readiness.d.ts +36 -0
- package/dist/runtime/readiness.js +44 -0
- package/dist/runtime/registration.d.ts +58 -0
- package/dist/runtime/registration.js +186 -0
- package/dist/runtime/request.d.ts +158 -0
- package/dist/runtime/request.js +102 -0
- package/dist/runtime/retry.d.ts +8 -0
- package/dist/runtime/retry.js +11 -0
- package/dist/runtime/runner.d.ts +93 -0
- package/dist/runtime/runner.js +122 -0
- package/dist/runtime/storage/codec.d.ts +39 -0
- package/dist/runtime/storage/codec.js +41 -0
- package/dist/runtime/storage/generation.d.ts +69 -0
- package/dist/runtime/storage/generation.js +49 -0
- package/dist/runtime/storage/placements.d.ts +15 -0
- package/dist/runtime/storage/placements.js +38 -0
- package/dist/runtime/storage/platform.d.ts +6 -0
- package/dist/runtime/storage/platform.js +9 -0
- package/dist/runtime/storage/retention.d.ts +73 -0
- package/dist/runtime/storage/retention.js +158 -0
- package/dist/runtime/subscriptions/identity.d.ts +31 -0
- package/dist/runtime/subscriptions/identity.js +45 -0
- package/dist/runtime/subscriptions/relay.d.ts +175 -0
- package/dist/runtime/subscriptions/relay.js +763 -0
- package/dist/runtime/subscriptions/storage.d.ts +40 -0
- package/dist/runtime/subscriptions/storage.js +98 -0
- package/dist/runtime/sweeps.d.ts +39 -0
- package/dist/runtime/sweeps.js +54 -0
- package/dist/runtime/telemetry/defects.d.ts +57 -0
- package/dist/runtime/telemetry/defects.js +43 -0
- package/dist/runtime/telemetry/metrics.d.ts +52 -0
- package/dist/runtime/telemetry/metrics.js +138 -0
- package/dist/runtime/telemetry/routes.d.ts +19 -0
- package/dist/runtime/telemetry/routes.js +18 -0
- package/dist/runtime/telemetry/sampler.d.ts +26 -0
- package/dist/runtime/telemetry/sampler.js +101 -0
- package/dist/runtime/telemetry/spans.d.ts +38 -0
- package/dist/runtime/telemetry/spans.js +44 -0
- package/dist/runtime/telemetry/usage.d.ts +52 -0
- package/dist/runtime/telemetry/usage.js +30 -0
- package/dist/runtime/topology/admission.d.ts +13 -0
- package/dist/runtime/topology/admission.js +36 -0
- package/dist/runtime/topology/locks.d.ts +56 -0
- package/dist/runtime/topology/locks.js +81 -0
- package/dist/runtime/topology/messages.d.ts +15 -0
- package/dist/runtime/topology/messages.js +32 -0
- package/dist/runtime/turn/admission.d.ts +22 -0
- package/dist/runtime/turn/admission.js +41 -0
- package/dist/runtime/turn/blobs.d.ts +38 -0
- package/dist/runtime/turn/blobs.js +215 -0
- package/dist/runtime/turn/execute.d.ts +208 -0
- package/dist/runtime/turn/execute.js +972 -0
- package/dist/runtime/turn/group.d.ts +165 -0
- package/dist/runtime/turn/group.js +326 -0
- package/dist/runtime/turn/hooks.d.ts +44 -0
- package/dist/runtime/turn/hooks.js +28 -0
- package/dist/runtime/turn/outbox.d.ts +159 -0
- package/dist/runtime/turn/outbox.js +269 -0
- package/dist/runtime/turn/pipeline.d.ts +68 -0
- package/dist/runtime/turn/pipeline.js +83 -0
- package/dist/runtime/turn/receipt.d.ts +81 -0
- package/dist/runtime/turn/receipt.js +32 -0
- package/dist/runtime/turn/relay.d.ts +179 -0
- package/dist/runtime/turn/relay.js +685 -0
- package/dist/runtime/turn/rows.d.ts +43 -0
- package/dist/runtime/turn/rows.js +592 -0
- package/dist/runtime/workflows/compatibility.d.ts +125 -0
- package/dist/runtime/workflows/compatibility.js +285 -0
- package/dist/runtime/workflows/engine.d.ts +107 -0
- package/dist/runtime/workflows/engine.js +826 -0
- package/dist/runtime/workflows/manifest.d.ts +34 -0
- package/dist/runtime/workflows/manifest.js +39 -0
- package/dist/runtime/workflows/steps.d.ts +33 -0
- package/dist/runtime/workflows/steps.js +152 -0
- package/dist/serve/api.d.ts +99 -0
- package/dist/serve/api.js +403 -0
- package/dist/serve/assertion/binding.d.ts +41 -0
- package/dist/serve/assertion/binding.js +92 -0
- package/dist/serve/assertion/verify.d.ts +93 -0
- package/dist/serve/assertion/verify.js +189 -0
- package/dist/serve/auth.d.ts +200 -0
- package/dist/serve/auth.js +92 -0
- package/dist/serve/clock.d.ts +10 -0
- package/dist/serve/clock.js +25 -0
- package/dist/serve/jwt.d.ts +65 -0
- package/dist/serve/jwt.js +202 -0
- package/dist/serve/layer.d.ts +98 -0
- package/dist/serve/layer.js +809 -0
- package/dist/serve/mcp/endpoint.d.ts +39 -0
- package/dist/serve/mcp/endpoint.js +187 -0
- package/dist/serve/mcp/tools.d.ts +37 -0
- package/dist/serve/mcp/tools.js +125 -0
- package/dist/serve/origin.d.ts +6 -0
- package/dist/serve/origin.js +21 -0
- package/dist/serve/sessions/feed.d.ts +79 -0
- package/dist/serve/sessions/feed.js +115 -0
- package/dist/serve/sessions/socket.d.ts +56 -0
- package/dist/serve/sessions/socket.js +212 -0
- package/dist/serve/sessions/sse.d.ts +27 -0
- package/dist/serve/sessions/sse.js +26 -0
- package/dist/serve/sessions/stream.d.ts +9 -0
- package/dist/serve/sessions/stream.js +9 -0
- package/dist/serve/sessions/watch.d.ts +12 -0
- package/dist/serve/sessions/watch.js +11 -0
- package/dist/serve/wire.d.ts +16 -0
- package/dist/serve/wire.js +50 -0
- package/dist/state/blob.d.ts +71 -0
- package/dist/state/blob.js +0 -0
- package/dist/state/migration.d.ts +53 -0
- package/dist/state/migration.js +29 -0
- package/dist/tables/fleet.d.ts +170 -0
- package/dist/tables/fleet.js +214 -0
- package/dist/tables/owned.d.ts +250 -0
- package/dist/tables/owned.js +233 -0
- package/dist/testing/actor-test.d.ts +360 -0
- package/dist/testing/actor-test.js +337 -0
- package/dist/testing/cluster.d.ts +93 -0
- package/dist/testing/cluster.js +296 -0
- package/dist/testing/conformance/access.d.ts +5 -0
- package/dist/testing/conformance/access.js +531 -0
- package/dist/testing/conformance/admission.d.ts +11 -0
- package/dist/testing/conformance/admission.js +182 -0
- package/dist/testing/conformance/adoption.d.ts +2 -0
- package/dist/testing/conformance/adoption.js +1019 -0
- package/dist/testing/conformance/assertions.d.ts +202 -0
- package/dist/testing/conformance/assertions.js +849 -0
- package/dist/testing/conformance/batches.d.ts +41 -0
- package/dist/testing/conformance/batches.js +388 -0
- package/dist/testing/conformance/blobs.d.ts +14 -0
- package/dist/testing/conformance/blobs.js +405 -0
- package/dist/testing/conformance/capacity.d.ts +8 -0
- package/dist/testing/conformance/capacity.js +433 -0
- package/dist/testing/conformance/client.d.ts +5 -0
- package/dist/testing/conformance/client.js +719 -0
- package/dist/testing/conformance/cold-serve.d.ts +16 -0
- package/dist/testing/conformance/cold-serve.js +254 -0
- package/dist/testing/conformance/connections/actors.d.ts +1143 -0
- package/dist/testing/conformance/connections/actors.js +180 -0
- package/dist/testing/conformance/connections/harness.d.ts +1754 -0
- package/dist/testing/conformance/connections/harness.js +142 -0
- package/dist/testing/conformance/connections/holders.d.ts +4 -0
- package/dist/testing/conformance/connections/holders.js +165 -0
- package/dist/testing/conformance/connections/lifecycle.d.ts +4 -0
- package/dist/testing/conformance/connections/lifecycle.js +113 -0
- package/dist/testing/conformance/connections/limits.d.ts +4 -0
- package/dist/testing/conformance/connections/limits.js +127 -0
- package/dist/testing/conformance/connections/reauthorization.d.ts +4 -0
- package/dist/testing/conformance/connections/reauthorization.js +170 -0
- package/dist/testing/conformance/connections/resync.d.ts +4 -0
- package/dist/testing/conformance/connections/resync.js +360 -0
- package/dist/testing/conformance/connections/takeover.d.ts +4 -0
- package/dist/testing/conformance/connections/takeover.js +287 -0
- package/dist/testing/conformance/connections.d.ts +4 -0
- package/dist/testing/conformance/connections.js +15 -0
- package/dist/testing/conformance/content-blobs.d.ts +16 -0
- package/dist/testing/conformance/content-blobs.js +534 -0
- package/dist/testing/conformance/counter.d.ts +16 -0
- package/dist/testing/conformance/counter.js +813 -0
- package/dist/testing/conformance/cron.d.ts +5 -0
- package/dist/testing/conformance/cron.js +665 -0
- package/dist/testing/conformance/drain.d.ts +26 -0
- package/dist/testing/conformance/drain.js +540 -0
- package/dist/testing/conformance/effect-control.d.ts +38 -0
- package/dist/testing/conformance/effect-control.js +1059 -0
- package/dist/testing/conformance/effects.d.ts +23 -0
- package/dist/testing/conformance/effects.js +432 -0
- package/dist/testing/conformance/events.d.ts +28 -0
- package/dist/testing/conformance/events.js +335 -0
- package/dist/testing/conformance/export.d.ts +2 -0
- package/dist/testing/conformance/export.js +368 -0
- package/dist/testing/conformance/fleet.d.ts +444 -0
- package/dist/testing/conformance/fleet.js +1009 -0
- package/dist/testing/conformance/groups.d.ts +7 -0
- package/dist/testing/conformance/groups.js +353 -0
- package/dist/testing/conformance/heap.d.ts +3 -0
- package/dist/testing/conformance/heap.js +149 -0
- package/dist/testing/conformance/http.d.ts +2809 -0
- package/dist/testing/conformance/http.js +1234 -0
- package/dist/testing/conformance/inspection-views.d.ts +8 -0
- package/dist/testing/conformance/inspection-views.js +272 -0
- package/dist/testing/conformance/inspector.d.ts +7 -0
- package/dist/testing/conformance/inspector.js +650 -0
- package/dist/testing/conformance/mint.d.ts +58 -0
- package/dist/testing/conformance/mint.js +692 -0
- package/dist/testing/conformance/multi-runner.d.ts +8 -0
- package/dist/testing/conformance/multi-runner.js +403 -0
- package/dist/testing/conformance/neki/plan.d.ts +19 -0
- package/dist/testing/conformance/neki/plan.js +30 -0
- package/dist/testing/conformance/observability.d.ts +3 -0
- package/dist/testing/conformance/observability.js +343 -0
- package/dist/testing/conformance/offline.d.ts +4 -0
- package/dist/testing/conformance/offline.js +474 -0
- package/dist/testing/conformance/operator-harness.d.ts +57 -0
- package/dist/testing/conformance/operator-harness.js +78 -0
- package/dist/testing/conformance/operator.d.ts +3 -0
- package/dist/testing/conformance/operator.js +379 -0
- package/dist/testing/conformance/outbox-cross-shard.d.ts +14 -0
- package/dist/testing/conformance/outbox-cross-shard.js +160 -0
- package/dist/testing/conformance/outbox.d.ts +36 -0
- package/dist/testing/conformance/outbox.js +437 -0
- package/dist/testing/conformance/payload-migrations.d.ts +3 -0
- package/dist/testing/conformance/payload-migrations.js +612 -0
- package/dist/testing/conformance/pipeline.d.ts +3 -0
- package/dist/testing/conformance/pipeline.js +1040 -0
- package/dist/testing/conformance/placement.d.ts +22 -0
- package/dist/testing/conformance/placement.js +539 -0
- package/dist/testing/conformance/platform.d.ts +40 -0
- package/dist/testing/conformance/platform.js +101 -0
- package/dist/testing/conformance/progress.d.ts +39 -0
- package/dist/testing/conformance/progress.js +666 -0
- package/dist/testing/conformance/properties.d.ts +6 -0
- package/dist/testing/conformance/properties.js +295 -0
- package/dist/testing/conformance/protocols.d.ts +4 -0
- package/dist/testing/conformance/protocols.js +618 -0
- package/dist/testing/conformance/provider/advertise.d.ts +21 -0
- package/dist/testing/conformance/provider/advertise.js +44 -0
- package/dist/testing/conformance/read-your-writes.d.ts +20 -0
- package/dist/testing/conformance/read-your-writes.js +192 -0
- package/dist/testing/conformance/reducers.d.ts +8 -0
- package/dist/testing/conformance/reducers.js +258 -0
- package/dist/testing/conformance/relay.d.ts +42 -0
- package/dist/testing/conformance/relay.js +1115 -0
- package/dist/testing/conformance/restore.d.ts +43 -0
- package/dist/testing/conformance/restore.js +341 -0
- package/dist/testing/conformance/retention.d.ts +14 -0
- package/dist/testing/conformance/retention.js +463 -0
- package/dist/testing/conformance/rls.d.ts +24 -0
- package/dist/testing/conformance/rls.js +576 -0
- package/dist/testing/conformance/simulation.d.ts +31 -0
- package/dist/testing/conformance/simulation.js +167 -0
- package/dist/testing/conformance/single-shard.d.ts +2 -0
- package/dist/testing/conformance/single-shard.js +125 -0
- package/dist/testing/conformance/singleton.d.ts +3 -0
- package/dist/testing/conformance/singleton.js +293 -0
- package/dist/testing/conformance/statements.d.ts +60 -0
- package/dist/testing/conformance/statements.js +108 -0
- package/dist/testing/conformance/streams.d.ts +7 -0
- package/dist/testing/conformance/streams.js +280 -0
- package/dist/testing/conformance/subscriptions/access.d.ts +4 -0
- package/dist/testing/conformance/subscriptions/access.js +98 -0
- package/dist/testing/conformance/subscriptions/actors.d.ts +4910 -0
- package/dist/testing/conformance/subscriptions/actors.js +372 -0
- package/dist/testing/conformance/subscriptions/cluster.d.ts +4 -0
- package/dist/testing/conformance/subscriptions/cluster.js +89 -0
- package/dist/testing/conformance/subscriptions/delivery.d.ts +4 -0
- package/dist/testing/conformance/subscriptions/delivery.js +253 -0
- package/dist/testing/conformance/subscriptions/deploys.d.ts +4 -0
- package/dist/testing/conformance/subscriptions/deploys.js +162 -0
- package/dist/testing/conformance/subscriptions/epochs.d.ts +4 -0
- package/dist/testing/conformance/subscriptions/epochs.js +169 -0
- package/dist/testing/conformance/subscriptions/failures.d.ts +4 -0
- package/dist/testing/conformance/subscriptions/failures.js +108 -0
- package/dist/testing/conformance/subscriptions/feeds.d.ts +4 -0
- package/dist/testing/conformance/subscriptions/feeds.js +218 -0
- package/dist/testing/conformance/subscriptions/harness.d.ts +124 -0
- package/dist/testing/conformance/subscriptions/harness.js +143 -0
- package/dist/testing/conformance/subscriptions/operator.d.ts +4 -0
- package/dist/testing/conformance/subscriptions/operator.js +128 -0
- package/dist/testing/conformance/subscriptions/retention.d.ts +4 -0
- package/dist/testing/conformance/subscriptions/retention.js +288 -0
- package/dist/testing/conformance/subscriptions/routing.d.ts +4 -0
- package/dist/testing/conformance/subscriptions/routing.js +179 -0
- package/dist/testing/conformance/subscriptions.d.ts +4 -0
- package/dist/testing/conformance/subscriptions.js +19 -0
- package/dist/testing/conformance/tables.d.ts +125 -0
- package/dist/testing/conformance/tables.js +664 -0
- package/dist/testing/conformance/transports/actors.d.ts +1907 -0
- package/dist/testing/conformance/transports/actors.js +163 -0
- package/dist/testing/conformance/transports/client.d.ts +3 -0
- package/dist/testing/conformance/transports/client.js +237 -0
- package/dist/testing/conformance/transports/feeds.d.ts +3 -0
- package/dist/testing/conformance/transports/feeds.js +232 -0
- package/dist/testing/conformance/transports/harness.d.ts +93 -0
- package/dist/testing/conformance/transports/harness.js +84 -0
- package/dist/testing/conformance/transports/streams.d.ts +3 -0
- package/dist/testing/conformance/transports/streams.js +96 -0
- package/dist/testing/conformance/transports/websocket.d.ts +3 -0
- package/dist/testing/conformance/transports/websocket.js +384 -0
- package/dist/testing/conformance/transports/wire.d.ts +141 -0
- package/dist/testing/conformance/transports/wire.js +204 -0
- package/dist/testing/conformance/transports.d.ts +3 -0
- package/dist/testing/conformance/transports.js +11 -0
- package/dist/testing/conformance/watch.d.ts +59 -0
- package/dist/testing/conformance/watch.js +879 -0
- package/dist/testing/conformance/workflow-engine.d.ts +97 -0
- package/dist/testing/conformance/workflow-engine.js +253 -0
- package/dist/testing/conformance/workflow-versions.d.ts +3 -0
- package/dist/testing/conformance/workflow-versions.js +545 -0
- package/dist/testing/conformance/workflows/access.d.ts +4 -0
- package/dist/testing/conformance/workflows/access.js +147 -0
- package/dist/testing/conformance/workflows/actors.d.ts +2317 -0
- package/dist/testing/conformance/workflows/actors.js +305 -0
- package/dist/testing/conformance/workflows/basics.d.ts +4 -0
- package/dist/testing/conformance/workflows/basics.js +144 -0
- package/dist/testing/conformance/workflows/engine.d.ts +4 -0
- package/dist/testing/conformance/workflows/engine.js +80 -0
- package/dist/testing/conformance/workflows/guards.d.ts +4 -0
- package/dist/testing/conformance/workflows/guards.js +172 -0
- package/dist/testing/conformance/workflows/harness.d.ts +14 -0
- package/dist/testing/conformance/workflows/harness.js +44 -0
- package/dist/testing/conformance/workflows/recovery.d.ts +4 -0
- package/dist/testing/conformance/workflows/recovery.js +181 -0
- package/dist/testing/conformance/workflows/starts.d.ts +4 -0
- package/dist/testing/conformance/workflows/starts.js +57 -0
- package/dist/testing/conformance/workflows/suspension.d.ts +4 -0
- package/dist/testing/conformance/workflows/suspension.js +106 -0
- package/dist/testing/conformance/workflows/waits.d.ts +4 -0
- package/dist/testing/conformance/workflows/waits.js +284 -0
- package/dist/testing/conformance/workflows.d.ts +4 -0
- package/dist/testing/conformance/workflows.js +19 -0
- package/dist/testing/conformance.d.ts +330 -0
- package/dist/testing/conformance.js +364 -0
- package/dist/testing/database.d.ts +31 -0
- package/dist/testing/database.js +70 -0
- package/dist/testing/foundation.d.ts +41 -0
- package/dist/testing/foundation.js +517 -0
- package/dist/testing/index.d.ts +20 -0
- package/dist/testing/index.js +12 -0
- package/dist/testing/property.d.ts +40 -0
- package/dist/testing/property.js +95 -0
- package/dist/testing/simulate-cluster.d.ts +112 -0
- package/dist/testing/simulate-cluster.js +257 -0
- package/dist/testing/simulate.d.ts +90 -0
- package/dist/testing/simulate.js +127 -0
- package/package.json +1 -0
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
import { Effect } from "effect";
|
|
2
|
+
import { SqlClient } from "effect/sql";
|
|
3
|
+
import { descriptorOf } from "../../actor/descriptor.js";
|
|
4
|
+
import {} from "../../members/payload.js";
|
|
5
|
+
import { inReadOnlySnapshot } from "../database/snapshot.js";
|
|
6
|
+
import { databaseTime } from "../turn/admission.js";
|
|
7
|
+
import { textArray } from "../turn/outbox.js";
|
|
8
|
+
/** How long a runtime's writer rows stay live without a refresh, by default. */
|
|
9
|
+
export const DEFAULT_WRITER_WINDOW_MS = 120_000;
|
|
10
|
+
/** A one-line operator-facing description of a payload problem. */
|
|
11
|
+
export const formatPayloadProblem = (problem) => `${problem.actorType}/${problem.tag} (${problem.kind}) ${problem.problem}`;
|
|
12
|
+
const keyOf = (declared) => `${declared.actorType}\u0000${declared.kind}\u0000${declared.tag}`;
|
|
13
|
+
/**
|
|
14
|
+
* Compares declared chains with the versions the database may hold. A
|
|
15
|
+
* version recorded above a chain's current version is a rollback past a
|
|
16
|
+
* schema change. A chain that starts above version `v` can't read values of
|
|
17
|
+
* `v`: an event version counts as stored until `durable payloads clear` marks
|
|
18
|
+
* it cleared. Every stored event has a recorded version, because a runtime
|
|
19
|
+
* records what it writes before it takes a shard and the migration refused
|
|
20
|
+
* databases that held rows before it. Job versions are read from the
|
|
21
|
+
* outbox and dead letters directly. `writers` names the actor types whose
|
|
22
|
+
* turns this deployment runs: an event tag one of them no longer declares is
|
|
23
|
+
* refused while a subscription still has undelivered events of it.
|
|
24
|
+
*/
|
|
25
|
+
export const findPayloadProblems = Effect.fnUntraced(function* (declarations, writers = []) {
|
|
26
|
+
const sql = yield* SqlClient.SqlClient;
|
|
27
|
+
const problems = [];
|
|
28
|
+
const actorTypes = [
|
|
29
|
+
...new Set([...declarations.map((d) => d.actorType), ...writers.map((w) => w.actorType)]),
|
|
30
|
+
];
|
|
31
|
+
if (actorTypes.length === 0)
|
|
32
|
+
return problems;
|
|
33
|
+
const recorded = yield* sql `SELECT actor_type, kind, tag, version,
|
|
34
|
+
cleared_at_ms IS NOT NULL AS cleared
|
|
35
|
+
FROM actor_payload_versions WHERE actor_type IN ${sql.in(actorTypes)}`;
|
|
36
|
+
const byTag = new Map();
|
|
37
|
+
for (const row of recorded) {
|
|
38
|
+
const key = keyOf({ actorType: row.actor_type, kind: row.kind, tag: row.tag });
|
|
39
|
+
byTag.set(key, [...(byTag.get(key) ?? []), row]);
|
|
40
|
+
}
|
|
41
|
+
const seen = new Set();
|
|
42
|
+
for (const declared of declarations) {
|
|
43
|
+
const key = `${keyOf(declared)}\u0000${declared.chain.first}\u0000${declared.chain.current}`;
|
|
44
|
+
if (seen.has(key))
|
|
45
|
+
continue;
|
|
46
|
+
seen.add(key);
|
|
47
|
+
const { first, current } = declared.chain;
|
|
48
|
+
const versions = byTag.get(keyOf(declared)) ?? [];
|
|
49
|
+
const problem = (text) => problems.push({
|
|
50
|
+
actorType: declared.actorType,
|
|
51
|
+
kind: declared.kind,
|
|
52
|
+
tag: declared.tag,
|
|
53
|
+
problem: text,
|
|
54
|
+
});
|
|
55
|
+
const newest = Math.max(-1, ...versions.map((row) => row.version));
|
|
56
|
+
if (newest > current)
|
|
57
|
+
problem(`version ${newest} recorded above this chain's current version ${current}: a rollback past a payload schema change`);
|
|
58
|
+
if (first === 0)
|
|
59
|
+
continue;
|
|
60
|
+
if (declared.kind === "event") {
|
|
61
|
+
for (const row of versions)
|
|
62
|
+
if (row.version < first && !row.cleared)
|
|
63
|
+
problem(`version ${row.version} may still be stored below this chain's first version ${first}; run durable payloads clear once its events are gone`);
|
|
64
|
+
}
|
|
65
|
+
else {
|
|
66
|
+
const [stored] = yield* sql `
|
|
67
|
+
SELECT min(v)::int AS version, count(*)::int AS rows FROM (
|
|
68
|
+
SELECT payload_version AS v FROM actor_outbox
|
|
69
|
+
WHERE kind = 'job' AND actor_type = ${declared.actorType} AND command = ${declared.tag}
|
|
70
|
+
AND payload_version < ${first}
|
|
71
|
+
UNION ALL
|
|
72
|
+
SELECT payload_version FROM actor_dead_letters
|
|
73
|
+
WHERE actor_type = ${declared.actorType} AND job = ${declared.tag}
|
|
74
|
+
AND payload_version < ${first}) stored`;
|
|
75
|
+
if (stored !== undefined && stored.version !== null)
|
|
76
|
+
problem(`version ${stored.version} stored in ${stored.rows} pending job or dead letter row${stored.rows === 1 ? "" : "s"} below this chain's first version ${first}`);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
for (const writer of writers) {
|
|
80
|
+
const removed = [
|
|
81
|
+
...new Set(recorded
|
|
82
|
+
.filter((row) => row.actor_type === writer.actorType &&
|
|
83
|
+
row.kind === "event" &&
|
|
84
|
+
!writer.events.includes(row.tag))
|
|
85
|
+
.map((row) => row.tag)),
|
|
86
|
+
];
|
|
87
|
+
for (const tag of removed) {
|
|
88
|
+
const [pending] = yield* sql `
|
|
89
|
+
SELECT s.subscriber_type, s.subscription FROM actor_subscriptions s
|
|
90
|
+
WHERE s.source_type = ${writer.actorType} AND ${tag} = ANY(s.events)
|
|
91
|
+
AND EXISTS (SELECT 1 FROM actor_events e
|
|
92
|
+
WHERE e.routing_key = s.routing_key AND e.tenant_id = s.tenant_id
|
|
93
|
+
AND e.actor_type = s.source_type AND e.actor_id = s.source_id
|
|
94
|
+
AND e.event = ${tag} AND e.sequence > s.delivered)
|
|
95
|
+
LIMIT 1`;
|
|
96
|
+
if (pending !== undefined)
|
|
97
|
+
problems.push({
|
|
98
|
+
actorType: writer.actorType,
|
|
99
|
+
kind: "event",
|
|
100
|
+
tag,
|
|
101
|
+
problem: `event class removed while subscription ${pending.subscriber_type}.${pending.subscription} has undelivered events of it`,
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
return problems;
|
|
106
|
+
});
|
|
107
|
+
/**
|
|
108
|
+
* Records the version each written class is written at, and marks every
|
|
109
|
+
* lower recorded version superseded. Writing a version again clears its
|
|
110
|
+
* `superseded` and `cleared` marks, since values of it are being stored anew.
|
|
111
|
+
*/
|
|
112
|
+
export const recordPayloadVersions = Effect.fnUntraced(function* (declarations) {
|
|
113
|
+
const written = declarations.filter((declared) => declared.writes);
|
|
114
|
+
if (written.length === 0)
|
|
115
|
+
return;
|
|
116
|
+
const sql = yield* SqlClient.SqlClient;
|
|
117
|
+
const now = yield* databaseTime;
|
|
118
|
+
yield* sql `WITH declared (actor_type, kind, tag, version) AS (
|
|
119
|
+
SELECT * FROM unnest(${textArray({ sql, values: written.map((d) => d.actorType) })},
|
|
120
|
+
${textArray({ sql, values: written.map((d) => d.kind) })},
|
|
121
|
+
${textArray({ sql, values: written.map((d) => d.tag) })},
|
|
122
|
+
${textArray({ sql, values: written.map((d) => String(d.chain.writeVersion)) })}::int[])),
|
|
123
|
+
recorded AS (
|
|
124
|
+
INSERT INTO actor_payload_versions (actor_type, kind, tag, version, first_written_at_ms)
|
|
125
|
+
SELECT actor_type, kind, tag, version, ${now} FROM declared
|
|
126
|
+
ON CONFLICT (actor_type, kind, tag, version) DO UPDATE
|
|
127
|
+
SET superseded_at_ms = NULL, cleared_at_ms = NULL
|
|
128
|
+
WHERE actor_payload_versions.superseded_at_ms IS NOT NULL
|
|
129
|
+
RETURNING 1)
|
|
130
|
+
UPDATE actor_payload_versions v SET superseded_at_ms = ${now}
|
|
131
|
+
FROM declared d
|
|
132
|
+
WHERE v.actor_type = d.actor_type AND v.kind = d.kind AND v.tag = d.tag
|
|
133
|
+
AND v.version < d.version AND v.superseded_at_ms IS NULL`;
|
|
134
|
+
});
|
|
135
|
+
/** Upserts this runtime's writer row for each class it writes, stamped now, in one statement. */
|
|
136
|
+
export const refreshWriters = Effect.fnUntraced(function* (runtimeId, windowMs, declarations) {
|
|
137
|
+
const written = declarations.filter((declared) => declared.writes);
|
|
138
|
+
if (written.length === 0)
|
|
139
|
+
return;
|
|
140
|
+
const sql = yield* SqlClient.SqlClient;
|
|
141
|
+
const now = yield* databaseTime;
|
|
142
|
+
yield* sql `INSERT INTO actor_payload_writers (runtime_id, actor_type, kind, tag, version,
|
|
143
|
+
window_ms, refreshed_at_ms)
|
|
144
|
+
SELECT DISTINCT ${runtimeId}, actor_type, kind, tag, version, ${windowMs}::bigint, ${now}::bigint
|
|
145
|
+
FROM unnest(${textArray({ sql, values: written.map((d) => d.actorType) })},
|
|
146
|
+
${textArray({ sql, values: written.map((d) => d.kind) })},
|
|
147
|
+
${textArray({ sql, values: written.map((d) => d.tag) })},
|
|
148
|
+
${textArray({ sql, values: written.map((d) => String(d.chain.writeVersion)) })}::int[])
|
|
149
|
+
AS declared (actor_type, kind, tag, version)
|
|
150
|
+
ON CONFLICT (runtime_id, actor_type, kind, tag, version)
|
|
151
|
+
DO UPDATE SET refreshed_at_ms = EXCLUDED.refreshed_at_ms, window_ms = EXCLUDED.window_ms`;
|
|
152
|
+
});
|
|
153
|
+
/** Drops a stopping runtime's writer rows, so a clear need not wait out its window. */
|
|
154
|
+
export const dropWriters = (runtimeId) => Effect.gen(function* () {
|
|
155
|
+
const sql = yield* SqlClient.SqlClient;
|
|
156
|
+
yield* sql `DELETE FROM actor_payload_writers WHERE runtime_id = ${runtimeId}`;
|
|
157
|
+
});
|
|
158
|
+
const definitionsOf = (actors) => actors.flatMap((actor) => {
|
|
159
|
+
const payloads = descriptorOf(actor)?.definitionPayloads;
|
|
160
|
+
return payloads === undefined ? [] : [payloads];
|
|
161
|
+
});
|
|
162
|
+
/** `durable payloads check`: the startup check for `actors`, read-only. */
|
|
163
|
+
export const checkPayloads = (actors) => Effect.suspend(() => {
|
|
164
|
+
const definitions = definitionsOf(actors);
|
|
165
|
+
return inReadOnlySnapshot(findPayloadProblems(definitions.flatMap((d) => d.declarations), definitions.flatMap((d) => {
|
|
166
|
+
const actorType = d.declarations[0]?.actorType;
|
|
167
|
+
return actorType === undefined
|
|
168
|
+
? []
|
|
169
|
+
: [
|
|
170
|
+
{
|
|
171
|
+
actorType,
|
|
172
|
+
events: d.declarations
|
|
173
|
+
.filter((declared) => declared.kind === "event")
|
|
174
|
+
.map((declared) => declared.tag),
|
|
175
|
+
},
|
|
176
|
+
];
|
|
177
|
+
})));
|
|
178
|
+
});
|
|
179
|
+
/**
|
|
180
|
+
* `durable payloads clear`: marks each superseded event version of `actors`
|
|
181
|
+
* cleared once its retention horizon has passed, no runtime can still write
|
|
182
|
+
* it, and no event of it remains. The version row is locked first, the
|
|
183
|
+
* writer rows are read again after the scan, and each statement of the
|
|
184
|
+
* transaction reads a fresh snapshot, so a writer that registers during the
|
|
185
|
+
* scan fails the clear instead of racing it. A writer counts as live until
|
|
186
|
+
* its window and then the longest command timeout have passed.
|
|
187
|
+
*/
|
|
188
|
+
export const clearPayloads = (actors) => Effect.gen(function* () {
|
|
189
|
+
const sql = yield* SqlClient.SqlClient;
|
|
190
|
+
const definitions = definitionsOf(actors);
|
|
191
|
+
const commandTimeoutMs = Math.max(0, ...definitions.map((d) => d.commandTimeoutMs));
|
|
192
|
+
const results = [];
|
|
193
|
+
for (const definition of definitions)
|
|
194
|
+
for (const declared of definition.declarations) {
|
|
195
|
+
if (declared.kind !== "event")
|
|
196
|
+
continue;
|
|
197
|
+
const now = yield* databaseTime;
|
|
198
|
+
const due = yield* sql `SELECT version FROM actor_payload_versions
|
|
199
|
+
WHERE actor_type = ${declared.actorType} AND kind = 'event' AND tag = ${declared.tag}
|
|
200
|
+
AND cleared_at_ms IS NULL AND superseded_at_ms IS NOT NULL
|
|
201
|
+
AND superseded_at_ms + ${definition.keepEventsMs}::bigint <= ${now}
|
|
202
|
+
ORDER BY version`;
|
|
203
|
+
for (const { version } of due) {
|
|
204
|
+
const writing = Effect.gen(function* () {
|
|
205
|
+
const at = yield* databaseTime;
|
|
206
|
+
return yield* sql `SELECT 1 FROM actor_payload_writers
|
|
207
|
+
WHERE actor_type = ${declared.actorType} AND kind = 'event' AND tag = ${declared.tag}
|
|
208
|
+
AND version = ${version}
|
|
209
|
+
AND refreshed_at_ms + window_ms + ${commandTimeoutMs}::bigint > ${at}
|
|
210
|
+
LIMIT 1`;
|
|
211
|
+
});
|
|
212
|
+
const outcome = yield* sql.withTransaction(Effect.gen(function* () {
|
|
213
|
+
const locked = yield* sql `SELECT 1 FROM actor_payload_versions
|
|
214
|
+
WHERE actor_type = ${declared.actorType} AND kind = 'event' AND tag = ${declared.tag}
|
|
215
|
+
AND version = ${version} AND cleared_at_ms IS NULL
|
|
216
|
+
AND superseded_at_ms IS NOT NULL
|
|
217
|
+
FOR UPDATE`;
|
|
218
|
+
if (locked.length === 0)
|
|
219
|
+
return undefined;
|
|
220
|
+
if ((yield* writing).length > 0)
|
|
221
|
+
return "writer";
|
|
222
|
+
const stored = yield* sql `SELECT 1 FROM actor_events
|
|
223
|
+
WHERE actor_type = ${declared.actorType} AND event = ${declared.tag}
|
|
224
|
+
AND payload_version = ${version}
|
|
225
|
+
LIMIT 1`;
|
|
226
|
+
if (stored.length > 0)
|
|
227
|
+
return "stored";
|
|
228
|
+
if ((yield* writing).length > 0)
|
|
229
|
+
return "writer";
|
|
230
|
+
yield* sql `UPDATE actor_payload_versions SET cleared_at_ms = ${yield* databaseTime}
|
|
231
|
+
WHERE actor_type = ${declared.actorType} AND kind = 'event' AND tag = ${declared.tag}
|
|
232
|
+
AND version = ${version}`;
|
|
233
|
+
return "cleared";
|
|
234
|
+
}));
|
|
235
|
+
if (outcome !== undefined)
|
|
236
|
+
results.push({ actorType: declared.actorType, tag: declared.tag, version, outcome });
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
return results;
|
|
240
|
+
});
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { DateTime, Duration, Effect, Redacted } from "effect";
|
|
2
|
+
import { type RunnerCredentials } from "./credentials.ts";
|
|
3
|
+
/** Options for one runner certificate. */
|
|
4
|
+
export interface IssueOptions {
|
|
5
|
+
readonly deployment: string;
|
|
6
|
+
/** Default 90 days. */
|
|
7
|
+
readonly validFor?: Duration.Input;
|
|
8
|
+
/** Default five minutes before now, so a peer whose clock runs behind accepts it at once. */
|
|
9
|
+
readonly notBefore?: DateTime.DateTime;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* A certificate authority that issues runner certificates for development
|
|
13
|
+
* stacks and tests. Hosted and production deployments issue from a managed
|
|
14
|
+
* authority instead, whose key never sits in a process's memory.
|
|
15
|
+
*/
|
|
16
|
+
export interface RunnerAuthority {
|
|
17
|
+
/** The authority's own certificate, PEM: what every runner of its deployments trusts. */
|
|
18
|
+
readonly certificate: string;
|
|
19
|
+
readonly key: Redacted.Redacted<string>;
|
|
20
|
+
/** A fresh key and certificate for one deployment's runners, with this authority as `ca`. */
|
|
21
|
+
readonly issue: (options: IssueOptions) => Effect.Effect<RunnerCredentials>;
|
|
22
|
+
}
|
|
23
|
+
/** Creates and restores development certificate authorities for runner peering. */
|
|
24
|
+
export declare const RunnerAuthority: {
|
|
25
|
+
/**
|
|
26
|
+
* A new authority with a fresh P-256 key. Its name carries a random suffix
|
|
27
|
+
* so an incoming and an outgoing authority never share a name.
|
|
28
|
+
*/
|
|
29
|
+
make: (options?: {
|
|
30
|
+
readonly name?: string;
|
|
31
|
+
readonly validFor?: Duration.Input;
|
|
32
|
+
}) => Effect.Effect<RunnerAuthority, never, never>;
|
|
33
|
+
/**
|
|
34
|
+
* An authority saved earlier, so runners started before and after a
|
|
35
|
+
* restart keep trusting each other. Refuses a key that does not match the
|
|
36
|
+
* certificate, or a certificate that is not an authority.
|
|
37
|
+
*/
|
|
38
|
+
from: (options: {
|
|
39
|
+
readonly certificate: string;
|
|
40
|
+
readonly key: Redacted.Redacted<string>;
|
|
41
|
+
}) => Effect.Effect<RunnerAuthority, never, never>;
|
|
42
|
+
};
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import { createHash, createPrivateKey, createPublicKey, generateKeyPairSync, randomBytes, sign, X509Certificate, } from "node:crypto";
|
|
2
|
+
import { Clock, DateTime, Duration, Effect, Redacted } from "effect";
|
|
3
|
+
import { identity } from "./credentials.js";
|
|
4
|
+
const tlv = (tag, ...parts) => {
|
|
5
|
+
const body = Buffer.concat(parts);
|
|
6
|
+
const length = body.length < 0x80
|
|
7
|
+
? Buffer.from([body.length])
|
|
8
|
+
: (() => {
|
|
9
|
+
const bytes = [];
|
|
10
|
+
for (let rest = body.length; rest > 0; rest = Math.floor(rest / 256))
|
|
11
|
+
bytes.unshift(rest % 256);
|
|
12
|
+
return Buffer.from([0x80 | bytes.length, ...bytes]);
|
|
13
|
+
})();
|
|
14
|
+
return Buffer.concat([Buffer.from([tag]), length, body]);
|
|
15
|
+
};
|
|
16
|
+
const sequence = (...parts) => tlv(0x30, ...parts);
|
|
17
|
+
const oid = (dotted) => {
|
|
18
|
+
const [first, second, ...rest] = dotted.split(".").map(Number);
|
|
19
|
+
const bytes = [first * 40 + second];
|
|
20
|
+
for (const arc of rest) {
|
|
21
|
+
const groups = [arc & 0x7f];
|
|
22
|
+
for (let value = arc >>> 7; value > 0; value >>>= 7)
|
|
23
|
+
groups.unshift(0x80 | (value & 0x7f));
|
|
24
|
+
bytes.push(...groups);
|
|
25
|
+
}
|
|
26
|
+
return tlv(0x06, Buffer.from(bytes));
|
|
27
|
+
};
|
|
28
|
+
const integer = (bytes) => tlv(0x02, (bytes[0] & 0x80) !== 0 ? Buffer.concat([Buffer.from([0]), bytes]) : bytes);
|
|
29
|
+
const time = (millis) => {
|
|
30
|
+
const text = DateTime.formatIso(DateTime.makeUnsafe(millis)).replace(/[-:T]|\.\d+/gu, "");
|
|
31
|
+
return Number(text.slice(0, 4)) < 2050
|
|
32
|
+
? tlv(0x17, Buffer.from(text.slice(2)))
|
|
33
|
+
: tlv(0x18, Buffer.from(text));
|
|
34
|
+
};
|
|
35
|
+
const name = (common) => sequence(tlv(0x31, sequence(oid("2.5.4.3"), tlv(0x0c, Buffer.from(common)))));
|
|
36
|
+
const extension = (id, critical, value) => sequence(oid(id), ...(critical ? [tlv(0x01, Buffer.from([0xff]))] : []), tlv(0x04, value));
|
|
37
|
+
const keyId = (key) => createHash("sha1")
|
|
38
|
+
.update(key.export({ type: "spki", format: "der" }))
|
|
39
|
+
.digest();
|
|
40
|
+
const ECDSA_SHA256 = sequence(oid("1.2.840.10045.4.3.2"));
|
|
41
|
+
/**
|
|
42
|
+
* A DER X.509 v3 certificate for `subject`, signed with ECDSA P-256 and
|
|
43
|
+
* SHA-256 by `issuer`. The serial is random, positive and minimally encoded,
|
|
44
|
+
* because strict parsers such as BoringSSL reject a leading zero byte; key identifiers let
|
|
45
|
+
* TLS stacks tell apart two authorities that share a name during a rotation.
|
|
46
|
+
*/
|
|
47
|
+
const build = (options) => {
|
|
48
|
+
const serial = randomBytes(16);
|
|
49
|
+
serial[0] = (serial[0] & 0x3f) | 0x40;
|
|
50
|
+
const tbs = sequence(tlv(0xa0, integer(Buffer.from([2]))), integer(serial), ECDSA_SHA256, name(options.issuer), sequence(time(options.notBefore), time(options.notAfter)), name(options.subject), options.publicKey.export({ type: "spki", format: "der" }), tlv(0xa3, sequence(...options.extensions)));
|
|
51
|
+
const der = sequence(tbs, ECDSA_SHA256, tlv(0x03, Buffer.from([0]), sign("sha256", tbs, options.signer)));
|
|
52
|
+
return `-----BEGIN CERTIFICATE-----\n${der
|
|
53
|
+
.toString("base64")
|
|
54
|
+
.match(/.{1,64}/gu)
|
|
55
|
+
.join("\n")}\n-----END CERTIFICATE-----\n`;
|
|
56
|
+
};
|
|
57
|
+
const pem = (key) => key.export({ type: "pkcs8", format: "pem" }).toString();
|
|
58
|
+
const SKEW = 5 * 60 * 1000;
|
|
59
|
+
const authority = (certificate, signer) => {
|
|
60
|
+
const issuer = new X509Certificate(certificate).subject.replace(/^CN=/u, "");
|
|
61
|
+
const issuerId = keyId(createPublicKey(signer));
|
|
62
|
+
return {
|
|
63
|
+
certificate,
|
|
64
|
+
key: Redacted.make(pem(signer)),
|
|
65
|
+
issue: (options) => Effect.gen(function* () {
|
|
66
|
+
const uri = identity(options.deployment);
|
|
67
|
+
const pair = generateKeyPairSync("ec", { namedCurve: "P-256" });
|
|
68
|
+
const notBefore = options.notBefore === undefined
|
|
69
|
+
? (yield* Clock.currentTimeMillis) - SKEW
|
|
70
|
+
: DateTime.toEpochMillis(options.notBefore);
|
|
71
|
+
return {
|
|
72
|
+
ca: certificate,
|
|
73
|
+
certificate: build({
|
|
74
|
+
subject: `akter runner ${options.deployment}`,
|
|
75
|
+
issuer,
|
|
76
|
+
publicKey: pair.publicKey,
|
|
77
|
+
signer,
|
|
78
|
+
notBefore,
|
|
79
|
+
notAfter: notBefore +
|
|
80
|
+
Duration.toMillis(Duration.fromInputUnsafe(options.validFor ?? "90 days")),
|
|
81
|
+
extensions: [
|
|
82
|
+
extension("2.5.29.19", true, sequence()),
|
|
83
|
+
extension("2.5.29.15", true, tlv(0x03, Buffer.from([7, 0x80]))),
|
|
84
|
+
extension("2.5.29.37", false, sequence(oid("1.3.6.1.5.5.7.3.1"), oid("1.3.6.1.5.5.7.3.2"))),
|
|
85
|
+
extension("2.5.29.17", false, sequence(tlv(0x86, Buffer.from(uri)))),
|
|
86
|
+
extension("2.5.29.14", false, tlv(0x04, keyId(pair.publicKey))),
|
|
87
|
+
extension("2.5.29.35", false, sequence(tlv(0x80, issuerId))),
|
|
88
|
+
],
|
|
89
|
+
}),
|
|
90
|
+
key: Redacted.make(pem(pair.privateKey)),
|
|
91
|
+
};
|
|
92
|
+
}),
|
|
93
|
+
};
|
|
94
|
+
};
|
|
95
|
+
/** Creates and restores development certificate authorities for runner peering. */
|
|
96
|
+
export const RunnerAuthority = {
|
|
97
|
+
/**
|
|
98
|
+
* A new authority with a fresh P-256 key. Its name carries a random suffix
|
|
99
|
+
* so an incoming and an outgoing authority never share a name.
|
|
100
|
+
*/
|
|
101
|
+
make: (options) => Effect.gen(function* () {
|
|
102
|
+
const pair = generateKeyPairSync("ec", { namedCurve: "P-256" });
|
|
103
|
+
const subject = `${options?.name ?? "akter runner authority"} ${randomBytes(4).toString("hex")}`;
|
|
104
|
+
const notBefore = (yield* Clock.currentTimeMillis) - SKEW;
|
|
105
|
+
return authority(build({
|
|
106
|
+
subject,
|
|
107
|
+
issuer: subject,
|
|
108
|
+
publicKey: pair.publicKey,
|
|
109
|
+
signer: pair.privateKey,
|
|
110
|
+
notBefore,
|
|
111
|
+
notAfter: notBefore +
|
|
112
|
+
Duration.toMillis(Duration.fromInputUnsafe(options?.validFor ?? "3650 days")),
|
|
113
|
+
extensions: [
|
|
114
|
+
extension("2.5.29.19", true, sequence(tlv(0x01, Buffer.from([0xff])))),
|
|
115
|
+
extension("2.5.29.15", true, tlv(0x03, Buffer.from([1, 0x06]))),
|
|
116
|
+
extension("2.5.29.14", false, tlv(0x04, keyId(pair.publicKey))),
|
|
117
|
+
],
|
|
118
|
+
}), pair.privateKey);
|
|
119
|
+
}),
|
|
120
|
+
/**
|
|
121
|
+
* An authority saved earlier, so runners started before and after a
|
|
122
|
+
* restart keep trusting each other. Refuses a key that does not match the
|
|
123
|
+
* certificate, or a certificate that is not an authority.
|
|
124
|
+
*/
|
|
125
|
+
from: (options) => Effect.sync(() => {
|
|
126
|
+
const parsed = new X509Certificate(options.certificate);
|
|
127
|
+
const signer = createPrivateKey(Redacted.value(options.key));
|
|
128
|
+
if (!parsed.ca || !parsed.checkPrivateKey(signer))
|
|
129
|
+
throw new Error("Runner authority needs a CA certificate and its matching key");
|
|
130
|
+
return authority(options.certificate, signer);
|
|
131
|
+
}),
|
|
132
|
+
};
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { Redacted } from "effect";
|
|
2
|
+
/**
|
|
3
|
+
* PEM material one runner presents to and trusts from its peers.
|
|
4
|
+
*
|
|
5
|
+
* `ca` holds every certificate authority a peer may chain to; during a CA
|
|
6
|
+
* rotation it holds both the outgoing and the incoming authority.
|
|
7
|
+
* `certificate` is this runner's chain, leaf first, and `key` its private key.
|
|
8
|
+
*/
|
|
9
|
+
export interface RunnerCredentials {
|
|
10
|
+
readonly ca: string;
|
|
11
|
+
readonly certificate: string;
|
|
12
|
+
readonly key: Redacted.Redacted<string>;
|
|
13
|
+
}
|
|
14
|
+
/** The URI prefix every Akter runner identity starts with. */
|
|
15
|
+
export declare const PREFIX = "spiffe://akter/";
|
|
16
|
+
/**
|
|
17
|
+
* The URI subject alternative name that marks a certificate as belonging to
|
|
18
|
+
* `deployment`'s runners. Peers accept a certificate only when it carries
|
|
19
|
+
* exactly this one Akter identity.
|
|
20
|
+
*/
|
|
21
|
+
export declare const identity: (deployment: string) => string;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
const DEPLOYMENT = /^[A-Za-z0-9._-]{1,128}$/u;
|
|
2
|
+
/** The URI prefix every Akter runner identity starts with. */
|
|
3
|
+
export const PREFIX = "spiffe://akter/";
|
|
4
|
+
/**
|
|
5
|
+
* The URI subject alternative name that marks a certificate as belonging to
|
|
6
|
+
* `deployment`'s runners. Peers accept a certificate only when it carries
|
|
7
|
+
* exactly this one Akter identity.
|
|
8
|
+
*/
|
|
9
|
+
export const identity = (deployment) => {
|
|
10
|
+
if (!DEPLOYMENT.test(deployment) || deployment === "." || deployment === "..")
|
|
11
|
+
throw new Error("Runner deployment must be 1 to 128 characters of letters, digits, '.', '_' or '-'");
|
|
12
|
+
return `${PREFIX}deployment/${deployment}`;
|
|
13
|
+
};
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { Context, Duration, Effect, Layer } from "effect";
|
|
2
|
+
import { Runners, ShardingConfig } from "effect/cluster";
|
|
3
|
+
import { RpcSerialization } from "effect/rpc";
|
|
4
|
+
import { SocketServer } from "effect/socket";
|
|
5
|
+
import { type RunnerCredentials } from "./credentials.ts";
|
|
6
|
+
declare const PeerHealth_base: Context.ServiceClass<PeerHealth, "@rikalabs/akter/runtime/peering/transport/PeerHealth", {
|
|
7
|
+
readonly healthy: Effect.Effect<boolean>;
|
|
8
|
+
}>;
|
|
9
|
+
/**
|
|
10
|
+
* Whether this runner can still peer: false once its current certificate has
|
|
11
|
+
* expired, or once no credential load has succeeded for longer than the
|
|
12
|
+
* transport's `unhealthyAfter`. Readiness reports `peering` while it is false.
|
|
13
|
+
*/
|
|
14
|
+
export declare class PeerHealth extends PeerHealth_base {
|
|
15
|
+
}
|
|
16
|
+
/** Peer transport options for `Runner.mtls`. */
|
|
17
|
+
export interface MutualTlsOptions<E> {
|
|
18
|
+
/** The deployment every peer must belong to; its identity is `Runner.identity(deployment)`. */
|
|
19
|
+
readonly deployment: string;
|
|
20
|
+
/**
|
|
21
|
+
* Reads this runner's credentials. It runs once before the listener opens
|
|
22
|
+
* and again every `refreshEvery`, so replacing what it reads rotates the
|
|
23
|
+
* certificate, key, or trusted authorities without a restart.
|
|
24
|
+
*/
|
|
25
|
+
readonly credentials: Effect.Effect<RunnerCredentials, E>;
|
|
26
|
+
/** Default 1 minute. */
|
|
27
|
+
readonly refreshEvery?: Duration.Input;
|
|
28
|
+
/** How long one credential load may take before it counts as failed. Default 10 seconds. */
|
|
29
|
+
readonly refreshTimeout?: Duration.Input;
|
|
30
|
+
/**
|
|
31
|
+
* How long loads may keep failing, or hanging, before readiness reports
|
|
32
|
+
* `peering`. Default 5 minutes. An expired current certificate reports
|
|
33
|
+
* `peering` at once.
|
|
34
|
+
*/
|
|
35
|
+
readonly unhealthyAfter?: Duration.Input;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Runner-to-runner TCP with mutual TLS 1.3. Each side presents its
|
|
39
|
+
* deployment's certificate and accepts a peer only when the peer's chain
|
|
40
|
+
* reaches a trusted authority, is within its validity window, and carries
|
|
41
|
+
* exactly this deployment's identity; a plaintext peer, a peer without a
|
|
42
|
+
* certificate, and a peer of another deployment never reach the runner's RPC
|
|
43
|
+
* handler. Credentials are reloaded every `refreshEvery`: new connections use
|
|
44
|
+
* the latest valid ones, established connections keep the session they
|
|
45
|
+
* authenticated, and credentials that fail validation are logged and
|
|
46
|
+
* ignored while the previous ones stay in use. A runner whose certificate has
|
|
47
|
+
* expired, or whose loads have failed for `unhealthyAfter`, stops reporting
|
|
48
|
+
* ready.
|
|
49
|
+
*/
|
|
50
|
+
export declare const mtls: <E>(options: MutualTlsOptions<E>) => Layer.Layer<PeerHealth | Runners.RpcClientProtocol | SocketServer.SocketServer, SocketServer.SocketServerError, RpcSerialization.RpcSerialization | ShardingConfig.ShardingConfig>;
|
|
51
|
+
export {};
|