bootstrap new electron app

This commit is contained in:
Ramnique Singh 2025-12-29 15:30:57 +05:30
parent 2491bacea1
commit 505e3ea620
89 changed files with 12397 additions and 8435 deletions

2
apps/x/apps/preload/.gitignore vendored Normal file
View file

@ -0,0 +1,2 @@
node_modules/
dist/

View file

@ -0,0 +1,16 @@
{
"name": "@x/preload",
"private": true,
"type": "module",
"main": "dist/preload.js",
"scripts": {
"build": "rm -rf dist && tsc && esbuild dist/preload.js --bundle --platform=node --format=cjs --external:electron --outfile=dist/preload.bundle.js && mv dist/preload.bundle.js dist/preload.js"
},
"dependencies": {
"@x/shared": "workspace:*"
},
"devDependencies": {
"electron": "^39.2.7",
"esbuild": "^0.24.2"
}
}

View file

@ -0,0 +1,54 @@
import { contextBridge, ipcRenderer } from 'electron';
import { ipc as ipcShared } from '@x/shared';
type InvokeChannels = ipcShared.InvokeChannels;
type IPCChannels = ipcShared.IPCChannels;
type SendChannels = ipcShared.SendChannels;
const { validateRequest } = ipcShared;
const ipc = {
/**
* Invoke a channel that expects a response (request/response pattern)
* Only channels with non-null responses can be invoked
*/
invoke<K extends InvokeChannels>(
channel: K,
args: IPCChannels[K]['req']
): Promise<IPCChannels[K]['res']> {
// Runtime validation of request payload
const validatedArgs = validateRequest(channel, args);
return ipcRenderer.invoke(channel, validatedArgs);
},
/**
* Send a message to a channel without expecting a response (fire-and-forget)
* Only channels with null responses can be sent
*/
send<K extends SendChannels>(
channel: K,
args: IPCChannels[K]['req']
): void {
// Runtime validation of request payload
const validatedArgs = validateRequest(channel, args);
ipcRenderer.send(channel, validatedArgs);
},
/**
* Listen to a send channel event
* Returns a cleanup function to remove the listener
*/
on<K extends SendChannels>(
channel: K,
handler: (event: IPCChannels[K]['req']) => void
): () => void {
const listener = (_event: unknown, data: IPCChannels[K]['req']) => {
handler(data);
};
ipcRenderer.on(channel, listener);
return () => {
ipcRenderer.removeListener(channel, listener);
};
},
};
contextBridge.exposeInMainWorld('ipc', ipc);

View file

@ -0,0 +1,9 @@
{
"extends": "../../tsconfig.base.json",
"compilerOptions": {
"outDir": "dist",
"rootDir": "src",
"types": ["electron"]
},
"include": ["src"]
}