Bones Architecture

April 25, 2020

Introduction

At Updater, we've developed a single page application framework that focuses on separating state and business logic from view. We've called it "Bones" as working in the architecture is like connecting bones together to create a working application.

This sandbox explores the core parts of Bones.

Observable

The observable is the core building block of Bones. Observables are tiny publication/subscribe engines. They maintain a list of observers and notify them. The implementation is super simple:

Bones Observable Code

Store

The store is just an observable with a tiny layer built on top to maintain state. When state changes, update is called on the observable to notify observers of the new state.

Bones Store Code

Interactor

Interactors bring business logic and store together to form a cohesive interactive component. They expose a self-documenting interface through actions and selectors. Actions can be called to change state, while selectors are used to retrieve state.

In this implementation, I've created an interactor factory function to bring store, actions, and selectors together.

Bones Interactor Factory Code

This count example has just one action.

Bones Action Code

And one selector.

Bones Selector Code

Builder

The builder is responsible for putting the application together. Connecting interactors to views through presenters. Builders are like the main function in an application.

Bones Builder Code

Presenter

A presenter consumes an interactor interface consisting of actions, selectors and state and returns a new interface specific to the view it's presenting into. This allows interactors to be as general as necessary while being reusable across different views.

View

A view accepts state, actions and selectors, renders an interface, and fires actions upon user interaction. The view is where rendering libraries such as React, Svelte, or Vue would run. One key reason Bones was created was to create clean separation between state / business logic and view rendering frameworks. This way, when frameworks change, the logic can live on.