Skip to content

Commit

Permalink
refactor: prefix store properties with $ (#254)
Browse files Browse the repository at this point in the history
BREAKING CHANGE: all store properties (`id`, `state`, `patch`, `subscribe`, and `reset`) are now prefixed with `$` to allow properties defined with the same type and avoid types breaking. Tip: you can refactor your whole codebase with F2 (or right-click + Refactor) on each of the store's properties
  • Loading branch information
posva authored Oct 9, 2020
1 parent 7c1899f commit 751f286
Show file tree
Hide file tree
Showing 14 changed files with 154 additions and 108 deletions.
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -237,16 +237,16 @@ To mutate the state you can either directly change something:
main.counter++
```

or call the method `patch` that allows you apply multiple changes at the same time with a partial `state` object:
or call the method `$patch` that allows you apply multiple changes at the same time with a partial `state` object:

```ts
main.patch({
main.$patch({
counter: -1,
name: 'Abalam',
})
```

The main difference here is that `patch` allows you to group multiple changes into one single entry in the devtools.
The main difference here is that `$patch` allows you to group multiple changes into one single entry in the devtools.

### Replacing the `state`

Expand Down
38 changes: 19 additions & 19 deletions __tests__/actions.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ describe('Actions', () => {
},

setFoo(foo: string) {
this.patch({ nested: { foo } })
this.$patch({ nested: { foo } })
},

combined() {
Expand All @@ -52,34 +52,34 @@ describe('Actions', () => {
actions: {
swap() {
const bStore = useB()
const b = bStore.state.b
bStore.state.b = this.state.a
this.state.a = b
const b = bStore.$state.b
bStore.$state.b = this.$state.a
this.$state.a = b
},
},
})

it('can use the store as this', () => {
const store = useStore()
expect(store.state.a).toBe(true)
expect(store.$state.a).toBe(true)
store.toggle()
expect(store.state.a).toBe(false)
expect(store.$state.a).toBe(false)
})

it('store is forced as the context', () => {
const store = useStore()
expect(store.state.a).toBe(true)
expect(store.$state.a).toBe(true)
store.toggle.call(null)
expect(store.state.a).toBe(false)
expect(store.$state.a).toBe(false)
})

it('can call other actions', () => {
const store = useStore()
expect(store.state.a).toBe(true)
expect(store.state.nested.foo).toBe('foo')
expect(store.$state.a).toBe(true)
expect(store.$state.nested.foo).toBe('foo')
store.combined()
expect(store.state.a).toBe(false)
expect(store.state.nested.foo).toBe('bar')
expect(store.$state.a).toBe(false)
expect(store.$state.nested.foo).toBe('bar')
})

it('supports being called between requests', () => {
Expand All @@ -91,12 +91,12 @@ describe('Actions', () => {
// simulate a different request
setActiveReq(req2)
const bStore = useB()
bStore.state.b = 'c'
bStore.$state.b = 'c'

aStore.swap()
expect(aStore.state.a).toBe('b')
expect(aStore.$state.a).toBe('b')
// a different instance of b store was used
expect(bStore.state.b).toBe('c')
expect(bStore.$state.b).toBe('c')
})

it('can force the req', () => {
Expand All @@ -105,13 +105,13 @@ describe('Actions', () => {
const aStore = useA(req1)

let bStore = useB(req2)
bStore.state.b = 'c'
bStore.$state.b = 'c'

aStore.swap()
expect(aStore.state.a).toBe('b')
expect(aStore.$state.a).toBe('b')
// a different instance of b store was used
expect(bStore.state.b).toBe('c')
expect(bStore.$state.b).toBe('c')
bStore = useB(req1)
expect(bStore.state.b).toBe('a')
expect(bStore.$state.b).toBe('a')
})
})
15 changes: 8 additions & 7 deletions __tests__/pinia/stores/cart.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { useUserStore } from './user'
export const useCartStore = defineStore({
id: 'cart',
state: () => ({
id: 2,
rawItems: [] as string[],
}),
getters: {
Expand All @@ -28,7 +29,7 @@ export const useCartStore = defineStore({

removeItem(name: string) {
const i = this.rawItems.indexOf(name)
if (i > -1) this.rawItems.splice(i, 1)
if (i > -1) this.$state.rawItems.splice(i, 1)
},

// TODO: use multiple stores
Expand All @@ -39,7 +40,7 @@ export const useCartStore = defineStore({

// console.log('Purchasing', this.items)
const n = this.items.length
this.state.rawItems = []
this.rawItems = []

return { amount: n, user: user.name }
},
Expand All @@ -50,23 +51,23 @@ export type CartStore = ReturnType<typeof useCartStore>

export function addItem(name: string) {
const store = useCartStore()
store.state.rawItems.push(name)
store.rawItems.push(name)
}

export function removeItem(name: string) {
const store = useCartStore()
const i = store.state.rawItems.indexOf(name)
if (i > -1) store.state.rawItems.splice(i, 1)
const i = store.rawItems.indexOf(name)
if (i > -1) store.rawItems.splice(i, 1)
}

export async function purchaseItems() {
const cart = useCartStore()
const user = useUserStore()
if (!user.state.name) return
if (!user.name) return

console.log('Purchasing', cart.items)
const n = cart.items.length
cart.state.rawItems = []
cart.rawItems = []

return n
}
6 changes: 3 additions & 3 deletions __tests__/pinia/stores/user.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ export const useUserStore = defineStore({
async login(user: string, password: string) {
const userData = await apiLogin(user, password)

this.patch({
this.$patch({
name: user,
...userData,
})
Expand All @@ -24,7 +24,7 @@ export const useUserStore = defineStore({
logout() {
this.login('a', 'b').then(() => {})

this.patch({
this.$patch({
name: '',
isAdmin: false,
})
Expand All @@ -46,7 +46,7 @@ export function logout() {

store.login('e', 'e').then(() => {})

store.patch({
store.$patch({
name: '',
isAdmin: false,
})
Expand Down
2 changes: 1 addition & 1 deletion __tests__/ssr.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@
* @jest-environment node
*/
import { createPinia } from '../src'
import { useCartStore } from './pinia/stores/cart'
import { createSSRApp, inject } from 'vue'
import { renderToString, ssrInterpolate } from '@vue/server-renderer'
import { useUserStore } from './pinia/stores/user'
import { useCartStore } from './pinia/stores/cart'

describe('SSR', () => {
const App = {
Expand Down
18 changes: 9 additions & 9 deletions __tests__/store.patch.spec.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { defineStore, setActiveReq } from '../src'

describe('store.patch', () => {
describe('store.$patch', () => {
const useStore = () => {
// create a new store
setActiveReq({})
Expand All @@ -18,8 +18,8 @@ describe('store.patch', () => {

it('patches a property without touching the rest', () => {
const store = useStore()
store.patch({ a: false })
expect(store.state).toEqual({
store.$patch({ a: false })
expect(store.$state).toEqual({
a: false,
nested: {
foo: 'foo',
Expand All @@ -30,16 +30,16 @@ describe('store.patch', () => {

it('patches a nested property without touching the rest', () => {
const store = useStore()
store.patch({ nested: { foo: 'bar' } })
expect(store.state).toEqual({
store.$patch({ nested: { foo: 'bar' } })
expect(store.$state).toEqual({
a: true,
nested: {
foo: 'bar',
a: { b: 'string' },
},
})
store.patch({ nested: { a: { b: 'hello' } } })
expect(store.state).toEqual({
store.$patch({ nested: { a: { b: 'hello' } } })
expect(store.$state).toEqual({
a: true,
nested: {
foo: 'bar',
Expand All @@ -50,8 +50,8 @@ describe('store.patch', () => {

it('patches multiple properties at the same time', () => {
const store = useStore()
store.patch({ a: false, nested: { foo: 'hello' } })
expect(store.state).toEqual({
store.$patch({ a: false, nested: { foo: 'hello' } })
expect(store.$state).toEqual({
a: false,
nested: {
foo: 'hello',
Expand Down
Loading

0 comments on commit 751f286

Please sign in to comment.