Просмотр исходного кода

enhance: use `EventName` on window's `once` and remove listener before calling handler (#10246)

* Refactor

* Revert event => void

* Change file
Tony 1 год назад
Родитель
Сommit
080b6e1272

+ 5 - 0
.changes/fix-once-handler-throw.md

@@ -0,0 +1,5 @@
+---
+'@tauri-apps/api': 'patch:bug'
+---
+
+Fix `once` doesn't detached after one callback if event handler throws

+ 5 - 0
.changes/once-event-name.md

@@ -0,0 +1,5 @@
+---
+'@tauri-apps/api': 'patch:enhance'
+---
+
+Use `EventName` on `Window`, `Webview` and `WebviewWindow`'s `once` so you can get auto complete for tauri's built-in events

Разница между файлами не показана из-за своего большого размера
+ 0 - 0
core/tauri/scripts/bundle.global.js


+ 2 - 1
tooling/api/src/event.ts

@@ -152,8 +152,9 @@ async function once<T>(
   return listen<T>(
     event,
     (eventData) => {
+      // eslint-disable-next-line @typescript-eslint/no-floating-promises
+      _unlisten(event, eventData.id)
       handler(eventData)
-      _unlisten(event, eventData.id).catch(() => {})
     },
     options
   )

+ 12 - 9
tooling/api/src/webview.ts

@@ -225,11 +225,11 @@ class Webview {
     handler: EventCallback<T>
   ): Promise<UnlistenFn> {
     if (this._handleTauriEvent(event, handler)) {
-      return Promise.resolve(() => {
+      return () => {
         // eslint-disable-next-line security/detect-object-injection
         const listeners = this.listeners[event]
         listeners.splice(listeners.indexOf(handler), 1)
-      })
+      }
     }
     return listen(event, handler, {
       target: { kind: 'Webview', label: this.label }
@@ -255,13 +255,16 @@ class Webview {
    * @returns A promise resolving to a function to unlisten to the event.
    * Note that removing the listener is required if your listener goes out of scope e.g. the component is unmounted.
    */
-  async once<T>(event: string, handler: EventCallback<T>): Promise<UnlistenFn> {
+  async once<T>(
+    event: EventName,
+    handler: EventCallback<T>
+  ): Promise<UnlistenFn> {
     if (this._handleTauriEvent(event, handler)) {
-      return Promise.resolve(() => {
+      return () => {
         // eslint-disable-next-line security/detect-object-injection
         const listeners = this.listeners[event]
         listeners.splice(listeners.indexOf(handler), 1)
-      })
+      }
     }
     return once(event, handler, {
       target: { kind: 'Webview', label: this.label }
@@ -290,7 +293,7 @@ class Webview {
           payload
         })
       }
-      return Promise.resolve()
+      return
     }
     return emit(event, payload)
   }
@@ -322,7 +325,7 @@ class Webview {
           payload
         })
       }
-      return Promise.resolve()
+      return
     }
     return emitTo(target, event, payload)
   }
@@ -331,10 +334,10 @@ class Webview {
   _handleTauriEvent<T>(event: string, handler: EventCallback<T>): boolean {
     if (localTauriEvents.includes(event)) {
       if (!(event in this.listeners)) {
-        // eslint-disable-next-line
+        // eslint-disable-next-line security/detect-object-injection
         this.listeners[event] = [handler]
       } else {
-        // eslint-disable-next-line
+        // eslint-disable-next-line security/detect-object-injection
         this.listeners[event].push(handler)
       }
       return true

+ 8 - 5
tooling/api/src/webviewWindow.ts

@@ -155,11 +155,11 @@ class WebviewWindow {
     handler: EventCallback<T>
   ): Promise<UnlistenFn> {
     if (this._handleTauriEvent(event, handler)) {
-      return Promise.resolve(() => {
+      return () => {
         // eslint-disable-next-line security/detect-object-injection
         const listeners = this.listeners[event]
         listeners.splice(listeners.indexOf(handler), 1)
-      })
+      }
     }
     return listen(event, handler, {
       target: { kind: 'WebviewWindow', label: this.label }
@@ -185,13 +185,16 @@ class WebviewWindow {
    * @returns A promise resolving to a function to unlisten to the event.
    * Note that removing the listener is required if your listener goes out of scope e.g. the component is unmounted.
    */
-  async once<T>(event: string, handler: EventCallback<T>): Promise<UnlistenFn> {
+  async once<T>(
+    event: EventName,
+    handler: EventCallback<T>
+  ): Promise<UnlistenFn> {
     if (this._handleTauriEvent(event, handler)) {
-      return Promise.resolve(() => {
+      return () => {
         // eslint-disable-next-line security/detect-object-injection
         const listeners = this.listeners[event]
         listeners.splice(listeners.indexOf(handler), 1)
-      })
+      }
     }
     return once(event, handler, {
       target: { kind: 'WebviewWindow', label: this.label }

+ 18 - 15
tooling/api/src/window.ts

@@ -105,7 +105,7 @@ class CloseRequestedEvent {
   id: number
   private _preventDefault = false
 
-  constructor(event: Event<null>) {
+  constructor(event: Event<unknown>) {
     this.event = event.event
     this.id = event.id
   }
@@ -373,11 +373,11 @@ class Window {
     handler: EventCallback<T>
   ): Promise<UnlistenFn> {
     if (this._handleTauriEvent(event, handler)) {
-      return Promise.resolve(() => {
+      return () => {
         // eslint-disable-next-line security/detect-object-injection
         const listeners = this.listeners[event]
         listeners.splice(listeners.indexOf(handler), 1)
-      })
+      }
     }
     return listen(event, handler, {
       target: { kind: 'Window', label: this.label }
@@ -403,13 +403,16 @@ class Window {
    * @returns A promise resolving to a function to unlisten to the event.
    * Note that removing the listener is required if your listener goes out of scope e.g. the component is unmounted.
    */
-  async once<T>(event: string, handler: EventCallback<T>): Promise<UnlistenFn> {
+  async once<T>(
+    event: EventName,
+    handler: EventCallback<T>
+  ): Promise<UnlistenFn> {
     if (this._handleTauriEvent(event, handler)) {
-      return Promise.resolve(() => {
+      return () => {
         // eslint-disable-next-line security/detect-object-injection
         const listeners = this.listeners[event]
         listeners.splice(listeners.indexOf(handler), 1)
-      })
+      }
     }
     return once(event, handler, {
       target: { kind: 'Window', label: this.label }
@@ -437,7 +440,7 @@ class Window {
           payload
         })
       }
-      return Promise.resolve()
+      return
     }
     return emit(event, payload)
   }
@@ -460,7 +463,7 @@ class Window {
     payload?: unknown
   ): Promise<void> {
     if (localTauriEvents.includes(event)) {
-      // eslint-disable-next-line
+      // eslint-disable-next-line security/detect-object-injection
       for (const handler of this.listeners[event] || []) {
         handler({
           event,
@@ -468,7 +471,7 @@ class Window {
           payload
         })
       }
-      return Promise.resolve()
+      return
     }
     return emitTo(target, event, payload)
   }
@@ -1710,13 +1713,13 @@ class Window {
   async onCloseRequested(
     handler: (event: CloseRequestedEvent) => void | Promise<void>
   ): Promise<UnlistenFn> {
-    return this.listen<null>(TauriEvent.WINDOW_CLOSE_REQUESTED, (event) => {
+    // eslint-disable-next-line @typescript-eslint/no-misused-promises
+    return this.listen(TauriEvent.WINDOW_CLOSE_REQUESTED, async (event) => {
       const evt = new CloseRequestedEvent(event)
-      void Promise.resolve(handler(evt)).then(() => {
-        if (!evt.isPreventDefault()) {
-          return this.destroy()
-        }
-      })
+      await handler(evt)
+      if (!evt.isPreventDefault()) {
+        await this.destroy()
+      }
     })
   }
 

Некоторые файлы не были показаны из-за большого количества измененных файлов