]> git.ipfire.org Git - thirdparty/vuejs/pinia.git/commitdiff
refactor: change Subscription Array to Subscription Set (#2887)
authorWick <wick.linxunjie@gmail.com>
Tue, 1 Jul 2025 09:57:12 +0000 (17:57 +0800)
committerGitHub <noreply@github.com>
Tue, 1 Jul 2025 09:57:12 +0000 (11:57 +0200)
This reduces the size of the library a bit and should avoid the error of adding the same subscription twice

packages/pinia/src/store.ts
packages/pinia/src/subscriptions.ts

index 4d10c690d532f1a4ee7fffd0b39ef55c41862d1a..7ec0e17aeb0178dbf1755ee60e1c444de356886f 100644 (file)
@@ -53,7 +53,7 @@ import { addSubscription, triggerSubscriptions, noop } from './subscriptions'
 
 const fallbackRunWithContext = (fn: () => unknown) => fn()
 
-type _ArrayType<AT> = AT extends Array<infer T> ? T : never
+type _SetType<AT> = AT extends Set<infer T> ? T : never
 
 /**
  * Marks a function as an action for `$onAction`
@@ -267,8 +267,8 @@ function createSetupStore<
   // internal state
   let isListening: boolean // set to true at the end
   let isSyncListening: boolean // set to true at the end
-  let subscriptions: SubscriptionCallback<S>[] = []
-  let actionSubscriptions: StoreOnActionListener<Id, S, G, A>[] = []
+  let subscriptions: Set<SubscriptionCallback<S>> = new Set()
+  let actionSubscriptions: Set<StoreOnActionListener<Id, S, G, A>> = new Set()
   let debuggerEvents: DebuggerEvent[] | DebuggerEvent
   const initialState = pinia.state.value[$id] as UnwrapRef<S> | undefined
 
@@ -350,8 +350,8 @@ function createSetupStore<
 
   function $dispose() {
     scope.stop()
-    subscriptions = []
-    actionSubscriptions = []
+    subscriptions.clear()
+    actionSubscriptions.clear()
     pinia._s.delete($id)
   }
 
@@ -371,13 +371,13 @@ function createSetupStore<
       setActivePinia(pinia)
       const args = Array.from(arguments)
 
-      const afterCallbackList: Array<(resolvedReturn: any) => any> = []
-      const onErrorCallbackList: Array<(error: unknown) => unknown> = []
-      function after(callback: _ArrayType<typeof afterCallbackList>) {
-        afterCallbackList.push(callback)
+      const afterCallbackSet: Set<(resolvedReturn: any) => any> = new Set()
+      const onErrorCallbackSet: Set<(error: unknown) => unknown> = new Set()
+      function after(callback: _SetType<typeof afterCallbackSet>) {
+        afterCallbackSet.add(callback)
       }
-      function onError(callback: _ArrayType<typeof onErrorCallbackList>) {
-        onErrorCallbackList.push(callback)
+      function onError(callback: _SetType<typeof onErrorCallbackSet>) {
+        onErrorCallbackSet.add(callback)
       }
 
       // @ts-expect-error
@@ -394,24 +394,24 @@ function createSetupStore<
         ret = fn.apply(this && this.$id === $id ? this : store, args)
         // handle sync errors
       } catch (error) {
-        triggerSubscriptions(onErrorCallbackList, error)
+        triggerSubscriptions(onErrorCallbackSet, error)
         throw error
       }
 
       if (ret instanceof Promise) {
         return ret
           .then((value) => {
-            triggerSubscriptions(afterCallbackList, value)
+            triggerSubscriptions(afterCallbackSet, value)
             return value
           })
           .catch((error) => {
-            triggerSubscriptions(onErrorCallbackList, error)
+            triggerSubscriptions(onErrorCallbackSet, error)
             return Promise.reject(error)
           })
       }
 
       // trigger after callbacks
-      triggerSubscriptions(afterCallbackList, ret)
+      triggerSubscriptions(afterCallbackSet, ret)
       return ret
     } as MarkedAction<Fn>
 
index 49b2d7174d18d0d821eba10fe981d59161cf0e8e..7c33f11c1c26959f5c7a8c698563da485436d852 100644 (file)
@@ -4,19 +4,16 @@ import { _Method } from './types'
 export const noop = () => {}
 
 export function addSubscription<T extends _Method>(
-  subscriptions: T[],
+  subscriptions: Set<T>,
   callback: T,
   detached?: boolean,
   onCleanup: () => void = noop
 ) {
-  subscriptions.push(callback)
+  subscriptions.add(callback)
 
   const removeSubscription = () => {
-    const idx = subscriptions.indexOf(callback)
-    if (idx > -1) {
-      subscriptions.splice(idx, 1)
-      onCleanup()
-    }
+    const isDel = subscriptions.delete(callback)
+    isDel && onCleanup()
   }
 
   if (!detached && getCurrentScope()) {
@@ -27,10 +24,10 @@ export function addSubscription<T extends _Method>(
 }
 
 export function triggerSubscriptions<T extends _Method>(
-  subscriptions: T[],
+  subscriptions: Set<T>,
   ...args: Parameters<T>
 ) {
-  subscriptions.slice().forEach((callback) => {
+  subscriptions.forEach((callback) => {
     callback(...args)
   })
 }