Resource.newMutation
luastra/resourceResource.newMutation(options: MutationOptions<T>): MutationState<T>
Creates a controller for one non-concurrent mutation with explicit submission, success, failure, cancellation, optional optimistic apply and rollback callbacks, and an idempotency requirement whenever retry is enabled.
Before you use it
Add luastra/resource to this module's dependencies in luastra.json, then import it with require("luastra/resource"). Create each controller once outside app.render. Record the exact ticket returned by begin, correlate it with the host RequestId, and settle only that ticket from app.resolve or another admitted completion boundary.
How it fits
Constructors and transitions are synchronous. begin creates a new generation ticket; resolve, reject, and cancel accept only the active ticket; snapshot returns the current frozen view used by render.
When to use it
Use Resource.newMutation for create, update, delete, upload-commit, or similar writes that need visible progress and safe late-result suppression. Enable retry only when the backend accepts the supplied stable idempotency key.
Parameters
| Parameter | Type / values | Description |
|---|---|---|
| options | MutationOptions<T> | Checked options argument accepted by Resource.newMutation. |
Returns
MutationState<T> — the exact MutationState<T> value declared by the SDK contract.
What happens next
A reusable read or mutation controller whose snapshot represents loading, success, empty, stale failure, retry, cancellation, or submission state.
Failures and fixes
Invalid options and programmer contract violations fail immediately. A stale ticket returns false without overwriting current state. Translate provider failures to bounded Resource.Error codes and keep raw messages, payloads, tokens, and credentials outside the controller.
Availability
Public-source alpha state API in 0.5.0-alpha; host-independent and designed to compose with any asynchronous capability.
Focused example
local Resource = require("luastra/resource")
local profile = Resource.new {
isEmpty = function(value: { name: string }): boolean
return value.name == ""
end,
}
local ticket = profile.begin(requestId, "load")
if result ~= nil then
profile.resolve(ticket, result)
else
profile.reject(ticket, Resource.error("NOT_FOUND", false))
end
local snapshot = profile.snapshot()