Skip to content

Plugin Events (Plugins)

The Tuff uses an event-driven architecture to facilitate communication between the core application and plugins. This guide explains how plugins can emit and listen to events.

Event Bus

The application provides an event bus system that allows plugins to communicate with each other and with the core application. The event bus is accessible through the plugin SDK.

Listening to Events

Plugins can listen to events emitted by the core application or other plugins.

Basic Event Listening

To listen to an event, use the on method provided by the event bus:

javascript
// In your plugin's main file or preload script
import { eventBus } from '@polyglot-toolbox/plugin-sdk';

eventBus.on('document-opened', (data) => {
  console.log('A document was opened:', data);
  // Perform actions when a document is opened
});

Event Data

Events can carry data that provides context about the event. The structure of this data depends on the specific event.

Example event data:

json
{
  "documentId": "doc-12345",
  "filePath": "/path/to/document.txt",
  "timestamp": "2023-10-15T14:30:00Z"
}

Emitting Events

Plugins can also emit their own events to communicate with other parts of the application.

Basic Event Emission

To emit an event, use the emit method:

javascript
// In your plugin's main file or preload script
import { eventBus } from '@polyglot-toolbox/plugin-sdk';

// Emit an event when a custom action is performed
eventBus.emit('my-plugin-action', {
  action: 'button-clicked',
  timestamp: new Date().toISOString()
});

Common Application Events

The core application emits several built-in events that plugins can listen to:

Document Events

  • document-opened: Emitted when a document is opened.
  • document-closed: Emitted when a document is closed.
  • document-saved: Emitted when a document is saved.
  • document-modified: Emitted when a document is modified.

Window Events

  • window-focused: Emitted when the application window gains focus.
  • window-blurred: Emitted when the application window loses focus.
  • window-resized: Emitted when the window is resized.

User Events

  • user-logged-in: Emitted when a user logs in.
  • user-logged-out: Emitted when a user logs out.

System Events

  • app-started: Emitted when the application starts.
  • app-closing: Emitted when the application is about to close.
  • settings-changed: Emitted when application settings are modified.

Event Best Practices

When working with events in your plugin, consider the following best practices:

1. Use Descriptive Event Names

Choose clear and descriptive names for your events to make them easy to understand and use.

javascript
// Good
eventBus.emit('translation-completed', result);
javascript
// Avoid
eventBus.emit('done', result);

2. Provide Useful Event Data

Include relevant data with your events to make them more useful to listeners.

javascript
// Good
eventBus.emit('file-processed', {
  fileId: 'file-123',
  fileName: 'document.txt',
  processingTime: 1500, // in milliseconds
  success: true
});
javascript
// Avoid
eventBus.emit('file-processed', 'file-123');

3. Handle Event Listener Cleanup

If your plugin creates event listeners, make sure to remove them when they're no longer needed to prevent memory leaks.

javascript
// Store the listener function
const listener = (data) => {
  // Handle the event
};

// Add the listener
eventBus.on('document-opened', listener);

// Remove the listener when cleaning up
eventBus.off('document-opened', listener);

4. Avoid Circular Event Dependencies

Be careful not to create circular dependencies where events trigger each other in a loop.

javascript
// This could create an infinite loop
eventBus.on('setting-changed', () => {
  // Some logic that changes a setting
  changeSetting(); // This might emit 'setting-changed' again
});

Custom Events in Plugins

When creating custom events for your plugin, follow these conventions:

  1. Prefix your event names with your plugin's identifier to avoid conflicts:

    javascript
    eventBus.emit('my-plugin-name:data-processed', data);
  2. Document the events your plugin emits so other developers can use them:

    javascript
    /**
     * Emitted when the plugin finishes processing data
     * @event my-plugin-name:data-processed
     * @type {object}
     * @property {string} id - The ID of the processed item
     * @property {object} result - The processing result
     */

Example: Creating a Simple Event-Based Plugin

Here's a complete example of a plugin that uses events:

javascript
// plugin.js
import { eventBus } from '@polyglot-toolbox/plugin-sdk';

class SimpleEventPlugin {
  constructor() {
    // Listen to document events
    eventBus.on('document-opened', this.handleDocumentOpened.bind(this));
    
    // Emit a custom event when the plugin is initialized
    eventBus.emit('simple-event-plugin:initialized', {
      timestamp: new Date().toISOString()
    });
  }
  
  handleDocumentOpened(data) {
    console.log('Document opened:', data.filePath);
    
    // Perform some action and emit a result
    const result = this.processDocument(data);
    
    eventBus.emit('simple-event-plugin:document-processed', {
      documentId: data.documentId,
      result: result,
      timestamp: new Date().toISOString()
    });
  }
  
  processDocument(data) {
    // Simulate document processing
    return {
      wordCount: Math.floor(Math.random() * 1000),
      processed: true
    };
  }
}

// Initialize the plugin
new SimpleEventPlugin();

This plugin listens for document open events, processes the document, and emits its own events to communicate the results.

For more information about the plugin SDK and available APIs, see the Plugin SDK documentation.