From fbfd99a9a87092111bbf6fdd037211fbaaff2a78 Mon Sep 17 00:00:00 2001 From: Cezar Augusto Date: Thu, 22 Aug 2024 16:14:14 -0300 Subject: [PATCH] Fix multiple browsers not running together --- .../create/steps/import-external-template.ts | 2 +- .../plugin-browsers/browsers-lib/messages.ts | 2 +- .../manager-extension-firefox/background.js | 1 + .../define-initial-tab.js | 9 ++-- .../manager-extension-firefox/manifest.json | 2 +- .../manager-extension/background.js | 2 +- .../manager-extension/manifest.json | 2 +- .../manager-extension/reload-service.js | 30 +++++++++----- .../web-socket-server/start-server.ts | 41 +++++++------------ 9 files changed, 44 insertions(+), 47 deletions(-) diff --git a/programs/create/steps/import-external-template.ts b/programs/create/steps/import-external-template.ts index 338077ef..5ec41dd5 100644 --- a/programs/create/steps/import-external-template.ts +++ b/programs/create/steps/import-external-template.ts @@ -25,7 +25,7 @@ export async function importExternalTemplate( await fs.mkdir(projectPath, {recursive: true}) if (process.env.EXTENSION_ENV === 'development') { - console.log(messages.installingFromTemplate(projectName, template)) + console.log(messages.installingFromTemplate(projectName, template)) await fs.cp( path.join(__dirname, '..', '..', '..', 'examples', templateName), diff --git a/programs/develop/plugin-browsers/browsers-lib/messages.ts b/programs/develop/plugin-browsers/browsers-lib/messages.ts index 8f643c43..04c7e723 100644 --- a/programs/develop/plugin-browsers/browsers-lib/messages.ts +++ b/programs/develop/plugin-browsers/browsers-lib/messages.ts @@ -66,7 +66,7 @@ export function creatingUserProfile(browser: DevOptions['browser']) { const browsername = capitalizedBrowserName(browser) return ( `${getLoggingPrefix(browser, 'info')} Creating ${browsername} ` + - `profile directory...` + `user profile directory...` ) } diff --git a/programs/develop/webpack/plugin-reload/extensions/manager-extension-firefox/background.js b/programs/develop/webpack/plugin-reload/extensions/manager-extension-firefox/background.js index 0b916700..a7d217a5 100644 --- a/programs/develop/webpack/plugin-reload/extensions/manager-extension-firefox/background.js +++ b/programs/develop/webpack/plugin-reload/extensions/manager-extension-firefox/background.js @@ -31,6 +31,7 @@ async function handleTabOnExtensionLoad() { ██████████████████████████ ████████████████████████████ ██████████████████████████████████████████████████████████ ██████████████████████████████████████████████████████████ +MIT (c) ${new Date().getFullYear()} - Cezar Augusto and the Extension.js Authors. `, bgGreen('') ) diff --git a/programs/develop/webpack/plugin-reload/extensions/manager-extension-firefox/define-initial-tab.js b/programs/develop/webpack/plugin-reload/extensions/manager-extension-firefox/define-initial-tab.js index 95986149..ad994cb5 100644 --- a/programs/develop/webpack/plugin-reload/extensions/manager-extension-firefox/define-initial-tab.js +++ b/programs/develop/webpack/plugin-reload/extensions/manager-extension-firefox/define-initial-tab.js @@ -3,14 +3,12 @@ async function getDevExtension() { return allExtensions.filter((extension) => { return ( - // Do not include itself - extension.id !== browser.runtime.id && // Reload extension extension.name !== 'Extension Manager' && // Show only unpackaged extensions extension.installType === 'development' ) - }) + })[0] } // Create a new tab and set it to background. @@ -40,14 +38,13 @@ export async function createFirefoxAddonsTab(initialTab, url) { // Function to handle first run logic export async function handleFirstRun() { try { - const devExtensions = await getDevExtension() + const devExtension = await getDevExtension() - if (devExtensions.length === 0) { + if (!devExtension) { console.warn('No development extensions found') return } - const devExtension = await getDevExtension() const result = await browser.storage.local.get(devExtension.id) if (result[devExtension.id] && result[devExtension.id].didRun) { diff --git a/programs/develop/webpack/plugin-reload/extensions/manager-extension-firefox/manifest.json b/programs/develop/webpack/plugin-reload/extensions/manager-extension-firefox/manifest.json index f8a3412f..1045f0f7 100644 --- a/programs/develop/webpack/plugin-reload/extensions/manager-extension-firefox/manifest.json +++ b/programs/develop/webpack/plugin-reload/extensions/manager-extension-firefox/manifest.json @@ -1,6 +1,6 @@ { "name": "Extension Manager", - "description": "Developer Tools for extension management.", + "description": "Extension.js developer tools for tabs and reload management.", "version": "1.0", "manifest_version": 2, "background": { diff --git a/programs/develop/webpack/plugin-reload/extensions/manager-extension/background.js b/programs/develop/webpack/plugin-reload/extensions/manager-extension/background.js index 4c847023..e17c73dd 100644 --- a/programs/develop/webpack/plugin-reload/extensions/manager-extension/background.js +++ b/programs/develop/webpack/plugin-reload/extensions/manager-extension/background.js @@ -30,7 +30,7 @@ chrome.tabs.query({active: true}, async ([initialTab]) => { ██████████████████████████ ████████████████████████████ ██████████████████████████████████████████████████████████ ██████████████████████████████████████████████████████████ - Make it very easy to develop cross-browser extensions. +MIT (c) ${new Date().getFullYear()} - Cezar Augusto and the Extension.js Authors. `, bgGreen('') ) diff --git a/programs/develop/webpack/plugin-reload/extensions/manager-extension/manifest.json b/programs/develop/webpack/plugin-reload/extensions/manager-extension/manifest.json index a98b0e44..6a4d71ac 100644 --- a/programs/develop/webpack/plugin-reload/extensions/manager-extension/manifest.json +++ b/programs/develop/webpack/plugin-reload/extensions/manager-extension/manifest.json @@ -1,6 +1,6 @@ { "name": "Extension Manager", - "description": "Developer Tools for extension management.", + "description": "Extension.js developer tools for tabs and reload management.", "version": "1.0", "manifest_version": 3, "key": "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAolEJq/DBHxY5dBpOqBRWNCl7vRPBvJPlpEzF19fYFVzzaH44AF6+sKjN3jwIKlsgI82F3TIuwoNFiN1yBu5Unf8SVBE4BTO92P02/ACcGYQxicgCLFUGQKlq4uSrwSPaBYl7FHcYl5SERgxnIGCGnaGMdL2vC7waCj2/U/iKoBF9I1lBH9/aKCSjTd3h2UYo7gg6n5nY/ENbzylDt42T3ATmvnVJfYhSNKA9Dv/zryknfnHYYgBKHtz7pDZwWnYdxs78n2VEKwGj7TgbXuIPDpCkrMnU9PTKpHbXFYARA4H9qYORQmYazfIxUZRnKQNSR+GAOGrb8JK+ijeQdwzDAwIDAQAB", diff --git a/programs/develop/webpack/plugin-reload/extensions/manager-extension/reload-service.js b/programs/develop/webpack/plugin-reload/extensions/manager-extension/reload-service.js index 14486178..8c58b086 100644 --- a/programs/develop/webpack/plugin-reload/extensions/manager-extension/reload-service.js +++ b/programs/develop/webpack/plugin-reload/extensions/manager-extension/reload-service.js @@ -7,28 +7,38 @@ export async function connect() { return } - webSocket = new WebSocket('ws://localhost:__RELOAD_PORT__') + try { + // Attempt to connect using wss (secure WebSocket) + webSocket = new WebSocket('wss://localhost:__RELOAD_PORT__') + } catch (error) { + console.warn( + 'Extension.js ►►► Secure WebSocket (wss) failed, falling back to ws.', + error + ) + // If wss fails, fallback to ws (non-secure WebSocket) + webSocket = new WebSocket('ws://localhost:__RELOAD_PORT__') + } webSocket.onerror = (event) => { - console.error(`[Extension.js] Connection error: ${JSON.stringify(event)}`) + console.error(`Extension.js ►►► Connection error: ${JSON.stringify(event)}`) webSocket.close() } webSocket.onopen = () => { - console.info(`[Extension.js] Connection opened.`) + console.info(`Extension.js ►►► Connection opened.`) } webSocket.onmessage = async (event) => { const message = JSON.parse(event.data) if (message.status === 'serverReady') { - console.info('[Extension.js] Connection ready.') + console.info('Extension.js ►►► Connection ready.') await requestInitialLoadData() } if (message.changedFile) { console.info( - `[Extension.js] Changes detected on ${message.changedFile}. Reloading extension...` + `Extension.js ►►► Changes detected on ${message.changedFile}. Reloading extension...` ) await messageAllExtensions(message.changedFile) @@ -36,7 +46,7 @@ export async function connect() { } webSocket.onclose = () => { - console.info('[Extension.js] Connection closed.') + console.info('Extension.js ►►► Connection closed.') webSocket = null } } @@ -71,7 +81,7 @@ async function messageAllExtensions(changedFile) { const reloadAll = devExtensions.map((extension) => { chrome.runtime.sendMessage(extension.id, {changedFile}, (response) => { if (response) { - console.info('[Extension.js] Extension reloaded and ready.') + console.info('Extension.js ►►► Extension reloaded and ready.') } }) @@ -80,7 +90,7 @@ async function messageAllExtensions(changedFile) { await Promise.all(reloadAll) } else { - console.info('[Extension.js] External extension is not ready.') + console.info('Extension.js ►►► External extension is not ready.') } } @@ -108,7 +118,7 @@ async function requestInitialLoadData() { const responses = await Promise.all(messagePromises) - // We received the info from the use extension. + // We received the info from the user extension. // All good, client is ready. Inform the server. if (webSocket && webSocket.readyState === WebSocket.OPEN) { const message = JSON.stringify({ @@ -135,7 +145,7 @@ export function keepAlive() { const keepAliveIntervalId = setInterval(() => { if (webSocket) { webSocket.send(JSON.stringify({status: 'ping'})) - console.info('[Extension.js] Listening for changes...') + console.info('Extension.js ►►► Listening for changes...') } else { clearInterval(keepAliveIntervalId) } diff --git a/programs/develop/webpack/plugin-reload/steps/create-web-socket-server/web-socket-server/start-server.ts b/programs/develop/webpack/plugin-reload/steps/create-web-socket-server/web-socket-server/start-server.ts index 3392f36b..3f89f5a3 100644 --- a/programs/develop/webpack/plugin-reload/steps/create-web-socket-server/web-socket-server/start-server.ts +++ b/programs/develop/webpack/plugin-reload/steps/create-web-socket-server/web-socket-server/start-server.ts @@ -41,46 +41,29 @@ function isPortInUse(port: number): Promise { }) } +let webSocketServer: WebSocket.Server | null = null + export async function startServer(compiler: Compiler, options: DevOptions) { const projectPath = compiler.options.context || '' const manifest = require(path.join(projectPath, 'manifest.json')) const manifestName = manifest.name || 'Extension.js' - let webSocketServer: WebSocket.Server | undefined + const port = options.port || 8000 + const portInUse = await isPortInUse(port) - if (options.browser === 'firefox') { - const {server} = httpsServer(manifestName, options.port || 8000) + if (!webSocketServer && !portInUse) { + const {server} = httpsServer(manifestName, port) webSocketServer = new WebSocket.Server({server}) - } else { - const portInUse = await isPortInUse(options.port as number) - if (!portInUse) { - webSocketServer = new WebSocket.Server({ - host: 'localhost', - port: options.port - }) - } else { - // Port is already in use. Connect to the existing server. - webSocketServer = new WebSocket.Server({ - noServer: true - }) - } - } + console.log(`WebSocket server started on port ${port}`) - if (webSocketServer) { webSocketServer.on('connection', (ws) => { ws.send(JSON.stringify({status: 'serverReady'})) ws.on('error', (error) => { console.log(messages.webSocketError(manifestName, error)) - webSocketServer?.close() - }) - - ws.on('close', () => { - webSocketServer?.close() }) - // We're only ready when the extension says so ws.on('message', (msg) => { const message: Message = JSON.parse(msg.toString()) @@ -102,11 +85,17 @@ export async function startServer(compiler: Compiler, options: DevOptions) { } }) }) + } else if (webSocketServer) { + console.log(`Reusing existing WebSocket server on port ${port}`) } else { - console.log('Failed to start WebSocket server.') + console.error( + `Port ${port} is already in use but WebSocket server is not initialized.` + ) + return } - if (options.browser === 'firefox') { + // Additional logic specific to Firefox, such as certificate checks + if (options.browser === 'firefox' && !portInUse) { if (!fs.existsSync(CERTIFICATE_DESTINATION_PATH)) { const hardcodedMessage = getHardcodedMessage(manifest) console.log(messages.runningInDevelopment(manifest, hardcodedMessage))