% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/board-server.R
\name{board_update}
\alias{board_update}
\alias{validate_board_update}
\alias{augment_board_update}
\alias{apply_board_update}
\title{Board update}
\usage{
validate_board_update(payload, board, ..., session = get_session())

augment_board_update(upd, board, ..., session = get_session())

apply_board_update(board, upd, ..., session = get_session())
}
\arguments{
\item{payload, upd}{A board update payload — see Validation above
for the accepted shape.}

\item{board}{A \code{board} object.}

\item{...}{Forwarded between methods. For \code{\link[=apply_board_update]{apply_board_update()}},
the final observer also splices \code{board_server()}'s \code{...} in here.}

\item{session}{A shiny session, default \code{\link[=get_session]{get_session()}}.}
}
\value{
\code{\link[=validate_board_update]{validate_board_update()}} returns \code{invisible(payload)} (or
throws a \code{blockr_abort()} error). \code{\link[=augment_board_update]{augment_board_update()}} returns
the (possibly extended) payload. \code{\link[=apply_board_update]{apply_board_update()}} returns a
\code{board}.
}
\description{
Inside \code{\link[=board_server]{board_server()}} every state change flows through one
\code{board_update} reactive. Core registers two observers framing the
change: an initial one that validates the payload and runs
\code{\link[=augment_board_update]{augment_board_update()}} for auto-fixups, and a final one that runs
\code{\link[=apply_board_update]{apply_board_update()}} and resets the reactive. Plugins or
callbacks may register their own observers in between, provided they
use a \emph{finite} priority — the highest and lowest reactive priorities
are reserved for core.
}
\details{
All three functions dispatch on the \code{board} class. Subclasses
override to validate, augment, or react to their own payload slots,
typically composing with \code{NextMethod()}. \code{\link[=validate_board_update]{validate_board_update()}}
is also a caller-facing entry point: it mirrors the initial
observer's checks against a caller-supplied payload, useful for
staging layers (e.g. accumulating LLM-proposed updates) that need
to fail loudly before publishing.
}
\section{Validation}{

The default \code{.board} method runs a structural check on the payload
(block / link / stack per-slot rules) and a cross-reference check
that link endpoints and stack members resolve in the post-update
merged view. Unknown top-level keys are passed through, so subclass
payload slots reach subclass augment / apply methods.
}

\section{Augment}{

The default \code{.board} method inserts implied link removals and stack
updates that follow from block removals, plus link-input
completion. Subclass methods may extend the payload with their own
fixups; an error thrown here aborts the update before apply runs.
}

\section{Apply}{

The default \code{.board} method returns the supplied board unchanged —
the core apply path (block / link / stack mutation, block UI
insertion / removal) is not routed through this generic. Subclass
methods receive a plain \code{board} snapshot (no reactive surface) and
return a \code{board}, which the final observer assigns back to
\code{rv$board}. For piecemeal customization of the core apply path
itself, override the relevant sub-generic
(\code{\link[=modify_board_links]{modify_board_links()}}, \code{\link[=insert_block_ui]{insert_block_ui()}}, etc.) instead.

Errors thrown from either augment or apply are caught by the
observer, reported via \code{\link[=notify]{notify()}}, and the reactive is reset so the
app keeps running.
}

\section{Outcome}{

Alongside the human-facing \code{\link[=notify]{notify()}} toast, every update cycle
records a machine-readable result into \code{board$last_update} (the
read-only board handed to plugins and callbacks). It is a list with
a monotonically increasing \code{seq}, a logical \code{ok}, the \code{phase} it
ended in (\code{"validate"} or \code{"apply"}), and a \code{message}
(\code{conditionMessage()} on failure, \code{NA} on success); it is \code{NULL}
before the first update. The \code{seq} advances on every write so that
two consecutive identical outcomes still invalidate a downstream
observer. A programmatic caller can watch this field to learn
whether a dispatched update was rejected, failed to apply, or landed.
}

\examples{
brd <- new_board(
  blocks = c(a = new_dataset_block("iris"), b = new_subset_block()),
  links = links(ab = new_link(from = "a", to = "b"))
)

validate_board_update(
  list(links = list(rm = "ab")),
  brd
)

try(
  validate_board_update(
    list(links = list(add = links(xy = new_link(from = "x", to = "y")))),
    brd
  )
)

}
\seealso{
On a locked board (see \code{\link[=is_board_locked]{is_board_locked()}}) the update is
dropped rather than applied.
}
