Closed nhunzaker closed 6 years ago
Super exciting to see this getting fleshed out Nate! I know we discussed over Slack for a bit, but I've got a few questions for ya:
I get the 'State Management' part of the chart from Actions down to Domains, but could you briefly explain the other pieces and how they relate to the Presenter? I'm still hazy on [Command]
and [Fetch]
but it would be good to get a short description of each piece.
Client-side GraphQL querying looks very promising. Straight off the bat I can see how this would significantly increase readability of model subscriptions (especially with nested structures). Just to prod a little further, are there any performance benefits to this as well, or is it to simply improve the ergonomics of getting model data in the Presenter layer?
New signature for Domains are 👌. Just to clarify, in the toggleMenu
method in the code sample you provided, is open
a variable passed through the Action payload?
I also noticed that you are not using computed property names for domain registration. Is there a reason for that?
[Command]
is basically a function that gets passed into repo.push
, it's the job that an action conducts. This concept is very board, [Fetch]
represents a new specialized type of command purely for fetching data.open
is the prior state of menuOpen
. I think it would be neat to let a user pass a function to that let's them operate on the prior state.repo.fetch
, we're using a method on a Domain as an action. I'm thinking that we could tag that method and automatically register it to the Domain (because the dispatch process can see that the tag is a member of the domain)
Based on a discussion @efatsi and I had at our team offsite, I wanted to better document the plan for Microcosm 13.x. I still need to flesh a bunch of stuff out in this issue, but here's a first pass:
Overall Design
Domains store changesets
At the lowest level, I'd like to increase the abstraction level of domains. Instead of manipulating data directly, domains will return a changeset:
So the signature has changed. The first argument of a Domain will be a
changeset
object with methods similar to our data helpers:set
,merge
,update
, etc.This creates a changeset. Under the hood, Microcosm will know precisely that
settings.menuOpen
changed. When Microcosm sends out an update, consumers can subscribe to precisely the data paths they care about. It also means that users don't have to worry about immutable data updates. We can do that for them.Queries (and subscriptions)
We've wanted a formal query API in Microcosm for a while. I think GraphQL offers a great way to go about this. The goal is not to support GraphQL backends from the get-go, but it would be a good milestone for later.
From this query we can infer a few things. This presenter cares about the
planets
andstars
data paths. If a domain modifies those paths, we know to update this query. In the future, we could even go so far as to subscribe to changes to a specificplanet.id
,planet.name
, orstar.name
update.Fetching vs Mutating in Domains
Over time I've found that fetching data and modifying client-side state are different flows. When fetching data, we always end up just passing it through to state, or merging the payload into existing records. This results in a lot of unnecessary boilerplate.
Fetching
Fetching data and storing it in a domain should be streamlined:
repo.fetch
returns a subscription to a pool of data, whereasrepo.push
returns a subscription to the state of an action. If we ask for page 1 of all Planets records, it merges the request payload into a greater pool of all planets, returning a subscription to the records from the AJAX request for page 1.For example, with
repo.fetch(PlanetsDomain.all, { page: 1 })
:[{ id: 0, name: 'Mercury' }]
repo.fetch
returns a subscription to Mercury.