@flighthq/tray 0.5.0-next.1944.cd6b6e7 → 0.5.1-edge.638.d4dbd4e

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # @flighthq/tray
2
2
 
3
- Tray icon and application badge over a swappable web/native backend
3
+ Capability-refined tray icon Entities over explicitly injected host facets
4
4
 
5
5
  ## Install
6
6
 
@@ -13,5 +13,5 @@ Import the supported application-facing API from `@flighthq/tray`. The `@flighth
13
13
  This package is part of the locked-version Flight SDK graph. Applications may instead install and import `@flighthq/sdk` when package-level tree shaking is sufficient.
14
14
 
15
15
  - [Flight project](https://github.com/flighthq/flight)
16
- - [Source for @flighthq/tray@0.5.0-next.1944.cd6b6e7](https://github.com/flighthq/flight/tree/cd6b6e71eb472b3a4249830a7743333f019fa7b7/packages/tray)
17
- - [License](https://github.com/flighthq/flight/blob/cd6b6e71eb472b3a4249830a7743333f019fa7b7/LICENSE.md)
16
+ - [Source for @flighthq/tray@0.5.1-edge.638.d4dbd4e](https://github.com/flighthq/flight/tree/d4dbd4e347dc8be10b180c85a766ab50333dcb51/packages/tray)
17
+ - [License](https://github.com/flighthq/flight/blob/d4dbd4e347dc8be10b180c85a766ab50333dcb51/LICENSE.md)
package/dist/index.d.ts CHANGED
@@ -1,2 +1,2 @@
1
- export { disableTrayGuards, enableTrayGuards, createTrayIcon, destroyTrayIcon, displayTrayBalloon, explainTrayBackend, getTrayCapabilities, getTrayIconBounds, getTrayIconTitle, getTrayIconTooltip, getTrayIcons, isTrayDestroyed, isTrayIconAnimating, onTrayEvent, popupTrayContextMenu, removeTrayBalloon, setTrayIcon, setTrayIconContextMenu, setTrayIconTemplate, setTrayIconTitle, setTrayIconTooltip, setTrayIgnoreDoubleClickEvents, setTrayPressedIcon, startTrayIconAnimation, stopTrayIconAnimation, } from './contract';
1
+ export { disableTrayGuards, enableTrayGuards, createTrayIcon, destroyTrayIcon, displayTrayBalloon, getTrayIconBounds, getTrayIconTitle, getTrayIconTooltip, getTrayIcons, isTrayDestroyed, isTrayIconAnimating, onTrayBalloonEvent, onTrayDrop, onTrayInteraction, onTrayMenuSelection, popupTrayContextMenu, removeTrayBalloon, setTrayIcon, setTrayIconContextMenu, setTrayIconTemplate, setTrayIconTitle, setTrayIconTooltip, setTrayIgnoreDoubleClickEvents, setTrayPressedIcon, startTrayIconAnimation, stopTrayIconAnimation, } from './contract';
2
2
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,iBAAiB,EACjB,gBAAgB,EAChB,cAAc,EACd,eAAe,EACf,kBAAkB,EAClB,kBAAkB,EAClB,mBAAmB,EACnB,iBAAiB,EACjB,gBAAgB,EAChB,kBAAkB,EAClB,YAAY,EACZ,eAAe,EACf,mBAAmB,EACnB,WAAW,EACX,oBAAoB,EACpB,iBAAiB,EACjB,WAAW,EACX,sBAAsB,EACtB,mBAAmB,EACnB,gBAAgB,EAChB,kBAAkB,EAClB,8BAA8B,EAC9B,kBAAkB,EAClB,sBAAsB,EACtB,qBAAqB,GACtB,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,iBAAiB,EACjB,gBAAgB,EAChB,cAAc,EACd,eAAe,EACf,kBAAkB,EAClB,iBAAiB,EACjB,gBAAgB,EAChB,kBAAkB,EAClB,YAAY,EACZ,eAAe,EACf,mBAAmB,EACnB,kBAAkB,EAClB,UAAU,EACV,iBAAiB,EACjB,mBAAmB,EACnB,oBAAoB,EACpB,iBAAiB,EACjB,WAAW,EACX,sBAAsB,EACtB,mBAAmB,EACnB,gBAAgB,EAChB,kBAAkB,EAClB,8BAA8B,EAC9B,kBAAkB,EAClB,sBAAsB,EACtB,qBAAqB,GACtB,MAAM,YAAY,CAAC"}
package/dist/index.js CHANGED
@@ -1,2 +1,2 @@
1
- export { disableTrayGuards, enableTrayGuards, createTrayIcon, destroyTrayIcon, displayTrayBalloon, explainTrayBackend, getTrayCapabilities, getTrayIconBounds, getTrayIconTitle, getTrayIconTooltip, getTrayIcons, isTrayDestroyed, isTrayIconAnimating, onTrayEvent, popupTrayContextMenu, removeTrayBalloon, setTrayIcon, setTrayIconContextMenu, setTrayIconTemplate, setTrayIconTitle, setTrayIconTooltip, setTrayIgnoreDoubleClickEvents, setTrayPressedIcon, startTrayIconAnimation, stopTrayIconAnimation, } from './contract';
1
+ export { disableTrayGuards, enableTrayGuards, createTrayIcon, destroyTrayIcon, displayTrayBalloon, getTrayIconBounds, getTrayIconTitle, getTrayIconTooltip, getTrayIcons, isTrayDestroyed, isTrayIconAnimating, onTrayBalloonEvent, onTrayDrop, onTrayInteraction, onTrayMenuSelection, popupTrayContextMenu, removeTrayBalloon, setTrayIcon, setTrayIconContextMenu, setTrayIconTemplate, setTrayIconTitle, setTrayIconTooltip, setTrayIgnoreDoubleClickEvents, setTrayPressedIcon, startTrayIconAnimation, stopTrayIconAnimation, } from './contract';
2
2
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,iBAAiB,EACjB,gBAAgB,EAChB,cAAc,EACd,eAAe,EACf,kBAAkB,EAClB,kBAAkB,EAClB,mBAAmB,EACnB,iBAAiB,EACjB,gBAAgB,EAChB,kBAAkB,EAClB,YAAY,EACZ,eAAe,EACf,mBAAmB,EACnB,WAAW,EACX,oBAAoB,EACpB,iBAAiB,EACjB,WAAW,EACX,sBAAsB,EACtB,mBAAmB,EACnB,gBAAgB,EAChB,kBAAkB,EAClB,8BAA8B,EAC9B,kBAAkB,EAClB,sBAAsB,EACtB,qBAAqB,GACtB,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,iBAAiB,EACjB,gBAAgB,EAChB,cAAc,EACd,eAAe,EACf,kBAAkB,EAClB,iBAAiB,EACjB,gBAAgB,EAChB,kBAAkB,EAClB,YAAY,EACZ,eAAe,EACf,mBAAmB,EACnB,kBAAkB,EAClB,UAAU,EACV,iBAAiB,EACjB,mBAAmB,EACnB,oBAAoB,EACpB,iBAAiB,EACjB,WAAW,EACX,sBAAsB,EACtB,mBAAmB,EACnB,gBAAgB,EAChB,kBAAkB,EAClB,8BAA8B,EAC9B,kBAAkB,EAClB,sBAAsB,EACtB,qBAAqB,GACtB,MAAM,YAAY,CAAC"}
package/dist/tray.d.ts CHANGED
@@ -1,36 +1,27 @@
1
- import type { BackendExplanation } from '@flighthq/types/contract';
2
- import type { MenuItemTemplate, RectangleLike, TrayBackend, TrayBalloonOptions, TrayCapabilities, TrayEventData, TrayIcon, TrayIconOptions } from '@flighthq/types/contract';
3
- import type { Vector2Like } from '@flighthq/types/contract';
4
- export declare function createTrayIcon(options?: Readonly<TrayIconOptions>): TrayIcon | null;
5
- export declare function destroyTrayIcon(tray: TrayIcon): void;
6
- export declare function displayTrayBalloon(tray: TrayIcon, options: Readonly<TrayBalloonOptions>): void;
7
- export declare function explainTrayBackend(): BackendExplanation;
8
- export declare function getTrayBackend(): TrayBackend;
9
- export declare function getTrayCapabilities(): Readonly<TrayCapabilities>;
10
- export declare function getTrayIconBounds(tray: TrayIcon): Readonly<RectangleLike> | null;
11
- export declare function getTrayIcons(): readonly TrayIcon[];
12
- export declare function getTrayIconTitle(tray: TrayIcon): string;
13
- export declare function getTrayIconTooltip(tray: TrayIcon): string;
14
- export declare function installTrayHostBackend(backend: TrayBackend): void;
15
- export declare function isTrayDestroyed(tray: TrayIcon): boolean;
16
- export declare function isTrayIconAnimating(tray: TrayIcon): boolean;
17
- export declare function observeTrayHostResult(operation: string, succeeded: boolean): void;
18
- export declare function onTrayEvent(listener: (event: Readonly<TrayEventData>) => void): () => void;
19
- export declare function popupTrayContextMenu(tray: TrayIcon, position?: Readonly<Vector2Like>): void;
20
- export declare function removeTrayBalloon(tray: TrayIcon): void;
21
- export declare function resetTrayBackendForTest(): void;
22
- /** Installs the tray guard, or clears it with `null`. The seam exists so the messages and the
23
- * `@flighthq/log` dependency live in the separately-importable guard module rather than here; not
24
- * importing that module costs production nothing. Called by `enableTrayGuards`, not directly. */
1
+ import type { HasTrayLifecycle, MenuItemTemplate, TrayAnimationStartResult, TrayAnimationStopResult, TrayBalloonDisplayResult, TrayBalloonEvent, TrayBalloonOptions, TrayBalloonRemoveResult, TrayBoundsResult, TrayCreateResult, TrayDestroyResult, TrayDoubleClickPolicyUpdateResult, TrayDropEvent, TrayEventAttachResult, TrayIcon, TrayIconForHost, TrayIconOptions, TrayIconSource, TrayImageUpdateResult, TrayInteractionEvent, TrayMenuSelectionEvent, TrayMenuUpdateResult, TrayPopupMenuResult, TrayPressedImageUpdateResult, TrayTemplateImageUpdateResult, TrayTitleReadResult, TrayTitleUpdateResult, TrayTooltipReadResult, TrayTooltipUpdateResult, TrayWithBalloon, TrayWithBalloonEvents, TrayWithBounds, TrayWithDoubleClickPolicy, TrayWithDropEvents, TrayWithImage, TrayWithInteractionEvents, TrayWithMenu, TrayWithMenuSelectionEvents, TrayWithPopupMenu, TrayWithPressedImage, TrayWithTemplateImage, TrayWithTitle, TrayWithTooltip, Vector2Like } from '@flighthq/types/contract';
2
+ export declare function createTrayIcon<HostType extends HasTrayLifecycle>(host: HostType, options?: Readonly<TrayIconOptions>): Promise<TrayCreateResult<TrayIconForHost<HostType>>>;
3
+ export declare function destroyTrayIcon(tray: TrayIcon): Promise<TrayDestroyResult>;
4
+ export declare function displayTrayBalloon(tray: TrayWithBalloon, options: Readonly<TrayBalloonOptions>): Promise<TrayBalloonDisplayResult>;
5
+ export declare function getTrayIconBounds(tray: TrayWithBounds): Promise<TrayBoundsResult>;
6
+ export declare function getTrayIcons(host: HasTrayLifecycle): readonly TrayIcon[];
7
+ export declare function getTrayIconTitle(tray: TrayWithTitle): Promise<TrayTitleReadResult>;
8
+ export declare function getTrayIconTooltip(tray: TrayWithTooltip): Promise<TrayTooltipReadResult>;
9
+ export declare function isTrayDestroyed(tray: Readonly<TrayIcon>): boolean;
10
+ export declare function isTrayIconAnimating(tray: Readonly<TrayIcon>): boolean;
11
+ export declare function onTrayBalloonEvent(tray: TrayWithBalloonEvents, listener: (event: Readonly<TrayBalloonEvent>) => void): TrayEventAttachResult;
12
+ export declare function onTrayDrop(tray: TrayWithDropEvents, listener: (event: Readonly<TrayDropEvent>) => void): TrayEventAttachResult;
13
+ export declare function onTrayInteraction(tray: TrayWithInteractionEvents, listener: (event: Readonly<TrayInteractionEvent>) => void): TrayEventAttachResult;
14
+ export declare function onTrayMenuSelection(tray: TrayWithMenuSelectionEvents, listener: (event: Readonly<TrayMenuSelectionEvent>) => void): TrayEventAttachResult;
15
+ export declare function popupTrayContextMenu(tray: TrayWithPopupMenu, position?: Readonly<Vector2Like>): Promise<TrayPopupMenuResult>;
16
+ export declare function removeTrayBalloon(tray: TrayWithBalloon): Promise<TrayBalloonRemoveResult>;
25
17
  export declare function setTrayAnimationGuard(guard: ((tray: TrayIcon, frameCount: number, intervalMs: number) => void) | null): void;
26
- export declare function setTrayBackend(backend: TrayBackend | null): void;
27
- export declare function setTrayIcon(tray: TrayIcon, icon: string): void;
28
- export declare function setTrayIconContextMenu(tray: TrayIcon, items: readonly MenuItemTemplate[]): void;
29
- export declare function setTrayIconTemplate(tray: TrayIcon, isTemplate: boolean): void;
30
- export declare function setTrayIconTitle(tray: TrayIcon, title: string): void;
31
- export declare function setTrayIconTooltip(tray: TrayIcon, tooltip: string): void;
32
- export declare function setTrayIgnoreDoubleClickEvents(tray: TrayIcon, ignore: boolean): void;
33
- export declare function setTrayPressedIcon(tray: TrayIcon, icon: string): void;
34
- export declare function startTrayIconAnimation(tray: TrayIcon, frames: readonly string[], intervalMs: number): () => void;
35
- export declare function stopTrayIconAnimation(tray: TrayIcon): void;
18
+ export declare function setTrayIcon(tray: TrayWithImage, icon: TrayIconSource): Promise<TrayImageUpdateResult>;
19
+ export declare function setTrayIconContextMenu(tray: TrayWithMenu, items: readonly MenuItemTemplate[]): Promise<TrayMenuUpdateResult>;
20
+ export declare function setTrayIconTemplate(tray: TrayWithTemplateImage, isTemplate: boolean): Promise<TrayTemplateImageUpdateResult>;
21
+ export declare function setTrayIconTitle(tray: TrayWithTitle, title: string): Promise<TrayTitleUpdateResult>;
22
+ export declare function setTrayIconTooltip(tray: TrayWithTooltip, tooltip: string): Promise<TrayTooltipUpdateResult>;
23
+ export declare function setTrayIgnoreDoubleClickEvents(tray: TrayWithDoubleClickPolicy, ignore: boolean): Promise<TrayDoubleClickPolicyUpdateResult>;
24
+ export declare function setTrayPressedIcon(tray: TrayWithPressedImage, icon: TrayIconSource): Promise<TrayPressedImageUpdateResult>;
25
+ export declare function startTrayIconAnimation(tray: TrayWithImage, frames: readonly TrayIconSource[], intervalMs: number): Promise<TrayAnimationStartResult>;
26
+ export declare function stopTrayIconAnimation(tray: TrayIcon): TrayAnimationStopResult;
36
27
  //# sourceMappingURL=tray.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"tray.d.ts","sourceRoot":"","sources":["../src/tray.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"tray.d.ts","sourceRoot":"","sources":["../src/tray.ts"],"names":[],"mappings":"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"}
package/dist/tray.js CHANGED
@@ -1,283 +1,231 @@
1
- // Web tray capability constants. Web has no system tray — all capabilities are false. Readonly and
2
- // shared: getCapabilities hands this same object to every caller, so a mutable one would let any of
3
- // them rewrite what the backend reports to all the others.
4
- const WEB_CAPABILITIES = {
5
- balloon: false,
6
- bounds: false,
7
- clickEvents: false,
8
- dropFiles: false,
9
- pressedIcon: false,
10
- title: false,
11
- };
12
- // Creates a tray icon, or null when the host has no system tray (e.g. web). The backend returns -1 to
13
- // signal no tray; this translates that to a null sentinel for the caller.
14
- export function createTrayIcon(options) {
15
- const id = getTrayBackend().create(options ?? {});
16
- return id < 0 ? null : { id };
17
- }
18
- // Destroys a tray icon and frees its host resource. No-op when the host has no tray.
19
- // Any icon animation running on this tray is stopped first: the interval writes through setTrayIcon,
20
- // and left running it would keep calling into a resource the host has freed — forever, since the
21
- // timer holds its own closure alive. Destroying the thing being animated is the clearest possible
22
- // signal that the animation is over, so the caller does not have to have kept the stop function.
23
- export function destroyTrayIcon(tray) {
24
- stopTrayIconAnimation(tray);
25
- getTrayBackend().destroy(tray.id);
26
- }
27
- // Displays a Windows balloon notification from the tray icon. No-op on macOS/Linux and on web.
28
- // Balloon lifecycle events (balloonShow/balloonClick/balloonClose) are emitted via onTrayEvent.
29
- export function displayTrayBalloon(tray, options) {
30
- getTrayBackend().displayBalloon(tray.id, options);
31
- }
32
- export function explainTrayBackend() {
33
- if (_custom !== null) {
34
- return { conflict: _hostConflict, layer: 'custom', operation: null, viability: 'unobserved' };
1
+ import { createEntity, createEntityRuntime } from '@flighthq/entity/contract';
2
+ import { connectSignal, disconnectSignal } from '@flighthq/signals/contract';
3
+ import { EntityRuntimeKey } from '@flighthq/types/contract';
4
+ export async function createTrayIcon(host, options = {}) {
5
+ const tray = createEntity();
6
+ let result;
7
+ try {
8
+ result = await host.tray.lifecycle.create(tray, options);
35
9
  }
36
- if (_host !== null) {
37
- return {
38
- conflict: _hostConflict,
39
- layer: 'host',
40
- operation: _hostObservation !== null ? _hostObservation.operation : null,
41
- viability: _hostObservation !== null ? _hostObservation.viability : 'unobserved',
42
- };
10
+ catch (error) {
11
+ return { error, outcome: 'tray-create-failed' };
43
12
  }
44
- return { conflict: false, layer: 'host-not-enabled', operation: null, viability: 'unobserved' };
13
+ if (result.outcome !== 'created')
14
+ return result;
15
+ const runtime = createEntityRuntime();
16
+ runtime.animationGeneration = 0;
17
+ runtime.animationTimer = null;
18
+ runtime.animationWriteTail = Promise.resolve();
19
+ runtime.capabilities = { ...host.tray };
20
+ runtime.destroyPromise = null;
21
+ runtime.lifecycle = host.tray.lifecycle;
22
+ runtime.releases = new Set();
23
+ runtime.state = 'active';
24
+ tray[EntityRuntimeKey] = runtime;
25
+ return { outcome: 'created', tray };
45
26
  }
46
- // The active tray backend. Precedence: custom > host > sentinel.
47
- export function getTrayBackend() {
48
- return _custom ?? _host ?? _sentinel;
27
+ export function destroyTrayIcon(tray) {
28
+ const runtime = getTrayRuntime(tray);
29
+ if (runtime === null || runtime.state === 'destroyed')
30
+ return Promise.resolve({ outcome: 'already-destroyed' });
31
+ if (runtime.destroyPromise !== null)
32
+ return runtime.destroyPromise;
33
+ runtime.destroyPromise = destroyTrayRuntime(tray, runtime).finally(() => {
34
+ runtime.destroyPromise = null;
35
+ });
36
+ return runtime.destroyPromise;
49
37
  }
50
- // Returns the capability flags for the active tray backend. Use before calling APIs that may
51
- // silently no-op — for example, check capabilities.balloon before displayTrayBalloon, or
52
- // capabilities.bounds before getTrayIconBounds. On web all flags are false.
53
- export function getTrayCapabilities() {
54
- return getTrayBackend().getCapabilities();
38
+ export function displayTrayBalloon(tray, options) {
39
+ return invokeUpdate(tray, 'balloon', 'balloon-display-failed', (backend) => backend.display(tray, options));
55
40
  }
56
- // Returns the screen bounds of the tray icon (x/y/width/height), or null when the platform does not
57
- // expose icon geometry (Linux/AppIndicator, web). Use for anchoring popovers or windows to the icon.
58
41
  export function getTrayIconBounds(tray) {
59
- return getTrayBackend().getBounds(tray.id);
42
+ return invokeRead(tray, 'bounds', 'bounds-read-failed', (backend) => backend.get(tray));
43
+ }
44
+ async function destroyTrayRuntime(tray, runtime) {
45
+ runtime.state = 'destroying';
46
+ stopTrayAnimationRuntime(runtime);
47
+ for (const release of [...runtime.releases])
48
+ await release.release();
49
+ let result;
50
+ try {
51
+ result = await runtime.lifecycle.destroy(tray);
52
+ }
53
+ catch (error) {
54
+ result = { failures: [{ error, step: 'native-resource' }], outcome: 'tray-destroy-failed' };
55
+ }
56
+ if (result.outcome === 'destroyed') {
57
+ runtime.state = 'destroyed';
58
+ return result;
59
+ }
60
+ runtime.state = 'partially-destroyed';
61
+ return result;
60
62
  }
61
- // Returns all live tray icon handles known to the active backend. On web this is always empty.
62
- export function getTrayIcons() {
63
- return getTrayBackend()
64
- .listIds()
65
- .map((id) => ({ id }));
63
+ export function getTrayIcons(host) {
64
+ return host.tray.lifecycle.list();
66
65
  }
67
- // Returns the current title text of a tray icon, or an empty string when unavailable (web, non-macOS).
68
66
  export function getTrayIconTitle(tray) {
69
- return getTrayBackend().getTitle(tray.id);
67
+ return invokeRead(tray, 'title', 'title-read-failed', (backend) => backend.get(tray));
70
68
  }
71
- // Returns the current hover tooltip text of a tray icon, or an empty string when unavailable (web).
72
69
  export function getTrayIconTooltip(tray) {
73
- return getTrayBackend().getTooltip(tray.id);
74
- }
75
- export function installTrayHostBackend(backend) {
76
- if (_host !== null) {
77
- if (_host !== backend)
78
- _hostConflict = true;
79
- return;
80
- }
81
- _host = backend;
70
+ return invokeRead(tray, 'tooltip', 'tooltip-read-failed', (backend) => backend.get(tray));
82
71
  }
83
- // Returns whether a tray icon has been destroyed. Returns true on web (no trays exist).
84
- // Use this to guard calls after destroyTrayIcon when the tray lifecycle is unclear.
85
72
  export function isTrayDestroyed(tray) {
86
- return getTrayBackend().isDestroyed(tray.id);
73
+ const runtime = getTrayRuntime(tray);
74
+ return runtime === null || runtime.state !== 'active' || runtime.lifecycle.isDestroyed(tray);
87
75
  }
88
- // True while an icon animation started by startTrayIconAnimation is running on this tray. False once
89
- // it is stopped, replaced by a later start, or the tray is destroyed.
90
76
  export function isTrayIconAnimating(tray) {
91
- return _animations.has(tray.id);
77
+ return getTrayRuntime(tray)?.animationTimer !== null;
92
78
  }
93
- export function observeTrayHostResult(operation, succeeded) {
94
- _hostObservation = {
95
- operation,
96
- viability: succeeded ? 'available' : 'runtime-api-unavailable',
97
- };
79
+ export function onTrayBalloonEvent(tray, listener) {
80
+ return attachTrayEvent(tray, 'balloonEvents', listener);
81
+ }
82
+ export function onTrayDrop(tray, listener) {
83
+ return attachTrayEvent(tray, 'dropEvents', listener);
84
+ }
85
+ export function onTrayInteraction(tray, listener) {
86
+ return attachTrayEvent(tray, 'interactionEvents', listener);
98
87
  }
99
- // Subscribes to tray icon events, delivering a rich TrayEventData payload (id, type, bounds,
100
- // position, modifier keys, and drop payloads). Returns an unsubscribe function. On web this
101
- // never fires (no tray); a native host is required.
102
- export function onTrayEvent(listener) {
103
- return getTrayBackend().subscribe(listener);
88
+ export function onTrayMenuSelection(tray, listener) {
89
+ return attachTrayEvent(tray, 'menuSelectionEvents', listener);
104
90
  }
105
- // Programmatically shows the attached context menu, optionally at a specific screen position.
106
- // On web this is a no-op. Useful for showing the menu in response to a custom gesture or shortcut
107
- // without waiting for the user to right-click the tray icon.
108
91
  export function popupTrayContextMenu(tray, position) {
109
- getTrayBackend().popUpContextMenu(tray.id, position);
92
+ return invokeUpdate(tray, 'popupMenu', 'popup-failed', (backend) => backend.popup(tray, position));
110
93
  }
111
- // Dismisses the currently-displayed Windows balloon notification. No-op on macOS/Linux and web.
112
94
  export function removeTrayBalloon(tray) {
113
- getTrayBackend().removeBalloon(tray.id);
95
+ return invokeUpdate(tray, 'balloon', 'balloon-remove-failed', (backend) => backend.remove(tray));
114
96
  }
115
- export function resetTrayBackendForTest() {
116
- _custom = null;
117
- _host = null;
118
- _hostConflict = false;
119
- _hostObservation = null;
120
- }
121
- /** Installs the tray guard, or clears it with `null`. The seam exists so the messages and the
122
- * `@flighthq/log` dependency live in the separately-importable guard module rather than here; not
123
- * importing that module costs production nothing. Called by `enableTrayGuards`, not directly. */
124
97
  export function setTrayAnimationGuard(guard) {
125
98
  _animationGuard = guard;
126
99
  }
127
- // Installs a custom tray backend; pass null to clear the custom override.
128
- export function setTrayBackend(backend) {
129
- _custom = backend;
130
- }
131
- // Sets the image for the tray icon. Accepts the same icon path/data-URI accepted by createTrayIcon.
132
- // Use this for runtime status updates (indicators, spinners, theme changes).
133
100
  export function setTrayIcon(tray, icon) {
134
- getTrayBackend().setIcon(tray.id, icon);
101
+ return invokeUpdate(tray, 'image', 'image-update-failed', (backend) => backend.set(tray, icon));
135
102
  }
136
- // Sets the context menu attached to a tray icon. Shown on right-click (or popupTrayContextMenu).
137
- // No-op when the host has no tray.
138
103
  export function setTrayIconContextMenu(tray, items) {
139
- getTrayBackend().setContextMenu(tray.id, items);
104
+ return invokeUpdate(tray, 'menu', 'menu-install-failed', (backend) => backend.set(tray, items));
140
105
  }
141
- // Marks the tray icon as a macOS template image. Template images auto-invert for light/dark menu
142
- // bars. No-op on Windows/Linux and on web. Set iconTemplate:true on TrayIconOptions at creation to
143
- // combine with the initial icon, or call this after creation to update the flag dynamically.
144
106
  export function setTrayIconTemplate(tray, isTemplate) {
145
- getTrayBackend().setTemplate(tray.id, isTemplate);
107
+ return invokeUpdate(tray, 'templateImage', 'template-image-update-failed', (backend) => backend.set(tray, isTemplate));
146
108
  }
147
- // Sets the title text displayed next to the tray icon (macOS menu bar only). No-op on other platforms.
148
109
  export function setTrayIconTitle(tray, title) {
149
- getTrayBackend().setTitle(tray.id, title);
110
+ return invokeUpdate(tray, 'title', 'title-update-failed', (backend) => backend.set(tray, title));
150
111
  }
151
- // Sets the hover tooltip for the tray icon. No-op when the host has no tray.
152
112
  export function setTrayIconTooltip(tray, tooltip) {
153
- getTrayBackend().setTooltip(tray.id, tooltip);
113
+ return invokeUpdate(tray, 'tooltip', 'tooltip-update-failed', (backend) => backend.set(tray, tooltip));
114
+ }
115
+ function attachTrayEvent(tray, slot, listener) {
116
+ const runtime = getActiveTrayRuntime(tray);
117
+ if (runtime === null)
118
+ return { outcome: 'tray-destroyed' };
119
+ try {
120
+ const backend = runtime.capabilities[slot];
121
+ const signal = backend?.getSignal(tray) ?? null;
122
+ if (signal === null)
123
+ return { outcome: 'tray-destroyed' };
124
+ connectSignal(signal, listener);
125
+ const release = {
126
+ released: false,
127
+ async release() {
128
+ if (release.released)
129
+ return { outcome: 'already-released' };
130
+ try {
131
+ disconnectSignal(signal, listener);
132
+ release.released = true;
133
+ runtime.releases.delete(release);
134
+ return { outcome: 'released' };
135
+ }
136
+ catch (error) {
137
+ return { error, outcome: 'release-failed' };
138
+ }
139
+ },
140
+ };
141
+ runtime.releases.add(release);
142
+ return { outcome: 'attached', release };
143
+ }
144
+ catch (error) {
145
+ return { error, outcome: 'subscription-failed' };
146
+ }
154
147
  }
155
- // Sets whether the host should collapse double-click events into individual click events (macOS).
156
- // No-op on Windows/Linux and on web.
157
148
  export function setTrayIgnoreDoubleClickEvents(tray, ignore) {
158
- getTrayBackend().setIgnoreDoubleClickEvents(tray.id, ignore);
149
+ return invokeUpdate(tray, 'doubleClickPolicy', 'double-click-policy-update-failed', (backend) => backend.setIgnore(tray, ignore));
159
150
  }
160
- // Sets the image shown when the tray icon is pressed (macOS only). Electron calls this
161
- // setPressedImage. No-op on Windows/Linux and on web.
162
151
  export function setTrayPressedIcon(tray, icon) {
163
- getTrayBackend().setPressedIcon(tray.id, icon);
164
- }
165
- // Starts an animated icon sequence by cycling through the given frames at the specified interval,
166
- // returning a stop function. An empty frame list is a no-op. The tray icon is not destroyed when the
167
- // animation stops, and the last frame shown stays.
168
- //
169
- // A tray icon has one image, so it has one animation: starting a second on the same tray replaces the
170
- // first rather than running both. Without that, a perfectly ordinary sequence — swap a "syncing"
171
- // animation for an "error" one — left two intervals writing to the same icon on the same tick, and
172
- // the only handle to the orphaned one was a stop function the caller had no reason to still be
173
- // holding. The returned function stops only the animation it started, so calling a stale one cannot
174
- // cancel a newer animation.
175
- //
176
- // Note: interval timing is best-effort; the actual frame rate depends on the host event loop.
177
- export function startTrayIconAnimation(tray, frames, intervalMs) {
152
+ return invokeUpdate(tray, 'pressedImage', 'pressed-image-update-failed', (backend) => backend.set(tray, icon));
153
+ }
154
+ export async function startTrayIconAnimation(tray, frames, intervalMs) {
178
155
  if (frames.length === 0)
179
- return _noopStop;
156
+ return { outcome: 'empty' };
157
+ const runtime = getActiveTrayRuntime(tray);
158
+ if (runtime === null)
159
+ return { outcome: 'tray-destroyed' };
180
160
  _animationGuard?.(tray, frames.length, intervalMs);
181
- stopTrayIconAnimation(tray);
161
+ stopTrayAnimationRuntime(runtime);
162
+ const generation = runtime.animationGeneration;
163
+ const first = await queueAnimationWrite(tray, runtime, generation, frames[0]);
164
+ if (first.outcome !== 'updated')
165
+ return first;
166
+ if (runtime.state !== 'active' || runtime.animationGeneration !== generation)
167
+ return { outcome: 'tray-destroyed' };
182
168
  let index = 0;
183
- setTrayIcon(tray, frames[index]);
184
- const handle = setInterval(() => {
169
+ runtime.animationTimer = setInterval(() => {
185
170
  index = (index + 1) % frames.length;
186
- setTrayIcon(tray, frames[index]);
171
+ void queueAnimationWrite(tray, runtime, generation, frames[index]);
187
172
  }, intervalMs);
188
- _animations.set(tray.id, handle);
189
- return () => {
190
- // Only clear if this animation is still the current one; a later start already replaced it.
191
- if (_animations.get(tray.id) !== handle)
192
- return;
193
- clearInterval(handle);
194
- _animations.delete(tray.id);
173
+ const release = {
174
+ released: false,
175
+ async release() {
176
+ if (release.released)
177
+ return { outcome: 'already-released' };
178
+ release.released = true;
179
+ if (runtime.animationGeneration === generation)
180
+ stopTrayAnimationRuntime(runtime);
181
+ return { outcome: 'released' };
182
+ },
195
183
  };
184
+ return { outcome: 'started', release };
185
+ }
186
+ async function queueAnimationWrite(tray, runtime, generation, frame) {
187
+ let result = { outcome: 'tray-destroyed' };
188
+ runtime.animationWriteTail = runtime.animationWriteTail.then(async () => {
189
+ if (runtime.state !== 'active' || runtime.animationGeneration !== generation)
190
+ return;
191
+ result = await setTrayIcon(tray, frame);
192
+ });
193
+ await runtime.animationWriteTail;
194
+ return result;
195
+ }
196
+ function stopTrayAnimationRuntime(runtime) {
197
+ runtime.animationGeneration++;
198
+ if (runtime.animationTimer !== null)
199
+ clearInterval(runtime.animationTimer);
200
+ runtime.animationTimer = null;
196
201
  }
197
- // The interval per animating tray id. Module-scoped like the backend, and correct at that scope: an
198
- // id is the host's, so one id is one icon is one animation.
199
- const _animations = new Map();
200
- function _noopStop() { }
201
- // Stops the icon animation running on this tray, if any. Idempotent, and safe on a tray that never
202
- // animated. The named counterpart to startTrayIconAnimation for callers that hold the TrayIcon but
203
- // not the stop function it returned — which is most of them, since the handle is what gets passed
204
- // around and the closure is what gets dropped.
205
202
  export function stopTrayIconAnimation(tray) {
206
- const handle = _animations.get(tray.id);
207
- if (handle === undefined)
208
- return;
209
- clearInterval(handle);
210
- _animations.delete(tray.id);
203
+ const runtime = getTrayRuntime(tray);
204
+ if (runtime === null || runtime.animationTimer === null)
205
+ return { outcome: 'already-stopped' };
206
+ stopTrayAnimationRuntime(runtime);
207
+ return { outcome: 'stopped' };
211
208
  }
212
209
  let _animationGuard = null;
213
- let _custom = null;
214
- let _host = null;
215
- let _hostConflict = false;
216
- let _hostObservation = null;
217
- const _sentinel = {
218
- create() {
219
- // No tray on web. -1 signals "unsupported"; createTrayIcon maps it to null.
220
- return -1;
221
- },
222
- destroy() {
223
- // No-op: web has no tray icon to destroy.
224
- },
225
- displayBalloon() {
226
- // No-op: balloon notifications require a native host (Windows only).
227
- },
228
- getBounds() {
229
- // No tray on web; null signals unavailable.
230
- return null;
231
- },
232
- getCapabilities() {
233
- return WEB_CAPABILITIES;
234
- },
235
- getTitle() {
236
- // No tray on web.
237
- return '';
238
- },
239
- getTooltip() {
240
- // No tray on web.
241
- return '';
242
- },
243
- isDestroyed() {
244
- // No tray icons exist on web; treat every id as destroyed.
245
- return true;
246
- },
247
- listIds() {
248
- // No tray icons exist on web.
249
- return [];
250
- },
251
- popUpContextMenu() {
252
- // No-op: web has no context menu to pop up.
253
- },
254
- removeBalloon() {
255
- // No-op: balloon notifications require a native host (Windows only).
256
- },
257
- setContextMenu() {
258
- // No-op: web has no tray icon — a native host (Electron/Tauri) is required.
259
- },
260
- setIcon() {
261
- // No-op: web has no tray icon to update.
262
- },
263
- setIgnoreDoubleClickEvents() {
264
- // No-op: web has no tray icon double-click behavior to configure.
265
- },
266
- setPressedIcon() {
267
- // No-op: web has no tray icon; pressed icon is macOS-specific.
268
- },
269
- setTemplate() {
270
- // No-op: template images are a macOS menu-bar concept; irrelevant on web.
271
- },
272
- setTitle() {
273
- // No-op: web has no tray icon to update.
274
- },
275
- setTooltip() {
276
- // No-op: web has no tray icon to update.
277
- },
278
- subscribe() {
279
- // No tray on web — a native host (Electron/Tauri) is required to emit tray events.
280
- return () => { };
281
- },
282
- };
210
+ function getTrayRuntime(tray) {
211
+ return tray[EntityRuntimeKey] ?? null;
212
+ }
213
+ function getActiveTrayRuntime(tray) {
214
+ const runtime = getTrayRuntime(tray);
215
+ return runtime?.state === 'active' ? runtime : null;
216
+ }
217
+ async function invokeUpdate(tray, slot, failure, operation) {
218
+ const runtime = getActiveTrayRuntime(tray);
219
+ if (runtime === null)
220
+ return { outcome: 'tray-destroyed' };
221
+ try {
222
+ return await operation(runtime.capabilities[slot]);
223
+ }
224
+ catch (error) {
225
+ return { error, outcome: failure };
226
+ }
227
+ }
228
+ function invokeRead(tray, slot, failure, operation) {
229
+ return invokeUpdate(tray, slot, failure, operation);
230
+ }
283
231
  //# sourceMappingURL=tray.js.map