@live-change/dao 0.3.5 → 0.3.9

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/browser.js CHANGED
@@ -14,6 +14,10 @@ import ObservableList from "./lib/ObservableList.js"
14
14
  rd.ObservableList = ObservableList
15
15
  export { ObservableList }
16
16
 
17
+ import ExtendedObservableList from "./lib/ExtendedObservableList.js"
18
+ rd.ExtendedObservableList = ExtendedObservableList
19
+ export { ExtendedObservableList }
20
+
17
21
  import DaoPrerenderCache from "./lib/DaoPrerenderCache.js"
18
22
  const ReactiveCache = DaoPrerenderCache // backward compatibility
19
23
  rd.ReactiveCache = DaoPrerenderCache // backward compatibility
package/index.js CHANGED
@@ -11,6 +11,9 @@ Dao.ObservableValue = ObservableValue
11
11
  const ObservableList = require("./lib/ObservableList.js")
12
12
  Dao.ObservableList = ObservableList
13
13
 
14
+ const ExtendedObservableList = require("./lib/ExtendedObservableList.js")
15
+ Dao.ExtendedObservableList = ExtendedObservableList
16
+
14
17
  const ReactiveServer = require("./lib/ReactiveServer.js")
15
18
  Dao.ReactiveServer = ReactiveServer
16
19
 
@@ -6,12 +6,21 @@ class DaoPrerenderCache {
6
6
  constructor(dao, mode) {
7
7
  this.dao = dao
8
8
  this.cache = new Map()
9
+ this.extendedCache = new Map()
9
10
  this.mode = mode
10
11
  this.observables = new Map()
11
12
  }
12
-
13
+
13
14
  setCache(data) {
14
15
  this.cache = new Map(data)
16
+ for(const [keyJson, value] of data) {
17
+ const key = JSON.parse(keyJson)
18
+ if(key.paths) {
19
+ for(const { what, data } of value) {
20
+ this.extendedCache.set(JSON.stringify(what), data)
21
+ }
22
+ }
23
+ }
15
24
  for(const [what, observable] of this.observables.entries()) {
16
25
  if(observable.isDisposed()) {
17
26
  observable.set(this.cache.get(what))
@@ -35,7 +44,12 @@ class DaoPrerenderCache {
35
44
  observable = this.dao.observable(what)
36
45
  }
37
46
  this.observables.set(cacheKey, observable)
38
- if (this.cache.has(cacheKey)) observable.restore(this.cache.get(cacheKey))
47
+ if(this.cache.has(cacheKey)) observable.restore(this.cache.get(cacheKey))
48
+ if(this.extendedCache.has(cacheKey)) {
49
+ observable.restore(this.extendedCache.get(cacheKey))
50
+ return observable
51
+ // do not save extended values
52
+ }
39
53
  if(observable.isInitialized && observable.isInitialized()) {
40
54
  if(this.mode == 'save') {
41
55
  this.cache.set(cacheKey, observable.save())
@@ -43,34 +57,57 @@ class DaoPrerenderCache {
43
57
  return observable
44
58
  }
45
59
  if(this.mode == 'load') {
46
- //if (this.cache.has(cacheKey)) observable.restore(this.cache.get(cacheKey))
60
+ // if (this.cache.has(cacheKey)) observable.restore(this.cache.get(cacheKey))
61
+ // it was loaded earlier
47
62
  }
48
63
  return observable
49
64
  }
50
-
65
+
51
66
  get(what) {
52
67
  const cacheKey = JSON.stringify(what)
53
68
  debug("GET", cacheKey)
54
- if (this.cache.has(cacheKey)) {
69
+ if(this.cache.has(cacheKey)) {
55
70
  const value = this.cache.get(cacheKey)
56
71
  debug("GET FROM CACHE", cacheKey, " => ", value)
57
72
  return Promise.resolve(value)
58
73
  }
74
+ if(this.extendedCache.has(cacheKey)) {
75
+ const value = this.extendedCache.get(cacheKey)
76
+ debug("GET FROM EXTENDED CACHE", cacheKey, " => ", value)
77
+ return Promise.resolve(value)
78
+ }
59
79
  if(this.mode == 'load') {
60
80
  }
61
81
  const promise = this.dao.get(what)
62
82
  if(this.mode == 'save') {
63
83
  if(!promise) throw new Error("GET NOT FOUND: "+what)
64
- promise.then(result => {
84
+ promise.then(result => {
65
85
  let observable = this.observables.get(cacheKey)
66
86
  if(observable) {
67
- if(typeof observable == 'function') return observable('set', result)
68
- if(observable.notify) {
69
- return observable.notify('set', result)
87
+ if(typeof observable == 'function') {
88
+ observable('set', result)
89
+ } else if(observable.notify) {
90
+ observable.notify('set', result)
91
+ } else {
92
+ observable.set(result)
70
93
  }
71
- observable.set(result)
72
94
  }
73
95
  this.cache.set(cacheKey, result)
96
+ if(what.paths) {
97
+ for(const { what, data } of result) {
98
+ let observable = this.observables.get(cacheKey)
99
+ if(observable) {
100
+ if(typeof observable == 'function') {
101
+ observable('set', data)
102
+ } else if(observable.notify) {
103
+ observable.notify('set', data)
104
+ } else {
105
+ observable.set(data)
106
+ }
107
+ }
108
+ this.extendedCache.set(JSON.stringify(what), data)
109
+ }
110
+ }
74
111
  })
75
112
  }
76
113
  return promise
@@ -0,0 +1,225 @@
1
+ const ObservableList = require("./ObservableList.js")
2
+
3
+ class ExtendedObservableList extends ObservableList {
4
+ constructor(observableList, elementActivator, elementDispose, valueActivator = observableList.valueActivator) {
5
+ let list = observableList.list
6
+ if(elementActivator) {
7
+ list = Array.isArray(list) ? list.map(elementActivator) : elementActivator(list)
8
+ }
9
+ super(list, undefined, undefined, valueActivator)
10
+
11
+ this.observableList = observableList
12
+ this.elementActivator = elementActivator
13
+ this.elementDispose = elementDispose
14
+ this.valueActivator = valueActivator
15
+
16
+ this.savedError = null
17
+ this.properties = []
18
+ this.errorProperties = []
19
+
20
+ this.observableList.observe(this)
21
+ }
22
+
23
+ dispose() {
24
+ this.observableList.unobserve(this)
25
+ if(this.elementDispose) {
26
+ if(Array.isArray(this.list)) {
27
+ for(const disposed of this.list) this.elementDispose(disposed)
28
+ } else {
29
+ this.elementDispose(this.list)
30
+ }
31
+ this.list = undefined
32
+ }
33
+ ObservableList.dispose.apply(this)
34
+ }
35
+
36
+ respawn() {
37
+ ObservableList.respawn.apply(this)
38
+ this.observableList.observe(this)
39
+ }
40
+
41
+ extend(elementFunc, elementDispose) {
42
+ const extendedList = new ExtendedObservableList(
43
+ this.value, null, null, this.valueActivator, elementFunc, elementDispose)
44
+ const oldDispose = extendedList.dispose
45
+ const oldRespawn = extendedList.respawn
46
+
47
+ this.observe(extendedList)
48
+ extendedList.dispose = () => {
49
+ this.unobserve(extendedList)
50
+ oldDispose.apply(extendedList)
51
+ }
52
+ extendedList.respawn = () => {
53
+ oldRespawn.apply(extendedList)
54
+ this.observe(extendedList)
55
+ }
56
+ return extendedList
57
+ }
58
+
59
+ set(list) {
60
+ if(list === this.list) return;
61
+ try {
62
+ if (JSON.stringify(list) == JSON.stringify(this.list)) return;
63
+ } catch(e) {}
64
+ if(this.elementDispose) {
65
+ if(Array.isArray(this.list)) {
66
+ for(const disposed of this.list) this.elementDispose(disposed)
67
+ } else {
68
+ this.elementDispose(this.list)
69
+ }
70
+ }
71
+ if(this.elementActivator) {
72
+ list = Array.isArray(list) ? list.map(this.elementActivator) : this.elementActivator(list)
73
+ }
74
+ this.list = this.valueActivator ? this.valueActivator(list) : list
75
+ this.fireObservers('set', list)
76
+ for(const [object, property] of this.properties) {
77
+ object[property] = this.list
78
+ }
79
+ }
80
+
81
+ push(value) {
82
+ if(this.elementActivator) value = this.elementActivator(value)
83
+ this.list.push(value)
84
+ this.fireObservers('push', value)
85
+ }
86
+ unshift(value) {
87
+ if(this.elementActivator) value = this.elementActivator(value)
88
+ this.list.unshift(value)
89
+ this.fireObservers('unshift', value)
90
+ }
91
+ pop() {
92
+ if(this.elementDispose) this.elementDispose(this.list[this.list.length - 1])
93
+ this.list.pop()
94
+ this.fireObservers('pop')
95
+ }
96
+ shift() {
97
+ if(this.elementDispose) this.elementDispose(this.list[0])
98
+ this.list.shift()
99
+ this.fireObservers('shift')
100
+ }
101
+ splice(at, del, ...values) {
102
+ const removed = this.list.splice(at, del, ...values)
103
+ if(this.elementDispose) for(const disposed of removed) this.elementDispose(dispose)
104
+ this.fireObservers('splice', at, del, ...values)
105
+ }
106
+ putByField(field, value, element, reverse = false, oldElement) {
107
+ if(this.elementActivator) element = this.elementActivator(element)
108
+ if(!reverse) {
109
+ let i, l
110
+ for(i = 0, l = this.list.length; i < l; i++) {
111
+ if(this.list[i][field] == value) {
112
+ oldElement = this.list[i]
113
+ if(this.elementDispose) this.elementDispose(oldElement)
114
+ this.list.splice(i, 1, element)
115
+ break
116
+ } else if(this.list[i][field] > value) {
117
+ this.list.splice(i, 0, element)
118
+ break
119
+ }
120
+ }
121
+ if(i == l) this.list.push(element)
122
+ } else {
123
+ let i
124
+ for(i = this.list.length-1; i >= 0; i--) {
125
+ if(this.list[i][field] == value) {
126
+ oldElement = this.list[i]
127
+ if(this.elementDispose) this.elementDispose(oldElement)
128
+ this.list.splice(i, 1, element)
129
+ break
130
+ } else if(this.list[i][field] > value) {
131
+ this.list.splice(i + 1, 0, element)
132
+ break
133
+ }
134
+ }
135
+ if(i < 0) this.list.splice(0, 0, element)
136
+ }
137
+ this.fireObservers('putByField', field, value, element, reverse, oldElement)
138
+ }
139
+ remove(exact) {
140
+ let json = JSON.stringify(exact)
141
+ for(let i = 0, l = this.list.length; i < l; i++) {
142
+ if(JSON.stringify(this.list[i]) == json) {
143
+ if(this.elementDispose) this.elementDispose(this.list[i])
144
+ this.list.splice(i, 1)
145
+ }
146
+ }
147
+ this.fireObservers('remove', exact)
148
+ }
149
+ removeByField(field, value, oldElement) {
150
+ let json = JSON.stringify(value)
151
+ for(let i = 0, l = this.list.length; i < l; i++) {
152
+ if(JSON.stringify(this.list[i][field]) == json) {
153
+ oldElement = this.list[i]
154
+ if(this.elementDispose) this.elementDispose(oldElement)
155
+ this.list.splice(i, 1)
156
+ i--
157
+ l--
158
+ }
159
+ }
160
+ this.fireObservers('removeByField', field, value, oldElement)
161
+ }
162
+ removeBy(fields) {
163
+ let jsonf = []
164
+ for(var k in fields) {
165
+ jsonf.push([k, JSON.stringify(fields[k])])
166
+ }
167
+ for(let i = 0, l = this.list.length; i < l; i++) {
168
+ let found = true
169
+ for(let [key, json] of jsonf) {
170
+ found = found && (JSON.stringify(this.list[i][key]) == json)
171
+ }
172
+ if(found) {
173
+ if(this.elementDispose) this.elementDispose(this.list[i])
174
+ this.list.splice(i, 1)
175
+ i--
176
+ l--
177
+ }
178
+ }
179
+ this.fireObservers('removeBy', fields)
180
+ }
181
+
182
+ update(exact, element) {
183
+ let json = JSON.stringify(exact)
184
+ for(let i = 0, l = this.list.length; i < l; i++) {
185
+ if(JSON.stringify(this.list[i]) == json) {
186
+ if(this.elementDispose) this.elementDispose(this.list[i])
187
+ if(this.elementActivator) element = this.elementActivator(element)
188
+ this.list.splice(i, 1, element)
189
+ }
190
+ }
191
+ this.fireObservers('update', exact, element)
192
+ }
193
+ updateByField(field, value, element) {
194
+ let json = JSON.stringify(value)
195
+ for(let i = 0, l = this.list.length; i < l; i++) {
196
+ if(JSON.stringify(this.list[i][field]) == json) {
197
+ if(this.elementDispose) this.elementDispose(this.list[i])
198
+ if(this.elementActivator) element = this.elementActivator(element)
199
+ this.list.splice(i, 1, element)
200
+ }
201
+ }
202
+ this.fireObservers('updateByField', field, value, element)
203
+ }
204
+ updateBy(fields, element) {
205
+ let jsonf = []
206
+ for(const k in fields) {
207
+ jsonf.push([k, JSON.stringify(fields[k])])
208
+ }
209
+ for(let i = 0, l = this.list.length; i < l; i++) {
210
+ let found = true
211
+ for(let [key, json] of jsonf) {
212
+ found = found && (JSON.stringify(this.list[i][key]) == json)
213
+ }
214
+ if(found) {
215
+ if(this.elementDispose) this.elementDispose(this.list[i])
216
+ if(this.elementActivator) element = this.elementActivator(element)
217
+ this.list.splice(i, 1, element)
218
+ }
219
+ }
220
+ this.fireObservers('updateBy', fields, element)
221
+ }
222
+
223
+ }
224
+
225
+ module.exports = ExtendedObservableList
package/lib/Observable.js CHANGED
@@ -90,21 +90,22 @@ class Observable {
90
90
 
91
91
  wait() {
92
92
  let finished = false
93
- const resultObserver = (signal) => {
94
- finished = true
95
- this.unobserve(resultObserver)
96
- this.uncatch(errorObserver)
97
- resolve(signal)
98
- }
99
- const errorObserver = (error) => {
100
- finished = true
101
- this.unobserve(resultObserver)
102
- this.uncatch(errorObserver)
103
- reject(error)
104
- }
105
- const waitPromise = Promise((resolve, reject) => {
106
- if(!finished) this.observe(resultObserver)
93
+
94
+ const waitPromise = new Promise((resolve, reject) => {
95
+ const resultObserver = (signal) => {
96
+ finished = true
97
+ this.unobserve(resultObserver)
98
+ this.uncatch(errorObserver)
99
+ resolve(signal)
100
+ }
101
+ const errorObserver = (error) => {
102
+ finished = true
103
+ this.unobserve(resultObserver)
104
+ this.uncatch(errorObserver)
105
+ reject(error)
106
+ }
107
107
  if(!finished) this.catch(errorObserver)
108
+ if(!finished) this.observe(resultObserver)
108
109
  })
109
110
  waitPromise.cancel = () => {
110
111
  finished = true
@@ -15,6 +15,7 @@ class ObservableProxy extends Observable {
15
15
  }
16
16
 
17
17
  setTarget(observable) {
18
+ if(this === observable) throw new Error('infinite loop')
18
19
  if(!this.disposed && this.observable) {
19
20
  this.observable.unobserve(this.observer)
20
21
  for(let [object, property] of this.properties) {
@@ -80,8 +81,8 @@ class ObservableProxy extends Observable {
80
81
  unbindProperty(object, property) {
81
82
  for(var i = 0; i < this.properties.length; i++) {
82
83
  var prop = this.properties[i]
83
- if(prop[0] == object && prop[1] == property) {
84
- this.properties.splice(i,1)
84
+ if(prop[0] === object && prop[1] === property) {
85
+ this.properties.splice(i, 1)
85
86
  if(this.observable) this.observable.unbindProperty(object, property)
86
87
  if(this.isUseless()) this.dispose()
87
88
  return
package/lib/Path.js CHANGED
@@ -35,16 +35,16 @@ function resolve(schema) {
35
35
  }
36
36
 
37
37
  class Path {
38
- constructor(what, more = undefined) {
38
+ constructor(what, more = undefined, to = undefined) {
39
39
  this.what = what
40
40
  this.more = more
41
+ this.to = to
41
42
  }
42
43
  with(...funcs) {
43
44
  let newMore = this.more ? this.more.slice() : []
44
45
  for(const func of funcs) {
45
46
  const source = sourceProxy()
46
47
  const fetchObject = func(source)
47
- const what = fetchObject.what
48
48
  const path = fetchObject.what.slice(0, -1)
49
49
  const params = fetchObject.what[fetchObject.what.length - 1]
50
50
  let processedParams = {}
@@ -57,7 +57,8 @@ class Path {
57
57
  }
58
58
  const more = {
59
59
  schema: [[...path, { object: processedParams }]],
60
- more: fetchObject.more
60
+ more: fetchObject.more,
61
+ to: fetchObject.to
61
62
  }
62
63
  newMore.push(more)
63
64
  }
@@ -71,6 +72,10 @@ class Path {
71
72
  schema: resolve(outputObject)
72
73
  }
73
74
  }
75
+
76
+ bind(to) {
77
+ return new Path(this.what, this.more, to)
78
+ }
74
79
  }
75
80
 
76
81
  module.exports = Path
@@ -1,8 +1,14 @@
1
1
  function flatMap(source, fun) {
2
2
  let results = source.map(fun)
3
3
  let count = 0
4
- for(let result of results) count += result.length
4
+ let many = source.many
5
+ for(let result of results) {
6
+ count += result.length
7
+ many = many || result.many
8
+ }
9
+ if(count > 1 && !many) throw new Error("too many results from not many")
5
10
  let out = new Array(count)
11
+ out.many = many
6
12
  let p = 0
7
13
  for(let result of results) {
8
14
  for(let element of result) out[p++] = element
@@ -12,12 +18,12 @@ function flatMap(source, fun) {
12
18
 
13
19
  function getPropertyValues(source, property) {
14
20
  if(Array.isArray(source)) {
15
- return flatMap(source, v => getPropertyValues(v, property))
21
+ return flatMap(markMany(source), v => getPropertyValues(v, property))
16
22
  } else {
17
23
  if(source === undefined) return []
18
24
  if(source === null) return []
19
25
  let v = source[property]
20
- if(Array.isArray(v)) return v
26
+ if(Array.isArray(v)) return markMany(v)
21
27
  if(v === undefined) return []
22
28
  return [v]
23
29
  }
@@ -31,10 +37,22 @@ function getNestedPropertyValues(source, property) {
31
37
  return accumulator
32
38
  }
33
39
 
40
+ function markMany(arr) {
41
+ arr = arr.slice()
42
+ arr.many = true
43
+ return arr
44
+ }
45
+
34
46
  function cross(lists) {
35
47
  let count = 1
36
- for(let list of lists) count *= list.length
48
+ let many = false
49
+ for(let list of lists) {
50
+ count *= list.length
51
+ many = many || list.many
52
+ }
37
53
  let out = new Array(count)
54
+ out.many = many
55
+ if(count > 1 && !many) throw new Error("more than one result for non array fields")
38
56
  for(let i = 0; i < count; i++) {
39
57
  let res = new Array(lists.length)
40
58
  let a = i
@@ -68,10 +86,13 @@ function collect(source, schema, getSource) {
68
86
  return results
69
87
  })
70
88
  } else if(schema.nonEmpty) {
71
- return collect(source, schema.nonEmpty, getSource).filter(x=>!!x)
89
+ const collected = collect(source, schema.nonEmpty, getSource)
90
+ const result = collected.filter(x=>!!x)
91
+ result.many = collected.many
92
+ return result
72
93
  } else if(schema.identity) {
73
94
  if(typeof source == 'undefined' || source === null) return []
74
- return Array.isArray(source) ? source : [source]
95
+ return Array.isArray(source) ? markMany(source) : [source]
75
96
  } else if(schema.array) {
76
97
  return [ collect(source, schema.array, getSource) ]
77
98
  } else if(schema.property) {
@@ -112,6 +133,7 @@ function collect(source, schema, getSource) {
112
133
  }
113
134
  results[i] = result
114
135
  }
136
+ results.many = crossed.many
115
137
  return results
116
138
  }
117
139
  }
@@ -120,9 +142,12 @@ function collect(source, schema, getSource) {
120
142
  function collectPointers(source, schemas, getSource) {
121
143
  let results = []
122
144
  for(let schema of schemas) {
123
- results = results.concat(collect(source, schema, getSource))
145
+ const collected = collect(source, schema, getSource)
146
+ const many = results.many || collected.many
147
+ results = results.concat(collected)
148
+ results.many = many
124
149
  }
125
150
  return results
126
151
  }
127
152
 
128
- module.exports = collectPointers
153
+ module.exports = collectPointers
package/package.json CHANGED
@@ -36,5 +36,5 @@
36
36
  "scripts": {
37
37
  "test": "NODE_ENV=test blue-tape tests/*"
38
38
  },
39
- "version": "0.3.5"
39
+ "version": "0.3.9"
40
40
  }
@@ -5,43 +5,47 @@ test("pointers collector", (t) => {
5
5
  t.plan(14)
6
6
 
7
7
  t.test("simple property", (t) => {
8
- t.plan(1)
8
+ t.plan(2)
9
9
  let pointers = ReactiveDao.collectPointers({
10
10
  user: "123"
11
11
  },[
12
12
  ["users", "User", { property: "user" }]
13
13
  ])
14
- t.deepEqual(pointers, [["users","User","123"]], "found one user")
14
+ t.equal(!!pointers.many, false)
15
+ t.deepEqual(pointers.slice(), [["users","User","123"]], "found one user")
15
16
  })
16
17
 
17
18
  t.test("simple property from array", (t) => {
18
- t.plan(1)
19
+ t.plan(2)
19
20
  let pointers = ReactiveDao.collectPointers([
20
21
  { user: "123" },
21
22
  { user: "233" }
22
23
  ],[
23
24
  ["users", "User", { property: "user" }]
24
25
  ])
25
- t.deepEqual(pointers, [["users","User","123"], ["users","User","233"]], "found two users")
26
+ t.equal(!!pointers.many, true)
27
+ t.deepEqual(pointers.slice(), [["users","User","123"], ["users","User","233"]], "found two users")
26
28
  })
27
29
 
28
30
  t.test("identity pointers", (t) => {
29
- t.plan(1)
31
+ t.plan(2)
30
32
  let pointers = ReactiveDao.collectPointers([ 0, 1, 2, 3 ], [
31
33
  [ 'test', 'user', { identity: true } ]
32
34
  ])
33
- t.deepEqual(pointers, [ [ 'test', 'user', 0 ], [ 'test', 'user', 1 ], [ 'test', 'user', 2 ],
35
+ t.equal(!!pointers.many, true)
36
+ t.deepEqual(pointers.slice(), [ [ 'test', 'user', 0 ], [ 'test', 'user', 1 ], [ 'test', 'user', 2 ],
34
37
  [ 'test', 'user', 3 ] ])
35
38
  })
36
39
 
37
40
  t.test("array property tags", (t) => {
38
- t.plan(1)
41
+ t.plan(2)
39
42
  let pointers = ReactiveDao.collectPointers({
40
43
  tags: ["1", "2", "3"]
41
44
  },[
42
45
  ["tags", "Tag", { property: "tags" }]
43
46
  ])
44
- t.deepEqual(pointers, [
47
+ t.equal(!!pointers.many, true)
48
+ t.deepEqual(pointers.slice(), [
45
49
  ["tags","Tag","1"],
46
50
  ["tags","Tag","2"],
47
51
  ["tags","Tag","3"]
@@ -49,7 +53,7 @@ test("pointers collector", (t) => {
49
53
  })
50
54
 
51
55
  t.test("nested property", (t) => {
52
- t.plan(1)
56
+ t.plan(2)
53
57
  let pointers = ReactiveDao.collectPointers({
54
58
  userData: {
55
59
  country: "PL"
@@ -57,7 +61,8 @@ test("pointers collector", (t) => {
57
61
  },[
58
62
  ["country", { property: ["userData", "country"] }]
59
63
  ])
60
- t.deepEqual(pointers, [["country","PL"]], "found nested property value")
64
+ t.equal(!!pointers.many, false)
65
+ t.deepEqual(pointers.slice(), [["country","PL"]], "found nested property value")
61
66
  })
62
67
 
63
68
  t.test("object result", (t) => {
@@ -72,7 +77,7 @@ test("pointers collector", (t) => {
72
77
  } },
73
78
  { object: { path: ["tags", { property: "tags" }] } }
74
79
  ])
75
- t.deepEqual(pointers, [
80
+ t.deepEqual(pointers.slice(), [
76
81
  { path: ["user", { user: "123" }], next: [[ "picture", { property: "picture" } ]] },
77
82
  { path: ["tags","1"] },
78
83
  { path: ["tags","2"] },
@@ -91,7 +96,7 @@ test("pointers collector", (t) => {
91
96
  { source: 'interests', schema: { array: { identity: true } }},
92
97
  { source: { static: 'city' }, schema: { property: "name" } }]
93
98
  ], (src) => sources[src])
94
- t.deepEqual(pointers, [ [ 'findProjects', [ 'cats', 'dogs', 'birds' ], 'NY' ] ])
99
+ t.deepEqual(JSON.parse(JSON.stringify(pointers)), [ [ 'findProjects', [ 'cats', 'dogs', 'birds' ], 'NY' ] ])
95
100
  })
96
101
 
97
102
  t.test("undefined argument", (t) => {
@@ -99,7 +104,7 @@ test("pointers collector", (t) => {
99
104
  let pointers = ReactiveDao.collectPointers({ sessionId: 1 },[
100
105
  ["users", "User", { property: "user" }]
101
106
  ])
102
- t.deepEqual(pointers, [])
107
+ t.deepEqual(pointers.slice(), [])
103
108
  })
104
109
 
105
110
  t.test("undefined argument in object", (t) => {
@@ -107,7 +112,7 @@ test("pointers collector", (t) => {
107
112
  let pointers = ReactiveDao.collectPointers({ sessionId: 1 },[
108
113
  ["users", "User", { object: { user: { property: "user" }}}]
109
114
  ])
110
- t.deepEqual(pointers, [])
115
+ t.deepEqual(pointers.slice(), [])
111
116
  })
112
117
 
113
118
  t.test("switch match", (t) => {
@@ -120,7 +125,7 @@ test("pointers collector", (t) => {
120
125
  US: "New York"
121
126
  }}]
122
127
  ])
123
- t.deepEqual(pointers, [["Warsaw"]], "switch working")
128
+ t.deepEqual(pointers.slice(), [["Warsaw"]], "switch working")
124
129
  })
125
130
 
126
131
  t.test("switch default", (t) => {
@@ -134,7 +139,7 @@ test("pointers collector", (t) => {
134
139
  },
135
140
  default: "London"}]
136
141
  ])
137
- t.deepEqual(pointers, [["London"]], "switch working")
142
+ t.deepEqual(pointers.slice(), [["London"]], "switch working")
138
143
  })
139
144
 
140
145
  t.test("switch not match", (t) => {
@@ -147,7 +152,7 @@ test("pointers collector", (t) => {
147
152
  US: "New York"
148
153
  }}]
149
154
  ])
150
- t.deepEqual(pointers, [], "switch working")
155
+ t.deepEqual(pointers.slice(), [], "switch working")
151
156
  })
152
157
 
153
158
  t.test("test nonEmpty", (t) => {
@@ -157,7 +162,7 @@ test("pointers collector", (t) => {
157
162
  },[
158
163
  ["users", "User", { nonEmpty: { property: "user" }}]
159
164
  ])
160
- t.deepEqual(pointers, [], "nulls are filtered")
165
+ t.deepEqual(pointers.slice(), [], "nulls are filtered")
161
166
  })
162
167
 
163
168
  t.test("test complex property fetch", (t) => {
@@ -187,7 +192,7 @@ test("pointers collector", (t) => {
187
192
  category: { nonEmpty: { property: ['data', 'sidebarItems','category'] } }
188
193
  } }]
189
194
  ])
190
- t.deepEqual(pointers, [
195
+ t.deepEqual(pointers.slice(), [
191
196
  [
192
197
  "categories",
193
198
  "CategoryOne",