diff --git a/packages/pinia-orm/src/composables/useStoreActions.ts b/packages/pinia-orm/src/composables/useStoreActions.ts index 6c0021b77..eae8cb327 100644 --- a/packages/pinia-orm/src/composables/useStoreActions.ts +++ b/packages/pinia-orm/src/composables/useStoreActions.ts @@ -5,17 +5,17 @@ import type { DataStore } from './useDataStore' export function useStoreActions (query?: Query) { return { save (this: DataStore, records: Elements, triggerQueryAction = true) { - Object.assign(this.data, records) + this.data = Object.assign({}, this.data, records) if (triggerQueryAction && query) { query.newQuery(this.$id).save(Object.values(records)) } }, insert (this: DataStore, records: Elements, triggerQueryAction = true) { - Object.assign(this.data, records) + this.data = Object.assign({}, this.data, records) if (triggerQueryAction && query) { query.newQuery(this.$id).insert(Object.values(records)) } }, update (this: DataStore, records: Elements, triggerQueryAction = true) { - Object.assign(this.data, records) + this.data = Object.assign({}, this.data, records) if (triggerQueryAction && query) { query.newQuery(this.$id).update(Object.values(records)) } }, @@ -27,7 +27,14 @@ export function useStoreActions (query?: Query) { destroy (this: DataStore, ids: (string | number)[], triggerQueryAction = true): void { if (triggerQueryAction && query) { query.newQuery(this.$id).newQuery(this.$id).destroy(ids) - } else { ids.forEach(id => delete this.data[id]) } + } else { + ids.forEach(id => delete this.data[id]) + // Trigger Vue 2 reactivity + /* v8 ignore next 3 */ + if (this.data.__ob__) { + this.data.__ob__.dep.notify() + } + } }, /** * Commit `delete` change to the store. @@ -35,7 +42,14 @@ export function useStoreActions (query?: Query) { delete (this: DataStore, ids: (string | number)[], triggerQueryAction = true): void { if (triggerQueryAction && query) { query.whereId(ids).delete() - } else { ids.forEach(id => delete this.data[id]) } + } else { + ids.forEach(id => delete this.data[id]) + // Trigger Vue 2 reactivity + /* v8 ignore next 3 */ + if (this.data.__ob__) { + this.data.__ob__.dep.notify() + } + } }, flush (this: DataStore, _records?: Elements, triggerQueryAction = true): void { this.data = {} diff --git a/packages/pinia-orm/tests/feature/reactivity/reactivity.spec.ts b/packages/pinia-orm/tests/feature/reactivity/reactivity.spec.ts new file mode 100644 index 000000000..85ff8ae28 --- /dev/null +++ b/packages/pinia-orm/tests/feature/reactivity/reactivity.spec.ts @@ -0,0 +1,129 @@ +import { describe, expect, it } from 'vitest' +import { computed } from 'vue-demi' + +import { Model, useRepo } from '../../../src' +import { Attr, Str } from '../../../src/decorators' +import { fillState } from '../../helpers' + +describe('feature/reactivity/reactivity', () => { + class User extends Model { + static entity = 'users' + + @Attr() id!: any + @Str('') name!: string + } + + it('check save reactivity', () => { + const userRepo = useRepo(User) + + const allUsers = computed(() => userRepo.all()) + + expect(allUsers.value).toEqual([]) + + userRepo.save([ + { id: 1, name: 'John Doe' }, + { id: 2, name: 'Jane Doe' }, + { id: 3, name: 'Johnny Doe' } + ]) + + expect(allUsers.value).toEqual([ + { id: 1, name: 'John Doe' }, + { id: 2, name: 'Jane Doe' }, + { id: 3, name: 'Johnny Doe' } + ]) + }) + + it('check insert reactivity', () => { + const userRepo = useRepo(User) + + const allUsers = computed(() => userRepo.all()) + + expect(allUsers.value).toEqual([]) + + userRepo.insert({ id: 1, name: 'John Doe' }) + + expect(allUsers.value).toEqual([ + { id: 1, name: 'John Doe' } + ]) + }) + + it('check update reactivity', () => { + const userRepo = useRepo(User) + + fillState({ + users: { + 1: { id: 1, name: 'John Doe' }, + 2: { id: 2, name: 'Jane Doe' }, + 3: { id: 3, name: 'Johnny Doe' } + } + }) + + const allUsers = computed(() => userRepo.all()) + + expect(allUsers.value).toEqual([ + { id: 1, name: 'John Doe' }, + { id: 2, name: 'Jane Doe' }, + { id: 3, name: 'Johnny Doe' } + ]) + + userRepo.where('name', 'Jane Doe').update({ name: 'Jane Doe Updated' }) + + expect(allUsers.value).toEqual([ + { id: 1, name: 'John Doe' }, + { id: 2, name: 'Jane Doe Updated' }, + { id: 3, name: 'Johnny Doe' } + ]) + }) + + it('check destroy reactivity', () => { + const userRepo = useRepo(User) + + fillState({ + users: { + 1: { id: 1, name: 'John Doe' }, + 2: { id: 2, name: 'Jane Doe' }, + 3: { id: 3, name: 'Johnny Doe' } + } + }) + + const allUsers = computed(() => userRepo.all()) + + expect(allUsers.value).toEqual([ + { id: 1, name: 'John Doe' }, + { id: 2, name: 'Jane Doe' }, + { id: 3, name: 'Johnny Doe' } + ]) + + userRepo.destroy([2, 3]) + + expect(allUsers.value).toEqual([ + { id: 1, name: 'John Doe' } + ]) + }) + + it('check delete reactivity', () => { + const userRepo = useRepo(User) + + fillState({ + users: { + 1: { id: 1, name: 'John Doe' }, + 2: { id: 2, name: 'Jane Doe' }, + 3: { id: 3, name: 'Johnny Doe' } + } + }) + + const allUsers = computed(() => userRepo.all()) + + expect(allUsers.value).toEqual([ + { id: 1, name: 'John Doe' }, + { id: 2, name: 'Jane Doe' }, + { id: 3, name: 'Johnny Doe' } + ]) + + userRepo.where('name', 'Jane Doe').orWhere('name', 'Johnny Doe').delete() + + expect(allUsers.value).toEqual([ + { id: 1, name: 'John Doe' } + ]) + }) +})