Hook System
The hook system is Trove's primary mechanism for extending functionality and enabling plugins to interact with the core system and each other.
What are Hooks?
Hooks are named events that plugins can listen for and respond to. When a hook is triggered, all registered handlers for that hook are called in sequence, allowing multiple plugins to process the same event or request.
Core Hooks
Event Lifecycle
event:validating
- Before event schema validationevent:validated
- After successful schema validationevent:received
- When a new event is createdevent:storing
- Before storing an eventevent:stored
- After an event is stored
Schema Lifecycle
schema:registering
- Before registering a new schemaschema:registered
- After a schema is registered
HTTP Lifecycle
http:request
- For each incoming HTTP requesthttp:response
- Before sending an HTTP response
System Lifecycle
system:initializing
- During system startupsystem:initialized
- After system is readysystem:shutting-down
- Before system shutdown
Using Hooks
Plugins can register hook handlers in their definition:
export default {
name: "my-plugin",
version: "1.0.0",
hooks: {
"event:received": async (context) => {
const { event, core } = context;
// Process the event
},
"http:request": async (context) => {
const { request } = context;
// Handle the request or return null to pass to next handler
},
},
};
Hook Context
Each hook receives a context object containing relevant data and utilities:
interface HookContext {
// The core system API
core: CoreSystem;
// Hook-specific data
event?: Event; // For event hooks
request?: Request; // For HTTP hooks
response?: Response; // For HTTP hooks
schema?: EventSchema; // For schema hooks
// Shared state for this processing chain
state: Map<string, any>;
// Utilities
logger: Logger;
}
Hook Priority
Plugins can specify priority for their hooks to control execution order:
export default {
name: "my-plugin",
hooks: {
"event:received": {
priority: 100, // Higher numbers run first
handler: async (context) => {
// Handle event
},
},
},
};
Creating Custom Hooks
Plugins can register their own hooks for other plugins to use:
export default {
name: "my-plugin",
async initialize(core) {
// Register a new hook
await core.registerHook("my-plugin:custom-event", {
schema: {
// JSON Schema for hook arguments
},
});
},
async someFunction() {
// Trigger the hook
await this.core.executeHook("my-plugin:custom-event", {
// Hook arguments
});
},
};
Best Practices
- Use descriptive hook names with namespaces
- Document hook arguments and expected behavior
- Handle hook failures gracefully
- Use priorities when order matters
- Keep hook handlers focused and efficient