(async () => {
try {
const {ipcRenderer, shell} = require('electron');
const http = require('node:http');
let domReady = false
let loadingOverlay
let hasSuccessfulUiLoad = false
const setLoadingOverlayVisible = (visible) => {
if (!loadingOverlay) {
return
}
if (visible) {
loadingOverlay.classList.remove('p3xre-hidden')
} else {
loadingOverlay.classList.add('p3xre-hidden')
}
}
const setLoadingState = (loading) => {
setLoadingOverlayVisible(loading)
if (!global.p3xre || !global.p3xre.iframe) {
return
}
if (loading) {
global.p3xre.iframe.classList.add('p3xre-webview-loading')
} else {
global.p3xre.iframe.classList.remove('p3xre-webview-loading')
}
}
let p3xSetLanguageWaiter
ipcRenderer.on('p3x-set-language', (event, data) => {
const callMe = async () => {
if (domReady === false) {
clearTimeout(p3xSetLanguageWaiter)
setTimeout(callMe, 250)
return;
}
const translation = data.translation
const stringsModule = await import(`../../../strings/${translation}/index.mjs`)
global.p3xre.strings = stringsModule.default
global.p3xre.iframe.contentWindow.postMessage({ type: 'p3x-set-language', translation: translation }, '*')
}
callMe()
})
ipcRenderer.on('p3x-menu', function (event, data) {
global.p3xre.iframe.contentWindow.postMessage({ type: 'p3x-menu', action: data.action }, '*')
})
ipcRenderer.on('p3x-new-window', function (event, data) {
shell.openExternal(data.url)
})
const pkg = require('../../../../package.json')
const enStrings = await import('../../../strings/en/index.mjs')
global.p3xre = {
iframe: undefined,
pkg: pkg,
strings: enStrings.default
}
const { p3xToast } = await import('./ui.mjs')
global.p3xre.toast = p3xToast
ipcRenderer.on('p3x-action', function (event, data) {
switch (data.action) {
case 'toast':
p3xre.toast.action(data.message)
break;
}
})
const isLocalHttpAvailable = (port, timeoutMs = 800, host = '127.0.0.1') => {
return new Promise((resolve) => {
let settled = false
const done = (value) => {
if (settled) {
return
}
settled = true
resolve(value)
}
const request = http.request({
host: host,
port: port,
path: '/',
method: 'GET',
}, () => {
done(true)
request.destroy()
})
request.on('error', () => {
done(false)
})
request.setTimeout(timeoutMs, () => {
request.destroy()
done(false)
})
request.end()
})
}
window.p3xreRun = async function () {
document.title = `${p3xre.strings.title} v${p3xre.pkg.version}`
try {
global.p3xre.iframe = document.getElementById("p3xre-redis-ui-electron");
loadingOverlay = document.getElementById('p3xre-loading-overlay')
setLoadingState(true)
const urlParams = new URLSearchParams(global.location.search)
const port = urlParams.get('port')
const localServerHosts = ['127.0.0.1', 'localhost']
const getLocalServerUrl = (host) => `http://${host}:${port}`
let currentLocalServerHostIndex = 0
const getCurrentLocalServerUrl = () => getLocalServerUrl(localServerHosts[currentLocalServerHostIndex])
const devServerUrl = 'http://localhost:8080'
const isDev = process.env.hasOwnProperty('NODE_ENV') && process.env.NODE_ENV === 'development'
const maxWaitRetries = 120
const waitRetryDelayMs = 500
// Wait for the local HTTP server to become available before loading the iframe.
const waitForServer = async (targetUrl) => {
for (let i = 0; i < maxWaitRetries; i++) {
for (const host of localServerHosts) {
const available = await isLocalHttpAvailable(port, 800, host)
if (available) {
currentLocalServerHostIndex = localServerHosts.indexOf(host)
return getCurrentLocalServerUrl()
}
}
await new Promise((r) => setTimeout(r, waitRetryDelayMs))
}
// Fall back to the target even if not confirmed available
return targetUrl
}
global.p3xre.iframe.addEventListener('load', function () {
domReady = true
const iframeSrc = global.p3xre.iframe.src || ''
if (iframeSrc === 'about:blank') {
return
}
hasSuccessfulUiLoad = true
setLoadingState(false)
})
let serverUrl
if (isDev) {
console.log('development mode')
const devServerAvailable = await isLocalHttpAvailable(8080)
if (devServerAvailable) {
serverUrl = devServerUrl
} else {
console.warn('Dev server http://localhost:8080 is not running, waiting for local server...')
serverUrl = await waitForServer(getCurrentLocalServerUrl())
}
} else {
serverUrl = await waitForServer(getCurrentLocalServerUrl())
}
global.p3xre.iframe.src = serverUrl
} catch (e) {
console.error(e);
alert(e.message);
}
}
if (document.readyState === 'complete') {
window.p3xreRun()
} else {
window.addEventListener('load', () => {
window.p3xreRun()
})
}
} catch(e) {
console.error('p3xre: fatal error in onload.mjs', e)
}
})();