Clients
A Client defines the wire contract between browser clients and actors.
Everything else in Liminal hangs off that contract:
- actors point at a client definition
- external handlers implement the methods callable by connected clients
Auditions can merge multiple clients into one event stream and call surface- reducers derive local state from events after the initial hydration
Define a client
A client is a named state schema, external method table, and event table.
import { Schema as S } from "effect"
import { Client } from "liminal"
export const Player = S.Literals(["X", "O"])
export const Coordinate = S.Literals([0, 1, 2])
export const Coordinates = S.Tuple([Coordinate, Coordinate])
export class TicTacToeClient extends Client.Service<TicTacToeClient>()("examples/TicTacToeClient", {
events: {
GameStarted: {},
MoveMade: {
player: Player,
position: Coordinates,
},
GameEnded: {
winner: S.optional(Player),
},
},
external: {
Move: {
payload: S.Struct({
position: Coordinates,
}),
success: S.Void,
failure: S.Never,
},
},
state: {
awaitingPartner: S.Boolean,
name: Player,
},
}) {}Shape
stateis the struct-fields record hydrated when the client connects.externalis a record of{ payload, success, failure }methods callable throughClient.fn(...).eventsis a record of plain struct fields.- Liminal tags events automatically with
_tag.
Next concepts
- Methods covers reusable method definitions.
- Client Calls covers
Client.fn(...). - Events covers
Client.eventsand replay. - Client State covers hydration and reducers.
- Actors covers the server-side runtime for this protocol.