Files
ink-note-app/electron/preload.cjs
T
Your NameandClaude Sonnet 5.5 313c41f867 feat(electron): main process, vault, search index, links, import, capture
Vault on plain .md files with FTS5 index, link rewriting, canvas files,
history/trash/backup, link previews, image fetch, tasks and unlinked
mentions, Notion/Obsidian importer, quick-capture window and shortcut.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-15 11:57:09 +02:00

110 lines
5.3 KiB
JavaScript

'use strict';
// The only bridge between the page and the file system. Everything goes through ipcMain handlers in main.cjs.
const { contextBridge, ipcRenderer } = require('electron');
const invoke = (channel, ...args) => ipcRenderer.invoke(channel, ...args);
contextBridge.exposeInMainWorld('vault', {
platform: process.platform,
get: () => invoke('vault:get'),
list: () => invoke('vault:list'),
pick: (kind) => invoke('vault:pick', kind),
read: (id) => invoke('vault:read', id),
write: (id, meta, body) => invoke('vault:write', id, meta, body),
duplicate: (id) => invoke('vault:duplicate', id),
create: (parent, title, meta, body) => invoke('vault:create', parent, title, meta, body),
createMany: (parent, items) => invoke('vault:createMany', parent, items),
createCanvas: (parent, title) => invoke('vault:createCanvas', parent, title),
listTemplates: () => invoke('vault:listTemplates'),
getTemplate: (name) => invoke('vault:getTemplate', name),
openTemplatesFolder: () => invoke('vault:openTemplates'),
rename: (id, title) => invoke('vault:rename', id, title),
move: (id, parent) => invoke('vault:move', id, parent),
renameHeading: (id, from, to) => invoke('vault:renameHeading', id, from, to),
tasks: () => invoke('vault:tasks'),
setTask: (id, line, text, done) => invoke('vault:setTask', id, line, text, done),
unlinked: (id) => invoke('vault:unlinked', id),
linkMention: (id, target) => invoke('vault:linkMention', id, target),
openCapture: () => invoke('capture:open'),
takeCaptures: () => invoke('capture:take'),
onCapture(cb) {
const listener = () => cb();
ipcRenderer.on('capture:ping', listener);
return () => ipcRenderer.removeListener('capture:ping', listener);
},
renameTag: (from, to) => invoke('vault:renameTag', from, to),
exportVaultZip: () => invoke('export:vaultZip'),
importNotes: (kind) => invoke('vault:import', kind),
clipPage: (url) => invoke('web:clip', url),
backlinks: (id) => invoke('vault:backlinks', id),
graph: () => invoke('vault:graph'),
keepVersion: (id) => invoke('vault:keepVersion', id),
listHistory: (id) => invoke('vault:listHistory', id),
readHistory: (id, ts) => invoke('vault:readHistory', id, ts),
restoreHistory: (id, ts) => invoke('vault:restoreHistory', id, ts),
saveImage: (id, name, bytes) => invoke('vault:saveImage', id, name, bytes),
saveImageFromUrl: (id, url) => invoke('vault:saveImageFromUrl', id, url),
pickImage: (id) => invoke('vault:pickImage', id),
pickFile: (id) => invoke('vault:pickFile', id),
openFile: (id, src) => invoke('vault:openFile', id, src),
mediaUrl: (id, src) => `notes-media://vault/${encodeURIComponent(id)}?src=${encodeURIComponent(src)}`,
remove: (id) => invoke('vault:remove', id),
trash: () => invoke('vault:trash'),
restore: (entry) => invoke('vault:restore', entry),
purge: (entry) => invoke('vault:purge', entry),
search: (q) => invoke('vault:search', q),
reveal: (id) => invoke('vault:reveal', id),
filePath: (id) => invoke('vault:filePath', id),
saveExport: (name, content) => invoke('export:save', name, content),
savePdf: (name, title, html) => invoke('export:pdf', name, title, html),
print: () => ipcRenderer.send('export:print'),
linkPreview: (url) => invoke('web:preview', url),
saveCanvasImage: (name, kind, html, width, height) => invoke('export:canvas', name, kind, html, width, height),
getSettings: () => invoke('settings:get'),
setSettings: (patch) => invoke('settings:set', patch),
getSpellcheck: () => invoke('spell:get'),
setSpellcheck: (enabled, langs) => invoke('spell:set', enabled, langs),
spellWords: () => invoke('spell:words'),
addSpellWord: (word) => invoke('spell:addWord', word),
removeSpellWord: (word) => invoke('spell:removeWord', word),
backupNow: () => invoke('backup:now'),
backupInfo: () => invoke('backup:info'),
pickBackupFolder: () => invoke('backup:pickFolder'),
revealBackups: () => invoke('backup:reveal'),
onNav(cb) {
const listener = (_e, dir) => cb(dir);
ipcRenderer.on('nav:go', listener);
return () => ipcRenderer.removeListener('nav:go', listener);
},
onChanged(cb) {
const listener = (_e, ids) => cb(ids);
ipcRenderer.on('vault:changed', listener);
return () => ipcRenderer.removeListener('vault:changed', listener);
},
minimize: () => ipcRenderer.send('win:minimize'),
toggleMaximize: () => ipcRenderer.send('win:toggleMaximize'),
close: () => ipcRenderer.send('win:close'),
isMaximized: () => invoke('win:isMaximized'),
onMaximized(cb) {
const listener = (_e, v) => cb(v);
ipcRenderer.on('win:maximized', listener);
return () => ipcRenderer.removeListener('win:maximized', listener);
},
onContextMenu(cb) {
const listener = (_e, info) => cb(info);
ipcRenderer.on('app:context-menu', listener);
return () => ipcRenderer.removeListener('app:context-menu', listener);
},
editAction: (action) => ipcRenderer.send('edit:do', action),
copyImageAt: (x, y) => ipcRenderer.send('edit:copyImageAt', x, y),
replaceMisspelling: (word) => ipcRenderer.send('edit:replaceMisspelling', word),
addToDictionary: (word) => ipcRenderer.send('edit:addToDictionary', word),
onFlush(cb) {
const listener = async () => {
try { await cb(); } finally { ipcRenderer.send('app:flushed'); }
};
ipcRenderer.on('app:flush', listener);
return () => ipcRenderer.removeListener('app:flush', listener);
}
});