wu

Reactive, functional and declarative framework for webapps

View the Project on GitHub migueldelmazo/wu

Wu framework

Pattern

Wu is a framework for building web applications (although if you want you can also use it in Node JS):

Pattern

Wu concepts

Ensurer:

Ensurer allows you to execute a function and save its result in the data model every time other data change. The goal is to always keep the data model consistent.

wu.create('ensurer', 'userIsLogged', { // name of the ensurer item
  // path of the data model that we are watching
  onChange: 'user.id',
  // arguments that will receive the function 'run'
  args: 'user.id',
  // pure function that runs when 'onChange' has changed
  run: (userId) => {
    return !!userId
  },
  // path of the data model where to save the result of 'run'
  update: 'user.isLogged'
})

Watcher:

Watcher works exactly like ensurer but does not save the result of the function in the data model. The goal is to use it to call third-party libraries such as React JS, LocalStorage, Stripe…

wu.create('watcher', 'setUserIdInLocalStorage', { // name of the watcher item
  // path of the data model that we are watching
  onChange: 'user.id',
  // arguments that will receive the function 'run'
  args: 'user.id',
  // impure function that runs when 'onChange' has changed
  run: (userId) => {
    window.localStorage.setItem('userId', userId)
  }
})

Router:

Router allows you to watch changes in the browser URL and save the normalized route in the data model. The data stored in the model are the URL params and if the route is active.

wu.create('router', 'userLoginRoute', { // name of the router item
  urlPattern: '/user/:userId/detail',
  update: 'user.detail.route'
})

// when browser URL is '/user/asdf1234/detail' 'user.detail.route' is { isActive: true, params: { userId: 'asdf1234' } }
// when browser URL is not '/user/asdf1234/detail' 'user.detail.route' is { isActive: false, params: {} }

Getter:

Getter allows you to define an interface to get data from the data model outside of Wu.

// file user.js
wu.create('getter', 'userGreeting', { // name of the getter item
  // arguments that will receive the function 'run'
  args: ['user.name', 'user.lang'],
  // pure function
  run: (name, lang) => {
    if (lang === 'en') return 'Hello ' + name
    else if (lang === 'it') return 'Ciao ' + name
    else return 'Hola ' + name
  }
})

// file userGreeting.template.js
render () {
  return (
    <h1>{wu.getter('userGreeting')}</h1>
  )
}

// when 'user.name' is 'Anna' and 'user.lang' is 'en' the result of render is '<h1>Hello Anna</h1>'

Setter:

Setter allows you to define an interface to save data from outside to the Wu data model.

// file user.js
wu.create('setter', 'userSendLoginData', { // name of the setter item
  // pure function
  run: (email, password) => {
    return {
      email,
      password
    }
  },
  // path of the data model where to save the result of 'run'
  update: 'user.login.data'
})

// file userLogin.template.js
sendLoginData () {
  wu.setter('userSendLoginData', 'email@email.com', '12345678')
}

// when 'sendLoginData' is executed 'user.login.data' will have { email: 'email@email.com', password: '12345678' }

API:

API allows you to watch changes in the data model and send Ajax requests to your server. When the server responses, API helps you manage it and save it in the data model.

wu.create('api', 'userProfile', { // name of the api item
  // path of the data model that we are watching
  onChange: 'user.id',
  request: {
    // request method
    method: 'get',
    // request URL or path
    path: 'https://server.com/api/user/profile',
  },
  onResponse: {
    // if response http code is 200
    success: {
      // save 'response.body' in 'user.profile' data model path
      run: (response) => response.body,
      update: 'user.profile'
    },
    error: {
      run: (response) => response.errorMessage,
      update: 'user.profile.errorMessage'
    }
  }
})

Documentation

You can find Wu documentation in following pages:

Third-party libraries

It is very easy to work with third-party libraries using getters, setters and watchers. Visit the documentation to learn about the modules developed.

Tests

To ejecute the tests (with Jest) run:

$ npm install
$ npm test

Examples

Here you can see an example of ToDo app.

Dependencies

Wu only has one dependency: Lodash

Current state of Wu

Wu is an experimental framework that is still in beta. The main purpose of Wu is to perform a proof of concept to compare this programming pattern with other patterns.

Contributions

If you are interested in participating in the improvement or development of Wu please contact me: migueldelmazo. I would love for you to help me develop Wu.

I would especially like to receive suggestions about the names of the methods, so that they are more readable and easier to use.

License

Wu is MIT licensed.