aboutsummaryrefslogtreecommitdiffstats
path: root/packages/preload/src/contextBridge/SophieRendererImpl.ts
diff options
context:
space:
mode:
Diffstat (limited to 'packages/preload/src/contextBridge/SophieRendererImpl.ts')
-rw-r--r--packages/preload/src/contextBridge/SophieRendererImpl.ts36
1 files changed, 16 insertions, 20 deletions
diff --git a/packages/preload/src/contextBridge/SophieRendererImpl.ts b/packages/preload/src/contextBridge/SophieRendererImpl.ts
index bbb4f65..18ab07e 100644
--- a/packages/preload/src/contextBridge/SophieRendererImpl.ts
+++ b/packages/preload/src/contextBridge/SophieRendererImpl.ts
@@ -18,46 +18,44 @@
18 * SPDX-License-Identifier: AGPL-3.0-only 18 * SPDX-License-Identifier: AGPL-3.0-only
19 */ 19 */
20 20
21import { ipcRenderer } from 'electron';
21import type { IJsonPatch } from 'mobx-state-tree'; 22import type { IJsonPatch } from 'mobx-state-tree';
22import { 23import {
23 Action, 24 Action,
24 action, 25 action,
26 MainToRendererIpcMessage,
27 RendererToMainIpcMessage,
25 sharedStore, 28 sharedStore,
26 SharedStoreListener, 29 SharedStoreListener,
27 SophieRenderer, 30 SophieRenderer,
28} from '@sophie/shared'; 31} from '@sophie/shared';
29 32
30import { IpcRendererService } from '../services/IpcRendererService';
31
32class SophieRendererImpl implements SophieRenderer { 33class SophieRendererImpl implements SophieRenderer {
33 readonly #ipcService; 34 private onSharedStoreChangeCalled: boolean = false;
34
35 #onSharedStoreChangeCalled: boolean = false;
36 35
37 #listener: SharedStoreListener | null = null; 36 private listener: SharedStoreListener | null = null;
38 37
39 constructor(ipcService: IpcRendererService) { 38 constructor() {
40 this.#ipcService = ipcService; 39 ipcRenderer.on(MainToRendererIpcMessage.SharedStorePatch, (_event, patch) => {
41 this.#ipcService.onSharedStorePatch((patch) => {
42 try { 40 try {
43 // `mobx-state-tree` will validate the patch, so we can safely cast here. 41 // `mobx-state-tree` will validate the patch, so we can safely cast here.
44 this.#listener?.onPatch(patch as IJsonPatch); 42 this.listener?.onPatch(patch as IJsonPatch);
45 } catch (err) { 43 } catch (err) {
46 console.error('Shared store listener onPatch failed', err); 44 console.error('Shared store listener onPatch failed', err);
47 this.#listener = null; 45 this.listener = null;
48 } 46 }
49 }); 47 });
50 } 48 }
51 49
52 async onSharedStoreChange(listener: SharedStoreListener): Promise<void> { 50 async onSharedStoreChange(listener: SharedStoreListener): Promise<void> {
53 if (this.#onSharedStoreChangeCalled) { 51 if (this.onSharedStoreChangeCalled) {
54 throw new Error('Shared store change listener was already set'); 52 throw new Error('Shared store change listener was already set');
55 } 53 }
56 this.#onSharedStoreChangeCalled = true; 54 this.onSharedStoreChangeCalled = true;
57 let success = false; 55 let success = false;
58 let snapshot: unknown | null = null; 56 let snapshot: unknown | null = null;
59 try { 57 try {
60 snapshot = await this.#ipcService.getSharedStoreSnapshot(); 58 snapshot = await ipcRenderer.invoke(RendererToMainIpcMessage.GetSharedStoreSnapshot);
61 success = true; 59 success = true;
62 } catch (err) { 60 } catch (err) {
63 console.error('Failed to get initial shared store snapshot', err); 61 console.error('Failed to get initial shared store snapshot', err);
@@ -65,7 +63,7 @@ class SophieRendererImpl implements SophieRenderer {
65 if (success) { 63 if (success) {
66 if (sharedStore.is(snapshot)) { 64 if (sharedStore.is(snapshot)) {
67 listener.onSnapshot(snapshot); 65 listener.onSnapshot(snapshot);
68 this.#listener = listener; 66 this.listener = listener;
69 return; 67 return;
70 } 68 }
71 console.error('Got invalid initial shared store snapshot', snapshot); 69 console.error('Got invalid initial shared store snapshot', snapshot);
@@ -78,7 +76,7 @@ class SophieRendererImpl implements SophieRenderer {
78 // since all data it may contain was provided from the main world. 76 // since all data it may contain was provided from the main world.
79 const parsedAction = action.parse(actionToDispatch); 77 const parsedAction = action.parse(actionToDispatch);
80 try { 78 try {
81 this.#ipcService.dispatchAction(parsedAction); 79 ipcRenderer.send(RendererToMainIpcMessage.DispatchAction, parsedAction);
82 } catch (err) { 80 } catch (err) {
83 // Do not leak IPC failure details into the main world. 81 // Do not leak IPC failure details into the main world.
84 const message = 'Failed to dispatch action'; 82 const message = 'Failed to dispatch action';
@@ -88,10 +86,8 @@ class SophieRendererImpl implements SophieRenderer {
88 } 86 }
89} 87}
90 88
91export function createSophieRenderer( 89export function createSophieRenderer(): SophieRenderer {
92 ipcService: IpcRendererService, 90 const impl = new SophieRendererImpl();
93): SophieRenderer {
94 const impl = new SophieRendererImpl(ipcService);
95 return { 91 return {
96 onSharedStoreChange: impl.onSharedStoreChange.bind(impl), 92 onSharedStoreChange: impl.onSharedStoreChange.bind(impl),
97 dispatchAction: impl.dispatchAction.bind(impl), 93 dispatchAction: impl.dispatchAction.bind(impl),