Skip to main content

Process Architecture

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

Process Overview​

Main Process​

The main-process source (main.ts) 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 source (preload.ts) 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.ts)​

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

UI Management (main-ui.ts)​

  • Tab navigation
  • User interactions
  • View updates

Module Loading​

// Dynamic imports for code splitting
const { renderMap } = await import("./utils/maps/core/renderMap.js");
const { renderChartJS } = await import(
"./utils/charts/core/renderChartJS.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.ts - 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 β†’