first commit
This commit is contained in:
112
docs/api-stack/api/api-plugin-events/src/plugin/plugin.md
Normal file
112
docs/api-stack/api/api-plugin-events/src/plugin/plugin.md
Normal file
@@ -0,0 +1,112 @@
|
||||
# plugin
|
||||
|
||||
<!-- begin:auto-docs -->
|
||||
_(no submodules)_
|
||||
<!-- end:auto-docs -->
|
||||
|
||||
## Purpose
|
||||
|
||||
Defines `createEventsPlugin`, the factory that returns the
|
||||
`PluginDescriptor<EventsPluginConfig>` consumed by `@suaveplan/api`'s
|
||||
plugin registry. The factory Zod-validates options at the boundary,
|
||||
constructs the runtime closure, and returns the four lifecycle hooks
|
||||
(`onInit`, `onReady`, `onClose`) that the registry's topological
|
||||
sorter wires up after the `database` dependency has booted.
|
||||
|
||||
The lifecycle is intentionally split: `onInit` reads the `db` slot
|
||||
and registers the two repositories so downstream plugins (search,
|
||||
audit, notifications) can resolve `eventRepository` /
|
||||
`rsvpRepository` during their own `onInit`; `onReady` is the latest
|
||||
phase the registry runs, so the `app` slot is guaranteed-populated
|
||||
and the route mount is the last side effect before the host starts
|
||||
listening.
|
||||
|
||||
## Features
|
||||
|
||||
- Zod-validated config at construction time — invalid options raise
|
||||
`EventsPluginError(INVALID_CONFIG)` before the descriptor leaves
|
||||
the factory.
|
||||
- Lifecycle dedup — `onReady` refuses to mount when the configured
|
||||
`basePath` already has routes registered, raising
|
||||
`EventsPluginError(ROUTE_PREFIX_COLLISION)` instead of silently
|
||||
shadowing the first mount.
|
||||
- Forwards typed route events to the host's shared
|
||||
`ctx.eventBus` (fixes the upstream "local emitter" smell flagged in
|
||||
`enterprise/api-plugin-events.md`).
|
||||
- `onClose` clears repository references so the GC can collect them.
|
||||
|
||||
## Usage: Basic Example
|
||||
|
||||
```ts
|
||||
import { createEventsPlugin } from "@suaveplan/api-plugin-events";
|
||||
import { quickstart } from "@suaveplan/api";
|
||||
import { createDatabasePlugin } from "@suaveplan/api-plugin-database";
|
||||
|
||||
const app = await quickstart({
|
||||
plugins: [
|
||||
createDatabasePlugin({
|
||||
/* ... */
|
||||
}),
|
||||
createEventsPlugin(), // mounts under /events by default
|
||||
],
|
||||
});
|
||||
```
|
||||
|
||||
## Usage: Advanced Example
|
||||
|
||||
```ts
|
||||
import { createEventsPlugin } from "@suaveplan/api-plugin-events";
|
||||
|
||||
const plugin = createEventsPlugin({
|
||||
basePath: "/v1/events",
|
||||
enableNotifications: false,
|
||||
maxInvitesPerRequest: 25,
|
||||
});
|
||||
|
||||
// Inspect the descriptor before handing it to the registry
|
||||
console.log(plugin.name); // "events"
|
||||
console.log(plugin.dependencies); // ["database"]
|
||||
console.log(plugin.defaults.maxInvitesPerRequest); // 25
|
||||
|
||||
// Subscribe to lifecycle and domain events on the shared bus:
|
||||
host.eventBus.on("events:ready", () => {
|
||||
/* routes are now mounted */
|
||||
});
|
||||
host.eventBus.on("event:created", ({ eventId, creatorId }) => {
|
||||
/* fan out to notifications, search index, audit log */
|
||||
});
|
||||
```
|
||||
|
||||
## API Reference
|
||||
|
||||
### `createEventsPlugin(options?: EventsPluginConfigInput): PluginDescriptor<EventsPluginConfig>`
|
||||
|
||||
Builds the plugin descriptor.
|
||||
|
||||
- **options** — Partial `EventsPluginConfig`. Each field has a
|
||||
default; passing `{}` (or no argument) produces the default
|
||||
config (`/events`, `enableNotifications: false`,
|
||||
`maxInvitesPerRequest: 50`).
|
||||
- **throws** `EventsPluginError(INVALID_CONFIG)` if `options` fails
|
||||
`EventsPluginOptionsSchema`.
|
||||
|
||||
### Lifecycle hooks (attached to the returned descriptor)
|
||||
|
||||
- `onInit(ctx)` — pulls `db` from the registry, constructs the
|
||||
repositories, registers `eventRepository` and `rsvpRepository`,
|
||||
emits `events:initialized`.
|
||||
- `onReady(ctx)` — pulls `app`, builds routes via
|
||||
`createEventRoutes`, mounts under `config.basePath`, emits
|
||||
`events:ready`.
|
||||
- `onClose()` — clears repository refs.
|
||||
|
||||
## Implementation Notes
|
||||
|
||||
The plugin's `dependencies: ["database"]` declaration makes the
|
||||
suaveplan registry topo-sort the events plugin strictly after the
|
||||
database plugin. Without that ordering, `onInit` would fail because
|
||||
`ctx.getService("db")` would resolve to `undefined`. The `app` slot
|
||||
does not need to be declared as a dependency because every host
|
||||
seeds it during registry construction (per the foundation patch
|
||||
shipped on `2026-05-17`); the runtime check inside `onReady` is
|
||||
defensive against custom hosts that don't pre-seed.
|
||||
Reference in New Issue
Block a user