Skip to content

Commit 14e5285

Browse files
committed
Making Multi type
1 parent a795099 commit 14e5285

File tree

5 files changed

+134
-6
lines changed

5 files changed

+134
-6
lines changed

src/const.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
export const ESCAPE_KEY = '$escape'
2-
export const DELETE_KEY = '$d'
32
export const FUNCTION_KEY = '$f'
3+
export const DELETE_KEY = '$d'
44
export const REPLACE_KEY = '$r'
55
export const SPLICE_KEY = '$s'
6-
export const INNER_KEY = '$i'
76
export const SWAP_KEY = '$w'
7+
export const MULTI_KEY = '$m'

src/index.js

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,13 @@ import createNodeFactory from './api/createNodeFactory'
66
import createStoreFactory from './api/createStoreFactory'
77
import applyPatchFactory from './api/applyPatchFactory'
88

9+
import Function from './types/Function'
910
import Primitives from './types/Primitives'
1011
import Delete from './types/Delete'
1112
import Replace from './types/Replace'
1213
import Splice from './types/Splice'
1314
import Swap from './types/Swap'
14-
import Function from './types/Function'
15+
import Multi from './types/Multi'
1516

1617
function factory() {
1718
const patchers = []
@@ -30,12 +31,13 @@ function factory() {
3031
if (isFunction(decode)) decoders.push(decode)
3132
}
3233

34+
addType(Function)
3335
addType(Primitives)
3436
addType(Delete)
3537
addType(Replace)
3638
addType(Splice)
3739
addType(Swap)
38-
addType(Function)
40+
addType(Multi)
3941

4042
return {
4143
version,
@@ -52,6 +54,7 @@ function factory() {
5254
Replace,
5355
Splice,
5456
Swap,
57+
Multi,
5558
},
5659
}
5760
}

src/types/Multi.js

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
import { ESCAPE_KEY, MULTI_KEY } from '../const'
2+
import { isValidToEscape } from '../util/isValid'
3+
import { getUniqueKey } from '../util/get'
4+
import { isArray } from '../util/is'
5+
6+
export default function Multi(...values) {
7+
if (!(this instanceof Multi)) {
8+
return new Multi(...values)
9+
}
10+
this.values = values
11+
}
12+
13+
Multi.patch = function ({ patch, target, prop, old_value, applyPatch }) {
14+
const patch_value = patch[prop]
15+
if (patch_value instanceof Multi) {
16+
target[prop] = old_value
17+
const unpatch = patch_value.values.map((value) => {
18+
const { unpatch } = applyPatch(target, { [prop]: value })
19+
return unpatch[prop]
20+
})
21+
return Multi.apply(null, unpatch.reverse())
22+
}
23+
return old_value
24+
}
25+
26+
Multi.encode = function ({ value, encode }) {
27+
if (value instanceof Multi) {
28+
return { [MULTI_KEY]: encode(value.values) }
29+
} else if (isValidToDecodeMulti({ value })) {
30+
return { [ESCAPE_KEY]: value }
31+
}
32+
return value
33+
}
34+
35+
Multi.decode = function ({ value, decode }) {
36+
if (isValidToDecodeMulti({ value })) {
37+
return Multi.apply(null, decode(value[MULTI_KEY]))
38+
} else if (
39+
isValidToEscape({ value }) &&
40+
isValidToDecodeMulti({ value: value[ESCAPE_KEY] })
41+
) {
42+
return value[ESCAPE_KEY]
43+
}
44+
return value
45+
}
46+
47+
function isValidToDecodeMulti({ value }) {
48+
return getUniqueKey(value) === MULTI_KEY && isArray(value[MULTI_KEY])
49+
}

test/type_multi.js

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
import test from 'ava'
2+
import { applyPatch } from '../'
3+
import { TYPE } from '../'
4+
import { testEncodeDecode, testPatchUnpatch } from './utils'
5+
6+
test('Valid type', function (t) {
7+
const patch = { convert: TYPE.Multi(0, 1) }
8+
const expected = { convert: { $m: [0, 1] } }
9+
testEncodeDecode(t, patch, expected)
10+
})
11+
12+
test('Inner encode', function (t) {
13+
const patch = { convert: TYPE.Multi(0, 1, TYPE.Delete()) }
14+
const expected = { convert: { $m: [0, 1, { $d: 0 }] } }
15+
const { encoded, decoded } = testEncodeDecode(t, patch, expected)
16+
})
17+
18+
// test('Escape', function (t) {
19+
// const patch = { escape: { $w: [0, 1] } }
20+
// const expected = { escape: { $escape: { $w: [0, 1] } } }
21+
// testEncodeDecode(t, patch, expected)
22+
// })
23+
24+
// test('Ignore', function (t) {
25+
// const patch = { ignore: { $w: { a: 2 } } }
26+
// const expected = { ignore: { $w: { a: 2 } } }
27+
// testEncodeDecode(t, patch, expected)
28+
// })
29+
30+
// test('API', function (t) {
31+
// const target = { array: ['a', 'b'] }
32+
// const patch = { array: TYPE.Swap(0, 1) }
33+
// const expected = { array: ['b', 'a'] }
34+
// const { unpatch, result, mutations } = testPatchUnpatch(
35+
// t,
36+
// target,
37+
// patch,
38+
// expected
39+
// )
40+
// t.is(mutations.length, 1)
41+
// t.is(result.array, target.array)
42+
// t.true(unpatch.array instanceof TYPE.Swap)
43+
// t.deepEqual(unpatch.array.args, [1, 0])
44+
// })
45+
46+
test('Deleting', function (t) {
47+
const target = { array: false }
48+
const patch = { array: TYPE.Multi(TYPE.Delete()) }
49+
const expected = {}
50+
testPatchUnpatch(t, target, patch, expected)
51+
})
52+
53+
test('Adding array and swaping', function (t) {
54+
const target = { array: 1234 }
55+
const patch = { array: TYPE.Multi([1, 2], TYPE.Swap(0, 1)) }
56+
const expected = { array: [2, 1] }
57+
testPatchUnpatch(t, target, patch, expected)
58+
})
59+
60+
test('Undefined before applying Multi', function (t) {
61+
const target = {}
62+
const patch = { array: TYPE.Multi(true) }
63+
const expected = { array: true }
64+
testPatchUnpatch(t, target, patch, expected)
65+
})

test/utils.js

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,15 +31,26 @@ function testEncodeDecode(
3131
const encoded = serializeDeserialize(encode(patch), serialize)
3232
t.deepEqual(expected, encoded)
3333
t.not(patch, encoded)
34+
const decoded = decode(serializeDeserialize(encoded, serialize))
3435
if (reverse) {
35-
const decoded = decode(serializeDeserialize(encoded, serialize))
3636
t.deepEqual(patch, decoded)
3737
t.not(encoded, decoded)
3838
}
39+
return { encoded, decoded }
3940
}
4041

41-
function testPatchUnpatch(t, target, patch, expected, reverse = true) {
42+
function testPatchUnpatch(
43+
t,
44+
target,
45+
patch,
46+
expected,
47+
reverse = true,
48+
serialize = true
49+
) {
4250
const cloned = getNewPlain(target)
51+
52+
// patch = decode(serializeDeserialize(encode(patch), serialize))
53+
4354
const output = applyPatch(target, patch)
4455
const { unpatch, mutations, result } = output
4556
if (isPlainObject(result) && isPlainObject(target)) {

0 commit comments

Comments
 (0)