• Stars
    star
    116
  • Rank 303,894 (Top 6 %)
  • Language
    JavaScript
  • License
    MIT License
  • Created over 7 years ago
  • Updated 11 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Pragmatic state management.


tiny atom logo

Pragmatic and concise state management.

npm size Build Status code style: standard

  • store modified via actions
  • can be used as global store or local component state
  • out of the box support for React and Preact
  • first class React hooks support
  • highly optimised with batched rerenders
  • beautiful console logger
  • battle tested and hardened

How is this different from redux? The key differences are:

  • Actions in tiny-atom are self contained units of business logic. They can read and update the state and dispatch other actions any number of times. This removes layers of boilerplate while preserving the benefits of redux like stores.
  • Tiny-atom includes useful utilities to make it completely sufficient for building application of any size.

Installation

$ npm install tiny-atom

Docs

Read the full docs or pick one of the highlights:

Example

import createAtom from 'tiny-atom'

const atom = createAtom(
  { unicorns: 0, rainbows: [] },
  {
    incrementUnicorns({ get, set }, n) {
      set({ unicorns: get().unicorns + n })
    },

    async fetchRainbows({ set, actions }) {
      set({ loading: true })
      const { data: rainbows } = await axios.get('/api/rainbows')
      set({ rainbows, loading: false })
      actions.incrementUnicorns(1)
    }
  }
)

atom.observe(atom => {
  console.log('atom', atom)
  const { rainbows, unicorns } = atom.get()
  render(unicorns).onClick(e => atom.actions.incrementUnicorns(10))
})

React Example

Provide the store:

import React from 'react'
import ReactDOM from 'react-dom'
import createAtom from 'tiny-atom'
import { Provider } from 'tiny-atom/react'

const atom = createAtom(
  { user: { name: 'Atom' } },
  {
    message({ get, set, swap, actions }, msg) {
      console.log(msg)
    }
  }
)

ReactDOM.render(
  <Provider atom={atom}>
    <App />
  </Provider>,
  document.querySelector('root')
)

Connect using React hooks:

import React from 'react'
import { useAtom, useActions } from 'tiny-atom/react/hooks'

export default function Hello() {
  const user = useAtom(state => state.user)
  const { message } = useActions()

  return <button onClick={() => message('hi')}>{user.name}</button>
}

API

createAtom(initialState, actions, options)

Create an atom.

initialState

type: any default: {}

The initial state of the atom.

actions

type: object default: {}

An object with action functions. The signature of an action function is ({ get, set, swap, actions, dispatch }, payload). If you provide nested action objects or other structure, make sure to also specify an appropriate options.evolve implementation to handle your actions appropriately.

  • get() - returns the current state
  • set(patch) - updates the state with the patch object by merging the patch using Object.assign
  • swap(state) - replace the entire state with the provided one
  • dispatch - same as atom.dispatch, dispatches an action
  • actions - actions prebound to dispatch, i.e. actions.increment(1) is equivalent to dispatch('increment', 1)

options.evolve

type: function

A function that receives all of the dispatched action objects and calls the action functions. The function signature is (atom, action, actions). Note that atom in this place has an extra added function set, a function that is used to update the state, this function does not exist on the actual atom. The default implementation uses action.type to find the matching function in the actions object.

options.debug

type: function | function[] default: null

A function that will be called on each action and state update. The function is passed an info object of shape { type, atom, action, sourceActions, prevState }. Tiny atom comes with 2 built in debug functions tiny-atom/log and tiny-atom/devtools.

createAtom(
  { count: 1 },
  {
    increment: ({ get, set }, payload) => set({ count: get().count + payload }),
    inc: ({ actions }, payload) => actions.increment(payload)
  }
)

atom.get()

Get current state.

atom.get()
atom.get().feed.items

atom.set(update)

Update state by shallowly merging an update.

atom.set({ user })
atom.set({ entities: { ...get().entities, posts } })

atom.swap(state)

Replace the entire state with the provided one.

atom.swap(nextState)

atom.dispatch(type, payload)

Send an action

atom.dispatch('fetchMovies')
atom.dispatch('increment', 5)

atom.actions

A map of prebound actions. For example, if your actions passed to atom are

const actions = {
  increment({ get, set }) {
    const { count } = get()
    set({ count: count + 1 })
  }
}

They will be bound such that calling atom.actions.increment(1) dispatches action with `dispatch('increment', 1).

atom.observe(cb)

Register a callback for when atom changes. Returns the unobserve function.

atom.observe(render)
atom.observe(atom => render(atom.get(), atom.dispatch))

atom.fuse(state, actions)

Extend atom's state and the action object. Convenient for composing atom from slices of state and actions from several modules.

const state = {
  project: { name: 'tiny-atom' }
}

const actions = {
  star: ({ get, set }) =>
    set({
      project: { starred: true }
    })
}

atom.fuse(state, actions)

React / Preact bindings

For documentation on the set of react and preact components <Provider />, <Consumer />, connect, useAtom, useActions and useDispatch see react or preact docs.

More Repositories

1

jetpack

🚀 Jetpack – Webpack made more convenient.
JavaScript
1,313
star
2

healthier

🧘‍♀️ Healthier is an opinionated style agnostic code linter – a friendly companion to Prettier
JavaScript
84
star
3

location-bar

A microlib for managing browser's location bar via pushState and hashChange APIs. This lib makes it easy to listen to URL changes and update the URL.
JavaScript
74
star
4

space-router

Framework agnostic router for single page apps
JavaScript
39
star
5

eslint-config-healthier

🧘‍♀️ Healthier is an opinionated style agnostic code linter – a friendly companion to Prettier
JavaScript
26
star
6

moonwave

🌗 A small web application framework.
JavaScript
14
star
7

grunt-bower-clean

Remove files (e.g. docs, tests, etc.) from installed bower components
JavaScript
10
star
8

PolyChrome

PolyChrome is a Firefox extension that can run Standard ML programs embedded in HTML documents
JavaScript
9
star
9

cherrytree-for-react

Seamlessly use cherrytree router with React
JavaScript
6
star
10

electronic-post-message

A postMessage polyfill for electron webview
JavaScript
6
star
11

kinfolk

Atoms and selectors for React
JavaScript
6
star
12

not-so-fast

Fast and efficient in-memory rate-limit, used to alleviate most common DOS attacks.
JavaScript
5
star
13

leap

An extension to Backbone that provides a solid foundation for JavaScript web applications
JavaScript
5
star
14

rave-load-jsx

Adds jsx loading to RaveJS based on file extensions.
JavaScript
4
star
15

vscode-healthier

VSCode extension to integrate healthier linter into VSCode
TypeScript
3
star
16

cherrytree-redux-react-example

A copy of emmenko/redux-react-router-async-example where react-router is replaced with cherrytree
JavaScript
3
star
17

leap-model

A lightweight alternative to Backbone.Model with support for nested attributes.
JavaScript
3
star
18

logcatislog

console log a cat
JavaScript
2
star
19

navstack.js

DEVELOPER PREVIEW
JavaScript
2
star
20

standard5

JavaScript Standard Style, but for es5 browser environments.
JavaScript
2
star
21

requirejs-examples

JavaScript
1
star
22

jetpack-serve

Jetpack's standalone middleware for serving jetpack bundles in express
JavaScript
1
star
23

kn-release

tag, push, and publish to npm and bower
JavaScript
1
star
24

rave-node-process

Adds a window.process object that shims some of node's global.process functionality
JavaScript
1
star
25

karma-webpack-grep

karma start --grep some/pattern
JavaScript
1
star
26

deploy

Tweaked combo of tj/deploy and mafintosh/taco-nginx
Shell
1
star
27

ff_async_bug

1
star
28

bro-size

Estimate the size of a package by browserifying it, uglifying and gzipping.
JavaScript
1
star
29

polychrome-scripts

1
star
30

mapsmaps

1
star