Asynchronous resources
luastra/resourceModels bounded asynchronous reads and mutations as small explicit state machines. Generation tickets suppress stale results, immutable snapshots drive UI, and application-owned errors preserve retry and field context without leaking provider details.
Create controllers once outside render, begin an operation when the host request starts, and settle only the matching ticket from resolve.
Use one read controller per logical value and one mutation controller per non-concurrent write workflow; compose them in application or feature state rather than subclassing them.
Complete 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()