auora

0.2.0 • Public • Published

Build Status Code coverage Maintenance yes GitHub license Documentation status

Auora

Overview

There are currently several broadly-adopted alternatives to state management for JavaScript applications (e.g. Redux, MobX, Vuex, Effector). Each provide a unique developer experience and enforce a specific paradigm for changing state and broadcasting updates to linked views/components.

Why Make Another State Manager?

This package is an alternative approach to the same problem, attempting to take the best ideas from each alternative listed above (and provide some new ones). It's meant to provide an all-in-one solution with an intuitive API that can easily fit into any frontend framework.

It also tries to consolidate and simplify constructs from other state managers. In this state manager, the concept of reducers and mutations has been removed in favor of an internally managed transactional layer.

The code for this project was initially developed as part of an all-purpose (frontend and backend) ORM, but after use and iteration has evolved into it's own thing.

How is this Library Different?

Unique features provided by this library that aren't readily available in other state management libraries include:

No Mutations or Reducers

Mutations do not need to be defined when stores are created. Committing mutations to the store happens in a more fluid way through actions or explicit store commits. However, they're still available to users comfortable with that pattern.

State Transactions

Actions dispatched from stores are automatically wrapped in a transaction so in-flight state changes don't affect store state if the action fails.

tip Multi-Layered Hooks

Users can subscribe to both global events (i.e. commit, dispatch, etc ...), and specific changes to state variables.

Simpler Syntax

Along with standard syntactic patterns, this module also supports a more fluid syntax for actions that allows users to call actions as functions instead of passing them as a string into dispatch calls.

Framework-Agnostic

This library was built to work with any front-end framework (or without one), and also has thorough Examples detailing how to best use this library within the context of several popular frameworks.

Each of these core features is described in detail throughout the Guide section of the documentation. For additional context on how to use this module in a front-end framework like Vue or React, see the Examples section of the documentation.

Installation

Install in Project

To use this library in a Vue project, add the package to your package dependencies via:

npm install --save auora

Or, with yarn:

yarn add auora

Use via CDN

To use this package via CDN, import it in your project via:

<script src="https://unpkg.com/auora/dist/index.min.js"></script>

Documentation

Documentation for the project can be found here.

Quickstart

To provide a quick and simple high-level picture of how this library can fit into a project, let's define a minimal Store and use that Store in a simple Vue application. We're going to define the Hello World of state management: a counter application.

A Minimal Store

In our counter application, we're interested in managing the state of a count variable, and updating the state of that variable throughout our application in a way that will be reflected across components. Here is a dead-simple Store we can use for this example:

import { Store } from 'auora';
 
const store = new Store({
  // state
  state: {
    count: 0,
    history: [0],
    operations: [],
  },
 
  // actions
  actions: {
    // sync
    increment({ state }) {
      state.count += 1;
      return state.count;
    },
 
    // async
    add({ state }, number) {
      return new Promise((resolve) => {
        state.count = state.count + number;
        resolve(state.count);
      });
    },
  },
 
  // events
  events: {
    dispatch(action, ...payload, { state }) {
      state.operations.push({ action, payload });
    }
  }
 
  // subscriptions
  subscribe: {
    count(newValue, oldValue, { state }) {
      state.history.push(state.count);
    },
  },
 
});

In this store, we've defined the following constructs:

  • state - The global source of truth for data models in the application.
  • actions - Synchronous or asynchronous processes that can change state.
  • events - Callbacks that execute after specific events that happen throughout the state management lifecycle.

More information about the purpose for each of these constructs can be found in the Guide section of the documentation.

Outside of a framework, we can use the Store like so:

store.state.count // 0
store.state.history // [0]
store.state.operations // []
 
store.apply.increment();
store.state.count // 1
store.state.history // [0, 1]
store.state.operations // [{action: 'increment', payload: []}]
 
store.reset('count');
store.state.count // 0
store.state.history // [0, 1, 0]
store.state.operations // [{action: 'increment', payload: []}]
 
store.apply.add(4).then(() => {
  store.state.count // 4
  store.state.history // [0, 1, 0, 4]
  store.state.operations // [{action: 'increment', payload: []}, {action: 'add', payload: [4]}]
});

A Minimal Application

This library can be used within the context of any front-end framework, but let's use Vue to provide a concrete example of how it can easily augment front-end development. This package has several Extensions built to easily bind Stores to modern front-end frameworks

First, to bind our store from the previous section in a Vue application, we can use:

// contents of index.js
import Auora from 'auora/ext/vue';
 
import counterStore from '@/store';
 
Vue.use(Auora);
 
const app = new Vue({
  el: '#app',
  store: counterStore
});

After binding the store, we can expose store state, mutations, and actions in components like:

<template>
  <div>
    <p>{{ count }}</p>
    <button @click="increment">Increment Counter</button>
    <button @click="add(5)">Add 5 to Counter</button>
  </div>
</template>
 
<script>
export default {
  name: 'counter',
  store: {
    state: ['count'],
    actions: ['increment', 'add'],
  },
}
</script> 

We can also access the store directly in components via:

this.$store.count // 0
 
this.$store.apply.add(1).then(() => {
  this.$store.state.count // 1
});

That's it! For more information on state management or how to use different features of this plugin, see the Guide section of the documentation.

Contributing

Getting Started

To get started contributing to the project, simply clone the repo and setup the dependencies using yarn or npm install:

git clone git@github.com:bprinty/auora.git
cd auora/
yarn

Once you do that, you should be ready to write code, run tests, and edit the documentation.

Building Documentation

To develop documentation for the project, make sure you have all of the developer dependencies installed from the package.json file in the repo. Once you have all of those dependencies, you can work on the documentation locally using:

yarn docs:dev

Or, using vuepress directly:

vuepress dev docs

Running Tests

The Jest framework is used for testing this application. To run tests for the project, use:

yarn test

To have Jest automatically watch for changes to code for re-running tests in an interactive way, use:

yarn test:watch

To run or watch a specific test during development, use:

yarn test:watch -t model.update

Or, you can invoke jest directly:

jest
jest --watch
jest --watch -t model.update

Submiting Feature Requests

If you would like to see or build a new feature for the project, submit an issue in the GitHub Issue Tracker for the project. When submitting a feature request, please fully explain the context, purpose, and potential implementation for the feature, and label the ticket with the discussion label. Once the feature is approved, it will be re-labelled as feature and added to the project Roadmap.

Improving Documentation

Project documentation can always be improved. If you see typos, inconsistencies, or confusing wording in the documentation, please create an issue in the GitHub Issue Tracker with the label documentation. If you would like to fix the issue or improve the documentation, create a branch with the issue number (i.e. GH-123) and submit a PR against the master branch.

Submitting PRs

For contributors to this project, please submit improvements according to the following guidelines:

  1. Create a branch named after the ticket you're addressing. GH-1 or bp/GH-1 are examples of good branch naming.
  2. Make your changes and write tests for your changes.
  3. Run all tests locally before pushing code.
  4. Address any test failures caught by Travis CI.
  5. Make sure you've updated the documentation to reflect your changes (if applicable).
  6. Submit a PR against the master branch for the project. Provide any additional context in the PR description or comments.

Keeping up to Speed on the Project

All development efforts for the project are tracked by the project Kanban board. Contributors use that board to communicate the status of pending, in-progress, or resolved development efforts. If you have a question about the Roadmap or current in-progress issues for the project, see that board.

Package Sidebar

Install

npm i auora

Weekly Downloads

3

Version

0.2.0

License

MIT

Unpacked Size

59.2 kB

Total Files

8

Last publish

Collaborators

  • bprinty