Skip to content

Commit 5bf1ffe

Browse files
committed
feat(refs): unbind missing refs in collections
1 parent 5079a35 commit 5bf1ffe

File tree

5 files changed

+43
-14
lines changed

5 files changed

+43
-14
lines changed

src/index.js

+13-3
Original file line numberDiff line numberDiff line change
@@ -95,11 +95,21 @@ function bindCollection ({
9595
})
9696
},
9797
modified: ({ oldIndex, newIndex, doc }) => {
98-
array.splice(oldIndex, 1)
99-
array.splice(newIndex, 0, createSnapshot(doc))
100-
// TODO replace listeners of nested refs
10198
const subs = arraySubs.splice(oldIndex, 1)[0]
10299
arraySubs.splice(newIndex, 0, subs)
100+
array.splice(oldIndex, 1)
101+
const snapshot = createSnapshot(doc)
102+
array.splice(newIndex, 0, snapshot)
103+
const [data, refs] = extractRefs(snapshot)
104+
subscribeToRefs({
105+
data,
106+
refs,
107+
subs,
108+
target: array,
109+
key: newIndex,
110+
depth: 0,
111+
resolve
112+
})
103113
},
104114
removed: ({ oldIndex }) => {
105115
array.splice(oldIndex, 1)

test/collection.spec.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ test('add elements', async () => {
3333

3434
test('delets items', async () => {
3535
await collection.add({ text: 'foo' })
36-
await collection.doc(vm.items[0].id).delete()
36+
await collection.doc(new Key(vm.items[0].id)).delete()
3737
expect(vm.items).toEqual([])
3838
})
3939

test/helpers/mock.js

+12-6
Original file line numberDiff line numberDiff line change
@@ -69,14 +69,14 @@ export class DocumentReference {
6969
Object.assign(this.data, data)
7070
this.exists = true
7171
this.cb(new DocumentSnapshot(null, this.id, this.data, true))
72-
return this.collection._modify(this.id, this.data)
72+
return this.collection._modify(this.id, this.data, this)
7373
}
7474

7575
async set (data) {
7676
this.data = { ...data }
7777
this.exists = true
7878
this.cb(new DocumentSnapshot(null, this.id, this.data, true))
79-
return this.collection._modify(this.id, this.data)
79+
return this.collection._modify(this.id, this.data, this)
8080
}
8181
}
8282

@@ -130,12 +130,12 @@ class CollectionReference {
130130

131131
doc (id) {
132132
id = id || new Key()
133-
return (this.data[id.v] = this.data[id.v] || new DocumentReference({
133+
return this.data[id.v] || new DocumentReference({
134134
collection: this,
135135
id,
136136
data: {},
137137
index: Object.keys(this.data).length
138-
}))
138+
})
139139
}
140140

141141
async _remove (id) {
@@ -151,10 +151,16 @@ class CollectionReference {
151151
ref.data = null
152152
}
153153

154-
async _modify (id, data) {
154+
async _modify (id, data, ref) {
155+
let type = 'modified'
156+
if (!this.data[id.v]) {
157+
ref.index = Object.keys(this.data).length
158+
this.data[id.v] = ref
159+
type = 'added'
160+
}
155161
this.cb({
156162
docChanges: [{
157-
type: 'modified',
163+
type,
158164
doc: new DocumentSnapshot(null, id, data),
159165
oldIndex: this.data[id.v].index,
160166
newIndex: this.data[id.v].index

test/refs-collections.spec.js

+16-3
Original file line numberDiff line numberDiff line change
@@ -4,20 +4,21 @@ import {
44
tick,
55
delay,
66
delayUpdate,
7+
Key,
78
spyUnbind,
89
Vue
910
} from './helpers'
1011

1112
Vue.use(Vuefire)
1213

13-
let vm, collection, a, b
14+
let vm, collection, a, b, first
1415
beforeEach(async () => {
1516
a = db.collection().doc()
1617
b = db.collection().doc()
1718
await a.update({ isA: true })
1819
await b.update({ isB: true })
1920
collection = db.collection()
20-
await collection.add({ ref: a })
21+
first = await collection.add({ ref: a })
2122
await collection.add({ ref: b })
2223

2324
vm = new Vue({
@@ -108,7 +109,19 @@ test('unbinds refs when items are removed', async () => {
108109
await vm.$bind('items', collection)
109110
expect(spyA).toHaveBeenCalledTimes(0)
110111

111-
await collection.doc(a.id).delete()
112+
await collection.doc(new Key(vm.items[0].id)).delete()
113+
expect(spyA).toHaveBeenCalledTimes(1)
114+
115+
spyA.mockRestore()
116+
})
117+
118+
test('unbinds refs when items are modified', async () => {
119+
const spyA = spyUnbind(a)
120+
await vm.$bind('items', collection)
121+
expect(spyA).toHaveBeenCalledTimes(0)
122+
123+
await first.set({ b })
124+
112125
expect(spyA).toHaveBeenCalledTimes(1)
113126

114127
spyA.mockRestore()

test/unbind.spec.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ Vue.use(Vuefire)
1010
let collection, document, vm
1111
beforeEach(async () => {
1212
collection = db.collection()
13-
document = collection.doc()
13+
document = db.collection().doc()
1414
vm = new Vue({
1515
// purposely set items as null
1616
// but it's a good practice to set it to an empty array

0 commit comments

Comments
 (0)