@promethean-os/plugin-hooks
v1.0.0
Published
Event-driven plugin hooks architecture for the Promethean framework
Downloads
15
Maintainers
Readme
@promethean-os/plugin-hooks
A sophisticated event-driven plugin hooks architecture for the Promethean framework, providing a robust foundation for extensible and maintainable plugin systems.
🌟 Features
- Event-Driven Architecture: Built on top of a powerful event bus system for decoupled communication
- Priority-Based Hook Execution: Control the order of hook execution with configurable priorities
- Plugin Lifecycle Management: Complete plugin lifecycle from initialization to destruction
- Cross-Platform Compatibility: Works seamlessly across Node.js, Browser, Deno, and Bun environments
- Comprehensive Security: Built-in sandboxing, policy enforcement, and audit logging
- Plugin Discovery: Automatic plugin discovery and loading from filesystem
- Development SDK: Rich SDK with utilities for logging, configuration, storage, and HTTP
- TypeScript Support: Full TypeScript support with comprehensive type definitions
- Zero-Downtime Reloading: Hot reload plugins without stopping the application
📦 Installation
pnpm add @promethean-os/plugin-hooks🚀 Quick Start
Basic Usage
import { HookRegistry, PluginManager, EventBus } from '@promethean-os/plugin-hooks';
import { LoggerPlugin } from '@promethean-os/plugin-hooks/examples/logger-plugin';
// Create an event bus (implementation depends on your event system)
const eventBus: EventBus = createEventBus();
// Create a hook registry
const hookRegistry = new HookRegistry();
// Create a plugin manager
const pluginManager = new PluginManager(eventBus, hookRegistry);
// Load a plugin
await pluginManager.loadPlugin(new LoggerPlugin());
// Execute hooks
const results = await pluginManager.executeHook('system.startup', 'Application starting');Enhanced Usage with Event-Driven Features
import { EnhancedPluginManager } from '@promethean-os/plugin-hooks';
import { EventBus } from '@promethean-os/event';
const eventBus = new EventBus();
const pluginManager = new EnhancedPluginManager(eventBus, {
autoLoad: true,
hookTimeout: 5000,
maxConcurrentHooks: 10,
enableHookLogging: true,
});
// Load plugins with event-driven capabilities
await pluginManager.loadPlugin(new LoggerPlugin());
// Hooks can now be triggered by events
await eventBus.publish('system.startup', { message: 'Application starting' });🏗️ Architecture
Core Components
- HookRegistry: Central registry for all hook registrations
- PluginManager: Basic plugin lifecycle management
- EnhancedPluginManager: Advanced plugin manager with event-driven features
- EventDrivenHookManager: Manages event-driven hook execution
- SecurityManager: Comprehensive security and sandboxing
- PluginLoader: Plugin discovery and loading utilities
- PluginSDK: Development utilities for plugin authors
Plugin Lifecycle
Plugin Discovery → Validation → Initialization → Hook Registration → Active → Hook Execution → DestructionEvent Flow
Event Published → Event Bus → Hook Manager → Hook Registry → Execute Hooks → Collect Results📝 Plugin Development
Creating a Basic Plugin
import { Plugin, PluginContext, HookRegistration, HookResult } from '@promethean-os/plugin-hooks';
export class MyPlugin implements Plugin {
metadata = {
name: 'my-plugin',
version: '1.0.0',
description: 'My awesome plugin',
hooks: ['system.startup', 'user.action'],
};
async initialize(context: PluginContext): Promise<void> {
console.log('My plugin initialized');
// Register hooks dynamically
context.registerHook({
pluginName: this.metadata.name,
hookName: 'system.startup',
handler: this.handleStartup.bind(this),
priority: 10,
});
}
async destroy(): Promise<void> {
console.log('My plugin destroyed');
}
getHooks(): HookRegistration[] {
return [
{
pluginName: this.metadata.name,
hookName: 'user.action',
handler: this.handleUserAction.bind(this),
priority: 5,
},
];
}
private handleStartup(data: string, context: HookContext): HookResult<void> {
console.log(`Handling startup: ${data}`);
return { success: true };
}
private handleUserAction(data: any, context: HookContext): HookResult<void> {
console.log(`User action: ${JSON.stringify(data)}`);
return { success: true };
}
}Using the Plugin SDK
import { PluginSDK } from '@promethean-os/plugin-hooks/sdk';
import { z } from 'zod';
export class AdvancedPlugin implements Plugin {
metadata = {
name: 'advanced-plugin',
version: '1.0.0',
description: 'Advanced plugin with SDK',
};
private sdk: PluginSDK;
async initialize(context: PluginContext): Promise<void> {
this.sdk = new PluginSDK(context);
// Create hooks with validation
const startupHook = this.sdk.createHook(
'system.startup',
(data: { message: string }) => {
this.sdk.logger.info(`Startup: ${data.message}`);
return { status: 'ok' };
},
{
priority: 10,
schema: {
input: z.object({
message: z.string(),
}),
output: z.object({
status: z.string(),
}),
},
},
);
context.registerHook(startupHook);
}
// ... rest of plugin implementation
}🔒 Security Features
Security Manager
import { SecurityManager, SecurityPolicy } from '@promethean-os/plugin-hooks/security';
const securityManager = new SecurityManager({
defaultPolicy: {
allowNetworkAccess: false,
allowFileSystemAccess: false,
allowedModules: [],
maxExecutionTime: 5000,
maxMemoryUsage: 50 * 1024 * 1024, // 50MB
},
globalSettings: {
maxViolationsPerPlugin: 5,
autoBlockOnViolation: true,
requireCodeSigning: false,
},
monitoring: {
enableRealTimeMonitoring: true,
violationAlertThreshold: 3,
},
});
// Secure plugin loading
await securityManager.validatePlugin(plugin);
await securityManager.createSandbox(plugin);Plugin Sandboxing
import { PluginSandbox, SecurityPolicy } from '@promethean-os/plugin-hooks/security';
const policy: SecurityPolicy = {
allowNetworkAccess: true,
allowedDomains: ['api.example.com'],
allowFileSystemAccess: true,
allowedPaths: ['/tmp/plugin-data'],
maxExecutionTime: 10000,
maxMemoryUsage: 100 * 1024 * 1024,
};
const sandbox = new PluginSandbox(policy);
const result = await sandbox.executePlugin(plugin, context);🔧 Configuration
Plugin Manager Configuration
const config = {
autoLoad: true, // Auto-load plugins from directory
hookTimeout: 5000, // Hook execution timeout
maxConcurrentHooks: 10, // Maximum concurrent hook executions
enableHookLogging: true, // Enable hook execution logging
pluginDirectory: './plugins', // Directory to scan for plugins
enableHotReload: true, // Enable hot reload functionality
security: {
enabled: true,
sandboxing: true,
auditLogging: true,
},
};Event-Driven Configuration
const eventDrivenConfig = {
enableEventDrivenHooks: true,
eventTopics: {
'system.startup': 'system.startup',
'system.shutdown': 'system.shutdown',
'user.action': 'user.action',
},
eventProcessing: {
batchSize: 100,
processingInterval: 1000,
retryAttempts: 3,
deadLetterQueue: true,
},
};🌐 Cross-Platform Support
Platform-Specific Loading
import { PluginLoader, PlatformAdapter } from '@promethean-os/plugin-hooks';
// Node.js
const nodeAdapter = new NodePlatformAdapter();
const loader = new PluginLoader(nodeAdapter);
// Browser
const browserAdapter = new BrowserPlatformAdapter();
const browserLoader = new PluginLoader(browserAdapter);
// Deno
const denoAdapter = new DenoPlatformAdapter();
const denoLoader = new PluginLoader(denoAdapter);
// Bun
const bunAdapter = new BunPlatformAdapter();
const bunLoader = new PluginLoader(bunAdapter);Plugin Parity Manager
import { PluginParityManager } from '@promethean-os/plugin-hooks';
const parityManager = new PluginParityManager();
// Check plugin compatibility across platforms
const compatibility = await parityManager.checkCompatibility(plugin, ['node', 'browser', 'deno']);
// Get platform-specific adaptations
const adaptations = await parityManager.getAdaptations(plugin, 'browser');📊 Monitoring and Metrics
Hook Execution Metrics
import { HookRegistry } from '@promethean-os/plugin-hooks';
const registry = new HookRegistry();
// Get execution metrics
const metrics = registry.getMetrics();
console.log(`Total hooks executed: ${metrics.totalExecutions}`);
console.log(`Average execution time: ${metrics.averageExecutionTime}ms`);
console.log(`Success rate: ${metrics.successRate}%`);
// Get metrics by hook name
const hookMetrics = registry.getHookMetrics('system.startup');
console.log(`Hook executions: ${hookMetrics.executions}`);
console.log(`Hook failures: ${hookMetrics.failures}`);Plugin Health Monitoring
import { EnhancedPluginManager } from '@promethean-os/plugin-hooks';
const manager = new EnhancedPluginManager(eventBus);
// Get plugin health status
const health = await manager.getPluginHealth();
console.log(`Active plugins: ${health.activePlugins}`);
console.log(`Failed plugins: ${health.failedPlugins}`);
console.log(`Total hooks: ${health.totalHooks}`);🧪 Testing
Unit Testing Plugins
import { test } from 'ava';
import { MockEventBus, MockHookRegistry } from '@promethean-os/plugin-hooks/test-utils';
import { MyPlugin } from './my-plugin';
test('MyPlugin initializes correctly', async (t) => {
const eventBus = new MockEventBus();
const registry = new MockHookRegistry();
const plugin = new MyPlugin();
await plugin.initialize({ eventBus, hookRegistry: registry });
t.is(plugin.metadata.name, 'my-plugin');
t.true(registry.hasHook('system.startup'));
});
test('MyPlugin handles startup hook', async (t) => {
const eventBus = new MockEventBus();
const registry = new MockHookRegistry();
const plugin = new MyPlugin();
await plugin.initialize({ eventBus, hookRegistry: registry });
const results = await registry.execute('system.startup', 'test data');
t.is(results.length, 1);
t.true(results[0].success);
});Integration Testing
import { test } from 'ava';
import { EnhancedPluginManager, EventBus } from '@promethean-os/plugin-hooks';
import { LoggerPlugin } from '@promethean-os/plugin-hooks/examples/logger-plugin';
test('Plugin manager loads and executes hooks', async (t) => {
const eventBus = new EventBus();
const manager = new EnhancedPluginManager(eventBus);
await manager.loadPlugin(new LoggerPlugin());
const results = await manager.executeHook('system.startup', 'test startup');
t.is(results.length, 1);
t.true(results[0].success);
});📚 Examples
Event-Driven Logger Plugin
import { Plugin, PluginContext, HookRegistration, HookResult } from '@promethean-os/plugin-hooks';
export class EventDrivenLoggerPlugin implements Plugin {
metadata = {
name: 'event-driven-logger',
version: '1.0.0',
description: 'Event-driven logging plugin',
hooks: ['system.startup', 'system.shutdown', 'error.occurred'],
};
private logs: Array<{ timestamp: number; level: string; message: string }> = [];
async initialize(context: PluginContext): Promise<void> {
// Subscribe to events
await context.eventBus.subscribe(
'system.startup',
'logger',
this.handleStartupEvent.bind(this),
);
await context.eventBus.subscribe(
'system.shutdown',
'logger',
this.handleShutdownEvent.bind(this),
);
await context.eventBus.subscribe('error.occurred', 'logger', this.handleErrorEvent.bind(this));
}
private async handleStartupEvent(event: any, ctx: any): Promise<void> {
this.logs.push({
timestamp: Date.now(),
level: 'info',
message: `System startup: ${event.payload}`,
});
}
private async handleShutdownEvent(event: any, ctx: any): Promise<void> {
this.logs.push({
timestamp: Date.now(),
level: 'info',
message: `System shutdown: ${event.payload}`,
});
}
private async handleErrorEvent(event: any, ctx: any): Promise<void> {
this.logs.push({
timestamp: Date.now(),
level: 'error',
message: `Error occurred: ${event.payload.message}`,
});
}
getLogs(): Array<{ timestamp: number; level: string; message: string }> {
return this.logs;
}
}Metrics Plugin
import { Plugin, PluginContext, HookRegistration, HookResult } from '@promethean-os/plugin-hooks';
export class MetricsPlugin implements Plugin {
metadata = {
name: 'metrics',
version: '1.0.0',
description: 'Metrics collection plugin',
hooks: ['request.start', 'request.end', 'error.occurred'],
};
private metrics: Map<string, number> = new Map();
async initialize(context: PluginContext): Promise<void> {
this.metrics.set('requestCount', 0);
this.metrics.set('errorCount', 0);
this.metrics.set('totalResponseTime', 0);
}
getHooks(): HookRegistration[] {
return [
{
pluginName: this.metadata.name,
hookName: 'request.start',
handler: this.handleRequestStart.bind(this),
priority: 1,
},
{
pluginName: this.metadata.name,
hookName: 'request.end',
handler: this.handleRequestEnd.bind(this),
priority: 1,
},
{
pluginName: this.metadata.name,
hookName: 'error.occurred',
handler: this.handleError.bind(this),
priority: 10,
},
];
}
private handleRequestStart(
data: { requestId: string; timestamp: number },
context: HookContext,
): HookResult<void> {
this.metrics.set('requestCount', (this.metrics.get('requestCount') || 0) + 1);
return { success: true };
}
private handleRequestEnd(
data: { requestId: string; duration: number },
context: HookContext,
): HookResult<void> {
this.metrics.set(
'totalResponseTime',
(this.metrics.get('totalResponseTime') || 0) + data.duration,
);
return { success: true };
}
private handleError(data: { error: Error }, context: HookContext): HookResult<void> {
this.metrics.set('errorCount', (this.metrics.get('errorCount') || 0) + 1);
return { success: true };
}
getMetrics(): Record<string, number> {
return Object.fromEntries(this.metrics);
}
}🔍 Best Practices
Plugin Development
- Keep Plugins Focused: Each plugin should have a single, well-defined responsibility
- Use Proper Error Handling: Always handle errors gracefully and return appropriate HookResult objects
- Implement Cleanup: Always implement the
destroy()method to clean up resources - Use the SDK: Leverage the PluginSDK for common utilities and validation
- Test Thoroughly: Write comprehensive tests for your plugins
Security Considerations
- Use Sandboxing: Always run plugins in sandboxes when dealing with untrusted code
- Validate Input: Validate all input data using schemas
- Limit Resources: Set appropriate limits on execution time and memory usage
- Audit Logging: Enable audit logging for security-sensitive operations
- Regular Updates: Keep security policies and dependencies up to date
Performance Optimization
- Use Appropriate Priorities: Set hook priorities based on execution order requirements
- Avoid Blocking Operations: Use async/await for I/O operations
- Monitor Performance: Regularly check hook execution metrics
- Use Batching: Batch operations when possible to reduce overhead
- Cache Results: Cache expensive operations when appropriate
🤝 Contributing
We welcome contributions! Please see our contributing guidelines for details.
Development Setup
# Clone the repository
git clone https://github.com/promethean/plugin-hooks.git
cd plugin-hooks
# Install dependencies
pnpm install
# Run tests
pnpm test
# Build the package
pnpm build
# Run linting
pnpm lint📄 License
This project is licensed under the GPL-3.0 License - see the LICENSE file for details.
🙏 Acknowledgments
- Built on top of the amazing Promethean framework
- Inspired by modern plugin architectures in systems like WordPress, VS Code, and Kubernetes
- Powered by Zod for schema validation
📞 Support
For support, please:
- Check the documentation
- Search existing issues
- Create a new issue if needed
Promethean Plugin Hooks - Stealing fire from the gods to grant man the gift of extensible architectures.
