@live-change/dao-vue3 0.8.21 → 0.8.23
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/LICENSE.md +11 -0
- package/index.js +3 -2
- package/lib/RangeBuckets.js +41 -13
- package/lib/freezable.js +24 -0
- package/package.json +3 -3
package/LICENSE.md
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
Copyright 2019-2024 Michał Łaszczewski
|
|
2
|
+
|
|
3
|
+
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
|
4
|
+
|
|
5
|
+
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
|
6
|
+
|
|
7
|
+
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
|
|
8
|
+
|
|
9
|
+
3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
|
|
10
|
+
|
|
11
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
package/index.js
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import reactiveMixin from './lib/reactiveMixin.js'
|
|
2
2
|
import reactivePrefetchMixin from './lib/reactivePrefetchMixin.js'
|
|
3
|
-
|
|
3
|
+
export { live, fetch } from './lib/live.js'
|
|
4
4
|
import ReactiveObservableList from './lib/ReactiveObservableList.js'
|
|
5
5
|
import RangeBuckets from './lib/RangeBuckets.js'
|
|
6
|
+
import freezable from './lib/freezable.js'
|
|
6
7
|
|
|
7
8
|
const ReactiveDaoVue = {
|
|
8
9
|
install(Vue, options) {
|
|
@@ -14,6 +15,6 @@ const ReactiveDaoVue = {
|
|
|
14
15
|
}
|
|
15
16
|
|
|
16
17
|
//// TODO: rename reactive to live
|
|
17
|
-
export { ReactiveDaoVue, reactiveMixin, reactivePrefetchMixin, ReactiveObservableList, RangeBuckets,
|
|
18
|
+
export { ReactiveDaoVue, reactiveMixin, reactivePrefetchMixin, ReactiveObservableList, RangeBuckets, freezable }
|
|
18
19
|
|
|
19
20
|
export default ReactiveDaoVue
|
package/lib/RangeBuckets.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import live from "./live.js"
|
|
2
|
-
import
|
|
2
|
+
import freezable from './freezable.js'
|
|
3
|
+
import { computed, reactive, ref, unref, watch, shallowRef, isRef } from "vue"
|
|
3
4
|
|
|
4
5
|
class Bucket {
|
|
5
6
|
|
|
@@ -16,10 +17,14 @@ class Bucket {
|
|
|
16
17
|
this.onDispose = []
|
|
17
18
|
this.domElements = []
|
|
18
19
|
|
|
20
|
+
this.freeze = () => {}
|
|
21
|
+
this.unfreeze = () => {}
|
|
22
|
+
this.changed = ref(false)
|
|
23
|
+
|
|
19
24
|
this.data = computed(() => {
|
|
20
25
|
const ldv = this.liveData.value
|
|
21
26
|
if(!ldv) return []
|
|
22
|
-
let source = unref(ldv)
|
|
27
|
+
let source = unref(unref(ldv))
|
|
23
28
|
if(this.range.reverse) {
|
|
24
29
|
source = source.slice()
|
|
25
30
|
source.reverse()
|
|
@@ -35,6 +40,7 @@ class Bucket {
|
|
|
35
40
|
))
|
|
36
41
|
})
|
|
37
42
|
this.liveData = ref(null)
|
|
43
|
+
this.rawLiveData = ref(null)
|
|
38
44
|
|
|
39
45
|
this.load()
|
|
40
46
|
|
|
@@ -48,8 +54,16 @@ class Bucket {
|
|
|
48
54
|
async load() {
|
|
49
55
|
this.path = this.pathFunction(this.range)
|
|
50
56
|
this.dataPromise = live(this.api(), this.path, fun => this.onDispose.push(fun))
|
|
51
|
-
this.dataPromise.then(
|
|
52
|
-
this.
|
|
57
|
+
this.dataPromise.then(dataRef => {
|
|
58
|
+
this.rawLiveData.value = dataRef
|
|
59
|
+
const { freeze, unfreeze, output, changed } = freezable(dataRef)
|
|
60
|
+
this.freeze = freeze
|
|
61
|
+
this.unfreeze = unfreeze
|
|
62
|
+
watch(() => changed.value, v => {
|
|
63
|
+
if(isRef(this.changed)) this.changed.value = v
|
|
64
|
+
else this.changed = v
|
|
65
|
+
}, { immediate: true })
|
|
66
|
+
this.liveData.value = output
|
|
53
67
|
})
|
|
54
68
|
return this.dataPromise
|
|
55
69
|
}
|
|
@@ -64,7 +78,7 @@ class Bucket {
|
|
|
64
78
|
|
|
65
79
|
canClose() {
|
|
66
80
|
const data = unref(this.data)
|
|
67
|
-
return data && data.length
|
|
81
|
+
return data && data.length === this.bucketSize
|
|
68
82
|
}
|
|
69
83
|
|
|
70
84
|
async closeTop() {
|
|
@@ -105,17 +119,19 @@ class RangeBuckets {
|
|
|
105
119
|
this.canLoadTop = computed(() => this.isTopLoadPossible())
|
|
106
120
|
this.canLoadBottom = computed(() => this.isBottomLoadPossible())
|
|
107
121
|
|
|
122
|
+
this.changed = computed(() => this.buckets.some(bucket => bucket.changed))
|
|
123
|
+
|
|
108
124
|
this.loadFirstBucket()
|
|
109
125
|
}
|
|
110
126
|
|
|
111
127
|
isTopLoadPossible() {
|
|
112
|
-
if(this.buckets.length
|
|
128
|
+
if(this.buckets.length === 0) return false
|
|
113
129
|
const firstBucket = this.buckets[0]
|
|
114
130
|
return firstBucket.isTopClosed() || firstBucket.canClose()
|
|
115
131
|
}
|
|
116
132
|
|
|
117
133
|
isBottomLoadPossible() {
|
|
118
|
-
if(this.buckets.length
|
|
134
|
+
if(this.buckets.length === 0) return false
|
|
119
135
|
const lastBucket = this.buckets[this.buckets.length - 1]
|
|
120
136
|
return lastBucket.isBottomClosed() || lastBucket.canClose()
|
|
121
137
|
}
|
|
@@ -141,11 +157,11 @@ class RangeBuckets {
|
|
|
141
157
|
|
|
142
158
|
async loadTop() {
|
|
143
159
|
//console.log("LOAD TOP!", this.isTopLoadPossible())
|
|
144
|
-
if(this.buckets.length
|
|
160
|
+
if(this.buckets.length === 0) return this.loadFirstBucket()
|
|
145
161
|
const firstBucket = this.buckets[0]
|
|
146
162
|
await firstBucket.promise
|
|
147
163
|
if(!this.isTopLoadPossible()) return
|
|
148
|
-
if(firstBucket
|
|
164
|
+
if(firstBucket !== this.buckets[0]) {
|
|
149
165
|
return this.buckets[0].promise
|
|
150
166
|
}
|
|
151
167
|
let range = { limit: this.bucketSize, reverse: true }
|
|
@@ -174,11 +190,11 @@ class RangeBuckets {
|
|
|
174
190
|
|
|
175
191
|
async loadBottom() {
|
|
176
192
|
//console.log("LOAD BOTTOM!", this.isBottomLoadPossible())
|
|
177
|
-
if(this.buckets.length
|
|
193
|
+
if(this.buckets.length === 0) return this.loadFirstBucket()
|
|
178
194
|
const lastBucket = this.buckets[this.buckets.length - 1]
|
|
179
195
|
await lastBucket.promise
|
|
180
196
|
if(!this.isBottomLoadPossible()) return
|
|
181
|
-
if(lastBucket
|
|
197
|
+
if(lastBucket !== this.buckets[this.buckets.length - 1]) {
|
|
182
198
|
return this.buckets[this.buckets.length - 1].promise
|
|
183
199
|
}
|
|
184
200
|
let range = { limit: this.bucketSize }
|
|
@@ -205,7 +221,7 @@ class RangeBuckets {
|
|
|
205
221
|
}
|
|
206
222
|
|
|
207
223
|
dropTop() {
|
|
208
|
-
if(this.buckets.length
|
|
224
|
+
if(this.buckets.length === 0) throw new Error('impossible to drop from empty')
|
|
209
225
|
//console.log("DROP TOP!")
|
|
210
226
|
const droppedBucket = this.buckets[0]
|
|
211
227
|
const height = droppedBucket.domElements.reduce((acc, el) => acc + (el?.offsetHeight || 0), 0)
|
|
@@ -217,7 +233,7 @@ class RangeBuckets {
|
|
|
217
233
|
|
|
218
234
|
dropBottom() {
|
|
219
235
|
//console.log("DROP BOTTOM!")
|
|
220
|
-
if(this.buckets.length
|
|
236
|
+
if(this.buckets.length === 0) throw new Error('impossible to drop from empty')
|
|
221
237
|
const droppedBucket = this.buckets[this.buckets.length - 1]
|
|
222
238
|
const height = droppedBucket.domElements.reduce((acc, el) => acc + el?.offsetHeight, 0)
|
|
223
239
|
this.buckets.pop()
|
|
@@ -225,6 +241,18 @@ class RangeBuckets {
|
|
|
225
241
|
return height
|
|
226
242
|
}
|
|
227
243
|
|
|
244
|
+
freeze() {
|
|
245
|
+
for(const bucket of this.buckets) {
|
|
246
|
+
bucket.freeze()
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
unfreeze() {
|
|
251
|
+
for(const bucket of this.buckets) {
|
|
252
|
+
bucket.unfreeze()
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
|
|
228
256
|
dispose() {
|
|
229
257
|
for(const bucket of this.buckets) {
|
|
230
258
|
bucket.dispose()
|
package/lib/freezable.js
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { ref, onUnmounted, getCurrentInstance, unref, reactive, isRef, shallowRef, watch, computed } from 'vue'
|
|
2
|
+
|
|
3
|
+
export default function freezable(source) {
|
|
4
|
+
if(typeof window === 'undefined') return {
|
|
5
|
+
output: source,
|
|
6
|
+
changed: ref(false),
|
|
7
|
+
freeze() {},
|
|
8
|
+
unfreeze() {}
|
|
9
|
+
}
|
|
10
|
+
const frozen = ref(false)
|
|
11
|
+
function freeze() {
|
|
12
|
+
if(frozen.value) return
|
|
13
|
+
frozen.value = JSON.parse(JSON.stringify(source.value))
|
|
14
|
+
}
|
|
15
|
+
function unfreeze() {
|
|
16
|
+
frozen.value = false
|
|
17
|
+
}
|
|
18
|
+
const output = computed(() => {
|
|
19
|
+
if(frozen.value) return frozen.value
|
|
20
|
+
return source.value
|
|
21
|
+
})
|
|
22
|
+
const changed = computed(() => JSON.stringify(output.value) !== JSON.stringify(source.value))
|
|
23
|
+
return { output, freeze, unfreeze, changed }
|
|
24
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@live-change/dao-vue3",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.23",
|
|
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-stack/issues"
|
|
11
11
|
},
|
|
12
12
|
"dependencies": {
|
|
13
|
-
"@live-change/dao": "0.8.
|
|
13
|
+
"@live-change/dao": "^0.8.23"
|
|
14
14
|
},
|
|
15
15
|
"type": "module",
|
|
16
16
|
"description": "Vue.js integration for live-change dao",
|
|
@@ -32,5 +32,5 @@
|
|
|
32
32
|
"scripts": {
|
|
33
33
|
"compileTests": "webpack test/*.js tests-bundle.js"
|
|
34
34
|
},
|
|
35
|
-
"gitHead": "
|
|
35
|
+
"gitHead": "581260523149a1e596f08e878b5f4fabeaba26ea"
|
|
36
36
|
}
|