Skip to main content

Process Architecture

FitFileViewer uses Electron's multi-process architecture for security and performance.

Process Overview​

Main Process​

The main process (main.js) handles:

App Lifecycle​

app.whenReady().then(() => {
createWindow();
setupMenu();
setupIpcHandlers();
});

app.on('window-all-closed', () => {
if (process.platform !== 'darwin') {
app.quit();
}
});

Window Management​

  • Creating browser windows
  • Window state persistence
  • Multi-window support

File System Access​

  • File dialogs (open/save)
  • File reading
  • Recent files management

IPC Handlers​

ipcMain.handle('dialog:open-fit-file', async () => {
const result = await dialog.showOpenDialog({
filters: [{ name: 'FIT Files', extensions: ['fit'] }]
});
return result;
});

Preload Script​

The preload script (preload.js) bridges main and renderer:

Context Bridge​

contextBridge.exposeInMainWorld('electronAPI', {
openFile: () => ipcRenderer.invoke('dialog:open-fit-file'),
onFileOpened: (callback) => ipcRenderer.on('file:opened', callback),
// Limited, validated operations only
});

Security​

  • Validates all messages
  • Sanitizes data
  • Prevents prototype pollution

Renderer Process​

The renderer process handles the UI:

Entry Point (renderer.js)​

// Initialize application
document.addEventListener('DOMContentLoaded', () => {
initializeApp();
setupEventListeners();
loadTheme();
});

UI Management (main-ui.js)​

  • Tab navigation
  • User interactions
  • View updates

Module Loading​

// Dynamic imports for code splitting
const { renderMap } = await import('./utils/maps/renderMap.js');
const { renderChart } = await import('./utils/charts/renderChart.js');

IPC Communication​

Main β†’ Renderer​

// Main process
mainWindow.webContents.send('file:opened', fileData);

// Renderer (via preload)
window.electronAPI.onFileOpened((event, data) => {
processFileData(data);
});

Renderer β†’ Main​

// Renderer
const result = await window.electronAPI.openFile();

// Main process
ipcMain.handle('dialog:open-fit-file', async () => {
return dialog.showOpenDialog(options);
});

Security Isolation​

Context Isolation​

// main.js - Window creation
const mainWindow = new BrowserWindow({
webPreferences: {
contextIsolation: true,
nodeIntegration: false,
sandbox: true,
preload: path.join(__dirname, 'preload.js')
}
});

Why This Matters​

SettingValuePurpose
contextIsolationtrueSeparate JS contexts
nodeIntegrationfalseNo Node in renderer
sandboxtrueOS-level isolation

Process Communication Flow​


Next: Module System β†’