···11-// main.js
11+/**
22+ * Electron Backend Entry Point
33+ *
44+ * This is the main entry point for the Electron application.
55+ * All Electron-specific code lives here.
66+ */
2738import { app } from 'electron';
44-59import fs from 'node:fs';
610import path from 'node:path';
1111+import unhandled from 'electron-unhandled';
71288-// Import from compiled TypeScript backend
1313+// Import from local backend modules
914import {
1015 // Main process orchestration
1116 configure,
···3136 unregisterLocalShortcut,
3237 // PubSub
3338 scopes,
3434- publish as pubsubPublish,
3535- subscribe as pubsubSubscribe,
3939+ publish,
4040+ subscribe,
3641 getSystemAddress,
3742 // IPC
3843 registerAllHandlers,
···4550 // Window helpers
4651 setPrefsGetter,
4752 updateDockVisibility,
4848-} from './dist/backend/electron/index.js';
4949-import unhandled from 'electron-unhandled';
5353+} from './index.js';
50545155// Catch unhandled errors and promise rejections without showing alert dialogs
5256unhandled({
···5660 }
5761});
58625959-const __dirname = import.meta.dirname;
6363+// Get the root directory (two levels up from dist/backend/electron/)
6464+const ROOT_DIR = path.resolve(import.meta.dirname, '..', '..', '..');
60656161-(async () => {
6262-6363-const DEBUG = process.env.DEBUG || false;
6464-const DEBUG_LEVELS = {
6565- BASIC: 1,
6666- FIRST_RUN: 2
6767-};
6868-const DEBUG_LEVEL = DEBUG_LEVELS.BASIC;
6969-//const DEBUG_LEVEL = DEBUG_LEVELS.FIRST_RUN;
6666+const DEBUG = !!process.env.DEBUG;
70677168// script loaded into every app window
7272-const preloadPath = path.join(__dirname, 'preload.js');
6969+const preloadPath = path.join(ROOT_DIR, 'preload.js');
73707471const systemAddress = getSystemAddress();
7572···8582 }
8683};
87848888-const profileIsLegit = p => p != undefined && typeof p == 'string' && p.length > 0;
8585+const profileIsLegit = (p: unknown): p is string =>
8686+ p !== undefined && typeof p === 'string' && p.length > 0;
89879088// Profile selection:
9189// 1. Explicit PROFILE env var takes precedence
···10199setProfile(PROFILE);
102100103101// Profile dirs are subdir of userData dir
104104-// ..................................... ↓ we set this per profile
105105-//
106102// {home} / {appData} / {userData} / {profileDir}
107107-//
108103// Chromium's data in a subfolder of profile folder
109109-//
110110-// ................................................. ↓ we set this per profile
111111-//
112104// {home} / {appData} / {userData} / {profileDir} / {sessionData}
113113-114105115106// specify various app data paths and make if not exist
116107const defaultUserDataPath = app.getPath('userData');
117108const profileDataPath = path.join(defaultUserDataPath, PROFILE);
118109const sessionDataPath = path.join(profileDataPath, 'chromium');
119110120120-//console.log('udp', defaultUserDataPath);
121121-//console.log('pdp', profileDataPath);
122122-//console.log('sdp', sessionDataPath);
123123-124111// create filesystem
125125-if (!fs.existsSync(sessionDataPath)){
112112+if (!fs.existsSync(sessionDataPath)) {
126113 fs.mkdirSync(sessionDataPath, { recursive: true });
127114}
128115···130117app.setPath('userData', profileDataPath);
131118app.setPath('sessionData', sessionDataPath);
132119133133-// ***** Datastore *****
134134-135135-// Note: getDb, generateId, now, parseUrl, normalizeUrl, calculateFrecency, isValidTable
136136-// are imported directly from backend/electron
137137-138120// ***** Features / Strings *****
139121140122const labels = {
···156138157139// app global prefs configurable by user
158140// populated during app init
159159-let _prefs = {};
160160-let _quitShortcut = null;
141141+let _prefs: Record<string, unknown> = {};
142142+let _quitShortcut: string | null = null;
161143162144// Set up prefs getter for backend window helpers
163145setPrefsGetter(() => _prefs);
164146165165-// ***** pubsub *****
166166-// Wrapper object for backend pubsub functions
167167-const pubsub = {
168168- publish: pubsubPublish,
169169- subscribe: pubsubSubscribe
170170-};
147147+// Define onQuit as alias to quitApp for use in IPC handlers and shortcuts
148148+const onQuit = quitApp;
171149172150// ***** init *****
173151···196174 registerSecondInstanceHandler();
197175198176 // Discover and register built-in extensions from extensions/ folder
199199- discoverBuiltinExtensions(path.join(__dirname, 'extensions'));
177177+ discoverBuiltinExtensions(path.join(ROOT_DIR, 'extensions'));
200178201179 // Register as default handler for http/https URLs (if not already and user hasn't declined)
202180 // Skip for test profiles to avoid system dialogs during automated testing
···216194 console.log('User previously declined default browser prompt');
217195 }
218196 }
219219- } catch (e) {
197197+ } catch {
220198 // Ignore errors reading pref file
221199 }
222200···239217 console.log('User declined default browser, saving preference');
240218 try {
241219 fs.writeFileSync(defaultBrowserPrefFile, JSON.stringify({ declined: true, timestamp: Date.now() }));
242242- } catch (e) {
243243- console.error('Failed to save default browser preference:', e);
220220+ } catch {
221221+ console.error('Failed to save default browser preference');
244222 }
245223 }
246224 }, 2000);
···257235258236 // listen for app prefs to configure ourself
259237 // TODO: kinda janky, needs rethink
260260- pubsub.subscribe(systemAddress, scopes.SYSTEM, strings.topics.prefs, async msg => {
261261- console.log('PREFS', msg);
238238+ subscribe(systemAddress, scopes.SYSTEM, strings.topics.prefs, async (msg: unknown) => {
239239+ const prefsMsg = msg as { prefs: Record<string, unknown> };
240240+ console.log('PREFS', prefsMsg);
262241263242 // cache all prefs
264264- _prefs = msg.prefs;
243243+ _prefs = prefsMsg.prefs;
265244266245 // Update dock visibility based on pref and visible windows
267246 updateDockVisibility();
268247269248 // initialize system tray
270270- if (msg.prefs.showTrayIcon == true) {
249249+ if (prefsMsg.prefs.showTrayIcon === true) {
271250 console.log('showing tray');
272272- initTray(__dirname, {
251251+ initTray(ROOT_DIR, {
273252 tooltip: labels.tray.tooltip,
274253 onClick: () => {
275275- pubsub.publish(WEB_CORE_ADDRESS, scopes.GLOBAL, 'open', {
254254+ publish(WEB_CORE_ADDRESS, scopes.GLOBAL, 'open', {
276255 address: SETTINGS_ADDRESS
277256 });
278257 }
···280259 }
281260282261 // update quit shortcut if changed (local shortcut - only works when app has focus)
283283- const newQuitShortcut = msg.prefs.quitShortcut || strings.defaults.quitShortcut;
262262+ const newQuitShortcut = (prefsMsg.prefs.quitShortcut as string) || strings.defaults.quitShortcut;
284263 if (newQuitShortcut !== _quitShortcut) {
285264 if (_quitShortcut) {
286265 console.log('unregistering old quit shortcut:', _quitShortcut);
···316295317296// Configure app before ready (registers protocol scheme, sets theme)
318297configure({
319319- rootDir: __dirname,
298298+ rootDir: ROOT_DIR,
320299 preloadPath: preloadPath,
321300 userDataPath: defaultUserDataPath,
322301 profile: PROFILE,
···327306// Register window-all-closed handler
328307registerWindowAllClosedHandler(quitApp);
329308309309+// Start the app
330310app.whenReady().then(onReady);
331331-332332-// Define onQuit as alias to quitApp for use in IPC handlers and shortcuts
333333-const onQuit = quitApp;
334334-335335-})();
+1-1
package.json
···22 "name": "Peek",
33 "version": "0.0.1",
44 "description": "Peek is a web user agent for working with the web in a more agent-ish fashion than a browser.",
55- "main": "index.js",
55+ "main": "dist/backend/electron/entry.js",
66 "author": "dietrich ayala",
77 "license": "MIT",
88 "type": "module",