@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,42 @@
|
|
|
1
|
+
import { Effect, Stream } from "effect";
|
|
2
|
+
import { SqlClient } from "effect/sql";
|
|
3
|
+
import { ActorError } from "../../errors/actor.ts";
|
|
4
|
+
import { type Caller } from "../../identity/caller.ts";
|
|
5
|
+
import type { AccessRequest } from "../../policies/access.ts";
|
|
6
|
+
import type { WatchResult } from "../members.ts";
|
|
7
|
+
import { type ResolvedView } from "./maintainer.ts";
|
|
8
|
+
/** One subscription to a fleet view, for the caller's own tenant. */
|
|
9
|
+
export interface FleetRequest {
|
|
10
|
+
readonly view: string;
|
|
11
|
+
readonly caller: Caller;
|
|
12
|
+
readonly tenant: string;
|
|
13
|
+
/** Equality filters on group columns by key, compared with each column's text form. */
|
|
14
|
+
readonly filter: Readonly<Record<string, string>>;
|
|
15
|
+
readonly limit: number;
|
|
16
|
+
/** The credential's expiry in epoch milliseconds, which ends the subscription. */
|
|
17
|
+
readonly expiresAt: number | undefined;
|
|
18
|
+
}
|
|
19
|
+
/** The most subscriptions one view has on one runner. */
|
|
20
|
+
export declare const FLEET_SUBSCRIPTIONS = 1000;
|
|
21
|
+
/**
|
|
22
|
+
* The fleet subscriptions of one runner. A view with subscribers has one
|
|
23
|
+
* poller, which reads its `status` and `applied_lsn` once a second however
|
|
24
|
+
* many subscribe; a subscription reruns its page query only when that state
|
|
25
|
+
* changed, and sends a page only when its rows or staleness differ from the
|
|
26
|
+
* last one it sent. `asOf` alone moving on is not sent: a lower `asOf` only
|
|
27
|
+
* proves less, never something false.
|
|
28
|
+
* A subscription is authorized when it opens (`kind: "fleet"`, `command` the
|
|
29
|
+
* view) and again every `reauthorizeMs` of the source's actor type
|
|
30
|
+
* (`kind: "reauthorize"`, `of: "fleet"`), and ends at the credential's
|
|
31
|
+
* expiry. Its `ref` names the caller's tenant and the view's source actor
|
|
32
|
+
* type, with the view as its id, because a fleet read spans every actor of
|
|
33
|
+
* the type. The page query runs in a tenant transaction, as the tenant role
|
|
34
|
+
* when row-level security is on.
|
|
35
|
+
*/
|
|
36
|
+
export declare const fleetSubscriptions: (options: {
|
|
37
|
+
readonly views: ReadonlyArray<ResolvedView>;
|
|
38
|
+
readonly role: string | undefined;
|
|
39
|
+
readonly permitted: (request: AccessRequest) => Effect.Effect<boolean>;
|
|
40
|
+
readonly reauthorizeMs: (actorType: string) => number;
|
|
41
|
+
}) => Effect.Effect<(request: FleetRequest) => Effect.Effect<Stream.Stream<WatchResult, ActorError, never>, ActorError, never>, never, import("effect/Scope").Scope | SqlClient.SqlClient>;
|
|
42
|
+
export type FleetSubscribe = Effect.Success<ReturnType<typeof fleetSubscriptions>>;
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
import { Clock, Effect, Schema, Stream, SubscriptionRef } from "effect";
|
|
2
|
+
import { SqlClient } from "effect/sql";
|
|
3
|
+
import { ActorError, ActorUnavailable, InvalidInput, RunnerAtCapacity, Unauthorized, } from "../../errors/actor.js";
|
|
4
|
+
import { ActorRef } from "../../identity/caller.js";
|
|
5
|
+
import { inTenant } from "../database/tenancy.js";
|
|
6
|
+
import { FleetHooks } from "./maintainer.js";
|
|
7
|
+
import { FLEET_PAGE_LIMIT } from "../../client/fleet-page.js";
|
|
8
|
+
/** The most subscriptions one view has on one runner. */
|
|
9
|
+
export const FLEET_SUBSCRIPTIONS = 1000;
|
|
10
|
+
/** How often a runner reads the state of each view it has subscribers of. */
|
|
11
|
+
const POLL_INTERVAL = "1 second";
|
|
12
|
+
const PageRow = Schema.Struct({
|
|
13
|
+
status: Schema.String,
|
|
14
|
+
as_of: Schema.NullOr(Schema.String),
|
|
15
|
+
rows: Schema.String,
|
|
16
|
+
});
|
|
17
|
+
const decodeRows = Schema.decodeUnknownEffect(Schema.fromJsonString(Schema.Array(Schema.Record(Schema.String, Schema.Json))));
|
|
18
|
+
const encodeResult = Schema.encodeEffect(Schema.fromJsonString(Schema.Struct({
|
|
19
|
+
value: Schema.Struct({
|
|
20
|
+
asOf: Schema.NullOr(Schema.String),
|
|
21
|
+
stale: Schema.Boolean,
|
|
22
|
+
rows: Schema.Array(Schema.Record(Schema.String, Schema.Json)),
|
|
23
|
+
}),
|
|
24
|
+
})));
|
|
25
|
+
const encodeContent = Schema.encodeEffect(Schema.fromJsonString(Schema.Struct({
|
|
26
|
+
stale: Schema.Boolean,
|
|
27
|
+
rows: Schema.Array(Schema.Record(Schema.String, Schema.Json)),
|
|
28
|
+
})));
|
|
29
|
+
const identifier = (name) => `"${name.replaceAll('"', '""')}"`;
|
|
30
|
+
const denied = (code) => ActorError.make({ reason: Unauthorized.make({ code }) });
|
|
31
|
+
/**
|
|
32
|
+
* The fleet subscriptions of one runner. A view with subscribers has one
|
|
33
|
+
* poller, which reads its `status` and `applied_lsn` once a second however
|
|
34
|
+
* many subscribe; a subscription reruns its page query only when that state
|
|
35
|
+
* changed, and sends a page only when its rows or staleness differ from the
|
|
36
|
+
* last one it sent. `asOf` alone moving on is not sent: a lower `asOf` only
|
|
37
|
+
* proves less, never something false.
|
|
38
|
+
* A subscription is authorized when it opens (`kind: "fleet"`, `command` the
|
|
39
|
+
* view) and again every `reauthorizeMs` of the source's actor type
|
|
40
|
+
* (`kind: "reauthorize"`, `of: "fleet"`), and ends at the credential's
|
|
41
|
+
* expiry. Its `ref` names the caller's tenant and the view's source actor
|
|
42
|
+
* type, with the view as its id, because a fleet read spans every actor of
|
|
43
|
+
* the type. The page query runs in a tenant transaction, as the tenant role
|
|
44
|
+
* when row-level security is on.
|
|
45
|
+
*/
|
|
46
|
+
export const fleetSubscriptions = Effect.fnUntraced(function* (options) {
|
|
47
|
+
const sql = yield* SqlClient.SqlClient;
|
|
48
|
+
const scope = yield* Effect.scope;
|
|
49
|
+
const hooks = yield* FleetHooks;
|
|
50
|
+
const pollers = new Map();
|
|
51
|
+
for (const resolved of options.views) {
|
|
52
|
+
const name = resolved.view.name;
|
|
53
|
+
const state = yield* SubscriptionRef.make(undefined);
|
|
54
|
+
const poller = { state, subscribers: 0 };
|
|
55
|
+
pollers.set(name, poller);
|
|
56
|
+
const poll = Effect.gen(function* () {
|
|
57
|
+
if (poller.subscribers === 0)
|
|
58
|
+
return;
|
|
59
|
+
yield* hooks.poll(name);
|
|
60
|
+
const [row] = yield* sql `
|
|
61
|
+
SELECT status, applied_lsn::text AS applied FROM actor_fleet_views WHERE view_name = ${name}`;
|
|
62
|
+
if (row !== undefined)
|
|
63
|
+
yield* SubscriptionRef.set(state, row);
|
|
64
|
+
});
|
|
65
|
+
yield* poll.pipe(Effect.catchCause((cause) => Effect.logWarning("Fleet view poll failed", cause)), Effect.andThen(Effect.sleep(POLL_INTERVAL)), Effect.forever, Effect.forkIn(scope));
|
|
66
|
+
}
|
|
67
|
+
const page = (resolved, request) => {
|
|
68
|
+
const { view } = resolved;
|
|
69
|
+
const derived = `${identifier(resolved.derivedSchema)}.${identifier(view.tableName.split(".").at(-1))}`;
|
|
70
|
+
const keys = view.groupBy;
|
|
71
|
+
const columns = [
|
|
72
|
+
...keys.map((key, index) => `d.${identifier(view.groupColumns[index])} AS ${identifier(key)}`),
|
|
73
|
+
...view.aggregates.map(({ key }) => `d.${identifier(key)}`),
|
|
74
|
+
];
|
|
75
|
+
const filters = Object.entries(request.filter);
|
|
76
|
+
const order = keys.map((key) => `r.${identifier(key)}`).join(", ");
|
|
77
|
+
const conditions = filters.map(([key], index) => `AND d.${identifier(view.groupColumns[keys.indexOf(key)])}::text = $${index + 3}`);
|
|
78
|
+
const statement = `SELECT v.status, v.applied_lsn::text AS as_of,
|
|
79
|
+
coalesce((SELECT jsonb_agg(to_jsonb(r) ORDER BY ${order})::text FROM (
|
|
80
|
+
SELECT ${columns.join(", ")} FROM ${derived} d
|
|
81
|
+
WHERE d.tenant_id = $2 ${conditions.join(" ")}
|
|
82
|
+
ORDER BY ${keys.map((_, index) => `d.${identifier(view.groupColumns[index])}`).join(", ")}
|
|
83
|
+
LIMIT ${request.limit}) r), '[]') AS rows
|
|
84
|
+
FROM actor_fleet_views v WHERE v.view_name = $1`;
|
|
85
|
+
return hooks.page(view.name).pipe(Effect.andThen(sql.unsafe(statement, [
|
|
86
|
+
view.name,
|
|
87
|
+
request.tenant,
|
|
88
|
+
...filters.map(([, value]) => value),
|
|
89
|
+
])), inTenant({ sql, role: options.role, tenant: request.tenant }), Effect.catchTag("SqlError", (cause) => Effect.fail(ActorError.make({ reason: ActorUnavailable.make({ cause }) }))), Effect.flatMap((rows) => Schema.decodeUnknownEffect(PageRow)(rows[0]).pipe(Effect.flatMap((row) => Effect.map(decodeRows(row.rows), (decoded) => ({
|
|
90
|
+
asOf: row.as_of,
|
|
91
|
+
stale: row.status !== "ready",
|
|
92
|
+
rows: decoded,
|
|
93
|
+
}))), Effect.flatMap((result) => Effect.all({
|
|
94
|
+
value: encodeResult({ value: result }),
|
|
95
|
+
content: encodeContent({ stale: result.stale, rows: result.rows }),
|
|
96
|
+
})), Effect.orDie)));
|
|
97
|
+
};
|
|
98
|
+
const subscribe = Effect.fnUntraced(function* (request) {
|
|
99
|
+
const resolved = options.views.find(({ view }) => view.name === request.view);
|
|
100
|
+
const poller = pollers.get(request.view);
|
|
101
|
+
if (resolved === undefined || poller === undefined)
|
|
102
|
+
return yield* ActorError.make({ reason: InvalidInput.make({ code: "unknown_route" }) });
|
|
103
|
+
const keys = resolved.view.groupBy;
|
|
104
|
+
for (const key of Object.keys(request.filter))
|
|
105
|
+
if (!keys.includes(key))
|
|
106
|
+
return yield* ActorError.make({ reason: InvalidInput.make({ code: "decode" }) });
|
|
107
|
+
if (!Number.isInteger(request.limit) || request.limit < 1 || request.limit > FLEET_PAGE_LIMIT)
|
|
108
|
+
return yield* ActorError.make({ reason: InvalidInput.make({ code: "decode" }) });
|
|
109
|
+
const actorType = resolved.view.source.owner ?? resolved.view.source.name;
|
|
110
|
+
const asked = {
|
|
111
|
+
caller: request.caller,
|
|
112
|
+
ref: ActorRef.make({ tenant: request.tenant, actor: actorType, id: request.view }),
|
|
113
|
+
command: request.view,
|
|
114
|
+
};
|
|
115
|
+
const access = (kind) => options.permitted(kind === "fleet" ? { ...asked, kind } : { ...asked, kind, of: "fleet" });
|
|
116
|
+
if (!(yield* access("fleet")))
|
|
117
|
+
return yield* denied("access_denied");
|
|
118
|
+
if (request.expiresAt !== undefined && (yield* Clock.currentTimeMillis) >= request.expiresAt)
|
|
119
|
+
return yield* denied("expired");
|
|
120
|
+
if (poller.subscribers >= FLEET_SUBSCRIPTIONS)
|
|
121
|
+
return yield* ActorError.make({ reason: RunnerAtCapacity.make({}) });
|
|
122
|
+
const run = (value) => ({ version: undefined, value });
|
|
123
|
+
const pages = SubscriptionRef.changes(poller.state).pipe(Stream.changesWith((a, b) => a?.status === b?.status && a?.applied === b?.applied), Stream.mapEffect(() => page(resolved, request)), Stream.changesWith((a, b) => a.content === b.content), Stream.map(({ value }) => run(value)));
|
|
124
|
+
const reauthorizeMs = options.reauthorizeMs(actorType);
|
|
125
|
+
const watchdog = Effect.gen(function* () {
|
|
126
|
+
while (true) {
|
|
127
|
+
const now = yield* Clock.currentTimeMillis;
|
|
128
|
+
const wait = request.expiresAt === undefined
|
|
129
|
+
? reauthorizeMs
|
|
130
|
+
: Math.min(reauthorizeMs, Math.max(0, request.expiresAt - now));
|
|
131
|
+
yield* Effect.sleep(wait);
|
|
132
|
+
if (request.expiresAt !== undefined &&
|
|
133
|
+
(yield* Clock.currentTimeMillis) >= request.expiresAt)
|
|
134
|
+
return yield* denied("expired");
|
|
135
|
+
if (!(yield* access("reauthorize")))
|
|
136
|
+
return yield* denied("access_denied");
|
|
137
|
+
}
|
|
138
|
+
});
|
|
139
|
+
const counted = Effect.acquireRelease(Effect.sync(() => {
|
|
140
|
+
poller.subscribers += 1;
|
|
141
|
+
}), () => Effect.sync(() => {
|
|
142
|
+
poller.subscribers -= 1;
|
|
143
|
+
}));
|
|
144
|
+
return Stream.unwrap(Effect.as(counted, pages)).pipe(Stream.merge(Stream.fromEffect(watchdog), { haltStrategy: "either" }));
|
|
145
|
+
});
|
|
146
|
+
return subscribe;
|
|
147
|
+
});
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { layer } from "./layer.ts";
|
|
2
|
+
import { serve } from "../serve/layer.ts";
|
|
3
|
+
import { make } from "../serve/auth.ts";
|
|
4
|
+
import { jwt } from "../serve/jwt.ts";
|
|
5
|
+
import { assertion } from "../serve/assertion/verify.ts";
|
|
6
|
+
/** Runtime construction: actor execution and authenticated protocol routes. */
|
|
7
|
+
export declare const Actors: {
|
|
8
|
+
layer: typeof layer;
|
|
9
|
+
serve: typeof serve;
|
|
10
|
+
};
|
|
11
|
+
/** Authentication providers for one served runtime. `none` is an explicit public opt-out. */
|
|
12
|
+
export declare const Auth: {
|
|
13
|
+
none: import("./index.ts").AuthProvider<never>;
|
|
14
|
+
make: typeof make;
|
|
15
|
+
jwt: typeof jwt;
|
|
16
|
+
assertion: typeof assertion;
|
|
17
|
+
};
|
|
18
|
+
export type { ServeOptions } from "../serve/layer.ts";
|
|
19
|
+
export type { AuthProvider, AuthRequest, Authenticated, Binding } from "../serve/auth.ts";
|
|
20
|
+
export { ASSERTION_SKEW_MS, AssertionClaims, AssertionKey, AssertionKeySet, KeyRefreshClaims, MAX_ASSERTION_SECONDS, } from "../serve/assertion/verify.ts";
|
|
21
|
+
export type { AssertionOptions } from "../serve/assertion/verify.ts";
|
|
22
|
+
export { actorErrorBody, closeCodeOf, statusOf } from "../protocol/wire.ts";
|
|
23
|
+
export { Database } from "./layer.ts";
|
|
24
|
+
export { Runner } from "./runner.ts";
|
|
25
|
+
export type { SocketRunnerOptions } from "./runner.ts";
|
|
26
|
+
export type { MutualTlsOptions } from "./peering/transport.ts";
|
|
27
|
+
export type { RunnerCredentials } from "./peering/credentials.ts";
|
|
28
|
+
export { RunnerAuthority } from "./peering/authority.ts";
|
|
29
|
+
export type { IssueOptions } from "./peering/authority.ts";
|
|
30
|
+
export { DataDirLocked, DataDirVersion } from "../errors/database.ts";
|
|
31
|
+
export type { Options } from "./layer.ts";
|
|
32
|
+
export { RuntimeControl } from "./drain.ts";
|
|
33
|
+
export type { DrainReport, Readiness } from "./drain.ts";
|
|
34
|
+
export { checkWorkflows, formatIncompatibility } from "./workflows/compatibility.ts";
|
|
35
|
+
export type { Incompatibility } from "./workflows/compatibility.ts";
|
|
36
|
+
export { Inspector } from "./inspector/layer.ts";
|
|
37
|
+
export type { InspectorOptions } from "./inspector/layer.ts";
|
|
38
|
+
export { Telemetry } from "./telemetry/routes.ts";
|
|
39
|
+
export type { TelemetryOptions } from "./telemetry/routes.ts";
|
|
40
|
+
export { DefectLog, DefectRecord, DefectRecords } from "./telemetry/defects.ts";
|
|
41
|
+
export { TelemetrySampler } from "./telemetry/sampler.ts";
|
|
42
|
+
export { Metrics } from "./telemetry/metrics.ts";
|
|
43
|
+
export { UsageAccounting } from "./telemetry/usage.ts";
|
|
44
|
+
export type { UsageAccountingService, UsageCommands, UsageRead } from "./telemetry/usage.ts";
|
|
45
|
+
export { SpanNames } from "./telemetry/spans.ts";
|
|
46
|
+
export { Operators } from "./operators/routes.ts";
|
|
47
|
+
export type { OperatorsOptions } from "./operators/routes.ts";
|
|
48
|
+
export { OperatorAuth } from "./operators/auth.ts";
|
|
49
|
+
export { Capability, OperatorAction, OperatorGrant } from "./operators/grants.ts";
|
|
50
|
+
export { AuditRecord } from "./operators/audit.ts";
|
|
51
|
+
export { Seed, SeedJson } from "./operators/seed.ts";
|
|
52
|
+
export { checkPayloads, clearPayloads, formatPayloadProblem } from "./payloads/versions.ts";
|
|
53
|
+
export type { ClearResult, PayloadProblem } from "./payloads/versions.ts";
|
|
54
|
+
export { AdoptionRefused } from "./adoption/target.ts";
|
|
55
|
+
export { formatAdoptionPlan, planAdoption } from "./adoption/plan.ts";
|
|
56
|
+
export type { AdoptionPlan } from "./adoption/plan.ts";
|
|
57
|
+
export { adoptionWriters, formatObservedWriter, observeAdoption } from "./adoption/observe.ts";
|
|
58
|
+
export type { ObservedWriter } from "./adoption/observe.ts";
|
|
59
|
+
export { backfillAdoption, formatBackfill } from "./adoption/backfill.ts";
|
|
60
|
+
export type { BackfillResult } from "./adoption/backfill.ts";
|
|
61
|
+
export { adoptionStatus, formatAdoptionStatus } from "./adoption/status.ts";
|
|
62
|
+
export type { AdoptionStatus } from "./adoption/status.ts";
|
|
63
|
+
export { enforceAdoption, formatEnforce, releaseAdoption } from "./adoption/enforce.ts";
|
|
64
|
+
export type { EnforceResult } from "./adoption/enforce.ts";
|
|
65
|
+
export { FleetSetupRefused, rebuildFleetView, setupFleet } from "./fleet/setup.ts";
|
|
66
|
+
export type { FleetSetup } from "./fleet/setup.ts";
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { layer } from "./layer.js";
|
|
2
|
+
import { serve } from "../serve/layer.js";
|
|
3
|
+
import { make, none } from "../serve/auth.js";
|
|
4
|
+
import { jwt } from "../serve/jwt.js";
|
|
5
|
+
import { assertion } from "../serve/assertion/verify.js";
|
|
6
|
+
/** Runtime construction: actor execution and authenticated protocol routes. */
|
|
7
|
+
export const Actors = { layer, serve };
|
|
8
|
+
/** Authentication providers for one served runtime. `none` is an explicit public opt-out. */
|
|
9
|
+
export const Auth = { none, make, jwt, assertion };
|
|
10
|
+
export { ASSERTION_SKEW_MS, AssertionClaims, AssertionKey, AssertionKeySet, KeyRefreshClaims, MAX_ASSERTION_SECONDS, } from "../serve/assertion/verify.js";
|
|
11
|
+
export { actorErrorBody, closeCodeOf, statusOf } from "../protocol/wire.js";
|
|
12
|
+
export { Database } from "./layer.js";
|
|
13
|
+
export { Runner } from "./runner.js";
|
|
14
|
+
export { RunnerAuthority } from "./peering/authority.js";
|
|
15
|
+
export { DataDirLocked, DataDirVersion } from "../errors/database.js";
|
|
16
|
+
export { RuntimeControl } from "./drain.js";
|
|
17
|
+
export { checkWorkflows, formatIncompatibility } from "./workflows/compatibility.js";
|
|
18
|
+
export { Inspector } from "./inspector/layer.js";
|
|
19
|
+
export { Telemetry } from "./telemetry/routes.js";
|
|
20
|
+
export { DefectLog, DefectRecord, DefectRecords } from "./telemetry/defects.js";
|
|
21
|
+
export { TelemetrySampler } from "./telemetry/sampler.js";
|
|
22
|
+
export { Metrics } from "./telemetry/metrics.js";
|
|
23
|
+
export { UsageAccounting } from "./telemetry/usage.js";
|
|
24
|
+
export { SpanNames } from "./telemetry/spans.js";
|
|
25
|
+
export { Operators } from "./operators/routes.js";
|
|
26
|
+
export { OperatorAuth } from "./operators/auth.js";
|
|
27
|
+
export { Capability, OperatorAction, OperatorGrant } from "./operators/grants.js";
|
|
28
|
+
export { AuditRecord } from "./operators/audit.js";
|
|
29
|
+
export { Seed, SeedJson } from "./operators/seed.js";
|
|
30
|
+
export { checkPayloads, clearPayloads, formatPayloadProblem } from "./payloads/versions.js";
|
|
31
|
+
export { AdoptionRefused } from "./adoption/target.js";
|
|
32
|
+
export { formatAdoptionPlan, planAdoption } from "./adoption/plan.js";
|
|
33
|
+
export { adoptionWriters, formatObservedWriter, observeAdoption } from "./adoption/observe.js";
|
|
34
|
+
export { backfillAdoption, formatBackfill } from "./adoption/backfill.js";
|
|
35
|
+
export { adoptionStatus, formatAdoptionStatus } from "./adoption/status.js";
|
|
36
|
+
export { enforceAdoption, formatEnforce, releaseAdoption } from "./adoption/enforce.js";
|
|
37
|
+
export { FleetSetupRefused, rebuildFleetView, setupFleet } from "./fleet/setup.js";
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { Effect, Option } from "effect";
|
|
2
|
+
import { type HttpServerRequest, HttpServerResponse } from "effect/http";
|
|
3
|
+
import type { ActorError } from "../../errors/actor.ts";
|
|
4
|
+
/** A 404 with the `NotFound` body. */
|
|
5
|
+
export declare const notFoundResponse: () => HttpServerResponse.HttpServerResponse;
|
|
6
|
+
/** Answers a found value as JSON and an absent one as a 404. */
|
|
7
|
+
export declare const foundOrNotFound: (found: Option.Option<unknown>) => HttpServerResponse.HttpServerResponse;
|
|
8
|
+
/**
|
|
9
|
+
* Refuses a browser page on another origin before its credentials are read,
|
|
10
|
+
* so an operator's cookie or token can't be spent by a page they visit.
|
|
11
|
+
*/
|
|
12
|
+
export declare const refuseCrossOrigin: (request: HttpServerRequest.HttpServerRequest) => ActorError | Effect.Effect<void, never, never>;
|
|
13
|
+
/**
|
|
14
|
+
* Finishes an operator or inspector route: an `ActorError` is answered as the
|
|
15
|
+
* wire error, a defect is logged under `failure` and answered with an opaque
|
|
16
|
+
* 500 naming only its trace, and no answer is cached, since every answer is
|
|
17
|
+
* bound to one authenticated principal.
|
|
18
|
+
*/
|
|
19
|
+
export declare const operatorResponse: (failure: string) => <R>(response: Effect.Effect<HttpServerResponse.HttpServerResponse, ActorError, R>) => Effect.Effect<HttpServerResponse.HttpServerResponse, never, R>;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { Effect, Option, Schema } from "effect";
|
|
2
|
+
import { Headers, HttpServerResponse } from "effect/http";
|
|
3
|
+
import { isSameOrigin } from "../../serve/layer.js";
|
|
4
|
+
import { Defect } from "../../protocol/wire.js";
|
|
5
|
+
import { actorErrorResponse, invalidInput } from "../../serve/wire.js";
|
|
6
|
+
/** The body of a 404: the tenant has nothing of that name. */
|
|
7
|
+
const NotFound = Schema.TaggedStruct("NotFound", {});
|
|
8
|
+
/** A 404 with the `NotFound` body. */
|
|
9
|
+
export const notFoundResponse = () => HttpServerResponse.jsonUnsafe(NotFound.make({}), { status: 404 });
|
|
10
|
+
/** Answers a found value as JSON and an absent one as a 404. */
|
|
11
|
+
export const foundOrNotFound = (found) => Option.match(found, {
|
|
12
|
+
onNone: notFoundResponse,
|
|
13
|
+
onSome: (value) => HttpServerResponse.jsonUnsafe(value),
|
|
14
|
+
});
|
|
15
|
+
/**
|
|
16
|
+
* Refuses a browser page on another origin before its credentials are read,
|
|
17
|
+
* so an operator's cookie or token can't be spent by a page they visit.
|
|
18
|
+
*/
|
|
19
|
+
export const refuseCrossOrigin = (request) => {
|
|
20
|
+
const origin = Headers.get(request.headers, "origin");
|
|
21
|
+
return Option.isSome(origin) && !isSameOrigin({ request, origin: origin.value })
|
|
22
|
+
? invalidInput("origin_not_allowed")
|
|
23
|
+
: Effect.void;
|
|
24
|
+
};
|
|
25
|
+
const traceId = Effect.currentSpan.pipe(Effect.map((span) => span.traceId), Effect.orElseSucceed(() => "0".repeat(32)));
|
|
26
|
+
/**
|
|
27
|
+
* Finishes an operator or inspector route: an `ActorError` is answered as the
|
|
28
|
+
* wire error, a defect is logged under `failure` and answered with an opaque
|
|
29
|
+
* 500 naming only its trace, and no answer is cached, since every answer is
|
|
30
|
+
* bound to one authenticated principal.
|
|
31
|
+
*/
|
|
32
|
+
export const operatorResponse = (failure) => (response) => response.pipe(Effect.catch(actorErrorResponse), Effect.catchCause((cause) => Effect.gen(function* () {
|
|
33
|
+
const trace = yield* traceId;
|
|
34
|
+
yield* Effect.logError(failure, cause);
|
|
35
|
+
return HttpServerResponse.jsonUnsafe(Defect.make({ traceId: trace }), { status: 500 });
|
|
36
|
+
})), Effect.map((answered) => HttpServerResponse.setHeaders(answered, { "cache-control": "no-store" })));
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { HttpRouter } from "effect/http";
|
|
2
|
+
import { SqlClient } from "effect/sql";
|
|
3
|
+
import { type AuthProvider } from "../../serve/auth.ts";
|
|
4
|
+
/** Configuration for `Inspector.serve`. */
|
|
5
|
+
export interface InspectorOptions<R> {
|
|
6
|
+
/**
|
|
7
|
+
* Authenticates every inspector request. The inspector reads only the
|
|
8
|
+
* authenticated principal's tenant, and every actor of it, so give it an
|
|
9
|
+
* operator's provider, not the one end users call `Actor.serve` with.
|
|
10
|
+
*/
|
|
11
|
+
readonly auth: AuthProvider<R>;
|
|
12
|
+
/** Prefix for every route. Default `"/inspector"`. */
|
|
13
|
+
readonly basePath?: `/${string}`;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Serves read-only JSON over the `durable` inspection views as routes on the
|
|
17
|
+
* application's `HttpRouter`. A request from another browser origin is
|
|
18
|
+
* refused with `403` before its credentials are read, and a credential over
|
|
19
|
+
* 8 KiB with `413` before its provider runs; each other request is
|
|
20
|
+
* authenticated per request, never cached, since the tenant is the one fact
|
|
21
|
+
* every read trusts. Every read is filtered to the principal's tenant and runs
|
|
22
|
+
* in a read-only transaction.
|
|
23
|
+
*
|
|
24
|
+
* - `GET /overview`: the view catalog, the tenant's row counts and its soonest timer.
|
|
25
|
+
* - `GET /actors?type&prefix&afterType&afterId&limit`: actors, one keyset page
|
|
26
|
+
* at a time, optionally those whose `type/id` address starts with `prefix`.
|
|
27
|
+
* - `GET /actor?type&id&limit`: one actor's state, receipts with the events
|
|
28
|
+
* each committed, events, outbox, jobs, dead letters, and workflows with steps.
|
|
29
|
+
* - `GET /actor-types?type&prefix&after&limit`: actor types with their actor
|
|
30
|
+
* counts, optionally one type or those whose name starts with `prefix`.
|
|
31
|
+
* - `GET /receipts?type&id&outcome&afterExpiresAtMs&afterType&afterId&afterCommandId&limit`:
|
|
32
|
+
* receipts of one actor, one type or the tenant, the latest expiry first.
|
|
33
|
+
* - `GET /latest-events?type&id&after&limit`: one actor's newest event of each name.
|
|
34
|
+
* - `GET /timeline?type&id&beforeSequence&beforeKind&limit`: one actor's events
|
|
35
|
+
* and the commands that emitted them, newest first.
|
|
36
|
+
* - `GET /job-types?after&limit`: pending jobs and dead letters by job name.
|
|
37
|
+
* - `GET /outbox`, `/jobs`, `/dead-letters?afterDeadAtMs&afterJobId`,
|
|
38
|
+
* `/workflows?status=open|all|running|suspended|finished|completed|failed&afterStartedAtMs&afterExecutionId`:
|
|
39
|
+
* tenant-wide lists; the paged ones answer the `next` cursor to pass back.
|
|
40
|
+
*/
|
|
41
|
+
declare const serve: <R = never>(options: InspectorOptions<R>) => import("effect/Layer").Layer<never, never, HttpRouter.HttpRouter | SqlClient.SqlClient | Exclude<R, import("effect/Scope").Scope>>;
|
|
42
|
+
/** The read-only inspector: `serve` mounts its routes. */
|
|
43
|
+
export declare const Inspector: {
|
|
44
|
+
serve: typeof serve;
|
|
45
|
+
};
|
|
46
|
+
export {};
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
import { Effect, Schema } from "effect";
|
|
2
|
+
import { HttpRouter } from "effect/http";
|
|
3
|
+
import { SqlClient } from "effect/sql";
|
|
4
|
+
import { ActorError, Unauthorized } from "../../errors/actor.js";
|
|
5
|
+
import { Anonymous, User } from "../../identity/caller.js";
|
|
6
|
+
import { CREDENTIAL_BYTES, oversizedCredential, readsCookies, withinLimits, } from "../../serve/auth.js";
|
|
7
|
+
import { invalidInput, undecodable } from "../../serve/wire.js";
|
|
8
|
+
import { foundOrNotFound, operatorResponse, refuseCrossOrigin } from "./http.js";
|
|
9
|
+
import * as Queries from "./queries.js";
|
|
10
|
+
const DEFAULT_LIMIT = 50;
|
|
11
|
+
const Limit = Schema.FiniteFromString.check(Schema.isInt(), Schema.isBetween({ minimum: 1, maximum: Queries.MAX_LIMIT })).pipe(Schema.withDecodingDefaultTypeKey(Effect.succeed(DEFAULT_LIMIT)));
|
|
12
|
+
const PageParams = Schema.Struct({ limit: Limit });
|
|
13
|
+
const Millis = Schema.FiniteFromString.check(Schema.isInt(), Schema.isBetween({ minimum: 0, maximum: Number.MAX_SAFE_INTEGER }));
|
|
14
|
+
/** Refuses a keyset cursor that names only some of its fields, which would silently restart the list. */
|
|
15
|
+
const whole = (...keys) => Schema.makeFilter((params) => {
|
|
16
|
+
const named = keys.filter((key) => params[key] !== undefined).length;
|
|
17
|
+
return named === 0 || named === keys.length || `${keys.join(", ")} go together`;
|
|
18
|
+
});
|
|
19
|
+
const ActorsParams = Schema.Struct({
|
|
20
|
+
limit: Limit,
|
|
21
|
+
type: Schema.optional(Schema.String),
|
|
22
|
+
prefix: Schema.optional(Schema.NonEmptyString),
|
|
23
|
+
afterType: Schema.optional(Schema.String),
|
|
24
|
+
afterId: Schema.optional(Schema.String),
|
|
25
|
+
}).check(whole("afterType", "afterId"));
|
|
26
|
+
const ActorParams = Schema.Struct({ limit: Limit, type: Schema.String, id: Schema.String });
|
|
27
|
+
const ActorTypesParams = Schema.Struct({
|
|
28
|
+
limit: Limit,
|
|
29
|
+
type: Schema.optional(Schema.String),
|
|
30
|
+
prefix: Schema.optional(Schema.NonEmptyString),
|
|
31
|
+
after: Schema.optional(Schema.String),
|
|
32
|
+
});
|
|
33
|
+
const JobTypesParams = Schema.Struct({ limit: Limit, after: Schema.optional(Schema.String) });
|
|
34
|
+
const LatestEventsParams = Schema.Struct({
|
|
35
|
+
...ActorParams.fields,
|
|
36
|
+
after: Schema.optional(Schema.String),
|
|
37
|
+
});
|
|
38
|
+
const TimelineParams = Schema.Struct({
|
|
39
|
+
...ActorParams.fields,
|
|
40
|
+
beforeSequence: Schema.optional(Millis),
|
|
41
|
+
beforeKind: Schema.optional(Schema.Literals(["command", "event"])),
|
|
42
|
+
}).check(whole("beforeSequence", "beforeKind"));
|
|
43
|
+
const ReceiptsParams = Schema.Struct({
|
|
44
|
+
limit: Limit,
|
|
45
|
+
type: Schema.optional(Schema.String),
|
|
46
|
+
id: Schema.optional(Schema.String),
|
|
47
|
+
outcome: Schema.optional(Schema.Literals(["Success", "Failure"])),
|
|
48
|
+
afterExpiresAtMs: Schema.optional(Millis),
|
|
49
|
+
afterType: Schema.optional(Schema.String),
|
|
50
|
+
afterId: Schema.optional(Schema.String),
|
|
51
|
+
afterCommandId: Schema.optional(Schema.String),
|
|
52
|
+
}).check(Schema.makeFilter(({ type, id }) => id === undefined || type !== undefined || "id needs type"), whole("afterExpiresAtMs", "afterType", "afterId", "afterCommandId"));
|
|
53
|
+
const DeadLettersParams = Schema.Struct({
|
|
54
|
+
limit: Limit,
|
|
55
|
+
afterDeadAtMs: Schema.optional(Millis),
|
|
56
|
+
afterJobId: Schema.optional(Schema.String),
|
|
57
|
+
}).check(whole("afterDeadAtMs", "afterJobId"));
|
|
58
|
+
const WorkflowsParams = Schema.Struct({
|
|
59
|
+
limit: Limit,
|
|
60
|
+
status: Schema.optional(Schema.Literals(["open", "all", "running", "suspended", "finished", "completed", "failed"])),
|
|
61
|
+
afterStartedAtMs: Schema.optional(Millis),
|
|
62
|
+
afterExecutionId: Schema.optional(Schema.String),
|
|
63
|
+
}).check(whole("afterStartedAtMs", "afterExecutionId"));
|
|
64
|
+
const isPrincipal = Schema.is(Schema.Union([User, Anonymous]));
|
|
65
|
+
/**
|
|
66
|
+
* Serves read-only JSON over the `durable` inspection views as routes on the
|
|
67
|
+
* application's `HttpRouter`. A request from another browser origin is
|
|
68
|
+
* refused with `403` before its credentials are read, and a credential over
|
|
69
|
+
* 8 KiB with `413` before its provider runs; each other request is
|
|
70
|
+
* authenticated per request, never cached, since the tenant is the one fact
|
|
71
|
+
* every read trusts. Every read is filtered to the principal's tenant and runs
|
|
72
|
+
* in a read-only transaction.
|
|
73
|
+
*
|
|
74
|
+
* - `GET /overview`: the view catalog, the tenant's row counts and its soonest timer.
|
|
75
|
+
* - `GET /actors?type&prefix&afterType&afterId&limit`: actors, one keyset page
|
|
76
|
+
* at a time, optionally those whose `type/id` address starts with `prefix`.
|
|
77
|
+
* - `GET /actor?type&id&limit`: one actor's state, receipts with the events
|
|
78
|
+
* each committed, events, outbox, jobs, dead letters, and workflows with steps.
|
|
79
|
+
* - `GET /actor-types?type&prefix&after&limit`: actor types with their actor
|
|
80
|
+
* counts, optionally one type or those whose name starts with `prefix`.
|
|
81
|
+
* - `GET /receipts?type&id&outcome&afterExpiresAtMs&afterType&afterId&afterCommandId&limit`:
|
|
82
|
+
* receipts of one actor, one type or the tenant, the latest expiry first.
|
|
83
|
+
* - `GET /latest-events?type&id&after&limit`: one actor's newest event of each name.
|
|
84
|
+
* - `GET /timeline?type&id&beforeSequence&beforeKind&limit`: one actor's events
|
|
85
|
+
* and the commands that emitted them, newest first.
|
|
86
|
+
* - `GET /job-types?after&limit`: pending jobs and dead letters by job name.
|
|
87
|
+
* - `GET /outbox`, `/jobs`, `/dead-letters?afterDeadAtMs&afterJobId`,
|
|
88
|
+
* `/workflows?status=open|all|running|suspended|finished|completed|failed&afterStartedAtMs&afterExecutionId`:
|
|
89
|
+
* tenant-wide lists; the paged ones answer the `next` cursor to pass back.
|
|
90
|
+
*/
|
|
91
|
+
const serve = (options) => HttpRouter.use(Effect.fnUntraced(function* (router) {
|
|
92
|
+
const basePath = (options.basePath ?? "/inspector").replace(/\/+$/, "");
|
|
93
|
+
const context = yield* Effect.context();
|
|
94
|
+
const sql = yield* SqlClient.SqlClient;
|
|
95
|
+
const authenticate = (request) => Effect.gen(function* () {
|
|
96
|
+
if (oversizedCredential({
|
|
97
|
+
provider: options.auth,
|
|
98
|
+
headers: request.headers,
|
|
99
|
+
limit: CREDENTIAL_BYTES,
|
|
100
|
+
}))
|
|
101
|
+
return yield* invalidInput("too_large");
|
|
102
|
+
const authenticated = yield* options.auth
|
|
103
|
+
.authenticate({
|
|
104
|
+
headers: request.headers,
|
|
105
|
+
cookies: readsCookies(options.auth) ? request.cookies : {},
|
|
106
|
+
})
|
|
107
|
+
.pipe(Effect.provideContext(context), Effect.mapError((reason) => ActorError.make({ reason })));
|
|
108
|
+
if (!isPrincipal(authenticated.caller) || !withinLimits(authenticated))
|
|
109
|
+
return yield* ActorError.make({
|
|
110
|
+
reason: Unauthorized.make({ code: "invalid_credentials" }),
|
|
111
|
+
});
|
|
112
|
+
return authenticated.tenant;
|
|
113
|
+
});
|
|
114
|
+
const route = (path, params, read) => router.add("GET", `${basePath}${path}`, (request) => Effect.gen(function* () {
|
|
115
|
+
yield* refuseCrossOrigin(request);
|
|
116
|
+
const tenant = yield* authenticate(request);
|
|
117
|
+
const decoded = yield* HttpRouter.schemaParams(params).pipe(Effect.mapError(undecodable));
|
|
118
|
+
return foundOrNotFound(yield* Queries.readOnly(tenant)(read(tenant, decoded)).pipe(Effect.provideService(SqlClient.SqlClient, sql), Effect.orDie));
|
|
119
|
+
}).pipe(operatorResponse("Inspector request failed")));
|
|
120
|
+
yield* route("/overview", Schema.Struct({}), (tenant) => Effect.asSome(Queries.overview({ tenant })));
|
|
121
|
+
yield* route("/actors", ActorsParams, (tenant, { limit, type, prefix, afterType, afterId }) => Effect.asSome(Queries.actors({
|
|
122
|
+
tenant,
|
|
123
|
+
limit,
|
|
124
|
+
actorType: type,
|
|
125
|
+
prefix,
|
|
126
|
+
after: afterType === undefined || afterId === undefined
|
|
127
|
+
? undefined
|
|
128
|
+
: { actorType: afterType, actorId: afterId },
|
|
129
|
+
})));
|
|
130
|
+
yield* route("/actor", ActorParams, (tenant, { limit, type, id }) => Queries.actor({ tenant, limit, actorType: type, actorId: id }));
|
|
131
|
+
yield* route("/outbox", PageParams, (tenant, { limit }) => Effect.asSome(Queries.outbox({ tenant, limit })));
|
|
132
|
+
yield* route("/jobs", PageParams, (tenant, { limit }) => Effect.asSome(Queries.jobs({ tenant, limit })));
|
|
133
|
+
yield* route("/dead-letters", DeadLettersParams, (tenant, { limit, afterDeadAtMs, afterJobId }) => Effect.asSome(Queries.deadLetters({
|
|
134
|
+
tenant,
|
|
135
|
+
limit,
|
|
136
|
+
after: afterDeadAtMs === undefined || afterJobId === undefined
|
|
137
|
+
? undefined
|
|
138
|
+
: { deadAtMs: afterDeadAtMs, jobId: afterJobId },
|
|
139
|
+
})));
|
|
140
|
+
yield* route("/workflows", WorkflowsParams, (tenant, { limit, status, afterStartedAtMs, afterExecutionId }) => Effect.asSome(Queries.workflows({
|
|
141
|
+
tenant,
|
|
142
|
+
limit,
|
|
143
|
+
status: status ?? "open",
|
|
144
|
+
after: afterStartedAtMs === undefined || afterExecutionId === undefined
|
|
145
|
+
? undefined
|
|
146
|
+
: { startedAtMs: afterStartedAtMs, executionId: afterExecutionId },
|
|
147
|
+
})));
|
|
148
|
+
yield* route("/actor-types", ActorTypesParams, (tenant, { limit, type, prefix, after }) => Effect.asSome(Queries.actorTypes({ tenant, limit, name: type, prefix, after })));
|
|
149
|
+
yield* route("/job-types", JobTypesParams, (tenant, { limit, after }) => Effect.asSome(Queries.jobTypes({ tenant, limit, after })));
|
|
150
|
+
yield* route("/receipts", ReceiptsParams, (tenant, { limit, type, id, outcome, afterExpiresAtMs, afterType, afterId, afterCommandId }) => Queries.receipts({
|
|
151
|
+
tenant,
|
|
152
|
+
limit,
|
|
153
|
+
actorType: type,
|
|
154
|
+
actorId: id,
|
|
155
|
+
outcomeTag: outcome,
|
|
156
|
+
after: afterExpiresAtMs === undefined ||
|
|
157
|
+
afterType === undefined ||
|
|
158
|
+
afterId === undefined ||
|
|
159
|
+
afterCommandId === undefined
|
|
160
|
+
? undefined
|
|
161
|
+
: {
|
|
162
|
+
expiresAtMs: afterExpiresAtMs,
|
|
163
|
+
actorType: afterType,
|
|
164
|
+
actorId: afterId,
|
|
165
|
+
commandId: afterCommandId,
|
|
166
|
+
},
|
|
167
|
+
}));
|
|
168
|
+
yield* route("/latest-events", LatestEventsParams, (tenant, { limit, type, id, after }) => Queries.latestEvents({ tenant, limit, actorType: type, actorId: id, after }));
|
|
169
|
+
yield* route("/timeline", TimelineParams, (tenant, { limit, type, id, beforeSequence, beforeKind }) => Queries.timeline({
|
|
170
|
+
tenant,
|
|
171
|
+
limit,
|
|
172
|
+
actorType: type,
|
|
173
|
+
actorId: id,
|
|
174
|
+
before: beforeSequence === undefined || beforeKind === undefined
|
|
175
|
+
? undefined
|
|
176
|
+
: { sequence: beforeSequence, kind: beforeKind },
|
|
177
|
+
}));
|
|
178
|
+
}));
|
|
179
|
+
/** The read-only inspector: `serve` mounts its routes. */
|
|
180
|
+
export const Inspector = { serve };
|