diff options
Diffstat (limited to 'packages')
-rw-r--r-- | packages/preload/src/contextBridge/SophieRendererImpl.ts | 58 |
1 files changed, 43 insertions, 15 deletions
diff --git a/packages/preload/src/contextBridge/SophieRendererImpl.ts b/packages/preload/src/contextBridge/SophieRendererImpl.ts index 5d29071..153fdd1 100644 --- a/packages/preload/src/contextBridge/SophieRendererImpl.ts +++ b/packages/preload/src/contextBridge/SophieRendererImpl.ts | |||
@@ -32,35 +32,63 @@ import { RendererToMainIpcService } from '../services/RendererToMainIpcService'; | |||
32 | class SophieRendererImpl implements SophieRenderer { | 32 | class SophieRendererImpl implements SophieRenderer { |
33 | readonly #ipcService: RendererToMainIpcService; | 33 | readonly #ipcService: RendererToMainIpcService; |
34 | 34 | ||
35 | #onSharedStoreChangeCalled = false; | ||
36 | |||
35 | #listener: SharedStoreListener | null = null; | 37 | #listener: SharedStoreListener | null = null; |
36 | 38 | ||
37 | constructor(ipcService: RendererToMainIpcService) { | 39 | constructor(ipcService: RendererToMainIpcService) { |
38 | this.#ipcService = ipcService; | 40 | this.#ipcService = ipcService; |
39 | ipcService.onSharedStorePatch((patch) => { | 41 | ipcService.onSharedStorePatch((patch) => { |
40 | // `mobx-state-tree` will validate the patch, so we can safely cast here. | 42 | try { |
41 | this.#listener?.onPatch(patch as IJsonPatch); | 43 | // `mobx-state-tree` will validate the patch, so we can safely cast here. |
44 | this.#listener?.onPatch(patch as IJsonPatch); | ||
45 | } catch (err) { | ||
46 | console.log('Shared store listener onPatch failed', err); | ||
47 | } | ||
42 | }); | 48 | }); |
43 | } | 49 | } |
44 | 50 | ||
45 | onSharedStoreChange(listener: SharedStoreListener): void { | 51 | async #setSharedStoreChangeListener(listener: SharedStoreListener): Promise<void> { |
46 | this.#ipcService.getSharedStoreSnapshot().then((snapshot) => { | 52 | let snapshot: unknown; |
47 | if (sharedStore.is(snapshot)) { | 53 | try { |
54 | snapshot = await this.#ipcService.getSharedStoreSnapshot(); | ||
55 | } catch (err) { | ||
56 | console.error('Failed to get initial shared store snapshot', err); | ||
57 | return; | ||
58 | } | ||
59 | if (sharedStore.is(snapshot)) { | ||
60 | try { | ||
48 | listener.onSnapshot(snapshot); | 61 | listener.onSnapshot(snapshot); |
49 | this.#listener = listener; | 62 | } catch (err) { |
50 | } else { | 63 | console.error('Shared store listener onSnapshot failed', err); |
51 | console.error('Got invalid initial shared store snapshot', snapshot); | 64 | return; |
52 | } | 65 | } |
53 | }).catch((err) => { | 66 | this.#listener = listener; |
54 | console.error('Failed set initial shared store snapshot', err); | 67 | return; |
68 | } | ||
69 | console.error('Got invalid initial shared store snapshot', snapshot); | ||
70 | } | ||
71 | |||
72 | onSharedStoreChange(listener: SharedStoreListener): void { | ||
73 | if (this.#onSharedStoreChangeCalled) { | ||
74 | throw new Error('Shared store change listener was already set'); | ||
75 | } | ||
76 | this.#setSharedStoreChangeListener(listener).catch((err) => { | ||
77 | console.log('Failed to set shared store change listener', err); | ||
55 | }); | 78 | }); |
56 | } | 79 | } |
57 | 80 | ||
58 | dispatchAction(actionToDispatch: Action): void { | 81 | dispatchAction(actionToDispatch: Action): void { |
59 | const parsedAction = action.safeParse(actionToDispatch); | 82 | // Let the full zod parse error bubble up to the main world, |
60 | if (parsedAction.success) { | 83 | // since all data it may contain was provided from the main world. |
61 | this.#ipcService.dispatchAction(parsedAction.data); | 84 | const parsedAction = action.parse(actionToDispatch); |
62 | } else { | 85 | try { |
63 | console.error('Trying to dispatch invalid action', actionToDispatch, parsedAction.error); | 86 | this.#ipcService.dispatchAction(parsedAction); |
87 | } catch (err) { | ||
88 | // Do not leak IPC failure details into the main world. | ||
89 | const message = 'Failed to dispatch action'; | ||
90 | console.error(message, actionToDispatch, err); | ||
91 | throw new Error(message); | ||
64 | } | 92 | } |
65 | } | 93 | } |
66 | } | 94 | } |