Skip to content

Commit

Permalink
enhance: use EventName on window's once and remove listener befor…
Browse files Browse the repository at this point in the history
…e calling handler (#10246)

* Refactor

* Revert event => void

* Change file
  • Loading branch information
Legend-Master authored Jul 10, 2024
1 parent 57612ab commit 080b6e1
Show file tree
Hide file tree
Showing 7 changed files with 51 additions and 31 deletions.
5 changes: 5 additions & 0 deletions .changes/fix-once-handler-throw.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@tauri-apps/api': 'patch:bug'
---

Fix `once` doesn't detached after one callback if event handler throws
5 changes: 5 additions & 0 deletions .changes/once-event-name.md
Original file line number Diff line number Diff line change
@@ -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
2 changes: 1 addition & 1 deletion core/tauri/scripts/bundle.global.js

Large diffs are not rendered by default.

3 changes: 2 additions & 1 deletion tooling/api/src/event.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
)
Expand Down
21 changes: 12 additions & 9 deletions tooling/api/src/webview.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 }
Expand All @@ -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 }
Expand Down Expand Up @@ -290,7 +293,7 @@ class Webview {
payload
})
}
return Promise.resolve()
return
}
return emit(event, payload)
}
Expand Down Expand Up @@ -322,7 +325,7 @@ class Webview {
payload
})
}
return Promise.resolve()
return
}
return emitTo(target, event, payload)
}
Expand All @@ -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
Expand Down
13 changes: 8 additions & 5 deletions tooling/api/src/webviewWindow.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 }
Expand All @@ -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 }
Expand Down
33 changes: 18 additions & 15 deletions tooling/api/src/window.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
Expand Down Expand Up @@ -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 }
Expand All @@ -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 }
Expand Down Expand Up @@ -437,7 +440,7 @@ class Window {
payload
})
}
return Promise.resolve()
return
}
return emit(event, payload)
}
Expand All @@ -460,15 +463,15 @@ 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,
id: -1,
payload
})
}
return Promise.resolve()
return
}
return emitTo(target, event, payload)
}
Expand Down Expand Up @@ -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()
}
})
}

Expand Down

0 comments on commit 080b6e1

Please sign in to comment.