extension-develop
Version:
The develop step of Extension.js
804 lines • 562 kB
JavaScript
"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