import type { JSONSchema } from "./refs"; import type { Command, CommandDefinition } from "./commands"; import type { Node } from "./node"; import type { NodeState } from "./instance"; /** * Metadata about a command (JSON-serializable). * Used in wire format for client-side display. */ export interface CommandMeta { name: string; description: string; inputSchema: JSONSchema; } /** * Wire format pack (JSON-serializable). * Contains pack name, validator schema, and command metadata. * State is stored separately in instance.packStates. */ export interface DryClientPack { name: string; description: string; validator: JSONSchema; commands: Record; } /** * Hydrated pack with callable command functions. * State is stored separately in instance.packStates. */ export interface ClientPack { name: string; description: string; validator: JSONSchema; commands: Record Command>; } /** * Derive typed command functions from Node's command definitions. * Maps each command to a function that takes typed input and returns a Command. */ // eslint-disable-next-line @typescript-eslint/no-explicit-any export type NodeCommands = N extends { commands: infer C } // eslint-disable-next-line @typescript-eslint/no-explicit-any ? C extends Record> ? { // eslint-disable-next-line @typescript-eslint/no-explicit-any [K in keyof C]: C[K] extends CommandDefinition ? (input: TInput) => Command : never; } : Record : Record; /** * Wire format node (JSON-serializable). * Contains instructions, validator schema, command metadata, and pack definitions. * Sent over the wire to clients. */ export interface DryClientNode = Node> { instructions: string; validator: JSONSchema; commands: Record; packs?: DryClientPack[]; } /** * Hydrated node with fully typed callable commands. * Created on the client by hydrating a DryClientNode. */ export interface ClientNode = Node> { instructions: string; validator: JSONSchema; commands: NodeCommands; packs?: ClientPack[]; } /** * Wire format instance (JSON-serializable). * Contains id, state, packStates, and a DryClientNode (which includes pack definitions). * Sent over the wire to clients. */ export interface DryClientInstance = Node> { id: string; state: NodeState; packStates?: Record; node: DryClientNode; } /** * Hydrated instance with fully typed commands. * Created on the client by hydrating a DryClientInstance. */ export interface ClientInstance = Node> { id: string; state: NodeState; packStates?: Record; node: ClientNode; }