From: Eduardo San Martin Morote Date: Thu, 17 Jun 2021 10:56:46 +0000 (+0200) Subject: feat(devtools): display custom properties X-Git-Tag: v2.0.0-beta.3~2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=fd901cdf34d035289067a189a874b7e2df1cbe3e;p=thirdparty%2Fvuejs%2Fpinia.git feat(devtools): display custom properties --- diff --git a/src/devtools/formatting.ts b/src/devtools/formatting.ts index b37bb403..892bbe24 100644 --- a/src/devtools/formatting.ts +++ b/src/devtools/formatting.ts @@ -1,7 +1,12 @@ -import { CustomInspectorNode, CustomInspectorState } from '@vue/devtools-api' +import { + ComponentCustomState, + CustomInspectorNode, + CustomInspectorState, +} from '@vue/devtools-api' import { Store, MutationType } from '../types' import { DebuggerEvent } from 'vue' import { Pinia } from '../rootStore' +import { isPinia } from './utils' export function formatDisplay(display: string) { return { @@ -31,7 +36,7 @@ export function formatStoreForInspectorTree( export function formatStoreForInspectorState( store: Store | Pinia ): CustomInspectorState { - if (!('$id' in store)) { + if (isPinia(store)) { const state: CustomInspectorState = { state: Object.keys(store.state.value).map((storeId) => ({ editable: true, @@ -54,7 +59,7 @@ export function formatStoreForInspectorState( return state } - const state: CustomInspectorState = { + const state: CustomInspectorState | ComponentCustomState = { state: Object.keys(store.$state).map((key) => ({ editable: true, key, @@ -73,6 +78,15 @@ export function formatStoreForInspectorState( })) } + if (store._customProperties.size) { + state.customProperties = Array.from(store._customProperties).map((key) => ({ + editable: true, + key, + // @ts-expect-error + value: store[key], + })) + } + return state } diff --git a/src/devtools/plugin.ts b/src/devtools/plugin.ts index 09171ae8..93c8285b 100644 --- a/src/devtools/plugin.ts +++ b/src/devtools/plugin.ts @@ -23,7 +23,7 @@ import { PINIA_ROOT_ID, PINIA_ROOT_LABEL, } from './formatting' -import { toastMessage } from './utils' +import { isPinia, toastMessage } from './utils' /** * Registered stores used for devtools. @@ -201,9 +201,15 @@ function addDevtools(app: App, store: Store) { const { path } = payload - if ('$id' in inspectedStore) { + if (!isPinia(store)) { // access only the state - path.unshift('$state') + if ( + path.length !== 1 || + !store._customProperties.has(path[0]) || + path[0] in store.$state + ) { + path.unshift('$state') + } } else { path.unshift('state', 'value') } @@ -403,5 +409,6 @@ export function devtoolsPlugin< store ) - return { ...wrappedActions } + // avoid returning to not display them in devtools + Object.assign(store, wrappedActions) } diff --git a/src/devtools/utils.ts b/src/devtools/utils.ts index bb577f61..07718b66 100644 --- a/src/devtools/utils.ts +++ b/src/devtools/utils.ts @@ -1,3 +1,5 @@ +import { Pinia } from '../rootStore' + /** * Shows a toast or console.log * @@ -20,3 +22,7 @@ export function toastMessage( console.log(piniaMessage) } } + +export function isPinia(o: any): o is Pinia { + return '_a' in o && 'install' in o +} diff --git a/src/store.ts b/src/store.ts index 0a7964c2..10170169 100644 --- a/src/store.ts +++ b/src/store.ts @@ -349,7 +349,12 @@ function buildStoreToUse< const store: Store = reactive( assign( - {}, + __DEV__ && IS_CLIENT + ? // devtools custom properties + { + _customProperties: markRaw(new Set()), + } + : {}, partialStore, // using this means no new properties can be added as state computedFromState(pinia.state, $id), @@ -370,8 +375,17 @@ function buildStoreToUse< // apply all plugins pinia._p.forEach((extender) => { - // @ts-expect-error: conflict between A and ActionsTree - assign(store, extender({ store, app: pinia._a, pinia, options })) + if (__DEV__ && IS_CLIENT) { + // @ts-expect-error: conflict between A and ActionsTree + const extensions = extender({ store, app: pinia._a, pinia, options }) + Object.keys(extensions || {}).forEach((key) => + store._customProperties.add(key) + ) + assign(store, extensions) + } else { + // @ts-expect-error: conflict between A and ActionsTree + assign(store, extender({ store, app: pinia._a, pinia, options })) + } }) return store diff --git a/src/types.ts b/src/types.ts index 608d7180..7c29becd 100644 --- a/src/types.ts +++ b/src/types.ts @@ -242,6 +242,13 @@ export interface StoreWithState< */ _getters?: string[] + /** + * Used by devtools plugin to retrieve properties added with plugins. Removed in production. + * + * @internal + */ + _customProperties: Set + /** * Applies a state patch to current state. Allows passing nested values *