@live-change/dao-vue3 0.1.19 → 0.2.0

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.
@@ -1,5 +1,5 @@
1
1
  import live from "./live.js"
2
- import { computed, reactive, unref } from "vue"
2
+ import { computed, reactive, ref, unref, watch } from "vue"
3
3
 
4
4
  class Bucket {
5
5
 
@@ -16,7 +16,26 @@ class Bucket {
16
16
  this.onDispose = []
17
17
  this.domElements = []
18
18
 
19
- this.data = undefined
19
+ this.data = computed(() => {
20
+ const ldv = this.liveData.value
21
+ if(!ldv) return []
22
+ let source = unref(ldv)
23
+ if(this.range.reverse) {
24
+ source = source.slice()
25
+ source.reverse()
26
+ }
27
+ if(this.hardClose) {
28
+ return source
29
+ }
30
+ return source.filter(element => (
31
+ (!this.range.gt || element.id > this.range.gt ) &&
32
+ (!this.range.gte || element.id >= this.range.gte) &&
33
+ (!this.range.lt || element.id < this.range.lt ) &&
34
+ (!this.range.lte || element.id <= this.range.lte)
35
+ ))
36
+ })
37
+ this.liveData = ref(null)
38
+
20
39
  this.load()
21
40
 
22
41
  this.promise = waitForComponents ? this.createPromise() : this.dataPromise
@@ -30,16 +49,7 @@ class Bucket {
30
49
  this.path = this.pathFunction(this.range)
31
50
  this.dataPromise = live(this.api(), this.path, fun => onDispose.push(fun))
32
51
  this.dataPromise.then(data => {
33
- if(this.hardClose) {
34
- this.data = data
35
- return
36
- }
37
- this.data = computed(() => data.filter(element => (
38
- (!this.range.gt || element.id > this.range.gt ) &&
39
- (!this.range.gte || element.id >= this.range.gte) &&
40
- (!this.range.lt || element.id < this.range.lt ) &&
41
- (!this.range.lte || element.id <= this.range.lte)
42
- )))
52
+ this.liveData.value = data
43
53
  })
44
54
  return this.dataPromise
45
55
  }
@@ -61,14 +71,14 @@ class Bucket {
61
71
  const data = unref(await this.dataPromise)
62
72
  if(!this.data) throw new Error("can't close - bucket not loaded!")
63
73
  if(this.data.length < this.bucketSize) throw new Error("can't close - bucket not full")
64
- this.range.gte = data[0].id
74
+ this.range.gte = data[this.range.reverse ? data.length - 1 : 0].id
65
75
  if(this.hardClose) await this.load()
66
76
  }
67
77
 
68
78
  async closeBottom() {
69
79
  const data = unref(await this.dataPromise)
70
80
  if(data.length < this.bucketSize) throw new Error("can't close - bucket not full")
71
- this.range.lte = data[data.length - 1].id
81
+ this.range.lte = data[this.range.reverse ? 0 : data.length - 1].id
72
82
  if(this.hardClose) await this.load()
73
83
  }
74
84
 
@@ -92,9 +102,24 @@ class RangeBuckets {
92
102
  this.lastBucketId = 0
93
103
  this.buckets = reactive([])
94
104
 
105
+ this.canLoadTop = computed(() => this.isTopLoadPossible())
106
+ this.canLoadBottom = computed(() => this.isBottomLoadPossible())
107
+
95
108
  this.loadFirstBucket()
96
109
  }
97
110
 
111
+ isTopLoadPossible() {
112
+ if(this.buckets.length == 0) return false
113
+ const firstBucket = this.buckets[0]
114
+ return firstBucket.isTopClosed() || firstBucket.canClose()
115
+ }
116
+
117
+ isBottomLoadPossible() {
118
+ if(this.buckets.length == 0) return false
119
+ const lastBucket = this.buckets[this.buckets.length - 1]
120
+ return lastBucket.isBottomClosed() || lastBucket.canClose()
121
+ }
122
+
98
123
  loadFirstBucket() {
99
124
  const firstBucket = this.createBucket({
100
125
  gte: this.position,
@@ -109,32 +134,25 @@ class RangeBuckets {
109
134
  }
110
135
 
111
136
  async wait() {
137
+ //console.log("WAIT FOR BUCKETS", this.buckets.length)
112
138
  await Promise.all(this.buckets.map(bucket => bucket.promise)).then(loaded => this)
113
139
  }
114
140
 
115
- canLoadTop() {
116
- if(this.buckets.length == 0) return false
117
- const firstBucket = this.buckets[0]
118
- return firstBucket.isTopClosed() || firstBucket.canClose()
119
- }
120
-
121
- canLoadBottom() {
122
- if(this.buckets.length == 0) return false
123
- const lastBucket = this.buckets[this.buckets.length - 1]
124
- return lastBucket.isBottomClosed() || lastBucket.canClose()
125
- }
126
-
127
141
  async loadTop() {
142
+ //console.log("LOAD TOP!", this.isTopLoadPossible())
128
143
  if(this.buckets.length == 0) return this.loadFirstBucket()
129
144
  const firstBucket = this.buckets[0]
130
145
  await firstBucket.promise
131
- if(!this.canLoadTop()) return
132
- if(firstBucket != this.buckets[0]) return this.buckets[0].promise
133
- let range = { limit: this.bucketSize }
146
+ if(!this.isTopLoadPossible()) return
147
+ if(firstBucket != this.buckets[0]) {
148
+ return this.buckets[0].promise
149
+ }
150
+ let range = { limit: this.bucketSize, reverse: true }
134
151
  if(!firstBucket.isTopClosed()) {
135
152
  if(firstBucket.canClose()) {
136
153
  await firstBucket.closeTop()
137
- if(!this.canLoadTop()) return
154
+ if(!firstBucket.isTopClosed()) throw new Error('top not closed!!!')
155
+ if(!this.isTopLoadPossible()) return
138
156
  return this.loadTop()
139
157
  } else {
140
158
  console.log("FBD", unref(firstBucket.data))
@@ -154,16 +172,20 @@ class RangeBuckets {
154
172
  }
155
173
 
156
174
  async loadBottom() {
175
+ //console.log("LOAD BOTTOM!", this.isBottomLoadPossible())
157
176
  if(this.buckets.length == 0) return this.loadFirstBucket()
158
177
  const lastBucket = this.buckets[this.buckets.length - 1]
159
178
  await lastBucket.promise
160
- if(!this.canLoadBottom()) return
161
- if(lastBucket != this.buckets[this.buckets.length - 1]) return this.buckets[this.buckets.length - 1].promise
179
+ if(!this.isBottomLoadPossible()) return
180
+ if(lastBucket != this.buckets[this.buckets.length - 1]) {
181
+ return this.buckets[this.buckets.length - 1].promise
182
+ }
162
183
  let range = { limit: this.bucketSize }
163
184
  if(!lastBucket.isBottomClosed()) {
164
185
  if(lastBucket.canClose()) {
165
186
  await lastBucket.closeBottom()
166
187
  if(!lastBucket.isBottomClosed()) throw new Error('bottom not closed!!!')
188
+ if(!this.isBottomLoadPossible()) return
167
189
  return this.loadBottom()
168
190
  } else {
169
191
  throw new Error('impossible to read after bucket that is not closeable')
@@ -183,14 +205,17 @@ class RangeBuckets {
183
205
 
184
206
  dropTop() {
185
207
  if(this.buckets.length == 0) throw new Error('impossible to drop from empty')
208
+ //console.log("DROP TOP!")
186
209
  const droppedBucket = this.buckets[0]
187
- const height = droppedBucket.domElements.reduce((acc, el) => acc + el?.offsetHeight, 0)
210
+ const height = droppedBucket.domElements.reduce((acc, el) => acc + (el?.offsetHeight || 0), 0)
211
+ //console.log("DOM ELEMENTS", droppedBucket.domElements.map(el => el?.offsetHeight || 0), height)
188
212
  this.buckets.shift()
189
213
  droppedBucket.dispose()
190
214
  return height
191
215
  }
192
216
 
193
217
  dropBottom() {
218
+ //console.log("DROP BOTTOM!")
194
219
  if(this.buckets.length == 0) throw new Error('impossible to drop from empty')
195
220
  const droppedBucket = this.buckets[this.buckets.length - 1]
196
221
  const height = droppedBucket.domElements.reduce((acc, el) => acc + el?.offsetHeight, 0)
package/lib/live.js CHANGED
@@ -1,4 +1,4 @@
1
- import { ref, onUnmounted, getCurrentInstance, unref, nextTick } from 'vue'
1
+ import { ref, onUnmounted, getCurrentInstance, unref, reactive } from 'vue'
2
2
  import { collectPointers, ExtendedObservableList } from '@live-change/dao'
3
3
 
4
4
  const liveSymbol = Symbol('live')
@@ -24,7 +24,7 @@ async function live(api, path, onUnmountedCb) {
24
24
  const res = preFetchMap.get(JSON.stringify(what))
25
25
  if(res.error) throw new Error(res.error)
26
26
  const data = res.data
27
- if(more) {
27
+ if(data && more) {
28
28
  if(Array.isArray(data)) {
29
29
  for(let i = 0; i < data.length; i ++) {
30
30
  for(const moreElement of more) {
@@ -59,7 +59,7 @@ async function live(api, path, onUnmountedCb) {
59
59
  }
60
60
  }
61
61
  }
62
- return data
62
+ return ref(data)
63
63
  }
64
64
  return createObject(path.what, path.more)
65
65
  } else {
@@ -72,7 +72,7 @@ async function live(api, path, onUnmountedCb) {
72
72
  const extendedObservable = new ExtendedObservableList(observable,
73
73
  newElement => {
74
74
  if(!newElement) return newElement
75
- const extendedElement = { ...newElement }
75
+ const extendedElement = reactive({ ...newElement })
76
76
  const props = {}
77
77
  for(const moreElement of more) {
78
78
  if(moreElement.to) {
@@ -152,6 +152,13 @@ async function live(api, path, onUnmountedCb) {
152
152
  propSource.observable.unobserve(propSource.observer)
153
153
  }
154
154
  }
155
+ },
156
+ (data) => {
157
+ if(data && typeof data == 'object') {
158
+ const activated = reactive(data)
159
+ return activated
160
+ }
161
+ return data
155
162
  }
156
163
  )
157
164
  extendedObservable.bindProperty(object, property)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@live-change/dao-vue3",
3
- "version": "0.1.19",
3
+ "version": "0.2.0",
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/dao-vue3/issues"
11
11
  },
12
12
  "dependencies": {
13
- "@live-change/dao": "^0.2.41"
13
+ "@live-change/dao": "^0.3.9"
14
14
  },
15
15
  "devDependencies": {},
16
16
  "description": "Vue.js integration for live-change dao",