# Plugin API Reference This document provides detailed technical information about BetterSEQTA+'s plugin APIs. For a beginner-friendly introduction, see [Creating Your First Plugin](./README.md). ## Plugin Interface The core `Plugin` interface that all plugins must implement: ```typescript interface Plugin { id: string; // Unique identifier for the plugin name: string; // Display name description: string; // Plugin description version: string; // Semantic version (e.g. "1.0.0") settings: T; // Plugin settings (type-safe) styles?: string; // Optional CSS styles disableToggle?: boolean; // Whether to show enable/disable toggle run: (api: PluginAPI) => void | Promise | (() => void) | Promise<(() => void)>; } ``` ## SEQTA API The `SEQTAAPI` interface provides methods for interacting with SEQTA's UI: ```typescript interface SEQTAAPI { // Wait for an element to appear in the DOM onMount( selector: string, // CSS selector callback: (el: Element) => void ): { unregister: () => void }; // Get React fiber for debugging/advanced usage getFiber(selector: string): ReactFiber; // Get current SEQTA page getCurrentPage(): string; // Listen for page changes onPageChange( callback: (page: string) => void ): { unregister: () => void }; } ``` ## Settings API The settings system provides type-safe plugin configuration: ```typescript interface SettingsAPI { // Access setting values [K in keyof T]: SettingValue; // Listen for setting changes onChange( key: K, callback: (value: SettingValue) => void ): { unregister: () => void }; // Remove change listener offChange( key: K, callback: (value: SettingValue) => void ): void; // Promise that resolves when settings are loaded loaded: Promise; } ``` ### Setting Types Available setting types: ```typescript // Boolean toggle booleanSetting({ default: boolean; title: string; description: string; }); // Text input stringSetting({ default: string; title: string; description: string; placeholder?: string; }); // Number input numberSetting({ default: number; title: string; description: string; min?: number; max?: number; step?: number; }); // Dropdown select selectSetting({ default: T; title: string; description: string; options: Array<{ value: T; label: string; }>; }); ``` ### Using Settings Two ways to define settings: 1. Using the BasePlugin class (recommended): ```typescript const settings = defineSettings({ mySetting: booleanSetting({...}) }); class MyPlugin extends BasePlugin { @Setting(settings.mySetting) mySetting!: boolean; } ``` 2. Direct object (simpler but less type-safe): ```typescript const settings = { mySetting: booleanSetting({...}) }; ``` ## Storage API Persistent storage for plugin data: ```typescript interface StorageAPI { // Get a stored value get(key: K): Promise; // Set a value set(key: K, value: T[K]): Promise; // Delete a value delete(key: K): Promise; // Listen for changes onChange( key: K, callback: (value: T[K]) => void ): { unregister: () => void }; // Promise that resolves when storage is loaded loaded: Promise; } ``` Storage is: - Persistent across page reloads - Isolated per plugin (plugins can't access each other's storage) - Type-safe when using TypeScript - Automatically synchronized across tabs ## Events API Inter-plugin communication system: ```typescript interface EventsAPI { // Listen for an event on( event: string, callback: (...args: any[]) => void ): { unregister: () => void }; // Emit an event emit(event: string, ...args: any[]): void; } ``` Event naming conventions: - Use `plugin.{pluginId}.{eventName}` for plugin-specific events - Use `seqta.{eventName}` for SEQTA-related events - Use `global.{eventName}` for system-wide events ## Plugin Lifecycle 1. **Registration**: ```typescript PluginManager.getInstance().registerPlugin(myPlugin); ``` 2. **Initialization**: - Plugin's `run` function is called - Settings and storage are loaded - CSS styles are injected (if any) 3. **Running**: - Plugin can use all APIs - Can listen for events and changes - Can modify SEQTA's UI 4. **Cleanup**: - When plugin is disabled or unloaded - Cleanup function from `run` is called - CSS styles are removed - Event listeners are cleaned up ## Type Safety TypeScript types for type-safe plugins: ```typescript // Plugin with settings and storage types interface MyPluginSettings { theme: string; notifications: boolean; } interface MyPluginStorage { lastVisit: string; userData: { name: string; id: number }; } const myPlugin: Plugin = { // TypeScript will ensure type safety for: // - Settings access and changes // - Storage operations // - Event payloads (when typed) }; ``` ## Error Handling Best practices for plugin error handling: ```typescript run: async (api) => { try { // Initialization await someAsyncOperation(); // Return cleanup return () => { try { // Cleanup code } catch (error) { console.error('Plugin cleanup failed:', error); } }; } catch (error) { // Log error but don't crash console.error('Plugin initialization failed:', error); // Still return cleanup to ensure proper shutdown return () => {}; } } ``` ## Performance Considerations 1. **DOM Operations**: - Use `onMount` instead of polling - Batch DOM updates - Use CSS classes instead of inline styles - Remove listeners when not needed 2. **Storage**: - Cache frequently accessed values - Batch storage operations - Don't store large objects 3. **Events**: - Clean up listeners - Use typed events - Don't emit events too frequently 4. **Settings**: - Use appropriate setting types - Provide good defaults - Handle setting changes efficiently