Appearance
Develop Plugins
This comprehensive guide covers everything you need to know about developing plugins for the Motanamy platform, including EA, SA, and OS applications.
Plugin Architecture
Overview
Plugins in Motanamy are modular extensions that add functionality to our core applications. They follow a standardized architecture that ensures compatibility, security, and maintainability.
Plugin Types
EA Plugins
- Web Plugins: Browser-based extensions for the EA web interface
- Server Plugins: Backend extensions for EA server functionality
- Integration Plugins: Connect EA with external systems and APIs
SA Plugins
- UI Plugins: Extend the standalone application interface
- Service Plugins: Background services and automation
- Data Plugins: Custom data sources and processing modules
OS Plugins
- Kernel Modules: Low-level system extensions
- Device Drivers: Hardware interface drivers
- System Services: Core system functionality extensions
Getting Started
Prerequisites
- Motanamy Developer Account
- Motanamy IDE or compatible development environment
- Basic knowledge of JavaScript/TypeScript or Python
- Understanding of the target platform (EA/SA/OS)
Development Environment Setup
Install Motanamy CLI:
bashnpm install -g @motanamy/cliCreate Plugin Project:
bashmotanamy create-plugin my-plugin --type ea-web cd my-pluginInstall Dependencies:
bashnpm install
Plugin Structure
Basic Plugin Structure
my-plugin/
├── src/
│ ├── main.js
│ ├── manifest.json
│ ├── components/
│ └── services/
├── tests/
├── docs/
├── package.json
└── README.mdKey Files
manifest.json
The plugin manifest defines metadata and configuration:
json
{
"name": "my-plugin",
"version": "1.0.0",
"description": "A custom plugin for Motanamy",
"author": "Your Name",
"platform": "ea",
"type": "web",
"main": "src/main.js",
"permissions": [
"read-data",
"write-data",
"api-access"
],
"hooks": [
"onUserLogin",
"onDataUpdate"
],
"dependencies": {
"@motanamy/sdk": "^1.0.0"
}
}main.js
The main entry point for your plugin:
javascript
import { Plugin, Logger } from '@motanamy/sdk';
export default class MyPlugin extends Plugin {
async onLoad() {
Logger.info('My plugin loaded successfully!');
// Register hooks
this.registerHook('onUserLogin', this.handleUserLogin);
// Add UI components
this.addMenuItem({
title: 'My Plugin',
action: () => this.showPluginUI()
});
}
handleUserLogin(user) {
Logger.info(`User ${user.name} logged in`);
// Custom login logic
}
showPluginUI() {
// Show plugin interface
this.createWindow({
title: 'My Plugin',
content: '<h1>Hello from my plugin!</h1>',
width: 400,
height: 300
});
}
async onUnload() {
Logger.info('My plugin unloaded');
// Cleanup resources
}
}Development Workflow
1. Planning Your Plugin
- Define Purpose: What problem does your plugin solve?
- Identify Platform: Which Motanamy platform will it target?
- Assess Requirements: What permissions and hooks are needed?
- Design Architecture: Plan your plugin's structure and components
2. Setting Up Development
- Create Project Structure: Use CLI templates or manual setup
- Configure Manifest: Define plugin metadata and requirements
- Install Dependencies: Add required SDKs and libraries
- Set Up Testing: Create test environment and fixtures
3. Implementing Core Functionality
- Hook Implementation: Respond to platform events
- API Integration: Connect with Motanamy APIs
- UI Development: Create user interfaces if needed
- Data Management: Handle data storage and retrieval
4. Testing and Debugging
- Unit Tests: Test individual functions and modules
- Integration Tests: Test plugin interaction with platform
- User Testing: Validate user experience and workflows
- Cross-Platform Testing: Ensure compatibility across environments
5. Packaging and Deployment
- Build Plugin: Compile and package for distribution
- Version Management: Handle versioning and updates
- Documentation: Create user and developer documentation
- Publishing: Submit to plugin marketplace
Hooks and Events
Common Hooks
User Management
onUserLogin: Fired when a user logs inonUserLogout: Fired when a user logs outonUserCreated: Fired when a new user is createdonUserUpdated: Fired when user data is updated
Data Operations
onDataCreated: Fired when new data is createdonDataUpdated: Fired when data is updatedonDataDeleted: Fired when data is deletedonDataQueried: Fired when data is queried
System Events
onAppStart: Fired when the application startsonAppShutdown: Fired when the application shuts downonPluginLoaded: Fired when a plugin is loadedonPluginUnloaded: Fired when a plugin is unloaded
Using Hooks
javascript
// Register multiple hooks
this.registerHook('onUserLogin', this.handleLogin);
this.registerHook('onDataUpdated', this.handleDataUpdate);
// Hook with priority (higher numbers run first)
this.registerHook('onUserLogin', this.priorityHandler, 100);
// Conditional hook registration
if (this.hasPermission('admin')) {
this.registerHook('onUserCreated', this.adminHandler);
}API Integration
Using Motanamy APIs
javascript
import { API, Database, UI } from '@motanamy/sdk';
// API calls
const users = await API.get('/users');
const newUser = await API.post('/users', { name: 'John Doe' });
// Database operations
const db = new Database('my-plugin-data');
await db.insert('settings', { theme: 'dark' });
const settings = await db.query('SELECT * FROM settings');
// UI interactions
UI.showNotification('Plugin action completed!');
const result = await UI.showDialog({
title: 'Confirm Action',
message: 'Are you sure?',
buttons: ['Yes', 'No']
});Authentication and Permissions
javascript
// Check permissions
if (await this.hasPermission('read-sensitive-data')) {
const data = await API.get('/sensitive-data');
}
// Request additional permissions
await this.requestPermission('write-files');
// Use authenticated API calls
const token = await this.getAuthToken();
const response = await API.get('/protected-endpoint', {
headers: { Authorization: `Bearer ${token}` }
});UI Development
Creating UI Components
javascript
// Create a custom component
const myComponent = this.createComponent({
template: `
<div class="my-plugin-component">
<h3>{{ title }}</h3>
<button @click="handleClick">Click me</button>
</div>
`,
data: {
title: 'My Plugin Component'
},
methods: {
handleClick() {
UI.showNotification('Button clicked!');
}
}
});
// Add to application UI
this.addToSidebar(myComponent);Styling
css
.my-plugin-component {
padding: 20px;
background: #f5f5f5;
border-radius: 8px;
}
.my-plugin-component button {
background: #007bff;
color: white;
border: none;
padding: 8px 16px;
border-radius: 4px;
cursor: pointer;
}
.my-plugin-component button:hover {
background: #0056b3;
}Data Management
Local Storage
javascript
// Store plugin data
await this.setStorage('user-preferences', {
theme: 'dark',
language: 'en'
});
// Retrieve stored data
const preferences = await this.getStorage('user-preferences');
// Remove data
await this.removeStorage('user-preferences');Database Integration
javascript
// Connect to application database
const db = await this.getDatabaseConnection();
// Execute queries
const users = await db.query('SELECT * FROM users WHERE active = ?', [true]);
// Use transactions
await db.transaction(async (tx) => {
await tx.insert('logs', { message: 'Plugin action', timestamp: Date.now() });
await tx.update('stats', { actions: db.raw('actions + 1') }, { id: 1 });
});Error Handling and Logging
Logging
javascript
import { Logger } from '@motanamy/sdk';
// Different log levels
Logger.debug('Debug information');
Logger.info('General information');
Logger.warn('Warning message');
Logger.error('Error occurred', error);
// Contextual logging
Logger.info('User action', { userId: 123, action: 'login' });Error Handling
javascript
try {
const result = await riskyOperation();
Logger.info('Operation successful', result);
} catch (error) {
Logger.error('Operation failed', error);
// Show user-friendly error
UI.showError('Operation failed. Please try again.');
// Report error for debugging
this.reportError(error);
}Testing
Unit Testing
javascript
// tests/main.test.js
import { expect } from 'chai';
import MyPlugin from '../src/main.js';
describe('MyPlugin', () => {
let plugin;
beforeEach(() => {
plugin = new MyPlugin();
});
it('should load successfully', async () => {
await plugin.onLoad();
expect(plugin.loaded).to.be.true;
});
it('should handle user login', () => {
const user = { id: 1, name: 'Test User' };
plugin.handleUserLogin(user);
// Assert expected behavior
});
});Integration Testing
javascript
// Test with platform simulation
import { PlatformSimulator } from '@motanamy/testing';
describe('Plugin Integration', () => {
let simulator;
let plugin;
beforeEach(async () => {
simulator = new PlatformSimulator();
plugin = new MyPlugin();
await simulator.loadPlugin(plugin);
});
it('should respond to platform events', async () => {
await simulator.triggerEvent('onUserLogin', { id: 1, name: 'User' });
// Verify plugin response
});
});Security Best Practices
Input Validation
javascript
// Validate user input
function validateUserInput(input) {
if (!input || typeof input !== 'string') {
throw new Error('Invalid input');
}
// Sanitize input
const sanitized = input.replace(/<script>/gi, '');
return sanitized;
}Permission Management
javascript
// Request minimal permissions
const permissions = ['read-public-data'];
if (needsWriteAccess) {
permissions.push('write-data');
}
await this.requestPermissions(permissions);Secure API Calls
javascript
// Use HTTPS for all external API calls
const response = await API.post('https://secure-api.example.com/data', data, {
headers: {
'Content-Type': 'application/json',
'X-API-Key': this.getSecureApiKey()
}
});Performance Optimization
Efficient Event Handling
javascript
// Debounce frequent events
let debounceTimer;
this.registerHook('onDataUpdate', (data) => {
clearTimeout(debounceTimer);
debounceTimer = setTimeout(() => {
this.processDataUpdate(data);
}, 100);
});Memory Management
javascript
// Clean up resources
async onUnload() {
// Clear timers
if (this.updateTimer) {
clearInterval(this.updateTimer);
}
// Close connections
if (this.dbConnection) {
await this.dbConnection.close();
}
// Remove event listeners
this.removeAllHooks();
}Lazy Loading
javascript
// Load heavy components only when needed
async loadHeavyComponent() {
if (!this.heavyComponent) {
const module = await import('./HeavyComponent.js');
this.heavyComponent = new module.default();
}
return this.heavyComponent;
}Deployment and Distribution
Building for Production
bash
# Build plugin
npm run build
# Create distribution package
npm run package
# Validate package
npm run validatePublishing to Marketplace
Prepare Package:
- Ensure manifest is complete
- Include documentation and screenshots
- Test on all supported platforms
Submit for Review:
bashmotanamy publish --marketplaceManage Updates:
- Monitor reviews and feedback
- Release updates as needed
- Communicate changes to users
Troubleshooting
Common Issues
Plugin Won't Load
- Check manifest.json for syntax errors
- Verify all dependencies are installed
- Ensure compatible platform version
Hooks Not Firing
- Confirm hook names are correct
- Check registration timing
- Verify plugin permissions
API Calls Failing
- Check network connectivity
- Verify API endpoints and authentication
- Review error logs for details
Debugging Tools
javascript
// Enable debug mode
this.setDebugMode(true);
// Log detailed information
Logger.setLevel('debug');
// Inspect plugin state
console.log('Plugin state:', this.getState());Resources
Examples
Simple Notification Plugin
javascript
export default class NotificationPlugin extends Plugin {
async onLoad() {
this.registerHook('onUserLogin', this.showWelcomeMessage);
}
showWelcomeMessage(user) {
UI.showNotification(`Welcome back, ${user.name}!`, 'success');
}
}Data Export Plugin
javascript
export default class DataExportPlugin extends Plugin {
async onLoad() {
this.addMenuItem({
title: 'Export Data',
action: () => this.exportData()
});
}
async exportData() {
try {
const data = await API.get('/data/export');
const blob = new Blob([JSON.stringify(data, null, 2)], {
type: 'application/json'
});
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = 'export.json';
a.click();
URL.revokeObjectURL(url);
UI.showNotification('Data exported successfully!');
} catch (error) {
Logger.error('Export failed', error);
UI.showError('Export failed. Please try again.');
}
}
}Developing plugins for Motanamy is a powerful way to extend our platform's capabilities. Follow these guidelines to create high-quality, secure, and user-friendly plugins that enhance the Motanamy experience for all users.