123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219 |
- // Copyright 2019-2024 Tauri Programme within The Commons Conservancy
- // SPDX-License-Identifier: Apache-2.0
- // SPDX-License-Identifier: MIT
- /**
- * The event system allows you to emit events to the backend and listen to events from it.
- *
- * This package is also accessible with `window.__TAURI__.event` when [`app.withGlobalTauri`](https://tauri.app/v1/api/config/#appconfig.withglobaltauri) in `tauri.conf.json` is set to `true`.
- * @module
- */
- import { invoke, transformCallback } from './core'
- type EventTarget =
- | { kind: 'Any' }
- | { kind: 'AnyLabel'; label: string }
- | { kind: 'App' }
- | { kind: 'Window'; label: string }
- | { kind: 'Webview'; label: string }
- | { kind: 'WebviewWindow'; label: string }
- interface Event<T> {
- /** Event name */
- event: EventName
- /** Event identifier used to unlisten */
- id: number
- /** Event payload */
- payload: T
- }
- type EventCallback<T> = (event: Event<T>) => void
- type UnlistenFn = () => void
- type EventName = `${TauriEvent}` | (string & Record<never, never>)
- interface Options {
- /**
- * The event target to listen to, defaults to `{ kind: 'Any' }`, see {@link EventTarget}.
- *
- * If a string is provided, {@link EventTarget.AnyLabel} is used.
- */
- target?: string | EventTarget
- }
- /**
- * @since 1.1.0
- */
- enum TauriEvent {
- WINDOW_RESIZED = 'tauri://resize',
- WINDOW_MOVED = 'tauri://move',
- WINDOW_CLOSE_REQUESTED = 'tauri://close-requested',
- WINDOW_DESTROYED = 'tauri://destroyed',
- WINDOW_FOCUS = 'tauri://focus',
- WINDOW_BLUR = 'tauri://blur',
- WINDOW_SCALE_FACTOR_CHANGED = 'tauri://scale-change',
- WINDOW_THEME_CHANGED = 'tauri://theme-changed',
- WEBVIEW_CREATED = 'tauri://webview-created',
- FILE_DROP = 'tauri://file-drop',
- FILE_DROP_HOVER = 'tauri://file-drop-hover',
- FILE_DROP_CANCELLED = 'tauri://file-drop-cancelled'
- }
- /**
- * Unregister the event listener associated with the given name and id.
- *
- * @ignore
- * @param event The event name
- * @param eventId Event identifier
- * @returns
- */
- async function _unlisten(event: string, eventId: number): Promise<void> {
- await invoke('plugin:event|unlisten', {
- event,
- eventId
- })
- }
- /**
- * Listen to an emitted event to any {@link EventTarget|target}.
- *
- * @example
- * ```typescript
- * import { listen } from '@tauri-apps/api/event';
- * const unlisten = await listen<string>('error', (event) => {
- * console.log(`Got error, payload: ${event.payload}`);
- * });
- *
- * // you need to call unlisten if your handler goes out of scope e.g. the component is unmounted
- * unlisten();
- * ```
- *
- * @param event Event name. Must include only alphanumeric characters, `-`, `/`, `:` and `_`.
- * @param handler Event handler callback.
- * @param options Event listening options.
- * @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.
- *
- * @since 1.0.0
- */
- async function listen<T>(
- event: EventName,
- handler: EventCallback<T>,
- options?: Options
- ): Promise<UnlistenFn> {
- const target: EventTarget =
- typeof options?.target === 'string'
- ? { kind: 'AnyLabel', label: options.target }
- : options?.target ?? { kind: 'Any' }
- return invoke<number>('plugin:event|listen', {
- event,
- target,
- handler: transformCallback(handler)
- }).then((eventId) => {
- return async () => _unlisten(event, eventId)
- })
- }
- /**
- * Listens once to an emitted event to any {@link EventTarget|target}.
- *
- * @example
- * ```typescript
- * import { once } from '@tauri-apps/api/event';
- * interface LoadedPayload {
- * loggedIn: boolean,
- * token: string
- * }
- * const unlisten = await once<LoadedPayload>('loaded', (event) => {
- * console.log(`App is loaded, loggedIn: ${event.payload.loggedIn}, token: ${event.payload.token}`);
- * });
- *
- * // you need to call unlisten if your handler goes out of scope e.g. the component is unmounted
- * unlisten();
- * ```
- *
- * @param event Event name. Must include only alphanumeric characters, `-`, `/`, `:` and `_`.
- * @param handler Event handler callback.
- * @param options Event listening options.
- * @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.
- *
- * @since 1.0.0
- */
- async function once<T>(
- event: EventName,
- handler: EventCallback<T>,
- options?: Options
- ): Promise<UnlistenFn> {
- return listen<T>(
- event,
- (eventData) => {
- handler(eventData)
- _unlisten(event, eventData.id).catch(() => {})
- },
- options
- )
- }
- /**
- * Emits an event to all {@link EventTarget|targets}.
- *
- * @example
- * ```typescript
- * import { emit } from '@tauri-apps/api/event';
- * await emit('frontend-loaded', { loggedIn: true, token: 'authToken' });
- * ```
- *
- * @param event Event name. Must include only alphanumeric characters, `-`, `/`, `:` and `_`.
- * @param payload Event payload.
- *
- * @since 1.0.0
- */
- async function emit(event: string, payload?: unknown): Promise<void> {
- await invoke('plugin:event|emit', {
- event,
- payload
- })
- }
- /**
- * Emits an event to all {@link EventTarget|targets} matching the given target.
- *
- * @example
- * ```typescript
- * import { emitTo } from '@tauri-apps/api/event';
- * await emitTo('main', 'frontend-loaded', { loggedIn: true, token: 'authToken' });
- * ```
- *
- * @param target Label of the target Window/Webview/WebviewWindow or raw {@link EventTarget} object.
- * @param event Event name. Must include only alphanumeric characters, `-`, `/`, `:` and `_`.
- * @param payload Event payload.
- *
- * @since 1.0.0
- */
- async function emitTo(
- target: EventTarget | string,
- event: string,
- payload?: unknown
- ): Promise<void> {
- const eventTarget: EventTarget =
- typeof target === 'string' ? { kind: 'AnyLabel', label: target } : target
- await invoke('plugin:event|emit_to', {
- target: eventTarget,
- event,
- payload
- })
- }
- export type {
- Event,
- EventTarget,
- EventCallback,
- UnlistenFn,
- EventName,
- Options
- }
- export { listen, once, emit, emitTo, TauriEvent }
|