diff options
author | Kristóf Marussy <kristof@marussy.com> | 2022-02-27 00:57:44 +0100 |
---|---|---|
committer | Kristóf Marussy <kristof@marussy.com> | 2022-03-06 18:56:46 +0100 |
commit | f05d54406c9bc4b69609a4935132ff17b8e28824 (patch) | |
tree | e7ffde8f8b3433e004932a6e068dedbb4f2196da /packages/renderer/src | |
parent | design: Simpler message count indicators (diff) | |
download | sophie-f05d54406c9bc4b69609a4935132ff17b8e28824.tar.gz sophie-f05d54406c9bc4b69609a4935132ff17b8e28824.tar.zst sophie-f05d54406c9bc4b69609a4935132ff17b8e28824.zip |
refactor: Shared model type factories
Allows customization of stores both in the renderer and in the main
process. Instead of exposing a basic model type from the shared module
(which was be overwritted with more specific props in the main package),
we expose factory function that can create specific model types in
both the renderer and the main process.
Using these package-specific customization to stores, the renderer
package can attach IPC calls directly to store objects, which the main
package can attach the handlers for IPC calls and other internal
actions.
Signed-off-by: Kristóf Marussy <kristof@marussy.com>
Diffstat (limited to 'packages/renderer/src')
12 files changed, 241 insertions, 55 deletions
diff --git a/packages/renderer/src/components/locationBar/LocationTextField.tsx b/packages/renderer/src/components/locationBar/LocationTextField.tsx index f436bf0..e6da59f 100644 --- a/packages/renderer/src/components/locationBar/LocationTextField.tsx +++ b/packages/renderer/src/components/locationBar/LocationTextField.tsx | |||
@@ -20,11 +20,12 @@ | |||
20 | 20 | ||
21 | import FilledInput from '@mui/material/FilledInput'; | 21 | import FilledInput from '@mui/material/FilledInput'; |
22 | import { styled } from '@mui/material/styles'; | 22 | import { styled } from '@mui/material/styles'; |
23 | import { Service } from '@sophie/shared'; | ||
24 | import { autorun } from 'mobx'; | 23 | import { autorun } from 'mobx'; |
25 | import { observer } from 'mobx-react-lite'; | 24 | import { observer } from 'mobx-react-lite'; |
26 | import React, { useCallback, useEffect, useState } from 'react'; | 25 | import React, { useCallback, useEffect, useState } from 'react'; |
27 | 26 | ||
27 | import Service from '../../stores/Service'; | ||
28 | |||
28 | import GoAdornment from './GoAdornment'; | 29 | import GoAdornment from './GoAdornment'; |
29 | import LocationOverlayInput from './LocationOverlayInput'; | 30 | import LocationOverlayInput from './LocationOverlayInput'; |
30 | import UrlAdornment from './UrlAdornment'; | 31 | import UrlAdornment from './UrlAdornment'; |
diff --git a/packages/renderer/src/components/locationBar/NavigationButtons.tsx b/packages/renderer/src/components/locationBar/NavigationButtons.tsx index 77b02b6..ce59692 100644 --- a/packages/renderer/src/components/locationBar/NavigationButtons.tsx +++ b/packages/renderer/src/components/locationBar/NavigationButtons.tsx | |||
@@ -26,10 +26,11 @@ import IconRefresh from '@mui/icons-material/Refresh'; | |||
26 | import { useTheme } from '@mui/material'; | 26 | import { useTheme } from '@mui/material'; |
27 | import Box from '@mui/material/Box'; | 27 | import Box from '@mui/material/Box'; |
28 | import IconButton from '@mui/material/IconButton'; | 28 | import IconButton from '@mui/material/IconButton'; |
29 | import { Service } from '@sophie/shared'; | ||
30 | import { observer } from 'mobx-react-lite'; | 29 | import { observer } from 'mobx-react-lite'; |
31 | import React from 'react'; | 30 | import React from 'react'; |
32 | 31 | ||
32 | import Service from '../../stores/Service'; | ||
33 | |||
33 | function NavigationButtons({ | 34 | function NavigationButtons({ |
34 | service, | 35 | service, |
35 | }: { | 36 | }: { |
diff --git a/packages/renderer/src/components/sidebar/ServiceIcon.tsx b/packages/renderer/src/components/sidebar/ServiceIcon.tsx index 144f860..5db8a0c 100644 --- a/packages/renderer/src/components/sidebar/ServiceIcon.tsx +++ b/packages/renderer/src/components/sidebar/ServiceIcon.tsx | |||
@@ -20,10 +20,11 @@ | |||
20 | 20 | ||
21 | import Badge from '@mui/material/Badge'; | 21 | import Badge from '@mui/material/Badge'; |
22 | import { styled, useTheme } from '@mui/material/styles'; | 22 | import { styled, useTheme } from '@mui/material/styles'; |
23 | import { Service } from '@sophie/shared'; | ||
24 | import { observer } from 'mobx-react-lite'; | 23 | import { observer } from 'mobx-react-lite'; |
25 | import React, { useEffect, useState } from 'react'; | 24 | import React, { useEffect, useState } from 'react'; |
26 | 25 | ||
26 | import type Service from '../../stores/Service'; | ||
27 | |||
27 | const ServiceIconRoot = styled('div', { | 28 | const ServiceIconRoot = styled('div', { |
28 | name: 'ServiceIcon', | 29 | name: 'ServiceIcon', |
29 | slot: 'Root', | 30 | slot: 'Root', |
diff --git a/packages/renderer/src/components/sidebar/ServiceSwitcher.tsx b/packages/renderer/src/components/sidebar/ServiceSwitcher.tsx index 2241476..eba21b5 100644 --- a/packages/renderer/src/components/sidebar/ServiceSwitcher.tsx +++ b/packages/renderer/src/components/sidebar/ServiceSwitcher.tsx | |||
@@ -65,11 +65,8 @@ const ServiceSwitcherTab = styled(Tab, { | |||
65 | })); | 65 | })); |
66 | 66 | ||
67 | function ServiceSwitcher(): JSX.Element { | 67 | function ServiceSwitcher(): JSX.Element { |
68 | const store = useStore(); | 68 | const { settings, services } = useStore(); |
69 | const { | 69 | const { selectedService } = settings; |
70 | settings: { selectedService }, | ||
71 | services, | ||
72 | } = store; | ||
73 | 70 | ||
74 | return ( | 71 | return ( |
75 | <ServiceSwitcherRoot | 72 | <ServiceSwitcherRoot |
@@ -77,7 +74,7 @@ function ServiceSwitcher(): JSX.Element { | |||
77 | orientation="vertical" | 74 | orientation="vertical" |
78 | value={selectedService === undefined ? false : selectedService.id} | 75 | value={selectedService === undefined ? false : selectedService.id} |
79 | onChange={(_event, newValue: string) => | 76 | onChange={(_event, newValue: string) => |
80 | store.setSelectedServiceId(newValue) | 77 | settings.setSelectedServiceId(newValue) |
81 | } | 78 | } |
82 | > | 79 | > |
83 | {services.map((service) => ( | 80 | {services.map((service) => ( |
diff --git a/packages/renderer/src/components/sidebar/ToggleDarkModeButton.tsx b/packages/renderer/src/components/sidebar/ToggleDarkModeButton.tsx index 164b066..bacbf07 100644 --- a/packages/renderer/src/components/sidebar/ToggleDarkModeButton.tsx +++ b/packages/renderer/src/components/sidebar/ToggleDarkModeButton.tsx | |||
@@ -27,15 +27,13 @@ import React from 'react'; | |||
27 | import { useStore } from '../StoreProvider'; | 27 | import { useStore } from '../StoreProvider'; |
28 | 28 | ||
29 | export default observer(() => { | 29 | export default observer(() => { |
30 | const store = useStore(); | 30 | const { shared } = useStore(); |
31 | const { | 31 | const { shouldUseDarkColors } = shared; |
32 | shared: { shouldUseDarkColors }, | ||
33 | } = store; | ||
34 | 32 | ||
35 | return ( | 33 | return ( |
36 | <IconButton | 34 | <IconButton |
37 | aria-label="Toggle dark mode" | 35 | aria-label="Toggle dark mode" |
38 | onClick={() => store.toggleDarkMode()} | 36 | onClick={() => shared.toggleDarkMode()} |
39 | > | 37 | > |
40 | {shouldUseDarkColors ? <LightModeIcon /> : <DarkModeIcon />} | 38 | {shouldUseDarkColors ? <LightModeIcon /> : <DarkModeIcon />} |
41 | </IconButton> | 39 | </IconButton> |
diff --git a/packages/renderer/src/components/sidebar/ToggleLocationBarButton.tsx b/packages/renderer/src/components/sidebar/ToggleLocationBarButton.tsx index 60033b0..d2f0745 100644 --- a/packages/renderer/src/components/sidebar/ToggleLocationBarButton.tsx +++ b/packages/renderer/src/components/sidebar/ToggleLocationBarButton.tsx | |||
@@ -45,17 +45,15 @@ function ToggleLocationBarIcon({ | |||
45 | } | 45 | } |
46 | 46 | ||
47 | function ToggleLocationBarButton(): JSX.Element { | 47 | function ToggleLocationBarButton(): JSX.Element { |
48 | const store = useStore(); | 48 | const { settings } = useStore(); |
49 | const { | 49 | const { selectedService, showLocationBar } = settings; |
50 | settings: { selectedService, showLocationBar }, | ||
51 | } = store; | ||
52 | 50 | ||
53 | return ( | 51 | return ( |
54 | <IconButton | 52 | <IconButton |
55 | aria-pressed={showLocationBar} | 53 | aria-pressed={showLocationBar} |
56 | aria-controls={LOCATION_BAR_ID} | 54 | aria-controls={LOCATION_BAR_ID} |
57 | aria-label="Show location bar" | 55 | aria-label="Show location bar" |
58 | onClick={() => store.toggleLocationBar()} | 56 | onClick={() => settings.toggleLocationBar()} |
59 | > | 57 | > |
60 | <ToggleLocationBarIcon | 58 | <ToggleLocationBarIcon |
61 | loading={selectedService?.state === 'loading'} | 59 | loading={selectedService?.state === 'loading'} |
diff --git a/packages/renderer/src/stores/GlobalSettings.ts b/packages/renderer/src/stores/GlobalSettings.ts new file mode 100644 index 0000000..79815ba --- /dev/null +++ b/packages/renderer/src/stores/GlobalSettings.ts | |||
@@ -0,0 +1,63 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2022 Kristóf Marussy <kristof@marussy.com> | ||
3 | * | ||
4 | * This file is part of Sophie. | ||
5 | * | ||
6 | * Sophie is free software: you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU Affero General Public License as | ||
8 | * published by the Free Software Foundation, version 3. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | * GNU Affero General Public License for more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU Affero General Public License | ||
16 | * along with this program. If not, see <https://www.gnu.org/licenses/>. | ||
17 | * | ||
18 | * SPDX-License-Identifier: AGPL-3.0-only | ||
19 | */ | ||
20 | |||
21 | import { defineGlobalSettingsModel, ThemeSource } from '@sophie/shared'; | ||
22 | import { Instance } from 'mobx-state-tree'; | ||
23 | |||
24 | import getEnv from '../env/getEnv'; | ||
25 | |||
26 | import Service from './Service'; | ||
27 | |||
28 | const GlobalSettings = defineGlobalSettingsModel(Service).actions((self) => ({ | ||
29 | setSelectedServiceId(serviceId: string): void { | ||
30 | getEnv(self).dispatchMainAction({ | ||
31 | action: 'set-selected-service-id', | ||
32 | serviceId, | ||
33 | }); | ||
34 | }, | ||
35 | setThemeSource(themeSource: ThemeSource): void { | ||
36 | getEnv(self).dispatchMainAction({ | ||
37 | action: 'set-theme-source', | ||
38 | themeSource, | ||
39 | }); | ||
40 | }, | ||
41 | setShowLocationBar(showLocationBar: boolean): void { | ||
42 | getEnv(self).dispatchMainAction({ | ||
43 | action: 'set-show-location-bar', | ||
44 | showLocationBar, | ||
45 | }); | ||
46 | }, | ||
47 | toggleLocationBar(): void { | ||
48 | this.setShowLocationBar(!self.showLocationBar); | ||
49 | }, | ||
50 | })); | ||
51 | |||
52 | /* | ||
53 | eslint-disable-next-line @typescript-eslint/no-redeclare -- | ||
54 | Intentionally naming the type the same as the store definition. | ||
55 | */ | ||
56 | interface GlobalSettings extends Instance<typeof GlobalSettings> {} | ||
57 | |||
58 | export default GlobalSettings; | ||
59 | |||
60 | export type { | ||
61 | GlobalSettingsSnapshotIn, | ||
62 | GlobalSettingsSnapshotOut, | ||
63 | } from '@sophie/shared'; | ||
diff --git a/packages/renderer/src/stores/Profile.ts b/packages/renderer/src/stores/Profile.ts new file mode 100644 index 0000000..20a3a17 --- /dev/null +++ b/packages/renderer/src/stores/Profile.ts | |||
@@ -0,0 +1,32 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2022 Kristóf Marussy <kristof@marussy.com> | ||
3 | * | ||
4 | * This file is part of Sophie. | ||
5 | * | ||
6 | * Sophie is free software: you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU Affero General Public License as | ||
8 | * published by the Free Software Foundation, version 3. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | * GNU Affero General Public License for more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU Affero General Public License | ||
16 | * along with this program. If not, see <https://www.gnu.org/licenses/>. | ||
17 | * | ||
18 | * SPDX-License-Identifier: AGPL-3.0-only | ||
19 | */ | ||
20 | |||
21 | import { Profile as ProfileBase } from '@sophie/shared'; | ||
22 | import { Instance } from 'mobx-state-tree'; | ||
23 | |||
24 | const Profile = ProfileBase; | ||
25 | |||
26 | /* | ||
27 | eslint-disable-next-line @typescript-eslint/no-redeclare -- | ||
28 | Intentionally naming the type the same as the store definition. | ||
29 | */ | ||
30 | interface Profile extends Instance<typeof Profile> {} | ||
31 | |||
32 | export default Profile; | ||
diff --git a/packages/renderer/src/stores/RendererStore.ts b/packages/renderer/src/stores/RendererStore.ts index 1acc605..8f424f6 100644 --- a/packages/renderer/src/stores/RendererStore.ts +++ b/packages/renderer/src/stores/RendererStore.ts | |||
@@ -18,20 +18,17 @@ | |||
18 | * SPDX-License-Identifier: AGPL-3.0-only | 18 | * SPDX-License-Identifier: AGPL-3.0-only |
19 | */ | 19 | */ |
20 | 20 | ||
21 | import { | 21 | import { BrowserViewBounds, SophieRenderer } from '@sophie/shared'; |
22 | BrowserViewBounds, | ||
23 | SharedStore, | ||
24 | Service, | ||
25 | SophieRenderer, | ||
26 | ThemeSource, | ||
27 | GlobalSettings, | ||
28 | } from '@sophie/shared'; | ||
29 | import { applySnapshot, applyPatch, Instance, types } from 'mobx-state-tree'; | 22 | import { applySnapshot, applyPatch, Instance, types } from 'mobx-state-tree'; |
30 | 23 | ||
31 | import RendererEnv from '../env/RendererEnv'; | 24 | import RendererEnv from '../env/RendererEnv'; |
32 | import getEnv from '../env/getEnv'; | 25 | import getEnv from '../env/getEnv'; |
33 | import { getLogger } from '../utils/log'; | 26 | import { getLogger } from '../utils/log'; |
34 | 27 | ||
28 | import GlobalSettings from './GlobalSettings'; | ||
29 | import Service from './Service'; | ||
30 | import SharedStore from './SharedStore'; | ||
31 | |||
35 | const log = getLogger('RendererStore'); | 32 | const log = getLogger('RendererStore'); |
36 | 33 | ||
37 | const RendererStore = types | 34 | const RendererStore = types |
@@ -47,40 +44,12 @@ const RendererStore = types | |||
47 | }, | 44 | }, |
48 | })) | 45 | })) |
49 | .actions((self) => ({ | 46 | .actions((self) => ({ |
50 | setSelectedServiceId(serviceId: string): void { | ||
51 | getEnv(self).dispatchMainAction({ | ||
52 | action: 'set-selected-service-id', | ||
53 | serviceId, | ||
54 | }); | ||
55 | }, | ||
56 | setBrowserViewBounds(browserViewBounds: BrowserViewBounds): void { | 47 | setBrowserViewBounds(browserViewBounds: BrowserViewBounds): void { |
57 | getEnv(self).dispatchMainAction({ | 48 | getEnv(self).dispatchMainAction({ |
58 | action: 'set-browser-view-bounds', | 49 | action: 'set-browser-view-bounds', |
59 | browserViewBounds, | 50 | browserViewBounds, |
60 | }); | 51 | }); |
61 | }, | 52 | }, |
62 | setThemeSource(themeSource: ThemeSource): void { | ||
63 | getEnv(self).dispatchMainAction({ | ||
64 | action: 'set-theme-source', | ||
65 | themeSource, | ||
66 | }); | ||
67 | }, | ||
68 | toggleDarkMode(): void { | ||
69 | if (self.shared.shouldUseDarkColors) { | ||
70 | this.setThemeSource('light'); | ||
71 | } else { | ||
72 | this.setThemeSource('dark'); | ||
73 | } | ||
74 | }, | ||
75 | setShowLocationBar(showLocationBar: boolean): void { | ||
76 | getEnv(self).dispatchMainAction({ | ||
77 | action: 'set-show-location-bar', | ||
78 | showLocationBar, | ||
79 | }); | ||
80 | }, | ||
81 | toggleLocationBar(): void { | ||
82 | this.setShowLocationBar(!self.settings.showLocationBar); | ||
83 | }, | ||
84 | })); | 53 | })); |
85 | 54 | ||
86 | /* | 55 | /* |
diff --git a/packages/renderer/src/stores/Service.ts b/packages/renderer/src/stores/Service.ts new file mode 100644 index 0000000..c2c938a --- /dev/null +++ b/packages/renderer/src/stores/Service.ts | |||
@@ -0,0 +1,34 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2022 Kristóf Marussy <kristof@marussy.com> | ||
3 | * | ||
4 | * This file is part of Sophie. | ||
5 | * | ||
6 | * Sophie is free software: you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU Affero General Public License as | ||
8 | * published by the Free Software Foundation, version 3. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | * GNU Affero General Public License for more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU Affero General Public License | ||
16 | * along with this program. If not, see <https://www.gnu.org/licenses/>. | ||
17 | * | ||
18 | * SPDX-License-Identifier: AGPL-3.0-only | ||
19 | */ | ||
20 | |||
21 | import { defineServiceModel } from '@sophie/shared'; | ||
22 | import { Instance } from 'mobx-state-tree'; | ||
23 | |||
24 | import ServiceSettings from './ServiceSettings'; | ||
25 | |||
26 | const Service = defineServiceModel(ServiceSettings); | ||
27 | |||
28 | /* | ||
29 | eslint-disable-next-line @typescript-eslint/no-redeclare -- | ||
30 | Intentionally naming the type the same as the store definition. | ||
31 | */ | ||
32 | interface Service extends Instance<typeof Service> {} | ||
33 | |||
34 | export default Service; | ||
diff --git a/packages/renderer/src/stores/ServiceSettings.ts b/packages/renderer/src/stores/ServiceSettings.ts new file mode 100644 index 0000000..5d37347 --- /dev/null +++ b/packages/renderer/src/stores/ServiceSettings.ts | |||
@@ -0,0 +1,39 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2022 Kristóf Marussy <kristof@marussy.com> | ||
3 | * | ||
4 | * This file is part of Sophie. | ||
5 | * | ||
6 | * Sophie is free software: you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU Affero General Public License as | ||
8 | * published by the Free Software Foundation, version 3. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | * GNU Affero General Public License for more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU Affero General Public License | ||
16 | * along with this program. If not, see <https://www.gnu.org/licenses/>. | ||
17 | * | ||
18 | * SPDX-License-Identifier: AGPL-3.0-only | ||
19 | */ | ||
20 | |||
21 | import { defineServiceSettingsModel } from '@sophie/shared'; | ||
22 | import { Instance } from 'mobx-state-tree'; | ||
23 | |||
24 | import Profile from './Profile'; | ||
25 | |||
26 | const ServiceSettings = defineServiceSettingsModel(Profile); | ||
27 | |||
28 | /* | ||
29 | eslint-disable-next-line @typescript-eslint/no-redeclare -- | ||
30 | Intentionally naming the type the same as the store definition. | ||
31 | */ | ||
32 | interface ServiceSettings extends Instance<typeof ServiceSettings> {} | ||
33 | |||
34 | export default ServiceSettings; | ||
35 | |||
36 | export type { | ||
37 | ServiceSettingsSnapshotIn, | ||
38 | ServiceSettingsSnapshotOut, | ||
39 | } from '@sophie/shared'; | ||
diff --git a/packages/renderer/src/stores/SharedStore.ts b/packages/renderer/src/stores/SharedStore.ts new file mode 100644 index 0000000..062479d --- /dev/null +++ b/packages/renderer/src/stores/SharedStore.ts | |||
@@ -0,0 +1,53 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2022 Kristóf Marussy <kristof@marussy.com> | ||
3 | * | ||
4 | * This file is part of Sophie. | ||
5 | * | ||
6 | * Sophie is free software: you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU Affero General Public License as | ||
8 | * published by the Free Software Foundation, version 3. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | * GNU Affero General Public License for more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU Affero General Public License | ||
16 | * along with this program. If not, see <https://www.gnu.org/licenses/>. | ||
17 | * | ||
18 | * SPDX-License-Identifier: AGPL-3.0-only | ||
19 | */ | ||
20 | |||
21 | import { defineSharedStoreModel } from '@sophie/shared'; | ||
22 | import { Instance } from 'mobx-state-tree'; | ||
23 | |||
24 | import GlobalSettings from './GlobalSettings'; | ||
25 | import Profile from './Profile'; | ||
26 | import Service from './Service'; | ||
27 | |||
28 | const SharedStore = defineSharedStoreModel( | ||
29 | GlobalSettings, | ||
30 | Profile, | ||
31 | Service, | ||
32 | ).actions((self) => ({ | ||
33 | toggleDarkMode(): void { | ||
34 | if (self.shouldUseDarkColors) { | ||
35 | self.settings.setThemeSource('light'); | ||
36 | } else { | ||
37 | self.settings.setThemeSource('dark'); | ||
38 | } | ||
39 | }, | ||
40 | })); | ||
41 | |||
42 | /* | ||
43 | eslint-disable-next-line @typescript-eslint/no-redeclare -- | ||
44 | Intentionally naming the type the same as the store definition. | ||
45 | */ | ||
46 | interface SharedStore extends Instance<typeof SharedStore> {} | ||
47 | |||
48 | export default SharedStore; | ||
49 | |||
50 | export type { | ||
51 | SharedStoreSnapshotIn, | ||
52 | SharedStoreSnapshotOut, | ||
53 | } from '@sophie/shared'; | ||