- A plugin can
redo
,undo
deep nested JSON. - Vue or React friendly.
- Support
Date
as value butregex
andfunction
- min+gzipped 12.2kB
- uses google-diff-match-patch for long text diffs (diff at character level)
- Import jsondiffpatch but without the formatter.
The source code still messy but works fine. I will refactor once have time.
yarn add json-history
const history = new JsonHistory({
tree: object | array
})
new JsonHistory({
tree = {},
steps = 50, // how many steps can redo
backUpDeltas = [], // can backup the previous deltas
callback = {
onRecorded() {},
onEachPatch() {},
onUndo() {},
onUndid() {},
onRedo() {},
onRedid() {},
},
setter(tree, key, value) {
Vue.set(tree, key, value)
},
deleter(tree, key) {
Vue.delete(tree, key)
}
})
Update any value of object or array by multi records. Can redo
or undo
after record
.
Accept array or an object.
const history = new JsonHistory({
tree: {
1: [1, 3],
a: [{}, { 1: 3 }],
b: { c: 5, d: { e: 6 }}
}
})
history.record({
path: '1[4]',
value: {},
insertArray: true
})
expect(history.tree).toEqual({
1: [1, 3, null, null, {}],
a: [{}, {1: 3}],
b: {c: 5, d: {e: 6}}
})
history.record([
{
path: '1[4]',
value: [],
insertArray: true
},
{
path: '1[5]',
value: [1, 2, 3]
}
])
expect(history.tree).toEqual({
1: [1, 3, null, null, [], [1, 2, 3]],
a: [{}, {1: 3}],
b: {c: 5, d: {e: 6}}
})
history.record([{
path: 'a.b',
value: 123
}])
expect(history.tree).toEqual({
1: [1, 3, null, null, [], [1, 2, 3]],
a: { b: 123 },
b: {c: 5, d: {e: 6}}
})
expect(history.deltas.length).toEqual(3)
history.undo()
history.redo()
history.undo()
history.undo()
history.undo()
expect(history.tree).toEqual(tree)
Delete object key.
Same as record
with undefined
value.
const history = new JsonHistory({
tree: {
1: [1, 3],
a: [{}, { 1: 3 }],
b: { c: 5, d: { e: 6 }}
}
})
history.delete([{
path: '1'
}])
expect(history.tree).toEqual({
a: [{}, {1: 3}],
b: {c: 5, d: {e: 6}}
})
Replace the whole tree and record a step.
const history = new JsonHistory({
tree: [1, 2, 3]
})
history.snapShot([1, { a: 4 }])
expect(history.tree).toEqual([1, { a: 4 }])
history.undo()
expect(history.tree).toEqual([1, 2, 3])
Can merge multi actions, such as delete
or record
.
const history = new JsonHistory({
tree: {
1: [1, 3],
a: [{}, { 1: 3 }],
b: { c: 5, d: { e: 6 }}
}
})
history.recordsMerge(() => {
history.record([
{
path: 'b',
value: undefined
}
])
history.record([
{
path: 1,
value: []
}
])
history.record([
{
path: 'a.length.length',
value: {}
}
])
})
expect(history.deltas.length).toEqual(1)
expect(history.tree).toEqual({
1: [],
a: {
length: {
length: {}
}
}
})
Can pass a function to check the delta should delete or not.
const shouldDeleteFunction = function (defalt) {
const key = Object.keys(delta)[0]
return key === 'this one should delete'
}
cleanDeltas(shouldDeleteFunction)
const history = new JsonHistory({
tree: {
1: [1, 3],
a: [{}, { 1: 3 }],
b: { c: 5, d: { e: 6 }}
}
})
history.record([
{
path: 'b',
value: undefined
}
])
history.record([
{
path: 1,
value: []
}
])
history.record([
{
path: 'a.length.length',
value: {}
}
])
history.undo()
history.cleanDeltas(delta => {
const key = Object.keys(delta)[0]
return key === '1'
})
history.undo()
history.undo()
expect(history.tree).toEqual({
1: [],
a: [{}, {1: 3}],
b: {c: 5, d: {e: 6}}
})
https://github.com/lustan3216/json-history/tree/master/tests