@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.
Files changed (3) hide show
  1. package/index.js +2 -2
  2. package/lib/live.js +201 -174
  3. 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
- if(typeof window == 'undefined') {
28
- const preFetchPaths = await api.get({ paths })
29
- debug("PRE FETCH DATA", preFetchPaths)
30
- const preFetchMap = new Map(preFetchPaths.map((res) => [JSON.stringify(res.what), res] ))
31
- function createObject(what, more) {
32
- const res = preFetchMap.get(JSON.stringify(what))
33
- if(res.error) throw new Error(res.error)
34
- const data = res.data
35
- if(data && more) {
36
- if(Array.isArray(data)) {
37
- for(let i = 0; i < data.length; i ++) {
38
- for(const moreElement of more) {
39
- if(moreElement.to) {
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 pointers = collectPointers(data, moreElement.schema,
59
- (what) => preFetchMap.get(JSON.stringify(what)))
60
- const values = pointers.map(pointer => createObject(pointer, moreElement.more))
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
- return ref(data)
71
- }
72
- return createObject(path.what, path.more)
73
- } else {
74
- const preFetchPaths = api.observable({ paths })
75
- function bindResult(what, more, object, property, onError) {
76
- if(!what) throw new Error("what parameter required!")
77
- const observable = api.observable(what)
78
- const errorObserver = { error: onError }
79
- if(more && more.some(m => m.to)) {
80
- const extendedObservable = new ExtendedObservableList(observable,
81
- newElement => {
82
- if(!newElement) return newElement
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
- function bindPointers(pointers) {
116
- if(pointers.many) {
117
- const oldBound = prop.bounds.slice()
118
- const newArray = new Array(pointers.length)
119
- const newBounds = new Array(pointers.length)
120
- for(let i = 0; i < pointers.length; i++) {
121
- newBounds[i] = bindResult(pointers[i], moreElements.more, newArray, i, onError)
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
- prop.bounds = newBounds
124
- oldBound.forEach(b => b.dispose())
125
- extendedElement[moreElement.to] = newArray
126
- } else if(pointers.length > 0) {
127
- const oldBound = prop.bounds
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
- extendedElement[liveSymbol] = props
145
- return extendedElement
146
- },
147
- disposedElement => {
148
- if(!disposedElement) return
149
- const boundProps = disposedElement[liveSymbol]
150
- for(const propName in boundProps) {
151
- const prop = boundProps[propName]
152
- const propBounds = prop.bounds
153
- for(const propBound of propBounds) {
154
- //console.log("PROP BOUND DISPOSE", propBound)
155
- propBound.dispose()
156
- }
157
- const propSources = prop.sources
158
- for(const propSource of propSources) {
159
- debug("PROP SOURCE DISPOSE", propSource)
160
- debug("UNOBSERVE PROPERTY", what, object, property)
161
- propSource.observable.unobserve(propSource.observer)
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
- (data) => {
166
- if(data && typeof data == 'object') {
167
- const activated = reactive(data)
168
- return activated
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
- extendedObservable.bindProperty(object, property)
174
- observable.observe(errorObserver)
175
- return {
176
- what,
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
- const resultRef = ref()
198
- await new Promise((resolve, reject) => {
199
- let error = null
200
- const onError = (msg) => {
201
- console.error("LIVE ERROR", msg)
202
- if(error) return
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 resultRef
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.10",
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.10"
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": "741a8b2e6c0a41f7ac3cb389fa79b2ec14099355"
35
+ "gitHead": "573a234a6c5a9525aa97894fd9b2bf67ffe1d2a4"
36
36
  }