VVibeFlui

Hooks and Events

Hooks and events let schemas reference runtime behavior by string key.

Use hooks for lifecycle behavior around operations. Use events for UI events that should notify application code.

Lifecycle hooks

Hooks are mapped in the schema.

schemas/users/users.schema.ts

TS
export const usersSchema = {
  version: "1.0.0",
  resource: "users",
  hooks: {
    beforeCreate: "users.beforeCreate",
    afterCreate: "users.afterCreate",
    beforeUpdate: "users.beforeUpdate",
    afterUpdate: "users.afterUpdate",
    beforeDelete: "users.beforeDelete",
    afterDelete: "users.afterDelete"
  },
  registry: {
    hooks: [
      "users.beforeCreate",
      "users.afterCreate",
      "users.beforeUpdate",
      "users.afterUpdate",
      "users.beforeDelete",
      "users.afterDelete"
    ]
  }
} as const;

Lifecycle hook names are generated from operation names, such as beforeCreate, afterCreate, beforeUpdate, and afterDelete.

Generic submit hooks

beforeSubmit and afterSubmit are two additional hook keys that are not generated from an operation name. They run once per form submit, for both create and edit mode, in addition to whichever operation-specific hook (beforeCreate/afterCreate or beforeUpdate/afterUpdate) also fires for that submit. Use them for cross-cutting behavior that should run regardless of mode, such as logging or analytics, instead of duplicating the same registry function under both operation-specific keys.

schemas/users/users.schema.ts

TS
export const usersSchema = {
  version: "1.0.0",
  resource: "users",
  hooks: {
    beforeSubmit: "users.beforeSubmit",
    afterSubmit: "users.afterSubmit"
  },
  registry: {
    hooks: ["users.beforeSubmit", "users.afterSubmit"]
  }
} as const;
TS
export const registry = createRegistry({
  hooks: {
    "users.beforeSubmit": async ({ operation, values }) => {
      console.info(`Submitting ${operation} form`, values);
    },
    "users.afterSubmit": async ({ operation, values }) => {
      console.info(`${operation} form submitted`, values);
    }
  }
});

The context passed to beforeSubmit/afterSubmit uses operation ("create" or "update"), the same execution-context shape used by every other hook and handler — not the form's mode prop ("create" | "edit" | "view").

Runtime hooks

lib/vibeflui/registry.ts

TS
import { createRegistry } from "@vibeflui/core";

export const registry = createRegistry({
  hooks: {
    "users.beforeCreate": async ({ values }) => {
      console.info("Creating user", values);
    },
    "users.afterCreate": async ({ values }) => {
      console.info("User created", values);
    }
  }
});

Hooks can also resolve through actionHandlers or handlers, but prefer the hooks registry slot for lifecycle-specific code.

Events

Events are mapped in schema and resolved through registry.events.

schemas/users/users.schema.ts

TS
export const usersSchema = {
  version: "1.0.0",
  resource: "users",
  events: {
    formSubmitSucceeded: "users.formSubmitSucceeded",
    rowClicked: "users.rowClicked",
    actionSucceeded: "users.actionSucceeded"
  },
  registry: {
    events: ["users.formSubmitSucceeded", "users.rowClicked", "users.actionSucceeded"]
  }
} as const;

lib/vibeflui/registry.ts

TS
export const registry = createRegistry({
  events: {
    "users.formSubmitSucceeded": async ({ values }) => {
      console.info("Form submitted", values);
    },
    "users.rowClicked": async ({ row }) => {
      console.info("Row clicked", row);
    },
    "users.actionSucceeded": async ({ action, row }) => {
      console.info("Action succeeded", action?.key, row);
    }
  }
});

Runtime-emitted event names include formOpened, formSubmitted, formSubmitSucceeded, formSubmitFailed, rowSelected, rowClicked, actionClicked, actionSucceeded, and actionFailed.

Hooks vs action handlers

Use action handlers to execute the action itself.

Use hooks to run behavior before or after the operation.

schemas/users/users.schema.ts

TS
actions: {
  create: { handler: "users.create" }
},
hooks: {
  beforeCreate: "users.beforeCreate",
  afterCreate: "users.afterCreate"
}

Official examples note

Avoid noisy side effects in local demos. For local demos, hooks and events should update demo state or log to a visible panel instead of calling real services.