Skip to content

dubiousdavid/muv.js

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

39 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

müv.js

müv.js is a small library for building reactive web apps.

Introduction

müv.js is intentionally simple. You could write it yourself. The hard work was done by the authors of Snabbdom virtual dom and functional reactive programming libraries like RxJs. The trick is understanding how to compose these two things in order to build complex applications. The pattern for data flow and state change takes inspiration from the model/update/view architecture found in Elm.

Examples

  1. Counter (source)
  2. Wikipedia (source)
  3. Giphy (source)
  4. Websocket (source)
  5. TodoMVC (source)

What FRP libraries can I use?

Any library with a subscribe method. Here are a few: RxJs, Bacon.js, Kefir, xstream, Most

What does it look like?

HTML is represented using arrays. For example:

['a', {props: {href: 'http://todomvc.com'}}, 'TodoMVC']
['ul#frp-list', {},
  ['li.selected', {}, 'RxJs'],
  ['li', {}, 'Bacon.js'],
  ['li', {}, 'Kefir']]

The class, props, style, and eventlistener modules from Snabbdom are automatically loaded. See: https://github.com/snabbdom/snabbdom#modules-documentation for more information.

State is held inside the scan method of the data stream and updates with every action that is pushed to the stream. Both the update function and view function should be pure. The render function takes a stream and an element to render the stream of "HTML" to.

import { render } from '../../src/index.js';
import Rx from 'rxjs/Rx';

// Stream
let actions$ = new Rx.Subject();

// Model
let initModel = 0;

// Update
function update(model, action) {
  switch (action) {
    case 'add':
      return model + 1;
    case 'subtract':
      return model - 1;
  }
}

// View
function button(action, text) {
  return ['button', { on: { click: e => actions$.next(action) } }, text];
}

function view(model) {
  return (
    ['div', {},
      button('subtract', '-'),
      ['span', {}, ` ${model} `],
      button('add', '+')]
  )
}

// Reduce
let model$ = actions$
  .do(x => console.log('Actions', x))
  .scan(update, initModel)
  .startWith(initModel)
  .do(x => console.log('Model', x));

// Render
let view$ = model$.map(view);
render(view$, document.getElementById('container'));

FAQ

Q: What projects have you drawn inspiration from? A: Elm, Cycle.js, and Redux

About

Elm-inspired FRP Javascript Library

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published