Skip to main content
On this pageFunctions

Command/Interruptible

Functions

define

functionsource
/**
 * Defines an interruptible Command. Like `Command.define`, but every
 * invocation registers under a key in the runtime's interrupt registry for
 * the duration of its Effect, and the returned Definition carries an
 * `Interrupt` constructor that builds the Command to stop it.
 * 
 * Keys are namespaced by the Command name automatically. With no declared
 * args the key is the Command name itself. With declared args, `toKey` maps
 * them to the part that distinguishes invocations, and the full key becomes
 * `` `${name}:${toKey(args)}` ``, so keys never collide across definitions
 * and call sites never restate the name. Derive the key part from the Model
 * identity that owns the in-flight work (a list item id, an entity id), never
 * from a generated value: the update function is pure, and any invocation you
 * can meaningfully target is already distinguished by data in the Model.
 * 
 * Semantics:
 * 
 * - A key is an address, not a lock. Any number of invocations may run under
 *   one key concurrently, and dispatching never interrupts anything.
 *   Interruption only happens when update returns an Interrupt Command.
 * - `Definition.Interrupt` produces a Command whose Effect interrupts every
 *   current holder of the key and results in `toMessage(outcome)`. The
 *   outcome is `Interrupted` when at least one holder was stopped (the
 *   stopped holders' result Messages are guaranteed never to dispatch) or
 *   `NotFound` when nothing held the key. Name the result Message
 *   `CompletedCancel<CommandName>`.
 * - To dispatch a replacement after cancelling, sequence through the
 *   Interrupt's result Message: return the new Command from the
 *   `CompletedCancel<CommandName>` handler. Commands in one batch run
 *   concurrently with no execution-order guarantee, so `[Interrupt, Next]`
 *   in a single list is a race, not a sequence.
 * 
 * For work that should stop when the Model says so, reach for a Subscription
 * or ManagedResource instead; interruption is for one-shot async work that is
 * structurally a Command (for example an in-flight HTTP request, a file read,
 * or an upload).
 */
<Name extends string, Results extends readonly Array<Top>>(
  name: Name,
  results: Results
): (effect: Eff) => DefinitionNoArgs<Name, Eff>

<Name extends string, Fields extends Fields, KeyArgs extends Partial<View<Fields, "Type", TypeOptionalKeys<Fields>, TypeMutableKeys<Fields>>>, Results extends readonly Array<Top>>(
  name: Name,
  args: Fields,
  toKey: (keyArgs: KeyArgs) => string,
  results: Results
): (effectBuilder: (args: View<Fields>) => Eff) => DefinitionWithArgs<Name, Fields, KeyArgs, Eff>

Interfaces

DefinitionNoArgs

interfacesource
/**
 * An interruptible Command definition with no declared args; its key is the
 *  Command name. Call as `Definition()` to produce a Command instance; use
 *  `Definition.Interrupt` to build the Command that stops it.
 */
interface DefinitionNoArgs {
  [CommandDefinitionTypeId]: typeof CommandDefinitionTypeId
  Interrupt: InterruptDefinitionNoArgs<Name>
  name: Name
}

DefinitionWithArgs

interfacesource
/**
 * An interruptible Command definition with declared args and a key derived
 *  from them, namespaced by the Command name. Call as `Definition(args)` to
 *  produce a Command instance; use `Definition.Interrupt` to build the
 *  Command that stops every holder of a specific key.
 */
interface DefinitionWithArgs {
  [CommandDefinitionTypeId]: typeof CommandDefinitionTypeId
  Interrupt: InterruptDefinitionWithArgs<Name, KeyArgs>
  name: Name
}

InterruptDefinitionNoArgs

interfacesource
/**
 * An Interrupt Command definition derived from an interruptible Command
 *  definition with no declared args. Call as `Definition.Interrupt(toMessage)`
 *  to produce a Command that interrupts every holder of the definition's key.
 */
interface InterruptDefinitionNoArgs {
  [CommandDefinitionTypeId]: typeof CommandDefinitionTypeId
  name: `${Name}.Interrupt`
}

InterruptDefinitionWithArgs

interfacesource
/**
 * An Interrupt Command definition derived from an interruptible Command
 *  definition with declared args. Call as
 *  `Definition.Interrupt(keyArgs, toMessage)` to produce a Command that
 *  interrupts every holder of the key derived from `keyArgs`.
 */
interface InterruptDefinitionWithArgs {
  [CommandDefinitionTypeId]: typeof CommandDefinitionTypeId
  name: `${Name}.Interrupt`
}

Constants

Interrupted

constsource
/**
 * At least one in-flight Command held the interrupt key, and every holder
 *  has been stopped. Their declared result Messages are guaranteed never to
 *  dispatch.
 */
const Interrupted: CallableTaggedStruct<"Interrupted", {}>

NotFound

constsource
/**
 * No Command holds the interrupt key: every target already completed (its
 *  result Message dispatched or will dispatch) or was never dispatched. The
 *  two cases are indistinguishable by design.
 */
const NotFound: CallableTaggedStruct<"NotFound", {}>

Outcome

constsource
/**
 * The result of an Interrupt Command: Interrupted when at least one
 *  holder was stopped, NotFound when nothing held the key.
 *  Interruption itself cannot fail.
 */
const Outcome: Union<readonly [CallableTaggedStruct<"Interrupted", {}>, CallableTaggedStruct<"NotFound", {}>]>

Stay in the update loop.

New releases, patterns, and the occasional deep dive.


Built with Foldkit.

© 2026 Devin Jameson