KimuExtensionManager โ
Gestore singleton per il caricamento, la sincronizzazione e la gestione dinamica delle estensioni nel framework KIMU.
Descrizione โ
KimuExtensionManager รจ il cuore del sistema modulare di KIMU. Gestisce tutto il ciclo di vita delle estensioni:
- Inizializzazione: Caricamento manifest e setup IndexedDB
- Sincronizzazione: Allineamento tra manifest JSON e database
- Caricamento dinamico: Import on-demand delle estensioni
- Registry: Tracciamento estensioni caricate e disponibili
Pattern Singleton garantisce una gestione centralizzata e consistente.
Utilizzo โ
Inizializzazione โ
import { KimuExtensionManager } from './core/kimu-extension-manager';
// Ottieni l'istanza singleton
const manager = KimuExtensionManager.getInstance();
// Inizializza il sistema (da chiamare una volta all'avvio)
await manager.init();Caricamento Estensioni โ
// Carica una singola estensione
await manager.load('kimu-home');
// Carica piรน estensioni
const extensions = ['header-component', 'footer-component', 'sidebar'];
for (const ext of extensions) {
await manager.load(ext);
}Gestione Registry โ
// Lista estensioni disponibili
const available = manager.listAvailable();
console.log('Estensioni disponibili:', available.map(e => e.name));
// Verifica se un'estensione รจ caricata
if (manager.isLoaded('my-widget')) {
console.log('Widget giร caricato');
} else {
await manager.load('my-widget');
}
// Ottieni metadata estensione
const meta = manager.get('kimu-home');
console.log(`${meta?.name} v${meta?.version}`);API โ
Metodi Statici โ
getInstance(): KimuExtensionManager โ
Restituisce l'istanza singleton del gestore estensioni.
Ritorna: KimuExtensionManager
Esempio:
const manager = KimuExtensionManager.getInstance();Inizializzazione โ
init(): Promise<void> โ
Inizializza il sistema di estensioni:
- Setup IndexedDB store
- Caricamento manifest iniziale
- Sincronizzazione database/manifest
- Popolazione registry in memoria
Esempio:
const manager = KimuExtensionManager.getInstance();
await manager.init();
console.log('โ
Sistema estensioni inizializzato');Caricamento Dinamico โ
load(tag): Promise<void> โ
Carica dinamicamente un'estensione se non giร caricata.
Parametri:
tag: string- Tag identificativo dell'estensione
Processo:
- Verifica se giร caricata
- Risolve dipendenze
- Import dinamico del modulo
- Registrazione automatica del Web Component
Esempio:
// Caricamento semplice
await manager.load('user-profile');
// Caricamento con gestione errori
try {
await manager.load('advanced-widget');
console.log('Widget caricato con successo');
} catch (error) {
console.error('Errore caricamento widget:', error);
}Registry e Query โ
listAvailable(): KimuExtensionMeta[] โ
Restituisce tutte le estensioni disponibili in memoria.
Ritorna: KimuExtensionMeta[]
Esempio:
const extensions = manager.listAvailable();
extensions.forEach(ext => {
console.log(`๐ฆ ${ext.name} (${ext.tag}) v${ext.version}`);
if (ext.description) {
console.log(` ${ext.description}`);
}
});list(): Promise<KimuExtensionMeta[]> โ
Restituisce tutte le estensioni salvate in IndexedDB.
Ritorna: Promise<KimuExtensionMeta[]>
Esempio:
const stored = await manager.list();
console.log(`๐พ Estensioni in database: ${stored.length}`);get(tag): KimuExtensionMeta | undefined โ
Ottiene i metadata di un'estensione specifica.
Parametri:
tag: string- Tag dell'estensione
Ritorna: KimuExtensionMeta | undefined
Esempio:
const appMeta = manager.get('kimu-home');
if (appMeta) {
console.log(`App principale: ${appMeta.name}`);
console.log(`Versione: ${appMeta.version}`);
console.log(`Autore: ${appMeta.author}`);
}getTags(): string[] โ
Restituisce i tag di tutte le estensioni disponibili.
Ritorna: string[]
Esempio:
const tags = manager.getTags();
console.log('Tag disponibili:', tags.join(', '));isLoaded(tag): boolean โ
Verifica se un'estensione รจ stata caricata.
Parametri:
tag: string- Tag dell'estensione
Ritorna: boolean
Esempio:
if (!manager.isLoaded('optional-feature')) {
// Carica solo se necessario
await manager.load('optional-feature');
}Gestione Manifest โ
reloadManifest(): Promise<void> โ
Ricarica il manifest delle estensioni dal file remoto e aggiorna il database.
Uso tipico: Aggiornamento runtime delle estensioni disponibili
Esempio:
// Aggiornamento periodico
setInterval(async () => {
try {
await manager.reloadManifest();
console.log('๐ Manifest aggiornato');
} catch (error) {
console.warn('Errore aggiornamento manifest:', error);
}
}, 300000); // Ogni 5 minutiStruttura Manifest โ
Il manifest delle estensioni (extensions-manifest.json) definisce le estensioni disponibili:
[
{
"tag": "kimu-home",
"path": "kimu-home",
"internal": true,
"name": "KIMU Home Main App",
"description": "Main interface container",
"version": "1.0.0",
"author": "UnicรฒVerso",
"icon": "๐ ",
"kimuVersion": "1.0.0",
"dependencies": []
},
{
"tag": "user-widget",
"path": "widgets/user-widget",
"name": "User Widget",
"description": "Display user information",
"version": "2.1.0",
"author": "Community",
"icon": "๐ค",
"dependencies": ["base-utils", "icon-library"]
}
]Gestione Dipendenze โ
Il sistema risolve automaticamente le dipendenze:
// Extension A dipende da B e C
{
"tag": "extension-a",
"dependencies": ["extension-b", "extension-c"]
}
// Caricando A, vengono automaticamente caricate B e C
await manager.load('extension-a');
// โ carica extension-b
// โ carica extension-c
// โ carica extension-aEsempi Avanzati โ
Loader di Estensioni Condizionale โ
class ConditionalLoader {
static async loadByFeature(feature: string): Promise<void> {
const manager = KimuExtensionManager.getInstance();
const featureMap = {
'user-management': ['user-profile', 'user-settings', 'user-permissions'],
'data-visualization': ['charts-widget', 'tables-widget', 'graphs-widget'],
'content-editing': ['rich-editor', 'image-uploader', 'file-manager']
};
const extensions = featureMap[feature] || [];
for (const ext of extensions) {
if (!manager.isLoaded(ext)) {
console.log(`๐ Caricamento ${ext} per feature ${feature}`);
await manager.load(ext);
}
}
}
}
// Uso
await ConditionalLoader.loadByFeature('user-management');Dashboard delle Estensioni โ
class ExtensionDashboard {
static async getStatus(): Promise<any> {
const manager = KimuExtensionManager.getInstance();
const available = manager.listAvailable();
return {
total: available.length,
loaded: available.filter(e => manager.isLoaded(e.tag)).length,
internal: available.filter(e => e.internal).length,
byAuthor: this.groupByAuthor(available),
versions: available.map(e => ({ tag: e.tag, version: e.version }))
};
}
private static groupByAuthor(extensions: any[]): Record<string, number> {
return extensions.reduce((acc, ext) => {
const author = ext.author || 'Unknown';
acc[author] = (acc[author] || 0) + 1;
return acc;
}, {});
}
static async printReport(): Promise<void> {
const status = await this.getStatus();
console.log('๐ Rapporto Estensioni:');
console.log(` Totali: ${status.total}`);
console.log(` Caricate: ${status.loaded}`);
console.log(` Interne: ${status.internal}`);
console.log(` Per autore:`, status.byAuthor);
}
}
// Uso
await ExtensionDashboard.printReport();Hot Reload di Estensioni โ
class HotReloader {
private static loadedModules = new Map<string, any>();
static async hotReload(tag: string): Promise<void> {
const manager = KimuExtensionManager.getInstance();
const meta = manager.get(tag);
if (!meta) {
console.warn(`โ Estensione ${tag} non trovata`);
return;
}
try {
// Rimuovi componente esistente
if (customElements.get(tag)) {
console.log(`๐ Hot reload di ${tag}`);
// Ricarica modulo con cache-busting
const modulePath = `/extensions/${meta.path}/component.js?t=${Date.now()}`;
const newModule = await import(/* @vite-ignore */ modulePath);
this.loadedModules.set(tag, newModule);
console.log(`โ
${tag} ricaricato`);
}
} catch (error) {
console.error(`โ Errore hot reload ${tag}:`, error);
}
}
}
// Uso in sviluppo
if (isDevelopment) {
await HotReloader.hotReload('my-component');
}Lazy Loading Intelligente โ
class IntelligentLoader {
private static loadQueue = new Set<string>();
private static loading = new Map<string, Promise<void>>();
static async lazyLoad(tag: string): Promise<void> {
const manager = KimuExtensionManager.getInstance();
// Evita caricamenti duplicati
if (manager.isLoaded(tag) || this.loading.has(tag)) {
return this.loading.get(tag);
}
const loadPromise = this.performLoad(tag);
this.loading.set(tag, loadPromise);
try {
await loadPromise;
} finally {
this.loading.delete(tag);
}
}
private static async performLoad(tag: string): Promise<void> {
const manager = KimuExtensionManager.getInstance();
console.log(`โณ Lazy loading ${tag}...`);
const startTime = performance.now();
await manager.load(tag);
const endTime = performance.now();
console.log(`โก ${tag} caricato in ${(endTime - startTime).toFixed(2)}ms`);
}
static async preloadCritical(): Promise<void> {
const criticalExtensions = ['kimu-home', 'error-handler', 'loading-spinner'];
await Promise.all(
criticalExtensions.map(tag => this.lazyLoad(tag))
);
}
}Best Practices โ
โ Inizializzazione Corretta โ
// All'avvio dell'app
async function initializeApp(): Promise<void> {
const manager = KimuExtensionManager.getInstance();
// 1. Inizializza sistema
await manager.init();
// 2. Carica estensioni
await manager.load('kimu-home');
// 3. Pre-carica estensioni comuni
const common = ['header', 'footer', 'navigation'];
await Promise.all(common.map(tag => manager.load(tag)));
}โ Gestione Errori โ
async function safeLoadExtension(tag: string): Promise<boolean> {
const manager = KimuExtensionManager.getInstance();
try {
await manager.load(tag);
return true;
} catch (error) {
console.error(`Errore caricamento ${tag}:`, error);
// Fallback o retry logic
return false;
}
}โ Performance Monitoring โ
class ExtensionProfiler {
static async profileLoad(tag: string): Promise<void> {
const manager = KimuExtensionManager.getInstance();
const start = performance.now();
await manager.load(tag);
const end = performance.now();
console.log(`โฑ๏ธ ${tag}: ${(end - start).toFixed(2)}ms`);
}
}Vedi Anche โ
- KimuStore - Persistenza IndexedDB
- KimuEngine - Caricamento componenti
- Manifest - Configurazione estensioni
- Creare Estensioni - Guida sviluppo