Skip to content

Commit

Permalink
fix: outlive components lifespan
Browse files Browse the repository at this point in the history
Fix #370

BREAKING_CHANGE: It's now necessary to create a pinia instance and
install it:
  ```js
  import { createPinia } from 'pinia'

  const pinia = createPinia()
  Vue.use(pinia)
  ```
  The `pinia` instance can be passed to `useStore(pinia)` when called
  outside of a `setup()` function. Check the SSR section of the docs for
  more details.

BREAKING_CHANGE: `setActiveReq()` and `getActiveReq()` have been
replaced with `setActivePinia()` and `getActivePinia()` respectively.
`setActivePinia()` can only be passed a `pinia` instance created with
`createPinia()`.

BREAKING_CHANGE: Since req as a parameter was replacetd with `pinia`,
`getRootState` is no longer necessary. Replace it with
`pinia.state.value` to **read and write** the root state`.

BREAKING_CHANGE: `PiniaSsr` is no longer necessary and has been removed.
  • Loading branch information
posva committed Mar 3, 2021
1 parent 281d8e2 commit f1d60f9
Show file tree
Hide file tree
Showing 2 changed files with 10 additions and 77 deletions.
14 changes: 4 additions & 10 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,16 @@
export { defineStore } from './store'
export {
setActiveReq,
setStateProvider,
getRootState,
setActivePinia,
createPinia,
Pinia,
PiniaStorePlugin,
PiniaCustomProperties,
createPinia,
setActivePinia,
getActivePinia,
} from './rootStore'
export { defineStore } from './store'
export {
StateTree,
Store,
StoreWithActions,
StoreWithGetters,
StoreWithActions,
StoreWithState,
} from './types'
export { PiniaSsr } from './ssrPlugin'

export { createStore } from './deprecated'
73 changes: 6 additions & 67 deletions src/rootStore.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,7 @@
import { InjectionKey, ref, Ref } from '@vue/composition-api'
import {
NonNullObject,
StateTree,
GenericStore,
StoreWithState,
StateDescriptor,
} from './types'
import { StateTree, StoreWithState, StateDescriptor } from './types'
import Vue, { PluginFunction, VueConstructor } from 'vue'

/**
* 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
import { IS_CLIENT } from './env'

/**
* The api needs more work we must be able to use the store easily in any
Expand All @@ -28,47 +14,6 @@ export const storesMap = new WeakMap<
Map<string, [StoreWithState<string, StateTree>, StateDescriptor<StateTree>]>
>()

/**
* A state provider allows to set how states are stored for hydration. e.g. setting a property on a context, getting a property from window
*/
interface StateProvider {
(): Record<string, StateTree>
}

/**
* Map of initial states used for hydration
*/
export const stateProviders = new WeakMap<NonNullObject, StateProvider>()

export function setStateProvider(stateProvider: StateProvider) {
stateProviders.set(getActiveReq(), stateProvider)
}

export function getInitialState(id: string): StateTree | undefined {
const provider = stateProviders.get(getActiveReq())
return provider && provider()[id]
}

/**
* Gets the root state of all active stores. This is useful when reporting an application crash by
* retrieving the problematic state and send it to your error tracking service.
* @param req request key
*/
export function getRootState(req: NonNullObject): Record<string, StateTree> {
const stores = storesMap.get(req)
if (!stores) return {}
const rootState = {} as Record<string, StateTree>

// forEach is the only one that also works on IE11
stores.forEach((store) => {
rootState[store.$id] = store.$state
})

return rootState
}

// ----------------------------------

/**
* Properties that are added to every store by `pinia.use()`
*/
Expand Down Expand Up @@ -153,9 +98,7 @@ export function createPinia(): Pinia {
// app.config.globalProperties.$pinia = pinia
Vue.mixin({
beforeCreate() {
const options = this.$options as any
// Make pinia accessible everywhere through this.$pinia
// FIXME: typings
const options = this.$options
if (options.pinia) {
// HACK: taken from provide(): https://github.com/vuejs/composition-api/blob/master/src/apis/inject.ts#L25
if (!(this as any)._provided) {
Expand All @@ -170,13 +113,9 @@ export function createPinia(): Pinia {
},
})

// only set the app on client for devtools
if (__BROWSER__ && IS_CLIENT) {
// setClientApp(app)
// this allows calling useStore() outside of a component setup after
// installing pinia's plugin
setActivePinia(pinia)
}
// this allows calling useStore() outside of a component setup after
// installing pinia's plugin
setActivePinia(pinia)

toBeInstalled.forEach((plugin) => _p.push(plugin.bind(null, pinia)))
},
Expand Down

0 comments on commit f1d60f9

Please sign in to comment.