Skip to content

Commit

Permalink
refactor: make core api client initialization synchronous (#77)
Browse files Browse the repository at this point in the history
Co-authored-by: Gregor MacLennan <[email protected]>
  • Loading branch information
achou11 and gmaclennan authored Jan 7, 2025
1 parent 453b421 commit c7d2878
Show file tree
Hide file tree
Showing 6 changed files with 29 additions and 68 deletions.
9 changes: 4 additions & 5 deletions src/main/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import { defineMessages } from '@formatjs/intl'
import debug from 'debug'
import {
BrowserWindow,
MessageChannelMain,
app,
dialog,
ipcMain,
Expand Down Expand Up @@ -215,17 +214,17 @@ function initMainWindow({ appMode, services }) {

// Set up communication channel between window and core service
// https://www.electronjs.org/docs/latest/tutorial/message-ports/#messageports-in-the-main-process
mainWindow.webContents.ipc.on('request-comapeo-port', (event) => {
const { port1, port2 } = new MessageChannelMain()
mainWindow.webContents.ipc.on('comapeo-port', (event) => {
const [port] = event.ports
if (!port) return // TODO: throw/report error
services.core.postMessage(
/** @satisfies {NewClientMessage} */
{
type: 'core:new-client',
payload: { clientId: `window-${mainWindow.id}` },
},
[port1],
[port],
)
event.senderFrame?.postMessage('provide-comapeo-port', null, [port2])
})

// Set up IPC specific to the main window
Expand Down
24 changes: 9 additions & 15 deletions src/preload/main-window.js
Original file line number Diff line number Diff line change
@@ -1,25 +1,19 @@
const { contextBridge, ipcRenderer } = require('electron/renderer')

// We need to wait until the main world is ready to receive the message before
// sending the port. We create this promise in the preload so it's guaranteed
// to register the onload listener before the load event is fired.
const windowLoaded = new Promise((resolve) => {
window.onload = resolve
})
window.onmessage = (event) => {
// event.source === window means the message is coming from the preload
// script, as opposed to from an <iframe> or other source.
if (event.source !== window) return
if (event.data !== 'comapeo-port') return
const [port] = event.ports
if (!port) return // TODO: throw/report error
ipcRenderer.postMessage('comapeo-port', null, [port])
}

/**
* @type {import('./runtime.js').RuntimeApi}
*/
const runtimeApi = {
// Setup
init() {
ipcRenderer.send('request-comapeo-port')
ipcRenderer.once('provide-comapeo-port', async (event) => {
await windowLoaded
window.postMessage('comapeo-port', '*', event.ports)
})
},

// Locale
async getLocale() {
const locale = await ipcRenderer.invoke('locale:get')
Expand Down
1 change: 0 additions & 1 deletion src/preload/runtime.d.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
export type RuntimeApi = {
init: () => void
getLocale: () => Promise<string>
updateLocale: (locale: string) => void
selectFile: (extensionFilters?: Array<string>) => Promise<string | undefined>
Expand Down
13 changes: 7 additions & 6 deletions src/renderer/src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,19 @@
import { ClientApiProvider } from '@comapeo/core-react'
import { CssBaseline, ThemeProvider } from '@mui/material'
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
import { RouterProvider, createRouter } from '@tanstack/react-router'

import { theme } from './Theme'
import { initComapeoClient } from './comapeo-client'
import {
ActiveProjectIdProvider,
createActiveProjectIdStore,
} from './contexts/ActiveProjectIdProvider'
import { ApiProvider } from './contexts/ApiContext'
import { IntlProvider } from './contexts/IntlContext'
import { routeTree } from './routeTree.gen'

const queryClient = new QueryClient()

const clientApi = initComapeoClient()
const router = createRouter({ routeTree })

declare module '@tanstack/react-router' {
Expand All @@ -30,11 +31,11 @@ export const App = () => (
<CssBaseline />
<IntlProvider>
<QueryClientProvider client={queryClient}>
<ActiveProjectIdProvider store={PersistedProjectIdStore}>
<ApiProvider>
<ClientApiProvider clientApi={clientApi}>
<ActiveProjectIdProvider store={PersistedProjectIdStore}>
<RouterProvider router={router} />
</ApiProvider>
</ActiveProjectIdProvider>
</ActiveProjectIdProvider>
</ClientApiProvider>
</QueryClientProvider>
</IntlProvider>
</ThemeProvider>
Expand Down
9 changes: 9 additions & 0 deletions src/renderer/src/comapeo-client.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { createMapeoClient } from '@comapeo/ipc'

export function initComapeoClient() {
const { port1, port2 } = new MessageChannel()
window.postMessage('comapeo-port', '*', [port2])
const client = createMapeoClient(port1, { timeout: Infinity })
port1.start()
return client
}
41 changes: 0 additions & 41 deletions src/renderer/src/contexts/ApiContext.tsx

This file was deleted.

0 comments on commit c7d2878

Please sign in to comment.