/* * preload.js — the only bridge between the renderer and Node. * Nothing here takes a path or a command from the page; every call is a fixed * verb with no free-form arguments beyond a config patch. */ 'use strict'; const { contextBridge, ipcRenderer } = require('electron'); contextBridge.exposeInMainWorld('engineHost', { getConfig: () => ipcRenderer.invoke('config:get'), setConfig: (patch) => ipcRenderer.invoke('config:set', patch), micStatus: () => ipcRenderer.invoke('mic:status'), askMic: () => ipcRenderer.invoke('mic:ask'), openPrivacy: () => ipcRenderer.invoke('app:openPrivacy'), cacheInfo: () => ipcRenderer.invoke('app:cacheInfo'), revealCache: () => ipcRenderer.invoke('app:revealCache'), copyText: (text) => ipcRenderer.invoke('app:copy', text), setLive: (live) => ipcRenderer.send('engine:live', !!live), logLine: (line) => ipcRenderer.send('log:line', String(line || '')), /* Translation lives in the main process; these are its only two verbs. */ mtEnsure: () => ipcRenderer.invoke('mt:ensure'), settingsExport: () => ipcRenderer.invoke('settings:export'), settingsImport: () => ipcRenderer.invoke('settings:import'), audioDevices: () => ipcRenderer.invoke('audio:devices'), modelsCached: (id) => ipcRenderer.invoke('models:cached', id), mtTranslate: (req) => ipcRenderer.invoke('mt:translate', req), mtTranslateMulti: (req) => ipcRenderer.invoke('mt:translateMulti', req), onMtProgress: (fn) => ipcRenderer.on('mt:progress', (_e, p) => fn(p)), onMtDown: (fn) => ipcRenderer.on('mt:down', (_e, info) => fn(info)), /* The congregation server runs inside this app; these describe it. */ localInfo: () => ipcRenderer.invoke('local:info'), onServerUp: (fn) => ipcRenderer.on('server:up', (_e, info) => fn(info)), onServerDown: (fn) => ipcRenderer.on('server:down', () => fn()), /* Share to the internet: a Cloudflare quick tunnel for livestream viewers. */ tunnelStart: () => ipcRenderer.invoke('tunnel:start'), tunnelStop: () => ipcRenderer.invoke('tunnel:stop'), tunnelStatus: () => ipcRenderer.invoke('tunnel:status'), onTunnel: (fn) => ipcRenderer.on('tunnel:status', (_e, s) => fn(s)), /* Built-in voices: this Mac speaks, and the phones play what it sends. */ ttsInfo: () => ipcRenderer.invoke('tts:info'), ttsSpeak: (req) => ipcRenderer.invoke('tts:speak', req), ttsPreload: (langs) => ipcRenderer.invoke('tts:preload', langs), /* Audition one specific voice, and save the per-language choices. */ ttsAudition: (req) => ipcRenderer.invoke('tts:audition', req), ttsSetVoices: (c) => ipcRenderer.invoke('tts:setVoices', c), ttsSetListenerVoices: (m) => ipcRenderer.invoke('tts:setListenerVoices', m), onTtsReady: (fn) => ipcRenderer.on('tts:ready', (_e, i) => fn(i)), onTtsProgress: (fn) => ipcRenderer.on('tts:progress', (_e, p) => fn(p)), onTtsCloud: (fn) => ipcRenderer.on('tts:cloud', (_e, s) => fn(s)), onLocalVoices: (fn) => ipcRenderer.on('localvoices:status', (_e, s) => fn(s)), localVoicesStatus: () => ipcRenderer.invoke('localvoices:status') });