All checks were successful
farmcontrol/farmcontrol-ui/pipeline/head This commit looks good
- Introduced a new mechanism for handling RPC requests and responses in the Electrobun bridge, including timeout management for requests. - Refactored the desktop RPC to utilize a centralized request handler, improving code organization and clarity. - Added support for various RPC methods, enhancing communication between the renderer and the desktop environment.
140 lines
4.2 KiB
JavaScript
140 lines
4.2 KiB
JavaScript
import { BrowserView } from 'electrobun/bun'
|
|
import { checkForCompletedUpdate, startAppUpdate } from './appupdate.js'
|
|
import {
|
|
checkForDuplicateInstallations,
|
|
removeDuplicateInstallations
|
|
} from './check-duplicate-installations.js'
|
|
import { setSidebarViewMenu } from './menu.js'
|
|
import { sendToRenderer } from './notify.js'
|
|
import { resizeSpotlightWindow } from './spotlight.js'
|
|
import {
|
|
clearAuthSession,
|
|
getAppSettings,
|
|
getAuthSession,
|
|
setAppSettings,
|
|
setAuthSession
|
|
} from './store.js'
|
|
import {
|
|
getMainWindow,
|
|
getWindowState,
|
|
handleWindowControl,
|
|
openExternalUrl,
|
|
openInternalUrl
|
|
} from './window.js'
|
|
|
|
export function createAppRpc() {
|
|
const requestHandlers = {
|
|
getOsInfo: async () => ({
|
|
platform: process.platform
|
|
}),
|
|
getWindowState: async () => getWindowState(),
|
|
windowControl: async ({ action }) => {
|
|
handleWindowControl(action)
|
|
return { ok: true }
|
|
},
|
|
openExternalUrl: async ({ url }) => {
|
|
openExternalUrl(url)
|
|
return { ok: true }
|
|
},
|
|
openInternalUrl: async ({ url }) => ({
|
|
ok: openInternalUrl(url)
|
|
}),
|
|
getAuthSession: async () => getAuthSession(),
|
|
setAuthSession: async ({ session }) => ({
|
|
ok: await setAuthSession(session)
|
|
}),
|
|
clearAuthSession: async () => ({
|
|
ok: await clearAuthSession()
|
|
}),
|
|
getAppSettings: async () => getAppSettings(),
|
|
setAppSettings: async ({ settings }) => ({
|
|
ok: await setAppSettings(settings)
|
|
}),
|
|
startAppUpdate: async ({ update }) => {
|
|
const mainWindow = getMainWindow()
|
|
const sendProgress = (payload) => {
|
|
sendToRenderer('appUpdateProgress', {
|
|
timestamp: new Date().toISOString(),
|
|
...payload
|
|
})
|
|
}
|
|
|
|
// Updates can take several minutes; return immediately and report
|
|
// progress via appUpdateProgress messages instead of blocking RPC.
|
|
void startAppUpdate(mainWindow, update, sendProgress).catch((error) => {
|
|
console.error('App update failed:', error)
|
|
})
|
|
return { ok: true }
|
|
},
|
|
resizeSpotlightWindow: async ({ height }) => ({
|
|
ok: resizeSpotlightWindow(height)
|
|
}),
|
|
setSidebarViewMenu: async ({ sections }) => ({
|
|
ok: setSidebarViewMenu(sections)
|
|
}),
|
|
checkAppUpdateResult: async () =>
|
|
checkForCompletedUpdate(getMainWindow()),
|
|
checkDuplicateInstallations: async () => checkForDuplicateInstallations(),
|
|
removeDuplicateInstallations: async () => {
|
|
// Removal waits on an admin/UAC prompt which can outlive the RPC
|
|
// timeout; report the outcome via a push message instead.
|
|
void removeDuplicateInstallations()
|
|
.catch((error) => ({
|
|
ok: false,
|
|
error:
|
|
error?.message || 'Failed to remove the duplicate installation.'
|
|
}))
|
|
.then((result) => {
|
|
sendToRenderer('duplicateInstallationsRemoved', result)
|
|
})
|
|
return { ok: true }
|
|
},
|
|
getAppVersion: async () => process.env.ELECTROBUN_VERSION || 'desktop',
|
|
getAppEngine: async () => {
|
|
const mainWindow = getMainWindow()
|
|
const renderer = mainWindow?.renderer || 'native'
|
|
return renderer === 'cef' ? 'chromium' : 'native'
|
|
}
|
|
}
|
|
|
|
return BrowserView.defineRPC({
|
|
maxRequestTime: 30000,
|
|
handlers: {
|
|
requests: requestHandlers,
|
|
messages: {
|
|
rendererResponseAck: ({ id }) => {
|
|
console.log('[rpc-diagnostic] renderer received response', id)
|
|
},
|
|
rendererRequest: ({ id, method, params }) => {
|
|
const handler = requestHandlers[method]
|
|
if (!handler) {
|
|
sendToRenderer('rpcResponse', {
|
|
id,
|
|
success: false,
|
|
error: `Unknown desktop RPC method: ${String(method)}`
|
|
})
|
|
return
|
|
}
|
|
|
|
void Promise.resolve()
|
|
.then(() => handler(params || {}))
|
|
.then((result) => {
|
|
sendToRenderer('rpcResponse', {
|
|
id,
|
|
success: true,
|
|
result
|
|
})
|
|
})
|
|
.catch((error) => {
|
|
sendToRenderer('rpcResponse', {
|
|
id,
|
|
success: false,
|
|
error: error?.message || String(error)
|
|
})
|
|
})
|
|
}
|
|
}
|
|
}
|
|
})
|
|
}
|