# Refactoring work for the "MatrixStore" The `MatrixStore` has far to many roles and responsibilities. It needs to be broken down. In order to do this we need to examine the code and what it's methods do. ```mermaid classDiagram class MatrixStore { -_matrix -_uninstalledAppletInstances -_newAppletInstances -_installedAppletClasses -_appletGuis -_appletInstanceRenderers -_appletClassRenderers +myAgentPubKey() -constructor() +connect() +matrix() +profilesStore() +peerStatusStore() +sensemakerStore() +getWeGroupInfo() +fetchWeGroupInfo() +getAllWeGroupInfos() +getAppletClassInfo() +isInstalled() +isInstalledInGroup() +weGroupInfos() +installedAppletClasses() +fetchAppletInstanceRenderers() +fetchAppletClassRenderers() +queryAppletGui() +getProfileForWeGroupAgent() // Not implemented +getAppletInstanceInfosForGroup() +getUninstalledAppletInstanceInfosForGroup() +getInstanceInfosForAppletClass() +fetchAllApplets() +fetchNewAppletInstancesForGroup() +fetchNewAppletInstances() -originalWeDnaHash() +fetchMatrix() +inviteToJoinGroup() +createWeGroup() +joinWeGroup() +installWeGroup() +leaveWeGroup() +removeInvitation() +joinApplet() +createApplet() +reinstallApplet() +federateApplet() +disableApp() +enableApp() +uninstallApp() +fetchWebHapp() +decompressWebHapp() +getDevhubHapp() +getWeGroupInfoForAppletInstance() +getUninstalledAppletInstanceInfo() +getNewAppletInstanceInfo() +getAppletInstanceInfo() +releaseHashOfAppletInstance() +getInstalledAppletInfoListForClass() +isSameApp() +initializeStateForGroup() +getResourceView() } ``` Also, the zome code is split into the following chunks: * applets_coordinator * we_coordinator * peer_status_coordinator * profiles_coordinator ## Interlude: A view at the latest We The latest We break the libraries up into a few different components. * AppletBundleStore * AppletStore * CustomViewsStore * GroupStore * WeStore ```mermaid classDiagram class WeStore { +constructor() -_selectedAppletHash : Writable<AppletHash | undefined> +groupStore() +selectedAppletHash() +selectAppletHash() +availableUiUpdates: Record<InstalledAppId, ResourceLocatorB64> +fetchAvailableUiUpdates() +createGroup +joinGroup() +leaveGroup() +groupStores +installedApps +runningApps +installedApplets +runningApplets +runningGroupsApps +groupsDnaHashes +appletStores +allRunningApplets +allGroupsProfiles +getGroupsForApplet() +groupsForApplet +dnaLocations +hrlLocations +entryInfo +appletsForBundleHash +allAppletsHosts +allAttachmentTypes +installApplet() +uninstallApplet() +disableApplet() +enableApplet() +reloadManualStores() +isInstalled +isRunning +hrlToClipboard() +removeHrlFromClipboard() } class AppletBundlesStore{ +allAppletBundles +appletBundles +appletBundleLogo +constructor() +getVisibleHosts() +getLatestVersion() } class AppletStore { +host +attachmentTypes +blocks +logo +_unreadNotifications +constructor() +unreadNotifications() +setUnreadNotifications() +clearNotificationStatus() } class CustomViewsStore { +customViews +allCustomViews +constructor() } class GroupStore { +profilesStore: ProfilesStore +peerStatusStore: PeerStatusStore +groupClient: GroupClient +customViewsStore: CustomViewsStore +members : AsyncReadable<Array<AgentPubKey>> -constructed: boolean +constructor() +addRelatedGroup() +addFederatedApplet() +groupDnaModifiers() +networkSeed +groupProfile +installApplet() +installAndAdvertiseApplet() +appletFederatedGroups +applets +allMyRunningApplets +allMyApplets +allAdvertisedApplets +unjoinedApplets +activeAppletStores +allBlocks +relatedGroups +allUnreadNotifications +appletUiUpdatesAvailable } class GroupStore { +constructor() +addRelatedGroup() +addFederatedApplet() +groupDnaModifiers() +installApplet() +installAndAdvertiseApplet() } WeStore ..> AppletBundlesStore AppletStore ..> AppletBundlesStore WeStore ..> AppletStore WeStore ..> GroupStore GroupStore ..> CustomViewsStore GroupStore ..> WeStore ``` This is more broken down, but we can see: * There is a circular dependency between `WeStore` and `GroupStore`. * Multiple classes still have responsibilities relating to Applets. * `WeStore` has all the responsibility for installing an applet (really, it just defers to the Tauri command) in addition to managing groups. This may be part of a transitory period. * `GroupStore` defers to `WeStore` for some functions. * The two above things indicate a third class may be necessary, some thing like `AppManager`. * `AppletStore` is just a store for a particular applet. It constructs the iframe host of the application, stores the attachment types, stores the blocks, fetches the logo for the app from the `AppStore`, and proxies notifications from the localStorage. * `AppletBundlesStore` is a wrapper around the App Store zome. Strangely, the aspect around the public key has been shoved off onto `AppletBundleStore` where it's a property on the public `appstoreClient` property which takes the `AppAgentClient` On the plus side: * They are broken down more. It's fine if more than one class has responsibilities of one domain, and we can see a little bit of that here. However, the way the zomes are broken down is stil similar to the current situation. They have also been more fully realized, so there's a bunch more implemented functions. * custom_views * group_coordinator * peer_status_coordinator * profiles_coordinator The applets_coordinator zome has been roled into the group_coordinator zome. I find this to be a little strange, but they are related in some ways. It might be a little more correct to have a lobby type zome for the applets and related bits, while the group specific applet configs can live in the group. It's getting close to that, at any rate. ## Mapped out Data Structures There's a decent amount of what is likely unnecessary complexity in our data structures and the way the are indexed in the MatrixStore. Especially when we need to just reach in and grab some data that makes traversing through this structure very inefficient. We really need to have more of a graph store or set of indices that approximates a graph or at least the relationships and tranversals we need. There is definitely an inordinate amount of traversing from applet instance to WeGroup ```mermaid classDiagram direction LR class Matrix{ Matrix(WeGroupID) -> [WeGroupData, AppletInstanceInfo[]] } class WeGroupData { <<Interface>> info: WeGroupInfo appAgentWebsocket : AppAgentWebsocket profilesStore : ProfilesStore peerStatusStore : PeerStatusStore sensemakerStore : SensemakerStore } class WeGroupInfo { <<Interface>> info : NeighbourhoodInfo cell_id : CellId dna_hash : DnaHash cloneName : string enabled : boolean } class NeighbourhoodInfo { logoSrc: string name: string } class BaseAppletInstanceInfo { appletId: EntryHash applet: Applet federatedGroups: DnaHash[] } class UninstalledAppletInstanceInfo { <<Interface>> & BaseAppletInstanceInfo } class NewAppletInstanceInfo { <<Interface>> & BaseAppletInstanceInfo } class AppletInstanceInfo { <<Interface>> & BaseAppletInstanceInfo appInfo : AppInfo appAgentWebsocket? : AppAgentClient views? : AppletRenderers } class Applet { <<Interface>> // this is a subset of the AppletMetaData defined elsewhere customName: string title: string description: string logoSrc: string // B64 encoded img devhubHappReleaseHash: EntryHash devhubGuiReleaseHash: EntryHash properties: Record(RoleName, Uint8Array) networkSeed: Record(RoleName, string | undefined) // crypto.randomUUID() // assumed to be the same for each role //so this data structure is unnecessarily complex dnaHashes: Record(RoleName, DnaHash) // this is the key to mapping data types back // to the applet, basically we need to know the // role a datatype comes from, then we // can look up the DnaHash } class AppInfo { <<Interface>> // Note: // install_app_id should be viewed as an instance id // each copy of the same version of the app should have // the same sha1 hash and all components/dimensions/etc. // should be mapped to the same sha1 hash of the built app agent_pub_key: AgentPubKey installed_app_id: string // applet@we-network_seed_sha1-customName // this comes from the above structure } Matrix --> WeGroupData WeGroupData --> WeGroupInfo WeGroupInfo --> NeighbourhoodInfo Matrix --> AppletInstanceInfo AppletInstanceInfo --> BaseAppletInstanceInfo UninstalledAppletInstanceInfo --> BaseAppletInstanceInfo NewAppletInstanceInfo --> BaseAppletInstanceInfo AppletInstanceInfo --> AppInfo BaseAppletInstanceInfo --> Applet class AppletClassData { <<Interface>> info : AppletClassInfo renderers : AppletRenderers } class AppletClassInfo { <<Interface>> devhubHappReleaseHash : EntryHash title : string logoSrc : string | undefined description : string } AppletClassData --> AppletClassInfo ```