Meiosis Documentation

Table of Contents

The Meiosis Pattern Cheatsheet

IMPORTANT NOTE: For a complete explanation of the Meiosis Pattern, please see the Meiosis Tutorial.

Helper functions! Meiosis is a pattern that you can set up yourself, but by popular demand meiosis-setup is now available for your convenience.

This is a quick summary of the Meiosis Pattern:

Here is the code to set up the Meiosis Pattern:

const app = {
  Initial: () => ...,
  Actions: update => {
    return ...
  }
};

const update = flyd.stream();

// Using Mergerino:
const states = flyd.scan(merge, app.Initial(), update);

// Using Function Patches:
const states = flyd.scan((x, f) => f(x), app.Initial(), update);

const actions = app.Actions(update);

Then, pass state and actions to views.

Optionally, add Services and Accepted State:

// Using Mergerino:
const accept = state =>
  acceptors.reduce(
    (updatedState, acceptor) =>
      merge(updatedState, acceptor(updatedState)),
    state
  );

const states = m.stream.scan(
  (state, patch) => accept(merge(state, patch)),
  accept(app.Initial()),
  update
);
states.map(state =>
  services.forEach(service => service({ state, update })));

// Using Function Patches:
const accept = state =>
  acceptors.reduce(
    (updatedState, acceptor) =>
      acceptor(updatedState)(updatedState),
    state
  );

const states = m.stream.scan(
  (state, patch) => accept(T(state, patch)),
  accept(app.Initial()),
  update
);

states.map(state =>
  services.forEach(service => service({ state, update })));

Using Mithril

const App = {
  view: function({ attrs: { state, actions } }) {
    // render view according to state, call actions to trigger changes
    // pass { state, actions } to other components.
  }
};

m.mount(document.getElementById("app"), {
  view: () => m(App, { state: states(), actions })
});

Using React

class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = props.states();
  }
  componentDidMount() {
    const setState = this.setState.bind(this);
    this.props.states.map(state => { setState(state); })
  }
  render() {
    const state = this.state;
    const { actions } = this.props;
    // render view according to state, call actions to trigger changes
    // pass state={state} actions={actions} to other components.
  }
}

ReactDOM.render(<App states={states} actions={actions} />,
  document.getElementById("app"));

This setup initally calls render() twice. If this is problematic in your application, we can use a skippedFirst flag:

class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = props.states();
    this.skippedFirst = false;
  }
  componentDidMount() {
    const setState = this.setState.bind(this);
    this.props.states.map(state => {
      if (this.skippedFirst) {
        setState(state);
      }
      else {
        this.skippedFirst = true;
      }
    });
  }
  render() {
    const state = this.state;
    const { actions } = this.props;
    // render view according to state, call actions to trigger changes
    // pass state={state} actions={actions} to other components.
  }
}

Using Preact

class App extends preact.Component {
  componentWillMount() {
    const setState = this.setState.bind(this);
    this.props.states.map(state => { setState(state); });
  }
  render() {
    const state = this.state;
    const { actions } = this.props;
    // render view according to state, call actions to trigger changes
    // pass state={state} actions={actions} to other components.
  }
}

preact.render(<App states={states} actions={actions} />,
  document.getElementById("app"));

Using lit-html

const App = (state, actions) => {
  // render view according to state, call actions to trigger changes
  // pass (state, actions) to other view functions.
};

const element = document.getElementById("app");
states.map(state => render(App(state, actions), element));

Components

To use multiple instances of a component, or to specify the state property outside of a component, pass an id along with state and actions to views. Use state[id] to read the component's state, pass the id to actions, and use the id in actions to issue patches that update the corresponding state property.

See the Components section of the Meiosis Tutorial for a complete explanation.

Table of Contents


Meiosis is developed by @foxdonut00 / foxdonut and is released under the MIT license.