wired createserver 4747 into main.ts added scripts added predev hook

This commit is contained in:
Sparsh 2026-04-19 15:22:05 +05:30
parent f5c6fd1b40
commit 31755de553
3 changed files with 122 additions and 5 deletions

View file

@ -11,6 +11,7 @@
"node": ">=20.0.0"
},
"scripts": {
"predev": "node scripts/ensure-gitnexus-runtime.mjs",
"dev": "electron-vite dev --outDir=dist",
"start": "electron-vite preview --outDir=dist",
"bundle": "electron-vite build --outDir=dist",

View file

@ -0,0 +1,39 @@
import { spawnSync } from 'node:child_process';
import { existsSync } from 'node:fs';
import path from 'node:path';
import { fileURLToPath } from 'node:url';
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const workspaceRoot = path.resolve(__dirname, '..', '..');
const sharedRoot = path.join(workspaceRoot, 'gitnexus-shared');
const gitnexusRoot = path.join(workspaceRoot, 'gitnexus');
const gitnexusServerEntry = path.join(gitnexusRoot, 'dist', 'server', 'api.js');
const runNpm = (args, cwd) => {
const result = spawnSync('npm', args, {
cwd,
stdio: 'inherit',
shell: process.platform === 'win32',
});
if (result.error) {
throw result.error;
}
if (result.status !== 0) {
process.exit(result.status ?? 1);
}
};
if (!existsSync(path.join(sharedRoot, 'node_modules', 'typescript'))) {
runNpm(['ci'], sharedRoot);
}
if (!existsSync(path.join(gitnexusRoot, 'node_modules', 'tsx'))) {
runNpm(['ci'], gitnexusRoot);
}
if (!existsSync(gitnexusServerEntry)) {
runNpm(['run', 'build'], gitnexusRoot);
}

View file

@ -1,15 +1,76 @@
import { app, BrowserWindow } from 'electron';
import { app, BrowserWindow, dialog } from 'electron';
import path from 'node:path';
import { fileURLToPath } from 'node:url';
import { fileURLToPath, pathToFileURL } from 'node:url';
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const GITNEXUS_PORT = 4747;
const GITNEXUS_HOST = 'localhost';
const GITNEXUS_SERVER_ENTRY = path.resolve(__dirname, '../../../gitnexus/dist/server/api.js');
type GitNexusServerModule = {
createServer: (port: number, host?: string) => Promise<void>;
};
let serverReadyPromise: Promise<void> | null = null;
const getErrorMessage = (error: unknown): string => {
if (error instanceof Error) {
return error.message;
}
return String(error);
};
const isAddressInUseError = (error: unknown): boolean => {
return (error as NodeJS.ErrnoException | undefined)?.code === 'EADDRINUSE';
};
const showStartupError = (error: unknown): void => {
if (isAddressInUseError(error)) {
dialog.showErrorBox(
'GitNexus Desktop Startup Failed',
`Port ${GITNEXUS_PORT} is already in use.\n\nStop the other process using port ${GITNEXUS_PORT} and try again.`,
);
return;
}
dialog.showErrorBox(
'GitNexus Desktop Startup Failed',
`Failed to start GitNexus Desktop.\n\n${getErrorMessage(error)}`,
);
};
const loadGitNexusServerModule = async (): Promise<GitNexusServerModule> => {
try {
return (await import(pathToFileURL(GITNEXUS_SERVER_ENTRY).href)) as GitNexusServerModule;
} catch (error) {
throw new Error(
`Could not load the GitNexus server runtime at ${GITNEXUS_SERVER_ENTRY}. ${getErrorMessage(error)}`,
);
}
};
const ensureGitNexusServerStarted = async (): Promise<void> => {
if (!serverReadyPromise) {
serverReadyPromise = (async () => {
const { createServer } = await loadGitNexusServerModule();
await createServer(GITNEXUS_PORT, GITNEXUS_HOST);
})().catch((error) => {
serverReadyPromise = null;
throw error;
});
}
await serverReadyPromise;
};
async function createWindow(): Promise<void> {
const mainWindow = new BrowserWindow({
width: 1280,
height: 800,
title: 'GitNexus Desktop',
show: false,
webPreferences: {
preload: path.join(__dirname, '../preload/preload.mjs'),
contextIsolation: true,
@ -17,6 +78,12 @@ async function createWindow(): Promise<void> {
},
});
mainWindow.once('ready-to-show', () => {
if (!mainWindow.isDestroyed()) {
mainWindow.show();
}
});
const rendererUrl = process.env.ELECTRON_RENDERER_URL;
if (rendererUrl) {
@ -27,12 +94,22 @@ async function createWindow(): Promise<void> {
await mainWindow.loadFile(path.join(__dirname, '../renderer/src/renderer/index.html'));
}
app.whenReady().then(() => {
void createWindow();
app.whenReady().then(async () => {
try {
await ensureGitNexusServerStarted();
await createWindow();
} catch (error) {
showStartupError(error);
app.quit();
return;
}
app.on('activate', () => {
if (BrowserWindow.getAllWindows().length === 0) {
void createWindow();
void createWindow().catch((error) => {
showStartupError(error);
app.quit();
});
}
});
});