import { beforeEach, describe, it, expect, vi } from 'vitest'
import { createPinia, defineStore, setActivePinia } from '../src'
-import { computed, nextTick, ref, watch } from 'vue'
+import { computed, inject, nextTick, ref, watch, version } from 'vue'
function expectType<T>(_value: T): void {}
expect(store.counter).toBe(2)
expect(counter.value).toBe(2)
})
+
+ // TODO:
+ it.todo('can use app level injections', async () => {
+ const pinia = createPinia()
+ setActivePinia(pinia)
+ const useStore = defineStore('id', () => {
+ const injected = ref(inject('hello', 'nope'))
+
+ return { injected }
+ })
+
+ const store = useStore()
+ expect(store.injected).toBe('pinia')
+ })
})
-import {
- App,
- EffectScope,
- getCurrentInstance,
- inject,
- InjectionKey,
- Ref,
-} from 'vue-demi'
+import { App, EffectScope, inject, InjectionKey, Ref } from 'vue-demi'
+// FIXME: move to vue-demi when available
+import { hasInjectionContext } from 'vue'
import {
StateTree,
PiniaCustomProperties,
* Get the currently active pinia if there is any.
*/
export const getActivePinia = () =>
- (getCurrentInstance() && inject(piniaSymbol)) || activePinia
+ (hasInjectionContext() && inject(piniaSymbol)) || activePinia
/**
* Every application must own its own pinia to be able to create stores
nextTick,
isVue2,
} from 'vue-demi'
+// FIXME: move to vue-demi when available
+import { hasInjectionContext } from 'vue'
import {
StateTree,
SubscriptionCallback,
import { patchObject } from './hmr'
import { addSubscription, triggerSubscriptions, noop } from './subscriptions'
+const fallbackRunWithContext = (fn: Function) => fn()
+
type _ArrayType<AT> = AT extends Array<infer T> ? T : never
function mergeReactiveObjects<
// creating infinite loops.
pinia._s.set($id, store)
+ const runWithContext =
+ (pinia._a && pinia._a.runWithContext) || fallbackRunWithContext
+
// TODO: idea create skipSerialize that marks properties as non serializable and they are skipped
const setupStore = pinia._e.run(() => {
scope = effectScope()
- return scope.run(() => setup())
+ return runWithContext(() => scope.run(() => setup()))
})!
// overwrite existing actions to support $onAction
}
function useStore(pinia?: Pinia | null, hot?: StoreGeneric): StoreGeneric {
- const currentInstance = getCurrentInstance()
+ const hasContext = hasInjectionContext()
pinia =
// in test mode, ignore the argument provided as we can always retrieve a
// pinia instance with getActivePinia()
(__TEST__ && activePinia && activePinia._testing ? null : pinia) ||
- (currentInstance && inject(piniaSymbol, null))
+ (hasContext ? inject(piniaSymbol, null) : null)
if (pinia) setActivePinia(pinia)
if (__DEV__ && !activePinia) {
pinia._s.delete(hotId)
}
- // save stores in instances to access them devtools
- if (
- __DEV__ &&
- IS_CLIENT &&
- currentInstance &&
- currentInstance.proxy &&
- // avoid adding stores that are just built for hot module replacement
- !hot
- ) {
- const vm = currentInstance.proxy
- const cache = '_pStores' in vm ? vm._pStores! : (vm._pStores = {})
- cache[id] = store
+ if (__DEV__ && IS_CLIENT) {
+ const currentInstance = getCurrentInstance()
+ // save stores in instances to access them devtools
+ if (
+ currentInstance &&
+ currentInstance.proxy &&
+ // avoid adding stores that are just built for hot module replacement
+ !hot
+ ) {
+ const vm = currentInstance.proxy
+ const cache = '_pStores' in vm ? vm._pStores! : (vm._pStores = {})
+ cache[id] = store
+ }
}
// StoreGeneric cannot be casted towards Store
-import { computed, createApp, markRaw, Ref } from 'vue'
+import { computed, createApp, inject, markRaw, Ref } from 'vue'
import App from './App.vue'
import { createPinia } from 'pinia'
import { router } from './router'
RouteLocationNormalized,
RouteLocationNormalizedLoaded,
} from 'vue-router'
+import { useCounter } from './stores/counterSetup'
const pinia = createPinia()
// }
}
-createApp(App).use(router).use(pinia).mount('#app')
+const app = createApp(App).use(pinia).use(router).provide('hello', 'injections')
+
+app.mount('#app')
+
+console.log(
+ 'hello',
+ app.runWithContext(() => inject('hello'))
+)
+
+const store = useCounter()
-import { computed, toRefs, reactive } from 'vue'
+import { computed, toRefs, reactive, inject } from 'vue'
import { acceptHMRUpdate, defineStore } from 'pinia'
+import { useRoute } from 'vue-router'
const delay = (t: number) => new Promise((r) => setTimeout(r, t))
numbers: [] as number[],
})
+ const route = useRoute()
+ console.log('route in setup', route)
+
+ console.log('injection', inject('hello'))
+
const double = computed(() => state.n * 2)
function increment(amount = 1) {
"resolveJsonModule": true,
"esModuleInterop": true,
"lib": ["esnext", "dom"],
- "types": ["vite/client"]
- }
+ "types": ["vite/client"],
+ "paths": {
+ "pinia": ["../pinia/src/index.ts"]
+ }
+ },
// "include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue"]
}
export default defineConfig({
plugins: [vue(), copyPiniaPlugin()],
define: {
- // __DEV__: 'true',
+ __DEV__: 'true',
// __BROWSER__: 'true',
__TEST__: 'false',
},
// alias: {
// '@vue/composition-api': 'vue-demi',
// },
- dedupe: ['vue-demi', 'vue'],
+ dedupe: ['vue-demi', 'vue', 'pinia'],
+ alias: {
+ pinia: path.resolve(__dirname, '../pinia/src/index.ts'),
+ },
},
optimizeDeps: {
exclude: ['vue-demi', '@vueuse/shared', '@vueuse/core', 'pinia'],