All Projects → JannicBeck → undox

JannicBeck / undox

Licence: MIT license
⎌ Redux Implementation of Undo/Redo based on storing actions instead of states.

Programming Languages

typescript
32286 projects
javascript
184084 projects - #8 most used programming language

Projects that are alternatives of or similar to undox

Redux Undo
♻️ higher order reducer to add undo/redo functionality to redux state containers
Stars: ✭ 2,744 (+10876%)
Mutual labels:  history, redo, undo, redux-undo
UndoRedo.js
A powerful and simple JavaScript library provides a history for undo/redo functionality. Just like a time machine! 🕐
Stars: ✭ 19 (-24%)
Mutual labels:  history, redo, undo
js-undo-manager
Simple JavaScript undo/redo command manager supporting transactions with no dependencies
Stars: ✭ 23 (-8%)
Mutual labels:  redo, undo
rundo
Rundo is a undo redo library for rust which can auto generate undo op
Stars: ✭ 32 (+28%)
Mutual labels:  redo, undo
actions
Software without side-effects. Redo and Undo.
Stars: ✭ 23 (-8%)
Mutual labels:  redo, undo
zundo
🍜 undo/redo middleware for zustand
Stars: ✭ 170 (+580%)
Mutual labels:  redo, undo
undo
A undo-redo library.
Stars: ✭ 38 (+52%)
Mutual labels:  redo, undo
Regret
[Moved to MavenCentral] An undo-redo Android library which works with any objects and with an easy implementation. Perfect for drawing, text and photo editing apps.
Stars: ✭ 65 (+160%)
Mutual labels:  redo, undo
camunda-kafka-polling-client
Stream your process history to Kafka
Stars: ✭ 28 (+12%)
Mutual labels:  history
ionic3-firebase-ngrx
Sample Ionic 3 application using ngrx with firebase (auth, crud and camera plugin)
Stars: ✭ 48 (+92%)
Mutual labels:  ngrx
microsoft-opensource
An unofficial timeline of Microsoft's transition towards open source
Stars: ✭ 83 (+232%)
Mutual labels:  history
material2-admin
Angular - Material2 - Redux - Flex - Admin Example - Starter
Stars: ✭ 13 (-48%)
Mutual labels:  ngrx
TTTTRPG
Timeline Tree of Tabletop Role-Playing Games, celebrating more than 40 years game design innovations
Stars: ✭ 34 (+36%)
Mutual labels:  history
ngrx-films-list
Ngrx example app
Stars: ✭ 15 (-40%)
Mutual labels:  ngrx
blog
🏷️ 收集整理我的笔记 记录所思所想,互联网、产品设计、商业、低代码、量化金融、合成生物学
Stars: ✭ 20 (-20%)
Mutual labels:  history
on-this-day
App that serves and displays events, births and deaths that occurred during the queried day of history, scraped from Wikipedia
Stars: ✭ 12 (-52%)
Mutual labels:  history
slack-backup
Make copy of slack converstaions
Stars: ✭ 15 (-40%)
Mutual labels:  history
timeline-component-lwc
This component enables timeline view for Salesforce Record history.
Stars: ✭ 18 (-28%)
Mutual labels:  history
WikiChron
Data visualization tool for wikis evolution
Stars: ✭ 19 (-24%)
Mutual labels:  history
angular-plugins
Reactive Angular Plugins
Stars: ✭ 36 (+44%)
Mutual labels:  ngrx

Undox

Redux implementation of Undo/Redo based on storing actions instead of states.

License: MIT TypeScript

Install

npm install undox --save
yarn add undox --save

Usage

import { undox, createSelectors, UndoxTypes } from 'undox'

// the reducer which we want to add undo/redo functionality to
const counter = (state = 0, action) => action.type === 'INCREMENT' ? state + 1 : state

// wrap the counter reducer with undox
const reducer = undox(counter)

store.dispatch({ type: 'INCREMENT' })
state.present // 1

store.dispatch({ type: UndoxTypes.UNDO })
state.present // 0

store.dispatch({ type: UndoxTypes.REDO })
state.present // 1

// state now looks like this
{
  history: [ { type: 'undox/INIT' }, type: 'INCREMENT', type: 'INCREMENT' ],
  index: 1,
  present: 1
}

// the library provides some basic selectors
const selectors = createSelectors(counter)

selectors.getPresentState(state) // 1
selectors.getPresentAction(state) // { type: 'INCREMENT' }
selectors.getPastStates(state)    // [ 0 ]
selectors.getPastActions(state)   // [ { type: 'undox/INIT' } ]
selectors.getFutureStates(state)  // [ 2 ]
selectors.getFutureActions(state) // { type: 'INCREMENT' }

Actions are stored in an array named history. The index points at the present action in the history array.

Past actions are left to the present and future actions on the right.

Comparison

It really just boils down to if your state is fat and your actions are thin or your state is thin and your actions are fat.

The most popular and used library to add undo/redo functionality to redux is without a doubt redux-undo.

It stores whole states instead of actions. This is great for small states and fat actions, but does not scale well if the state tree grows and especially if state is persisted.

Undox takes a different approach and only stores actions, which has advantages as well as disadvantages.

Advantages

  • Takes up less space inside localStorage for thin actions and fat states
  • Better performance for thin actions and fat states
  • A complete history for free!

Disadvantages

  • Takes up more space inside localStorage for fat actions and thin states
  • Worse performance for fat actions and thin states
  • Less feature rich than redux-undo

API

Undo

There are two recommended ways to create an undo action:

  1. Use the action creators
import { undo, redo, group } from 'undox'
const undoAction = undo()
const redoAction = redo()
const groupAction = group()
  1. Use the UndoxTypes
import { UndoxTypes } from 'undox'
const undoAction = { type: UndoxTypes.UNDO }
const redoAction = { type: UndoxTypes.REDO }
const groupAction = { type: UndoxTypes.GROUP }

The payload of the undo/redo action corresponds to the number of steps to undo/redo, it defaults to 1. If the payload is greater than the length of the past/future, all actions will be undone/redone.

Group

The group action is a sepcial undox action. It will group the actions given in the payload, and store them as an array inside the history. Undo/Redo will then undo/redo them as one single step.

import { group } from 'undox'
const incrementTwice = group({ type: 'INCREMENT' }, { type: 'INCREMENT' })

store.dispatch(incrementTwice)

{
  history : [ { type: 'undox/INIT' }, [ { type: 'INCREMENT' }, { type: 'INCREMENT' } ] ],
  index   : 1,
  present : 2
}

store.dispatch(undo(1))

{
  history : [ { type: 'undox/INIT' }, [ { type: 'INCREMENT' }, { type: 'INCREMENT' } ] ],
  index   : 0,
  present : 0
}

Parameters

initAction (optional)

You may have wondered where { type: 'undox/INIT' } inside the history comes from. It is the default init action with which your reducer is called when it is initialized.

const reducer = undox(counter, { type: 'MY_CUSTOM_INIT' })

{
  history : [ { type: 'MY_CUSTOM_INIT' } ],
  index   : 0,
  present : 0
}

Comparator (optional)

The third argument of undox is a comparator function which compares two states in order to detect state changes.

  • If it evaluates to true, the action history is not updated and the state is returned.
  • If it evaluates to false, the action history is updated and the new state is returned.
  • The default comparator uses strict equality (s1, s2) => s1 === s2.
Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].