Skip to content

Events API

The Events API lets you emit and listen to events across windows and bridge components. All listener methods return a Promise that resolves to an unlisten function — call it when the listener is no longer needed to avoid memory leaks.

Methods

Emitting

MethodDescription
emit(event, payload?)Emits an event to the current window only.
emitToAll(event, payload?)Emits an event to all open windows.
emitTo(windowLabel, event, payload?)Emits an event to the window identified by windowLabel.

Listening

MethodHandler signatureReturn type
on(event, handler)(payload) => voidPromise<() => void>
once(event)
Promise<any>
onMany(events[], handler)(eventName, payload) => voidPromise<() => void>
onNetworkStatus(handler)(payload) => voidPromise<() => void>
onDeeplink(handler)(payload) => voidPromise<() => void>
onShortcut(handler)(payload) => voidPromise<() => void>
onDragDrop(handler, options?)(eventName, payload) => voidPromise<() => void>
onMenuEvent(handler)(payload) => voidPromise<() => void>
onTrayIconEvent(handler)(payload) => voidPromise<() => void>

Unsubscribing

Every listener method returns a Promise that resolves to an unlisten function. Always await the call — without await, you hold a Promise object, not the unlisten function.

js
// ✅ Correct
const unlisten = await Liatir.desktop.events.on('data:refresh', (payload) => {
  console.log(payload);
});

// Later, when the component unmounts or the listener is no longer needed:
unlisten();
js
// ❌ Wrong — you need 'await' otherwise 'unlisten' is a Promise, not a function
const unlisten = Liatir.events.on('data:refresh', handler);
unlisten(); // TypeError

Examples

on — persistent listener

js
const unlisten = await Liatir.desktop.events.on('order:updated', (payload) => {
  console.log('Order updated:', payload);
});

// Remove the listener when done
unlisten();

once — wait for a single event

once returns a Promise that resolves with the event payload the first time the event fires. It automatically unsubscribes after the first occurrence — no unlisten needed.

js
const payload = await Liatir.desktop.events.once('auth:token-ready');
console.log('Token received:', payload);

onMany — one handler for multiple events

The handler receives the event name as its first argument, so you can branch on it.

js
const unlisten = await Liatir.desktop.events.onMany(
  ['cart:add', 'cart:remove', 'cart:clear'],
  (eventName, payload) => {
    if (eventName === 'cart:clear') resetCart();
    else updateCart(eventName, payload);
  }
);

onNetworkStatus — online/offline

js
const unlisten = await Liatir.desktop.events.onNetworkStatus(({ online, reason, latency_ms }) => {
  console.log(online ? `Online (${latency_ms}ms)` : `Offline — ${reason}`);
});
js
const unlisten = await Liatir.desktop.events.onDeeplink(({ scheme, segments, query, raw }) => {
  // e.g. myapp://reset-password?token=abc
  console.log(scheme, segments.list, query);
});

onShortcut — global keyboard shortcuts

Fires when a shortcut registered via Liatir.globalShortcut.register() is triggered.

js
const unlisten = await Liatir.desktop.events.onShortcut(({ accelerator, state }) => {
  if (state === 'Pressed') handleShortcut(accelerator);
});

onDragDrop — file drag and drop

By default listens to dragdrop:enter, dragdrop:drop, and dragdrop:cancel. Pass { includeHover: true } to also receive dragdrop:hover events while files are being dragged over the window.

js
const unlisten = await Liatir.desktop.events.onDragDrop(
  (eventName, { kind, paths, position }) => {
    if (kind === 'drop') {
      console.log('Files dropped:', paths);
    }
  },
  { includeHover: true }
);

unlisten();

onMenuEvent / onTrayIconEvent

js
const unlistenMenu = await Liatir.desktop.events.onMenuEvent((payload) => {
  console.log('Menu action:', payload);
});

const unlistenTray = await Liatir.desktop.events.onTrayIconEvent((payload) => {
  console.log('Tray interaction:', payload);
});

Payload types

Event sourceRelevant fields
onNetworkStatusonline: boolean, reason: "ok" | "dns" | "timeout" | "unknown", latency_ms?: number
onDeeplinkscheme: string, segments: { first, last, list }, query: Record<string, string>, raw: string
onShortcutaccelerator: string, shortcut: string, id: number, state: "Pressed" | "Released"
onDragDropkind: "enter" | "hover" | "drop" | "cancel", paths: string[], position?: { x, y }

Notes

Cleanup pattern in components

If you are using a framework, store unlisten functions and call them on component teardown:

js
// Svelte
import { onDestroy } from 'svelte';

const unlisten = await Liatir.desktop.events.on('my:event', handler);
onDestroy(unlisten);

// React
useEffect(() => {
  let unlisten;
  Liatir.events.on('my:event', handler).then(fn => { unlisten = fn; });
  return () => unlisten?.();
}, []);

Forgetting to unlisten

Each call to on registers a new listener. If your component re-renders or re-mounts without cleaning up, the same event will be handled multiple times. Always pair each on call with a corresponding unlisten().

Liatir — powerful bioinformatics on your machine.

By using this app, you agree to our Privacy Policy and Terms of Service.