0.0.9 • Published 2 years ago

js-reducers v0.0.9

Weekly downloads
4
License
LGPL-3.0
Repository
github
Last release
2 years ago

js-reducers

Licence npm version Build status Coverage status

A small library to build state reducers in an opinionated way. This a sister project of js-messages. In combination they provide a more concise way for application that base on Redux patterns.

API

  • createReducer(config) => concise way to implement state reducers

  • when(messageCreator | type, reduce) => helper function to be used in combination with createReducer (see below)

  • on(messageCreator | type, update) => helper function (based on "immer" library) to be used in combination with createReducer (see below)

  • combineReducers(config) => combine multiple reducers to a more complex one that whens state of several domains (similar to the same-named function in redux)

Usage (demo is completely type-safe with TypeScript)

import { defineMessages } from 'js-messages'
import { createReducer, combineReducer, on, when } from 'js-reducers'

// This will generate message creators for the counter domain.
const CounterMsg = defineMessages('counter', {
  increment: (delta: number = 1) => ({ delta }),
  reset: (count: number = 0) => ({ count })
})

// This will generate message creators for the log domain.
const LogMsg = defineMessages('log', {
  info: (text: string) => ({ text }),
  warn: (text: string) => ({ text }),
  error: (text: string) => ({ text })
})

const initialCounterState = {
  count: 0
}

const initialLogState = {
  entries: [] as { level: 'info' | 'warn' | 'error', text: string }[]
}

// The `when` helper is useful if you want to define
// reducers in a strict functional way.
const counterReducer = createReducer(initialCountState, [
  when(CounterMsg.increment, (state, { delta }) => {
    return { ...state, count: state.count + delta }
  }),

  when(CounterMsg.reset, (state, { count }) => {
    return { ...state, count }
  })
])

// The `on` helper is useful if you want to define
// reducers in an imperative way (using Immer internally).
// Be aware the created reducer will still behave completely
// strict functional externally - nobody will notice that
// Immer has been used internally.
const logReducer = createReducer(initialLogState, [
  on(LogMsg.info, (state, { text }) => {
    state.entries.push({ level: 'info', text })
  }),

  on(LogMsg.warn, (state, { text }) => {
    state.entries.push({ level: 'warn', text })
  }),

  on(LogMsg.error, (state, { text }) => {
    state.entries.push({ level: 'error', text })
  })
])

const rootReducer = combineReducers({
  counter: counterReducer,
  log: logReducer
})

Project status

js-reducers is in beta stage.

0.0.9

2 years ago

0.0.8

3 years ago

0.0.7

4 years ago

0.0.6

4 years ago

0.0.5

4 years ago

0.0.4

4 years ago

0.0.3

4 years ago

0.0.2

4 years ago

0.0.1

4 years ago