obj-history
v0.1.0
Published
Downloads
7
Readme
obj-history
Usage
Basic history
import { History } from 'obj-history';
let target = {
foo: 42,
bar: [1, 4, 9, 16]
};
let history = new History(target);
history.commit({
foo: 35,
bar: undefined // delete 'bar'
});
history.apply({
foo: 35
});
history.canUndo();
history.undo();
history.canRedo();
history.redo();
history.clear();
history.clearFuture();
history.clearPast();Creating changes
let target = {
users: {
...,
34: { female: false, name: 'Bob' },
...
}
};
let history = new History(target);
let change = history.createChange((state) => {
state.users[34].female = true;
state.users[34].name = 'Alice';
// or
state.users[34] = {
female: true,
name: 'Alice'
};
// to delete
delete state.users[34];
});
let reverse = history.reverse(change);Manipulating the current working change
history.hasWorkingChange(); // => boolean
// reverses previous working change, if any
history.setWorkingChange(...);
history.setWorkingChange((state) => {
});
// keeps old reverse change
history.updateWorkingChange((change) => {
change.foo = 35;
});
history.commitWorkingChange();
history.clearWorkingChange();
history.checkWorkingChange();Options
let history = new History(<target>, {
maxEntries: Infinity
});Built-in constructors
Array
- Proxy:
pop(),push(),shift(),unshift(),splice(),[index] = <new value>,[index].<...> = <...> - Syntax:
{ type: 'splice', index: <number>, deleted: <number>, inserted: [<uncloned new value ...>] } { type: 'set', index: <number>, value: <change> } - Caveats:
[index] = <new value>and[index].<...>act on the original index; do not use them with other methods
Object
- Proxy:
[prop] = <uncloned new value>,[prop].<...> =,delete [prop] - Syntax:
{ [prop]: <change> } { [prop]: undefined }
Set
- Proxy:
add(<uncloned new value>),delete(<...>),has(<...>),size - Syntax:
{ added: [...], deleted: [...] } { added: [...], deleted: null } // = clear
Custom constructors
class Vec {
constructor(x, y) {
this.x = x;
this.y = y;
}
}
history.register(Vec, {
clone(target) {
return new Vec(target.x, target.y);
},
isChange(change, target) {
return ('x' in change && change.x !== target.x)
|| ('y' in change && change.y !== target.y);
},
apply(change, target) {
if ('x' in change) target.x = change.x;
if ('y' in change) target.y = change.y;
},
reverse(change, target) {
let reverse = {};
if ('x' in change) reverse.x = target.x;
if ('y' in change) reverse.y = target.y;
return reverse;
},
createProxy(target) {
let change = {};
let proxy = new Proxy({}, {
set(obj, prop, value) {
if (prop === 'x') change.x = value;
if (prop === 'y') change.y = value;
return true;
}
});
return [change, proxy];
}
});