UNPKG

muspe-cli

Version:

MusPE Advanced Framework v2.1.3 - Mobile User-friendly Simple Progressive Engine with Enhanced CLI Tools, Specialized E-Commerce Templates, Material Design 3, Progressive Enhancement, Mobile Optimizations, Performance Analysis, and Enterprise-Grade Develo

972 lines (819 loc) 27 kB
// MusPE Core Framework - Advanced Version with UI Components, MVC, Cache & Memory Optimization, SPA Routing import MusPECacheManager from './CacheManager.js'; import MusPEMemoryOptimizer from './MemoryOptimizer.js'; import { MusPEMVCFactory } from './MVC.js'; import { MusPEAdvancedRouter, RouteMiddleware, generateHtaccess } from './router.js'; class MusPECore { constructor() { this.version = '2.1.0'; this.components = new Map(); this.pages = new Map(); this.services = new Map(); this.eventBus = new EventTarget(); this.router = null; this.plugins = null; this.reactivity = null; this.vdom = null; this.compiler = null; this.hooks = null; this.ui = null; // UI Components system this.provided = new Map(); // New optimization systems this.cache = null; this.memoryOptimizer = null; this.mvc = MusPEMVCFactory; this.init(); } init() { this.detectEnvironment(); this.setupGlobalEventListeners(); this.initializeOptimizationSystems(); this.initializeAdvancedSystems(); console.log(`🚀 MusPE Core v${this.version} initialized with enterprise-grade features`); } // Initialize optimization systems first initializeOptimizationSystems() { // Initialize cache manager this.cache = new MusPECacheManager({ maxMemoryUsage: 100 * 1024 * 1024, // 100MB maxCacheSize: 2000, enableCompression: true, enablePerformanceMonitoring: true }); // Initialize memory optimizer this.memoryOptimizer = new MusPEMemoryOptimizer({ enableAutoOptimization: true, memoryThreshold: 0.85, optimizationInterval: 30000, enableLeakDetection: true }); console.log('💾 Cache and Memory Optimization systems initialized'); } // Initialize advanced systems initializeAdvancedSystems() { // Initialize reactivity system this.initializeReactivity(); // Initialize virtual DOM this.initializeVDOM(); // Initialize template compiler this.initializeCompiler(); // Initialize hooks system this.initializeHooks(); // Initialize UI components this.initializeUI(); // Initialize advanced router this.initializeAdvancedRouter(); // Initialize plugin system this.initializePlugins(); // Setup component system integration this.setupComponentIntegration(); // Setup MVC integration this.setupMVCIntegration(); // Setup optimization integration this.setupOptimizationIntegration(); } initializeReactivity() { // Reactivity will be loaded from external file this.reactivity = window.reactivity || null; } initializeVDOM() { // Virtual DOM will be loaded from external file with cache optimization this.vdom = window.vdom || null; // Integrate with cache for VDOM optimization if (this.vdom && this.cache) { this.vdom.setCache = (key, value) => this.cache.set(`vdom_${key}`, value, { ttl: 300000 }); this.vdom.getCache = (key) => this.cache.get(`vdom_${key}`); } } initializeCompiler() { // Template compiler will be loaded from external file with caching this.compiler = window.compiler || null; // Integrate compiler with cache if (this.compiler && this.cache) { this.compiler.setCache = (key, value) => this.cache.set(`template_${key}`, value, { ttl: 600000 }); this.compiler.getCache = (key) => this.cache.get(`template_${key}`); } } initializeHooks() { // Hooks system will be loaded from external file this.hooks = window.hookSystem || null; } initializeUI() { // UI Components system integration this.ui = window.MusPEUI || null; if (this.ui) { // Add global CSS if not already present if (!document.querySelector('link[href*="muspe-ui.css"]') && !document.querySelector('style[data-muspe-ui]')) { this.injectUIStyles(); } // Make UI components globally available if (!window.UI) { window.UI = this.ui; } // Setup UI component integration with reactivity if (this.reactivity && this.ui) { this.setupUIReactivity(); } console.log('🎨 MusPE UI Components initialized'); } } injectUIStyles() { // This would normally load the CSS file // For now, we assume it's already included in the build console.log('📄 MusPE UI styles loaded'); } setupUIReactivity() { // Integrate UI components with reactive system const originalReactive = this.reactivity.reactive; const self = this; this.reactivity.reactive = function(target) { const reactiveObj = originalReactive.call(this, target); // Add UI-specific reactive helpers Object.defineProperty(reactiveObj, '$ui', { value: { button: (options) => new self.ui.Button(options), input: (options) => new self.ui.Input(options), card: (options) => new self.ui.Card(options), modal: (options) => new self.ui.Modal(options), actionSheet: (options) => new self.ui.ActionSheet(options) }, writable: false, enumerable: false, configurable: false }); return reactiveObj; }; } initializeAdvancedRouter() { // Initialize the advanced SPA router with enterprise features if (window.router && window.router instanceof MusPEAdvancedRouter) { this.router = window.router; } else { this.router = new MusPEAdvancedRouter({ mode: 'history', basePath: '', fallback: '/404', enablePrefetch: true, enableLazyLoading: true, enableAnalytics: true, htaccessMode: true, transitionDuration: 300, scrollBehavior: 'top' }); // Make router globally available window.router = this.router; } // Add convenience methods to MusPE core this.route = this.router.route.bind(this.router); this.navigate = this.router.navigate.bind(this.router); this.push = this.router.push.bind(this.router); this.replace = this.router.replace.bind(this.router); this.back = this.router.back.bind(this.router); this.forward = this.router.forward.bind(this.router); this.go = this.router.go.bind(this.router); // Router utilities this.generateHtaccess = generateHtaccess; this.RouteMiddleware = RouteMiddleware; } initializePlugins() { // Plugin system will be loaded from external file this.plugins = window.plugins || null; } setupComponentIntegration() { // Integrate all systems with component lifecycle if (this.hooks && window.MusPEComponent) { // Override component render to use hooks const originalMount = MusPEComponent.prototype.mount; MusPEComponent.prototype.mount = function(container) { // Set current instance for hooks window.hookSystem.setCurrentInstance(this); try { return originalMount.call(this, container); } finally { window.hookSystem.setCurrentInstance(null); } }; const originalUpdate = MusPEComponent.prototype.update; MusPEComponent.prototype.update = function() { // Set current instance for hooks window.hookSystem.setCurrentInstance(this); try { return originalUpdate.call(this); } finally { window.hookSystem.setCurrentInstance(null); } }; } } setupMVCIntegration() { // Integrate MVC with optimization systems if (this.mvc) { // Override MVC factory to include optimization const originalCreateMVC = this.mvc.createMVC; this.mvc.createMVC = (options = {}) => { const mvc = originalCreateMVC(options); // Integrate with memory optimizer if (this.memoryOptimizer) { this.memoryOptimizer.trackComponent(mvc.controller, 'Controller'); this.memoryOptimizer.trackComponent(mvc.view, 'View'); this.memoryOptimizer.trackComponent(mvc.model, 'Model'); } // Integrate with cache if (this.cache && mvc.controller) { mvc.controller.cache = this.cache; } return mvc; }; } } setupOptimizationIntegration() { // Integrate cache and memory optimizer with component lifecycle if (this.cache && this.memoryOptimizer) { // Override component creation to include optimization tracking const originalCreateComponent = this.createComponent.bind(this); this.createComponent = (componentClass, props = {}) => { const component = originalCreateComponent(componentClass, props); // Track component memory const componentId = this.memoryOptimizer.trackComponent(component, componentClass.name); // Override component methods for optimization const originalDestroy = component.destroy; component.destroy = () => { this.memoryOptimizer.cleanupComponent(component); if (originalDestroy) originalDestroy.call(component); }; return component; }; } } detectEnvironment() { this.env = { isMobile: /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent), isTablet: /(tablet|ipad|playbook|silk)|(android(?!.*mobi))/i.test(navigator.userAgent), isIOS: /iPad|iPhone|iPod/.test(navigator.userAgent), isAndroid: /Android/.test(navigator.userAgent), hasTouch: 'ontouchstart' in window || navigator.maxTouchPoints > 0, isOnline: navigator.onLine, isPWA: window.matchMedia('(display-mode: standalone)').matches }; // Add environment classes to body document.body.classList.add(this.env.isMobile ? 'mobile' : 'desktop'); if (this.env.isTablet) document.body.classList.add('tablet'); if (this.env.isIOS) document.body.classList.add('ios'); if (this.env.isAndroid) document.body.classList.add('android'); if (this.env.hasTouch) document.body.classList.add('touch'); if (this.env.isPWA) document.body.classList.add('pwa'); } setupGlobalEventListeners() { // Handle online/offline events window.addEventListener('online', () => { this.env.isOnline = true; this.emit('online'); }); window.addEventListener('offline', () => { this.env.isOnline = false; this.emit('offline'); }); // Prevent zoom on double tap for mobile if (this.env.isMobile) { let lastTouchEnd = 0; document.addEventListener('touchend', (event) => { const now = Date.now(); if (now - lastTouchEnd <= 300) { event.preventDefault(); } lastTouchEnd = now; }, false); } // Handle app state changes document.addEventListener('visibilitychange', () => { if (document.hidden) { this.emit('app:background'); // Trigger memory optimization when app goes to background if (this.memoryOptimizer) { this.memoryOptimizer.triggerOptimization('app_background'); } } else { this.emit('app:foreground'); } }); // Memory pressure handling if (typeof performance !== 'undefined' && performance.memory) { setInterval(() => { const memoryInfo = performance.memory; const usagePercentage = (memoryInfo.usedJSHeapSize / memoryInfo.totalJSHeapSize) * 100; if (usagePercentage > 90) { this.emit('memory:pressure', { usage: usagePercentage }); if (this.memoryOptimizer) { this.memoryOptimizer.triggerOptimization('memory_pressure'); } } }, 30000); // Check every 30 seconds } } initializeRouter() { this.router = new MusPERouter(); } // Component management with advanced features and optimization registerComponent(name, componentClass) { // Cache component class for faster access if (this.cache) { this.cache.set(`component_${name}`, componentClass, { cacheType: 'memory', ttl: 0 // Never expire }); } this.components.set(name, componentClass); // Register with plugin system if available if (this.plugins) { this.plugins.registerGlobalComponent(name, componentClass); } return this; } createComponent(name, options = {}) { // Try to get from cache first let ComponentClass = this.cache ? this.cache.get(`component_${name}`) : null; if (!ComponentClass) { ComponentClass = this.components.get(name); if (!ComponentClass) { throw new Error(`Component '${name}' not found`); } } const component = new ComponentClass(options); // Track component for memory optimization if (this.memoryOptimizer) { this.memoryOptimizer.trackComponent(component, name); } // Set up hooks context if available if (this.hooks) { component.hooks = []; } return component; } // Advanced component creation with composition API defineComponent(options) { if (window.defineComponent) { return window.defineComponent(options); } // Fallback to basic component return class extends MusPEComponent { constructor(props) { super(props); Object.assign(this, options); } }; } // Page management registerPage(name, pageClass) { this.pages.set(name, pageClass); return this; } navigateToPage(name, options = {}) { const PageClass = this.pages.get(name); if (!PageClass) { throw new Error(`Page '${name}' not found`); } return this.router.navigate(name, PageClass, options); } // Service management registerService(name, serviceInstance) { this.services.set(name, serviceInstance); return this; } getService(name) { return this.services.get(name); } // Event system on(event, callback) { this.eventBus.addEventListener(event, callback); return this; } off(event, callback) { this.eventBus.removeEventListener(event, callback); return this; } emit(event, detail = {}) { this.eventBus.dispatchEvent(new CustomEvent(event, { detail })); return this; } // Advanced rendering with Virtual DOM render(vnode, container) { if (this.vdom && window.render) { return window.render(vnode, container); } // Fallback to DOM manipulation if (typeof container === 'string') { container = document.querySelector(container); } if (vnode && vnode.render) { const element = vnode.render(); container.appendChild(element); return element; } return container; } // Create virtual node h(tag, props, ...children) { if (window.h) { return window.h(tag, props, ...children); } // Fallback to simple object return { tag, props, children }; } // Reactive state creation reactive(target) { if (window.reactive) { return window.reactive(target); } // Fallback to plain object return target; } ref(value) { if (window.ref) { return window.ref(value); } // Fallback to simple object return { value }; } computed(getter) { if (window.computed) { return window.computed(getter); } // Fallback to simple getter return { value: getter() }; } // Plugin system integration use(plugin, options) { if (this.plugins) { return this.plugins.install(plugin, options); } console.warn('Plugin system not available'); return this; } // Dependency injection provide(key, value) { this.provided.set(key, value); if (this.plugins) { this.plugins.provide(key, value); } return this; } inject(key, defaultValue) { if (this.provided.has(key)) { return this.provided.get(key); } return defaultValue; } // Utility methods ready(callback) { if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', callback); } else { callback(); } return this; } // Advanced mobile-specific utilities vibrate(pattern) { if ('vibrate' in navigator) { navigator.vibrate(pattern); } return this; } // Screen orientation lockOrientation(orientation) { if (screen.orientation && screen.orientation.lock) { return screen.orientation.lock(orientation); } return Promise.reject(new Error('Screen orientation lock not supported')); } unlockOrientation() { if (screen.orientation && screen.orientation.unlock) { screen.orientation.unlock(); } return this; } // Performance optimization nextTick(callback) { return new Promise(resolve => { setTimeout(() => { if (callback) callback(); resolve(); }, 0); }); } // Error handling errorHandler(error, instance, info) { console.error('MusPE Error:', error); console.error('Instance:', instance); console.error('Info:', info); this.emit('error', { error, instance, info }); } // Performance monitoring measure(name, fn) { const start = performance.now(); const result = fn(); const end = performance.now(); console.log(`${name} took ${end - start} milliseconds`); return result; } // Memory management cleanup() { // Cleanup components this.components.clear(); this.pages.clear(); this.services.clear(); this.provided.clear(); // Cleanup router cache if (this.router && this.router.clearCache) { this.router.clearCache(); } // Cleanup plugins if (this.plugins) { // Plugins handle their own cleanup } // Clear event listeners this.eventBus = new EventTarget(); } // Storage helpers storage = { local: { set: (key, value) => { try { localStorage.setItem(key, JSON.stringify(value)); return true; } catch (e) { console.error('LocalStorage error:', e); return false; } }, get: (key, defaultValue = null) => { try { const value = localStorage.getItem(key); return value ? JSON.parse(value) : defaultValue; } catch (e) { console.error('LocalStorage error:', e); return defaultValue; } }, remove: (key) => { try { localStorage.removeItem(key); return true; } catch (e) { console.error('LocalStorage error:', e); return false; } } }, session: { set: (key, value) => { try { sessionStorage.setItem(key, JSON.stringify(value)); return true; } catch (e) { console.error('SessionStorage error:', e); return false; } }, get: (key, defaultValue = null) => { try { const value = sessionStorage.getItem(key); return value ? JSON.parse(value) : defaultValue; } catch (e) { console.error('SessionStorage error:', e); return defaultValue; } }, remove: (key) => { try { sessionStorage.removeItem(key); return true; } catch (e) { console.error('SessionStorage error:', e); return false; } } } }; } // Simple Router class MusPERouter { constructor() { this.routes = new Map(); this.currentPage = null; this.history = []; this.setupRouting(); } setupRouting() { window.addEventListener('popstate', (event) => { const path = window.location.pathname; this.handleRoute(path, event.state); }); } register(path, pageClass) { this.routes.set(path, pageClass); return this; } navigate(path, pageClass, options = {}) { if (pageClass) { this.routes.set(path, pageClass); } const PageClass = this.routes.get(path); if (!PageClass) { console.error(`Route '${path}' not found`); return false; } // Deactivate current page if (this.currentPage && this.currentPage.deactivate) { this.currentPage.deactivate(); } // Create and activate new page this.currentPage = new PageClass(options); if (this.currentPage.activate) { this.currentPage.activate(); } // Update browser history if (!options.replace) { window.history.pushState(options.state || {}, '', path); } else { window.history.replaceState(options.state || {}, '', path); } this.history.push({ path, timestamp: Date.now(), state: options.state }); return true; } back() { window.history.back(); } forward() { window.history.forward(); } handleRoute(path, state) { const PageClass = this.routes.get(path); if (PageClass) { this.navigate(path, null, { state, replace: true }); } } } // Load advanced systems and utilities if (typeof window !== 'undefined') { // Load core systems first const coreScripts = [ './src/core/reactivity.js', './src/core/vdom.js', './src/core/template.js', './src/core/hooks.js', './src/core/component.js', './src/core/router.js', './src/core/plugins.js' ]; // Load scripts in order coreScripts.forEach((src, index) => { const script = document.createElement('script'); script.src = src; script.async = false; // Ensure order script.onerror = () => { console.warn(`Advanced feature not found: ${src}`); }; document.head.appendChild(script); }); // Load DOM and Fetch utilities const script1 = document.createElement('script'); script1.src = './src/utils/dom.js'; document.head.appendChild(script1); const script2 = document.createElement('script'); script2.src = './src/utils/fetch.js'; document.head.appendChild(script2); // Load Cordova utilities if available const script3 = document.createElement('script'); script3.src = './src/utils/cordova.js'; script3.onerror = () => { console.log('📱 Cordova utilities not found (browser mode)'); }; document.head.appendChild(script3); } // Global instance const MusPE = new MusPECore(); // Extend MusPE with advanced utilities when available if (typeof window !== 'undefined') { // Wait for all scripts to load then initialize setTimeout(() => { // Add DOM utilities to MusPE MusPE.dom = window.MusPEDOM; MusPE.$ = window.$; MusPE.$$ = window.$$; // Add Fetch utilities to MusPE MusPE.http = window.$http; MusPE.fetch = window.fetch; // Add advanced features to MusPE if (window.reactive) { MusPE.reactive = window.reactive; MusPE.ref = window.ref; MusPE.computed = window.computed; MusPE.watch = window.watch; MusPE.effect = window.effect; } if (window.h) { MusPE.h = window.h; MusPE.render = window.render; MusPE.text = window.text; MusPE.fragment = window.fragment; } if (window.defineComponent) { MusPE.defineComponent = window.defineComponent; } if (window.router) { MusPE.router = window.router; MusPE.RouterLink = window.RouterLink; MusPE.RouterView = window.RouterView; } if (window.plugins) { MusPE.plugins = window.plugins; MusPE.use = window.plugins.install.bind(window.plugins); } // Add optimization systems to global MusPE MusPE.cache = MusPE.cache; MusPE.memory = MusPE.memoryOptimizer; MusPE.mvc = MusPE.mvc; // Add convenience methods for optimization MusPE.optimizeMemory = () => MusPE.memoryOptimizer.manualOptimization(); MusPE.clearCache = (type = 'all') => MusPE.cache.clear(type); MusPE.getCacheStats = () => MusPE.cache.getStats(); MusPE.getMemoryStats = () => MusPE.memoryOptimizer.getMemoryStats(); // Add MVC convenience methods MusPE.createMVC = MusPE.mvc.createMVC; MusPE.Model = MusPE.mvc.createModel; MusPE.View = MusPE.mvc.createView; MusPE.Controller = MusPE.mvc.createController; // Emit ready event MusPE.emit('ready', { version: MusPE.version, features: { cache: !!MusPE.cache, memoryOptimization: !!MusPE.memoryOptimizer, mvc: !!MusPE.mvc, reactivity: !!window.reactive, virtualDOM: !!window.h, router: !!window.router, plugins: !!window.plugins } }); // Add hooks to MusPE if (window.useState) { MusPE.useState = window.useState; MusPE.useEffect = window.useEffect; MusPE.useRef = window.useRef; MusPE.useComputed = window.useComputed; MusPE.useWatch = window.useWatch; MusPE.useMemo = window.useMemo; MusPE.useCallback = window.useCallback; MusPE.useReducer = window.useReducer; // Mobile-specific hooks MusPE.useTouch = window.useTouch; MusPE.useSwipe = window.useSwipe; MusPE.useGeolocation = window.useGeolocation; MusPE.useDeviceOrientation = window.useDeviceOrientation; MusPE.useNetworkStatus = window.useNetworkStatus; MusPE.useLocalStorage = window.useLocalStorage; MusPE.useAnimation = window.useAnimation; } // Add router utilities to MusPE if (window.router) { MusPE.router = window.router; MusPE.route = window.router.route?.bind(window.router); MusPE.navigate = window.router.navigate?.bind(window.router); MusPE.push = window.router.push?.bind(window.router); MusPE.replace = window.router.replace?.bind(window.router); MusPE.back = window.router.back?.bind(window.router); MusPE.forward = window.router.forward?.bind(window.router); MusPE.go = window.router.go?.bind(window.router); MusPE.generateHtaccess = window.generateHtaccess; MusPE.RouteMiddleware = window.RouteMiddleware; // Router components MusPE.RouterLink = window.RouterLink; MusPE.RouterView = window.RouterView; } // Add Cordova utilities to MusPE if available if (window.MusPECordova) { MusPE.cordova = window.MusPECordova; console.log('📱 Cordova utilities loaded'); } // Emit ready event for advanced features MusPE.emit('advanced:ready'); console.log('🚀 MusPE Advanced features loaded'); }, 100); } // Export for module usage if (typeof module !== 'undefined' && module.exports) { module.exports = { MusPECore, MusPERouter, MusPE }; } // Make available globally if (typeof window !== 'undefined') { window.MusPE = MusPE; window.MusPECore = MusPECore; window.MusPERouter = MusPERouter; }