]> git.ipfire.org Git - thirdparty/vuejs/pinia.git/commitdiff
fix(devtools): group setup store sync actions mutations
authorEduardo San Martin Morote <posva13@gmail.com>
Wed, 14 Jun 2023 14:00:12 +0000 (16:00 +0200)
committerEduardo San Martin Morote <posva13@gmail.com>
Wed, 14 Jun 2023 14:00:12 +0000 (16:00 +0200)
packages/pinia/src/devtools/actions.ts
packages/pinia/src/devtools/plugin.ts
packages/pinia/src/devtools/utils.ts

index 17b586351c6e0db7cd215ad256e9754c85b86068..6ca91d304317d7a08d66c674b24008440b6aaadc 100644 (file)
@@ -2,6 +2,12 @@ import { Pinia } from '../rootStore'
 import { saveAs } from './file-saver'
 import { toastMessage } from './utils'
 
+/**
+ * This file contain devtools actions, they are not Pinia actions.
+ */
+
+// ---
+
 export function checkClipboardAccess() {
   if (!('clipboard' in navigator)) {
     toastMessage(`Your browser doesn't support the Clipboard API`, 'error')
index 1bafecfc2fb7669a7a442b369f90e4efd72b3996..646b395673675751697ab6fea18dedbcf2889765 100644 (file)
@@ -428,9 +428,6 @@ function addStoreToDevtools(app: DevtoolsApp, store: StoreGeneric) {
             groupId: activeAction,
           }
 
-          // reset for the next mutation
-          activeAction = undefined
-
           if (type === MutationType.patchFunction) {
             eventData.subtitle = '⤵️'
           } else if (type === MutationType.patchObject) {
@@ -510,7 +507,11 @@ let activeAction: number | undefined
  * @param store - store to patch
  * @param actionNames - list of actionst to patch
  */
-function patchActionForGrouping(store: StoreGeneric, actionNames: string[]) {
+function patchActionForGrouping(
+  store: StoreGeneric,
+  actionNames: string[],
+  wrapWithProxy: boolean
+) {
   // original actions of the store as they are given by pinia. We are going to override them
   const actions = actionNames.reduce((storeActions, actionName) => {
     // use toRaw to avoid tracking #541
@@ -520,23 +521,30 @@ function patchActionForGrouping(store: StoreGeneric, actionNames: string[]) {
 
   for (const actionName in actions) {
     store[actionName] = function () {
-      // setActivePinia(store._p)
       // the running action id is incremented in a before action hook
       const _actionId = runningActionId
-      const trackedStore = new Proxy(store, {
-        get(...args) {
-          activeAction = _actionId
-          return Reflect.get(...args)
-        },
-        set(...args) {
-          activeAction = _actionId
-          return Reflect.set(...args)
-        },
-      })
-      return actions[actionName].apply(
+      const trackedStore = wrapWithProxy
+        ? new Proxy(store, {
+            get(...args) {
+              activeAction = _actionId
+              return Reflect.get(...args)
+            },
+            set(...args) {
+              activeAction = _actionId
+              return Reflect.set(...args)
+            },
+          })
+        : store
+
+      // For Setup Stores we need https://github.com/tc39/proposal-async-context
+      activeAction = _actionId
+      const retValue = actions[actionName].apply(
         trackedStore,
         arguments as unknown as any[]
       )
+      // this is safer as async actions in Setup Stores would associate mutations done outside of the action
+      activeAction = undefined
+      return retValue
     }
   }
 }
@@ -556,29 +564,23 @@ export function devtoolsPlugin<
   }
 
   // detect option api vs setup api
-  if (options.state) {
-    store._isOptionsAPI = true
-  }
+  store._isOptionsAPI = !!options.state
+
+  patchActionForGrouping(
+    store as StoreGeneric,
+    Object.keys(options.actions),
+    store._isOptionsAPI
+  )
 
-  // only wrap actions in option-defined stores as this technique relies on
-  // wrapping the context of the action with a proxy
-  if (typeof options.state === 'function') {
+  // Upgrade the HMR to also update the new actions
+  const originalHotUpdate = store._hotUpdate
+  toRaw(store)._hotUpdate = function (newStore) {
+    originalHotUpdate.apply(this, arguments as any)
     patchActionForGrouping(
-      // @ts-expect-error: can cast the store...
-      store,
-      Object.keys(options.actions)
+      store as StoreGeneric,
+      Object.keys(newStore._hmrPayload.actions),
+      !!store._isOptionsAPI
     )
-
-    const originalHotUpdate = store._hotUpdate
-
-    // Upgrade the HMR to also update the new actions
-    toRaw(store)._hotUpdate = function (newStore) {
-      originalHotUpdate.apply(this, arguments as any)
-      patchActionForGrouping(
-        store as StoreGeneric,
-        Object.keys(newStore._hmrPayload.actions)
-      )
-    }
   }
 
   addStoreToDevtools(
index 07718b668c6c778f22c4e4e84787d5a541616d1d..f1df4cda1b47c3e42edcca4ca7521e42f76e25c4 100644 (file)
@@ -13,6 +13,7 @@ export function toastMessage(
   const piniaMessage = '🍍 ' + message
 
   if (typeof __VUE_DEVTOOLS_TOAST__ === 'function') {
+    // No longer available :(
     __VUE_DEVTOOLS_TOAST__(piniaMessage, type)
   } else if (type === 'error') {
     console.error(piniaMessage)