From: Eduardo San Martin Morote Date: Mon, 20 Jan 2020 17:52:10 +0000 (+0100) Subject: refactor: add rootStore.ts X-Git-Tag: 0.0.5~6 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=546e958a02fdfd73005b10aa75a89477e4de4f6d;p=thirdparty%2Fvuejs%2Fpinia.git refactor: add rootStore.ts --- diff --git a/src/index.ts b/src/index.ts index 7743f447..4ca79b37 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,8 +1,3 @@ -export { - createStore, - Store, - setActiveReq, - setStateProvider, - getRootState, -} from './store' -export { StateTree, StoreGetter } from './types' +export { createStore } from './store' +export { setActiveReq, setStateProvider, getRootState } from './rootStore' +export { StateTree, StoreGetter, Store } from './types' diff --git a/src/rootStore.ts b/src/rootStore.ts new file mode 100644 index 00000000..23142455 --- /dev/null +++ b/src/rootStore.ts @@ -0,0 +1,65 @@ +import { NonNullObject, StateTree, GenericStore } from './types' + +/** + * 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 + * be able to reset the store instance between requests on the server + */ + +export const storesMap = new WeakMap< + NonNullObject, + Record +>() + +/** + * 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 { + get(): Record + set(store: GenericStore): any +} + +/** + * Map of initial states used for hydration + */ +export const stateProviders = new WeakMap() + +export function setStateProvider(stateProvider: StateProvider) { + stateProviders.set(getActiveReq(), stateProvider) +} + +export function getInitialState(id: string): StateTree | undefined { + const provider = stateProviders.get(getActiveReq()) + return provider && provider.get()[id] +} + +export function setInitialState(store: GenericStore): void { + const provider = stateProviders.get(getActiveReq()) + if (provider) provider.set(store) +} + +/** + * 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 { + const stores = storesMap.get(req) + if (!stores) return {} + const rootState = {} as Record + + for (const store of Object.values(stores)) { + rootState[store.id] = store.state + } + + return rootState +} diff --git a/src/store.ts b/src/store.ts index d33989cd..7781332e 100644 --- a/src/store.ts +++ b/src/store.ts @@ -7,11 +7,18 @@ import { isPlainObject, StoreWithGetters, StoreGetter, - NonNullObject, StoreAction, + Store, StoreWithActions, } from './types' import { useStoreDevtools } from './devtools' +import { + getActiveReq, + setActiveReq, + storesMap, + getInitialState, + setInitialState, +} from './rootStore' const isClient = typeof window != 'undefined' @@ -34,23 +41,6 @@ function innerPatch( 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 - -// has the actions without the context (this) for typings -export type Store< - Id extends string, - S extends StateTree, - G extends Record>, - A extends Record -> = StoreWithState & StoreWithGetters & StoreWithActions - /** * Creates a store instance * @param id unique identifier of the store, like a name. eg: main, cart, user @@ -166,61 +156,6 @@ export function buildStore< return store } -/** - * 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 - * be able to reset the store instance between requests on the server - */ - -export const storesMap = new WeakMap< - NonNullObject, - Record> ->() - -/** - * 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 { - get(): Record - set(store: Store): any -} - -/** - * Map of initial states used for hydration - */ -export const stateProviders = new WeakMap() - -export function setStateProvider(stateProvider: StateProvider) { - stateProviders.set(getActiveReq(), stateProvider) -} - -function getInitialState(id: string): StateTree | undefined { - const provider = stateProviders.get(getActiveReq()) - return provider && provider.get()[id] -} - -function setInitialState(store: Store): void { - const provider = stateProviders.get(getActiveReq()) - if (provider) provider.set(store) -} - -/** - * 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 { - const stores = storesMap.get(req) - if (!stores) return {} - const rootState = {} as Record - - for (const store of Object.values(stores)) { - rootState[store.id] = store.state - } - - return rootState -} - /** * Creates a `useStore` function that retrieves the store instance * @param options @@ -245,7 +180,7 @@ export function createStore< let stores = storesMap.get(req) if (!stores) storesMap.set(req, (stores = {})) - let store = stores[id] + let store = stores[id] as Store if (!store) { stores[id] = store = buildStore( id, @@ -254,9 +189,7 @@ export function createStore< actions, getInitialState(id) ) - // save a reference to the initial state - // TODO: this implies that replacing the store cannot be done by the user on the server - setInitialState(store) + if (isClient) useStoreDevtools(store) } diff --git a/src/types.ts b/src/types.ts index f2cbd8ce..8a59e111 100644 --- a/src/types.ts +++ b/src/types.ts @@ -91,6 +91,21 @@ export type StoreWithActions> = { : never } +// has the actions without the context (this) for typings +export type Store< + Id extends string, + S extends StateTree, + G extends Record>, + A extends Record +> = StoreWithState & StoreWithGetters & StoreWithActions + +export type GenericStore = Store< + string, + StateTree, + Record>, + Record +> + export interface DevtoolHook { on( event: string,