1
0
Эх сурвалжийг харах

fix(plugin): occasional memory leak when dynamic slot ui with provide ui

charlie 3 жил өмнө
parent
commit
cc04718576

+ 6 - 0
libs/src/LSPlugin.core.ts

@@ -19,6 +19,7 @@ import {
   cleanInjectedScripts,
   safeSnakeCase,
   injectTheme,
+  cleanInjectedUI,
 } from './helpers'
 import * as pluginHelpers from './helpers'
 import Debug from 'debug'
@@ -1476,6 +1477,11 @@ class LSPluginCore
     this._hostMountedActor.resolve()
   }
 
+  _forceCleanInjectedUI(id: string) {
+    if (!id) return
+    return cleanInjectedUI(id)
+  }
+
   get registeredPlugins(): Map<PluginLocalIdentity, PluginLocal> {
     return this._registeredPlugins
   }

+ 13 - 0
libs/src/helpers.ts

@@ -203,6 +203,9 @@ export function setupInjectedStyle(
 
 const injectedUIEffects = new Map<string, () => void>()
 
+// @ts-ignore
+window.__injectedUIEffects = injectedUIEffects
+
 export function setupInjectedUI(
   this: PluginLocal,
   ui: UIOptions,
@@ -380,6 +383,16 @@ export function setupInjectedUI(
   return teardownUI
 }
 
+export function cleanInjectedUI(
+  id: string
+) {
+  if (!injectedUIEffects.has(id)) return
+  const clean = injectedUIEffects.get(id)
+  try { clean() } catch (e) {
+    console.warn('[CLEAN Injected UI] ', id, e)
+  }
+}
+
 export function cleanInjectedScripts(this: PluginLocal) {
   const scripts = document.head.querySelectorAll(`script[data-ref=${this.id}]`)
 

+ 12 - 4
src/main/frontend/components/plugins.cljs

@@ -791,15 +791,23 @@
 (rum/defc hook-ui-slot
   ([type payload] (hook-ui-slot type payload nil))
   ([type payload opts]
-   (let [rs (util/rand-str 8)
-         id (str "slot__" rs)]
+   (let [rs      (util/rand-str 8)
+         id      (str "slot__" rs)
+         *el-ref (rum/use-ref nil)]
+
      (rum/use-effect!
       (fn []
-        (plugin-handler/hook-plugin-app type {:slot id :payload payload} nil)
-        #())
+        (let [el (rum/deref *el-ref)]
+          (plugin-handler/hook-plugin-app type {:slot id :payload payload} nil)
+          #(when-let [uis (seq (.querySelectorAll el "[data-injected-ui]"))]
+             (doseq [^js el uis]
+               (when-let [id (.-injectedUi (.-dataset el))]
+                 (js/LSPluginCore._forceCleanInjectedUI id))))))
       [id])
+
      [:div.lsp-hook-ui-slot
       (merge opts {:id            id
+                   :ref           *el-ref
                    :on-mouse-down (fn [e] (util/stop e))})])))
 
 (rum/defc ui-item-renderer