-import { computed } from '@vue/composition-api'
+import { computed, nextTick, ref, watch } from '@vue/composition-api'
import Vue from 'vue'
import { defineStore, setActivePinia, createPinia, Pinia } from '../src'
store.name = 'Ed'
expect(upperCased.value).toBe('ED')
})
+
+ // it('watch', () => {
+ // setActivePinia(createPinia())
+ // defineStore({
+ // id: 'main',
+ // state: () => ({
+ // name: 'Eduardo',
+ // counter: 0,
+ // }),
+ // })()
+ // })
+
+ it('state can be watched', async () => {
+ const store = useStore()
+ const spy = jest.fn()
+ watch(() => store.name, spy)
+ expect(spy).not.toHaveBeenCalled()
+ store.name = 'Ed'
+ await nextTick()
+ expect(spy).toHaveBeenCalledTimes(1)
+ })
+
+ it('unwraps refs', () => {
+ const name = ref('Eduardo')
+ const counter = ref(0)
+ const double = computed({
+ get: () => counter.value * 2,
+ set(val) {
+ counter.value = val / 2
+ },
+ })
+
+ setActivePinia(createPinia())
+ const useStore = defineStore({
+ id: 'main',
+ state: () => ({
+ name,
+ counter,
+ double,
+ }),
+ })
+
+ const store = useStore()
+
+ expect(store.name).toBe('Eduardo')
+ name.value = 'Ed'
+ expect(store.name).toBe('Ed')
+ store.name = 'Edu'
+ expect(store.name).toBe('Edu')
+ })
})
onUnmounted,
InjectionKey,
provide,
+ WatchOptions,
+ UnwrapRef,
} from '@vue/composition-api'
import {
StateTree,
subscriptions.forEach((callback) => {
callback(
{ storeName: $id, type, payload: partialState },
- pinia.state.value[$id]
+ pinia.state.value[$id] as UnwrapRef<S>
)
})
}
// watch here to link the subscription to the current active instance
// e.g. inside the setup of a component
const stopWatcher = watch(
- () => pinia.state.value[$id],
+ () => pinia.state.value[$id] as UnwrapRef<S>,
(state) => {
if (isListening) {
callback({ storeName: $id, type: '🧩 in place', payload: {} }, state)
+import { UnwrapRef } from '@vue/composition-api'
import { Pinia } from './rootStore'
/**
* Callback of a subscription
*/
export type SubscriptionCallback<S> = (
- mutation: { storeName: string; type: string; payload: DeepPartial<S> },
- state: S
+ // TODO: make type an enumeration
+ // TODO: payload should be optional
+ mutation: {
+ storeName: string
+ type: MutationType
+
+ payload: DeepPartial<UnwrapRef<S>>
+ },
+ state: UnwrapRef<S>
) => void
/**
/**
* State of the Store. Setting it will replace the whole state.
*/
- $state: S
+ $state: UnwrapRef<S>
/**
* Private property defining the pinia the store is attached to.
// has the actions without the context (this) for typings
A
> = StoreWithState<Id, S> &
- S &
+ UnwrapRef<S> &
StoreWithGetters<G> &
StoreWithActions<A> &
PiniaCustomProperties<Id, S, G, A>
*/
export type GettersTree<S extends StateTree> = Record<
string,
- ((state: S) => any) | (() => any)
+ ((state: UnwrapRef<S>) => any) | (() => any)
>
/**
/**
* Optional object of getters.
*/
- getters?: G & ThisType<S & StoreWithGetters<G> & PiniaCustomProperties>
+ getters?: G &
+ ThisType<UnwrapRef<S> & StoreWithGetters<G> & PiniaCustomProperties>
/**
* Optional object of actions.
*/
actions?: A &
ThisType<
A &
- S &
+ UnwrapRef<S> &
StoreWithState<Id, S> &
StoreWithGetters<G> &
PiniaCustomProperties
--- /dev/null
+import { computed, ref } from 'vue'
+import { defineStore, expectType } from './'
+
+const name = ref('Eduardo')
+const counter = ref(0)
+const double = computed({
+ get: () => counter.value * 2,
+ set(val) {
+ counter.value = val / 2
+ },
+})
+
+const useStore = defineStore({
+ id: 'name',
+ state: () => ({
+ n: 0,
+ name,
+ double,
+ counter,
+ }),
+
+ getters: {
+ myDouble: (state) => {
+ expectType<number>(state.double)
+ expectType<number>(state.counter)
+ return state.n * 2
+ },
+ other(): undefined {
+ expectType<number>(this.double)
+ expectType<number>(this.counter)
+ return undefined
+ },
+ },
+
+ actions: {
+ some() {
+ expectType<number>(this.$state.double)
+ expectType<number>(this.$state.counter)
+ expectType<number>(this.double)
+ expectType<number>(this.counter)
+ },
+ },
+})
+
+const store = useStore()
+
+expectType<number>(store.$state.counter)
+expectType<number>(store.$state.double)