-
Notifications
You must be signed in to change notification settings - Fork 9
/
Copy pathindex.js
78 lines (64 loc) · 1.7 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
import React from "react"
/**
* Serialize React element to JSON string
*
* @param {ReactNode} element
* @returns {string}
*/
export function serialize(element) {
const replacer = (key, value) => {
switch (key) {
case "_owner":
case "_store":
case "ref":
case "key":
return
default:
return value
}
}
return JSON.stringify(element, replacer)
}
/**
* Deserialize JSON string to React element
*
* @param {string|object} data
* @param {object?} options
* @param {object?} options.components
* @param {function?} options.reviver
* @returns {ReactNode}
*/
export function deserialize(data, options) {
if (typeof data === "string") {
data = JSON.parse(data)
}
if (data instanceof Object) {
return deserializeElement(data, options)
}
throw new Error("Deserialization error: incorrect data type")
}
function deserializeElement(element, options = {}, key) {
let { components = {}, reviver } = options
if (typeof element !== "object") {
return element
}
if (element === null) {
return element
}
if (element instanceof Array) {
return element.map((el, i) => deserializeElement(el, options, i))
}
// Now element has following shape { type: string, props: object }
let { type, props } = element
if (typeof type !== "string") {
throw new Error("Deserialization error: element type must be string")
}
type = components[type] || type.toLowerCase()
if (props.children) {
props = { ...props, children: deserializeElement(props.children, options) }
}
if (reviver) {
;({ type, props, key, components } = reviver(type, props, key, components))
}
return React.createElement(type, { ...props, key })
}