]> git.ipfire.org Git - thirdparty/vuejs/pinia.git/commitdiff
feat(devtools): display custom properties
authorEduardo San Martin Morote <posva13@gmail.com>
Thu, 17 Jun 2021 10:56:46 +0000 (12:56 +0200)
committerEduardo San Martin Morote <posva13@gmail.com>
Thu, 17 Jun 2021 10:57:33 +0000 (12:57 +0200)
src/devtools/formatting.ts
src/devtools/plugin.ts
src/devtools/utils.ts
src/store.ts
src/types.ts

index b37bb403a651415038c537f43bd9397ec81d8909..892bbe24202f36c7fc1aed7e02203e464a4b16ad 100644 (file)
@@ -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
 }
 
index 09171ae82ede8b8ca5325130e0f220bcd92d7c17..93c8285bfbca974f94e7d4fc2b1b260a2a70306f 100644 (file)
@@ -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)
 }
index bb577f61245271879f80a287d7ec58eb5cfc177d..07718b668c6c778f22c4e4e84787d5a541616d1d 100644 (file)
@@ -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
+}
index 0a7964c24e2986317d31018f6b3a1b1ee67cef0f..101701693b72c9f23d8bf03856568c7693e1a123 100644 (file)
@@ -349,7 +349,12 @@ function buildStoreToUse<
 
   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),
@@ -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
index 608d7180e703883b989e53ae26995ecdca203b0a..7c29becdf4ccc1808122caccc873047341af7095 100644 (file)
@@ -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<string>
+
   /**
    * Applies a state patch to current state. Allows passing nested values
    *