Skip to content

Commit 080b6e1

Browse files
enhance: use EventName on window's once and remove listener before calling handler (#10246)
* Refactor * Revert event => void * Change file
1 parent 57612ab commit 080b6e1

7 files changed

Lines changed: 51 additions & 31 deletions

File tree

.changes/fix-once-handler-throw.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@tauri-apps/api': 'patch:bug'
3+
---
4+
5+
Fix `once` doesn't detached after one callback if event handler throws

.changes/once-event-name.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@tauri-apps/api': 'patch:enhance'
3+
---
4+
5+
Use `EventName` on `Window`, `Webview` and `WebviewWindow`'s `once` so you can get auto complete for tauri's built-in events

core/tauri/scripts/bundle.global.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

tooling/api/src/event.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,8 +152,9 @@ async function once<T>(
152152
return listen<T>(
153153
event,
154154
(eventData) => {
155+
// eslint-disable-next-line @typescript-eslint/no-floating-promises
156+
_unlisten(event, eventData.id)
155157
handler(eventData)
156-
_unlisten(event, eventData.id).catch(() => {})
157158
},
158159
options
159160
)

tooling/api/src/webview.ts

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -225,11 +225,11 @@ class Webview {
225225
handler: EventCallback<T>
226226
): Promise<UnlistenFn> {
227227
if (this._handleTauriEvent(event, handler)) {
228-
return Promise.resolve(() => {
228+
return () => {
229229
// eslint-disable-next-line security/detect-object-injection
230230
const listeners = this.listeners[event]
231231
listeners.splice(listeners.indexOf(handler), 1)
232-
})
232+
}
233233
}
234234
return listen(event, handler, {
235235
target: { kind: 'Webview', label: this.label }
@@ -255,13 +255,16 @@ class Webview {
255255
* @returns A promise resolving to a function to unlisten to the event.
256256
* Note that removing the listener is required if your listener goes out of scope e.g. the component is unmounted.
257257
*/
258-
async once<T>(event: string, handler: EventCallback<T>): Promise<UnlistenFn> {
258+
async once<T>(
259+
event: EventName,
260+
handler: EventCallback<T>
261+
): Promise<UnlistenFn> {
259262
if (this._handleTauriEvent(event, handler)) {
260-
return Promise.resolve(() => {
263+
return () => {
261264
// eslint-disable-next-line security/detect-object-injection
262265
const listeners = this.listeners[event]
263266
listeners.splice(listeners.indexOf(handler), 1)
264-
})
267+
}
265268
}
266269
return once(event, handler, {
267270
target: { kind: 'Webview', label: this.label }
@@ -290,7 +293,7 @@ class Webview {
290293
payload
291294
})
292295
}
293-
return Promise.resolve()
296+
return
294297
}
295298
return emit(event, payload)
296299
}
@@ -322,7 +325,7 @@ class Webview {
322325
payload
323326
})
324327
}
325-
return Promise.resolve()
328+
return
326329
}
327330
return emitTo(target, event, payload)
328331
}
@@ -331,10 +334,10 @@ class Webview {
331334
_handleTauriEvent<T>(event: string, handler: EventCallback<T>): boolean {
332335
if (localTauriEvents.includes(event)) {
333336
if (!(event in this.listeners)) {
334-
// eslint-disable-next-line
337+
// eslint-disable-next-line security/detect-object-injection
335338
this.listeners[event] = [handler]
336339
} else {
337-
// eslint-disable-next-line
340+
// eslint-disable-next-line security/detect-object-injection
338341
this.listeners[event].push(handler)
339342
}
340343
return true

tooling/api/src/webviewWindow.ts

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -155,11 +155,11 @@ class WebviewWindow {
155155
handler: EventCallback<T>
156156
): Promise<UnlistenFn> {
157157
if (this._handleTauriEvent(event, handler)) {
158-
return Promise.resolve(() => {
158+
return () => {
159159
// eslint-disable-next-line security/detect-object-injection
160160
const listeners = this.listeners[event]
161161
listeners.splice(listeners.indexOf(handler), 1)
162-
})
162+
}
163163
}
164164
return listen(event, handler, {
165165
target: { kind: 'WebviewWindow', label: this.label }
@@ -185,13 +185,16 @@ class WebviewWindow {
185185
* @returns A promise resolving to a function to unlisten to the event.
186186
* Note that removing the listener is required if your listener goes out of scope e.g. the component is unmounted.
187187
*/
188-
async once<T>(event: string, handler: EventCallback<T>): Promise<UnlistenFn> {
188+
async once<T>(
189+
event: EventName,
190+
handler: EventCallback<T>
191+
): Promise<UnlistenFn> {
189192
if (this._handleTauriEvent(event, handler)) {
190-
return Promise.resolve(() => {
193+
return () => {
191194
// eslint-disable-next-line security/detect-object-injection
192195
const listeners = this.listeners[event]
193196
listeners.splice(listeners.indexOf(handler), 1)
194-
})
197+
}
195198
}
196199
return once(event, handler, {
197200
target: { kind: 'WebviewWindow', label: this.label }

tooling/api/src/window.ts

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ class CloseRequestedEvent {
105105
id: number
106106
private _preventDefault = false
107107

108-
constructor(event: Event<null>) {
108+
constructor(event: Event<unknown>) {
109109
this.event = event.event
110110
this.id = event.id
111111
}
@@ -373,11 +373,11 @@ class Window {
373373
handler: EventCallback<T>
374374
): Promise<UnlistenFn> {
375375
if (this._handleTauriEvent(event, handler)) {
376-
return Promise.resolve(() => {
376+
return () => {
377377
// eslint-disable-next-line security/detect-object-injection
378378
const listeners = this.listeners[event]
379379
listeners.splice(listeners.indexOf(handler), 1)
380-
})
380+
}
381381
}
382382
return listen(event, handler, {
383383
target: { kind: 'Window', label: this.label }
@@ -403,13 +403,16 @@ class Window {
403403
* @returns A promise resolving to a function to unlisten to the event.
404404
* Note that removing the listener is required if your listener goes out of scope e.g. the component is unmounted.
405405
*/
406-
async once<T>(event: string, handler: EventCallback<T>): Promise<UnlistenFn> {
406+
async once<T>(
407+
event: EventName,
408+
handler: EventCallback<T>
409+
): Promise<UnlistenFn> {
407410
if (this._handleTauriEvent(event, handler)) {
408-
return Promise.resolve(() => {
411+
return () => {
409412
// eslint-disable-next-line security/detect-object-injection
410413
const listeners = this.listeners[event]
411414
listeners.splice(listeners.indexOf(handler), 1)
412-
})
415+
}
413416
}
414417
return once(event, handler, {
415418
target: { kind: 'Window', label: this.label }
@@ -437,7 +440,7 @@ class Window {
437440
payload
438441
})
439442
}
440-
return Promise.resolve()
443+
return
441444
}
442445
return emit(event, payload)
443446
}
@@ -460,15 +463,15 @@ class Window {
460463
payload?: unknown
461464
): Promise<void> {
462465
if (localTauriEvents.includes(event)) {
463-
// eslint-disable-next-line
466+
// eslint-disable-next-line security/detect-object-injection
464467
for (const handler of this.listeners[event] || []) {
465468
handler({
466469
event,
467470
id: -1,
468471
payload
469472
})
470473
}
471-
return Promise.resolve()
474+
return
472475
}
473476
return emitTo(target, event, payload)
474477
}
@@ -1710,13 +1713,13 @@ class Window {
17101713
async onCloseRequested(
17111714
handler: (event: CloseRequestedEvent) => void | Promise<void>
17121715
): Promise<UnlistenFn> {
1713-
return this.listen<null>(TauriEvent.WINDOW_CLOSE_REQUESTED, (event) => {
1716+
// eslint-disable-next-line @typescript-eslint/no-misused-promises
1717+
return this.listen(TauriEvent.WINDOW_CLOSE_REQUESTED, async (event) => {
17141718
const evt = new CloseRequestedEvent(event)
1715-
void Promise.resolve(handler(evt)).then(() => {
1716-
if (!evt.isPreventDefault()) {
1717-
return this.destroy()
1718-
}
1719-
})
1719+
await handler(evt)
1720+
if (!evt.isPreventDefault()) {
1721+
await this.destroy()
1722+
}
17201723
})
17211724
}
17221725

0 commit comments

Comments
 (0)