Primitives / DOM

Start with one: copy to the clipboard

ts
import { mapMessage } from 'foldkit/command'
import { defineMessageUnion } from 'foldkit/message'
import { ClipboardMessage, copyText } from 'foldkit-primitives/dom'

const Message = defineMessageUnion({
  CopyClicked: {},
  Clipboard: { message: ClipboardMessage },
})
type Model = { readonly text: string; readonly status: string }

const update = (model: Model, message: typeof Message.Type) =>
  Message.match(message, {
    CopyClicked: () => ({
      model,
      commands: [mapMessage(copyText(model.text), message => Message.Clipboard({ message }))],
    }),
    Clipboard: ({ message }) => ({
      model: {
        ...model,
        status: ClipboardMessage.match(message, {
          Copied: () => 'Copied',
          CopyFailed: ({ message }) => message,
        }),
      },
    }),
  })

copyText describes a Command; returning it from update lets the runtime perform the write. mapMessage wraps its result into the parent's union, so success and failure land in the same reducer, and the clipboard never enters the Model: it is not application state. readText() reads the same way.

The Commands

share(data) posts { title?, text?, url? } to the platform sheet: Shared on success, Dismissed when the user cancels the sheet (its own outcome, not a failure), ShareFailed otherwise.

loadScript(src) appends a head script unless one carries the URL already, so concurrent loads collapse onto the first tag and share its fate, yielding Loaded or LoadFailed. A dead tag is removed, so a retry fetches afresh.

Denial, an insecure context, a missing API (a server), and a network error all become the failure Message. No Command here throws.