1 | CircularJSON
|
2 | ============
|
3 |
|
4 | [![donate](https://img.shields.io/badge/$-donate-ff69b4.svg?maxAge=2592000&style=flat)](https://github.com/WebReflection/donate) ![Downloads](https://img.shields.io/npm/dm/circular-json.svg) [![Build Status](https://travis-ci.org/WebReflection/circular-json.svg?branch=master)](https://travis-ci.org/WebReflection/circular-json) [![Coverage Status](https://coveralls.io/repos/github/WebReflection/circular-json/badge.svg?branch=master)](https://coveralls.io/github/WebReflection/circular-json?branch=master)
|
5 |
|
6 | Serializes and deserializes otherwise valid JSON objects containing circular references into and from a specialized JSON format.
|
7 |
|
8 | - - -
|
9 |
|
10 | ## The future of this module is called [flatted](https://github.com/WebReflection/flatted#flatted)
|
11 |
|
12 | Smaller, faster, and able to produce on average a reduced output too, [flatted](https://github.com/WebReflection/flatted#flatted) is the new, bloatless, ESM and CJS compatible, circular JSON parser.
|
13 |
|
14 | It has now reached V1 and it implements the exact same JSON API.
|
15 |
|
16 | Please note **CircularJSON is in maintenance only** and **[flatted](https://github.com/WebReflection/flatted#flatted) is its successor**.
|
17 |
|
18 | - - -
|
19 |
|
20 | ### A Working Solution To A Common Problem
|
21 | A usage example:
|
22 |
|
23 | ```JavaScript
|
24 | var object = {};
|
25 | object.arr = [
|
26 | object, object
|
27 | ];
|
28 | object.arr.push(object.arr);
|
29 | object.obj = object;
|
30 |
|
31 | var serialized = CircularJSON.stringify(object);
|
32 | // '{"arr":["~","~","~arr"],"obj":"~"}'
|
33 | // NOTE: CircularJSON DOES NOT parse JS
|
34 | // it handles receiver and reviver callbacks
|
35 |
|
36 | var unserialized = CircularJSON.parse(serialized);
|
37 | // { arr: [ [Circular], [Circular] ],
|
38 | // obj: [Circular] }
|
39 |
|
40 | unserialized.obj === unserialized;
|
41 | unserialized.arr[0] === unserialized;
|
42 | unserialized.arr.pop() === unserialized.arr;
|
43 | ```
|
44 |
|
45 | A quick summary:
|
46 |
|
47 | * **new** in version `0.5`, you can specify a JSON parser different from JSON itself. `CircularJSON.parser = ABetterJSON;` is all you need.
|
48 | * uses `~` as a special prefix symbol to denote which parent the reference belongs to (i.e. `~root~child1~child2`)
|
49 | * reasonably fast in both serialization and deserialization
|
50 | * compact serialization for easier and slimmer transportation across environments
|
51 | * [tested and covered](test/circular-json.js) over nasty structures too
|
52 | * compatible with all JavaScript engines
|
53 |
|
54 | Node Installation & Usage
|
55 | ============
|
56 |
|
57 | ```bash
|
58 | npm install --save circular-json
|
59 | ```
|
60 |
|
61 | ```javascript
|
62 | 'use strict';
|
63 |
|
64 | var
|
65 | CircularJSON = require('circular-json'),
|
66 | obj = { foo: 'bar' },
|
67 | str
|
68 | ;
|
69 |
|
70 | obj.self = obj;
|
71 | str = CircularJSON.stringify(obj);
|
72 | ```
|
73 |
|
74 | There are no dependencies.
|
75 |
|
76 | Browser Installation & Usage
|
77 | ================
|
78 |
|
79 | * Global: <build/circular-json.js>
|
80 | * AMD: <build/circular-json.amd.js>
|
81 | * CommonJS: <build/circular-json.node.js>
|
82 |
|
83 | (generated via [gitstrap](https://github.com/WebReflection/gitstrap))
|
84 |
|
85 | ```html
|
86 | <script src="build/circular-json.js"></script>
|
87 | ```
|
88 |
|
89 | ```javascript
|
90 | 'use strict';
|
91 |
|
92 | var CircularJSON = window.CircularJSON
|
93 | , obj = { foo: 'bar' }
|
94 | , str
|
95 | ;
|
96 |
|
97 | obj.self = obj;
|
98 | str = CircularJSON.stringify(obj);
|
99 | ```
|
100 |
|
101 | NOTE: Platforms without native JSON (i.e. MSIE <= 8) requires `json3.js` or similar.
|
102 |
|
103 | It is also *a bad idea* to `CircularJSON.parse(JSON.stringify(object))` because of those manipulation used in `CircularJSON.stringify()` able to make parsing safe and secure.
|
104 |
|
105 | As summary: `CircularJSON.parse(CircularJSON.stringify(object))` is the way to go, same is for `JSON.parse(JSON.stringify(object))`.
|
106 |
|
107 | API
|
108 | ===
|
109 |
|
110 | It's the same as native JSON, except the fourth parameter `placeholder`, which circular references to be replaced with `"[Circular]"` (i.e. for logging).
|
111 |
|
112 | * CircularJSON.stringify(object, replacer, spacer, placeholder)
|
113 | * CircularJSON.parse(string, reviver)
|
114 |
|
115 | Bear in mind `JSON.parse(CircularJSON.stringify(object))` will work but not produce the expected output.
|
116 |
|
117 | Similar Libraries
|
118 | =======
|
119 |
|
120 | ### Why Not the [@izs](https://twitter.com/izs) One
|
121 | The module [json-stringify-safe](https://github.com/isaacs/json-stringify-safe) seems to be for `console.log()` but it's completely pointless for `JSON.parse()`, being latter one unable to retrieve back the initial structure. Here an example:
|
122 |
|
123 | ```JavaScript
|
124 | // a logged object with circular references
|
125 | {
|
126 | "circularRef": "[Circular]",
|
127 | "list": [
|
128 | "[Circular]",
|
129 | "[Circular]"
|
130 | ]
|
131 | }
|
132 | // what do we do with above output ?
|
133 | ```
|
134 |
|
135 | Just type this in your `node` console: `var o = {}; o.a = o; console.log(o);`. The output will be `{ a: [Circular] }` ... good, but that ain't really solving the problem.
|
136 |
|
137 | However, if that's all you need, the function used to create that kind of output is probably faster than `CircularJSON` and surely fits in less lines of code.
|
138 |
|
139 |
|
140 | ### Why Not {{put random name}} Solution
|
141 | So here the thing: circular references can be wrong but, if there is a need for them, any attempt to ignore them or remove them can be considered just a failure.
|
142 |
|
143 | Not because the method is bad or it's not working, simply because the circular info, the one we needed and used in the first place, is lost!
|
144 |
|
145 | In this case, `CircularJSON` does even more than just solve circular and recursions: it maps all same objects so that less memory is used as well on deserialization as less bandwidth too!
|
146 | It's able to redefine those references back later on so the way we store is the way we retrieve and in a reasonably performant way, also trusting the snappy and native `JSON` methods to iterate.
|
147 |
|
\ | No newline at end of file |