@live-change/dao 0.3.10 → 0.3.14

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/lib/DaoCache.js CHANGED
@@ -30,14 +30,17 @@ class CacheState {
30
30
 
31
31
  turnOff() {
32
32
  if(!this.cached) throw new Error("uncache of not cached")
33
+ if(!this.observable) throw new Error("race condition")
33
34
  this.cached = false
34
35
  this.cache.cachedCount --
35
- this.observable.unobserve(this.cache.dummyObserver)
36
+ const observable = this.observable
36
37
  this.observable = null
38
+ observable.unobserve(this.cache.dummyObserver)
37
39
  }
38
40
 
39
41
  turnOn() {
40
42
  if(this.cached) throw new Error("already cached")
43
+ if(this.observable) throw new Error("race condition")
41
44
  this.cached = true
42
45
  this.cache.cachedCount ++
43
46
  this.cache.cache.push(this)
@@ -81,7 +84,7 @@ class CacheState {
81
84
  if(delta > 0) {
82
85
  this.score += delta * this.settings.singleReadScore
83
86
  }
84
- this.updateCacheState()
87
+ setTimeout(() => this.updateCacheState(), 0)
85
88
  }
86
89
  }
87
90
 
@@ -133,6 +136,15 @@ class DaoCache extends EventEmitter {
133
136
  this.dummyObserver = () => 0
134
137
  }
135
138
 
139
+ clear() {
140
+ const now = Date.now()
141
+ for(const cacheState of this.cache) {
142
+ cacheState.score = 0
143
+ cacheState.scoreTime = now
144
+ if(cacheState.cached) cacheState.turnOff()
145
+ }
146
+ this.cache = []
147
+ }
136
148
 
137
149
  clean() {
138
150
  //console.log("CACHE STATE:", this.cacheState)
@@ -184,8 +196,9 @@ class DaoCache extends EventEmitter {
184
196
 
185
197
  noticeObserverCount(what, count, delta) {
186
198
  //console.log("OBSERVER COUNT", JSON.stringify(what), count, "D", delta)
187
- const cacheState = this.getOrCreateCacheState(what)
188
- if(!cacheState) return
199
+ let cacheState = this.getOrCreateCacheState(what)
200
+ if(!cacheState && delta <= 0) return
201
+ cacheState = this.getOrCreateCacheState(what)
189
202
  if(delta > 0) {
190
203
  //console.log("CACHE TEST", cacheState.cached)
191
204
  if(cacheState.observable) {
@@ -253,6 +266,7 @@ class DaoCache extends EventEmitter {
253
266
  }
254
267
 
255
268
  dispose() {
269
+ clear()
256
270
  clearInterval(this.interval)
257
271
  this.dao.dispose()
258
272
  }
package/lib/DaoProxy.js CHANGED
@@ -20,9 +20,11 @@ class DaoProxy extends EventEmitter {
20
20
  this.dao = dao
21
21
  if(this.dao) {
22
22
  for(let [id, observable] of this.observables.entries()) {
23
- let what = JSON.parse(id)
24
- const target = this.dao.observable(what)
25
- observable.setTarget(target)
23
+ if(!observable.disposed) {
24
+ let what = JSON.parse(id)
25
+ const target = this.dao.observable(what)
26
+ observable.setTarget(target)
27
+ }
26
28
  }
27
29
  if(this.dao.on) {
28
30
  this.dao.on('connect', this.onConnect)
@@ -45,11 +47,23 @@ class DaoProxy extends EventEmitter {
45
47
  } else {
46
48
  observable = new ObservableProxy()
47
49
  }
48
- /*const oldDispose = observable.dispose
50
+ const oldDispose = observable.dispose
49
51
  observable.dispose = (...args) => {
50
- //this.observables.delete(spath)
52
+ this.observables.delete(spath)
51
53
  oldDispose.call(observable, ...args)
52
- }*/
54
+ }
55
+ const oldRespawn = observable.respawn
56
+ observable.respawn = (...args) => {
57
+ const newObservable = this.observables.get(spath)
58
+ if(newObservable && newObservable !== observable) {
59
+ observable.observable = newObservable
60
+ } else if(this.dao) {
61
+ observable.observable = this.dao.observable(what)
62
+ } else {
63
+ observable.observable = null
64
+ }
65
+ oldRespawn.call(observable, ...args)
66
+ }
53
67
  this.observables.set(JSON.stringify(what), observable)
54
68
  return observable
55
69
  }
@@ -30,11 +30,11 @@ class ExtendedObservableList extends ObservableList {
30
30
  }
31
31
  this.list = undefined
32
32
  }
33
- ObservableList.dispose.apply(this)
33
+ super.dispose.apply(this)
34
34
  }
35
35
 
36
36
  respawn() {
37
- ObservableList.respawn.apply(this)
37
+ super.respawn.apply(this)
38
38
  this.observableList.observe(this)
39
39
  }
40
40
 
@@ -176,7 +176,7 @@ class ObservableList extends Observable {
176
176
  this.errorProperties.splice(i, 1)
177
177
  i--
178
178
  if(this.isUseless()) this.dispose()
179
- return;
179
+ return
180
180
  }
181
181
  }
182
182
  throw new Error("cannot unbind not bound property "+property)
@@ -282,6 +282,9 @@ class ObservableList extends Observable {
282
282
  getValue() {
283
283
  return this.list
284
284
  }
285
+ getError() {
286
+ return this.savedError
287
+ }
285
288
  }
286
289
 
287
290
  module.exports = ObservableList
@@ -10,7 +10,8 @@ class ObservablePromiseProxy extends Observable {
10
10
  this.observer = (signal, ...args) => {
11
11
  this.fireObservers(signal, ...args)
12
12
  }
13
- promise.then((result) => {
13
+ this.promise = promise
14
+ this.promise.then((result) => {
14
15
  if(result.observe) {
15
16
  this.init(result)
16
17
  } else {
@@ -51,7 +52,9 @@ class ObservablePromiseProxy extends Observable {
51
52
  }
52
53
  }
53
54
  getValue() {
54
- return promise.then(r => r.getValue())
55
+ if(!this.observable) return undefined
56
+ if(!this.observable.getValue) return undefined
57
+ return this.observable.getValue()
55
58
  }
56
59
  }
57
60
 
@@ -17,6 +17,7 @@ class ObservableProxy extends Observable {
17
17
  setTarget(observable) {
18
18
  if(this === observable) throw new Error('infinite loop')
19
19
  if(!this.disposed && this.observable) {
20
+ //console.log("SET TARGET UNOBSERVE TARGET")
20
21
  this.observable.unobserve(this.observer)
21
22
  for(let [object, property] of this.properties) {
22
23
  this.observable.unbindProperty(object, property)
@@ -27,6 +28,7 @@ class ObservableProxy extends Observable {
27
28
  }
28
29
  this.observable = observable
29
30
  if(!this.disposed && this.observable) {
31
+ //console.log("SET TARGET OBSERVE TARGET")
30
32
  this.observable.observe(this.observer)
31
33
  for(let [object, property] of this.properties) {
32
34
  this.observable.bindProperty(object, property)
@@ -51,6 +53,7 @@ class ObservableProxy extends Observable {
51
53
 
52
54
  reobserveTarget() {
53
55
  if(!this.disposed && this.observable) {
56
+ //console.log("REOBSERVE TARGET!", this.observable)
54
57
  this.observable.unobserve(this.observer)
55
58
  this.observable.observe(this.observer)
56
59
  }
@@ -64,13 +67,27 @@ class ObservableProxy extends Observable {
64
67
  catch(...args) {
65
68
  let beenDisposed = this.disposed
66
69
  Observable.prototype.catch.apply(this, args)
67
- if(!beenDisposed) this.reobserveTarget()
70
+ if(!beenDisposed) {
71
+ if(this.observable.getError) {
72
+ const error = this.observable.getError()
73
+ if(error) this.fireObserver(args[0], 'error', error)
74
+ } else {
75
+ this.reobserveTarget()
76
+ }
77
+ }
68
78
  }
69
79
 
70
80
  observe(...args) {
71
81
  let beenDisposed = this.disposed
72
82
  Observable.prototype.observe.apply(this, args)
73
- if(!beenDisposed) this.reobserveTarget()
83
+ if(!beenDisposed) {
84
+ if(this.observable.getValue) {
85
+ const value = this.observable.getValue()
86
+ if(value !== undefined) this.fireObserver(args[0], 'set', value)
87
+ } else {
88
+ this.reobserveTarget()
89
+ }
90
+ }
74
91
  }
75
92
 
76
93
  bindProperty(object, property) {
@@ -160,6 +160,10 @@ class ObservableValue extends Observable {
160
160
  getValue() {
161
161
  return this.value
162
162
  }
163
+
164
+ getError() {
165
+ return this.savedError
166
+ }
163
167
  }
164
168
 
165
169
  module.exports = ObservableValue
@@ -389,8 +389,7 @@ class ReactiveServerConnection extends EventEmitter {
389
389
 
390
390
  if(this.settings.fastAuth) {
391
391
  try {
392
- this.credentials = {}
393
- this.daoPromise = this.daoFactory(this.credentials, this.connection, this)
392
+ this.handleDaoPromise(this.daoFactory(this.credentials, this.connection, this))
394
393
  } catch(error) {
395
394
  return this.handleDaoFactoryError(error)
396
395
  }
@@ -515,9 +514,11 @@ class ReactiveServerConnection extends EventEmitter {
515
514
  handleUnobserve(message) {
516
515
  const path = message.what
517
516
  const spath = JSON.stringify(path)
518
- //debug('handle unobserve', spath)
517
+ debug('handle unobserve', spath)
519
518
  const observation = this.observations.get(spath)
520
- if(!observation) throw new Error("Unobserve of not observed "+spath)
519
+ if(!observation) {
520
+ throw new Error("Unobserve of not observed "+spath)
521
+ }
521
522
  observation.unobserve(message.pushed)
522
523
  }
523
524
 
@@ -696,6 +697,21 @@ class ReactiveServerConnection extends EventEmitter {
696
697
  this.closeConnection()
697
698
  }
698
699
 
700
+ handleDaoPromise(daoPromise) {
701
+ this.daoPromise = daoPromise
702
+ if(!this.daoPromise.then) {
703
+ this.dao = this.daoPromise
704
+ this.daoPromise = null
705
+ } else {
706
+ this.daoPromise.catch(error => this.handleDaoFactoryError(error)).then(dd => {
707
+ if(!dd) return this.handleDaoFactoryError("dao not defined")
708
+ this.dao = dd
709
+ this.daoPromise = null
710
+ for(const message of this.daoGenerationQueue) this.handleAuthorizedMessage(message)
711
+ })
712
+ }
713
+ }
714
+
699
715
  handleMessage(message) {
700
716
  if (!this.dao && !this.daoPromise) {
701
717
  if (!message) {
@@ -704,21 +720,10 @@ class ReactiveServerConnection extends EventEmitter {
704
720
  }
705
721
  try {
706
722
  this.credentials = message
707
- this.daoPromise = this.daoFactory(this.credentials, this.connection, this)
723
+ this.handleDaoPromise(this.daoFactory(this.credentials, this.connection, this))
708
724
  } catch(error) {
709
725
  return this.handleDaoFactoryError(error)
710
726
  }
711
- if(!this.daoPromise.then) {
712
- this.dao = this.daoPromise
713
- this.daoPromise = null
714
- } else {
715
- this.daoPromise.catch(error => this.handleDaoFactoryError(error)).then(dd => {
716
- if(!dd) return this.handleDaoFactoryError("dao not defined")
717
- this.dao = dd
718
- this.daoPromise = null
719
- for(const message of this.daoGenerationQueue) this.handleAuthorizedMessage(message)
720
- })
721
- }
722
727
  } else if(this.daoPromise && !this.dao) {
723
728
  this.daoGenerationQueue.push(message)
724
729
  } else {
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.10"
39
+ "version": "0.3.14"
40
40
  }