Files
akai-utils/electron/main.js
T
david a17f22ccb2 rename binary from fetch to akai-fetch
Consistent with go.mod, usage strings, and docs.
Updated Dockerfile, electron config, and Makefile.
2026-06-21 22:45:12 -07:00

123 lines
2.7 KiB
JavaScript

const { app, BrowserWindow, dialog } = require('electron');
const path = require('path');
const { spawn } = require('child_process');
let mainWindow;
let serverProcess;
let serverPort = 0;
function findServerBinary() {
const candidates = [
path.join(__dirname, '..', 'akai-fetch'),
path.join(__dirname, '..', 'fetch'),
path.join(process.resourcesPath, 'akai-fetch'),
path.join(process.resourcesPath, 'fetch'),
];
for (const p of candidates) {
try {
require('fs').accessSync(p, require('fs').constants.X_OK);
return p;
} catch (_) {}
}
return null;
}
async function startServer() {
const bin = findServerBinary();
if (!bin) {
dialog.showErrorBox('Missing Binary',
'Could not find fetch/akai-fetch binary. Place it next to the app or in resources.');
app.quit();
return;
}
const usePort = process.env.AKAI_PORT ? parseInt(process.env.AKAI_PORT) : 0;
return new Promise((resolve, reject) => {
serverProcess = spawn(bin, ['serve', '-p', String(usePort), '--no-browser'], {
stdio: ['pipe', 'pipe', 'pipe'],
});
let output = '';
serverProcess.stdout.on('data', (data) => {
output += data.toString();
const m = output.match(/Local:\s+http:\/\/localhost:(\d+)/);
if (m) {
serverPort = parseInt(m[1]);
resolve();
}
});
serverProcess.stderr.on('data', (data) => {
console.error('[server]', data.toString().trim());
});
serverProcess.on('error', (err) => {
console.error('Failed to start server:', err);
reject(err);
});
serverProcess.on('close', (code) => {
if (serverPort === 0) {
reject(new Error(`Server exited with code ${code}`));
}
});
});
}
async function createWindow() {
try {
await startServer();
} catch (err) {
dialog.showErrorBox('Server Error', String(err));
app.quit();
return;
}
mainWindow = new BrowserWindow({
width: 1200,
height: 800,
minWidth: 800,
minHeight: 600,
title: 'AKAI Utils',
backgroundColor: '#1a1a2e',
webPreferences: {
preload: path.join(__dirname, 'preload.js'),
contextIsolation: true,
nodeIntegration: false,
},
});
mainWindow.loadURL(`http://localhost:${serverPort}`);
mainWindow.setMenuBarVisibility(false);
mainWindow.on('closed', () => {
mainWindow = null;
});
}
app.whenReady().then(createWindow);
app.on('window-all-closed', () => {
if (serverProcess) {
serverProcess.kill();
serverProcess = null;
}
if (process.platform !== 'darwin') {
app.quit();
}
});
app.on('activate', () => {
if (mainWindow === null) {
createWindow();
}
});
app.on('before-quit', () => {
if (serverProcess) {
serverProcess.kill();
serverProcess = null;
}
});