@huang-julien/history-state
v1.0.1
Published
A simple state history manager, written in TS
Downloads
2
Maintainers
Readme
A simple library for state history management
How it works
this library provide two classes:
HistoryState
This class handle the history of whatever you want and can be extended.HistoryManager
This class handle traces of multipleHistoryState
changes. If you are using a HistoryManager on a HistoryState, avoid usingundo()
orredo()
from theHistoryState
instance but instead call it from theHistoryManager
Methods
HistoryState
/**
* method to override if you are extending HistoryState
*/
__onStateChange(value: S, states: S[], type: 'redo'|'undo'): void
/**
* method to call to commit a change
* you have to call this method everytime you want to commit a change
*/
commitChange(value: S): void
/**
* method to call to redo changes
*/
redo(): void
/**
* method to call to undo changes
*/
undo(): void
HistoryManager
/**
* method to call to redo changes
*/
redo(): void
/**
* method to call to undo changes
*/
undo(): void
Basic usage
let data = ''
const dataHistory = new HistoryState<string>({
onStateChange: (value: string, states: string[], type: 'redo'|'undo') => {
data = value
},
originalState = ''
})
data = 'hello'
dataHistory.registerChange(data)
dataHistory.undo() // data === ''
data.redo() // data === 'hello'
Manage multiple HistoryState
if you need to manage multiple HistoryState, pass a HistoryManager instance as the second param in the constructor
let hello = 'hello'
let world = 'world'
const statesHistory = new HistoryManager()
const helloStateHistory = new HistoryState({
onStateChange: (value: string, states: string[], type: 'redo'|'undo') => {
data = value
},
originalState: hello
}, statesHistory)
const worldStateHistory = new HistoryState({
onStateChange: (value: string, states: string[], type: 'redo'|'undo') => {
data = value
},
originalState: world
}, statesHistory)
hello = 'test'
helloStateHistory.registerChange(hello)
/* call the redo and undo from HistoryManager */
statesHistory.undo() // hello === 'hello'; world === 'world';
statesHistory.redo() // hello === 'test'; world === 'world';
In this case, don't call redo()
and undo()
on the HistoryState
instances but call theses methods from the HistoryManager
instance
Extend HistoryState
A class can extends the HistoryState
class.
Instead of passing onStateChange
, these methods can be overriden.
type THistoryState = {hello: string, world: string}
class SomeData extends HistoryState<THistoryState> {
notSaved = 'data not kept in history'
#hello = 'hello'
#world = 'world'
constructor() {
super({ hello: 'hello', world: 'world' })
}
get hello() {
return this.#hello;
}
set hello(v: string) {
this.#hello = v
this.onChange()
}
get hello() {
return this.#world;
}
set hello(v: string) {
this.#world = v
this.onChange()
}
onChange() {
this.registerChange({
hello: this.#hello,
world: this.#world
})
}
__onStateChange(s: THistoryState) {
const { hello, world } = s
this.#hello = hello
this.#world = world
}
}
Note: Feel free to fork it and improve it