Registry Handlers
Handlers execute actions.
In schemas, actions reference handlers by string key. The actual async function lives in the runtime registry.
Schema usage
schemas/users/user-actions.schema.ts
export const usersSchema = {
version: "1.0.0",
resource: "users",
actions: {
create: {
enabled: true,
label: "Create user",
icon: "lucide:plus",
handler: "users.create"
},
delete: {
enabled: true,
label: "Delete",
icon: "lucide:trash-2",
variant: "danger",
handler: "users.delete",
confirm: true
},
row: [
{
key: "invite",
label: "Invite",
icon: "lucide:send",
handler: "users.invite"
}
]
},
registry: {
actionHandlers: ["users.create", "users.delete", "users.invite"]
}
} as const;Runtime registry
lib/vibeflui/registry.ts
import { createRegistry } from "@vibeflui/core";
export const registry = createRegistry({
actionHandlers: {
"users.create": async ({ values }) => {
return {
status: true,
code: 200,
message: `${String(values?.name ?? "User")} created`,
data: values
};
},
"users.delete": async ({ identityValue }) => {
return {
status: true,
code: 200,
message: `User ${String(identityValue)} deleted`
};
},
"users.invite": async ({ row }) => {
return {
status: true,
code: 200,
message: `${String(row?.email ?? "User")} invited`
};
}
}
});Handler context
Handlers receive an execution context.
| Context property | Purpose |
|---|---|
schema | Normalized schema. |
action | Resolved action config. |
operation | Operation name such as create, update, delete, or custom key. |
row | Current row for row actions. |
values | Current form values for form actions. |
query | Query state for list operations. |
endpoint | Resolved endpoint if one exists. |
fetcher | Fetch-like function when provided. |
identityValue | Row identity value resolved from identity.key. |
params | Endpoint placeholder values. |
permissionContext | Roles, permissions, user, or custom context. |
actionHandlers vs handlers
Use actionHandlers for new documentation and examples.
The runtime also supports handlers as an alias during action execution and lifecycle hooks. Prefer actionHandlers for clarity.
lib/vibeflui/registry.ts
export const registry = createRegistry({
actionHandlers: {
"users.approve": async () => ({ status: true, code: 200, message: "Approved" })
}
});Endpoint actions vs handler actions
Use endpoint actions when the schema only needs to call an API.
schemas/users/user-actions.ts
export const archiveAction = {
key: "archive",
label: "Archive",
endpoint: { url: "/api/users/:id/archive", method: "POST" },
refreshOnSuccess: true
} as const;Use handler actions when UI-specific runtime behavior is needed.
schemas/users/user-actions.ts
export const inviteAction = {
key: "invite",
label: "Invite",
handler: "users.invite"
} as const;Backend responsibility
Handlers may call APIs, update local UI state, or return mock responses for local demos. They must not be treated as backend authorization. The backend still owns final security decisions.