-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 {
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,
return state
}
- const state: CustomInspectorState = {
+ const state: CustomInspectorState | ComponentCustomState = {
state: Object.keys(store.$state).map((key) => ({
editable: true,
key,
}))
}
+ if (store._customProperties.size) {
+ state.customProperties = Array.from(store._customProperties).map((key) => ({
+ editable: true,
+ key,
+ // @ts-expect-error
+ value: store[key],
+ }))
+ }
+
return state
}
PINIA_ROOT_ID,
PINIA_ROOT_LABEL,
} from './formatting'
-import { toastMessage } from './utils'
+import { isPinia, toastMessage } from './utils'
/**
* Registered stores used for devtools.
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')
}
store
)
- return { ...wrappedActions }
+ // avoid returning to not display them in devtools
+ Object.assign(store, wrappedActions)
}
+import { Pinia } from '../rootStore'
+
/**
* Shows a toast or console.log
*
console.log(piniaMessage)
}
}
+
+export function isPinia(o: any): o is Pinia {
+ return '_a' in o && 'install' in o
+}
const store: Store<Id, S, G, A> = reactive(
assign(
- {},
+ __DEV__ && IS_CLIENT
+ ? // devtools custom properties
+ {
+ _customProperties: markRaw(new Set<string>()),
+ }
+ : {},
partialStore,
// using this means no new properties can be added as state
computedFromState(pinia.state, $id),
// 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
*/
_getters?: string[]
+ /**
+ * Used by devtools plugin to retrieve properties added with plugins. Removed in production.
+ *
+ * @internal
+ */
+ _customProperties: Set<string>
+
/**
* Applies a state patch to current state. Allows passing nested values
*