Akter

Server

Everything on this page comes from @rikalabs/akter/server. For a walkthrough, see Deploying.

App.make⁠

TypeScript
App.make({ actors: [Room, Table], layer: Layer.mergeAll(RoomLive, TableLive) })

Lists the actors a server runs and the layer that implements them. It doesn't compile if an actor has no implementation in the layer. akter dev expects your app module to default-export one.

Akter.serve⁠

TypeScript
Akter.serve({ app, auth }).pipe(Layer.provide(Store.s3({ bucket })))

Returns a Layer that runs the app's actors and serves them over HTTP. Provide exactly one store.

OptionDefaultMeaning
apprequiredThe app from App.make
authrequiredHow requests are authenticated; see Access
port8080The port; 0 picks a free one
hostname0.0.0.0The address to listen on
basePathnoneA prefix for every route, such as /api
originsnoneBrowser origins allowed besides the server's own
reauthorizeEvery60 secondsHow often a live session runs auth and access again
credentialBytes8 KiBThe largest credential a request may carry
runnernoneSettings for running several servers
operatorAuthnoneTurns on the operator endpoint
prometheusfalseServes metrics at /metrics

Routes⁠

RouteWhat it serves
/rpcEvery actor call: WebSocket with JSON, or POST with NDJSON
/ready200 while serving, 503 while shutting down
/metricsPrometheus metrics, with prometheus: true
POST /operatorOperator requests, with operatorAuth

Auth⁠

ProviderUse
Auth.jwt({ issuer, audience, jwks, tenant, subject?, algorithms?, clockTolerance? })Verifies bearer JWTs. jwks is a URL or static keys. RS256, ES256 and EdDSA by default.
Auth.make(authenticate)Your own check, reading the authorization header
Auth.make({ authenticate, cookies: { name }, bearer? })Your own check, reading a cookie
Auth.noneEvery caller is Anonymous

tenant must return "default".

Store⁠

StoreUse
Store.s3({ bucket, endpoint?, region?, credentials?, prefix?, ...options })Production: an S3-compatible bucket
Store.fileSystem(directory, options?)Development and tests on one machine
Store.memory(options?)Tests; nothing survives the process

Every store takes these options:

OptionDefaultMeaning
buildempty{ bundle, framework } recorded with everything this release writes
shards16Shards in a new store; an existing store keeps its own count
retention7 daysHistory kept by a new store; change it later with Store.setRetention

Store.retention reads the store's current retention in milliseconds. Store.setRetention(duration, { grant, reason }) changes it, given an operator grant with retention.set.

RuntimeControl⁠

RuntimeControl.waitForSignal({ deadline }) waits for SIGTERM or SIGINT, makes the server unready, drains for up to deadline, and prints the DRAINED report with each shard's log position and nextDue. Run it inside the scope that built the server.

DurableClock⁠

DurableClock.sleep({ name, duration }) waits inside a job, and survives restarts. See Jobs.

Telemetry⁠

MemberWhat it does
Telemetry.layer({ otlp?, devtools? })Exports traces and metrics over OTLP, or to Effect DevTools
Telemetry.prometheus()The current metrics in Prometheus text format
Telemetry.usageSuccessful commands and job seconds on this server, by actor type

OperatorAuth⁠

OperatorAuth.tokens([{ token, grant }]) authenticates operator requests by bearer token. See Operating.

Forks⁠

Forks.fork(engine, options) and Forks.run(app, sourceStore, targetStore, options) fork an actor from code, for operator tooling. Most people use akter fork instead.