npm package: @jamx-framework/plugins
Description: JAMX Framework â€” Plugin system and marketplace
Author: Stiven-21
Latest version: 2.0.0

# @jamx-framework/plugins

## Descripción
Sistema de plugins para JAMX Framework. Proporciona una arquitectura extensible que permite añadir funcionalidades al framework mediante plugins, con registro automático, gestión de dependencias entre plugins, y un marketplace para descubrir e instalar plugins de la comunidad. Los plugins pueden extender el core, añadir adaptadores, comandos CLI, o integraciones con servicios externos.

## Cómo funciona
El sistema de plugins implementa un registro centralizado con dependencias y ciclo de vida:

1. **Plugin Registry**: Registra plugins disponibles y gestiona su orden de carga
2. **Plugin Loader**: Carga plugins desde archivos o paquetes npm
3. **Marketplace**: Catálogo de plugins públicos/privados para descubrimiento
4. **Built-in Plugins**: Plugins incluidos por defecto en JAMX

## Componentes principales
- **src/plugin-registry.ts**: `PluginRegistry` que gestiona registro y orden de plugins
- **src/plugin-loader.ts**: `PluginLoader` que carga plugins desde disco o npm
- **src/marketplace.ts**: `Marketplace` para buscar y descargar plugins
- **src/built-in-plugins.ts**: Lista de plugins incluidos por defecto
- **src/types.ts**: Tipos (`Plugin`, `PluginMeta`, `PluginContext`)
- **src/index.ts**: Punto de exportación

## Uso básico
```typescript
import { PluginRegistry, Plugin } from '@jamx-framework/plugins';

// Crear registry
const registry = new PluginRegistry();

// Definir un plugin
class MyPlugin implements Plugin {
  meta = {
    name: 'my-plugin',
    version: '1.0.0',
    dependencies: ['@jamx-framework/core'],
  };

  async setup(ctx) {
    console.log('Plugin my-plugin inicializado');
    // Registrar servicios, comandos, etc.
  }

  async teardown(ctx) {
    console.log('Plugin my-plugin limpiando');
  }
}

// Registrar y ejecutar
registry.register(new MyPlugin());
await registry.setupAll(ctx);
```

## Ejemplos
### Plugin que añade un comando CLI
```typescript
import { Plugin, PluginContext } from '@jamx-framework/plugins';

class MyCliPlugin implements Plugin {
  meta = {
    name: 'my-cli-plugin',
    version: '1.0.0',
    dependencies: ['@jamx-framework/cli'],
  };

  async setup(ctx: PluginContext) {
    // Registrar comando en CLI
    ctx.cli.registerCommand({
      name: 'my-command',
      description: 'Mi comando personalizado',
      action: async (options) => {
        console.log('Ejecutando mi comando');
      },
    });
  }
}
```

### Plugin con dependencias
```typescript
class AnalyticsPlugin implements Plugin {
  meta = {
    name: 'analytics',
    version: '1.0.0',
    dependencies: [
      '@jamx-framework/core',
      '@jamx-framework/events',
      '@jamx-framework/metrics',
    ],
  };

  async setup(ctx) {
    // Usar servicios de otras dependencias
    const events = ctx.container.resolve('eventBus');
    const metrics = ctx.container.resolve('metrics');
    
    events.on('user.created', (data) => {
      metrics.counter('users_created_total').increment();
    });
  }
}
```

### Plugin que extiende el contenedor
```typescript
class DatabasePlugin implements Plugin {
  meta = {
    name: 'database-extension',
    version: '1.0.0',
    dependencies: ['@jamx-framework/db'],
  };

  async setup(ctx) {
    const { Container } = await import('@jamx-framework/core');
    
    // Registrar servicios adicionales
    Container.registerSingleton('userRepository', () => {
      return new UserRepository(ctx.db);
    });
  }
}
```

### Marketplace: instalar plugin
```bash
# Buscar plugins
jamx plugins:search analytics

# Instalar plugin
jamx plugins:install @jamx-plugin/analytics

# Listar plugins instalados
jamx plugins:list

# Actualizar plugins
jamx plugins:update

# Desinstalar plugin
jamx plugins:uninstall @jamx-plugin/analytics
```

### Configuración de plugins en jamx.config.ts
```typescript
import { defineConfig } from '@jamx-framework/core';

export default defineConfig({
  plugins: [
    '@jamx-plugin/analytics',
    '@jamx-plugin/monitoring',
    // Plugins locales
    './plugins/my-local-plugin.js',
  ],
  
  pluginOptions: {
    analytics: {
      apiKey: process.env.ANALYTICS_KEY,
      endpoint: 'https://analytics.example.com',
    },
    monitoring: {
      enabled: true,
      sampleRate: 0.1,
    },
  },
});
```

## Flujo interno
1. **Discovery**: El `PluginLoader` busca plugins en `node_modules`, directorio local, o registry npm
2. **Loading**: Carga el módulo del plugin (ESM o CommonJS)
3. **Validation**: Verifica que el plugin exporte una clase que implemente `Plugin` interface
4. **Registration**: Añade el plugin a `PluginRegistry`
5. **Dependency resolution**: Ordena plugins según dependencias (topological sort)
6. **Setup**: Ejecuta `setup()` de cada plugin en orden, inyectando `PluginContext`
7. **Teardown**: Al cerrar la app, ejecuta `teardown()` en orden inverso

## API Reference (Resumen)
### Plugin (interface)
```typescript
interface Plugin<TContext extends PluginContext = PluginContext> {
  meta: PluginMeta;
  setup(ctx: TContext): Promise<void> | void;
  teardown?(ctx: TContext): Promise<void> | void;
}
```

### PluginMeta
- `name: string`
- `version: string`
- `description?: string`
- `dependencies?: string[]` (otros plugins o paquetes)
- `peerDependencies?: string[]`
- `optionalDependencies?: string[]`

### PluginContext
- `container: Container`
- `config: Record<string, any>`
- `logger: Logger`
- `cli?: CLI`
- `server?: Server`
- `db?: Database`
- etc. (todos los servicios disponibles)

### PluginRegistry
- `register(plugin: Plugin): this`
- `registerAll(plugins: Plugin[]): this`
- `setupAll(ctx: PluginContext): Promise<void>`
- `teardownAll(ctx: PluginContext): Promise<void>`
- `has(name: string): boolean`
- `list(): Plugin[]`
- `resolveOrder(): Plugin[]` (topological sort)

### PluginLoader
- `loadFromPath(path: string): Promise<Plugin>`
- `loadFromPackage(name: string): Promise<Plugin>`
- `loadAllFromDir(dir: string): Promise<Plugin[]>`

### Marketplace
- `search(query: string): Promise<PluginInfo[]>`
- `install(name: string, version?: string): Promise<void>`
- `uninstall(name: string): Promise<void>`
- `listInstalled(): Promise<InstalledPlugin[]>`
- `update(name?: string): Promise<void>`

## Performance Considerations
- **Lazy loading**: Los plugins se cargan solo cuando se necesitan
- **Dependency caching**: Las dependencias se resuelven una vez y se cachean
- **Parallel setup**: Los plugins sin dependencias cruzadas pueden inicializarse en paralelo
- **Tree-shaking**: Solo se incluyen plugins usados en el build final

## Configuration Options
```typescript
// jamx.config.ts
export default defineConfig({
  plugins: [
    // Plugins desde npm
    '@jamx-plugin/analytics@^2.0.0',
    '@jamx-plugin/cache@latest',
    
    // Plugins locales (desarrollo)
    './plugins/local-plugin.js',
  ],
  
  // Opciones específicas por plugin
  pluginOptions: {
    analytics: {
      apiKey: 'xxx',
      endpoint: 'https://api.example.com',
      sampleRate: 0.1,
    },
    cache: {
      driver: 'redis',
      ttl: 3600,
    },
  },
  
  // Habilitar/deshabilitar plugins
  disabledPlugins: ['@jamx-plugin/experimental'],
});
```

## Testing
Tests en `packages/plugins/tests/unit/`:

```bash
pnpm test
```

Cubre:
- Registro de plugins
- Resolución de dependencias
- Orden de setup/teardown
- Carga desde archivos
- Marketplace (mock)

## Compatibility
- Compatible con Node.js 18+
- Funciona con ESM y CommonJS
- Plugins pueden ser paquetes npm o archivos locales
- Soporta versionado semántico

## CLI Integration
- `jamx plugins:search <query>`: Busca plugins en marketplace
- `jamx plugins:install <name>`: Instala plugin desde npm
- `jamx plugins:list`: Lista plugins instalados
- `jamx plugins:uninstall <name>`: Desinstala plugin
- `jamx plugins:update [name]`: Actualiza plugins
- `jamx plugins:create <name>`: Scaffold de plugin nuevo

## Best Practices
1. **Mantener plugins pequeños**: Un plugin = una funcionalidad
2. **Declarar dependencias**: Especificar `dependencies` en `meta`
3. **Implementar teardown**: Limpiar recursos al desinstalar
4. **Usar context**: Acceder a servicios a través de `ctx.container.resolve()`
5. **Versionado semántico**: Seguir semver para compatibilidad
6. **Documentar**: Incluir README en cada plugin
7. **Testing**: Escribir tests para el plugin

## Publishing Plugins
Para publicar un plugin en el marketplace:

1. Crear paquete npm con `@jamx-plugin/` prefix
2. Exportar clase que implemente `Plugin`
3. Incluir `jamx.plugin.json` con metadatos
4. Publicar en npm: `npm publish --access public`
5. Enviar PR al marketplace para listado

Ejemplo de `jamx.plugin.json`:
```json
{
  "name": "@jamx-plugin/analytics",
  "version": "1.0.0",
  "description": "Analytics plugin for JAMX",
  "author": "Your Name",
  "license": "MIT",
  "keywords": ["jamx", "plugin", "analytics"],
  "jamx": {
    "type": "plugin",
    "entry": "./dist/index.js",
    "dependencies": ["@jamx-framework/core"],
  }
}
```

This plugin system provides a powerful extension mechanism for JAMX Framework, enabling developers to create, share, and consume plugins that enhance the framework's capabilities in a modular, dependency-aware manner.