Skip to content

Lifecycle Hooks

Plugins can respond to lifecycle events through handler functions defined in the manifest. These hooks allow plugins to initialize resources, clean up state, and respond to user actions.

interface PluginHandlers {
onEnable?: () => Promise<void>;
onDisable?: () => Promise<void>;
onInstall?: () => Promise<void>;
onUninstall?: () => Promise<void>;
}

Called when a user enables the plugin in Settings > Plugins.

When to use:

  • Initialize runtime resources
  • Set up event listeners
  • Load cached data
  • Register global handlers

Example:

handlers: {
onEnable: async () => {
console.log('Timer plugin enabled');
// Initialize storage
const timers = localStorage.getItem('aether_timers');
if (!timers) {
localStorage.setItem('aether_timers', JSON.stringify({}));
}
// Set up event listeners
window.addEventListener('beforeunload', handleBeforeUnload);
// Notify user
showNotification({
title: 'Timer plugin enabled',
message: 'You can now track time on work units',
color: 'success',
});
}
}

Called when a user disables the plugin in Settings > Plugins.

When to use:

  • Clean up resources
  • Remove event listeners
  • Save state before disabling
  • Archive data

Example:

handlers: {
onDisable: async () => {
console.log('Timer plugin disabled');
// Stop any running timers
const timers = getTimersFromStorage();
Object.keys(timers).forEach(id => {
if (timers[id].isRunning) {
stopTimer(id);
}
});
// Remove event listeners
window.removeEventListener('beforeunload', handleBeforeUnload);
// Notify user
showNotification({
title: 'Timer plugin disabled',
message: 'Time tracking has been stopped',
color: 'warning',
});
}
}

Called once when the plugin is first installed.

When to use:

  • Run database migrations
  • Create default configuration
  • Set up initial data
  • Create plugin-specific tables

Called when the plugin is uninstalled.

When to use:

  • Remove plugin data
  • Clean up database tables
  • Delete plugin-specific settings
  • Archive data for export
  1. User installs plugin package
  2. Platform discovers plugin manifest
  3. onInstall hook called
  4. Plugin appears in Settings > Plugins (disabled by default)
  1. User enables plugin in settings
  2. onEnable hook called
  3. Plugin extensions registered
  4. UI updates with new extensions
  1. User disables plugin in settings
  2. onDisable hook called
  3. Plugin extensions unregistered
  4. UI updates to remove extensions
  1. User uninstalls plugin
  2. onUninstall hook called
  3. Plugin removed from registry
  4. UI fully cleaned up

Lifecycle hooks should handle errors gracefully:

handlers: {
onEnable: async () => {
try {
await initializePlugin();
showNotification({
title: 'Plugin enabled',
color: 'success',
});
} catch (error) {
console.error('Failed to enable plugin:', error);
showNotification({
title: 'Failed to enable plugin',
message: error.message,
color: 'error',
});
throw error;
}
}
}

Avoid long-running operations that block the UI. Queue background work instead.

Track and clean up all resources (listeners, timers, etc) in onDisable.

Show notifications to inform users about lifecycle events.

Properly manage initialization state across enable/disable cycles.