Skip to main content
On this pageFunctions

Command

Functions

define

functionsource
/**
 * Defines a Command. Two forms, distinguished by whether the second argument
 * is a Schema (a result message) or a record of Schemas (the args declaration).
 * 
 * The Effect (or effect builder) is bound at definition time. The returned
 * Definition is callable: with no args for a Command that doesn't declare any,
 * or with the declared args record otherwise.
 */
<Name extends string, Results extends readonly Array<Top>>(
  name: Name,
  results: Results
): (effect: Eff) => CommandDefinitionNoArgs<Name, Eff>

<Name extends string, Fields extends Fields, Results extends readonly Array<Top>>(
  name: Name,
  args: Fields,
  results: Results
): (effectBuilder: (args: {
  [K in string | number | symbol]: Type_<Fields, TypeOptionalKeys<Fields>, TypeMutableKeys<Fields>>[K]
}) => Eff) => CommandDefinitionWithArgs<Name, Fields, Eff>

Types

Command

typesource
/** A named Effect that produces a message, optionally carrying the args used to construct it. */
type Command = [T] extends [Schema.Top]
  ? Readonly<{
    args: Record<string, unknown>
    effect: Effect.Effect<Schema.Schema.Type<T>, E, R>
    name: string
  }>
  : Readonly<{
    args: Record<string, unknown>
    effect: Effect.Effect<T, E, R>
    name: string
  }>

CommandDefinition

typesource
/** A Command definition created with `Command.define`. Union over the no-args and with-args shapes; consumers that only need name/identity can accept this. */
type CommandDefinition = CommandDefinitionNoArgs<Name, Effect.Effect<ResultMessage, any, any>> | CommandDefinitionWithArgs<Name, any, Effect.Effect<ResultMessage, any, any>>

Interfaces

CommandDefinitionNoArgs

interfacesource
/** A Command definition for a Command with no declared args. Call as `Definition()` to produce a Command instance. */
interface CommandDefinitionNoArgs {
  [CommandDefinitionTypeId]: typeof CommandDefinitionTypeId
  name: Name
}

CommandDefinitionWithArgs

interfacesource
/** A Command definition for a Command with declared args. Call as `Definition(args)` to produce a Command instance. */
interface CommandDefinitionWithArgs {
  [CommandDefinitionTypeId]: typeof CommandDefinitionTypeId
  name: Name
}

Constants

CommandDefinitionTypeId

constsource
/** Type-level brand for CommandDefinition values. */
const CommandDefinitionTypeId: unique symbol

mapEffect

constsource
/** Transforms the Effect inside a Command while preserving its name and args. */
const mapEffect: (f: (effect: Effect<A, E1, R1>) => Effect<B, E2, R2>) => (command: Readonly<{
  args: Record<string, unknown>
  effect: Effect.Effect<A, E1, R1>
  name: string
}>) => Readonly<{
  args: Record<string, unknown>
  effect: Effect.Effect<B, E2, R2>
  name: string
}>

mapMessage

constsource
/**
 * Lifts a single Command's result Message through `f`, transforming
 *  `FromMessage` to `ToMessage`. The singular complement to
 *  mapMessages: reach for this when a child returns one Command
 *  (e.g. an animation leave Command), reach for `mapMessages` when it
 *  returns a list.
 * 
 *  Preserves the Command's `name` and `args` so traces still attribute
 *  it to the originating Submodel. When you need to transform the
 *  Effect itself (not just the result Message), reach for
 *  mapEffect instead.
 */
const mapMessage: (command: Readonly<{
  args: Record<string, unknown>
  effect: Effect.Effect<FromMessage, E, R>
  name: string
}>, f: (message: FromMessage) => ToMessage) => Readonly<{
  args: Record<string, unknown>
  effect: Effect.Effect<ToMessage, E, R>
  name: string
}>

mapMessages

constsource
/**
 * Lifts every Command in a list through `f`, transforming the result
 *  Message type from `FromMessage` to `ToMessage`. Reach for this at the
 *  boundary where a child Submodel's `update` returns Commands typed in
 *  the child's Message and the parent needs them typed in the parent's
 *  Message:
 * 
 *  ```ts
 *  GotChildMessage: ({ message }) => {
 *    const [nextChild, commands, maybeOutMessage] = Child.update(model.child, message)
 *    const mappedCommands = Command.mapMessages(
 *      commands,
 *      message => GotChildMessage({ message }),
 *    )
 *    // ...
 *  }
 *  ```
 * 
 *  Preserves each Command's `name` and `args` so traces still attribute
 *  the Command to the originating Submodel. When you need to transform
 *  the Effect itself (not just the result Message), reach for
 *  mapEffect instead.
 */
const mapMessages: (commands: readonly Array<Readonly<{
  args: Record<string, unknown>
  effect: Effect.Effect<FromMessage, E, R>
  name: string
}>>, f: (message: FromMessage) => ToMessage) => readonly Array<Readonly<{
  args: Record<string, unknown>
  effect: Effect.Effect<ToMessage, E, R>
  name: string
}>>

Stay in the update loop.

New releases, patterns, and the occasional deep dive.


Built with Foldkit.

© 2026 Devin Jameson