Skip to main content
On this pageFunctions

Story

Functions

expectExactCommands

functionsource
/** Asserts that the pending Commands match the given definitions exactly (order-independent). */
(definitions: readonly Array<CommandDefinition<string, unknown>>): (simulation: StorySimulation<Model, Message, OutMessage>) => StorySimulation<Model, Message, OutMessage>

expectHasCommands

functionsource
/** Asserts that every given Command is among the pending Commands. */
(definitions: readonly Array<CommandDefinition<string, unknown>>): (simulation: StorySimulation<Model, Message, OutMessage>) => StorySimulation<Model, Message, OutMessage>

expectNoCommands

functionsource
/** Asserts that there are no pending Commands. */
(): (simulation: StorySimulation<Model, Message, OutMessage>) => StorySimulation<Model, Message, OutMessage>

expectNoOutMessage

functionsource
/** Asserts that the OutMessage is None. */
(): (simulation: StorySimulation<Model, Message, Option.Option<OutMessage>>) => StorySimulation<Model, Message, Option.Option<OutMessage>>

expectOutMessage

functionsource
/** Asserts that the OutMessage is Some with the expected value. */
<OutMessage>(expected: OutMessage): (simulation: StorySimulation<Model, Message, Option.Option<OutMessage>>) => StorySimulation<Model, Message, Option.Option<OutMessage>>

message

functionsource
/** Sends a Message through update. Commands stay pending until resolve or resolveAll. */
<Message>(message_: NoInfer<Message>): (simulation: StorySimulation<Model, Message, OutMessage>) => StorySimulation<Model, Message, OutMessage>

model

functionsource
/** Runs an assertion function against the current Model. */
<Model, Message, OutMessage = undefined>(f: (model: Model) => void): (simulation: StorySimulation<Model, Message, OutMessage>) => StorySimulation<Model, Message, OutMessage>

resolveAll

functionsource
/** Resolves all listed Commands with their result Messages. Handles cascading resolution. */
(pairs: readonly Array<ResolverPair>): (simulation: StorySimulation<Model, Message, OutMessage>) => StorySimulation<Model, Message, OutMessage>

with

functionsource
/** Sets the initial Model for a test story. */
<Model>(model: Model): WithStep<Model>

Types

StorySimulation

typesource
/** An immutable test simulation of a Foldkit program. */
type StorySimulation = Readonly<{
  commands: ReadonlyArray<AnyCommand>
  model: Model
  outMessage: OutMessage
}>

StoryStep

typesource
/** A single step in a story — either a WithStep or a simulation transform. */
type StoryStep = WithStep<NoInfer<Model>> | (simulation: StorySimulation<Model, Message, OutMessage>) => StorySimulation<Model, Message, OutMessage>

WithStep

typesource
/** A callable step that sets the initial Model. Carries phantom type for compile-time validation. */
type WithStep = Readonly<{
  _phantomModel: Model
}> & (simulation: StorySimulation<M, Message, OutMessage>) => StorySimulation<M, Message, OutMessage>

Constants

resolve

constsource
/** Resolves a specific pending Command with the given result Message. */
const resolve: (definition: CommandDefinition<Name, ResultMessage>, resultMessage: ResultMessage) => (simulation: StorySimulation<Model, Message, OutMessage>) => StorySimulation<Model, Message, OutMessage>

story

constsource
/** Executes a test story. Throws if any Commands remain unresolved. */
const story: (updateFn: (model: Model, message: Message) => readonly [
  Model,
  readonly Array<Readonly<{
    name: string
  }>>,
  OutMessage
], steps: readonly Array<StoryStep<Model, Message, OutMessage>>) => void

Stay in the update loop.

New releases, patterns, and the occasional deep dive.


Built with Foldkit.

© 2026 Devin Jameson