├── .gitignore
├── .prettierrc
├── .babelrc
├── example
├── package.json
└── index.js
├── README.md
├── package.json
└── src
└── index.js
/.gitignore:
--------------------------------------------------------------------------------
1 | /lib
2 | /example/package-lock.json
3 |
--------------------------------------------------------------------------------
/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "semi": false,
3 | "trailingComma": "all",
4 | "printWidth": 120
5 | }
6 |
--------------------------------------------------------------------------------
/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": ["@babel/preset-env", "@babel/preset-stage-1", "@babel/preset-react"]
3 | }
4 |
--------------------------------------------------------------------------------
/example/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "dependencies": {
3 | "react": "latest",
4 | "react-serialize": "latest"
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/example/index.js:
--------------------------------------------------------------------------------
1 | import React from "react"
2 | import { serialize, deserialize } from "react-serialize"
3 |
4 | const input = (
5 |
6 |
7 |
8 |
9 |
10 | )
11 | console.log("input", input)
12 |
13 | const json = serialize(input)
14 | console.log("json", json)
15 |
16 | const output = deserialize(json)
17 | console.log("output", output)
18 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | # React Serialize
4 |
5 | serialize and deserialize React components to JSON
6 |
7 |
8 |
9 | |
10 |
11 | ```js
12 | serialize(
13 |
14 |
15 |
16 |
17 |
18 | )
19 | ```
20 |
21 | | ⇄ |
22 |
23 | ```js
24 | deserialize({
25 | type: "div",
26 | props: {
27 | children: {
28 | type: "h1",
29 | props: {
30 | align: "center",
31 | children: { type: "blink", props: { children: "Hello" } }
32 | }
33 | }
34 | }
35 | })
36 | ```
37 |
38 | |
39 |
40 | ## Install
41 |
42 | ```sh
43 | npm i react-serialize
44 | ```
45 |
46 | ## API
47 |
48 | See [src/index.js](src/index.js#L1).
49 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "react-serialize",
3 | "productName": "React Serialize",
4 | "description": "Serialize and deserialize React components to JSON",
5 | "keywords": [
6 | "react",
7 | "serialization"
8 | ],
9 | "version": "0.2.1",
10 | "main": "lib",
11 | "esnext": "src",
12 | "files": [
13 | "bin",
14 | "lib",
15 | "src"
16 | ],
17 | "scripts": {
18 | "build": "babel src -d lib",
19 | "watch": "babel src -d lib -w",
20 | "prepare": "npm run build"
21 | },
22 | "devDependencies": {
23 | "@babel/cli": "^7.0.0-beta.44",
24 | "@babel/core": "^7.0.0-beta.44",
25 | "@babel/preset-env": "^7.0.0-beta.44",
26 | "@babel/preset-stage-1": "^7.0.0-beta.44",
27 | "@babel/preset-react": "^7.0.0-beta.44"
28 | },
29 | "peerDependencies": {
30 | "react": ">14.0.0"
31 | },
32 | "license": "MIT"
33 | }
34 |
--------------------------------------------------------------------------------
/src/index.js:
--------------------------------------------------------------------------------
1 | import React from "react"
2 |
3 | /**
4 | * Serialize React element to JSON string
5 | *
6 | * @param {ReactNode} element
7 | * @returns {string}
8 | */
9 | export function serialize(element) {
10 | const replacer = (key, value) => {
11 | switch (key) {
12 | case "_owner":
13 | case "_store":
14 | case "ref":
15 | case "key":
16 | return
17 | default:
18 | return value
19 | }
20 | }
21 |
22 | return JSON.stringify(element, replacer)
23 | }
24 |
25 | /**
26 | * Deserialize JSON string to React element
27 | *
28 | * @param {string|object} data
29 | * @param {object?} options
30 | * @param {object?} options.components
31 | * @param {function?} options.reviver
32 | * @returns {ReactNode}
33 | */
34 | export function deserialize(data, options) {
35 | if (typeof data === "string") {
36 | data = JSON.parse(data)
37 | }
38 | if (data instanceof Object) {
39 | return deserializeElement(data, options)
40 | }
41 | throw new Error("Deserialization error: incorrect data type")
42 | }
43 |
44 | function deserializeElement(element, options = {}, key) {
45 | let { components = {}, reviver } = options
46 |
47 | if (typeof element !== "object") {
48 | return element
49 | }
50 |
51 | if (element === null) {
52 | return element
53 | }
54 |
55 | if (element instanceof Array) {
56 | return element.map((el, i) => deserializeElement(el, options, i))
57 | }
58 |
59 | // Now element has following shape { type: string, props: object }
60 |
61 | let { type, props } = element
62 |
63 | if (typeof type !== "string") {
64 | throw new Error("Deserialization error: element type must be string")
65 | }
66 |
67 | type = components[type] || type.toLowerCase()
68 |
69 | if (props.children) {
70 | props = { ...props, children: deserializeElement(props.children, options) }
71 | }
72 |
73 | if (reviver) {
74 | ;({ type, props, key, components } = reviver(type, props, key, components))
75 | }
76 |
77 | return React.createElement(type, { ...props, key })
78 | }
79 |
--------------------------------------------------------------------------------