Skip to content
Liminal

Client State

Client state is part of the Client.Service(...) definition. When a client connects, the actor runtime sends an initial state value during audition. After that, client-side reducers fold incoming events into the current state.

There is no separate state service. The client itself exposes the state stream, event stream, call surface, and typed reducer helper.

Define state on the client

import {  as  } from "effect"
import {  } from "liminal"
 
export const  = .(["X", "O"])
export const  = .([0, 1, 2])
export const  = .([, ])
 
export class  extends .<>()(
  "examples/TicTacToeClient",
  {
    : {
      : .,
      : ,
    },
    : {
      : {},
      : {
        : ,
        : ,
      },
      : {
        : .(),
      },
    },
    : {
      : {
        : .({ :  }),
        : .,
        : .,
      },
    },
  },
) {}

The state record is Effect Schema struct fields. The actor runtime must hydrate a value matching that shape for every new connection.

Hydrate on connect

In a Workerd actor runtime, hydrate returns the initial state for the connecting client.

 
export default .(function* () {
  const {  } = yield* 
  if (. === 1) {
    return {
      : true,
      : "X" as ,
    }
  }
 
  yield* ..("GameStarted", {})
  return {
    : false,
    : "O" as ,
  }
}).(.)

Hydration is the snapshot. Events sent after hydration are deltas that reducers apply locally.

Reduce events

Reducers live next to the client runtime. Client.reducer(...) narrows the event tag and returns the reducer unchanged at runtime.

 
export const  = .(
  "GameStarted",
  () =>
    ({  }) =>
      .({ , : false }),
)
 
export const  = .(
  "MoveMade",
  () => () => .(),
)
 
export const  = .(
  "GameEnded",
  () => () => .(),
)

Each reducer receives the event first and the current state second. Return the next state to publish an update, or return void to leave the current state unchanged.

Provide reducers

Pass the reducer table to Client.layerSocket(...).

 
export const  = .(
  .({
    : ,
    : "/play",
    : { : "startup" },
    ,
  }).(.(.)),
)

Consume state

TicTacToeClient.state is a stream of hydrated and reduced state values.

 
export const  = .(.)

Read Snapshot and Delta Events for event design guidance.