diff options
Diffstat (limited to 'packages/preload/src/contextBridge/SophieRendererImpl.ts')
-rw-r--r-- | packages/preload/src/contextBridge/SophieRendererImpl.ts | 36 |
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 | ||
21 | import { ipcRenderer } from 'electron'; | ||
21 | import type { IJsonPatch } from 'mobx-state-tree'; | 22 | import type { IJsonPatch } from 'mobx-state-tree'; |
22 | import { | 23 | import { |
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 | ||
30 | import { IpcRendererService } from '../services/IpcRendererService'; | ||
31 | |||
32 | class SophieRendererImpl implements SophieRenderer { | 33 | class 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 | ||
91 | export function createSophieRenderer( | 89 | export 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), |