@live-change/dao 0.9.84 → 0.9.86
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/index.js +3 -0
- package/lib/DaoPrerenderCache.js +18 -6
- package/lib/ReactiveConnection.js +19 -4
- package/lib/collectPointers.js +79 -66
- package/package.json +2 -2
package/index.js
CHANGED
package/lib/DaoPrerenderCache.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import Debug from 'debug'
|
|
2
2
|
const debug = Debug('reactive-dao:cache')
|
|
3
3
|
import ObservableValue from "./ObservableValue.js"
|
|
4
|
+
import { sourceSymbol } from "./ReactiveConnection.js"
|
|
4
5
|
|
|
5
6
|
class DaoPrerenderCache {
|
|
6
7
|
|
|
@@ -22,9 +23,12 @@ class DaoPrerenderCache {
|
|
|
22
23
|
}
|
|
23
24
|
}
|
|
24
25
|
}
|
|
25
|
-
for(const [
|
|
26
|
+
for(const [cacheKey, observable] of this.observables.entries()) {
|
|
26
27
|
if(observable.isDisposed()) {
|
|
27
|
-
observable.set(this.cache.get(
|
|
28
|
+
observable.set(this.cache.get(cacheKey))
|
|
29
|
+
if(this.extendedCache.has(cacheKey)) {
|
|
30
|
+
observable.restore(this.extendedCache.get(cacheKey))
|
|
31
|
+
}
|
|
28
32
|
}
|
|
29
33
|
}
|
|
30
34
|
this.observables.clear()
|
|
@@ -40,14 +44,19 @@ class DaoPrerenderCache {
|
|
|
40
44
|
}
|
|
41
45
|
if(this.mode === 'save') {
|
|
42
46
|
observable = new ObservableValue()
|
|
43
|
-
this.get(what).then(value =>
|
|
47
|
+
this.get(what).then(value => {
|
|
48
|
+
if(value && typeof value === 'object') value[sourceSymbol] = what
|
|
49
|
+
observable.set(value)
|
|
50
|
+
}).catch(error => observable.error(error))
|
|
44
51
|
} else {
|
|
45
52
|
observable = this.dao.observable(what)
|
|
46
53
|
}
|
|
47
54
|
this.observables.set(cacheKey, observable)
|
|
48
55
|
if(this.cache.has(cacheKey)) observable.restore(this.cache.get(cacheKey))
|
|
49
56
|
if(this.extendedCache.has(cacheKey)) {
|
|
50
|
-
|
|
57
|
+
const data = this.extendedCache.get(cacheKey)
|
|
58
|
+
if(data && typeof data === 'object') data[sourceSymbol] = what
|
|
59
|
+
observable.restore(data)
|
|
51
60
|
return observable
|
|
52
61
|
// do not save extended values
|
|
53
62
|
}
|
|
@@ -112,8 +121,11 @@ class DaoPrerenderCache {
|
|
|
112
121
|
}
|
|
113
122
|
})
|
|
114
123
|
}
|
|
115
|
-
|
|
116
|
-
return promise
|
|
124
|
+
|
|
125
|
+
return promise.then(data => {
|
|
126
|
+
if(data && typeof data === 'object') data[sourceSymbol] = what
|
|
127
|
+
return data
|
|
128
|
+
})
|
|
117
129
|
}
|
|
118
130
|
|
|
119
131
|
set(what, value) {
|
|
@@ -5,6 +5,8 @@ import * as utils from './utils.js'
|
|
|
5
5
|
|
|
6
6
|
let lastUid = 0
|
|
7
7
|
|
|
8
|
+
export const sourceSymbol = Symbol("source")
|
|
9
|
+
|
|
8
10
|
class Observation {
|
|
9
11
|
constructor(connection, what, pushed) {
|
|
10
12
|
this.what = what
|
|
@@ -23,10 +25,15 @@ class Observation {
|
|
|
23
25
|
this.connection.sendObserve(this)
|
|
24
26
|
}
|
|
25
27
|
//process.nextTick(() => { // next tick will replay events through all layer to the client - it's waste of resources
|
|
26
|
-
for(let { signal, args} of this.receivedSignals) {
|
|
28
|
+
for(let { signal, args } of this.receivedSignals) {
|
|
29
|
+
if(signal === "set" && args[0] && typeof args[0] === 'object') args[0][sourceSymbol] = this.what
|
|
27
30
|
if(typeof observable == 'function') observable(signal, ...args)
|
|
28
31
|
else if(observable.notify) observable.notify(signal, ...args)
|
|
29
32
|
else observable[signal](...args)
|
|
33
|
+
if(signal === "set" && observable.getValue) {
|
|
34
|
+
const value = observable.getValue()
|
|
35
|
+
if(value && typeof value === 'object') value[sourceSymbol] = this.what
|
|
36
|
+
}
|
|
30
37
|
}
|
|
31
38
|
//})
|
|
32
39
|
}
|
|
@@ -93,12 +100,17 @@ class Observation {
|
|
|
93
100
|
}
|
|
94
101
|
handleNotifyMessage({ signal, args }) {
|
|
95
102
|
if(this.disposed) return
|
|
103
|
+
if(signal === "set" && args[0] && typeof args[0] === 'object') args[0][sourceSymbol] = this.what
|
|
96
104
|
this.receivedSignals.push({ signal, args })
|
|
97
105
|
for(let observable of this.observables) {
|
|
98
|
-
utils.nextTick(
|
|
106
|
+
utils.nextTick(() => {
|
|
99
107
|
if(typeof observable == 'function') observable(signal, ...args)
|
|
100
108
|
else if(observable.notify) observable.notify(signal, ...args)
|
|
101
|
-
else observable[signal](...args)
|
|
109
|
+
else observable[signal](...args)
|
|
110
|
+
if(signal === "set" && observable.getValue) {
|
|
111
|
+
const value = observable.getValue()
|
|
112
|
+
if(value && typeof value === 'object') value[sourceSymbol] = this.what
|
|
113
|
+
}
|
|
102
114
|
})
|
|
103
115
|
}
|
|
104
116
|
}
|
|
@@ -228,7 +240,10 @@ class Connection extends EventEmitter {
|
|
|
228
240
|
type: 'get',
|
|
229
241
|
what: what
|
|
230
242
|
}
|
|
231
|
-
return this.sendRequest(msg)
|
|
243
|
+
return this.sendRequest(msg).then(data => {
|
|
244
|
+
if(data && typeof data === 'object') data[sourceSymbol] = what
|
|
245
|
+
return data
|
|
246
|
+
})
|
|
232
247
|
}
|
|
233
248
|
getMore(what, more) {
|
|
234
249
|
const msg={
|
package/lib/collectPointers.js
CHANGED
|
@@ -16,9 +16,10 @@ function flatMap(source, fun) {
|
|
|
16
16
|
return out
|
|
17
17
|
}
|
|
18
18
|
|
|
19
|
-
function getPropertyValues(source, property) {
|
|
19
|
+
function getPropertyValues(source, property) {
|
|
20
20
|
if(Array.isArray(source)) {
|
|
21
|
-
|
|
21
|
+
const values = flatMap(markMany(source), v => getPropertyValues(v, property))
|
|
22
|
+
return values
|
|
22
23
|
} else {
|
|
23
24
|
if(source === undefined) return []
|
|
24
25
|
if(source === null) return []
|
|
@@ -52,7 +53,10 @@ function cross(lists) {
|
|
|
52
53
|
}
|
|
53
54
|
let out = new Array(count)
|
|
54
55
|
out.many = many
|
|
55
|
-
if(count > 1 && !many)
|
|
56
|
+
if(count > 1 && !many) {
|
|
57
|
+
console.log("ERROR WHEN CROSSING", lists.map(l => JSON.stringify(l, null, 2)+' many:'+(!!l.many)).join('\n'))
|
|
58
|
+
throw new Error("more than one result for non array fields")
|
|
59
|
+
}
|
|
56
60
|
for(let i = 0; i < count; i++) {
|
|
57
61
|
let res = new Array(lists.length)
|
|
58
62
|
let a = i
|
|
@@ -67,75 +71,84 @@ function cross(lists) {
|
|
|
67
71
|
}
|
|
68
72
|
|
|
69
73
|
function collect(source, schema, getSource) {
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
return cross(partValues)
|
|
80
|
-
} else {
|
|
81
|
-
if(schema.source) {
|
|
82
|
-
const sourcePointers = collect(source, schema.source, getSource)
|
|
83
|
-
return flatMap( sourcePointers, ptr => {
|
|
84
|
-
const source = getSource(ptr)
|
|
85
|
-
const results = collect(source, schema.schema, getSource)
|
|
86
|
-
return results
|
|
87
|
-
})
|
|
88
|
-
} else if(schema.nonEmpty) {
|
|
89
|
-
const collected = collect(source, schema.nonEmpty, getSource)
|
|
90
|
-
const result = collected.filter(x=>!!x)
|
|
91
|
-
result.many = collected.many
|
|
92
|
-
return result
|
|
93
|
-
} else if(schema.identity) {
|
|
94
|
-
if(typeof source == 'undefined' || source === null) return []
|
|
95
|
-
return Array.isArray(source) ? markMany(source) : [source]
|
|
96
|
-
} else if(schema.array) {
|
|
97
|
-
return [ collect(source, schema.array, getSource) ]
|
|
98
|
-
} else if(schema.property) {
|
|
99
|
-
if(typeof source == 'undefined' || source === null) return []
|
|
100
|
-
if(Array.isArray(schema.property)) {
|
|
101
|
-
let values = getNestedPropertyValues(source, schema.property)
|
|
102
|
-
return values
|
|
103
|
-
} else {
|
|
104
|
-
let values = getPropertyValues(source, schema.property)
|
|
105
|
-
return values
|
|
74
|
+
try {
|
|
75
|
+
if(typeof schema == 'string') {
|
|
76
|
+
return [schema]
|
|
77
|
+
} else if(typeof schema != 'object') {
|
|
78
|
+
return [schema]
|
|
79
|
+
} else if(Array.isArray(schema)) {
|
|
80
|
+
let partValues = new Array(schema.length)
|
|
81
|
+
for(let i = 0; i < schema.length; i++) {
|
|
82
|
+
partValues[i] = collect(source, schema[i], getSource)
|
|
106
83
|
}
|
|
107
|
-
|
|
108
|
-
const values = collect(source, schema.value, getSource)
|
|
109
|
-
return flatMap(values, v => {
|
|
110
|
-
const found = schema.switch[v]
|
|
111
|
-
if(found) return collect(source, found, getSource)
|
|
112
|
-
if(schema.default) return collect(source, schema.default, getSource)
|
|
113
|
-
return []
|
|
114
|
-
})
|
|
115
|
-
} else if(schema.static) {
|
|
116
|
-
return [schema.static]
|
|
84
|
+
return cross(partValues)
|
|
117
85
|
} else {
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
86
|
+
if(schema.source) {
|
|
87
|
+
const sourcePointers = collect(source, schema.source, getSource)
|
|
88
|
+
return flatMap( sourcePointers, ptr => {
|
|
89
|
+
const source = getSource(ptr)
|
|
90
|
+
const results = collect(source, schema.schema, getSource)
|
|
91
|
+
return results
|
|
92
|
+
})
|
|
93
|
+
} else if(schema.nonEmpty) {
|
|
94
|
+
const collected = collect(source, schema.nonEmpty, getSource)
|
|
95
|
+
const result = collected.filter(x=>!!x)
|
|
96
|
+
result.many = collected.many
|
|
97
|
+
return result
|
|
98
|
+
} else if(schema.identity) {
|
|
99
|
+
if(typeof source == 'undefined' || source === null) return []
|
|
100
|
+
return Array.isArray(source) ? markMany(source) : [source]
|
|
101
|
+
} else if(schema.array) {
|
|
102
|
+
return [ collect(source, schema.array, getSource) ]
|
|
103
|
+
} else if(schema.property) {
|
|
104
|
+
if(typeof source == 'undefined' || source === null) return []
|
|
105
|
+
if(Array.isArray(schema.property)) {
|
|
106
|
+
let values = getNestedPropertyValues(source, schema.property)
|
|
107
|
+
return values
|
|
108
|
+
} else {
|
|
109
|
+
let values = getPropertyValues(source, schema.property)
|
|
110
|
+
return values
|
|
111
|
+
}
|
|
112
|
+
} else if(schema.switch) {
|
|
113
|
+
const values = collect(source, schema.value, getSource)
|
|
114
|
+
return flatMap(values, v => {
|
|
115
|
+
const found = schema.switch[v]
|
|
116
|
+
if(found) return collect(source, found, getSource)
|
|
117
|
+
if(schema.default) return collect(source, schema.default, getSource)
|
|
118
|
+
return []
|
|
119
|
+
})
|
|
120
|
+
} else if(schema.static) {
|
|
121
|
+
return [schema.static]
|
|
122
|
+
} else if(schema.or) {
|
|
123
|
+
const resultsFromOr = schema.or.map(orSchema => collect(source, orSchema, getSource))
|
|
124
|
+
return resultsFromOr.find(r => r.length > 0) || []
|
|
125
|
+
} else {
|
|
126
|
+
let objectSchema = schema.object ? schema.object : schema
|
|
127
|
+
let propValues = []
|
|
128
|
+
let propId = 0
|
|
131
129
|
for(let key in objectSchema) {
|
|
132
|
-
|
|
130
|
+
let values = collect(source, objectSchema[key], getSource)
|
|
131
|
+
propValues[propId] = values.filter(Boolean)
|
|
132
|
+
propValues[propId].many = values.many
|
|
133
|
+
propId++
|
|
134
|
+
}
|
|
135
|
+
let crossed = cross(propValues)
|
|
136
|
+
let results = new Array(crossed.length)
|
|
137
|
+
for(let i = 0; i < crossed.length; i++) {
|
|
138
|
+
let result = {}
|
|
139
|
+
let j = 0
|
|
140
|
+
for(let key in objectSchema) {
|
|
141
|
+
result[key] = crossed[i][j++]
|
|
142
|
+
}
|
|
143
|
+
results[i] = result
|
|
133
144
|
}
|
|
134
|
-
results
|
|
145
|
+
results.many = crossed.many
|
|
146
|
+
return results
|
|
135
147
|
}
|
|
136
|
-
results.many = crossed.many
|
|
137
|
-
return results
|
|
138
148
|
}
|
|
149
|
+
} catch(e) {
|
|
150
|
+
console.log("ERROR WHEN COLLECTING", source, JSON.stringify(schema, null, 2), e)
|
|
151
|
+
throw e
|
|
139
152
|
}
|
|
140
153
|
}
|
|
141
154
|
|
package/package.json
CHANGED