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>
110 lines
5.3 KiB
JavaScript
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);
|
|
}
|
|
});
|