Skip to content
Moku LabsDocs
Concepts pages

Events

Strict emit, the register callback, who sees what.

events.mdllms.txt

Strict emit

Events are notifications: fire-and-forget, typed, no return value. Only known event names compile, and the payload must match.

ctx.emit("auth:login", { userId: "123" }); // OK
ctx.emit("auth:login", { wrongKey: true }); // compile error: wrong payload
ctx.emit("unknown:event", {}); // compile error: unknown event

Handlers for one event run in plugin order, each awaited before the next. A handler error goes to onError; it never stops the emitter.

Declaring events

A plugin declares its own events with the register callback. The payload type comes from register<T>(), so createPlugin still takes no generics.

src/plugins/auth.ts
import { createApp, createPlugin } from "@moku-labs/web";

const authPlugin = createPlugin("auth", {
  events: register => ({
    "auth:login": register<{ userId: string }>("Triggered after user login")
  }),
  api: ctx => ({
    login: (userId: string) => ctx.emit("auth:login", { userId })
  })
});

const auditPlugin = createPlugin("audit", {
  depends: [authPlugin],
  createState: (): { entries: string[] } => ({ entries: [] }),
  hooks: ctx => ({
    "auth:login": ({ userId }) => {
      ctx.state.entries.push(`login:${userId}`);
    }
  }),
  api: ctx => ({ entries: () => [...ctx.state.entries] })
});

const app = createApp({
  plugins: [authPlugin, auditPlugin],
  pluginConfigs: { site: { name: "Demo", url: "https://example.com" } }
});

app.auth.login("ada");
  1. The description is documentation; the type is the contract.
  2. depends makes auth's events visible to audit's hooks.

With a separate event-map type, use register.map:

type AuthEvents = { "auth:login": { userId: string }; "auth:logout": { userId: string } };

events: register =>
  register.map<AuthEvents>({
    "auth:login": "Triggered after user login",
    "auth:logout": "Triggered after user logout"
  });

Who sees which events

SourceDeclared inVisible to
Global eventsthe framework's createCoreConfig<Config, Events>all plugins
Own eventsevents: register => ({ ... }) on the pluginthis plugin
Dependency eventsevents on plugins listed in dependsplugins that declare the dependency

Events in @moku-labs/web

EventEmitted by
build:phase, build:completebuild
content:ready, content:invalidatedcontent
deploy:completedeploy
spa:navigate, spa:navigated, spa:island-mount, spa:island-unmountspa