aboutsummaryrefslogtreecommitdiffstats
path: root/packages/renderer/src/stores/RootStore.ts
blob: 86efac6fed92725df03e48760e127b9d6041ec29 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
import {
  applySnapshot,
  applyPatch,
  getEnv as getAnyEnv,
  IAnyStateTreeNode,
  Instance,
  types
} from 'mobx-state-tree';
import { sharedStore, SophieRenderer } from '@sophie/shared';

export interface RootEnv {
  ipc: SophieRenderer;
}

/**
 * Gets a well-typed environment from `model`.
 *
 * Only useable inside state trees created by `createAndConnectRootStore`.
 *
 * @param model The state tree node.
 */
export function getEnv(model: IAnyStateTreeNode): RootEnv {
  return getAnyEnv<RootEnv>(model);
}

export const rootStore = types.model('RootStore', {
  shared: sharedStore,
}).actions((self) => ({
  buttonClick() {
    getEnv(self).ipc.buttonClick();
  },
}));

export interface RootStore extends Instance<typeof rootStore> {}

/**
 * Creates a new `RootStore` with a new environment and connects it to `ipc`.
 *
 * Changes to the `shared` store in the main process will be propagated to
 * the newly created store via `ipc`.
 *
 * @param ipc The `sophieRenderer` context bridge.
 */
export function createAndConnectRootStore(ipc: SophieRenderer): RootStore {
  const store = rootStore.create({
    shared: {},
  }, {
    ipc,
  });

  ipc.setSharedStoreListener({
    onSnapshot(snapshot) {
      applySnapshot(store.shared, snapshot);
    },
    onPatch(patch) {
      applyPatch(store.shared, patch);
    },
  });

  return store;
}