Apps
An App bundles one or more actor definitions into a single object that the server, client, and React packages can consume.
Creating an App
Section titled “Creating an App”import { createApp } from "@zocket/core";import { ChatRoom } from "./chat";import { GameMatch } from "./game";
export const app = createApp({ actors: { chat: ChatRoom, game: GameMatch, },});The keys you choose (chat, game) become the actor names used everywhere:
- Server — the handler routes RPC calls to the correct actor by name
- Client —
client.chat("room-1")returns a typed handle for thechatactor - React —
useActor("chat", "room-1")uses the same name
Type Inference
Section titled “Type Inference”The AppDef type carries the full type information of all registered actors. Pass typeof app as a generic to the client and React factories:
import { createClient } from "@zocket/client";import type { app } from "./server";
// Full type inference — no manual types neededconst client = createClient<typeof app>({ url: "ws://localhost:3000" });
const room = client.chat("general");// ^? ActorHandle with sendMessage, on("newMessage"), state, etc.AppDef Shape
Section titled “AppDef Shape”The returned object has this shape:
interface AppDef<TActors> { readonly _tag: "AppDef"; readonly actors: TActors; // Record<string, ActorDef>}The _tag discriminant is used internally for type narrowing. You generally don’t need to interact with it directly.
setup()
Section titled “setup()”setup() is an alias for createApp() with different naming, used when registering actors for the distributed runtime (docker-compose deployment with gateway + NATS + runtime):
import { setup } from "@zocket/core";import { counter } from "./actors/counter";import { chat } from "./actors/chat";
export const registry = setup({ use: { counter, chat } });The returned object is the same AppDef — the only difference is the naming convention (use instead of actors). Use createApp() for standalone mode and setup() for the distributed runtime.
Naming Conventions
Section titled “Naming Conventions”- Use camelCase for actor names:
chat,gameMatch,drawingRoom - Each name must be unique within an app
- The name is used as-is in the wire protocol (
{ actor: "chat", actorId: "room-1" })