@muze-nl/od-jsontag 0.3.4 → 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/src/serialize.mjs CHANGED
@@ -1,6 +1,5 @@
1
1
  import JSONTag from '@muze-nl/jsontag';
2
2
  import {source,isProxy, isChanged, getIndex, getBuffer, resultSet} from './symbols.mjs'
3
- import * as odJSONTag from './jsontag.mjs'
4
3
 
5
4
  // faststringify function for a fast parseable arraybuffer output
6
5
  //
@@ -17,233 +16,233 @@ function stringToSAB(strData) {
17
16
  }
18
17
 
19
18
  export default function serialize(value, options={}) {
20
- let resultArray = false
21
- let references = new WeakMap()
19
+ let resultArray = false
20
+ let references = new WeakMap()
22
21
 
23
- if (options.meta) {
24
- if (!options.meta.index) {
25
- options.meta.index = {}
26
- }
27
- if (!options.meta.index.id) {
28
- options.meta.index.id = new Map()
29
- }
30
- if (options.meta.resultArray) {
31
- resultArray = options.meta.resultArray
32
- }
33
- }
34
- if (!resultArray) {
35
- resultArray = value?.[resultSet]
36
- }
37
- if (!resultArray) {
38
- resultArray = []
39
- }
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
+ }
40
39
 
41
- function stringifyValue(value, inarray=false, current) {
42
- let prop
43
- let typeString = odJSONTag.getTypeString(value)
44
- let type = odJSONTag.getType(value)
45
- switch (type) {
46
- case 'string':
47
- case 'decimal':
48
- case 'money':
49
- case 'link':
50
- case 'text':
51
- case 'blob':
52
- case 'color':
53
- case 'email':
54
- case 'hash':
55
- case 'duration':
56
- case 'phone':
57
- case 'url':
58
- case 'uuid':
59
- case 'date':
60
- case 'time':
61
- case 'datetime':
62
- if (odJSONTag.isNull(value)) {
63
- value = 'null'
64
- } else {
65
- value = realJSON.stringify(''+value)
66
- }
67
- prop = typeString + value
68
- break
69
- case 'int':
70
- case 'uint':
71
- case 'int8':
72
- case 'uint8':
73
- case 'int16':
74
- case 'uint16':
75
- case 'int32':
76
- case 'uint32':
77
- case 'int64':
78
- case 'uint64':
79
- case 'float':
80
- case 'float32':
81
- case 'float64':
82
- case 'timestamp':
83
- case 'number':
84
- case 'boolean':
85
- if (odJSONTag.isNull(value)) {
86
- value = 'null'
87
- } else {
88
- value = realJSON.stringify(value)
89
- }
90
- prop = typeString + value
91
- break
92
- case 'array':
93
- let entries = value.map(e => stringifyValue(e, true, current))
94
- let mergedEntries = []
95
- let previousIndex = null
96
- let startSlice = null
97
- entries.forEach(e => {
98
- if (e[0]=='~') {
99
- let currIndex = parseInt(e.substr(1))
100
- if (startSlice && currIndex === (previousIndex + 1)) {
101
- mergedEntries.pop()
102
- mergedEntries.push('~' + startSlice + '-' + currIndex)
103
- previousIndex = currIndex
104
- } else {
105
- mergedEntries.push(e)
106
- previousIndex = currIndex
107
- startSlice = currIndex
108
- }
109
- } else {
110
- mergedEntries.push(e)
111
- previousIndex = null
112
- startSlice = null
113
- }
114
- })
115
- entries = mergedEntries.join(',')
116
- prop = typeString + '[' + entries + ']'
117
- break
118
- case 'object':
119
- if (!value) {
120
- prop = 'null'
121
- } else if (value[isProxy]) {
122
- if (inarray) {
123
- prop = '~'+value[getIndex]
124
- } else {
125
- prop = decoder.decode(value[getBuffer](current))
126
- }
127
- } else {
128
- if (!references.has(value)) {
129
- references.set(value, resultArray.length)
130
- resultArray.push(value)
131
- }
132
- prop = '~'+references.get(value)
133
- }
134
- break
135
- default:
136
- throw new Error(JSONTag.getType(value)+' type not yet implemented')
137
- break
138
- }
139
- return prop
140
- }
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
+ }
141
140
 
142
- const encoder = new TextEncoder()
143
- const decoder = new TextDecoder()
141
+ const encoder = new TextEncoder()
142
+ const decoder = new TextDecoder()
144
143
 
145
- // is only ever called on object values
146
- // and should always return a stringified object, not a reference (~n)
147
- const innerStringify = (current) => {
148
- let object = resultArray[current]
149
- let result
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
150
149
 
151
- // if value is a valueProxy, just copy the input slice
152
- if (object && !odJSONTag.isNull(object) && object[isProxy] && !object[isChanged]) {
153
- return decoder.decode(object[getBuffer](current))
154
- }
155
- if (typeof object === 'undefined' || object === null) {
156
- return 'null'
157
- }
158
-
159
- let props = []
160
- for (let key of Object.getOwnPropertyNames(object)) {
161
- let value = object[key]
162
- let prop = stringifyValue(value, false, current)
163
- let enumerable = object.propertyIsEnumerable(key) ? '' : '#'
164
- props.push(enumerable+realJSON.stringify(key)+':'+prop) //FIXME: how does key get escaped?
165
- }
166
- result = odJSONTag.getTypeString(object)+'{'+props.join(',')+'}'
167
- return result
168
- }
169
-
170
- const encode = (s) => {
171
- if (typeof s == 'string' || s instanceof String) {
172
- s = encoder.encode(s)
173
- }
174
- if (s[0]==43 || options.skipLength) {
175
- return new Uint8Array(s)
176
- }
177
- let length = encoder.encode('('+s.length+')')
178
- let u8arr = new Uint8Array(length.length+s.length)
179
- u8arr.set(length, 0)
180
- u8arr.set(s, length.length)
181
- return u8arr
182
- }
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
+ }
183
182
 
184
- if (!value?.[resultSet]) {
185
- resultArray.push(value)
186
- }
187
- let currentSource = 0
188
- let currentResult = 0
189
- let skipCount = 0
190
- let result = []
191
- while(currentSource<resultArray.length) {
192
- if (!resultArray[currentSource]) {
193
- //FIXME: should not happen, this means that there is no complete
194
- //od-jsontag file, only patches?
195
- skipCount++
196
- } else if (resultArray[currentSource][isChanged] || !resultArray[currentSource][isProxy]) {
197
- if (skipCount) {
198
- result[currentResult] = encoder.encode('+'+skipCount)
199
- skipCount = 0
200
- currentResult++
201
- }
202
- result[currentResult] = encoder.encode(innerStringify(currentSource))
203
- if (options.meta) {
204
- const id=odJSONTag.getAttribute(resultArray[currentSource],'id')
205
- if (id) {
206
- options.meta.index.id.set(id, currentSource)
207
- }
208
- }
209
- currentResult++
210
- } else if (!options.changes) {
211
- result[currentResult] = resultArray[currentSource][getBuffer](currentSource)
212
- if (options.meta) {
213
- const id=odJSONTag.getAttribute(resultArray[currentSource],'id')
214
- if (id) {
215
- options.meta.index.id.set(id, currentSource)
216
- }
217
- }
218
- currentResult++
219
- } else {
220
- skipCount++
221
- }
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
+ }
222
221
 
223
- currentSource++
224
- }
225
- let arr = result.map(encode)
226
- let length = 0
227
- for (let line of arr) {
228
- length += line.length+1
229
- }
230
- if (length) {
231
- length -= 1 // skip last newline
232
- }
233
- let sab = new SharedArrayBuffer(length)
234
- let u8arr = new Uint8Array(sab)
235
- let offset = 0
236
- for(let line of arr) {
237
- u8arr.set(line, offset)
238
- offset+=line.length
239
- if (offset<length) {
240
- u8arr.set([10], offset)
241
- offset++
242
- }
243
- }
244
- return u8arr
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
245
244
  }
246
245
 
247
246
  export function stringify(buf) {
248
- return decoder.decode(buf)
247
+ return decoder.decode(buf)
249
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,61 +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
- }
32
- return JSONTag.setAttribute(obj?.[source] ?? obj, attr, value)
33
- }
34
-
35
- export function setAttributes(obj, attr) {
36
- if (obj?.[source]) {
37
- obj[isChanged] = true
38
- }
39
- return JSONTag.setAttribute(obj?.[source] ?? obj, attr)
40
- }
41
-
42
- export function setType(obj, type) {
43
- if (obj?.[source]) {
44
- obj[isChanged] = true
45
- }
46
- return JSONTag.setType(obj?.[source] ?? obj, type)
47
- }
48
-
49
- export function addAttribute(obj, attr, value) {
50
- if (obj?.[source]) {
51
- obj[isChanged] = true
52
- }
53
- return JSONTag.addAttribute(obj?.[source] ?? obj, attr, value)
54
- }
55
-
56
- export function removeAttribute(obj, attr) {
57
- if (obj?.[source]) {
58
- obj[isChanged] = true
59
- }
60
- return JSONTag.removeAttribute(obj?.[source] ?? obj, attr)
61
- }