Skip to content

Releases: vigetlabs/microcosm

v12.1.0: Version 12.1.0

09 Mar 13:12
Compare
Choose a tag to compare
- Add `onOpen` callback props to `ActionForm` and `ActionButton`
- Replaced internal references of `behavior` with `command`
- Cleaned up some internal operations they no longer expose actions in history

v12.0.0

03 Mar 22:47
Compare
Choose a tag to compare
  • merge helper skips over nully values. For example, merge(null, {}) will
    start with the second argument
  • Renamed Presenter::model to Presenter::getModel.
  • Renamed Presenter::register to Presenter::intercept
  • Added Presenter::ready, which fires after ::setup
  • Added a model property to Presenters. This behaves similarly to props or
    state, and is available after setup executes
  • Presenter::render is now the primary rendering method for Presenters
  • Presenter::view always gets called with React.createElement
  • Removed deprecated Action::send
  • Added nested action registrations in domains. See the Domains component of
    the upgrading section later.
  • Microcosm:toJSON only serializes domains that implement ::serialize
  • Microcosm::reset only operate on keys managed by the specific Microcosm.
    reset effects the entire tree of forks.
  • Microcosm::patch only operate on keys managed by the specific Microcosm.
    patch effects the entire tree of forks.
  • Removed Domain::commit, which consistently added needless complexity to our
    applications.
  • All instances of intent have been replaced with action. They are the
    exact same thing under the hood, and it is a common source of confusion.
  • Renamed IntentButton to ActionButton. Import from microcosm/addons/action-button
  • Renamed Form to ActionForm Import from microcosm/addons/action-form
  • Renamed withIntent to withSend. Import from microcosm/addons/with-send
  • Added update data utility, which calls set on the result of a function that
    is passed the result of get.

Upgrading

Microcosm

deserialize, serialize, reset, and patch only operate on keys managed
by a particular Microcosm. Verify that, where you are using these methods, your
application is not relying on them to inject arbitrary application state.

These methods now return the merged result of calling all the way up the
hierarchy of Microcosm forks. In practice, this means that Microcosms only have
to deal with the keys for domains they were assigned, which is more in line with
the behavior we expect from forks.

Actions

With the exception of removing send, which was replaced with update,
actions have not changed. If you have removed all deprecated action.send
calls after upgrading to 11.6.0, there should be no further change required.

Domains

No more commit

Domains no longer support commit(), and subsequently shouldCommit(). We
found, while useful for serializing libraries such as ImmutableJS, that it our
usage of commit turned into a convenience method for always writing state in a
specific way. This created an awkwardness with serializing data, and could be
a source of performance problems as they continually write new object references
from things like filter or slice.

So we removed it. We recommend moving this sort of behavior to getModel in
the Presenter add-on.

Nested action registrations

Domains may now nest action statuses as an object:

class Domain {
  register () {
    return {
      [action]: {
        open  : this.setLoading,
        error : this.setError,
        done  : this.setDone
      }
    }
  }
}

Presenters

getModel is the new model

We frequently found ourselves wanting to access the latest model inside of our
presenter. What if we wanted to fetch extra data from records pulled out of a
model, or render differently if the record was missing?

Presenters now have a model property, which can be accessed after setup has
completed:

class MyPresenter extends Presenter {
  getModel () {
    return { count: state => state.count }
  }

  render () {
    return (
      <ActionButton action={step} value={1}>
        {this.model.count}
      </ActionButton>
    )
  }
}

ready

setup can not have access to this.model because repo specific setup
behavior might cause the model to be recalculated excessively. So we've added a
ready method. Both ready and update have access to the last calculated
model, which makes them ideal for performing some work based on it:

class MyPresenter extends Presenter {
  getModel (props) {
    return {
      user: data => data.users.find(u => u.id === props.id)
    }
  }
  ready (repo, props)
    if (this.model.user == null) {
      repo.push(this.fetchUser, props.id)
    }
  }
}

You can still do this sort of fetching inside of setup, there just won't be a
model to access. Not much of a change from 11.6.0, where this.model was not
available.

render is the new view

We (Nate) got this wrong. By not using render, too much distance was created
between the underlying React Component behavior and the "special treatment"
received by view.

render now works just like React.Component::render, as it should be. Still,
we haven't gotten rid of view, which is useful in a couple of places, like as
a getter to switch over some piece of model state:

class MyPresenter extends Presenter {
  getModel (props) {
    return {
      user: data => data.users.find(u => u.id === props.id)
    }
  }

  get view () {
    return this.model.user ? MyUserView : My404View
  }
}

view is always invoked with React.createElement. render is always called
in the context of the Presenter. It is a plain-old React render method (for
great justice).

intercept is the new register

Presenter::register was a confusing name for the what it did.
Presenter::register allows you to catch messages sent from child view
components. Catch is a reserved word, so we've renamed it intercept.

In the future, Presenter::register might behave more like an Effect, which is
what several users have mistaken it for.

v11.2.0

10 Jan 22:18
Compare
Choose a tag to compare
  • The withIntent add-on correctly sets its displayName property to "withIntent(ComponentName)"). This makes it selectable by enzyme's find function.
  • Pass send prop to Presenter children

Version 11.1.0

10 Jan 14:02
Compare
Choose a tag to compare
  • Added getRepo method to presenters to allow greater control over repo assignment
  • Action payloads may now, intentionally, be set to undefined
  • Fixed case where action.toggle() would not adjust history tree as intended.
  • Cut memory usage for action history by roughly 80%
  • Cut action resolution times by roughly 85%

v11.0.0: Version 11.0.0

15 Dec 19:05
Compare
Choose a tag to compare
- Fix bug where Presenter given stateless view component as an inline
  prop would call it as a function instead of React.createElement.
- Add warning when using `render()` directly in the Presenter.
- Presenter.setState state will re-calculate the model. State is now
  the second argument of `model()`.
- Removed some deprecated methods and aliases:
  - action.close() - Use action.resolve()
  - repo.replace() - Use repo.patch(data, true)
  - repo.addStore() - Use repo.addDomain
  - Presenter::viewModel - Use Presenter::model
- Domains mounted to the root must pass `null` as the first argument
  to `addDomain`, like: `repo.addDomain(null, RootLevelDomain)`
- `addDomain` accepts a third argument: `options`. These options will
  be passed to domain constructors and to the setup method.
- Microcosm ships as an ES6 module. If you are using CommonJS, import
  Microcosm using `require('microcosm').Microcosm`
- Presenter:render is now protected. Instead, always use `view`
- Removed concept of purity. Microcosm depends on side-effect free
  updates, so it's not really viable.
- Presenter extends from `React.PureComponent` when available.
- The Presenter model no longer returns all state by default. This is
  nice for short examples, however it can quickly get out of hand for
  non-trivial uses.
- Significantly improved performance across the board.

10.8.0

21 Nov 12:37
Compare
Choose a tag to compare
  • Added a formal method of side-effects: Effect. An effect runs
    once, whenever an action moves from one state to the next. See
    ./docs/api/effects.md
  • Effect callbacks should be invoked within the context of the effect
  • Throw an error if Presenter::view is nully. This will inevitably
    cause an error either way, and should make troubleshooting much easier.
  • patch and reset only apply to the repo that invoked them (and thus their
    children)

10.7.1

21 Nov 12:38
Compare
Choose a tag to compare
  • Do not pass prepare prop to form element of Form add-on

10.7.0

21 Nov 12:38
Compare
Choose a tag to compare
  • Added prepare method for processing form parameters after they
    are serialized.

10.6.1

21 Nov 12:37
Compare
Choose a tag to compare
  • Made a few performance tweaks to achieve deeper v8 optimization
  • Never dispatch on archive. We don't need to. History will correctly
    reconcile in all cases.

v10.6.0

03 Nov 20:16
Compare
Choose a tag to compare
  • Presenter views can be React components.