You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
@@ -55,16 +56,83 @@ The `parse` function also matches `JSON.parse`'s behavior for invalid input. If
55
56
we have the entire value.
56
57
3. Strings may be replaced with a longer string, with more characters (in
57
58
the JavaScript sense) appended.
58
-
4. Arrays are only modified by either appending new elements, or
59
+
4. Arrays are modified only by appending new elements, or
59
60
replacing/mutating the element currently at the end.
60
61
5. Objects are only modified by either adding new properties, or
61
62
replacing/mutating the most recently added property, (except in the case of
62
63
repeated keys, see invariant 7).
63
64
6. As a consequence of 1 and 5, we only add a property to an object once we
64
65
have the entire key and enough of the value to know that value's type.
65
-
7. If an object has the same key multiple times, later values take precedence
66
-
over earlier ones, matching the behavior of JSON.parse. This may result in
67
-
changing the type of a value, and mutating earlier keys in the object.
66
+
7. If an object has the same key multiple times, later values take
67
+
precedence over earlier ones, matching the behavior of JSON.parse. This
68
+
may result in changing the type of a value, and setting earlier keys
69
+
the object.
70
+
71
+
## Complete Values
72
+
73
+
The parse function can be passed an options argument as its second parameter. If the options object has a `completeCallback` function, that function will be called like `completeCallback(value, path)` each time the parser has finished with a value.
74
+
75
+
Formally, a value is complete when jsonriver will not mutate it again, nor
76
+
replace it with a different value, except for the unusual case of a
77
+
repeated key in an object (see invariant 7 in the parse() docs).
78
+
79
+
The calls that jsonriver makes to a `completeCallback` are deterministic,
80
+
regardless of how the incoming JSON streams in.
81
+
82
+
For example, when parsing this JSON:
83
+
84
+
```json
85
+
{"name": "Alex", "keys": [1, 20, 300]}
86
+
```
87
+
88
+
`completeCallback` will be called six times, with the following values:
89
+
90
+
```js
91
+
'Alex'
92
+
1
93
+
20
94
+
300
95
+
[1, 20, 300]
96
+
{"name":"Alex", "keys": [1, 20, 300]}
97
+
```
98
+
99
+
It is also given a `path`, describing where the newly complete value is in relation to the toplevel parsed value. So for the above example, the paths are:
100
+
101
+
```js
102
+
['name'] // `'Alex'` is in the 'keys' property on a toplevel object
103
+
['keys', 0] // `1` is at index 0 in the array on the 'keys' prop
104
+
['keys', 1] // `20` is at index 1 on that array
105
+
['keys', 2] // `300` is at 2
106
+
['keys'] // the array is complete, and found on the 'keys' property
107
+
[] // finally, the toplevel object is complete
108
+
```
109
+
110
+
This information is constructed lazily, so that you only pay for it if you use it. As a result, `completeCallback` must call `path.segments()` synchronously.
111
+
112
+
### Completions Recipe
113
+
114
+
A simple and low overhead way to handle completion information is with a WeakMap:
0 commit comments