})()
}
+ const useB = createStore({
+ id: 'B',
+ state: () => ({ b: 'b' }),
+ })
+
+ const useA = createStore({
+ id: 'A',
+ state: () => ({ a: 'a' }),
+ actions: {
+ swap() {
+ const bStore = useB()
+ 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(false)
expect(store.state.nested.foo).toBe('bar')
})
+
+ it('supports being called between requests', () => {
+ const req1 = {}
+ const req2 = {}
+ setActiveReq(req1)
+ const aStore = useA()
+
+ // simulate a different request
+ setActiveReq(req2)
+ const bStore = useB()
+ bStore.state.b = 'c'
+
+ aStore.swap()
+ expect(aStore.state.a).toBe('b')
+ // a different instance of b store was used
+ expect(bStore.state.b).toBe('c')
+ })
})
})()
}
+ const useB = createStore({
+ id: 'B',
+ state: () => ({ b: 'b' }),
+ })
+
+ const useA = createStore({
+ id: 'A',
+ state: () => ({ a: 'a' }),
+ getters: {
+ fromB(state) {
+ const bStore = useB()
+ return state.a + ' ' + bStore.state.b
+ },
+ },
+ })
+
it('adds getters to the store', () => {
const store = useStore()
expect(store.upperCaseName.value).toBe('EDUARDO')
store.state.name = 'Ed'
expect(store.upperCaseName.value).toBe('ED')
})
+
+ it('supports changing between requests', () => {
+ const req1 = {}
+ const req2 = {}
+ setActiveReq(req1)
+ const aStore = useA()
+
+ // simulate a different request
+ setActiveReq(req2)
+ const bStore = useB()
+ bStore.state.b = 'c'
+
+ aStore.state.a = 'b'
+ expect(aStore.fromB.value).toBe('b b')
+ })
})
isPlainObject,
StoreWithGetters,
StoreGetter,
+ NonNullObject,
} from './types'
import { useStoreDevtools } from './devtools'
return target
}
+/**
+ * setActiveReq must be called to handle SSR at the top of functions like `fetch`, `setup`, `serverPrefetch` and others
+ */
+export let activeReq: NonNullObject = {}
+export const setActiveReq = (req: NonNullObject | undefined) =>
+ req && (activeReq = req)
+
+export const getActiveReq = () => activeReq
+
export interface StoreAction {
(...args: any[]): any
}
initialState?: S | undefined
): Store<Id, S, G, A> {
const state: Ref<S> = ref(initialState || buildState())
+ const _r = getActiveReq()
let isListening = true
let subscriptions: SubscriptionCallback<S>[] = []
const storeWithState: StoreWithState<Id, S> = {
id,
+ _r,
// it is replaced below by a getter
state: state.value,
reset,
}
- // @ts-ignore we have to build it
- const computedGetters: StoreWithGetters<S, G> = {}
+ const computedGetters: StoreWithGetters<S, G> = {} as StoreWithGetters<S, G>
for (const getterName in getters) {
- const method = getters[getterName]
- // @ts-ignore
- computedGetters[getterName] = computed<ReturnType<typeof method>>(() =>
- getters[getterName](state.value)
- )
+ computedGetters[getterName] = computed(() => {
+ setActiveReq(_r)
+ return getters[getterName](state.value)
+ }) as StoreWithGetters<S, G>[typeof getterName]
+ }
+
+ const wrappedActions: StoreWithActions<A> = {} as StoreWithActions<A>
+ for (const actionName in actions) {
+ wrappedActions[actionName] = function() {
+ setActiveReq(_r)
+ // eslint-disable-next-line
+ return actions[actionName].apply(this, arguments as unknown as any[])
+ } as StoreWithActions<A>[typeof actionName]
}
const store: Store<Id, S, G, A> = {
...storeWithState,
...computedGetters,
- ...((actions as unknown) as StoreWithActions<A>),
+ ...wrappedActions,
}
// make state access invisible
return store
}
-type NonNullObject = Record<any, any>
-
-/**
- * setActiveReq must be called to handle SSR at the top of functions like `fetch`, `setup`, `serverPrefetch` and others
- */
-export let activeReq: NonNullObject = {}
-export const setActiveReq = (req: NonNullObject | undefined) =>
- req && (activeReq = req)
-
-export const getActiveReq = () => activeReq
-
/**
* The api needs more work we must be able to use the store easily in any
* function by calling `useStore` to get the store Instance and we also need to