@muze-nl/od-jsontag 0.2.8 → 0.3.0

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@muze-nl/od-jsontag",
3
- "version": "0.2.8",
3
+ "version": "0.3.0",
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>",
package/src/jsontag.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  import JSONTag from '@muze-nl/jsontag'
2
- import {source} from './symbols.mjs'
2
+ import {source, isChanged} from './symbols.mjs'
3
3
 
4
4
  export function getType(obj) {
5
5
  return JSONTag.getType(obj?.[source] ?? obj)
@@ -26,22 +26,36 @@ export function isNull(obj) {
26
26
  }
27
27
 
28
28
  export function setAttribute(obj, attr, value) {
29
+ if (obj?.[source]) {
30
+ obj[isChanged] = true
31
+ }
29
32
  return JSONTag.setAttribute(obj?.[source] ?? obj, attr, value)
30
33
  }
31
34
 
32
35
  export function setAttributes(obj, attr) {
36
+ if (obj?.[source]) {
37
+ obj[isChanged] = true
38
+ }
33
39
  return JSONTag.setAttribute(obj?.[source] ?? obj, attr)
34
40
  }
35
41
 
36
42
  export function setType(obj, type) {
43
+ if (obj?.[source]) {
44
+ obj[isChanged] = true
45
+ }
37
46
  return JSONTag.setType(obj?.[source] ?? obj, type)
38
47
  }
39
48
 
40
49
  export function addAttribute(obj, attr, value) {
50
+ if (obj?.[source]) {
51
+ obj[isChanged] = true
52
+ }
41
53
  return JSONTag.addAttribute(obj?.[source] ?? obj, attr, value)
42
54
  }
43
55
 
44
56
  export function removeAttribute(obj, attr) {
57
+ if (obj?.[source]) {
58
+ obj[isChanged] = true
59
+ }
45
60
  return JSONTag.removeAttribute(obj?.[source] ?? obj, attr)
46
- }
47
-
61
+ }
package/src/parse.mjs CHANGED
@@ -5,6 +5,7 @@ import {source,isProxy,proxyType,getBuffer,getIndex,isChanged,isParsed,position,
5
5
 
6
6
  const decoder = new TextDecoder()
7
7
  const encoder = new TextEncoder()
8
+ const arrayProxies = new WeakMap()
8
9
 
9
10
  function stringToSAB(strData) {
10
11
  const buffer = encoder.encode(strData)
@@ -674,6 +675,18 @@ export default function parse(input, meta, immutable=true)
674
675
  })
675
676
  }
676
677
 
678
+ const getArrayProxy = (arr, par, handler) => {
679
+ if (!handler) {
680
+ handler = handlers.arrayHandler
681
+ }
682
+ if (!arrayProxies.has(arr)) {
683
+ arrayProxies.set(arr, new Proxy(arr, handler))
684
+ }
685
+ let aProxy = arrayProxies.get(arr)
686
+ aProxy[parent] = par
687
+ return aProxy
688
+ }
689
+
677
690
  const handlers = {
678
691
  newArrayHandler: {
679
692
  get(target, prop) {
@@ -694,12 +707,17 @@ export default function parse(input, meta, immutable=true)
694
707
  return undefined
695
708
  }
696
709
  if (Array.isArray(target[prop])) {
697
- return new Proxy(target[prop], handlers.newArrayHandler)
710
+ return getArrayProxy(target[prop], target, handlers.newArrayHandler)
698
711
  }
699
712
  return target[prop]
700
713
  }
701
714
  },
702
715
  set(target, prop, value) {
716
+ if (prop === isChanged || prop === parent) {
717
+ // prevent infinite loops, parent is only needed to mark it isChanged
718
+ // but this is a new array proxy, parent is already dirty
719
+ return true
720
+ }
703
721
  if (meta.access && !meta.access(target, prop)) {
704
722
  return undefined
705
723
  }
@@ -745,7 +763,7 @@ export default function parse(input, meta, immutable=true)
745
763
  return undefined
746
764
  }
747
765
  if (Array.isArray(target[prop])) {
748
- return new Proxy(target[prop], handlers.newArrayHandler)
766
+ return getArrayProxy(target[prop], target, handlers.newArrayHandler)
749
767
  }
750
768
  return target[prop]
751
769
  break
@@ -782,19 +800,24 @@ export default function parse(input, meta, immutable=true)
782
800
  return result
783
801
  }
784
802
  } else if (prop===isChanged) {
785
- return target[parent][isChanged]
803
+ return target[isChanged] || target[parent][isChanged]
804
+ } else if (prop===source) {
805
+ return target
786
806
  } else {
787
807
  if (meta.access && !meta.access(target, prop, 'get')) {
788
808
  return undefined
789
809
  }
790
810
  if (Array.isArray(target[prop])) {
791
- target[prop][parent] = target[parent]
792
- return new Proxy(target[prop], handlers.arrayHandler)
811
+ return getArrayProxy(target[prop], target)
793
812
  }
794
813
  return target[prop]
795
814
  }
796
815
  },
797
816
  set(target, prop, value) {
817
+ if (prop == parent) {
818
+ target[parent] = value
819
+ return true
820
+ }
798
821
  if (immutable) {
799
822
  throw new Error('dataspace is immutable')
800
823
  }
@@ -805,6 +828,7 @@ export default function parse(input, meta, immutable=true)
805
828
  value = getNewValueProxy(value)
806
829
  }
807
830
  target[prop] = value
831
+ target[isChanged] = true
808
832
  target[parent][isChanged] = true
809
833
  return true
810
834
  },
@@ -819,6 +843,7 @@ export default function parse(input, meta, immutable=true)
819
843
  //that object should be deleted so that its line will become empty
820
844
  //when stringifying resultArray again
821
845
  delete target[prop]
846
+ target[isChanged] = true
822
847
  target[parent][isChanged] = true
823
848
  return true
824
849
  }
@@ -867,15 +892,14 @@ export default function parse(input, meta, immutable=true)
867
892
  return undefined
868
893
  }
869
894
  if (Array.isArray(target[prop])) {
870
- target[prop][parent] = target
871
- return new Proxy(target[prop], handlers.arrayHandler)
895
+ return getArrayProxy(target[prop], target)
872
896
  }
873
897
  return target[prop]
874
898
  break
875
899
  }
876
900
  },
877
901
  set(target, prop, value, receiver) {
878
- if (immutable && prop!==resultSet && prop!==source) {
902
+ if (immutable && prop!==resultSet && prop!==source && prop!==isChanged) {
879
903
  throw new Error('dataspace is immutable')
880
904
  }
881
905
  switch(prop) {
package/src/serialize.mjs CHANGED
@@ -32,7 +32,7 @@ export default function serialize(value, options={}) {
32
32
  }
33
33
  }
34
34
  if (!resultArray) {
35
- resultArray = value[resultSet]
35
+ resultArray = value?.[resultSet]
36
36
  }
37
37
  if (!resultArray) {
38
38
  resultArray = []
@@ -159,7 +159,7 @@ export default function serialize(value, options={}) {
159
159
  return u8arr
160
160
  }
161
161
 
162
- if (!value[resultSet]) {
162
+ if (!value?.[resultSet]) {
163
163
  resultArray.push(value)
164
164
  }
165
165
  let currentSource = 0
@@ -167,7 +167,11 @@ export default function serialize(value, options={}) {
167
167
  let skipCount = 0
168
168
  let result = []
169
169
  while(currentSource<resultArray.length) {
170
- if (resultArray[currentSource][isChanged] || !resultArray[currentSource][isProxy]) {
170
+ if (!resultArray[currentSource]) {
171
+ //FIXME: should not happen, this means that there is no complete
172
+ //od-jsontag file, only patches?
173
+ skipCount++
174
+ } else if (resultArray[currentSource][isChanged] || !resultArray[currentSource][isProxy]) {
171
175
  if (skipCount) {
172
176
  result[currentResult] = encoder.encode('+'+skipCount)
173
177
  skipCount = 0
@@ -201,7 +205,9 @@ export default function serialize(value, options={}) {
201
205
  for (let line of arr) {
202
206
  length += line.length+1
203
207
  }
204
- length -= 1 // skip last newline
208
+ if (length) {
209
+ length -= 1 // skip last newline
210
+ }
205
211
  let sab = new SharedArrayBuffer(length)
206
212
  let u8arr = new Uint8Array(sab)
207
213
  let offset = 0