Architecture
IPC Contract
Typed Inter-Process Communication between renderer and main process
IPC Contract
The renderer talks to main only through window.dripnex. Main validates args with Zod before any business logic.
Architecture
Renderer (React)
↓ window.dripnex.notes.create()
Preload (contextBridge)
↓ ipcRenderer.invoke('notes:create')
Main (defineIpcHandler + Zod)
↓ createNoteOperation()
@dripnex/core + SQLiteNoteRepositoryPreload API
Namespaces on window.dripnex:
| Namespace | Owns |
|---|---|
notes | CRUD, trash/restore, pin, move, list, search, counts, tags |
notebooks | Hierarchy |
data | Backup, export/import, data-folder paths |
sync / auth / encryption | Optional E2E sync (not required to take notes) |
ai | Chat, tools, local index |
plugins | Scan, enable, install, init.js / styles.css |
git / integrations | Git notebooks, GitHub, 1Password |
settings | Cross-window broadcast (API keys never travel this channel) |
Main handlers
defineIpcHandler({
channel: 'notes:create',
args: z.tuple([z.object({ content: z.string().max(10 * 1024 * 1024) })]),
handler: input => createNoteOperation(input, noteRepository),
});There is no syncEngine in sync-core. Push/pull live on desktop SyncService.
Security Rules
| Rule | Description |
|---|---|
No nodeIntegration | Renderer cannot require Node |
contextIsolation | Preload is the only bridge |
No executeSQL | Raw SQL never exposed |
| Typed channels | Zod at the IPC boundary |
| Plugins | Trusted renderer JS. They call PluginContext, not IPC directly |