@live-change/dao-vue3 0.4.10 → 0.4.13
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 +2 -2
- package/lib/live.js +201 -174
- package/package.json +3 -3
package/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import reactiveMixin from './lib/reactiveMixin.js'
|
|
2
2
|
import reactivePrefetchMixin from './lib/reactivePrefetchMixin.js'
|
|
3
|
-
import live from './lib/live.js'
|
|
3
|
+
import { live, fetch } from './lib/live.js'
|
|
4
4
|
import ReactiveObservableList from './lib/ReactiveObservableList.js'
|
|
5
5
|
import RangeBuckets from './lib/RangeBuckets.js'
|
|
6
6
|
|
|
@@ -14,6 +14,6 @@ const ReactiveDaoVue = {
|
|
|
14
14
|
}
|
|
15
15
|
|
|
16
16
|
//// TODO: rename reactive to live
|
|
17
|
-
export { ReactiveDaoVue, reactiveMixin, reactivePrefetchMixin, ReactiveObservableList, RangeBuckets, live }
|
|
17
|
+
export { ReactiveDaoVue, reactiveMixin, reactivePrefetchMixin, ReactiveObservableList, RangeBuckets, live, fetch }
|
|
18
18
|
|
|
19
19
|
export default ReactiveDaoVue
|
package/lib/live.js
CHANGED
|
@@ -6,6 +6,74 @@ debug.log = console.log.bind(console)
|
|
|
6
6
|
|
|
7
7
|
const liveSymbol = Symbol('live')
|
|
8
8
|
|
|
9
|
+
function createActionFunction(action, object) {
|
|
10
|
+
function getSource(ptr) {
|
|
11
|
+
throw new Error('not implemented')
|
|
12
|
+
/// TODO: implement
|
|
13
|
+
}
|
|
14
|
+
const objectParams = () => {
|
|
15
|
+
const params = collectPointers(object, [action.params], getSource)[0]
|
|
16
|
+
return params
|
|
17
|
+
}
|
|
18
|
+
const func = async (additionalParams) => {
|
|
19
|
+
const params = { ...additionalParams, ...objectParams() }
|
|
20
|
+
return api.request(action.path, params)
|
|
21
|
+
}
|
|
22
|
+
func.params = objectParams
|
|
23
|
+
func.path = action.path
|
|
24
|
+
return func
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
async function fetch(api, path) {
|
|
28
|
+
if(Array.isArray(path)) path = { what: path }
|
|
29
|
+
const paths = [ path ]
|
|
30
|
+
const preFetchPaths = await api.get({ paths })
|
|
31
|
+
debug("PRE FETCH DATA", preFetchPaths)
|
|
32
|
+
const preFetchMap = new Map(preFetchPaths.map((res) => [JSON.stringify(res.what), res] ))
|
|
33
|
+
function createObject(what, more) {
|
|
34
|
+
const res = preFetchMap.get(JSON.stringify(what))
|
|
35
|
+
if(res.error) throw new Error(res.error)
|
|
36
|
+
const data = res.data
|
|
37
|
+
if(data && more) {
|
|
38
|
+
if(Array.isArray(data)) {
|
|
39
|
+
for(let i = 0; i < data.length; i ++) {
|
|
40
|
+
for(const moreElement of more) {
|
|
41
|
+
if(moreElement.to) {
|
|
42
|
+
debug("COLLECT POINTERS FROM", data[i], "SC", moreElement.schema)
|
|
43
|
+
const pointers = collectPointers(data[i], moreElement.schema ,
|
|
44
|
+
(what) => preFetchMap.get(JSON.stringify(what)))
|
|
45
|
+
debug("POINTERS COLLECTED", pointers)
|
|
46
|
+
const values = pointers.map(pointer => createObject(pointer, moreElement.more))
|
|
47
|
+
debug("VALUES", values)
|
|
48
|
+
debug("MANY", pointers.many)
|
|
49
|
+
if(pointers.many) {
|
|
50
|
+
data[i][moreElement.to] = values
|
|
51
|
+
} else {
|
|
52
|
+
data[i][moreElement.to] = values[0] || null
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
} else {
|
|
58
|
+
for(const moreElement of more) {
|
|
59
|
+
if(moreElement.to) {
|
|
60
|
+
const pointers = collectPointers(data, moreElement.schema,
|
|
61
|
+
(what) => preFetchMap.get(JSON.stringify(what)))
|
|
62
|
+
const values = pointers.map(pointer => createObject(pointer, moreElement.more))
|
|
63
|
+
if(pointers.many) {
|
|
64
|
+
data[moreElement.to] = values
|
|
65
|
+
} else {
|
|
66
|
+
data[moreElement.to] = values[0] || null
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
return ref(data)
|
|
73
|
+
}
|
|
74
|
+
return createObject(path.what, path.more)
|
|
75
|
+
}
|
|
76
|
+
|
|
9
77
|
async function live(api, path, onUnmountedCb) {
|
|
10
78
|
if(isRef(path)) {
|
|
11
79
|
/// TODO: support path as ref/computed
|
|
@@ -22,201 +90,160 @@ async function live(api, path, onUnmountedCb) {
|
|
|
22
90
|
}
|
|
23
91
|
}
|
|
24
92
|
|
|
93
|
+
if(typeof window == 'undefined') return fetch(api, path)
|
|
25
94
|
if(Array.isArray(path)) path = { what: path }
|
|
26
95
|
const paths = [ path ]
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
const
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
const
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
debug("COLLECT POINTERS FROM", data[i], "SC", moreElement.schema)
|
|
41
|
-
const pointers = collectPointers(data[i], moreElement.schema ,
|
|
42
|
-
(what) => preFetchMap.get(JSON.stringify(what)))
|
|
43
|
-
debug("POINTERS COLLECTED", pointers)
|
|
44
|
-
const values = pointers.map(pointer => createObject(pointer, moreElement.more))
|
|
45
|
-
debug("VALUES", values)
|
|
46
|
-
debug("MANY", pointers.many)
|
|
47
|
-
if(pointers.many) {
|
|
48
|
-
data[i][moreElement.to] = values
|
|
49
|
-
} else {
|
|
50
|
-
data[i][moreElement.to] = values[0] || null
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
} else {
|
|
56
|
-
for(const moreElement of more) {
|
|
96
|
+
const preFetchPaths = api.observable({ paths })
|
|
97
|
+
function bindResult(what, more, actions, object, property, onError) {
|
|
98
|
+
if(!what) throw new Error("what parameter required!")
|
|
99
|
+
const observable = api.observable(what)
|
|
100
|
+
const errorObserver = { error: onError }
|
|
101
|
+
let dispose
|
|
102
|
+
if((more && more.some(m => m.to)) || actions) {
|
|
103
|
+
const extendedObservable = new ExtendedObservableList(observable,
|
|
104
|
+
newElement => {
|
|
105
|
+
if(!newElement) return newElement
|
|
106
|
+
const extendedElement = reactive({ ...newElement })
|
|
107
|
+
const props = {}
|
|
108
|
+
if(more) for(const moreElement of more) {
|
|
57
109
|
if(moreElement.to) {
|
|
58
|
-
const
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
if(pointers.many) {
|
|
62
|
-
data[moreElement.to] = values
|
|
63
|
-
} else {
|
|
64
|
-
data[moreElement.to] = values[0] || null
|
|
110
|
+
const prop = {
|
|
111
|
+
bounds: [],
|
|
112
|
+
sources: []
|
|
65
113
|
}
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
const extendedElement = reactive({ ...newElement })
|
|
84
|
-
const props = {}
|
|
85
|
-
for(const moreElement of more) {
|
|
86
|
-
if(moreElement.to) {
|
|
87
|
-
const prop = {
|
|
88
|
-
bounds: [],
|
|
89
|
-
sources: []
|
|
90
|
-
}
|
|
91
|
-
props[moreElement.to] = prop
|
|
92
|
-
let requiredSrcs = []
|
|
93
|
-
const srcs = new Map()
|
|
94
|
-
function getSource(ptr) {
|
|
95
|
-
const exists = srcs.get(ptr)
|
|
96
|
-
if(exists !== undefined) return exists.list
|
|
97
|
-
requiredSrcs.push(exists)
|
|
98
|
-
return undefined
|
|
99
|
-
}
|
|
100
|
-
function computePointers() {
|
|
101
|
-
while(true) {
|
|
102
|
-
const pointers = collectPointers(newElement, moreElement.schema, getSource)
|
|
103
|
-
if(requiredSrcs.length == 0) return pointers
|
|
104
|
-
for(const requiredSrc of requiredSrcs) {
|
|
105
|
-
const observable = api.observable(requiredSrc)
|
|
106
|
-
const observer = () => {
|
|
107
|
-
bindPointers(computePointers())
|
|
108
|
-
}
|
|
109
|
-
srcs.set(JSON.stringify(requiredSrc), observable)
|
|
110
|
-
prop.sources.push({ observable, observer })
|
|
111
|
-
observable.observe(observer)
|
|
114
|
+
props[moreElement.to] = prop
|
|
115
|
+
let requiredSrcs = []
|
|
116
|
+
const srcs = new Map()
|
|
117
|
+
function getSource(ptr) {
|
|
118
|
+
const exists = srcs.get(ptr)
|
|
119
|
+
if(exists !== undefined) return exists.list
|
|
120
|
+
requiredSrcs.push(exists)
|
|
121
|
+
return undefined
|
|
122
|
+
}
|
|
123
|
+
function computePointers() {
|
|
124
|
+
while(true) {
|
|
125
|
+
const pointers = collectPointers(newElement, moreElement.schema, getSource)
|
|
126
|
+
if(requiredSrcs.length == 0) return pointers
|
|
127
|
+
for(const requiredSrc of requiredSrcs) {
|
|
128
|
+
const observable = api.observable(requiredSrc)
|
|
129
|
+
const observer = () => {
|
|
130
|
+
bindPointers(computePointers())
|
|
112
131
|
}
|
|
132
|
+
srcs.set(JSON.stringify(requiredSrc), observable)
|
|
133
|
+
prop.sources.push({ observable, observer })
|
|
134
|
+
observable.observe(observer)
|
|
113
135
|
}
|
|
114
136
|
}
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
137
|
+
}
|
|
138
|
+
function bindPointers(pointers) {
|
|
139
|
+
if(pointers.many) {
|
|
140
|
+
const oldBound = prop.bounds.slice()
|
|
141
|
+
const newArray = new Array(pointers.length)
|
|
142
|
+
const newBounds = new Array(pointers.length)
|
|
143
|
+
for(let i = 0; i < pointers.length; i++) {
|
|
144
|
+
newBounds[i] = bindResult(pointers[i], moreElement.more, moreElement.actions,
|
|
145
|
+
newArray, i, onError)
|
|
146
|
+
}
|
|
147
|
+
prop.bounds = newBounds
|
|
148
|
+
oldBound.forEach(b => b.dispose())
|
|
149
|
+
extendedElement[moreElement.to] = newArray
|
|
150
|
+
} else if(pointers.length > 0) {
|
|
151
|
+
const oldBound = prop.bounds
|
|
152
|
+
if(!oldBound || oldBound.length == 0 ||
|
|
153
|
+
JSON.stringify(oldBound[0].what) != JSON.stringify(pointers[0])) {
|
|
154
|
+
if(oldBound) {
|
|
155
|
+
prop.bounds.forEach(b => b.dispose())
|
|
122
156
|
}
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
if(!oldBound || oldBound.length == 0 ||
|
|
129
|
-
JSON.stringify(oldBound[0].what) != JSON.stringify(pointers[0])) {
|
|
130
|
-
if(oldBound) {
|
|
131
|
-
prop.bounds.forEach(b => b.dispose())
|
|
132
|
-
}
|
|
133
|
-
if(pointers[0]) {
|
|
134
|
-
prop.bounds = [
|
|
135
|
-
bindResult(pointers[0], moreElement.more, extendedElement, moreElement.to, onError)
|
|
136
|
-
]
|
|
137
|
-
}
|
|
157
|
+
if(pointers[0]) {
|
|
158
|
+
prop.bounds = [
|
|
159
|
+
bindResult(pointers[0], moreElement.more, moreElement.actions,
|
|
160
|
+
extendedElement, moreElement.to, onError)
|
|
161
|
+
]
|
|
138
162
|
}
|
|
139
163
|
}
|
|
140
164
|
}
|
|
141
|
-
bindPointers(computePointers())
|
|
142
165
|
}
|
|
166
|
+
bindPointers(computePointers())
|
|
143
167
|
}
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
}
|
|
168
|
+
}
|
|
169
|
+
if(actions) for(const action of actions) {
|
|
170
|
+
if(!action.name) continue
|
|
171
|
+
debug("BIND ACTION", action.name, "TO", object)
|
|
172
|
+
extendedElement[action.name] = createActionFunction(action, extendedElement)
|
|
173
|
+
}
|
|
174
|
+
extendedElement[liveSymbol] = props
|
|
175
|
+
return extendedElement
|
|
176
|
+
},
|
|
177
|
+
disposedElement => {
|
|
178
|
+
if(!disposedElement) return
|
|
179
|
+
const boundProps = disposedElement[liveSymbol]
|
|
180
|
+
for(const propName in boundProps) {
|
|
181
|
+
const prop = boundProps[propName]
|
|
182
|
+
const propBounds = prop.bounds
|
|
183
|
+
for(const propBound of propBounds) {
|
|
184
|
+
//console.log("PROP BOUND DISPOSE", propBound)
|
|
185
|
+
propBound.dispose()
|
|
163
186
|
}
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
187
|
+
const propSources = prop.sources
|
|
188
|
+
for(const propSource of propSources) {
|
|
189
|
+
debug("PROP SOURCE DISPOSE", propSource)
|
|
190
|
+
debug("UNOBSERVE PROPERTY", what, object, property)
|
|
191
|
+
propSource.observable.unobserve(propSource.observer)
|
|
169
192
|
}
|
|
170
|
-
return data
|
|
171
193
|
}
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
property,
|
|
178
|
-
dispose() {
|
|
179
|
-
debug("UNBIND PROPERTY", what, object, property)
|
|
180
|
-
extendedObservable.unbindProperty(object, property)
|
|
181
|
-
observable.unobserve(errorObserver)
|
|
182
|
-
}
|
|
183
|
-
}
|
|
184
|
-
} else {
|
|
185
|
-
observable.bindProperty(object, property)
|
|
186
|
-
observable.observe(errorObserver)
|
|
187
|
-
return {
|
|
188
|
-
what, property,
|
|
189
|
-
dispose() {
|
|
190
|
-
debug("UNBIND PROPERTY", what, object, property)
|
|
191
|
-
observable.unbindProperty(object, property)
|
|
192
|
-
observable.unobserve(errorObserver)
|
|
194
|
+
},
|
|
195
|
+
(data) => {
|
|
196
|
+
if(data && typeof data == 'object') {
|
|
197
|
+
const activated = reactive(data)
|
|
198
|
+
return activated
|
|
193
199
|
}
|
|
200
|
+
return data
|
|
194
201
|
}
|
|
202
|
+
)
|
|
203
|
+
extendedObservable.bindProperty(object, property)
|
|
204
|
+
observable.observe(errorObserver)
|
|
205
|
+
dispose = () => {
|
|
206
|
+
debug("UNBIND PROPERTY", what, object, property)
|
|
207
|
+
extendedObservable.unbindProperty(object, property)
|
|
208
|
+
observable.unobserve(errorObserver)
|
|
195
209
|
}
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
error = msg
|
|
204
|
-
reject(error)
|
|
210
|
+
} else {
|
|
211
|
+
observable.bindProperty(object, property)
|
|
212
|
+
observable.observe(errorObserver)
|
|
213
|
+
dispose = () => {
|
|
214
|
+
debug("UNBIND PROPERTY", what, object, property)
|
|
215
|
+
observable.unbindProperty(object, property)
|
|
216
|
+
observable.unobserve(errorObserver)
|
|
205
217
|
}
|
|
206
|
-
const bound = bindResult(path.what, path.more, resultRef, 'value', onError)
|
|
207
|
-
const pathsObserver = (signal, value) => {}
|
|
208
|
-
preFetchPaths.observe(pathsObserver)
|
|
209
|
-
onUnmountedCb(() => {
|
|
210
|
-
preFetchPaths.unobserve(pathsObserver)
|
|
211
|
-
bound.dispose()
|
|
212
|
-
})
|
|
213
|
-
preFetchPaths.wait().then(resolve).catch(onError)
|
|
214
|
-
})
|
|
215
|
-
while(unref(resultRef) === undefined) { // wait for next tick
|
|
216
|
-
await new Promise((resolve) => setTimeout(resolve, 0))
|
|
217
218
|
}
|
|
218
|
-
return
|
|
219
|
+
return {
|
|
220
|
+
what, property, dispose
|
|
221
|
+
}
|
|
219
222
|
}
|
|
223
|
+
const resultRef = ref()
|
|
224
|
+
await new Promise((resolve, reject) => {
|
|
225
|
+
let error = null
|
|
226
|
+
const onError = (msg) => {
|
|
227
|
+
console.error("LIVE ERROR", msg)
|
|
228
|
+
if(error) return
|
|
229
|
+
error = msg
|
|
230
|
+
reject(error)
|
|
231
|
+
}
|
|
232
|
+
const bound = bindResult(path.what, path.more, path.actions, resultRef, 'value', onError)
|
|
233
|
+
const pathsObserver = (signal, value) => {}
|
|
234
|
+
preFetchPaths.observe(pathsObserver)
|
|
235
|
+
onUnmountedCb(() => {
|
|
236
|
+
preFetchPaths.unobserve(pathsObserver)
|
|
237
|
+
bound.dispose()
|
|
238
|
+
})
|
|
239
|
+
preFetchPaths.wait().then(resolve).catch(onError)
|
|
240
|
+
})
|
|
241
|
+
while(unref(resultRef) === undefined) { // wait for next tick
|
|
242
|
+
await new Promise((resolve) => setTimeout(resolve, 0))
|
|
243
|
+
}
|
|
244
|
+
return resultRef
|
|
245
|
+
|
|
220
246
|
}
|
|
221
247
|
|
|
222
|
-
export default live
|
|
248
|
+
export default live
|
|
249
|
+
export { live, fetch }
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@live-change/dao-vue3",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.13",
|
|
4
4
|
"author": {
|
|
5
5
|
"email": "m8@em8.pl",
|
|
6
6
|
"name": "Michał Łaszczewski",
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
"url": "https://github.com/live-change/live-change-dao/issues"
|
|
11
11
|
},
|
|
12
12
|
"dependencies": {
|
|
13
|
-
"@live-change/dao": "^0.4.
|
|
13
|
+
"@live-change/dao": "^0.4.13"
|
|
14
14
|
},
|
|
15
15
|
"description": "Vue.js integration for live-change dao",
|
|
16
16
|
"directories": {},
|
|
@@ -32,5 +32,5 @@
|
|
|
32
32
|
"scripts": {
|
|
33
33
|
"compileTests": "webpack test/*.js tests-bundle.js"
|
|
34
34
|
},
|
|
35
|
-
"gitHead": "
|
|
35
|
+
"gitHead": "573a234a6c5a9525aa97894fd9b2bf67ffe1d2a4"
|
|
36
36
|
}
|