@live-change/db-store-localstorage 0.6.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.
- package/index.js +1 -0
- package/lib/Store.js +416 -0
- package/lib/storage.js +158 -0
- package/package.json +34 -0
- package/tests/broadcast-object-changes.js +80 -0
- package/tests/broadcast-range-changes.js +168 -0
- package/tests/limited-range-observable.js +176 -0
- package/tests/limited-reverse-range-observable.js +175 -0
- package/tests/object-observable.js +68 -0
- package/tests/range-observable.js +140 -0
- package/tests/reverse-range-observable.js +139 -0
- package/tests/store-non-reactive.js +120 -0
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
const test = require('tape')
|
|
2
|
+
|
|
3
|
+
require('fake-indexeddb/auto.js')
|
|
4
|
+
const idb = require('idb')
|
|
5
|
+
const Store = require('../lib/Store.js')
|
|
6
|
+
|
|
7
|
+
test("store range observable", t => {
|
|
8
|
+
t.plan(5)
|
|
9
|
+
|
|
10
|
+
let store
|
|
11
|
+
|
|
12
|
+
t.test("create store", async t => {
|
|
13
|
+
t.plan(1)
|
|
14
|
+
store = new Store('test-range-observable', 'test', 'local')
|
|
15
|
+
await store.open()
|
|
16
|
+
t.pass('store created')
|
|
17
|
+
})
|
|
18
|
+
|
|
19
|
+
t.test("put objects", async t => {
|
|
20
|
+
t.plan(1)
|
|
21
|
+
await store.put({ v: 1, id: 'a' })
|
|
22
|
+
await store.put({ v: 3, id: 'c' })
|
|
23
|
+
t.pass('objects written')
|
|
24
|
+
})
|
|
25
|
+
|
|
26
|
+
let nextValueResolve
|
|
27
|
+
let gotNextValue
|
|
28
|
+
const getNextValue = () => {
|
|
29
|
+
if(gotNextValue) {
|
|
30
|
+
gotNextValue = false
|
|
31
|
+
return rangeObservable.list
|
|
32
|
+
}
|
|
33
|
+
return new Promise((resolve, reject) => nextValueResolve = resolve)
|
|
34
|
+
}
|
|
35
|
+
let rangeObservable
|
|
36
|
+
const rangeObserver = (signal, value, ...rest) => {
|
|
37
|
+
console.log("SIGNAL", signal, value, ...rest)
|
|
38
|
+
gotNextValue = true
|
|
39
|
+
if(nextValueResolve) nextValueResolve(rangeObservable.list)
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
t.test("observe range [a,z]", t => {
|
|
43
|
+
t.plan(6)
|
|
44
|
+
rangeObservable = store.rangeObservable({ gte: 'a', lte: 'z' })
|
|
45
|
+
rangeObservable.observe(rangeObserver)
|
|
46
|
+
let values
|
|
47
|
+
t.test("get values", async t => {
|
|
48
|
+
t.plan(1)
|
|
49
|
+
values = await getNextValue()
|
|
50
|
+
t.deepEqual(values, [{v: 1, id: 'a'}, {v: 3, id: 'c'}], 'range value')
|
|
51
|
+
})
|
|
52
|
+
|
|
53
|
+
t.test("remove object 'a' from observed range", async t => {
|
|
54
|
+
t.plan(1)
|
|
55
|
+
await store.delete('a')
|
|
56
|
+
let values = await getNextValue()
|
|
57
|
+
t.deepEqual(values, [ { v: 3, id: 'c' } ], 'range value' )
|
|
58
|
+
})
|
|
59
|
+
|
|
60
|
+
t.test("add object 'a' to observed range", async t => {
|
|
61
|
+
t.plan(1)
|
|
62
|
+
await store.put({ id: 'a', v: 4 })
|
|
63
|
+
let values = await getNextValue()
|
|
64
|
+
t.deepEqual(values, [ { v: 4, id: 'a' }, { v: 3, id: 'c' } ], 'range value' )
|
|
65
|
+
})
|
|
66
|
+
|
|
67
|
+
t.test("add object 'b' to observed range", async t => {
|
|
68
|
+
t.plan(1)
|
|
69
|
+
await store.put({ id: 'b', v: 5 })
|
|
70
|
+
let values = await getNextValue()
|
|
71
|
+
t.deepEqual(values, [ { v: 4, id: 'a' }, { v: 5, id: 'b' }, { v: 3, id: 'c' } ], 'range value' )
|
|
72
|
+
})
|
|
73
|
+
|
|
74
|
+
t.test("add object 'd' to observed range", async t => {
|
|
75
|
+
t.plan(1)
|
|
76
|
+
await store.put({ id: 'd', v: 6 })
|
|
77
|
+
let values = await getNextValue()
|
|
78
|
+
t.deepEqual(values, [ { v: 4, id: 'a' }, { v: 5, id: 'b' }, { v: 3, id: 'c' }, { v: 6, id: 'd' } ], 'range value' )
|
|
79
|
+
})
|
|
80
|
+
|
|
81
|
+
t.test("unobserve range", async t => {
|
|
82
|
+
t.plan(1)
|
|
83
|
+
rangeObservable.unobserve(rangeObserver)
|
|
84
|
+
t.pass('unobserved')
|
|
85
|
+
})
|
|
86
|
+
})
|
|
87
|
+
|
|
88
|
+
t.test("observe range (a,d)", t => {
|
|
89
|
+
t.plan(6)
|
|
90
|
+
rangeObservable = store.rangeObservable({ gt: 'a', lt: 'd' })
|
|
91
|
+
rangeObservable.observe(rangeObserver)
|
|
92
|
+
|
|
93
|
+
let values
|
|
94
|
+
|
|
95
|
+
t.test("get values", async t => {
|
|
96
|
+
t.plan(1)
|
|
97
|
+
values = await getNextValue()
|
|
98
|
+
t.deepEqual(values, [ { v: 5, id: 'b' }, { v: 3, id: 'c' } ], 'range value' )
|
|
99
|
+
})
|
|
100
|
+
|
|
101
|
+
t.test("remove object 'd' outside observed range", async t => {
|
|
102
|
+
t.plan(1)
|
|
103
|
+
await store.delete('d')
|
|
104
|
+
t.pass('deleted')
|
|
105
|
+
})
|
|
106
|
+
|
|
107
|
+
t.test("remove object 'a' outside observed range", async t => {
|
|
108
|
+
t.plan(1)
|
|
109
|
+
await store.delete('a')
|
|
110
|
+
t.pass('deleted')
|
|
111
|
+
})
|
|
112
|
+
|
|
113
|
+
t.test("add object 'ab' to observed range", async t => {
|
|
114
|
+
t.plan(1)
|
|
115
|
+
await store.put({ id: 'ab', v: 7 })
|
|
116
|
+
let values = await getNextValue()
|
|
117
|
+
t.deepEqual(values, [ { v: 7, id: 'ab' }, { v: 5, id: 'b' }, { v: 3, id: 'c' } ], 'range value' )
|
|
118
|
+
})
|
|
119
|
+
|
|
120
|
+
t.test("remove object 'ab' from observed range", async t => {
|
|
121
|
+
t.plan(1)
|
|
122
|
+
await store.delete('ab')
|
|
123
|
+
let values = await getNextValue()
|
|
124
|
+
t.deepEqual(values, [ { v: 5, id: 'b' }, { v: 3, id: 'c' } ], 'range value' )
|
|
125
|
+
})
|
|
126
|
+
|
|
127
|
+
t.test("unobserve range", async t => {
|
|
128
|
+
t.plan(1)
|
|
129
|
+
rangeObservable.unobserve(rangeObserver)
|
|
130
|
+
t.pass('unobserved')
|
|
131
|
+
})
|
|
132
|
+
})
|
|
133
|
+
|
|
134
|
+
t.test("close database", async t => {
|
|
135
|
+
await store.close()
|
|
136
|
+
t.pass('closed')
|
|
137
|
+
t.end()
|
|
138
|
+
})
|
|
139
|
+
|
|
140
|
+
})
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
const test = require('tape')
|
|
2
|
+
|
|
3
|
+
require('fake-indexeddb/auto.js')
|
|
4
|
+
const idb = require('idb')
|
|
5
|
+
const Store = require('../lib/Store.js')
|
|
6
|
+
|
|
7
|
+
test("store reverse range observable", t => {
|
|
8
|
+
t.plan(5)
|
|
9
|
+
|
|
10
|
+
let store
|
|
11
|
+
|
|
12
|
+
t.test("create store", async t => {
|
|
13
|
+
t.plan(1)
|
|
14
|
+
store = new Store('test-reverse-range-observable', 'test', 'local')
|
|
15
|
+
await store.open()
|
|
16
|
+
t.pass('store created')
|
|
17
|
+
})
|
|
18
|
+
|
|
19
|
+
t.test("put objects", async t => {
|
|
20
|
+
t.plan(1)
|
|
21
|
+
await store.put({ v: 1, id: 'a' })
|
|
22
|
+
await store.put({ v: 3, id: 'c' })
|
|
23
|
+
t.pass('objects written')
|
|
24
|
+
})
|
|
25
|
+
|
|
26
|
+
let nextValueResolve
|
|
27
|
+
let gotNextValue
|
|
28
|
+
const getNextValue = () => {
|
|
29
|
+
if(gotNextValue) {
|
|
30
|
+
gotNextValue = false
|
|
31
|
+
return rangeObservable.list
|
|
32
|
+
}
|
|
33
|
+
return new Promise((resolve, reject) => nextValueResolve = resolve)
|
|
34
|
+
}
|
|
35
|
+
let rangeObservable
|
|
36
|
+
const rangeObserver = (signal, value, ...rest) => {
|
|
37
|
+
console.log("SIGNAL", signal, value, ...rest)
|
|
38
|
+
gotNextValue = true
|
|
39
|
+
if(nextValueResolve) nextValueResolve(rangeObservable.list)
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
t.test("observe reverse range [z,a]", t => {
|
|
43
|
+
t.plan(6)
|
|
44
|
+
rangeObservable = store.rangeObservable({ gte: 'a', lte: 'z', reverse: true })
|
|
45
|
+
rangeObservable.observe(rangeObserver)
|
|
46
|
+
let values
|
|
47
|
+
|
|
48
|
+
t.test("get values", async t => {
|
|
49
|
+
t.plan(1)
|
|
50
|
+
values = await getNextValue()
|
|
51
|
+
t.deepEqual(values, [{v: 3, id: 'c'}, {v: 1, id: 'a'}], 'range value')
|
|
52
|
+
})
|
|
53
|
+
|
|
54
|
+
t.test("remove object 'a' from observed range", async t => {
|
|
55
|
+
t.plan(1)
|
|
56
|
+
await store.delete('a')
|
|
57
|
+
let values = await getNextValue()
|
|
58
|
+
t.deepEqual(values, [ { v: 3, id: 'c' } ], 'range value' )
|
|
59
|
+
})
|
|
60
|
+
|
|
61
|
+
t.test("add object 'a' to observed range", async t => {
|
|
62
|
+
t.plan(1)
|
|
63
|
+
await store.put({ id: 'a', v: 4 })
|
|
64
|
+
let values = await getNextValue()
|
|
65
|
+
t.deepEqual(values, [ { v: 3, id: 'c' }, { v: 4, id: 'a' } ], 'range value' )
|
|
66
|
+
})
|
|
67
|
+
|
|
68
|
+
t.test("add object 'b' to observed range", async t => {
|
|
69
|
+
t.plan(1)
|
|
70
|
+
await store.put({ id: 'b', v: 5 })
|
|
71
|
+
let values = await getNextValue()
|
|
72
|
+
t.deepEqual(values, [ { v: 3, id: 'c' }, { v: 5, id: 'b' }, { v: 4, id: 'a' } ], 'range value' )
|
|
73
|
+
})
|
|
74
|
+
|
|
75
|
+
t.test("add object 'd' to observed range", async t => {
|
|
76
|
+
t.plan(1)
|
|
77
|
+
await store.put({ id: 'd', v: 6 })
|
|
78
|
+
let values = await getNextValue()
|
|
79
|
+
t.deepEqual(values, [ { v: 6, id: 'd' }, { v: 3, id: 'c' }, { v: 5, id: 'b' }, { v: 4, id: 'a' } ], 'range value' )
|
|
80
|
+
})
|
|
81
|
+
|
|
82
|
+
t.test("unobserve range", async t => {
|
|
83
|
+
t.plan(1)
|
|
84
|
+
rangeObservable.unobserve(rangeObserver)
|
|
85
|
+
t.pass('unobserved')
|
|
86
|
+
})
|
|
87
|
+
})
|
|
88
|
+
|
|
89
|
+
t.test("observe reverse range (d, a)", t => {
|
|
90
|
+
t.plan(6)
|
|
91
|
+
rangeObservable = store.rangeObservable({ gt: 'a', lt: 'd', reverse: true })
|
|
92
|
+
rangeObservable.observe(rangeObserver)
|
|
93
|
+
let values
|
|
94
|
+
t.test("get values", async t => {
|
|
95
|
+
t.plan(1)
|
|
96
|
+
values = await getNextValue()
|
|
97
|
+
t.deepEqual(values, [ { v: 3, id: 'c' }, { v: 5, id: 'b' } ], 'range value' )
|
|
98
|
+
})
|
|
99
|
+
|
|
100
|
+
t.test("remove object 'd' outside observed range", async t => {
|
|
101
|
+
t.plan(1)
|
|
102
|
+
await store.delete('d')
|
|
103
|
+
t.pass('deleted')
|
|
104
|
+
})
|
|
105
|
+
|
|
106
|
+
t.test("remove object 'a' outside observed range", async t => {
|
|
107
|
+
t.plan(1)
|
|
108
|
+
await store.delete('a')
|
|
109
|
+
t.pass('deleted')
|
|
110
|
+
})
|
|
111
|
+
|
|
112
|
+
t.test("add object 'ab' to observed range", async t => {
|
|
113
|
+
t.plan(1)
|
|
114
|
+
await store.put({ id: 'ab', v: 7 })
|
|
115
|
+
let values = await getNextValue()
|
|
116
|
+
t.deepEqual(values, [ { v: 3, id: 'c' }, { v: 5, id: 'b' }, { v: 7, id: 'ab' } ], 'range value' )
|
|
117
|
+
})
|
|
118
|
+
|
|
119
|
+
t.test("remove object 'ab' from observed range", async t => {
|
|
120
|
+
t.plan(1)
|
|
121
|
+
await store.delete('ab')
|
|
122
|
+
let values = await getNextValue()
|
|
123
|
+
t.deepEqual(values, [ { v: 3, id: 'c' }, { v: 5, id: 'b' } ], 'range value' )
|
|
124
|
+
})
|
|
125
|
+
|
|
126
|
+
t.test("unobserve range", async t => {
|
|
127
|
+
t.plan(1)
|
|
128
|
+
rangeObservable.unobserve(rangeObserver)
|
|
129
|
+
t.pass('unobserved')
|
|
130
|
+
})
|
|
131
|
+
})
|
|
132
|
+
|
|
133
|
+
t.test("close database", async t => {
|
|
134
|
+
await store.close()
|
|
135
|
+
t.pass('closed')
|
|
136
|
+
t.end()
|
|
137
|
+
})
|
|
138
|
+
|
|
139
|
+
})
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
const test = require('tape')
|
|
2
|
+
|
|
3
|
+
require('fake-indexeddb/auto.js')
|
|
4
|
+
const idb = require('idb')
|
|
5
|
+
const Store = require('../lib/Store.js')
|
|
6
|
+
|
|
7
|
+
test("store non-reactive properties", t => {
|
|
8
|
+
t.plan(3)
|
|
9
|
+
|
|
10
|
+
let store
|
|
11
|
+
t.test("create store", async t => {
|
|
12
|
+
t.plan(1)
|
|
13
|
+
store = new Store('test-non-reactive', 'test', 'local')
|
|
14
|
+
await new Promise(resolve => setTimeout(resolve, 1000))
|
|
15
|
+
await store.open()
|
|
16
|
+
t.pass('store created')
|
|
17
|
+
})
|
|
18
|
+
|
|
19
|
+
t.test("non reactive operations", t => {
|
|
20
|
+
t.plan(15)
|
|
21
|
+
|
|
22
|
+
t.test("put value", async t => {
|
|
23
|
+
t.plan(1)
|
|
24
|
+
await store.put({ id:'a', v: 1 })
|
|
25
|
+
t.pass('value written')
|
|
26
|
+
})
|
|
27
|
+
|
|
28
|
+
t.test("get value", async t => {
|
|
29
|
+
t.plan(1)
|
|
30
|
+
const v = await store.objectGet('a')
|
|
31
|
+
t.deepEqual(v, { v: 1, id: 'a' }, 'value read')
|
|
32
|
+
})
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
t.test("put another values", async t => {
|
|
36
|
+
t.plan(1)
|
|
37
|
+
await store.put({ id: 'c', v: 3 })
|
|
38
|
+
await store.put({ id: 'b', v: 2 })
|
|
39
|
+
t.pass('values written')
|
|
40
|
+
})
|
|
41
|
+
|
|
42
|
+
t.test("get range [a,c]", async t => {
|
|
43
|
+
t.plan(1)
|
|
44
|
+
let values = await store.rangeGet({ gte: 'a', lte: 'c' })
|
|
45
|
+
t.deepEqual(values, [ { v: 1, id: 'a' }, { v: 2, id: 'b' }, { v: 3, id: 'c' } ], 'range read' )
|
|
46
|
+
})
|
|
47
|
+
|
|
48
|
+
t.test("get reverse range [c,a]", async t => {
|
|
49
|
+
t.plan(1)
|
|
50
|
+
let values = await store.rangeGet({ gte: 'a', lte: 'c', reverse: true })
|
|
51
|
+
t.deepEqual(values, [ { v: 3, id: 'c' }, { v: 2, id: 'b' }, { v: 1, id: 'a' } ], 'range read' )
|
|
52
|
+
})
|
|
53
|
+
|
|
54
|
+
t.test("get range [a,c] with limit 2", async t => {
|
|
55
|
+
t.plan(1)
|
|
56
|
+
let values = await store.rangeGet({ gte: 'a', lte: 'c', limit: 2 })
|
|
57
|
+
t.deepEqual(values, [ { v: 1, id: 'a' }, { v: 2, id: 'b' } ], 'range read' )
|
|
58
|
+
})
|
|
59
|
+
|
|
60
|
+
t.test("get reverse range [c,a] with limit 2", async t => {
|
|
61
|
+
t.plan(1)
|
|
62
|
+
let values = await store.rangeGet({ gte: 'a', lte: 'c', reverse: true, limit: 2 })
|
|
63
|
+
t.deepEqual(values, [ { v: 3, id: 'c' }, { v: 2, id: 'b' } ], 'range read' )
|
|
64
|
+
})
|
|
65
|
+
|
|
66
|
+
t.test("get range (a,c]", async t => {
|
|
67
|
+
t.plan(1)
|
|
68
|
+
let values = await store.rangeGet({ gt: 'a', lte: 'c' })
|
|
69
|
+
t.deepEqual(values, [ { v: 2, id: 'b' }, { v: 3, id: 'c' } ], 'range read' )
|
|
70
|
+
})
|
|
71
|
+
|
|
72
|
+
t.test("get reverse range [c,a)", async t => {
|
|
73
|
+
t.plan(1)
|
|
74
|
+
let values = await store.rangeGet({ gt: 'a', lte: 'c', reverse: true })
|
|
75
|
+
t.deepEqual(values, [ { v: 3, id: 'c' }, { v: 2, id: 'b' }, ], 'range read' )
|
|
76
|
+
})
|
|
77
|
+
|
|
78
|
+
t.test("get range [a,c)", async t => {
|
|
79
|
+
t.plan(1)
|
|
80
|
+
let values = await store.rangeGet({ gte: 'a', lt: 'c' })
|
|
81
|
+
t.deepEqual(values, [ { v: 1, id: 'a' }, { v: 2, id: 'b' } ], 'range read' )
|
|
82
|
+
})
|
|
83
|
+
|
|
84
|
+
t.test("get reverse range (c,a]", async t => {
|
|
85
|
+
t.plan(1)
|
|
86
|
+
let values = await store.rangeGet({ gte: 'a', lt: 'c', reverse: true })
|
|
87
|
+
t.deepEqual(values, [ { v: 2, id: 'b' }, { v: 1, id: 'a' } ], 'range read' )
|
|
88
|
+
})
|
|
89
|
+
|
|
90
|
+
t.test("get range (a,c)", async t => {
|
|
91
|
+
t.plan(1)
|
|
92
|
+
let values = await store.rangeGet({ gt: 'a', lt: 'c' })
|
|
93
|
+
t.deepEqual(values, [ { v: 2, id: 'b' } ], 'range read' )
|
|
94
|
+
})
|
|
95
|
+
|
|
96
|
+
t.test("get reverse range (a,c)", async t => {
|
|
97
|
+
t.plan(1)
|
|
98
|
+
let values = await store.rangeGet({ gt: 'a', lt: 'c', reverse: true })
|
|
99
|
+
t.deepEqual(values, [ { v: 2, id: 'b' } ], 'range read' )
|
|
100
|
+
})
|
|
101
|
+
|
|
102
|
+
t.test("remove 'b'", async t => {
|
|
103
|
+
t.plan(1)
|
|
104
|
+
await store.delete('b')
|
|
105
|
+
t.pass("removed")
|
|
106
|
+
})
|
|
107
|
+
|
|
108
|
+
t.test("get range [a,c]", async t => {
|
|
109
|
+
t.plan(1)
|
|
110
|
+
let values = await store.rangeGet({ gte: 'a', lte: 'c' })
|
|
111
|
+
t.deepEqual(values, [ { v: 1, id: 'a' }, { v: 3, id: 'c' } ], 'range read' )
|
|
112
|
+
})
|
|
113
|
+
})
|
|
114
|
+
|
|
115
|
+
t.test("close database", async t => {
|
|
116
|
+
await store.close()
|
|
117
|
+
t.pass('closed')
|
|
118
|
+
t.end()
|
|
119
|
+
})
|
|
120
|
+
})
|