@muze-nl/od-jsontag 0.4.0 → 0.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +10 -10
- package/package.json +3 -3
- package/src/parse.mjs +65 -17
- package/src/serialize.mjs +219 -219
- package/src/symbols.mjs +0 -1
- package/src/jsontag.mjs +0 -91
package/README.md
CHANGED
|
@@ -3,31 +3,31 @@
|
|
|
3
3
|
This library implements a parser and stringifier for a variant of [JSONTag](https://github.com/muze-nl/jsontag/) which is optimized so that you only need to parse objects that you use and skip parsing any other objects.
|
|
4
4
|
This is especially useful to share data between threads or other workers using sharedArrayBuffers, the only shared memory option in javascript currently.
|
|
5
5
|
|
|
6
|
-
The
|
|
6
|
+
The parser creates in memory Proxy objects that trigger parsing only when accessed. You can use the data as normal objects for most use-cases. The format supports non-enumerable
|
|
7
7
|
properties, which aren't part of the normal JSONTag format. The parse function expects an ArrayBuffer a input.
|
|
8
8
|
|
|
9
9
|
The stringify function creates a sharedArrayBuffer, which represents a file with one object per line. Each line is prefixed with a byte counter that indicates the length of the line. References to other objects are encoded as ~n, where n is the line number (starting at 0).
|
|
10
10
|
|
|
11
|
-
The
|
|
11
|
+
The parser doesn't build an id index, because that requires parsing all objects. Instead the stringify function builds or updates the id index. It isn't included in the string result.
|
|
12
12
|
|
|
13
13
|
In addition to the normal meta options, as defined in the [JSONTag library](https://github.com/muze-nl/jsontag/), od-jsontag adds the `meta.access` option. This must be a function like:
|
|
14
14
|
|
|
15
15
|
```
|
|
16
|
-
meta.access = (object, property, method) => true | false
|
|
16
|
+
parser.meta.access = (object, property, method) => true | false
|
|
17
17
|
```
|
|
18
18
|
|
|
19
|
-
If meta.access returns true, access to that property is allowed. Otherwise access is disallowed and the property value returned is `undefined`.
|
|
19
|
+
If `parser.meta.access` returns true, access to that property is allowed. Otherwise access is disallowed and the property value returned is `undefined`.
|
|
20
20
|
|
|
21
21
|
The `method` parameter is one of `set`,`get`,`has`,`deleteProperty`,`defineProperty`.
|
|
22
22
|
|
|
23
23
|
Add the access function in the meta parameter of the `parse` method:
|
|
24
24
|
|
|
25
25
|
```
|
|
26
|
-
import
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
26
|
+
import Parser from 'od-jsontag'
|
|
27
|
+
|
|
28
|
+
const parser = new Parser()
|
|
29
|
+
parser.meta.access: (object, property, method) => {
|
|
30
|
+
return property=='name'
|
|
31
31
|
}
|
|
32
|
-
const root = parse(string
|
|
32
|
+
const root = parser.parse(string)
|
|
33
33
|
```
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@muze-nl/od-jsontag",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.1",
|
|
4
4
|
"description": "On Demand JSONTag: parse/serialize large datastructures on demand, useful for sharing data between threads",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"author": "Auke van Slooten <auke@muze.nl>",
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
"@eslint/js": "^9.36.0",
|
|
29
29
|
"eslint": "^9.36.0",
|
|
30
30
|
"globals": "^16.4.0",
|
|
31
|
-
"tap": "~
|
|
31
|
+
"tap": "~21.1.0"
|
|
32
32
|
},
|
|
33
33
|
"files": [
|
|
34
34
|
"src/",
|
|
@@ -36,6 +36,6 @@
|
|
|
36
36
|
"LICENSE"
|
|
37
37
|
],
|
|
38
38
|
"dependencies": {
|
|
39
|
-
"@muze-nl/jsontag": "^0.10.
|
|
39
|
+
"@muze-nl/jsontag": "^0.10.2"
|
|
40
40
|
}
|
|
41
41
|
}
|
package/src/parse.mjs
CHANGED
|
@@ -60,10 +60,22 @@ export default class Parser extends JSONTag.Parser
|
|
|
60
60
|
this.handlers = {
|
|
61
61
|
newArrayHandler: {
|
|
62
62
|
get: (target, prop) => {
|
|
63
|
+
switch(prop) {
|
|
64
|
+
case source:
|
|
65
|
+
return target
|
|
66
|
+
break
|
|
67
|
+
case isProxy:
|
|
68
|
+
return true
|
|
69
|
+
break
|
|
70
|
+
case proxyType:
|
|
71
|
+
return 'new'
|
|
72
|
+
break
|
|
73
|
+
}
|
|
63
74
|
if (target[prop] instanceof Function) {
|
|
64
75
|
return (...args) => {
|
|
65
76
|
args = args.map(arg => {
|
|
66
|
-
|
|
77
|
+
const type = JSONTag.getType(arg)
|
|
78
|
+
if (type==='object' || type==='link') {
|
|
67
79
|
arg = this.getNewValueProxy(arg)
|
|
68
80
|
}
|
|
69
81
|
return arg
|
|
@@ -91,7 +103,10 @@ export default class Parser extends JSONTag.Parser
|
|
|
91
103
|
if (this.meta.access && !this.meta.access(target, prop)) {
|
|
92
104
|
return undefined
|
|
93
105
|
}
|
|
94
|
-
|
|
106
|
+
const type = JSONTag.getType(arg)
|
|
107
|
+
if ((type==='object' || type==='link')
|
|
108
|
+
&& typeof prop !== 'symbol'
|
|
109
|
+
) {
|
|
95
110
|
value = this.getNewValueProxy(value)
|
|
96
111
|
}
|
|
97
112
|
target[prop] = value
|
|
@@ -143,7 +158,10 @@ export default class Parser extends JSONTag.Parser
|
|
|
143
158
|
if (this.meta.access && !this.meta.access(target, prop, 'set')) {
|
|
144
159
|
return undefined
|
|
145
160
|
}
|
|
146
|
-
|
|
161
|
+
const type = JSONTag.getType(arg)
|
|
162
|
+
if ((type==='object' || type==='link')
|
|
163
|
+
&& typeof prop !== 'symbol'
|
|
164
|
+
) {
|
|
147
165
|
value = this.getNewValueProxy(value)
|
|
148
166
|
}
|
|
149
167
|
target[prop] = value
|
|
@@ -152,17 +170,31 @@ export default class Parser extends JSONTag.Parser
|
|
|
152
170
|
},
|
|
153
171
|
arrayHandler: {
|
|
154
172
|
get: (target, prop, receiver) => {
|
|
173
|
+
switch(prop) {
|
|
174
|
+
case source:
|
|
175
|
+
return target
|
|
176
|
+
break
|
|
177
|
+
case isProxy:
|
|
178
|
+
return true
|
|
179
|
+
break
|
|
180
|
+
case proxyType:
|
|
181
|
+
return 'array'
|
|
182
|
+
break
|
|
183
|
+
}
|
|
155
184
|
const value = target?.[prop]
|
|
156
185
|
if (value instanceof Function) {
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
186
|
+
if (['copyWithin','fill','pop','push','reverse','shift','sort','splice','unshift'].indexOf(prop)!==-1) {
|
|
187
|
+
if (this.immutable) {
|
|
188
|
+
throw new Error('dataspace is immutable')
|
|
189
|
+
}
|
|
190
|
+
}
|
|
162
191
|
return (...args) => {
|
|
163
192
|
args = args.map(arg => {
|
|
164
|
-
if (
|
|
165
|
-
|
|
193
|
+
if (!arg[isProxy]) {
|
|
194
|
+
let type = JSONTag.getType(arg)
|
|
195
|
+
if (type==='object' || type==='link') { //FIXME: check if other types need handling
|
|
196
|
+
arg = this.getNewValueProxy(arg)
|
|
197
|
+
}
|
|
166
198
|
}
|
|
167
199
|
return arg
|
|
168
200
|
})
|
|
@@ -193,7 +225,10 @@ export default class Parser extends JSONTag.Parser
|
|
|
193
225
|
if (this.meta.access && !this.meta.access(target, prop, 'set')) {
|
|
194
226
|
return undefined
|
|
195
227
|
}
|
|
196
|
-
|
|
228
|
+
const type = JSONTag.getType(value)
|
|
229
|
+
if ((type==='object' || type==='link') //FIXME: check if other types need handling
|
|
230
|
+
&& typeof prop !== 'symbol'
|
|
231
|
+
) {
|
|
197
232
|
value = this.getNewValueProxy(value)
|
|
198
233
|
}
|
|
199
234
|
if (target[prop] === value) {
|
|
@@ -294,7 +329,10 @@ export default class Parser extends JSONTag.Parser
|
|
|
294
329
|
if (this.meta.access && !this.meta.access(target, prop, 'set')) {
|
|
295
330
|
return undefined
|
|
296
331
|
}
|
|
297
|
-
|
|
332
|
+
const type = JSONTag.getType(value)
|
|
333
|
+
if ((type==='object' || type==='link') //FIXME: check if other types need handling
|
|
334
|
+
&& typeof prop !== 'symbol'
|
|
335
|
+
) {
|
|
298
336
|
value = this.getNewValueProxy(value)
|
|
299
337
|
}
|
|
300
338
|
if (target[prop] === value) {
|
|
@@ -679,10 +717,9 @@ export default class Parser extends JSONTag.Parser
|
|
|
679
717
|
Object.entries(parent).forEach(([key,entry]) => {
|
|
680
718
|
if (Array.isArray(entry)) {
|
|
681
719
|
this.makeChildProxies(entry)
|
|
682
|
-
} else if (entry &&
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
} else {
|
|
720
|
+
} else if (entry && !entry[isProxy]) {
|
|
721
|
+
let type = JSONTag.getType(entry)
|
|
722
|
+
if (type==='object' || type==='link') {//FIXME: check for other types
|
|
686
723
|
parent[key] = this.getNewValueProxy(entry)
|
|
687
724
|
}
|
|
688
725
|
}
|
|
@@ -716,6 +753,15 @@ export default class Parser extends JSONTag.Parser
|
|
|
716
753
|
if (value === null) {
|
|
717
754
|
return null
|
|
718
755
|
}
|
|
756
|
+
if (value[isProxy]) {
|
|
757
|
+
return value
|
|
758
|
+
}
|
|
759
|
+
if (JSONTag.getType(value)=='link') {
|
|
760
|
+
let index = this.meta.index.id.get(''+value)
|
|
761
|
+
if (typeof index != 'undefined') {
|
|
762
|
+
return this.meta.resultArray[index]
|
|
763
|
+
}
|
|
764
|
+
}
|
|
719
765
|
let index = this.meta.resultArray.length
|
|
720
766
|
this.meta.resultArray.push('')
|
|
721
767
|
value[getIndex] = index
|
|
@@ -759,10 +805,12 @@ export default class Parser extends JSONTag.Parser
|
|
|
759
805
|
return this.meta.resultArray[0]
|
|
760
806
|
}
|
|
761
807
|
|
|
762
|
-
checkUnresolved() {
|
|
808
|
+
checkUnresolved(item, object, key) {
|
|
763
809
|
// TODO:
|
|
764
810
|
// for now assume there are no <link> objects in od-jsontag
|
|
765
811
|
// JSONTag Parser.checkUnresolved triggers firstParse,
|
|
766
812
|
// while parsing the current object
|
|
813
|
+
// incorrect: when adding a new object from a JSONTag string
|
|
814
|
+
// it may contain links which cannot yet be resolved... these need to be handled
|
|
767
815
|
}
|
|
768
816
|
}
|
package/src/serialize.mjs
CHANGED
|
@@ -16,233 +16,233 @@ function stringToSAB(strData) {
|
|
|
16
16
|
}
|
|
17
17
|
|
|
18
18
|
export default function serialize(value, options={}) {
|
|
19
|
-
|
|
20
|
-
|
|
19
|
+
let resultArray = false
|
|
20
|
+
let references = new WeakMap()
|
|
21
21
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
22
|
+
if (options.meta) {
|
|
23
|
+
if (!options.meta.index) {
|
|
24
|
+
options.meta.index = {}
|
|
25
|
+
}
|
|
26
|
+
if (!options.meta.index.id) {
|
|
27
|
+
options.meta.index.id = new Map()
|
|
28
|
+
}
|
|
29
|
+
if (options.meta.resultArray) {
|
|
30
|
+
resultArray = options.meta.resultArray
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
if (!resultArray) {
|
|
34
|
+
resultArray = value?.[resultSet]
|
|
35
|
+
}
|
|
36
|
+
if (!resultArray) {
|
|
37
|
+
resultArray = []
|
|
38
|
+
}
|
|
39
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
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
40
|
+
function stringifyValue(value, inarray=false, current) {
|
|
41
|
+
let prop
|
|
42
|
+
let typeString = JSONTag.getTypeString(value)
|
|
43
|
+
let type = JSONTag.getType(value)
|
|
44
|
+
switch (type) {
|
|
45
|
+
case 'string':
|
|
46
|
+
case 'decimal':
|
|
47
|
+
case 'money':
|
|
48
|
+
case 'link':
|
|
49
|
+
case 'text':
|
|
50
|
+
case 'blob':
|
|
51
|
+
case 'color':
|
|
52
|
+
case 'email':
|
|
53
|
+
case 'hash':
|
|
54
|
+
case 'duration':
|
|
55
|
+
case 'phone':
|
|
56
|
+
case 'url':
|
|
57
|
+
case 'uuid':
|
|
58
|
+
case 'date':
|
|
59
|
+
case 'time':
|
|
60
|
+
case 'datetime':
|
|
61
|
+
if (JSONTag.isNull(value)) {
|
|
62
|
+
value = 'null'
|
|
63
|
+
} else {
|
|
64
|
+
value = realJSON.stringify(''+value)
|
|
65
|
+
}
|
|
66
|
+
prop = typeString + value
|
|
67
|
+
break
|
|
68
|
+
case 'int':
|
|
69
|
+
case 'uint':
|
|
70
|
+
case 'int8':
|
|
71
|
+
case 'uint8':
|
|
72
|
+
case 'int16':
|
|
73
|
+
case 'uint16':
|
|
74
|
+
case 'int32':
|
|
75
|
+
case 'uint32':
|
|
76
|
+
case 'int64':
|
|
77
|
+
case 'uint64':
|
|
78
|
+
case 'float':
|
|
79
|
+
case 'float32':
|
|
80
|
+
case 'float64':
|
|
81
|
+
case 'timestamp':
|
|
82
|
+
case 'number':
|
|
83
|
+
case 'boolean':
|
|
84
|
+
if (JSONTag.isNull(value)) {
|
|
85
|
+
value = 'null'
|
|
86
|
+
} else {
|
|
87
|
+
value = realJSON.stringify(value)
|
|
88
|
+
}
|
|
89
|
+
prop = typeString + value
|
|
90
|
+
break
|
|
91
|
+
case 'array':
|
|
92
|
+
let entries = value.map(e => stringifyValue(e, true, current))
|
|
93
|
+
let mergedEntries = []
|
|
94
|
+
let previousIndex = null
|
|
95
|
+
let startSlice = null
|
|
96
|
+
entries.forEach(e => {
|
|
97
|
+
if (e[0]=='~') {
|
|
98
|
+
let currIndex = parseInt(e.substr(1))
|
|
99
|
+
if (startSlice && currIndex === (previousIndex + 1)) {
|
|
100
|
+
mergedEntries.pop()
|
|
101
|
+
mergedEntries.push('~' + startSlice + '-' + currIndex)
|
|
102
|
+
previousIndex = currIndex
|
|
103
|
+
} else {
|
|
104
|
+
mergedEntries.push(e)
|
|
105
|
+
previousIndex = currIndex
|
|
106
|
+
startSlice = currIndex
|
|
107
|
+
}
|
|
108
|
+
} else {
|
|
109
|
+
mergedEntries.push(e)
|
|
110
|
+
previousIndex = null
|
|
111
|
+
startSlice = null
|
|
112
|
+
}
|
|
113
|
+
})
|
|
114
|
+
entries = mergedEntries.join(',')
|
|
115
|
+
prop = typeString + '[' + entries + ']'
|
|
116
|
+
break
|
|
117
|
+
case 'object':
|
|
118
|
+
if (!value) {
|
|
119
|
+
prop = 'null'
|
|
120
|
+
} else if (value[isProxy]) {
|
|
121
|
+
if (inarray) {
|
|
122
|
+
prop = '~'+value[getIndex]
|
|
123
|
+
} else {
|
|
124
|
+
prop = decoder.decode(value[getBuffer](current))
|
|
125
|
+
}
|
|
126
|
+
} else {
|
|
127
|
+
if (!references.has(value)) {
|
|
128
|
+
references.set(value, resultArray.length)
|
|
129
|
+
resultArray.push(value)
|
|
130
|
+
}
|
|
131
|
+
prop = '~'+references.get(value)
|
|
132
|
+
}
|
|
133
|
+
break
|
|
134
|
+
default:
|
|
135
|
+
throw new Error(JSONTag.getType(value)+' type not yet implemented')
|
|
136
|
+
break
|
|
137
|
+
}
|
|
138
|
+
return prop
|
|
139
|
+
}
|
|
140
140
|
|
|
141
|
-
|
|
142
|
-
|
|
141
|
+
const encoder = new TextEncoder()
|
|
142
|
+
const decoder = new TextDecoder()
|
|
143
143
|
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
144
|
+
// is only ever called on object values
|
|
145
|
+
// and should always return a stringified object, not a reference (~n)
|
|
146
|
+
const innerStringify = (current) => {
|
|
147
|
+
let object = resultArray[current]
|
|
148
|
+
let result
|
|
149
149
|
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
150
|
+
// if value is a valueProxy, just copy the input slice
|
|
151
|
+
if (object && !JSONTag.isNull(object) && object[isProxy] && !object[isChanged]) {
|
|
152
|
+
return decoder.decode(object[getBuffer](current))
|
|
153
|
+
}
|
|
154
|
+
if (typeof object === 'undefined' || object === null) {
|
|
155
|
+
return 'null'
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
let props = []
|
|
159
|
+
for (let key of Object.getOwnPropertyNames(object)) {
|
|
160
|
+
let value = object[key]
|
|
161
|
+
let prop = stringifyValue(value, false, current)
|
|
162
|
+
let enumerable = object.propertyIsEnumerable(key) ? '' : '#'
|
|
163
|
+
props.push(enumerable+realJSON.stringify(key)+':'+prop) //FIXME: how does key get escaped?
|
|
164
|
+
}
|
|
165
|
+
result = JSONTag.getTypeString(object)+'{'+props.join(',')+'}'
|
|
166
|
+
return result
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
const encode = (s) => {
|
|
170
|
+
if (typeof s == 'string' || s instanceof String) {
|
|
171
|
+
s = encoder.encode(s)
|
|
172
|
+
}
|
|
173
|
+
if (s[0]==43 || options.skipLength) {
|
|
174
|
+
return new Uint8Array(s)
|
|
175
|
+
}
|
|
176
|
+
let length = encoder.encode('('+s.length+')')
|
|
177
|
+
let u8arr = new Uint8Array(length.length+s.length)
|
|
178
|
+
u8arr.set(length, 0)
|
|
179
|
+
u8arr.set(s, length.length)
|
|
180
|
+
return u8arr
|
|
181
|
+
}
|
|
182
182
|
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
183
|
+
if (!value?.[resultSet]) {
|
|
184
|
+
resultArray.push(value)
|
|
185
|
+
}
|
|
186
|
+
let currentSource = 0
|
|
187
|
+
let currentResult = 0
|
|
188
|
+
let skipCount = 0
|
|
189
|
+
let result = []
|
|
190
|
+
while(currentSource<resultArray.length) {
|
|
191
|
+
if (!resultArray[currentSource]) {
|
|
192
|
+
//FIXME: should not happen, this means that there is no complete
|
|
193
|
+
//od-jsontag file, only patches?
|
|
194
|
+
skipCount++
|
|
195
|
+
} else if (resultArray[currentSource][isChanged] || !resultArray[currentSource][isProxy]) {
|
|
196
|
+
if (skipCount) {
|
|
197
|
+
result[currentResult] = encoder.encode('+'+skipCount)
|
|
198
|
+
skipCount = 0
|
|
199
|
+
currentResult++
|
|
200
|
+
}
|
|
201
|
+
result[currentResult] = encoder.encode(innerStringify(currentSource))
|
|
202
|
+
if (options.meta) {
|
|
203
|
+
const id=JSONTag.getAttribute(resultArray[currentSource],'id')
|
|
204
|
+
if (id) {
|
|
205
|
+
options.meta.index.id.set(id, currentSource)
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
currentResult++
|
|
209
|
+
} else if (!options.changes) {
|
|
210
|
+
result[currentResult] = resultArray[currentSource][getBuffer](currentSource)
|
|
211
|
+
if (options.meta) {
|
|
212
|
+
const id=JSONTag.getAttribute(resultArray[currentSource],'id')
|
|
213
|
+
if (id) {
|
|
214
|
+
options.meta.index.id.set(id, currentSource)
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
currentResult++
|
|
218
|
+
} else {
|
|
219
|
+
skipCount++
|
|
220
|
+
}
|
|
221
221
|
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
222
|
+
currentSource++
|
|
223
|
+
}
|
|
224
|
+
let arr = result.map(encode)
|
|
225
|
+
let length = 0
|
|
226
|
+
for (let line of arr) {
|
|
227
|
+
length += line.length+1
|
|
228
|
+
}
|
|
229
|
+
if (length) {
|
|
230
|
+
length -= 1 // skip last newline
|
|
231
|
+
}
|
|
232
|
+
let sab = new SharedArrayBuffer(length)
|
|
233
|
+
let u8arr = new Uint8Array(sab)
|
|
234
|
+
let offset = 0
|
|
235
|
+
for(let line of arr) {
|
|
236
|
+
u8arr.set(line, offset)
|
|
237
|
+
offset+=line.length
|
|
238
|
+
if (offset<length) {
|
|
239
|
+
u8arr.set([10], offset)
|
|
240
|
+
offset++
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
return u8arr
|
|
244
244
|
}
|
|
245
245
|
|
|
246
246
|
export function stringify(buf) {
|
|
247
|
-
|
|
247
|
+
return decoder.decode(buf)
|
|
248
248
|
}
|
package/src/symbols.mjs
CHANGED
|
@@ -5,7 +5,6 @@ export const getBuffer = Symbol('getBuffer')
|
|
|
5
5
|
export const getIndex = Symbol('getIndex')
|
|
6
6
|
export const isChanged = Symbol('isChanged')
|
|
7
7
|
export const isParsed = Symbol('isParsed')
|
|
8
|
-
export const isReceived = Symbol('isReceived')
|
|
9
8
|
export const getString = Symbol('getString')
|
|
10
9
|
export const position = Symbol('position')
|
|
11
10
|
export const parent = Symbol('parent')
|
package/src/jsontag.mjs
DELETED
|
@@ -1,91 +0,0 @@
|
|
|
1
|
-
import JSONTag from '@muze-nl/jsontag'
|
|
2
|
-
import {source, isChanged} from './symbols.mjs'
|
|
3
|
-
|
|
4
|
-
export function getType(obj) {
|
|
5
|
-
return JSONTag.getType(obj?.[source] ?? obj)
|
|
6
|
-
}
|
|
7
|
-
|
|
8
|
-
export function getAttribute(obj, attr) {
|
|
9
|
-
return JSONTag.getAttribute(obj?.[source] ?? obj, attr)
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
export function getAttributes(obj) {
|
|
13
|
-
return JSONTag.getAttributes(obj?.[source] ?? obj)
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
export function getAttributeString(obj) {
|
|
17
|
-
return JSONTag.getAttributesString(obj?.[source] ?? obj)
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
export function getTypeString(obj) {
|
|
21
|
-
return JSONTag.getTypeString(obj?.[source] ?? obj)
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
export function isNull(obj) {
|
|
25
|
-
return JSONTag.isNull(obj?.[source] ?? obj)
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
export function setAttribute(obj, attr, value) {
|
|
29
|
-
if (obj?.[source]) {
|
|
30
|
-
obj[isChanged] = true
|
|
31
|
-
// const info = globalThis.JSONTagTypeInfo.get(obj[source])
|
|
32
|
-
// if (!info) {
|
|
33
|
-
// info = {}
|
|
34
|
-
// globalThis.JSONTagTypeInfo.set(obj[source], info)
|
|
35
|
-
// }
|
|
36
|
-
// globalThis.JSONTagTypeInfo.set(obj, info)
|
|
37
|
-
}
|
|
38
|
-
return JSONTag.setAttribute(obj?.[source] ?? obj, attr, value)
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
export function setAttributes(obj, attr) {
|
|
42
|
-
if (obj?.[source]) {
|
|
43
|
-
obj[isChanged] = true
|
|
44
|
-
// const info = globalThis.JSONTagTypeInfo.get(obj[source])
|
|
45
|
-
// if (!info) {
|
|
46
|
-
// info = {}
|
|
47
|
-
// globalThis.JSONTagTypeInfo.set(obj[source], info)
|
|
48
|
-
// }
|
|
49
|
-
// globalThis.JSONTagTypeInfo.set(obj, info)
|
|
50
|
-
}
|
|
51
|
-
return JSONTag.setAttribute(obj?.[source] ?? obj, attr)
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
export function setType(obj, type) {
|
|
55
|
-
if (obj?.[source]) {
|
|
56
|
-
obj[isChanged] = true
|
|
57
|
-
// const info = globalThis.JSONTagTypeInfo.get(obj[source])
|
|
58
|
-
// if (!info) {
|
|
59
|
-
// info = {}
|
|
60
|
-
// globalThis.JSONTagTypeInfo.set(obj[source], info)
|
|
61
|
-
// }
|
|
62
|
-
// globalThis.JSONTagTypeInfo.set(obj, info)
|
|
63
|
-
}
|
|
64
|
-
return JSONTag.setType(obj?.[source] ?? obj, type)
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
export function addAttribute(obj, attr, value) {
|
|
68
|
-
if (obj?.[source]) {
|
|
69
|
-
obj[isChanged] = true
|
|
70
|
-
// const info = globalThis.JSONTagTypeInfo.get(obj[source])
|
|
71
|
-
// if (!info) {
|
|
72
|
-
// info = {}
|
|
73
|
-
// globalThis.JSONTagTypeInfo.set(obj[source], info)
|
|
74
|
-
// }
|
|
75
|
-
// globalThis.JSONTagTypeInfo.set(obj, info)
|
|
76
|
-
}
|
|
77
|
-
return JSONTag.addAttribute(obj?.[source] ?? obj, attr, value)
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
export function removeAttribute(obj, attr) {
|
|
81
|
-
if (obj?.[source]) {
|
|
82
|
-
obj[isChanged] = true
|
|
83
|
-
// const info = globalThis.JSONTagTypeInfo.get(obj[source])
|
|
84
|
-
// if (!info) {
|
|
85
|
-
// info = {}
|
|
86
|
-
// globalThis.JSONTagTypeInfo.set(obj[source], info)
|
|
87
|
-
// }
|
|
88
|
-
// globalThis.JSONTagTypeInfo.set(obj, info)
|
|
89
|
-
}
|
|
90
|
-
return JSONTag.removeAttribute(obj?.[source] ?? obj, attr)
|
|
91
|
-
}
|