# Ahau maintenance / complexity mentoring Purpose: high level review of current app state, leading to advice on what to focus on / research, or gotchas/ code smells ## Agenda - architecture overview - complexity - testing ## architecture overview ``` front-end - vue - vuex - vue-router - apollo ---+ | | ----- | | graphql API : +===============================+ | @ssb-graphql/whakapapa ---+ | | @ssb-graphql/profile | |-------+ | | | | | +=========|=================|===+ | | | | plugins: ssb-profile, ssb-whakapapa, ssb-ahau | --crut-- / \ indexes: backlinks query log: ||||||| ``` - database : - log: ssb-db, - indexes: - ssb-backlinks - ssb-query - record helpers: (using ssb-crut) - ssb-profile - ssb-artefact - ssb-whakapapa - general plugins - ssb-tribes (group encryption) - ssb-invites - ssb-friends - ssb-conn - ssb-replicate - ssb-blobs + ssb-serve-blobs - ssb-hyper-blobs - API : - ssb-ahau - graphql server (federated) - @ssb-graphql/main - @ssb-graphql/invite - @ssb-graphql/tribes - @ssb-graphql/profile - cache - @ssb-graphql/whakapapa - @ssb-graphq/story - @ssb-graphql/artefact - auto-private-profile - UI - Vue - Apollo (and vue integrations) - Vuex - D3 - Vue router ## current areas of complexity - state management - vuex - dialogs (modals) - notifications - selectedProfile in whakapapa tree - loading/ manipulating the whakapapa tree - apollo - query/ mutation mixins - cache - note there's client side cache + we have server side cache for some records - cache invalidation... - dialog handlers / modals - controls which dialog to open - routes - /tribe/:tribeId/profile/:profileId - take params.profileId > apollo > getProfile(profileId) > profile record - graphql - meant to be standalone fragments - problems - @ssb-graphql/main is required core ... (dumping ground?) - some modules quite dependant now - where is that type coming from / who is mutating this type? - extending types in other modules ## testing UI/ integration testing It's really easy for us to accidentally break a feature and not know D: - e.g. mix broke file uploading - e.g. somehow image loading on collections+whakapapa got broken - --- ## Questions - what are your shining golden examples of patterns you love - mixins - what are the anti-patterns that you'd like to remove - things doing raw apollo when there's already a mixin for that. - leave a NOTE about why you're doing raw apollo if you are going to? - gotcha: mixins sometimes have dependencies (functions they need. make sure to check for those) - is there anything in vuex that could better be stored in the route? - as these are both used for global state - which things really need to use vuex? - tree > vuex - selectedProfile > route? (depends if storing ID or whole profile) - dialogs - easy to design, hard to develop well - can have unintended consequences - how do you do routing - what happens we you go "back" or close a dialog - problem for mobile back - which things could be pages? - dialogs are pages without routing - they force you to re-write routing to make it work to flow between dialogs - if it greys out the rest of the page it's basically a new page - sidebars are cool - it's about NOT losing your place - if it's not obscuring the page, then it's extending context on current page - in our app, it means multiple different things - sidebar - modal which greys out the screen - e.g. confirm delete popup (over another one) - page thing - Mix: how do you hold position on page? - matt with patchwork - he built a custom router which holds all the pages rendered - when you go fwd/ back it hides/ shows - if a page hasn't been visited in 5 mins, unload it - can record scroll-position - router might support it - https://router.vuejs.org/guide/advanced/scroll-behavior.html - state management - i.e. database stuff - things are calling apollo at: - component - - mixins - like: - consolidates common state logic in one place (maintenance) - this.$route, this.$apollo, has access to componenent state - can await responses (vuex would have to use some annoying listener) - vuex - mikey: what are mixins doing that vuex can't? - mix: awaiting mixins is easier - mikey: can you await a dispatched action? YES: https://vuex.vuejs.org/guide/actions.html#composing-actions - e.g. the addPerson method could be a chain of composed actions. - this is better than doing lots of state management in a view (which should just be doing presentation) - mikey opinions: - mixins as a general pattern require on a lot of monkey patching - depends on what that object has - implicit deps - accessing things via this.* can be tricksy - how do you write unit tests? - different than functions which import other function - explicit deps - explicit is easier/ more well defined - vuex should be where apollo happens - need a way to inject apollo in - there are different modules in the store that will need apollo - need one place where data manipulation is happening - could use stand along functions which are not mixins (don't have magical context) - need to figure out how to pass in apollo to vuex (so it's easier to do testing well) - maybe also look at vuex alternatives - inject / provide : might be Vue 3 - https://v3.vuejs.org/guide/component-provide-inject.html - code smells summary - not easy to test - deps implicit - state management too spread out - can await responses ()vuex would have to use some annoying listener - caching - mix describes where caching has been done, challenges - mikey: there's a react lib called "stale-while-revalidate" - https://github.com/vercel/swr - strategy: - return stale data - start a fetch (revalidate) - provide new data when it arrives - could have a promise which resolves with { cached, current: Promise } - Every project is different and whats important is that you have a pattern that works for you - I've got some feelings about the arrangement you currently you - Not a huge fan of mixins - Dialogs force you to write your own router - cant easily go back ## Testing ## Next Steps - Research - async/await dispatch - see if you can await things from the frontend - see if this returns anything? - how to store results ?? vuex state? - next: - try converting one mixin over to vuex - stories - write a policy/ guide for how we do apollo/ vuex/ component states - makes sure everything else conforms to pattern (or leave detailed notes why it doesn't) - Dialogs - review the dialogs - which can be converted to pages (with distinct routes) - can investigate vue-router scroll position stuff (see link) - which are sidebars - which are happily modals