• Construct a typed Update from a discriminator key plus a record of per-tag handlers.

    Type Parameters

    • Msg extends { kind: string }

      The application's message union; must have a kind discriminator string.

    • G extends Graph = Graph

      The graph subtype.

    • Handlers extends { [K in string]: (msg: Extract<Msg, { kind: K }>, graph: G) => void } = { [K in string]: (msg: Extract<Msg, { kind: K }>, graph: G) => void }

      Record of handlers keyed by Msg['kind'], each receiving the narrowed message variant for its tag.

    Parameters

    • handlers: Handlers

      Map from message tag to a handler that issues graph.commit(...).

    Returns Update<Msg, G>

    An Update runner that dispatches to the matching handler.

    Error when an incoming message's kind has no registered handler.

    Each handler is responsible for issuing graph.commit(...) itself. Handlers return void — the engine's commit is a side-effecting method on the graph handle, so the runner is imperative by design. The exhaustiveness of the Handlers type is enforced by the mapped-type constraint on Msg['kind'] — adding a new tag to Msg without a handler is a compile error at the call site.

    type Msg =
    | { kind: 'set-a'; value: number }
    | { kind: 'set-b'; value: number }

    const update = createUpdate<Msg>({
    'set-a': (msg, g) => { g.commit('set-a', tx => tx.set(a, msg.value)) },
    'set-b': (msg, g) => { g.commit('set-b', tx => tx.set(b, msg.value)) },
    })