opentray 0.10.0 → 0.10.3

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opentray",
3
- "version": "0.10.0",
3
+ "version": "0.10.3",
4
4
  "description": "Developer-facing OpenTray SDK and CLI package.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -13,10 +13,6 @@
13
13
  "types": "./dist/index.d.mts",
14
14
  "import": "./dist/index.mjs"
15
15
  },
16
- "./node": {
17
- "types": "./dist/node.d.mts",
18
- "import": "./dist/node.mjs"
19
- },
20
16
  "./package.json": "./package.json"
21
17
  },
22
18
  "bin": {
@@ -28,7 +24,7 @@
28
24
  ],
29
25
  "sideEffects": false,
30
26
  "dependencies": {
31
- "@opentray/spec": "0.10.0"
27
+ "@opentray/spec": "0.10.3"
32
28
  },
33
29
  "devDependencies": {
34
30
  "tsdown": "^0.22.1",
@@ -36,22 +32,21 @@
36
32
  "vitest": "^4.1.7"
37
33
  },
38
34
  "optionalDependencies": {
39
- "@opentray/darwin-arm64": "0.10.0",
40
- "@opentray/darwin-x64": "0.10.0",
41
- "@opentray/linux-arm64": "0.10.0",
42
- "@opentray/linux-x64": "0.10.0",
43
- "@opentray/windows-arm64": "0.10.0",
44
- "@opentray/windows-x64": "0.10.0"
35
+ "@opentray/darwin-arm64": "0.10.3",
36
+ "@opentray/darwin-x64": "0.10.3",
37
+ "@opentray/linux-arm64": "0.10.3",
38
+ "@opentray/linux-x64": "0.10.3",
39
+ "@opentray/windows-arm64": "0.10.3",
40
+ "@opentray/windows-x64": "0.10.3"
45
41
  },
46
42
  "scripts": {
47
- "build": "tsdown src/index.ts src/node.ts src/cli.ts --format esm --dts",
43
+ "build": "tsdown src/index.ts src/cli.ts --format esm --dts",
48
44
  "cli": "bun run src/cli.ts",
49
45
  "example:matrix": "bun run examples/example-matrix.ts",
50
46
  "example:basic": "bun run examples/basic-tray.ts",
51
47
  "example:first-app": "bun run examples/first-app.ts",
52
48
  "example:debug-runtime-lynx": "bun run examples/debug-runtime-lynx.ts",
53
49
  "example:debug-runtime-tray": "bun run examples/debug-runtime-tray.ts",
54
- "example:visible-binding": "node examples/visible-binding-host.mjs",
55
50
  "example:mediaQuery": "bun run examples/media-query-panel.ts",
56
51
  "example:badge": "bun run examples/badge-panel.ts",
57
52
  "example:placement": "bun run examples/placement-panel.ts",
@@ -1,136 +0,0 @@
1
- import { ClientFrame, ClientRequestFrame, ExtensionEnvelope, Icon, Menu, RequestId, ServerFrame, Tooltip, TrayBoundsResult, TrayEvent, TrayId, TrayOptions } from "@opentray/spec";
2
-
3
- //#region src/client.d.ts
4
- interface OpenTrayTransport {
5
- request(frame: ClientRequestFrame): Promise<ServerFrame>;
6
- }
7
- type OpenTrayEventFrame = Extract<ServerFrame, {
8
- type: "event" | "ext-event";
9
- }>;
10
- interface OpenTrayEventSource {
11
- onEvent(listener: (frame: OpenTrayEventFrame) => void): () => void;
12
- }
13
- interface OpenTrayConnection extends OpenTrayTransport, OpenTrayEventSource {}
14
- interface OpenTrayClient {
15
- createTray(options: TrayOptions): Promise<TrayHandle>;
16
- }
17
- interface OpenTrayEventfulClient extends OpenTrayClient {
18
- createTray(options: TrayOptions): Promise<EventfulTrayHandle>;
19
- }
20
- interface TrayHandle {
21
- trayId: TrayId;
22
- getBounds(): Promise<TrayBoundsResult>;
23
- setMenu(menu: Menu): Promise<void>;
24
- setTooltip(tooltip: Tooltip): Promise<void>;
25
- setIcon(icon: Icon): Promise<void>;
26
- loadExtension(options: ExtensionLoadOptions): Promise<void>;
27
- commandExtension(ext: string, data: unknown): Promise<void>;
28
- requestExtension(ext: string, data: unknown): Promise<ExtensionEnvelope[]>;
29
- extend<TCapability extends object, TOptions = undefined>(extension: TrayExtension<TCapability, TOptions>, options?: TOptions): TrayHandle & TCapability;
30
- destroy(): Promise<void>;
31
- }
32
- type TrayScopedEvent = Exclude<TrayEvent, {
33
- type: "ready";
34
- }>;
35
- type TrayEventType = TrayScopedEvent["type"];
36
- type TrayEventByType<TEvent extends TrayEventType> = Extract<TrayScopedEvent, {
37
- type: TEvent;
38
- }>;
39
- interface EventfulTrayHandle extends TrayHandle {
40
- extend<TCapability extends object, TOptions = undefined>(extension: TrayExtension<TCapability, TOptions>, options?: TOptions): EventfulTrayHandle & TCapability;
41
- listenExtension<TData = unknown>(ext: string, handler: (event: ExtensionEnvelope<TData>) => void): () => void;
42
- listen<TEvent extends TrayEventType>(event: TEvent, handler: (event: TrayEventByType<TEvent>) => void): () => void;
43
- onMenuClick(handler: (event: TrayEventByType<"menuClick">) => void): () => void;
44
- onTrayClick(handler: (event: TrayEventByType<"trayClick">) => void): () => void;
45
- onTrayDoubleClick(handler: (event: TrayEventByType<"trayDoubleClick">) => void): () => void;
46
- }
47
- interface ExtensionLoadOptions {
48
- name: string;
49
- path: string;
50
- mountId?: string;
51
- }
52
- interface TrayExtensionMountSpec {
53
- name?: string;
54
- path?: string;
55
- mountId?: string;
56
- }
57
- interface TrayExtensionContext {
58
- readonly name: string;
59
- readonly path: string;
60
- readonly mountId: string;
61
- ensureLoaded(): Promise<void>;
62
- command(data: unknown): Promise<void>;
63
- request(data: unknown): Promise<ExtensionEnvelope[]>;
64
- }
65
- interface TrayExtension<TCapability extends object, TOptions = undefined> {
66
- readonly name: string;
67
- readonly path: string;
68
- resolveMount?(options: TOptions | undefined): TrayExtensionMountSpec;
69
- extend(tray: TrayHandle, context: TrayExtensionContext, options: TOptions | undefined): TCapability;
70
- }
71
- declare const createInitFrame: (clientVersion: string) => ClientFrame;
72
- interface CreateClientOptions {
73
- requestIdPrefix?: string;
74
- }
75
- declare function createClient(transport: OpenTrayConnection, options?: CreateClientOptions): OpenTrayEventfulClient;
76
- declare function createClient(transport: OpenTrayTransport, options?: CreateClientOptions): OpenTrayClient;
77
- declare function createTrayHandle(transport: OpenTrayConnection, appId: string, trayId: TrayId, nextRequestId?: () => RequestId): EventfulTrayHandle;
78
- declare function createTrayHandle(transport: OpenTrayTransport, appId: string, trayId: TrayId, nextRequestId?: () => RequestId): TrayHandle;
79
- //#endregion
80
- //#region src/native-runtime.d.ts
81
- interface OpenTrayRuntimeBindingInfo {
82
- readonly kind: string;
83
- readonly protocolVersion: number;
84
- }
85
- interface OpenTrayRuntimeBinding {
86
- runtimeBindingInfo(): OpenTrayRuntimeBindingInfo;
87
- runVisibleRuntimeHost?(options?: OpenTrayVisibleRuntimeHostOptions): void;
88
- createVisibleRuntime?(): OpenTrayVisibleRuntime;
89
- createHeadlessRuntime?(packageVersion?: string, appId?: string, appName?: string): OpenTrayHeadlessRuntime;
90
- }
91
- interface OpenTrayVisibleRuntimeHostOptions {
92
- readonly packageVersion?: string;
93
- readonly appId?: string;
94
- readonly appName?: string;
95
- readonly autoExitAfterMs?: number;
96
- }
97
- interface OpenTrayRuntimeHost {
98
- request(frameJson: string): string[] | Promise<string[]>;
99
- close(): string[] | Promise<string[]>;
100
- }
101
- interface OpenTrayVisibleRuntime extends OpenTrayRuntimeHost {
102
- pollEvents(): string[] | Promise<string[]>;
103
- }
104
- type OpenTrayHeadlessRuntime = OpenTrayRuntimeHost;
105
- interface RuntimeNativeTarget {
106
- readonly packageName: string;
107
- readonly bindingRelativePath: string;
108
- }
109
- interface ResolveRuntimeBindingOptions {
110
- readonly platform?: string;
111
- readonly arch?: string;
112
- readonly resolvePackageJson?: (packageName: string) => string | undefined;
113
- readonly nativeLoader?: (bindingPath: string) => unknown;
114
- }
115
- declare const resolveRuntimeNativeTarget: (platform?: string, arch?: string) => RuntimeNativeTarget;
116
- declare const resolveInstalledRuntimeBindingPath: ({
117
- platform,
118
- arch,
119
- resolvePackageJson
120
- }?: ResolveRuntimeBindingOptions) => Promise<string>;
121
- declare const loadOpenTrayRuntimeBinding: (options?: ResolveRuntimeBindingOptions) => Promise<OpenTrayRuntimeBinding>;
122
- declare class MissingPlatformRuntimeBindingError extends Error {
123
- readonly code = "OPENTRAY_MISSING_PLATFORM_RUNTIME_BINDING";
124
- readonly platform: string;
125
- readonly arch: string;
126
- readonly packageName: string | undefined;
127
- readonly bindingPath: string | undefined;
128
- constructor(message: string, platform: string, arch: string, options?: {
129
- readonly packageName?: string;
130
- readonly bindingPath?: string;
131
- readonly cause?: unknown;
132
- });
133
- }
134
- //#endregion
135
- export { TrayHandle as C, createTrayHandle as E, TrayExtensionMountSpec as S, createInitFrame as T, OpenTrayTransport as _, ResolveRuntimeBindingOptions as a, TrayExtension as b, resolveInstalledRuntimeBindingPath as c, EventfulTrayHandle as d, ExtensionLoadOptions as f, OpenTrayEventSource as g, OpenTrayEventFrame as h, OpenTrayVisibleRuntimeHostOptions as i, resolveRuntimeNativeTarget as l, OpenTrayConnection as m, OpenTrayRuntimeBinding as n, RuntimeNativeTarget as o, OpenTrayClient as p, OpenTrayRuntimeBindingInfo as r, loadOpenTrayRuntimeBinding as s, MissingPlatformRuntimeBindingError as t, CreateClientOptions as u, TrayEventByType as v, createClient as w, TrayExtensionContext as x, TrayEventType as y };
136
- //# sourceMappingURL=native-runtime-Cn8BaffH.d.mts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"native-runtime-Cn8BaffH.d.mts","names":[],"sources":["../src/client.ts","../src/native-runtime.ts"],"mappings":"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"}
package/dist/node.d.mts DELETED
@@ -1,70 +0,0 @@
1
- import { a as ResolveRuntimeBindingOptions, c as resolveInstalledRuntimeBindingPath, d as EventfulTrayHandle, i as OpenTrayVisibleRuntimeHostOptions, l as resolveRuntimeNativeTarget, m as OpenTrayConnection, n as OpenTrayRuntimeBinding, o as RuntimeNativeTarget, r as OpenTrayRuntimeBindingInfo, s as loadOpenTrayRuntimeBinding, t as MissingPlatformRuntimeBindingError } from "./native-runtime-Cn8BaffH.mjs";
2
- import { TrayOptions } from "@opentray/spec";
3
-
4
- //#region src/runtime-binding-transport.d.ts
5
- type RuntimeBindingTransportKind = "visible" | "headless";
6
- interface CreateRuntimeBindingTransportOptions {
7
- readonly kind?: RuntimeBindingTransportKind;
8
- readonly binding?: OpenTrayRuntimeBinding;
9
- readonly packageVersion?: string;
10
- readonly clientVersion?: string;
11
- readonly protocolVersion?: number;
12
- readonly appId?: string;
13
- readonly appName?: string;
14
- }
15
- declare const createRuntimeBindingTransport: ({
16
- binding,
17
- packageVersion,
18
- clientVersion,
19
- protocolVersion,
20
- appId,
21
- appName,
22
- kind
23
- }?: CreateRuntimeBindingTransportOptions) => Promise<OpenTrayConnection>;
24
- //#endregion
25
- //#region src/node-host.d.ts
26
- /** Options for resolving the native binding and running the visible host loop. */
27
- interface RunVisibleRuntimeHostOptions extends ResolveRuntimeBindingOptions, OpenTrayVisibleRuntimeHostOptions {}
28
- /** Run the visible native host loop on the caller-owned Node main thread. */
29
- declare const runVisibleRuntimeHost: ({
30
- platform,
31
- arch,
32
- resolvePackageJson,
33
- nativeLoader,
34
- ...hostOptions
35
- }?: RunVisibleRuntimeHostOptions) => Promise<void>;
36
- //#endregion
37
- //#region src/node-app.d.ts
38
- interface RunTrayAppOptions {
39
- /** Runtime package version used for host state partitioning and diagnostics. */
40
- readonly packageVersion?: string;
41
- /** Client version reported to the runtime host handshake. */
42
- readonly clientVersion?: string;
43
- /** Protocol version reported to the runtime host handshake. */
44
- readonly protocolVersion?: number;
45
- /** App identity for diagnostics and runtime isolation. */
46
- readonly appId?: string;
47
- /** Human-readable app identity for diagnostics. */
48
- readonly appName?: string;
49
- /** Optional finite runtime window for examples and smoke tests. */
50
- readonly autoExitAfterMs?: number;
51
- /** Delay before the worker callback runs, giving the visible host time to boot. */
52
- readonly startupDelayMs?: number;
53
- }
54
- interface TrayAppContext {
55
- /** Create a tray in the app worker while the helper owns the visible host loop. */
56
- createTray(options: TrayOptions): Promise<EventfulTrayHandle>;
57
- }
58
- /**
59
- * First-app entrypoint executed inside the app worker.
60
- *
61
- * Keep the callback self-contained. Imports needed by the callback should be
62
- * dynamic imports inside the callback because the helper runs it in a worker.
63
- */
64
- type TrayAppMain = (context: TrayAppContext) => void | Promise<void>;
65
- /** Run a self-contained tray app without exposing host-thread choreography. */
66
- declare const runTrayApp: (main: TrayAppMain, options?: RunTrayAppOptions) => Promise<void>;
67
- declare const createTrayAppWorkerSource: () => string;
68
- //#endregion
69
- export { type CreateRuntimeBindingTransportOptions, MissingPlatformRuntimeBindingError, type OpenTrayRuntimeBinding, type OpenTrayRuntimeBindingInfo, type OpenTrayVisibleRuntimeHostOptions, type ResolveRuntimeBindingOptions, type RunTrayAppOptions, type RunVisibleRuntimeHostOptions, type RuntimeNativeTarget, type TrayAppContext, type TrayAppMain, createRuntimeBindingTransport, createTrayAppWorkerSource, loadOpenTrayRuntimeBinding, resolveInstalledRuntimeBindingPath, resolveRuntimeNativeTarget, runTrayApp, runVisibleRuntimeHost };
70
- //# sourceMappingURL=node.d.mts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"node.d.mts","names":[],"sources":["../src/runtime-binding-transport.ts","../src/node-host.ts","../src/node-app.ts"],"mappings":";;;;KAgBY,2BAAA;AAAA,UAEK,oCAAA;EAAA,SACN,IAAA,GAAO,2BAAA;EAAA,SACP,OAAA,GAAU,sBAAsB;EAAA,SAChC,cAAA;EAAA,SACA,aAAA;EAAA,SACA,eAAA;EAAA,SACA,KAAA;EAAA,SACA,OAAA;AAAA;AAAA,cAGE,6BAAA;EAAuC,OAAA;EAAA,cAAA;EAAA,aAAA;EAAA,eAAA;EAAA,KAAA;EAAA,OAAA;EAAA;AAAA,IAQjD,oCAAA,KAA4C,OAAA,CAAQ,kBAAA;;;;UC7BtC,4BAAA,SACP,4BAAA,EACN,iCAAiC;ADOrC;AAAA,cCJa,qBAAA;EAA+B,QAAA;EAAA,IAAA;EAAA,kBAAA;EAAA,YAAA;EAAA,GAAA;AAAA,IAMzC,4BAAA,KAAoC,OAAA;;;UCZtB,iBAAA;;WAEN,cAAA;EFQ4B;EAAA,SEN5B,aAAA;EFM4B;EAAA,SEJ5B,eAAA;EFMM;EAAA,SEJN,KAAA;;WAEA,OAAA;EFGA;EAAA,SEDA,eAAA;EFEA;EAAA,SEAA,cAAA;AAAA;AAAA,UAGM,cAAA;EFAN;EEET,UAAA,CAAW,OAAA,EAAS,WAAA,GAAc,OAAA,CAAQ,kBAAA;AAAA;;AFA1B;AAGlB;;;;KEMY,WAAA,IAAe,OAAA,EAAS,cAAA,YAA0B,OAAO;;cAgBxD,UAAA,GACX,IAAA,EAAM,WAAA,EACN,OAAA,GAAS,iBAAA,KACR,OAAA;AAAA,cA8CU,yBAAA"}
package/dist/node.mjs DELETED
@@ -1,116 +0,0 @@
1
- import { a as resolveRuntimeNativeTarget, i as resolveInstalledRuntimeBindingPath, n as MissingPlatformRuntimeBindingError, r as loadOpenTrayRuntimeBinding, t as createRuntimeBindingTransport } from "./runtime-binding-transport-UPunusBT.mjs";
2
- import { Worker } from "node:worker_threads";
3
- //#region src/node-host.ts
4
- /** Run the visible native host loop on the caller-owned Node main thread. */
5
- const runVisibleRuntimeHost = async ({ platform, arch, resolvePackageJson, nativeLoader, ...hostOptions } = {}) => {
6
- const binding = await loadOpenTrayRuntimeBinding({
7
- ...platform === void 0 ? {} : { platform },
8
- ...arch === void 0 ? {} : { arch },
9
- ...resolvePackageJson === void 0 ? {} : { resolvePackageJson },
10
- ...nativeLoader === void 0 ? {} : { nativeLoader }
11
- });
12
- if (binding.runVisibleRuntimeHost === void 0) throw new Error("OpenTray runtime binding does not expose runVisibleRuntimeHost()");
13
- binding.runVisibleRuntimeHost(hostOptions);
14
- };
15
- //#endregion
16
- //#region src/node-app.ts
17
- /** Run a self-contained tray app without exposing host-thread choreography. */
18
- const runTrayApp = async (main, options = {}) => {
19
- if (typeof main !== "function") throw new TypeError("main must be a function");
20
- const worker = new Worker(createTrayAppWorkerSource(), {
21
- eval: true,
22
- workerData: {
23
- mainSource: main.toString(),
24
- sdkUrl: resolveWorkerSdkUrl(),
25
- runtimeOptions: {
26
- ...options.packageVersion === void 0 ? {} : { packageVersion: options.packageVersion },
27
- ...options.clientVersion === void 0 ? {} : { clientVersion: options.clientVersion },
28
- ...options.protocolVersion === void 0 ? {} : { protocolVersion: options.protocolVersion },
29
- ...options.appId === void 0 ? {} : { appId: options.appId },
30
- ...options.appName === void 0 ? {} : { appName: options.appName }
31
- },
32
- startupDelayMs: normalizeDelay(options.startupDelayMs)
33
- }
34
- });
35
- await waitForWorkerOnline(worker);
36
- worker.postMessage("start");
37
- try {
38
- await runVisibleRuntimeHost({
39
- ...options.packageVersion === void 0 ? {} : { packageVersion: options.packageVersion },
40
- ...options.appId === void 0 ? {} : { appId: options.appId },
41
- ...options.appName === void 0 ? {} : { appName: options.appName },
42
- ...options.autoExitAfterMs === void 0 ? {} : { autoExitAfterMs: options.autoExitAfterMs }
43
- });
44
- } finally {
45
- await worker.terminate();
46
- }
47
- };
48
- const createTrayAppWorkerSource = () => `
49
- const { parentPort, workerData } = require("node:worker_threads");
50
-
51
- const delay = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
52
- const isStartMessage = (value) => value === "start";
53
-
54
- if (parentPort === null) {
55
- throw new Error("OpenTray tray app worker requires a parent port");
56
- }
57
-
58
- import(workerData.sdkUrl)
59
- .then(({ createTray: rawCreateTray }) => {
60
- const createTray = (options) =>
61
- rawCreateTray(options, workerData.runtimeOptions);
62
- const main = eval("(" + workerData.mainSource + ")");
63
-
64
- parentPort.postMessage("online");
65
- parentPort.once("message", async (message) => {
66
- if (!isStartMessage(message)) {
67
- return;
68
- }
69
- if (workerData.startupDelayMs > 0) {
70
- await delay(workerData.startupDelayMs);
71
- }
72
- await main({ createTray });
73
- parentPort.postMessage("done");
74
- });
75
- })
76
- .catch((error) => {
77
- throw error;
78
- });
79
- `;
80
- const normalizeDelay = (value) => {
81
- if (value === void 0) return 250;
82
- if (!Number.isFinite(value) || value < 0) throw new Error(`startupDelayMs must be a non-negative number: ${value}`);
83
- return value;
84
- };
85
- const resolveWorkerSdkUrl = () => import.meta.url.endsWith(".mjs") ? new URL("./sdk.mjs", import.meta.url).href : new URL("./sdk.ts", import.meta.url).href;
86
- const waitForWorkerOnline = async (worker) => new Promise((resolve, reject) => {
87
- const onMessage = (value) => {
88
- if (value === "online") {
89
- cleanup();
90
- resolve();
91
- return;
92
- }
93
- };
94
- const onError = (error) => {
95
- cleanup();
96
- reject(error);
97
- };
98
- const onExit = (code) => {
99
- if (code !== 0) {
100
- cleanup();
101
- reject(/* @__PURE__ */ new Error(`tray app worker exited with code ${code}`));
102
- }
103
- };
104
- const cleanup = () => {
105
- worker.off("message", onMessage);
106
- worker.off("error", onError);
107
- worker.off("exit", onExit);
108
- };
109
- worker.on("message", onMessage);
110
- worker.on("error", onError);
111
- worker.on("exit", onExit);
112
- });
113
- //#endregion
114
- export { MissingPlatformRuntimeBindingError, createRuntimeBindingTransport, createTrayAppWorkerSource, loadOpenTrayRuntimeBinding, resolveInstalledRuntimeBindingPath, resolveRuntimeNativeTarget, runTrayApp, runVisibleRuntimeHost };
115
-
116
- //# sourceMappingURL=node.mjs.map
package/dist/node.mjs.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"node.mjs","names":[],"sources":["../src/node-host.ts","../src/node-app.ts"],"sourcesContent":["import {\n loadOpenTrayRuntimeBinding,\n type OpenTrayVisibleRuntimeHostOptions,\n type ResolveRuntimeBindingOptions,\n} from \"./native-runtime\";\n\n/** Options for resolving the native binding and running the visible host loop. */\nexport interface RunVisibleRuntimeHostOptions\n extends ResolveRuntimeBindingOptions,\n OpenTrayVisibleRuntimeHostOptions {}\n\n/** Run the visible native host loop on the caller-owned Node main thread. */\nexport const runVisibleRuntimeHost = async ({\n platform,\n arch,\n resolvePackageJson,\n nativeLoader,\n ...hostOptions\n}: RunVisibleRuntimeHostOptions = {}): Promise<void> => {\n const binding = await loadOpenTrayRuntimeBinding({\n ...(platform === undefined ? {} : { platform }),\n ...(arch === undefined ? {} : { arch }),\n ...(resolvePackageJson === undefined ? {} : { resolvePackageJson }),\n ...(nativeLoader === undefined ? {} : { nativeLoader }),\n });\n if (binding.runVisibleRuntimeHost === undefined) {\n throw new Error(\n \"OpenTray runtime binding does not expose runVisibleRuntimeHost()\"\n );\n }\n binding.runVisibleRuntimeHost(hostOptions);\n};\n\nexport {\n MissingPlatformRuntimeBindingError,\n resolveInstalledRuntimeBindingPath,\n resolveRuntimeNativeTarget,\n loadOpenTrayRuntimeBinding,\n type OpenTrayRuntimeBinding,\n type OpenTrayRuntimeBindingInfo,\n type OpenTrayVisibleRuntimeHostOptions,\n type ResolveRuntimeBindingOptions,\n type RuntimeNativeTarget,\n} from \"./native-runtime\";\nexport {\n createRuntimeBindingTransport,\n type CreateRuntimeBindingTransportOptions,\n} from \"./runtime-binding-transport\";\n","import { Worker } from \"node:worker_threads\";\n\nimport type { EventfulTrayHandle } from \"./client\";\nimport type { TrayOptions } from \"@opentray/spec\";\nimport { runVisibleRuntimeHost } from \"./node-host\";\n\nexport interface RunTrayAppOptions {\n /** Runtime package version used for host state partitioning and diagnostics. */\n readonly packageVersion?: string;\n /** Client version reported to the runtime host handshake. */\n readonly clientVersion?: string;\n /** Protocol version reported to the runtime host handshake. */\n readonly protocolVersion?: number;\n /** App identity for diagnostics and runtime isolation. */\n readonly appId?: string;\n /** Human-readable app identity for diagnostics. */\n readonly appName?: string;\n /** Optional finite runtime window for examples and smoke tests. */\n readonly autoExitAfterMs?: number;\n /** Delay before the worker callback runs, giving the visible host time to boot. */\n readonly startupDelayMs?: number;\n}\n\nexport interface TrayAppContext {\n /** Create a tray in the app worker while the helper owns the visible host loop. */\n createTray(options: TrayOptions): Promise<EventfulTrayHandle>;\n}\n\n/**\n * First-app entrypoint executed inside the app worker.\n *\n * Keep the callback self-contained. Imports needed by the callback should be\n * dynamic imports inside the callback because the helper runs it in a worker.\n */\nexport type TrayAppMain = (context: TrayAppContext) => void | Promise<void>;\n\ninterface RunTrayAppWorkerData {\n readonly mainSource: string;\n readonly sdkUrl: string;\n readonly runtimeOptions: {\n readonly packageVersion?: string;\n readonly clientVersion?: string;\n readonly protocolVersion?: number;\n readonly appId?: string;\n readonly appName?: string;\n };\n readonly startupDelayMs: number;\n}\n\n/** Run a self-contained tray app without exposing host-thread choreography. */\nexport const runTrayApp = async (\n main: TrayAppMain,\n options: RunTrayAppOptions = {}\n): Promise<void> => {\n if (typeof main !== \"function\") {\n throw new TypeError(\"main must be a function\");\n }\n\n const worker = new Worker(createTrayAppWorkerSource(), {\n eval: true,\n workerData: {\n mainSource: main.toString(),\n sdkUrl: resolveWorkerSdkUrl(),\n runtimeOptions: {\n ...(options.packageVersion === undefined\n ? {}\n : { packageVersion: options.packageVersion }),\n ...(options.clientVersion === undefined\n ? {}\n : { clientVersion: options.clientVersion }),\n ...(options.protocolVersion === undefined\n ? {}\n : { protocolVersion: options.protocolVersion }),\n ...(options.appId === undefined ? {} : { appId: options.appId }),\n ...(options.appName === undefined ? {} : { appName: options.appName }),\n },\n startupDelayMs: normalizeDelay(options.startupDelayMs),\n } satisfies RunTrayAppWorkerData,\n });\n\n await waitForWorkerOnline(worker);\n worker.postMessage(\"start\");\n\n try {\n await runVisibleRuntimeHost({\n ...(options.packageVersion === undefined\n ? {}\n : { packageVersion: options.packageVersion }),\n ...(options.appId === undefined ? {} : { appId: options.appId }),\n ...(options.appName === undefined ? {} : { appName: options.appName }),\n ...(options.autoExitAfterMs === undefined\n ? {}\n : { autoExitAfterMs: options.autoExitAfterMs }),\n });\n } finally {\n await worker.terminate();\n }\n}\n\nexport const createTrayAppWorkerSource = (): string => `\n const { parentPort, workerData } = require(\"node:worker_threads\");\n\n const delay = (ms) => new Promise((resolve) => setTimeout(resolve, ms));\n const isStartMessage = (value) => value === \"start\";\n\n if (parentPort === null) {\n throw new Error(\"OpenTray tray app worker requires a parent port\");\n }\n\n import(workerData.sdkUrl)\n .then(({ createTray: rawCreateTray }) => {\n const createTray = (options) =>\n rawCreateTray(options, workerData.runtimeOptions);\n const main = eval(\"(\" + workerData.mainSource + \")\");\n\n parentPort.postMessage(\"online\");\n parentPort.once(\"message\", async (message) => {\n if (!isStartMessage(message)) {\n return;\n }\n if (workerData.startupDelayMs > 0) {\n await delay(workerData.startupDelayMs);\n }\n await main({ createTray });\n parentPort.postMessage(\"done\");\n });\n })\n .catch((error) => {\n throw error;\n });\n`;\n\nconst normalizeDelay = (value: number | undefined): number => {\n if (value === undefined) {\n return 250;\n }\n if (!Number.isFinite(value) || value < 0) {\n throw new Error(`startupDelayMs must be a non-negative number: ${value}`);\n }\n return value;\n};\n\nconst resolveWorkerSdkUrl = (): string =>\n import.meta.url.endsWith(\".mjs\")\n ? new URL(\"./sdk.mjs\", import.meta.url).href\n : new URL(\"./sdk.ts\", import.meta.url).href;\n\nconst waitForWorkerOnline = async (worker: Worker): Promise<void> =>\n new Promise((resolve, reject) => {\n const onMessage = (value: unknown): void => {\n if (value === \"online\") {\n cleanup();\n resolve();\n return;\n }\n };\n const onError = (error: Error): void => {\n cleanup();\n reject(error);\n };\n const onExit = (code: number): void => {\n if (code !== 0) {\n cleanup();\n reject(new Error(`tray app worker exited with code ${code}`));\n }\n };\n const cleanup = (): void => {\n worker.off(\"message\", onMessage);\n worker.off(\"error\", onError);\n worker.off(\"exit\", onExit);\n };\n\n worker.on(\"message\", onMessage);\n worker.on(\"error\", onError);\n worker.on(\"exit\", onExit);\n });\n"],"mappings":";;;;AAYA,MAAa,wBAAwB,OAAO,EAC1C,UACA,MACA,oBACA,cACA,GAAG,gBAC6B,CAAC,MAAqB;CACtD,MAAM,UAAU,MAAM,2BAA2B;EAC/C,GAAI,aAAa,KAAA,IAAY,CAAC,IAAI,EAAE,SAAS;EAC7C,GAAI,SAAS,KAAA,IAAY,CAAC,IAAI,EAAE,KAAK;EACrC,GAAI,uBAAuB,KAAA,IAAY,CAAC,IAAI,EAAE,mBAAmB;EACjE,GAAI,iBAAiB,KAAA,IAAY,CAAC,IAAI,EAAE,aAAa;CACvD,CAAC;CACD,IAAI,QAAQ,0BAA0B,KAAA,GACpC,MAAM,IAAI,MACR,kEACF;CAEF,QAAQ,sBAAsB,WAAW;AAC3C;;;;ACmBA,MAAa,aAAa,OACxB,MACA,UAA6B,CAAC,MACZ;CAClB,IAAI,OAAO,SAAS,YAClB,MAAM,IAAI,UAAU,yBAAyB;CAG/C,MAAM,SAAS,IAAI,OAAO,0BAA0B,GAAG;EACrD,MAAM;EACN,YAAY;GACV,YAAY,KAAK,SAAS;GAC1B,QAAQ,oBAAoB;GAC5B,gBAAgB;IACd,GAAI,QAAQ,mBAAmB,KAAA,IAC3B,CAAC,IACD,EAAE,gBAAgB,QAAQ,eAAe;IAC7C,GAAI,QAAQ,kBAAkB,KAAA,IAC1B,CAAC,IACD,EAAE,eAAe,QAAQ,cAAc;IAC3C,GAAI,QAAQ,oBAAoB,KAAA,IAC5B,CAAC,IACD,EAAE,iBAAiB,QAAQ,gBAAgB;IAC/C,GAAI,QAAQ,UAAU,KAAA,IAAY,CAAC,IAAI,EAAE,OAAO,QAAQ,MAAM;IAC9D,GAAI,QAAQ,YAAY,KAAA,IAAY,CAAC,IAAI,EAAE,SAAS,QAAQ,QAAQ;GACtE;GACA,gBAAgB,eAAe,QAAQ,cAAc;EACvD;CACF,CAAC;CAED,MAAM,oBAAoB,MAAM;CAChC,OAAO,YAAY,OAAO;CAE1B,IAAI;EACF,MAAM,sBAAsB;GAC1B,GAAI,QAAQ,mBAAmB,KAAA,IAC3B,CAAC,IACD,EAAE,gBAAgB,QAAQ,eAAe;GAC7C,GAAI,QAAQ,UAAU,KAAA,IAAY,CAAC,IAAI,EAAE,OAAO,QAAQ,MAAM;GAC9D,GAAI,QAAQ,YAAY,KAAA,IAAY,CAAC,IAAI,EAAE,SAAS,QAAQ,QAAQ;GACpE,GAAI,QAAQ,oBAAoB,KAAA,IAC5B,CAAC,IACD,EAAE,iBAAiB,QAAQ,gBAAgB;EACjD,CAAC;CACH,UAAU;EACR,MAAM,OAAO,UAAU;CACzB;AACF;AAEA,MAAa,kCAA0C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAiCvD,MAAM,kBAAkB,UAAsC;CAC5D,IAAI,UAAU,KAAA,GACZ,OAAO;CAET,IAAI,CAAC,OAAO,SAAS,KAAK,KAAK,QAAQ,GACrC,MAAM,IAAI,MAAM,iDAAiD,OAAO;CAE1E,OAAO;AACT;AAEA,MAAM,4BACJ,OAAO,KAAK,IAAI,SAAS,MAAM,IAC3B,IAAI,IAAI,aAAa,OAAO,KAAK,GAAG,EAAE,OACtC,IAAI,IAAI,YAAY,OAAO,KAAK,GAAG,EAAE;AAE3C,MAAM,sBAAsB,OAAO,WACjC,IAAI,SAAS,SAAS,WAAW;CAC/B,MAAM,aAAa,UAAyB;EAC1C,IAAI,UAAU,UAAU;GACtB,QAAQ;GACR,QAAQ;GACR;EACF;CACF;CACA,MAAM,WAAW,UAAuB;EACtC,QAAQ;EACR,OAAO,KAAK;CACd;CACA,MAAM,UAAU,SAAuB;EACrC,IAAI,SAAS,GAAG;GACd,QAAQ;GACR,uBAAO,IAAI,MAAM,oCAAoC,MAAM,CAAC;EAC9D;CACF;CACA,MAAM,gBAAsB;EAC1B,OAAO,IAAI,WAAW,SAAS;EAC/B,OAAO,IAAI,SAAS,OAAO;EAC3B,OAAO,IAAI,QAAQ,MAAM;CAC3B;CAEA,OAAO,GAAG,WAAW,SAAS;CAC9B,OAAO,GAAG,SAAS,OAAO;CAC1B,OAAO,GAAG,QAAQ,MAAM;AAC1B,CAAC"}
@@ -1,177 +0,0 @@
1
- import { createRequire } from "node:module";
2
- import { PROTOCOL_VERSION, parseServerFrame } from "@opentray/spec";
3
- import { dirname, join } from "node:path";
4
- import { constants } from "node:fs";
5
- import { access } from "node:fs/promises";
6
- //#region src/native-runtime.ts
7
- const requireFromSource = createRequire(import.meta.url);
8
- const runtimeBindingRelativePath = "runtime/opentray_runtime.node";
9
- const resolveRuntimeNativeTarget = (platform = process.platform, arch = process.arch) => {
10
- return {
11
- packageName: `@opentray/${platformToPackageOs(platform)}-${normalizeArch(arch)}`,
12
- bindingRelativePath: runtimeBindingRelativePath
13
- };
14
- };
15
- const resolveInstalledRuntimeBindingPath = async ({ platform = process.platform, arch = process.arch, resolvePackageJson = resolvePackageJsonFromSource } = {}) => {
16
- const target = resolveRuntimeNativeTarget(platform, arch);
17
- const packageJsonPath = resolvePackageJson(target.packageName);
18
- if (packageJsonPath === void 0) throw new MissingPlatformRuntimeBindingError(`unable to resolve OpenTray runtime binding for ${platform}/${arch}; install ${target.packageName}`, platform, arch, { packageName: target.packageName });
19
- const bindingPath = join(dirname(packageJsonPath), target.bindingRelativePath);
20
- if (!await exists(bindingPath)) throw new MissingPlatformRuntimeBindingError(`OpenTray runtime package ${target.packageName} is installed but missing ${target.bindingRelativePath}`, platform, arch, {
21
- packageName: target.packageName,
22
- bindingPath
23
- });
24
- return bindingPath;
25
- };
26
- const loadOpenTrayRuntimeBinding = async (options = {}) => {
27
- const bindingPath = await resolveInstalledRuntimeBindingPath(options);
28
- const loaded = (options.nativeLoader ?? loadNativeModule)(bindingPath);
29
- if (!isRuntimeBinding(loaded)) throw new MissingPlatformRuntimeBindingError(`OpenTray runtime binding ${bindingPath} does not expose runtimeBindingInfo()`, options.platform ?? process.platform, options.arch ?? process.arch, { bindingPath });
30
- return loaded;
31
- };
32
- const loadNativeModule = (bindingPath) => requireFromSource(bindingPath);
33
- const isRuntimeBinding = (value) => {
34
- if (typeof value !== "object" || value === null || !("runtimeBindingInfo" in value)) return false;
35
- return typeof value.runtimeBindingInfo === "function";
36
- };
37
- const platformToPackageOs = (platform) => {
38
- switch (platform) {
39
- case "darwin":
40
- case "linux": return platform;
41
- case "win32": return "windows";
42
- default: throw new MissingPlatformRuntimeBindingError(`unsupported OpenTray runtime platform: ${platform}`, platform, process.arch);
43
- }
44
- };
45
- const normalizeArch = (arch) => {
46
- switch (arch) {
47
- case "arm64":
48
- case "x64": return arch;
49
- default: throw new MissingPlatformRuntimeBindingError(`unsupported OpenTray runtime architecture: ${arch}`, process.platform, arch);
50
- }
51
- };
52
- const resolvePackageJsonFromSource = (packageName) => {
53
- try {
54
- return requireFromSource.resolve(`${packageName}/package.json`);
55
- } catch (error) {
56
- if (isNodeError(error) && error.code === "MODULE_NOT_FOUND") return;
57
- throw error;
58
- }
59
- };
60
- const exists = async (path) => {
61
- try {
62
- await access(path, constants.F_OK);
63
- return true;
64
- } catch {
65
- return false;
66
- }
67
- };
68
- const isNodeError = (error) => error instanceof Error && "code" in error;
69
- var MissingPlatformRuntimeBindingError = class extends Error {
70
- code = "OPENTRAY_MISSING_PLATFORM_RUNTIME_BINDING";
71
- platform;
72
- arch;
73
- packageName;
74
- bindingPath;
75
- constructor(message, platform, arch, options = {}) {
76
- super(message, options.cause === void 0 ? void 0 : { cause: options.cause });
77
- this.name = "MissingPlatformRuntimeBindingError";
78
- this.platform = platform;
79
- this.arch = arch;
80
- this.packageName = options.packageName;
81
- this.bindingPath = options.bindingPath;
82
- }
83
- };
84
- //#endregion
85
- //#region src/runtime-binding-transport.ts
86
- const createRuntimeBindingTransport = async ({ binding, packageVersion = "0.0.0", clientVersion = packageVersion, protocolVersion = PROTOCOL_VERSION, appId, appName, kind = "visible" } = {}) => {
87
- const resolvedBinding = binding ?? await loadOpenTrayRuntimeBinding();
88
- const transport = new RuntimeBindingTransport(kind === "headless" ? createHeadlessRuntime(resolvedBinding, packageVersion, appId, appName) : createVisibleRuntime(resolvedBinding));
89
- await transport.init(clientVersion, protocolVersion);
90
- return transport;
91
- };
92
- const createVisibleRuntime = (binding) => {
93
- if (binding.createVisibleRuntime === void 0) throw new Error("OpenTray runtime binding does not expose createVisibleRuntime()");
94
- return binding.createVisibleRuntime();
95
- };
96
- const createHeadlessRuntime = (binding, packageVersion, appId, appName) => {
97
- if (binding.createHeadlessRuntime === void 0) throw new Error("OpenTray runtime binding does not expose createHeadlessRuntime()");
98
- return binding.createHeadlessRuntime(packageVersion, appId, appName);
99
- };
100
- var RuntimeBindingTransport = class {
101
- listeners = /* @__PURE__ */ new Set();
102
- runtime;
103
- pollInterval;
104
- constructor(runtime) {
105
- this.runtime = runtime;
106
- this.pollInterval = runtime.pollEvents === void 0 ? void 0 : setInterval(() => {
107
- this.pollRuntimeEvents().catch(() => {});
108
- }, 50);
109
- this.pollInterval?.unref();
110
- }
111
- async init(clientVersion, protocolVersion) {
112
- if ((await this.invoke({
113
- type: "init",
114
- protocolVersion,
115
- clientVersion
116
- })).find((frame) => frame.type === "ready") === void 0) throw new Error("OpenTray runtime binding did not return a ready frame");
117
- }
118
- async request(frame) {
119
- const response = (await this.invoke(frame)).find((candidate) => responseRequestId(candidate) === frame.requestId);
120
- if (response === void 0) throw new Error(`OpenTray runtime binding did not return response for requestId: ${frame.requestId}`);
121
- return response;
122
- }
123
- onEvent(listener) {
124
- this.listeners.add(listener);
125
- return () => {
126
- this.listeners.delete(listener);
127
- };
128
- }
129
- async close() {
130
- if (this.pollInterval !== void 0) clearInterval(this.pollInterval);
131
- const frames = await this.parseFrames(await this.runtime.close());
132
- this.dispatchEvents(frames);
133
- }
134
- async invoke(frame) {
135
- const frames = await this.parseFrames(await this.runtime.request(JSON.stringify(frame)));
136
- this.dispatchEvents(frames);
137
- return frames;
138
- }
139
- async parseFrames(frameJson) {
140
- return (await frameJson).map((raw) => {
141
- const parsed = parseServerFrame(raw);
142
- if (!parsed.ok || parsed.frame === void 0) throw new Error(`${parsed.error ?? "invalid server frame"}: ${raw}`);
143
- return parsed.frame;
144
- });
145
- }
146
- dispatchEvents(frames) {
147
- for (const frame of frames) {
148
- if (frame.type !== "event" && frame.type !== "ext-event") continue;
149
- for (const listener of this.listeners) listener(frame);
150
- }
151
- }
152
- async pollRuntimeEvents() {
153
- const pollEvents = this.runtime.pollEvents;
154
- if (pollEvents === void 0) return;
155
- const frames = await this.parseFrames(await pollEvents.call(this.runtime));
156
- this.dispatchEvents(frames);
157
- }
158
- };
159
- const responseRequestId = (frame) => {
160
- switch (frame.type) {
161
- case "app-created":
162
- case "default-app":
163
- case "tray-created":
164
- case "tray-bounds":
165
- case "ack":
166
- case "ext-command-result":
167
- case "runtime-host-health": return frame.requestId;
168
- case "ready":
169
- case "event":
170
- case "ext-event":
171
- case "error": return;
172
- }
173
- };
174
- //#endregion
175
- export { resolveRuntimeNativeTarget as a, resolveInstalledRuntimeBindingPath as i, MissingPlatformRuntimeBindingError as n, loadOpenTrayRuntimeBinding as r, createRuntimeBindingTransport as t };
176
-
177
- //# sourceMappingURL=runtime-binding-transport-UPunusBT.mjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"runtime-binding-transport-UPunusBT.mjs","names":["binding"],"sources":["../src/native-runtime.ts","../src/runtime-binding-transport.ts"],"sourcesContent":["import { access } from \"node:fs/promises\";\nimport { constants } from \"node:fs\";\nimport { createRequire } from \"node:module\";\nimport { dirname, join } from \"node:path\";\n\nconst requireFromSource = createRequire(import.meta.url);\n\nexport interface OpenTrayRuntimeBindingInfo {\n readonly kind: string;\n readonly protocolVersion: number;\n}\n\nexport interface OpenTrayRuntimeBinding {\n runtimeBindingInfo(): OpenTrayRuntimeBindingInfo;\n runVisibleRuntimeHost?(options?: OpenTrayVisibleRuntimeHostOptions): void;\n createVisibleRuntime?(): OpenTrayVisibleRuntime;\n createHeadlessRuntime?(\n packageVersion?: string,\n appId?: string,\n appName?: string\n ): OpenTrayHeadlessRuntime;\n}\n\nexport interface OpenTrayVisibleRuntimeHostOptions {\n readonly packageVersion?: string;\n readonly appId?: string;\n readonly appName?: string;\n readonly autoExitAfterMs?: number;\n}\n\nexport interface OpenTrayRuntimeHost {\n request(frameJson: string): string[] | Promise<string[]>;\n close(): string[] | Promise<string[]>;\n}\n\nexport interface OpenTrayVisibleRuntime extends OpenTrayRuntimeHost {\n pollEvents(): string[] | Promise<string[]>;\n}\n\nexport type OpenTrayHeadlessRuntime = OpenTrayRuntimeHost;\n\nexport interface RuntimeNativeTarget {\n readonly packageName: string;\n readonly bindingRelativePath: string;\n}\n\nexport interface ResolveRuntimeBindingOptions {\n readonly platform?: string;\n readonly arch?: string;\n readonly resolvePackageJson?: (packageName: string) => string | undefined;\n readonly nativeLoader?: (bindingPath: string) => unknown;\n}\n\nexport const runtimeBindingRelativePath = \"runtime/opentray_runtime.node\";\n\nexport const resolveRuntimeNativeTarget = (\n platform: string = process.platform,\n arch: string = process.arch\n): RuntimeNativeTarget => {\n const packageOs = platformToPackageOs(platform);\n const nativeArch = normalizeArch(arch);\n return {\n packageName: `@opentray/${packageOs}-${nativeArch}`,\n bindingRelativePath: runtimeBindingRelativePath,\n };\n};\n\nexport const resolveInstalledRuntimeBindingPath = async ({\n platform = process.platform,\n arch = process.arch,\n resolvePackageJson = resolvePackageJsonFromSource,\n}: ResolveRuntimeBindingOptions = {}): Promise<string> => {\n const target = resolveRuntimeNativeTarget(platform, arch);\n const packageJsonPath = resolvePackageJson(target.packageName);\n if (packageJsonPath === undefined) {\n throw new MissingPlatformRuntimeBindingError(\n `unable to resolve OpenTray runtime binding for ${platform}/${arch}; install ${target.packageName}`,\n platform,\n arch,\n { packageName: target.packageName }\n );\n }\n\n const bindingPath = join(\n dirname(packageJsonPath),\n target.bindingRelativePath\n );\n if (!(await exists(bindingPath))) {\n throw new MissingPlatformRuntimeBindingError(\n `OpenTray runtime package ${target.packageName} is installed but missing ${target.bindingRelativePath}`,\n platform,\n arch,\n {\n packageName: target.packageName,\n bindingPath,\n }\n );\n }\n return bindingPath;\n};\n\nexport const loadOpenTrayRuntimeBinding = async (\n options: ResolveRuntimeBindingOptions = {}\n): Promise<OpenTrayRuntimeBinding> => {\n const bindingPath = await resolveInstalledRuntimeBindingPath(options);\n const loaded = (options.nativeLoader ?? loadNativeModule)(bindingPath);\n if (!isRuntimeBinding(loaded)) {\n throw new MissingPlatformRuntimeBindingError(\n `OpenTray runtime binding ${bindingPath} does not expose runtimeBindingInfo()`,\n options.platform ?? process.platform,\n options.arch ?? process.arch,\n { bindingPath }\n );\n }\n return loaded;\n};\n\nconst loadNativeModule = (bindingPath: string): unknown =>\n requireFromSource(bindingPath);\n\nconst isRuntimeBinding = (value: unknown): value is OpenTrayRuntimeBinding => {\n if (\n typeof value !== \"object\" ||\n value === null ||\n !(\"runtimeBindingInfo\" in value)\n ) {\n return false;\n }\n const binding = value as { runtimeBindingInfo?: unknown };\n return typeof binding.runtimeBindingInfo === \"function\";\n};\n\nconst platformToPackageOs = (\n platform: string\n): \"darwin\" | \"linux\" | \"windows\" => {\n switch (platform) {\n case \"darwin\":\n case \"linux\":\n return platform;\n case \"win32\":\n return \"windows\";\n default:\n throw new MissingPlatformRuntimeBindingError(\n `unsupported OpenTray runtime platform: ${platform}`,\n platform,\n process.arch\n );\n }\n};\n\nconst normalizeArch = (arch: string): \"arm64\" | \"x64\" => {\n switch (arch) {\n case \"arm64\":\n case \"x64\":\n return arch;\n default:\n throw new MissingPlatformRuntimeBindingError(\n `unsupported OpenTray runtime architecture: ${arch}`,\n process.platform,\n arch\n );\n }\n};\n\nconst resolvePackageJsonFromSource = (\n packageName: string\n): string | undefined => {\n try {\n return requireFromSource.resolve(`${packageName}/package.json`);\n } catch (error) {\n if (isNodeError(error) && error.code === \"MODULE_NOT_FOUND\") {\n return undefined;\n }\n throw error;\n }\n};\n\nconst exists = async (path: string): Promise<boolean> => {\n try {\n await access(path, constants.F_OK);\n return true;\n } catch {\n return false;\n }\n};\n\nconst isNodeError = (error: unknown): error is NodeJS.ErrnoException =>\n error instanceof Error && \"code\" in error;\n\nexport class MissingPlatformRuntimeBindingError extends Error {\n readonly code = \"OPENTRAY_MISSING_PLATFORM_RUNTIME_BINDING\";\n readonly platform: string;\n readonly arch: string;\n readonly packageName: string | undefined;\n readonly bindingPath: string | undefined;\n\n constructor(\n message: string,\n platform: string,\n arch: string,\n options: {\n readonly packageName?: string;\n readonly bindingPath?: string;\n readonly cause?: unknown;\n } = {}\n ) {\n super(\n message,\n options.cause === undefined ? undefined : { cause: options.cause }\n );\n this.name = \"MissingPlatformRuntimeBindingError\";\n this.platform = platform;\n this.arch = arch;\n this.packageName = options.packageName;\n this.bindingPath = options.bindingPath;\n }\n}\n","import {\n PROTOCOL_VERSION,\n parseServerFrame,\n type ClientRequestFrame,\n type RequestId,\n type ServerFrame,\n} from \"@opentray/spec\";\n\nimport type { OpenTrayConnection, OpenTrayEventFrame } from \"./client\";\nimport {\n loadOpenTrayRuntimeBinding,\n type OpenTrayRuntimeHost,\n type OpenTrayRuntimeBinding,\n type OpenTrayVisibleRuntime,\n} from \"./native-runtime\";\n\nexport type RuntimeBindingTransportKind = \"visible\" | \"headless\";\n\nexport interface CreateRuntimeBindingTransportOptions {\n readonly kind?: RuntimeBindingTransportKind;\n readonly binding?: OpenTrayRuntimeBinding;\n readonly packageVersion?: string;\n readonly clientVersion?: string;\n readonly protocolVersion?: number;\n readonly appId?: string;\n readonly appName?: string;\n}\n\nexport const createRuntimeBindingTransport = async ({\n binding,\n packageVersion = \"0.0.0\",\n clientVersion = packageVersion,\n protocolVersion = PROTOCOL_VERSION,\n appId,\n appName,\n kind = \"visible\",\n}: CreateRuntimeBindingTransportOptions = {}): Promise<OpenTrayConnection> => {\n const resolvedBinding = binding ?? (await loadOpenTrayRuntimeBinding());\n const runtime =\n kind === \"headless\"\n ? createHeadlessRuntime(resolvedBinding, packageVersion, appId, appName)\n : createVisibleRuntime(resolvedBinding);\n const transport = new RuntimeBindingTransport(runtime);\n await transport.init(clientVersion, protocolVersion);\n return transport;\n};\n\nconst createVisibleRuntime = (\n binding: OpenTrayRuntimeBinding\n): OpenTrayVisibleRuntime => {\n if (binding.createVisibleRuntime === undefined) {\n throw new Error(\n \"OpenTray runtime binding does not expose createVisibleRuntime()\"\n );\n }\n return binding.createVisibleRuntime();\n};\n\nconst createHeadlessRuntime = (\n binding: OpenTrayRuntimeBinding,\n packageVersion: string,\n appId: string | undefined,\n appName: string | undefined\n): OpenTrayRuntimeHost => {\n if (binding.createHeadlessRuntime === undefined) {\n throw new Error(\n \"OpenTray runtime binding does not expose createHeadlessRuntime()\"\n );\n }\n return binding.createHeadlessRuntime(packageVersion, appId, appName);\n};\n\ntype RuntimeFrameInvoker = (frameJson: string) => string[] | Promise<string[]>;\n\ninterface RuntimeBindingHost extends OpenTrayRuntimeHost {\n request: RuntimeFrameInvoker;\n pollEvents?(): string[] | Promise<string[]>;\n}\n\nclass RuntimeBindingTransport implements OpenTrayConnection {\n private readonly listeners = new Set<(frame: OpenTrayEventFrame) => void>();\n private readonly runtime: RuntimeBindingHost;\n private readonly pollInterval: NodeJS.Timeout | undefined;\n\n constructor(runtime: RuntimeBindingHost) {\n this.runtime = runtime;\n this.pollInterval =\n runtime.pollEvents === undefined\n ? undefined\n : setInterval(() => {\n void this.pollRuntimeEvents().catch(() => {\n // Polling is an event ingress path. Request and close failures still surface to callers.\n });\n }, 50);\n this.pollInterval?.unref();\n }\n\n async init(clientVersion: string, protocolVersion: number): Promise<void> {\n const frames = await this.invoke({\n type: \"init\",\n protocolVersion,\n clientVersion,\n });\n const ready = frames.find(\n (frame): frame is Extract<ServerFrame, { type: \"ready\" }> =>\n frame.type === \"ready\"\n );\n if (ready === undefined) {\n throw new Error(\"OpenTray runtime binding did not return a ready frame\");\n }\n }\n\n async request(frame: ClientRequestFrame): Promise<ServerFrame> {\n const frames = await this.invoke(frame);\n const response = frames.find(\n (candidate) => responseRequestId(candidate) === frame.requestId\n );\n if (response === undefined) {\n throw new Error(\n `OpenTray runtime binding did not return response for requestId: ${frame.requestId}`\n );\n }\n return response;\n }\n\n onEvent(listener: (frame: OpenTrayEventFrame) => void): () => void {\n this.listeners.add(listener);\n return () => {\n this.listeners.delete(listener);\n };\n }\n\n async close(): Promise<void> {\n if (this.pollInterval !== undefined) {\n clearInterval(this.pollInterval);\n }\n const frames = await this.parseFrames(await this.runtime.close());\n this.dispatchEvents(frames);\n }\n\n private async invoke(frame: object): Promise<ServerFrame[]> {\n const frames = await this.parseFrames(\n await this.runtime.request(JSON.stringify(frame))\n );\n this.dispatchEvents(frames);\n return frames;\n }\n\n private async parseFrames(\n frameJson: string[] | Promise<string[]>\n ): Promise<ServerFrame[]> {\n const rawFrames = await frameJson;\n return rawFrames.map((raw) => {\n const parsed = parseServerFrame(raw);\n if (!parsed.ok || parsed.frame === undefined) {\n throw new Error(`${parsed.error ?? \"invalid server frame\"}: ${raw}`);\n }\n return parsed.frame;\n });\n }\n\n private dispatchEvents(frames: readonly ServerFrame[]): void {\n for (const frame of frames) {\n if (frame.type !== \"event\" && frame.type !== \"ext-event\") {\n continue;\n }\n for (const listener of this.listeners) {\n listener(frame);\n }\n }\n }\n\n private async pollRuntimeEvents(): Promise<void> {\n const pollEvents = this.runtime.pollEvents;\n if (pollEvents === undefined) {\n return;\n }\n const frames = await this.parseFrames(await pollEvents.call(this.runtime));\n this.dispatchEvents(frames);\n }\n}\n\nconst responseRequestId = (frame: ServerFrame): RequestId | undefined => {\n switch (frame.type) {\n case \"app-created\":\n case \"default-app\":\n case \"tray-created\":\n case \"tray-bounds\":\n case \"ack\":\n case \"ext-command-result\":\n case \"runtime-host-health\":\n return frame.requestId;\n case \"ready\":\n case \"event\":\n case \"ext-event\":\n case \"error\":\n return undefined;\n }\n};\n"],"mappings":"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"}