Skip to content

Instantly share code, notes, and snippets.

@cathylill
Last active August 29, 2015 14:21
Show Gist options
  • Save cathylill/97821d97d058e5e46579 to your computer and use it in GitHub Desktop.
Save cathylill/97821d97d058e5e46579 to your computer and use it in GitHub Desktop.
Architecting an application with MercuryJS

Architecting an application with Mercury.js

Mercury.js is not opinionated about your application architecture - it's components can be used independendently, with the mercury library adding a small amount of bootsrapping and event wiring sugar. The notes given here are just one example of how you could architect an application built with Mercury.js, and will hopefully address some of the questions you may have about implementations that are more complex than the documented examples.

This article will cover some of the key components you need to create a fully featured app and gives an example of how to structure those components in such a way as to keep your app clearly understandable and maintainable for humans.

Modularised Data store

Create a core app state object that contains top level paramaters. Child data stores are generated by individual 'store' scripts that create the store and wire up appropriate channels and methods for updating data in that store.

Each child store is initialised using mercury.state so that channels will be attached to the individual store, not the overall app state, allowing data stores to be modular and easier to reason about in a large application.

Renderers

Renderers should return a thunk, or an array of thunks for optimisation. Pass in only the required data stores to renderers.

Use delegated event listeners in renderers to trigger channel updates in your data stores. By attaching channels to individual data stores you can conveniently access the update methods for the data stores you are working with in your renderer.

Widgets

Need to do something directly with the DOM utside of virtual-hyperscript? Widgets allow you to 'cross over' between virtual-dom components and items in the actual DOM. Useful when you need to work with external code that needs to be inserted or manipulated directly in the DOM.

Remember, widgets will be re-rendered on any relevant store updates - an update method is essential to tell the widget what to change on updates after the initial render.

Widgets are loaded as the content of a virtual-hypertext node so in practice they will be required in their parent renderer.

Utilities

Utilities handle any state updates that do not originate from the client side user. This is essential where any data or state is being updated from a server, a browser API or another store. At Coviu, our app needs to respond to updates that are pushed to the client via WebRTC data channels - we use utilities to update our data stores based on the new data provided by the data channel.

We seperate these utilities from stores so that they are not tightly coupled to the app state data structure. They are loaded at the top level of the app and therefore have direct access to all of the app state. This prevents confusion and eliminates unecessary complexity. Utilities ahould trigger update methods on the data store rather than updating the store directly to maintain a single point of update for each store.

Bootstrap

Require all store initilaisers and utilities at the top level index.js, create the application state object and pass it into a top level view renderer.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment