UNPKG

extension-develop

Version:
804 lines 562 kB
"use strict"; const __rslib_import_meta_url__ = /*#__PURE__*/ function() { return 'undefined' == typeof document ? new (require('url'.replace('', ''))).URL('file:' + __filename).href : document.currentScript && document.currentScript.src || new URL('main.js', document.baseURI).href; }(); var __webpack_modules__ = { "./webpack/plugin-browsers/browsers-lib/add-progress-bar.ts": function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { __webpack_require__.d(__webpack_exports__, { F: ()=>addProgressBar }); const external_progress_namespaceObject = require("progress"); var external_progress_default = /*#__PURE__*/ __webpack_require__.n(external_progress_namespaceObject); function addProgressBar(text, completionCallback) { const contentLength = 131072; const bar = new (external_progress_default())(`${text} [:bar] :percent :etas`, { complete: '=', incomplete: ' ', width: 25, total: contentLength }); const timer = setInterval(()=>{ const chunk = 10 * Math.random() * 1024; bar.tick(chunk); if (bar.complete) { clearInterval(timer); completionCallback(); } }, 50); } }, "./webpack/plugin-browsers/browsers-lib/dynamic-extension-manager.ts": function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { __webpack_require__.d(__webpack_exports__, { f: ()=>DynamicExtensionManager }); var fs_promises__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__("fs/promises"); var fs__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__("fs"); var path__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__("path"); var crypto__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__("crypto"); var _webpack_lib_messages__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__("./webpack/webpack-lib/messages.ts"); function _define_property(obj, key, value) { if (key in obj) Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); else obj[key] = value; return obj; } class DynamicExtensionManager { generateExtensionKey() { const keyData = crypto__WEBPACK_IMPORTED_MODULE_3__.randomBytes(128); return keyData.toString('base64'); } getBaseExtensionPath(browser) { const browserMap = { chrome: 'chrome-manager-extension', edge: 'edge-manager-extension', firefox: 'firefox-manager-extension', 'chromium-based': 'chromium-based-manager-extension', 'gecko-based': 'gecko-based-manager-extension' }; const extensionName = browserMap[browser] || 'chrome-manager-extension'; return path__WEBPACK_IMPORTED_MODULE_2__.join(this.baseExtensionPath, extensionName); } async readBaseManifest(browser) { const basePath = this.getBaseExtensionPath(browser); const manifestPath = path__WEBPACK_IMPORTED_MODULE_2__.join(basePath, 'manifest.json'); const manifestContent = await fs_promises__WEBPACK_IMPORTED_MODULE_0__.readFile(manifestPath, 'utf-8'); return JSON.parse(manifestContent); } async readBaseServiceWorker(browser) { const basePath = this.getBaseExtensionPath(browser); const serviceWorkerPath = path__WEBPACK_IMPORTED_MODULE_2__.join(basePath, 'reload-service.js'); return await fs_promises__WEBPACK_IMPORTED_MODULE_0__.readFile(serviceWorkerPath, 'utf-8'); } async generateExtension(instance) { const extensionId = instance.managerExtensionId; const instanceId = instance.instanceId; const extensionName = "Extension.js DevTools"; const extensionDescription = `Extension.js built-in developer tools for instance ${instanceId.slice(0, 8)}`; const baseManifest = await this.readBaseManifest(instance.browser); const baseServiceWorker = await this.readBaseServiceWorker(instance.browser); const manifest = { ...baseManifest, name: extensionName, description: extensionDescription, key: this.generateExtensionKey() }; const serviceWorkerContent = baseServiceWorker.replace(/const\s+port\s*=\s*['"](__RELOAD_PORT__|\d+)['"]/, `const port = '${instance.webSocketPort}'`).replace(/const\s+instanceId\s*=\s*['"](__INSTANCE_ID__|\w+)['"]/, `const instanceId = '${instance.instanceId}'`); const enhancedServiceWorker = `// Instance: ${instanceId}\n// Generated: ${new Date().toISOString()}\n// Cache-buster: ${Date.now()}\n\n${serviceWorkerContent}\n\n// Instance-specific logging\n${'development' === process.env.EXTENSION_ENV ? `console.log('[Extension.js DevTools] Instance ${instanceId} initialized on port ${instance.webSocketPort}');` : ''}\n`; const extensionPath = path__WEBPACK_IMPORTED_MODULE_2__.join(this.userExtensionsPath, `${instance.browser}-manager-${instance.port}`); await fs_promises__WEBPACK_IMPORTED_MODULE_0__.mkdir(extensionPath, { recursive: true }); const manifestPath = path__WEBPACK_IMPORTED_MODULE_2__.join(extensionPath, 'manifest.json'); const manifestContent = JSON.stringify(manifest, null, 2).replace(/__INSTANCE_ID__/g, instance.instanceId); await fs_promises__WEBPACK_IMPORTED_MODULE_0__.writeFile(manifestPath, manifestContent); const serviceWorkerPath = path__WEBPACK_IMPORTED_MODULE_2__.join(extensionPath, 'reload-service.js'); await fs_promises__WEBPACK_IMPORTED_MODULE_0__.writeFile(serviceWorkerPath, enhancedServiceWorker); await this.copyExtensionFiles(instance.browser, extensionPath); return { extensionId, manifest, serviceWorkerPath, extensionPath }; } async copyExtensionFiles(browser, targetPath) { const basePath = this.getBaseExtensionPath(browser); try { const entries = await fs_promises__WEBPACK_IMPORTED_MODULE_0__.readdir(basePath, { withFileTypes: true }); for (const entry of entries)if (entry.isDirectory() && 'images' === entry.name) { const sourceImagesPath = path__WEBPACK_IMPORTED_MODULE_2__.join(basePath, 'images'); const targetImagesPath = path__WEBPACK_IMPORTED_MODULE_2__.join(targetPath, 'images'); await fs_promises__WEBPACK_IMPORTED_MODULE_0__.mkdir(targetImagesPath, { recursive: true }); const imageEntries = await fs_promises__WEBPACK_IMPORTED_MODULE_0__.readdir(sourceImagesPath, { withFileTypes: true }); for (const imageEntry of imageEntries)if (imageEntry.isFile()) { const sourceImagePath = path__WEBPACK_IMPORTED_MODULE_2__.join(sourceImagesPath, imageEntry.name); const targetImagePath = path__WEBPACK_IMPORTED_MODULE_2__.join(targetImagesPath, imageEntry.name); await fs_promises__WEBPACK_IMPORTED_MODULE_0__.copyFile(sourceImagePath, targetImagePath); } } else if (entry.isDirectory() && 'pages' === entry.name) { const sourcePagesPath = path__WEBPACK_IMPORTED_MODULE_2__.join(basePath, 'pages'); const targetPagesPath = path__WEBPACK_IMPORTED_MODULE_2__.join(targetPath, 'pages'); await fs_promises__WEBPACK_IMPORTED_MODULE_0__.mkdir(targetPagesPath, { recursive: true }); const pageEntries = await fs_promises__WEBPACK_IMPORTED_MODULE_0__.readdir(sourcePagesPath, { withFileTypes: true }); for (const pageEntry of pageEntries)if (pageEntry.isFile()) { const sourcePagePath = path__WEBPACK_IMPORTED_MODULE_2__.join(sourcePagesPath, pageEntry.name); const targetPagePath = path__WEBPACK_IMPORTED_MODULE_2__.join(targetPagesPath, pageEntry.name); await fs_promises__WEBPACK_IMPORTED_MODULE_0__.copyFile(sourcePagePath, targetPagePath); } } else if (entry.isFile() && 'manifest.json' !== entry.name && 'reload-service.js' !== entry.name) { const sourceFilePath = path__WEBPACK_IMPORTED_MODULE_2__.join(basePath, entry.name); const targetFilePath = path__WEBPACK_IMPORTED_MODULE_2__.join(targetPath, entry.name); await fs_promises__WEBPACK_IMPORTED_MODULE_0__.copyFile(sourceFilePath, targetFilePath); } } catch (error) { if ('development' === process.env.EXTENSION_ENV) console.warn(_webpack_lib_messages__WEBPACK_IMPORTED_MODULE_4__.O3(error)); } } async cleanupExtension(instanceId) { const { InstanceManager } = await Promise.resolve().then(__webpack_require__.bind(__webpack_require__, "./webpack/plugin-browsers/browsers-lib/instance-manager.ts")); const instanceManager = new InstanceManager(this.projectPath); const instance = await instanceManager.getInstance(instanceId); if (!instance) { if ('development' === process.env.EXTENSION_ENV) console.warn(_webpack_lib_messages__WEBPACK_IMPORTED_MODULE_4__.ej(instanceId)); return; } const extensionPath = path__WEBPACK_IMPORTED_MODULE_2__.join(this.userExtensionsPath, `${instance.browser}-manager-${instance.port}`); try { await fs_promises__WEBPACK_IMPORTED_MODULE_0__.rm(extensionPath, { recursive: true, force: true }); } catch (error) { if ('development' === process.env.EXTENSION_ENV) console.warn(`Warning: Could not cleanup extension for ${instance.browser}-manager-${instance.port}: ${error}`); } } async cleanupAllExtensions() { try { await fs_promises__WEBPACK_IMPORTED_MODULE_0__.rm(this.userExtensionsPath, { recursive: true, force: true }); } catch (error) { if ('development' === process.env.EXTENSION_ENV) console.warn(_webpack_lib_messages__WEBPACK_IMPORTED_MODULE_4__.rH(error)); } } getExtensionPath(instanceId) { return path__WEBPACK_IMPORTED_MODULE_2__.join(this.userExtensionsPath, `manager-port-${instanceId}`); } async extensionExists(instanceId) { const { InstanceManager } = await Promise.resolve().then(__webpack_require__.bind(__webpack_require__, "./webpack/plugin-browsers/browsers-lib/instance-manager.ts")); const instanceManager = new InstanceManager(this.projectPath); const instance = await instanceManager.getInstance(instanceId); if (!instance) return false; const extensionPath = path__WEBPACK_IMPORTED_MODULE_2__.join(this.userExtensionsPath, `${instance.browser}-manager-${instance.port}`); try { await fs_promises__WEBPACK_IMPORTED_MODULE_0__.access(extensionPath); return true; } catch { return false; } } async regenerateExtensionIfNeeded(instance) { const exists = await this.extensionExists(instance.instanceId); if (!exists) return await this.generateExtension(instance); const extensionPath = this.getExtensionPath(instance.instanceId); const serviceWorkerPath = path__WEBPACK_IMPORTED_MODULE_2__.join(extensionPath, 'reload-service.js'); try { const content = await fs_promises__WEBPACK_IMPORTED_MODULE_0__.readFile(serviceWorkerPath, 'utf-8'); const portMatch = content.match(/const\s+port\s*=\s*['"](\d+)['"]/); if (portMatch && parseInt(portMatch[1]) !== instance.webSocketPort) { await this.cleanupExtension(instance.instanceId); return await this.generateExtension(instance); } } catch (error) { await this.cleanupExtension(instance.instanceId); return await this.generateExtension(instance); } const manifest = await this.readBaseManifest(instance.browser); return { extensionId: instance.managerExtensionId, manifest, serviceWorkerPath: path__WEBPACK_IMPORTED_MODULE_2__.join(extensionPath, 'reload-service.js'), extensionPath }; } constructor(projectPath){ _define_property(this, "baseExtensionPath", void 0); _define_property(this, "projectPath", void 0); _define_property(this, "userExtensionsPath", void 0); const candidateBasePaths = []; try { const entryPath = require.resolve('extension-develop'); const distDir = path__WEBPACK_IMPORTED_MODULE_2__.dirname(entryPath); candidateBasePaths.push(path__WEBPACK_IMPORTED_MODULE_2__.join(distDir, 'extensions')); } catch {} candidateBasePaths.push(path__WEBPACK_IMPORTED_MODULE_2__.join(__dirname, 'extensions')); candidateBasePaths.push(path__WEBPACK_IMPORTED_MODULE_2__.join(__dirname, 'dist', 'extensions')); candidateBasePaths.push(path__WEBPACK_IMPORTED_MODULE_2__.join(__dirname, 'programs', 'develop', 'dist', 'extensions')); candidateBasePaths.push(path__WEBPACK_IMPORTED_MODULE_2__.join(process.cwd(), 'node_modules', 'extension-develop', 'dist', 'extensions')); candidateBasePaths.push(path__WEBPACK_IMPORTED_MODULE_2__.join(__dirname, '..', '..', 'plugin-reload', 'extensions')); let resolvedBasePath = candidateBasePaths[0]; for (const candidate of candidateBasePaths)try { if (fs__WEBPACK_IMPORTED_MODULE_1__.existsSync(candidate)) { resolvedBasePath = candidate; break; } } catch {} this.baseExtensionPath = resolvedBasePath; this.projectPath = projectPath || process.cwd(); this.userExtensionsPath = path__WEBPACK_IMPORTED_MODULE_2__.join(this.projectPath, 'dist', 'extension-js', 'extensions'); } } }, "./webpack/plugin-browsers/browsers-lib/instance-manager.ts": function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { __webpack_require__.d(__webpack_exports__, { InstanceManager: ()=>InstanceManager }); var fs_promises__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__("fs/promises"); var path__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__("path"); var os__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__("os"); var crypto__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__("crypto"); var net__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__("net"); var _webpack_webpack_lib_messages__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__("./webpack/webpack-lib/messages.ts"); function _define_property(obj, key, value) { if (key in obj) Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); else obj[key] = value; return obj; } class InstanceManager { getDataDirectory() { const platform = process.platform; const isWSL = process.env.WSL_DISTRO_NAME || process.env.WSLENV; switch(platform){ case 'darwin': return path__WEBPACK_IMPORTED_MODULE_1__.join(os__WEBPACK_IMPORTED_MODULE_2__.homedir(), 'Library', 'Application Support', 'extension-js'); case 'win32': return path__WEBPACK_IMPORTED_MODULE_1__.join(process.env.APPDATA || '', 'extension-js'); case 'linux': if (isWSL) { const windowsAppData = process.env.APPDATA; if (windowsAppData) return path__WEBPACK_IMPORTED_MODULE_1__.join(windowsAppData, 'extension-js'); } return path__WEBPACK_IMPORTED_MODULE_1__.join(os__WEBPACK_IMPORTED_MODULE_2__.homedir(), '.config', 'extension-js'); default: return path__WEBPACK_IMPORTED_MODULE_1__.join(os__WEBPACK_IMPORTED_MODULE_2__.homedir(), '.extension-js'); } } generateInstanceId() { return crypto__WEBPACK_IMPORTED_MODULE_3__.randomBytes(8).toString('hex'); } generateManagerExtensionId() { const chars = 'abcdefghijklmnopqrstuvwxyz'; let result = ''; for(let i = 0; i < 32; i++)result += chars.charAt(Math.floor(Math.random() * chars.length)); return result; } async ensureRegistryDir() { const dir = path__WEBPACK_IMPORTED_MODULE_1__.dirname(this.registryPath); try { await fs_promises__WEBPACK_IMPORTED_MODULE_0__.access(dir); } catch { await fs_promises__WEBPACK_IMPORTED_MODULE_0__.mkdir(dir, { recursive: true }); } } async loadRegistry() { try { await this.ensureRegistryDir(); const data = await fs_promises__WEBPACK_IMPORTED_MODULE_0__.readFile(this.registryPath, 'utf-8'); return JSON.parse(data); } catch { return { instances: {}, lastCleanup: Date.now() }; } } async saveRegistry(registry) { try { await this.ensureRegistryDir(); const data = JSON.stringify(registry, null, 2); await fs_promises__WEBPACK_IMPORTED_MODULE_0__.writeFile(this.registryPath, data); if ('development' === process.env.EXTENSION_ENV) console.log(_webpack_webpack_lib_messages__WEBPACK_IMPORTED_MODULE_5__.xc(this.registryPath)); } catch (error) { if ('development' === process.env.EXTENSION_ENV) console.error(_webpack_webpack_lib_messages__WEBPACK_IMPORTED_MODULE_5__.b9(error)); throw error; } } async isPortAvailable(port) { const check = (host)=>new Promise((resolve)=>{ const server = net__WEBPACK_IMPORTED_MODULE_4__.createServer(); const complete = (result)=>{ try { server.close(()=>resolve(result)); } catch { resolve(result); } }; server.once('error', (err)=>resolve({ available: false, errorCode: err.code })); server.once('listening', ()=>complete({ available: true })); try { server.listen(port, host); } catch (err) { resolve({ available: false, errorCode: null == err ? void 0 : err.code }); } }); const [v6, v4] = await Promise.all([ check('::1'), check('127.0.0.1') ]); const ipv6Unsupported = 'EADDRNOTAVAIL' === v6.errorCode || 'ENETUNREACH' === v6.errorCode || 'EINVAL' === v6.errorCode || void 0 === v6.errorCode; if (ipv6Unsupported) return v4.available; return v4.available && v6.available; } async allocateSmartPorts(requestedPort) { const registry = await this.loadRegistry(); await this.cleanupTerminatedInstances(registry); const cleanRegistry = await this.loadRegistry(); const existingInstances = Object.values(cleanRegistry.instances); const usedPorts = existingInstances.filter((instance)=>'running' === instance.status).map((instance)=>instance.port); const usedWebSocketPorts = existingInstances.filter((instance)=>'running' === instance.status).map((instance)=>instance.webSocketPort); if ('development' === process.env.EXTENSION_ENV) { console.log(_webpack_webpack_lib_messages__WEBPACK_IMPORTED_MODULE_5__.EP(usedPorts)); console.log(_webpack_webpack_lib_messages__WEBPACK_IMPORTED_MODULE_5__.Hh(usedWebSocketPorts)); } if (requestedPort) { const isPortAvailable = await this.isPortAvailable(requestedPort); if (isPortAvailable && !usedPorts.includes(requestedPort)) { const webSocketPort = await this.findAvailableWebSocketPort(usedWebSocketPorts); if ('development' === process.env.EXTENSION_ENV) console.log(_webpack_webpack_lib_messages__WEBPACK_IMPORTED_MODULE_5__.G(requestedPort, webSocketPort)); return { port: requestedPort, webSocketPort }; } if ('development' === process.env.EXTENSION_ENV) console.log(_webpack_webpack_lib_messages__WEBPACK_IMPORTED_MODULE_5__.S8(requestedPort)); } let port = this.basePort; while(usedPorts.includes(port) || !await this.isPortAvailable(port))port++; const webSocketPort = await this.findAvailableWebSocketPort(usedWebSocketPorts); if ('development' === process.env.EXTENSION_ENV) console.log(_webpack_webpack_lib_messages__WEBPACK_IMPORTED_MODULE_5__._Z(port, webSocketPort)); return { port, webSocketPort }; } async findAvailableWebSocketPort(usedWebSocketPorts) { let webSocketPort = this.baseWebSocketPort; while(usedWebSocketPorts.includes(webSocketPort) || !await this.isPortAvailable(webSocketPort))webSocketPort++; return webSocketPort; } async cleanupTerminatedInstances(registry) { const now = Date.now(); const maxAge = 86400000; const instancesToRemove = []; for (const [instanceId, instance] of Object.entries(registry.instances)){ let shouldRemove = false; if ('terminated' === instance.status || 'error' === instance.status || now - instance.startTime > maxAge) shouldRemove = true; else if (await this.isProcessRunning(instance.processId)) { if (await this.isPortAvailable(instance.port) && await this.isPortAvailable(instance.webSocketPort)) { if ('development' === process.env.EXTENSION_ENV) console.log(_webpack_webpack_lib_messages__WEBPACK_IMPORTED_MODULE_5__.Y_(instanceId, instance.port, instance.webSocketPort)); shouldRemove = true; } } else { if ('development' === process.env.EXTENSION_ENV) console.log(_webpack_webpack_lib_messages__WEBPACK_IMPORTED_MODULE_5__.jQ(instanceId, instance.processId)); shouldRemove = true; } if (shouldRemove) instancesToRemove.push(instanceId); } for (const instanceId of instancesToRemove){ delete registry.instances[instanceId]; if ('development' === process.env.EXTENSION_ENV) console.log(_webpack_webpack_lib_messages__WEBPACK_IMPORTED_MODULE_5__.Hl(instanceId)); } registry.lastCleanup = now; } async isProcessRunning(pid) { try { process.kill(pid, 0); return true; } catch (error) { return 'ESRCH' !== error.code; } } async monitorProcessHealth(instanceId) { const instance = await this.getInstance(instanceId); if (!instance) return; if ('development' === process.env.EXTENSION_ENV) console.log(_webpack_webpack_lib_messages__WEBPACK_IMPORTED_MODULE_5__.oN(instanceId)); const healthCheck = setInterval(async ()=>{ try { const isHealthy = await this.isProcessRunning(instance.processId); const portsInUse = await this.arePortsInUse(instance.port, instance.webSocketPort); const isCurrentProcess = instance.processId === process.pid; const definitelyOrphaned = !isCurrentProcess && !isHealthy && !portsInUse; if (definitelyOrphaned) { console.log(_webpack_webpack_lib_messages__WEBPACK_IMPORTED_MODULE_5__.zd(instanceId)); await this.terminateInstance(instanceId); clearInterval(healthCheck); this.healthChecks.delete(instanceId); } else if ('development' === process.env.EXTENSION_ENV) console.log(_webpack_webpack_lib_messages__WEBPACK_IMPORTED_MODULE_5__.IV(instanceId)); } catch (error) { console.error(_webpack_webpack_lib_messages__WEBPACK_IMPORTED_MODULE_5__.Es(instanceId, error)); clearInterval(healthCheck); this.healthChecks.delete(instanceId); } }, 30000); this.healthChecks.set(instanceId, healthCheck); } async arePortsInUse(port, webSocketPort) { const portInUse = !await this.isPortAvailable(port); const webSocketPortInUse = !await this.isPortAvailable(webSocketPort); return portInUse || webSocketPortInUse; } async forceCleanupProjectProcesses(projectPath) { if ('development' === process.env.EXTENSION_ENV) console.log(_webpack_webpack_lib_messages__WEBPACK_IMPORTED_MODULE_5__.r6(projectPath)); const registry = await this.loadRegistry(); const projectInstances = Object.values(registry.instances).filter((instance)=>instance.projectPath === projectPath); if ('development' === process.env.EXTENSION_ENV) console.log(_webpack_webpack_lib_messages__WEBPACK_IMPORTED_MODULE_5__.dQ(projectInstances.length)); for (const instance of projectInstances)try { if ('development' === process.env.EXTENSION_ENV) console.log(_webpack_webpack_lib_messages__WEBPACK_IMPORTED_MODULE_5__.j4(instance.instanceId)); if (await this.isProcessRunning(instance.processId)) { if ('development' === process.env.EXTENSION_ENV) console.log(_webpack_webpack_lib_messages__WEBPACK_IMPORTED_MODULE_5__.qb(instance.processId)); process.kill(instance.processId, 'SIGTERM'); setTimeout(()=>{ try { process.kill(instance.processId, 'SIGKILL'); if ('development' === process.env.EXTENSION_ENV) console.log(_webpack_webpack_lib_messages__WEBPACK_IMPORTED_MODULE_5__.o2(instance.processId)); } catch (error) {} }, 3000); } instance.status = 'terminated'; if ('development' === process.env.EXTENSION_ENV) console.log(_webpack_webpack_lib_messages__WEBPACK_IMPORTED_MODULE_5__.J9(instance.instanceId)); } catch (error) { if ('development' === process.env.EXTENSION_ENV) console.error(_webpack_webpack_lib_messages__WEBPACK_IMPORTED_MODULE_5__.Wc(instance.instanceId, error)); } await this.saveRegistry(registry); if ('development' === process.env.EXTENSION_ENV) console.log(_webpack_webpack_lib_messages__WEBPACK_IMPORTED_MODULE_5__.JJ()); } async createInstance(browser, projectPath, requestedPort) { if ('development' === process.env.EXTENSION_ENV) console.log(_webpack_webpack_lib_messages__WEBPACK_IMPORTED_MODULE_5__.jE({ browser, projectPath, requestedPort })); const registry = await this.loadRegistry(); if (Date.now() - registry.lastCleanup > this.cleanupInterval) await this.cleanupTerminatedInstances(registry); const instanceId = this.generateInstanceId(); const managerExtensionId = this.generateManagerExtensionId(); const { port, webSocketPort } = await this.allocateSmartPorts(requestedPort); const instance = { instanceId, browser, projectPath, port, webSocketPort, managerExtensionId, startTime: Date.now(), status: 'running', processId: process.pid, profilePath: path__WEBPACK_IMPORTED_MODULE_1__.join(os__WEBPACK_IMPORTED_MODULE_2__.tmpdir(), `extension-js-${instanceId}`) }; registry.instances[instanceId] = instance; await this.saveRegistry(registry); await this.monitorProcessHealth(instanceId); if ('development' === process.env.EXTENSION_ENV) console.log(_webpack_webpack_lib_messages__WEBPACK_IMPORTED_MODULE_5__.pU(registry)); return instance; } async updateInstance(instanceId, updates) { const registry = await this.loadRegistry(); if (registry.instances[instanceId]) { registry.instances[instanceId] = { ...registry.instances[instanceId], ...updates }; await this.saveRegistry(registry); } } async terminateInstance(instanceId) { const registry = await this.loadRegistry(); if (registry.instances[instanceId]) { registry.instances[instanceId].status = 'terminated'; await this.saveRegistry(registry); const healthCheck = this.healthChecks.get(instanceId); if (healthCheck) { clearInterval(healthCheck); this.healthChecks.delete(instanceId); } } } async getRunningInstances() { const registry = await this.loadRegistry(); return Object.values(registry.instances).filter((instance)=>'running' === instance.status); } async getInstance(instanceId) { const registry = await this.loadRegistry(); return registry.instances[instanceId] || null; } async isInstanceRunning(instanceId) { const instance = await this.getInstance(instanceId); if (!instance) return false; try { process.kill(instance.processId, 0); return 'running' === instance.status; } catch { await this.terminateInstance(instanceId); return false; } } async getInstanceByPort(port) { const instances = await this.getRunningInstances(); return instances.find((instance)=>instance.port === port) || null; } async getInstanceByWebSocketPort(webSocketPort) { const instances = await this.getRunningInstances(); return instances.find((instance)=>instance.webSocketPort === webSocketPort) || null; } async cleanupAllInstances() { const registry = await this.loadRegistry(); registry.instances = {}; registry.lastCleanup = Date.now(); await this.saveRegistry(registry); for (const healthCheck of this.healthChecks.values())clearInterval(healthCheck); this.healthChecks.clear(); } async forceCleanupOrphanedInstances() { const registry = await this.loadRegistry(); await this.cleanupTerminatedInstances(registry); await this.saveRegistry(registry); } async getStats() { const registry = await this.loadRegistry(); const instances = Object.values(registry.instances); return { total: instances.length, running: instances.filter((i)=>'running' === i.status).length, terminated: instances.filter((i)=>'terminated' === i.status).length, error: instances.filter((i)=>'error' === i.status).length }; } constructor(projectPath, basePort = 8080, baseWebSocketPort = 9000){ _define_property(this, "registryPath", void 0); _define_property(this, "basePort", void 0); _define_property(this, "baseWebSocketPort", void 0); _define_property(this, "cleanupInterval", 300000); _define_property(this, "healthChecks", new Map()); this.basePort = basePort; this.baseWebSocketPort = baseWebSocketPort; this.registryPath = path__WEBPACK_IMPORTED_MODULE_1__.join(this.getDataDirectory(), 'instances.json'); } } }, "./webpack/plugin-browsers/browsers-lib/messages.ts": function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { __webpack_require__.d(__webpack_exports__, { $O: ()=>cdpClientFoundTargets, $W: ()=>enhancedProcessManagementInstanceCleanup, A4: ()=>sourceInspectorCDPConnectionMaintained, AB: ()=>cdpClientMainHTMLLength, Ac: ()=>sourceInspectorEnsuringNavigation, Ak: ()=>sourceInspectorWaitingForContentScripts, BK: ()=>sourceInspectorReconnectedToTarget, Bq: ()=>cdpClientPageLoadEventFired, CP: ()=>chromeProcessExited, Cn: ()=>sourceInspectorHtmlExtractFailed, DF: ()=>requestWithoutTargetActorError, DQ: ()=>sourceInspectorCannotReconnect, Do: ()=>sourceInspectorNoTabActorAvailable, ET: ()=>sourceInspectorFileChanged, El: ()=>firefoxFailedToStart, F0: ()=>sourceInspectorUsingExistingTarget, G9: ()=>sourceInspectorStartingWatchMode, GB: ()=>cdpClientExtensionReloadFailed, GR: ()=>sourceInspectorAttachedToTarget, HM: ()=>enhancedProcessManagementUnhandledRejection, Hb: ()=>pathPermissionError, Hd: ()=>sourceInspectorHTMLOutputTitle, IM: ()=>firefoxRdpClientLoadEventTimeout, Io: ()=>enhancedProcessManagementCleanup, L7: ()=>sourceInspectorInspectionFailed, LX: ()=>cdpClientFailedToGetMainHTML, Lf: ()=>sourceInspectorAttemptingReconnection, Lh: ()=>chromeInitializingEnhancedReload, Li: ()=>sourceInspectorWatchModeActive, Mm: ()=>chromeFailedToSpawn, Mz: ()=>firefoxRdpClientFailedToGetMainHTML, NA: ()=>addonInstallError, N_: ()=>sourceInspectorTargetCreated, OL: ()=>cdpClientProcessingShadowDOM, Q: ()=>browserLaunchError, QB: ()=>sourceInspectorHTMLUpdateFailed, Qb: ()=>messagingClientClosedError, Qe: ()=>sourceInspectorInitialized, Qz: ()=>targetActorHasActiveRequestError, R1: ()=>cdpClientExtensionUnloadFailed, Rl: ()=>sourceInspectorChromeDebuggingRequired, Ro: ()=>sourceInspectorWaitingForChrome, S5: ()=>sourceInspectorCleanupComplete, S6: ()=>sourceInspectorReconnectingToTarget, Sj: ()=>cdpClientMessageParseError, Tq: ()=>sourceInspectorWaitingForContentScriptReinjection, Tz: ()=>sourceInspectorFindingExistingTarget, V9: ()=>sourceInspectorFirefoxDebuggingRequired, VF: ()=>firefoxServiceWorkerError, VZ: ()=>chromeRemoteDebuggingReady, Vg: ()=>firefoxLaunchCalled, W: ()=>cdpClientExtensionInfoFailed, W3: ()=>enhancedProcessManagementForceKill, WA: ()=>enhancedProcessManagementUncaughtException, Wv: ()=>cdpClientShadowDOMContentFound, X: ()=>cdpClientFinalHTMLWithShadowDOMLength, XO: ()=>connectionClosedError, X_: ()=>sourceInspectorFirefoxNotReadyYet, Xo: ()=>enhancedProcessManagementCleanupError, Xy: ()=>firefoxRemoteDebuggingReady, YM: ()=>stdoutData, YT: ()=>browserInstanceExited, Ym: ()=>sourceInspectorUrlRequired, Yw: ()=>sourceInspectorChromeNotReadyYet, ZM: ()=>firefoxBinaryArgsExtracted, Zk: ()=>sourceInspectorOpeningUrl, _A: ()=>enhancedProcessManagementTerminating, _C: ()=>cdpClientCheckingShadowDOM, _i: ()=>firefoxDetectionFailed, _u: ()=>cdpClientBrowserConnectionEstablished, _y: ()=>sourceInspectorWaitingForPageLoad, aW: ()=>sourceInspectorWatchModeStopped, bw: ()=>cdpClientConnected, c0: ()=>creatingUserProfile, c9: ()=>sourceInspectorInvalidWebSocketServer, cx: ()=>cdpClientLoadEventTimeout, dG: ()=>messageWithoutSenderError, dI: ()=>sourceInspectorHTMLOutputHeader, dX: ()=>sourceInspectorInitializationFailed, dz: ()=>cdpClientTargetWebSocketUrlStored, eK: ()=>cdpClientDocumentTitle, fp: ()=>cdpClientConnectionClosed, g0: ()=>parsingPacketError, gD: ()=>firefoxRdpClientConnected, hm: ()=>sourceInspectorWillInspect, hx: ()=>profileCreationError, iv: ()=>browserNotInstalledError, l: ()=>sourceInspectorWaitingForFirefox, ln: ()=>sourceInspectorNoActiveSession, mO: ()=>sourceInspectorNotInitialized, mf: ()=>cdpClientReturningMainHTML, n4: ()=>cdpClientExtensionLoadFailed, ng: ()=>generalBrowserError, o8: ()=>emptyLine, oP: ()=>sourceInspectorCleanupError, ov: ()=>sourceInspectorReExtractingHTML, ph: ()=>cdpClientGettingMainHTML, pl: ()=>sourceInspectorClientNotInitialized, q5: ()=>pathIsNotDirectoryError, qP: ()=>sourceInspectorNoTabTargetFound, qX: ()=>sourceInspectorHTMLOutputFooter, ql: ()=>cdpClientTestingEvaluation, qo: ()=>cdpClientShadowDOMContentLength, rV: ()=>firefoxRdpClientTestingEvaluation, re: ()=>cdpClientConnectionError, s: ()=>firefoxNoBinaryArgsFound, sC: ()=>chromeProcessError, si: ()=>errorConnectingToBrowser, tX: ()=>sourceInspectorAttachingToTarget, tg: ()=>sourceInspectorHTMLExtractionComplete, uc: ()=>enhancedProcessManagementInstanceCleanupComplete, v5: ()=>sourceInspectorCreatingTarget, w4: ()=>sourceInspectorReconnectionFailed, xQ: ()=>runningInDevelopment, xR: ()=>sourceInspectorEnablingPageDomain, y4: ()=>sourceInspectorSetupFailed, z6: ()=>firefoxRdpClientPageLoadEventFired }); var pintor__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__("pintor"); var pintor__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/ __webpack_require__.n(pintor__WEBPACK_IMPORTED_MODULE_0__); function getLoggingPrefix(type) { if ('error' === type) return pintor__WEBPACK_IMPORTED_MODULE_0___default().red('ERROR'); if ('warn' === type) return pintor__WEBPACK_IMPORTED_MODULE_0___default().brightYellow("\u25BA\u25BA\u25BA"); if ('info' === type) return pintor__WEBPACK_IMPORTED_MODULE_0___default().blue("\u25BA\u25BA\u25BA"); return pintor__WEBPACK_IMPORTED_MODULE_0___default().green("\u25BA\u25BA\u25BA"); } function capitalizedBrowserName(browser) { return `${browser.charAt(0).toUpperCase() + browser.slice(1)}`; } function creatingUserProfile(browser) { const browsername = capitalizedBrowserName(browser); return `${getLoggingPrefix('info')} Creating new user profile for ${browsername}...`; } function browserInstanceExited(browser) { return `${getLoggingPrefix('info')} ${capitalizedBrowserName(browser)} instance exited.`; } function stdoutData(browser, mode) { const extensionOutput = 'firefox' === browser || 'gecko-based' === browser ? 'Add-on' : 'Extension'; return `${getLoggingPrefix('info')} ${capitalizedBrowserName(browser)} ${extensionOutput} running in ${mode || 'unknown'} mode.`; } function browserNotInstalledError(browser, browserBinaryLocation) { const isUnreachable = 'null' == browserBinaryLocation ? `Browser ${capitalizedBrowserName(browser)} is not installed\n` : `Can't find the path for browser ${capitalizedBrowserName(browser)}\n`; return `${getLoggingPrefix('error')} ${isUnreachable}Either install the missing browser or choose a different one via ${pintor__WEBPACK_IMPORTED_MODULE_0___default().blue('--browser')} ${pintor__WEBPACK_IMPORTED_MODULE_0___default().gray('<chrome|edge|firefox>')}.\n${pintor__WEBPACK_IMPORTED_MODULE_0___default().red('NOT FOUND')} ${pintor__WEBPACK_IMPORTED_MODULE_0___default().underline(browserBinaryLocation || capitalizedBrowserName(browser) + 'BROWSER')}`; } function firefoxServiceWorkerError(browser) { return `${getLoggingPrefix('error')} No Service Worker Support for ${capitalizedBrowserName(browser)}\nFirefox does not support the ${pintor__WEBPACK_IMPORTED_MODULE_0___default().yellow('background.service_worker')} field yet.\nUpdate your ${pintor__WEBPACK_IMPORTED_MODULE_0___default().yellow('manifest.json')} file to use ${pintor__WEBPACK_IMPORTED_MODULE_0___default().yellow("background.scripts")} instead.\nRead more: ${pintor__WEBPACK_IMPORTED_MODULE_0___default().underline('https://bugzilla.mozilla.org/show_bug.cgi?id=1573659')}.`; } function browserLaunchError(browser, error) { return `${getLoggingPrefix('error')} Error launching ${capitalizedBrowserName(browser)}:\n${pintor__WEBPACK_IMPORTED_MODULE_0___default().red(String(error))}`; } function enhancedProcessManagementCleanup(browser) { return `${getLoggingPrefix('info')} Process Management cleanup for ${capitalizedBrowserName(browser)}`; } function enhancedProcessManagementTerminating(browser) { return `${getLoggingPrefix('info')} Terminating ${capitalizedBrowserName(browser)} process gracefully`; } function enhancedProcessManagementForceKill(browser) { return `${getLoggingPrefix('error')} Force killing ${capitalizedBrowserName(browser)} process after timeout`; } function enhancedProcessManagementCleanupError(browser, error) { return `${getLoggingPrefix('error')} Error during ${capitalizedBrowserName(browser)} cleanup:\n${pintor__WEBPACK_IMPORTED_MODULE_0___default().red(String(error))}`; } function enhancedProcessManagementInstanceCleanup(browser) { return `${getLoggingPrefix('info')} Cleaning up ${capitalizedBrowserName(browser)} instance`; } function enhancedProcessManagementInstanceCleanupComplete(browser) { return `${getLoggingPrefix('success')} ${capitalizedBrowserName(browser)} instance cleanup completed`; } function enhancedProcessManagementUncaughtException(browser, error) { return `${getLoggingPrefix('error')} Uncaught exception in ${capitalizedBrowserName(browser)} process:\n${pintor__WEBPACK_IMPORTED_MODULE_0___default().red(String(error))}`; } function enhancedProcessManagementUnhandledRejection(browser, reason) { return `${getLoggingPrefix('error')} Unhandled rejection in ${capitalizedBrowserName(browser)} process:\n${pintor__WEBPACK_IMPORTED_MODULE_0___default().red(String(reason))}`; } function generalBrowserError(browser, error) { return `${getLoggingPrefix('error')} General error in ${capitalizedBrowserName(browser)}:\n${pintor__WEBPACK_IMPORTED_MODULE_0___default().red(String(error))}`; } function errorConnectingToBrowser(browser) { return `${getLoggingPrefix('error')} Unable to connect to ${capitalizedBrowserName(browser)}. Too many retries.`; } function addonInstallError(browser, message) { return `${getLoggingPrefix('error')} Can't install add-on into ${capitalizedBrowserName(browser)}:\n${pintor__WEBPACK_IMPORTED_MODULE_0___default().red(message)}`; } function pathIsNotDirectoryError(browser, profilePath) { return `${getLoggingPrefix('error')} Profile path for ${capitalizedBrowserName(browser)} is not a directory.\n${pintor__WEBPACK_IMPORTED_MODULE_0___default().gray('PATH')} ${pintor__WEBPACK_IMPORTED_MODULE_0___default().underline(profilePath)}`; } function messagingClientClosedError(browser) { return `${getLoggingPrefix('error')} Messaging client closed unexpectedly for ${capitalizedBrowserName(browser)}`; } function requestWithoutTargetActorError(browser, requestType) { return `${getLoggingPrefix('error')} Request without target actor: ${pintor__WEBPACK_IMPORTED_MODULE_0___default().gray(requestType)} for ${capitalizedBrowserName(browser)}`; } function connectionClosedError(browser) { return `${getLoggingPrefix('error')} Connection closed unexpectedly for ${capitalizedBrowserName(browser)}`; } function targetActorHasActiveRequestError(browser, targetActor) { return `${getLoggingPrefix('error')} Target actor ${pintor__WEBPACK_IMPORTED_MODULE_0___default().gray(targetActor)} has active request for ${capitalizedBrowserName(browser)}`; } function parsingPacketError(browser, error) { return `${getLoggingPrefix('error')} Failed to parse packet from ${capitalizedBrowserName(browser)}:\n${pintor__WEBPACK_IMPORTED_MODULE_0___default().red(String(error))}`; } function messageWithoutSenderError(browser, message) { return `${getLoggingPrefix('error')} Message without sender from ${capitalizedBrowserName(browser)}:\n${pintor__WEBPACK_IMPORTED_MODULE_0___default().red(JSON.stringify(message))}`; } function pathPermissionError(bro