UNPKG

@dbs-portal/core-module-registry

Version:

Core module registry system for automatic module discovery and registration

257 lines 8.26 kB
/** * Platform-Agnostic Module Loader * * Provides a unified interface for loading platform-specific modules * (Node.js vs Browser) with automatic fallbacks and error handling. */ import { ENV, loadConditionalModule, createLogger } from './environment'; const logger = createLogger('platform-modules'); /** * Load platform-specific path utilities */ export async function loadPath() { return loadConditionalModule( // Node.js version async () => { try { const path = await import('path'); logger.debug('Loaded Node.js path module'); return path; } catch (error) { logger.warn('Failed to load Node.js path module, falling back to browser version'); const browserPath = await import(/* webpackChunkName: "browser-path" */ './browser-path.js'); return browserPath.default; } }, // Browser version async () => { const browserPath = await import(/* webpackChunkName: "browser-path" */ './browser-path.js'); logger.debug('Loaded browser path module'); return browserPath.default; }); } /** * Load platform-specific file system utilities */ export async function loadFs() { return loadConditionalModule( // Node.js version async () => { try { const fs = await import('fs/promises'); logger.debug('Loaded Node.js fs module'); return { ...fs, exists: async (path) => { try { await fs.access(path); return true; } catch { return false; } } }; } catch (error) { logger.warn('Failed to load Node.js fs module, falling back to browser version'); const browserFs = await import(/* webpackChunkName: "browser-fs" */ './browser-fs.js'); return browserFs.default; } }, // Browser version async () => { const browserFs = await import(/* webpackChunkName: "browser-fs" */ './browser-fs.js'); logger.debug('Loaded browser fs module'); return browserFs.default; }); } /** * Load platform-specific glob utilities */ export async function loadGlob() { return loadConditionalModule( // Node.js version async () => { try { const { glob, globSync } = await import('glob'); logger.debug('Loaded Node.js glob module'); return { glob: async (pattern, options = {}) => { if (Array.isArray(pattern)) { const results = await Promise.all(pattern.map(p => glob(p, options))); return results.flat(); } return await glob(pattern, options); }, globSync: (pattern, options = {}) => { if (Array.isArray(pattern)) { return pattern.flatMap(p => globSync(p, options)); } return globSync(pattern, options); } }; } catch (error) { logger.warn('Failed to load Node.js glob module, falling back to browser version'); const browserGlob = await import(/* webpackChunkName: "browser-glob" */ './browser-glob.js'); return browserGlob.default; } }, // Browser version async () => { const browserGlob = await import(/* webpackChunkName: "browser-glob" */ './browser-glob.js'); logger.debug('Loaded browser glob module'); return browserGlob.default; }); } /** * Platform module cache */ class PlatformModuleCache { pathModule = null; fsModule = null; globModule = null; async getPath() { if (!this.pathModule) { this.pathModule = await loadPath(); } return this.pathModule; } async getFs() { if (!this.fsModule) { this.fsModule = await loadFs(); } return this.fsModule; } async getGlob() { if (!this.globModule) { this.globModule = await loadGlob(); } return this.globModule; } clear() { this.pathModule = null; this.fsModule = null; this.globModule = null; } } // Global cache instance const moduleCache = new PlatformModuleCache(); /** * Get cached path utilities */ export const getPath = () => moduleCache.getPath(); /** * Get cached file system utilities */ export const getFs = () => moduleCache.getFs(); /** * Get cached glob utilities */ export const getGlob = () => moduleCache.getGlob(); /** * Clear module cache (useful for testing) */ export const clearModuleCache = () => moduleCache.clear(); /** * Initialize all platform modules */ export async function initializePlatformModules() { logger.info(`Initializing platform modules for ${ENV.isNode ? 'Node.js' : 'browser'} environment`); const [path, fs, glob] = await Promise.all([ getPath(), getFs(), getGlob() ]); logger.info('Platform modules initialized successfully'); return { path, fs, glob }; } /** * Preload browser modules with mock data (for browser usage) */ export async function preloadBrowserModules(mockData) { if (!ENV.isBrowser) { logger.warn('preloadBrowserModules called in non-browser environment'); return; } logger.info('Preloading browser modules with mock data'); try { // Preload file system data if (mockData.files || mockData.directories) { const fs = await getFs(); const browserFs = fs; if (mockData.files && browserFs.preloadFile) { for (const [path, content] of Object.entries(mockData.files)) { browserFs.preloadFile(path, content); } } if (mockData.directories && browserFs.preloadDirectory) { for (const [path, files] of Object.entries(mockData.directories)) { browserFs.preloadDirectory(path, files); } } } // Preload glob data if (mockData.structure) { const glob = await getGlob(); const browserGlob = glob; if (browserGlob.setMockStructure) { browserGlob.setMockStructure(mockData.structure); } } logger.info('Browser modules preloaded successfully'); } catch (error) { logger.error('Failed to preload browser modules:', error); throw error; } } /** * Get platform-specific module information */ export function getPlatformInfo() { return { platform: ENV.isNode ? 'node' : 'browser', canReadFiles: ENV.isNode, canScanDirectories: ENV.isNode, canUseGlob: ENV.isNode, requiresPreloading: ENV.isBrowser, features: { fileSystem: ENV.isNode, glob: ENV.isNode, dynamicImport: true, fetch: true } }; } /** * Create platform-specific error with helpful context */ export function createPlatformError(operation, originalError, suggestions) { const platform = ENV.isNode ? 'Node.js' : 'browser'; const info = getPlatformInfo(); let message = `Platform operation '${operation}' failed in ${platform} environment: ${originalError.message}`; if (suggestions?.length) { message += `\n\nSuggestions:\n${suggestions.map(s => ` - ${s}`).join('\n')}`; } if (!info.canReadFiles && operation.includes('file')) { message += '\n\nNote: File system operations are not available in browser environment. Consider using preloadBrowserModules() to provide mock data.'; } const error = new Error(message); error.name = 'PlatformError'; error.cause = originalError; return error; } export default { getPath, getFs, getGlob, initializePlatformModules, preloadBrowserModules, getPlatformInfo, createPlatformError, clearModuleCache }; //# sourceMappingURL=platform-modules.js.map