opentray 0.5.1 → 0.5.2

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
@@ -34,7 +34,7 @@ const space = await createSpace({ id: "com.example.status", default: true });
34
34
  await space.createTray({
35
35
  trayId: "status",
36
36
  title: "Status",
37
- icon: { type: "rgba", data: [0, 0, 0, 0], width: 1, height: 1 },
37
+ icon: { type: "file", path: "./assets/tray-icon.png" },
38
38
  });
39
39
 
40
40
  const defaultSpace = await resolveDefaultSpace();
@@ -42,7 +42,7 @@ await createTray(
42
42
  {
43
43
  trayId: "secondary",
44
44
  title: "Secondary",
45
- icon: { type: "rgba", data: [0, 0, 0, 0], width: 1, height: 1 },
45
+ icon: { type: "file", path: "./assets/tray-icon.png" },
46
46
  },
47
47
  { space: defaultSpace.space }
48
48
  );
@@ -65,6 +65,27 @@ pnpm --filter opentray example:webview-control
65
65
  That demo opens a native WebView window immediately and puts the controls inside the page itself, so you can exercise frameless, transparent, keep-on-top, title, icon, screen, and navigation behavior without going through the tray menu first.
66
66
  Treat `example:webview-control` as the API exercise surface. It is useful for probing capabilities and events, but it is not the canonical recipe for a tray-anchored glass shell.
67
67
 
68
+ Application code mounts WebView as a tray capability. The first WebView command loads the native extension automatically; ordinary code does not need to send `load-ext` manually:
69
+
70
+ ```ts
71
+ import { WebviewExt } from "@opentray/ext-webview";
72
+ import { createTray } from "opentray";
73
+
74
+ const tray = (await createTray({
75
+ trayId: "status",
76
+ title: "Status",
77
+ icon: { type: "file", path: "./tray-icon.png" },
78
+ })).extend(WebviewExt);
79
+
80
+ const panel = tray.createWebviewWindow({
81
+ html: "<main>Status</main>",
82
+ width: 360,
83
+ height: 240,
84
+ });
85
+
86
+ await panel.show();
87
+ ```
88
+
68
89
  Run the dedicated tray-panel demo:
69
90
 
70
91
  ```bash
@@ -91,7 +112,7 @@ Current WebView truth:
91
112
  - some requests are `unsupported by design`, such as asking the macOS runtime to apply a Windows-only style family
92
113
  - some results are `unavailable by context`, such as tray-bounds projection when the current session has no authoritative tray anchor
93
114
 
94
- When run from the repo worktree, the example automatically discovers `target/debug` or `target/release` `libopentray_ext_webview` and wires it through `OPENTRAY_EXT_PATH` before starting the daemon. That keeps the example on the real `load-ext` path without requiring a manual staging step for routine source-level testing.
115
+ When run from the repo worktree, the example automatically discovers `target/debug` or `target/release` `libopentray_ext_webview` and wires it through `OPENTRAY_EXT_PATH` before starting the daemon. The WebView mount still exercises the real generic extension loader, but example users do not author a manual `load-ext` request.
95
116
 
96
117
  After installing from npm, use the published CLI smoke path instead of workspace scripts:
97
118
 
@@ -175,4 +196,4 @@ otool -L target/release/libopentray_ext_webview.dylib
175
196
  otool -L target/release/libopentray_ext_lynx.dylib
176
197
  ```
177
198
 
178
- Current native icon support is `rgba`. `encoded` and `file` are typed protocol shapes, but the native `tray-icon` backend reports them as unsupported until decoding and file loading policy are implemented.
199
+ The native `tray-icon` backend now normalizes `encoded` and `file` icon inputs into RGBA before native tray materialization. `rgba` still works when you already have pixel data, but ordinary app code can point at a PNG file instead of hand-building pixels.
package/dist/cli.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { t as createClient } from "./client-B_zxQOo5.mjs";
2
+ import { t as createClient } from "./client-DzcHIH-f.mjs";
3
3
  import { a as inspectDaemon, c as stopDaemon, i as createNodeDaemonDriver, n as resolveDaemonPaths, o as restartDaemon, r as readPackageVersion, s as startDaemon, t as connectLocalBroker } from "./local-broker-CEIHPBcK.mjs";
4
4
  import { homedir } from "node:os";
5
5
  import { fileURLToPath } from "node:url";
@@ -20,9 +20,34 @@ interface TrayHandle {
20
20
  space: SpaceRef;
21
21
  trayId: TrayId;
22
22
  getBounds(): Promise<TrayBoundsResult>;
23
+ loadExtension(options: ExtensionLoadOptions): Promise<void>;
23
24
  commandExtension(ext: string, data: unknown): Promise<void>;
25
+ extend<TCapability extends object, TOptions = undefined>(extension: TrayExtension<TCapability, TOptions>, options?: TOptions): TrayHandle & TCapability;
24
26
  destroy(): Promise<void>;
25
27
  }
28
+ interface ExtensionLoadOptions {
29
+ name: string;
30
+ path: string;
31
+ mountId?: string;
32
+ }
33
+ interface TrayExtensionMountSpec {
34
+ name?: string;
35
+ path?: string;
36
+ mountId?: string;
37
+ }
38
+ interface TrayExtensionContext {
39
+ readonly name: string;
40
+ readonly path: string;
41
+ readonly mountId: string;
42
+ ensureLoaded(): Promise<void>;
43
+ command(data: unknown): Promise<void>;
44
+ }
45
+ interface TrayExtension<TCapability extends object, TOptions = undefined> {
46
+ readonly name: string;
47
+ readonly path: string;
48
+ resolveMount?(options: TOptions | undefined): TrayExtensionMountSpec;
49
+ extend(tray: TrayHandle, context: TrayExtensionContext, options: TOptions | undefined): TCapability;
50
+ }
26
51
  declare const createInitFrame: (clientVersion: string) => ClientFrame;
27
52
  interface CreateClientOptions {
28
53
  requestIdPrefix?: string;
@@ -33,5 +58,5 @@ declare const createSpaceHandle: (transport: OpenTrayTransport, space: SpaceRef,
33
58
  declare const createSurfaceHandle: (transport: OpenTrayTransport, space: SpaceRef, nextRequestId?: () => RequestId) => SpaceHandle;
34
59
  declare const createTrayHandle: (transport: OpenTrayTransport, space: SpaceRef, trayId: TrayId, nextRequestId?: () => RequestId) => TrayHandle;
35
60
  //#endregion
36
- export { SurfaceHandle as a, createInitFrame as c, createTrayHandle as d, SpaceHandle as i, createSpaceHandle as l, OpenTrayClient as n, TrayHandle as o, OpenTrayTransport as r, createClient as s, CreateClientOptions as t, createSurfaceHandle as u };
37
- //# sourceMappingURL=client-h6gZdeOk.d.mts.map
61
+ export { SpaceHandle as a, TrayExtensionContext as c, createClient as d, createInitFrame as f, createTrayHandle as h, OpenTrayTransport as i, TrayExtensionMountSpec as l, createSurfaceHandle as m, ExtensionLoadOptions as n, SurfaceHandle as o, createSpaceHandle as p, OpenTrayClient as r, TrayExtension as s, CreateClientOptions as t, TrayHandle as u };
62
+ //# sourceMappingURL=client-DQn3DLZw.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client-DQn3DLZw.d.mts","names":[],"sources":["../src/client.ts"],"mappings":";;;UAaiB,iBAAA;EACf,OAAA,CAAQ,KAAA,EAAO,kBAAA,GAAqB,OAAA,CAAQ,WAAA;AAAA;AAAA,UAG7B,cAAA;EACf,WAAA,CAAY,OAAA,EAAS,YAAA,GAAe,OAAA,CAAQ,WAAA;EAC5C,mBAAA,IAAuB,OAAA,CAAQ,WAAA;EALa;EAO5C,aAAA,CAAc,OAAA,EAAS,YAAA,GAAe,OAAA,CAAQ,WAAA;AAAA;AAAA,UAG/B,WAAA;EACf,KAAA,EAAO,QAAA;EACP,UAAA,CAAW,OAAA,EAAS,WAAA,GAAc,OAAA,CAAQ,UAAA;AAAA;;KAIhC,aAAA,GAAgB,WAAW;AAAA,UAEtB,UAAA;EACf,KAAA,EAAO,QAAA;EACP,MAAA,EAAQ,MAAA;EACR,SAAA,IAAa,OAAA,CAAQ,gBAAA;EACrB,aAAA,CAAc,OAAA,EAAS,oBAAA,GAAuB,OAAA;EAC9C,gBAAA,CAAiB,GAAA,UAAa,IAAA,YAAgB,OAAA;EAC9C,MAAA,mDACE,SAAA,EAAW,aAAA,CAAc,WAAA,EAAa,QAAA,GACtC,OAAA,GAAU,QAAA,GACT,UAAA,GAAa,WAAA;EAChB,OAAA,IAAW,OAAA;AAAA;AAAA,UAGI,oBAAA;EACf,IAAA;EACA,IAAA;EACA,OAAA;AAAA;AAAA,UAGe,sBAAA;EACf,IAAA;EACA,IAAA;EACA,OAAA;AAAA;AAAA,UAGe,oBAAA;EAAA,SACN,IAAA;EAAA,SACA,IAAA;EAAA,SACA,OAAA;EACT,YAAA,IAAgB,OAAA;EAChB,OAAA,CAAQ,IAAA,YAAgB,OAAO;AAAA;AAAA,UAGhB,aAAA;EAAA,SACN,IAAA;EAAA,SACA,IAAA;EACT,YAAA,EAAc,OAAA,EAAS,QAAA,eAAuB,sBAAA;EAC9C,MAAA,CAAO,IAAA,EAAM,UAAA,EAAY,OAAA,EAAS,oBAAA,EAAsB,OAAA,EAAS,QAAA,eAAuB,WAAA;AAAA;AAAA,cAG7E,eAAA,GAAmB,aAAA,aAAwB,WAItD;AAAA,UAEe,mBAAA;EACf,eAAe;AAAA;AAAA,cAGJ,YAAA,GACX,SAAA,EAAW,iBAAA,EACX,OAAA,GAAS,mBAAA,KACR,cAAA;AAAA,cA6BU,iBAAA,GACX,SAAA,EAAW,iBAAA,EACX,KAAA,EAAO,QAAA,EACP,aAAA,SAAqB,SAAA,KACpB,WAAA;;cAgBU,mBAAA,GAAmB,SAAA,EAnBnB,iBAAA,EAAiB,KAAA,EACrB,QAAA,EAAQ,aAAA,SACM,SAAA,KACpB,WAAA;AAAA,cAkBU,gBAAA,GACX,SAAA,EAAW,iBAAA,EACX,KAAA,EAAO,QAAA,EACP,MAAA,EAAQ,MAAA,EACR,aAAA,SAAqB,SAAA,KACpB,UAAA"}
@@ -44,39 +44,96 @@ const createSpaceHandle = (transport, space, nextRequestId = createRequestIdFact
44
44
  });
45
45
  /** @deprecated Use `createSpaceHandle`. */
46
46
  const createSurfaceHandle = createSpaceHandle;
47
- const createTrayHandle = (transport, space, trayId, nextRequestId = createRequestIdFactory("opentray")) => ({
48
- space,
49
- trayId,
50
- async getBounds() {
51
- const requestId = nextRequestId();
52
- return expectResponse(await transport.request({
53
- type: "get-tray-bounds",
54
- requestId,
55
- spaceId: space.spaceId,
56
- trayId
57
- }), requestId, "tray-bounds").bounds;
58
- },
59
- async commandExtension(ext, data) {
60
- const requestId = nextRequestId();
61
- expectResponse(await transport.request({
62
- type: "ext-command",
63
- requestId,
64
- spaceId: space.spaceId,
65
- trayId,
66
- ext,
67
- data
68
- }), requestId, "ack");
69
- },
70
- async destroy() {
71
- const requestId = nextRequestId();
72
- expectResponse(await transport.request({
73
- type: "destroy-tray",
74
- requestId,
75
- spaceId: space.spaceId,
76
- trayId
77
- }), requestId, "ack");
78
- }
79
- });
47
+ const createTrayHandle = (transport, space, trayId, nextRequestId = createRequestIdFactory("opentray")) => {
48
+ let nextMountOrdinal = 1;
49
+ const nextMountId = (extensionName) => {
50
+ const mountId = `${formatMountIdComponent(extensionName)}.${formatMountIdComponent(trayId)}.${nextMountOrdinal}`;
51
+ nextMountOrdinal += 1;
52
+ return mountId;
53
+ };
54
+ const handle = {
55
+ space,
56
+ trayId,
57
+ async getBounds() {
58
+ const requestId = nextRequestId();
59
+ return expectResponse(await transport.request({
60
+ type: "get-tray-bounds",
61
+ requestId,
62
+ spaceId: space.spaceId,
63
+ trayId
64
+ }), requestId, "tray-bounds").bounds;
65
+ },
66
+ async loadExtension(options) {
67
+ const requestId = nextRequestId();
68
+ expectResponse(await transport.request({
69
+ type: "load-ext",
70
+ requestId,
71
+ spaceId: space.spaceId,
72
+ name: options.name,
73
+ path: options.path,
74
+ ...options.mountId === void 0 ? {} : { mountId: options.mountId }
75
+ }), requestId, "ack");
76
+ },
77
+ async commandExtension(ext, data) {
78
+ const requestId = nextRequestId();
79
+ expectResponse(await transport.request({
80
+ type: "ext-command",
81
+ requestId,
82
+ spaceId: space.spaceId,
83
+ trayId,
84
+ ext,
85
+ data
86
+ }), requestId, "ack");
87
+ },
88
+ extend(extension, options) {
89
+ const context = createTrayExtensionContext(handle, extension, options, nextMountId);
90
+ const capability = extension.extend(handle, context, options);
91
+ return Object.assign({}, handle, capability);
92
+ },
93
+ async destroy() {
94
+ const requestId = nextRequestId();
95
+ expectResponse(await transport.request({
96
+ type: "destroy-tray",
97
+ requestId,
98
+ spaceId: space.spaceId,
99
+ trayId
100
+ }), requestId, "ack");
101
+ }
102
+ };
103
+ return handle;
104
+ };
105
+ const createTrayExtensionContext = (tray, extension, options, nextMountId) => {
106
+ const mount = extension.resolveMount?.(options) ?? {};
107
+ const name = mount.name ?? extension.name;
108
+ const path = mount.path ?? extension.path;
109
+ const mountId = mount.mountId ?? nextMountId(name);
110
+ let loadPromise;
111
+ const ensureLoaded = async () => {
112
+ if (loadPromise === void 0) loadPromise = tray.loadExtension({
113
+ name,
114
+ path,
115
+ mountId
116
+ }).catch((error) => {
117
+ loadPromise = void 0;
118
+ throw error;
119
+ });
120
+ await loadPromise;
121
+ };
122
+ return {
123
+ name,
124
+ path,
125
+ mountId,
126
+ ensureLoaded,
127
+ async command(data) {
128
+ await ensureLoaded();
129
+ await tray.commandExtension(mountId, data);
130
+ }
131
+ };
132
+ };
133
+ const formatMountIdComponent = (value) => {
134
+ const formatted = value.replaceAll(/[^a-zA-Z0-9._+-]/g, "_");
135
+ return formatted.length > 0 ? formatted : "ext";
136
+ };
80
137
  const createRequestIdFactory = (prefix) => {
81
138
  let next = 1;
82
139
  return () => {
@@ -108,4 +165,4 @@ const requestIdOf = (frame) => {
108
165
  //#endregion
109
166
  export { createTrayHandle as a, createSurfaceHandle as i, createInitFrame as n, createSpaceHandle as r, createClient as t };
110
167
 
111
- //# sourceMappingURL=client-B_zxQOo5.mjs.map
168
+ //# sourceMappingURL=client-DzcHIH-f.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client-DzcHIH-f.mjs","names":[],"sources":["../src/client.ts"],"sourcesContent":["import {\n PROTOCOL_VERSION,\n type ClientFrame,\n type ClientRequestFrame,\n type RequestId,\n type ServerFrame,\n type SpaceOptions,\n type SpaceRef,\n type TrayBoundsResult,\n type TrayId,\n type TrayOptions,\n} from \"@opentray/spec\";\n\nexport interface OpenTrayTransport {\n request(frame: ClientRequestFrame): Promise<ServerFrame>;\n}\n\nexport interface OpenTrayClient {\n createSpace(options: SpaceOptions): Promise<SpaceHandle>;\n resolveDefaultSpace(): Promise<SpaceHandle>;\n /** @deprecated Use `createSpace`. */\n createSurface(options: SpaceOptions): Promise<SpaceHandle>;\n}\n\nexport interface SpaceHandle {\n space: SpaceRef;\n createTray(options: TrayOptions): Promise<TrayHandle>;\n}\n\n/** @deprecated Use `SpaceHandle`. */\nexport type SurfaceHandle = SpaceHandle;\n\nexport interface TrayHandle {\n space: SpaceRef;\n trayId: TrayId;\n getBounds(): Promise<TrayBoundsResult>;\n loadExtension(options: ExtensionLoadOptions): Promise<void>;\n commandExtension(ext: string, data: unknown): Promise<void>;\n extend<TCapability extends object, TOptions = undefined>(\n extension: TrayExtension<TCapability, TOptions>,\n options?: TOptions,\n ): TrayHandle & TCapability;\n destroy(): Promise<void>;\n}\n\nexport interface ExtensionLoadOptions {\n name: string;\n path: string;\n mountId?: string;\n}\n\nexport interface TrayExtensionMountSpec {\n name?: string;\n path?: string;\n mountId?: string;\n}\n\nexport interface TrayExtensionContext {\n readonly name: string;\n readonly path: string;\n readonly mountId: string;\n ensureLoaded(): Promise<void>;\n command(data: unknown): Promise<void>;\n}\n\nexport interface TrayExtension<TCapability extends object, TOptions = undefined> {\n readonly name: string;\n readonly path: string;\n resolveMount?(options: TOptions | undefined): TrayExtensionMountSpec;\n extend(tray: TrayHandle, context: TrayExtensionContext, options: TOptions | undefined): TCapability;\n}\n\nexport const createInitFrame = (clientVersion: string): ClientFrame => ({\n type: \"init\",\n protocolVersion: PROTOCOL_VERSION,\n clientVersion,\n});\n\nexport interface CreateClientOptions {\n requestIdPrefix?: string;\n}\n\nexport const createClient = (\n transport: OpenTrayTransport,\n options: CreateClientOptions = {},\n): OpenTrayClient => {\n const nextRequestId = createRequestIdFactory(options.requestIdPrefix ?? \"opentray\");\n\n return {\n async createSpace(spaceOptions): Promise<SpaceHandle> {\n const requestId = nextRequestId();\n const response = await transport.request({\n type: \"create-space\",\n requestId,\n ...spaceOptions,\n });\n const space = expectResponse(response, requestId, \"space-created\").space;\n return createSpaceHandle(transport, space, nextRequestId);\n },\n async resolveDefaultSpace(): Promise<SpaceHandle> {\n const requestId = nextRequestId();\n const response = await transport.request({\n type: \"resolve-default-space\",\n requestId,\n });\n const space = expectResponse(response, requestId, \"default-space\").space;\n return createSpaceHandle(transport, space, nextRequestId);\n },\n async createSurface(spaceOptions): Promise<SpaceHandle> {\n return this.createSpace(spaceOptions);\n },\n };\n};\n\nexport const createSpaceHandle = (\n transport: OpenTrayTransport,\n space: SpaceRef,\n nextRequestId: () => RequestId = createRequestIdFactory(\"opentray\"),\n): SpaceHandle => ({\n space,\n async createTray(options: TrayOptions): Promise<TrayHandle> {\n const requestId = nextRequestId();\n const response = await transport.request({\n type: \"create-tray\",\n requestId,\n space,\n tray: options,\n });\n const frame = expectResponse(response, requestId, \"tray-created\");\n return createTrayHandle(transport, space, frame.trayId, nextRequestId);\n },\n});\n\n/** @deprecated Use `createSpaceHandle`. */\nexport const createSurfaceHandle = createSpaceHandle;\n\nexport const createTrayHandle = (\n transport: OpenTrayTransport,\n space: SpaceRef,\n trayId: TrayId,\n nextRequestId: () => RequestId = createRequestIdFactory(\"opentray\"),\n): TrayHandle => {\n let nextMountOrdinal = 1;\n const nextMountId = (extensionName: string): string => {\n const mountId = `${formatMountIdComponent(extensionName)}.${formatMountIdComponent(trayId)}.${nextMountOrdinal}`;\n nextMountOrdinal += 1;\n return mountId;\n };\n const handle: TrayHandle = {\n space,\n trayId,\n async getBounds(): Promise<TrayBoundsResult> {\n const requestId = nextRequestId();\n const response = await transport.request({\n type: \"get-tray-bounds\",\n requestId,\n spaceId: space.spaceId,\n trayId,\n });\n return expectResponse(response, requestId, \"tray-bounds\").bounds;\n },\n async loadExtension(options): Promise<void> {\n const requestId = nextRequestId();\n const response = await transport.request({\n type: \"load-ext\",\n requestId,\n spaceId: space.spaceId,\n name: options.name,\n path: options.path,\n ...(options.mountId === undefined ? {} : { mountId: options.mountId }),\n });\n expectResponse(response, requestId, \"ack\");\n },\n async commandExtension(ext: string, data: unknown): Promise<void> {\n const requestId = nextRequestId();\n const response = await transport.request({\n type: \"ext-command\",\n requestId,\n spaceId: space.spaceId,\n trayId,\n ext,\n data,\n });\n expectResponse(response, requestId, \"ack\");\n },\n extend<TCapability extends object, TOptions = undefined>(\n extension: TrayExtension<TCapability, TOptions>,\n options?: TOptions,\n ): TrayHandle & TCapability {\n const context = createTrayExtensionContext(handle, extension, options, nextMountId);\n const capability = extension.extend(handle, context, options);\n return Object.assign({}, handle, capability);\n },\n async destroy(): Promise<void> {\n const requestId = nextRequestId();\n const response = await transport.request({\n type: \"destroy-tray\",\n requestId,\n spaceId: space.spaceId,\n trayId,\n });\n expectResponse(response, requestId, \"ack\");\n },\n };\n return handle;\n};\n\nconst createTrayExtensionContext = <TCapability extends object, TOptions>(\n tray: TrayHandle,\n extension: TrayExtension<TCapability, TOptions>,\n options: TOptions | undefined,\n nextMountId: (extensionName: string) => string,\n): TrayExtensionContext => {\n const mount = extension.resolveMount?.(options) ?? {};\n const name = mount.name ?? extension.name;\n const path = mount.path ?? extension.path;\n const mountId = mount.mountId ?? nextMountId(name);\n let loadPromise: Promise<void> | undefined;\n\n const ensureLoaded = async (): Promise<void> => {\n if (loadPromise === undefined) {\n loadPromise = tray.loadExtension({ name, path, mountId }).catch((error: unknown) => {\n loadPromise = undefined;\n throw error;\n });\n }\n await loadPromise;\n };\n\n return {\n name,\n path,\n mountId,\n ensureLoaded,\n async command(data: unknown): Promise<void> {\n await ensureLoaded();\n await tray.commandExtension(mountId, data);\n },\n };\n};\n\nconst formatMountIdComponent = (value: string): string => {\n const formatted = value.replaceAll(/[^a-zA-Z0-9._+-]/g, \"_\");\n return formatted.length > 0 ? formatted : \"ext\";\n};\n\nconst createRequestIdFactory = (prefix: string): (() => RequestId) => {\n let next = 1;\n return () => {\n const requestId = `${prefix}-${next}`;\n next += 1;\n return requestId;\n };\n};\n\nconst expectResponse = <TType extends ServerFrame[\"type\"]>(\n frame: ServerFrame,\n requestId: RequestId,\n type: TType,\n): Extract<ServerFrame, { type: TType }> => {\n if (frame.type === \"error\") {\n throw new Error(`${frame.code}: ${frame.message}`);\n }\n if (frame.type !== type) {\n throw new Error(`expected ${type} for ${requestId}, received ${frame.type}`);\n }\n if (requestIdOf(frame) !== requestId) {\n throw new Error(`expected response for ${requestId}, received ${requestIdOf(frame) ?? \"none\"}`);\n }\n return frame as Extract<ServerFrame, { type: TType }>;\n};\n\nconst requestIdOf = (frame: ServerFrame): RequestId | undefined => {\n switch (frame.type) {\n case \"space-created\":\n case \"default-space\":\n case \"tray-created\":\n case \"tray-bounds\":\n case \"ack\":\n case \"daemon-health\":\n return frame.requestId;\n case \"error\":\n return frame.requestId;\n case \"ready\":\n case \"event\":\n case \"ext-event\":\n return undefined;\n }\n};\n"],"mappings":"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"}
package/dist/index.d.mts CHANGED
@@ -1,4 +1,4 @@
1
- import { a as SurfaceHandle, c as createInitFrame, d as createTrayHandle, i as SpaceHandle, l as createSpaceHandle, n as OpenTrayClient, o as TrayHandle, r as OpenTrayTransport, s as createClient, t as CreateClientOptions, u as createSurfaceHandle } from "./client-h6gZdeOk.mjs";
1
+ import { a as SpaceHandle, c as TrayExtensionContext, d as createClient, f as createInitFrame, h as createTrayHandle, i as OpenTrayTransport, l as TrayExtensionMountSpec, m as createSurfaceHandle, n as ExtensionLoadOptions, o as SurfaceHandle, p as createSpaceHandle, r as OpenTrayClient, s as TrayExtension, t as CreateClientOptions, u as TrayHandle } from "./client-DQn3DLZw.mjs";
2
2
  import { BrokerEndpointIdentity, BrokerEndpointIdentityOptions, PROTOCOL_VERSION, SpaceOptions, SpaceRef, TrayOptions, createBrokerEndpointIdentity, formatBrokerEndpointName, formatBrokerStateRoot, formatUnixSocketPath, formatWindowsPipeName, isSupportedProtocolVersion } from "@opentray/spec";
3
3
 
4
4
  //#region src/sdk.d.ts
@@ -19,5 +19,5 @@ declare const createSurface: (options: SpaceOptions, brokerOptions?: BrokerConne
19
19
  declare const resolveDefaultSpace: (brokerOptions?: BrokerConnectOptions) => Promise<SpaceHandle>;
20
20
  declare const createTray: (options: TrayOptions, brokerOptions?: CreateTrayOptions) => Promise<TrayHandle>;
21
21
  //#endregion
22
- export { type BrokerConnectOptions, type BrokerEndpointIdentity, type BrokerEndpointIdentityOptions, type CreateClientOptions, type CreateTrayOptions, type OpenTrayClient, type OpenTrayTransport, PROTOCOL_VERSION, type SpaceHandle, type SurfaceHandle, type TrayHandle, createBrokerEndpointIdentity, createClient, createInitFrame, createSpace, createSpaceHandle, createSurface, createSurfaceHandle, createTray, createTrayHandle, formatBrokerEndpointName, formatBrokerStateRoot, formatUnixSocketPath, formatWindowsPipeName, isSupportedProtocolVersion, resolveDefaultSpace };
22
+ export { type BrokerConnectOptions, type BrokerEndpointIdentity, type BrokerEndpointIdentityOptions, type CreateClientOptions, type CreateTrayOptions, type ExtensionLoadOptions, type OpenTrayClient, type OpenTrayTransport, PROTOCOL_VERSION, type SpaceHandle, type SurfaceHandle, type TrayExtension, type TrayExtensionContext, type TrayExtensionMountSpec, type TrayHandle, createBrokerEndpointIdentity, createClient, createInitFrame, createSpace, createSpaceHandle, createSurface, createSurfaceHandle, createTray, createTrayHandle, formatBrokerEndpointName, formatBrokerStateRoot, formatUnixSocketPath, formatWindowsPipeName, isSupportedProtocolVersion, resolveDefaultSpace };
23
23
  //# sourceMappingURL=index.d.mts.map
package/dist/index.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { a as createTrayHandle, i as createSurfaceHandle, n as createInitFrame, r as createSpaceHandle, t as createClient } from "./client-B_zxQOo5.mjs";
1
+ import { a as createTrayHandle, i as createSurfaceHandle, n as createInitFrame, r as createSpaceHandle, t as createClient } from "./client-DzcHIH-f.mjs";
2
2
  import { t as connectLocalBroker } from "./local-broker-CEIHPBcK.mjs";
3
3
  import { PROTOCOL_VERSION, createBrokerEndpointIdentity, formatBrokerEndpointName, formatBrokerStateRoot, formatUnixSocketPath, formatWindowsPipeName, isSupportedProtocolVersion } from "@opentray/spec";
4
4
  //#region src/sdk.ts
package/dist/node.d.mts CHANGED
@@ -1,4 +1,4 @@
1
- import { r as OpenTrayTransport } from "./client-h6gZdeOk.mjs";
1
+ import { i as OpenTrayTransport } from "./client-DQn3DLZw.mjs";
2
2
  import { BrokerEndpointIdentityOptions, ServerFrame } from "@opentray/spec";
3
3
 
4
4
  //#region src/daemon/paths.d.ts
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opentray",
3
- "version": "0.5.1",
3
+ "version": "0.5.2",
4
4
  "description": "Developer-facing OpenTray SDK and CLI package.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -29,7 +29,7 @@
29
29
  ],
30
30
  "sideEffects": false,
31
31
  "dependencies": {
32
- "@opentray/spec": "0.4.0"
32
+ "@opentray/spec": "0.4.1"
33
33
  },
34
34
  "devDependencies": {
35
35
  "tsdown": "^0.22.1",
@@ -37,12 +37,12 @@
37
37
  "vitest": "^4.1.7"
38
38
  },
39
39
  "optionalDependencies": {
40
- "@opentray/darwin-arm64": "0.5.1",
41
- "@opentray/darwin-x64": "0.5.1",
42
- "@opentray/linux-arm64": "0.5.1",
43
- "@opentray/linux-x64": "0.5.1",
44
- "@opentray/windows-arm64": "0.5.1",
45
- "@opentray/windows-x64": "0.5.1"
40
+ "@opentray/darwin-arm64": "0.5.2",
41
+ "@opentray/darwin-x64": "0.5.2",
42
+ "@opentray/linux-arm64": "0.5.2",
43
+ "@opentray/linux-x64": "0.5.2",
44
+ "@opentray/windows-arm64": "0.5.2",
45
+ "@opentray/windows-x64": "0.5.2"
46
46
  },
47
47
  "scripts": {
48
48
  "build": "tsdown src/index.ts src/node.ts src/cli.ts --format esm --dts",
@@ -1 +0,0 @@
1
- {"version":3,"file":"client-B_zxQOo5.mjs","names":[],"sources":["../src/client.ts"],"sourcesContent":["import {\n PROTOCOL_VERSION,\n type ClientFrame,\n type ClientRequestFrame,\n type RequestId,\n type ServerFrame,\n type SpaceOptions,\n type SpaceRef,\n type TrayBoundsResult,\n type TrayId,\n type TrayOptions,\n} from \"@opentray/spec\";\n\nexport interface OpenTrayTransport {\n request(frame: ClientRequestFrame): Promise<ServerFrame>;\n}\n\nexport interface OpenTrayClient {\n createSpace(options: SpaceOptions): Promise<SpaceHandle>;\n resolveDefaultSpace(): Promise<SpaceHandle>;\n /** @deprecated Use `createSpace`. */\n createSurface(options: SpaceOptions): Promise<SpaceHandle>;\n}\n\nexport interface SpaceHandle {\n space: SpaceRef;\n createTray(options: TrayOptions): Promise<TrayHandle>;\n}\n\n/** @deprecated Use `SpaceHandle`. */\nexport type SurfaceHandle = SpaceHandle;\n\nexport interface TrayHandle {\n space: SpaceRef;\n trayId: TrayId;\n getBounds(): Promise<TrayBoundsResult>;\n commandExtension(ext: string, data: unknown): Promise<void>;\n destroy(): Promise<void>;\n}\n\nexport const createInitFrame = (clientVersion: string): ClientFrame => ({\n type: \"init\",\n protocolVersion: PROTOCOL_VERSION,\n clientVersion,\n});\n\nexport interface CreateClientOptions {\n requestIdPrefix?: string;\n}\n\nexport const createClient = (\n transport: OpenTrayTransport,\n options: CreateClientOptions = {},\n): OpenTrayClient => {\n const nextRequestId = createRequestIdFactory(options.requestIdPrefix ?? \"opentray\");\n\n return {\n async createSpace(spaceOptions): Promise<SpaceHandle> {\n const requestId = nextRequestId();\n const response = await transport.request({\n type: \"create-space\",\n requestId,\n ...spaceOptions,\n });\n const space = expectResponse(response, requestId, \"space-created\").space;\n return createSpaceHandle(transport, space, nextRequestId);\n },\n async resolveDefaultSpace(): Promise<SpaceHandle> {\n const requestId = nextRequestId();\n const response = await transport.request({\n type: \"resolve-default-space\",\n requestId,\n });\n const space = expectResponse(response, requestId, \"default-space\").space;\n return createSpaceHandle(transport, space, nextRequestId);\n },\n async createSurface(spaceOptions): Promise<SpaceHandle> {\n return this.createSpace(spaceOptions);\n },\n };\n};\n\nexport const createSpaceHandle = (\n transport: OpenTrayTransport,\n space: SpaceRef,\n nextRequestId: () => RequestId = createRequestIdFactory(\"opentray\"),\n): SpaceHandle => ({\n space,\n async createTray(options: TrayOptions): Promise<TrayHandle> {\n const requestId = nextRequestId();\n const response = await transport.request({\n type: \"create-tray\",\n requestId,\n space,\n tray: options,\n });\n const frame = expectResponse(response, requestId, \"tray-created\");\n return createTrayHandle(transport, space, frame.trayId, nextRequestId);\n },\n});\n\n/** @deprecated Use `createSpaceHandle`. */\nexport const createSurfaceHandle = createSpaceHandle;\n\nexport const createTrayHandle = (\n transport: OpenTrayTransport,\n space: SpaceRef,\n trayId: TrayId,\n nextRequestId: () => RequestId = createRequestIdFactory(\"opentray\"),\n): TrayHandle => ({\n space,\n trayId,\n async getBounds(): Promise<TrayBoundsResult> {\n const requestId = nextRequestId();\n const response = await transport.request({\n type: \"get-tray-bounds\",\n requestId,\n spaceId: space.spaceId,\n trayId,\n });\n return expectResponse(response, requestId, \"tray-bounds\").bounds;\n },\n async commandExtension(ext: string, data: unknown): Promise<void> {\n const requestId = nextRequestId();\n const response = await transport.request({\n type: \"ext-command\",\n requestId,\n spaceId: space.spaceId,\n trayId,\n ext,\n data,\n });\n expectResponse(response, requestId, \"ack\");\n },\n async destroy(): Promise<void> {\n const requestId = nextRequestId();\n const response = await transport.request({\n type: \"destroy-tray\",\n requestId,\n spaceId: space.spaceId,\n trayId,\n });\n expectResponse(response, requestId, \"ack\");\n },\n});\n\nconst createRequestIdFactory = (prefix: string): (() => RequestId) => {\n let next = 1;\n return () => {\n const requestId = `${prefix}-${next}`;\n next += 1;\n return requestId;\n };\n};\n\nconst expectResponse = <TType extends ServerFrame[\"type\"]>(\n frame: ServerFrame,\n requestId: RequestId,\n type: TType,\n): Extract<ServerFrame, { type: TType }> => {\n if (frame.type === \"error\") {\n throw new Error(`${frame.code}: ${frame.message}`);\n }\n if (frame.type !== type) {\n throw new Error(`expected ${type} for ${requestId}, received ${frame.type}`);\n }\n if (requestIdOf(frame) !== requestId) {\n throw new Error(`expected response for ${requestId}, received ${requestIdOf(frame) ?? \"none\"}`);\n }\n return frame as Extract<ServerFrame, { type: TType }>;\n};\n\nconst requestIdOf = (frame: ServerFrame): RequestId | undefined => {\n switch (frame.type) {\n case \"space-created\":\n case \"default-space\":\n case \"tray-created\":\n case \"tray-bounds\":\n case \"ack\":\n case \"daemon-health\":\n return frame.requestId;\n case \"error\":\n return frame.requestId;\n case \"ready\":\n case \"event\":\n case \"ext-event\":\n return undefined;\n }\n};\n"],"mappings":";;AAwCA,MAAa,mBAAmB,mBAAwC;CACtE,MAAM;CACN,iBAAiB;CACjB;AACF;AAMA,MAAa,gBACX,WACA,UAA+B,CAAC,MACb;CACnB,MAAM,gBAAgB,uBAAuB,QAAQ,mBAAmB,UAAU;CAElF,OAAO;EACL,MAAM,YAAY,cAAoC;GACpD,MAAM,YAAY,cAAc;GAMhC,MAAM,QAAQ,eAAe,MALN,UAAU,QAAQ;IACvC,MAAM;IACN;IACA,GAAG;GACL,CAAC,GACsC,WAAW,eAAe,EAAE;GACnE,OAAO,kBAAkB,WAAW,OAAO,aAAa;EAC1D;EACA,MAAM,sBAA4C;GAChD,MAAM,YAAY,cAAc;GAKhC,MAAM,QAAQ,eAAe,MAJN,UAAU,QAAQ;IACvC,MAAM;IACN;GACF,CAAC,GACsC,WAAW,eAAe,EAAE;GACnE,OAAO,kBAAkB,WAAW,OAAO,aAAa;EAC1D;EACA,MAAM,cAAc,cAAoC;GACtD,OAAO,KAAK,YAAY,YAAY;EACtC;CACF;AACF;AAEA,MAAa,qBACX,WACA,OACA,gBAAiC,uBAAuB,UAAU,OACjD;CACjB;CACA,MAAM,WAAW,SAA2C;EAC1D,MAAM,YAAY,cAAc;EAQhC,OAAO,iBAAiB,WAAW,OADrB,eAAe,MANN,UAAU,QAAQ;GACvC,MAAM;GACN;GACA;GACA,MAAM;EACR,CAAC,GACsC,WAAW,cACJ,EAAE,QAAQ,aAAa;CACvE;AACF;;AAGA,MAAa,sBAAsB;AAEnC,MAAa,oBACX,WACA,OACA,QACA,gBAAiC,uBAAuB,UAAU,OAClD;CAChB;CACA;CACA,MAAM,YAAuC;EAC3C,MAAM,YAAY,cAAc;EAOhC,OAAO,eAAe,MANC,UAAU,QAAQ;GACvC,MAAM;GACN;GACA,SAAS,MAAM;GACf;EACF,CAAC,GAC+B,WAAW,aAAa,EAAE;CAC5D;CACA,MAAM,iBAAiB,KAAa,MAA8B;EAChE,MAAM,YAAY,cAAc;EAShC,eAAe,MARQ,UAAU,QAAQ;GACvC,MAAM;GACN;GACA,SAAS,MAAM;GACf;GACA;GACA;EACF,CAAC,GACwB,WAAW,KAAK;CAC3C;CACA,MAAM,UAAyB;EAC7B,MAAM,YAAY,cAAc;EAOhC,eAAe,MANQ,UAAU,QAAQ;GACvC,MAAM;GACN;GACA,SAAS,MAAM;GACf;EACF,CAAC,GACwB,WAAW,KAAK;CAC3C;AACF;AAEA,MAAM,0BAA0B,WAAsC;CACpE,IAAI,OAAO;CACX,aAAa;EACX,MAAM,YAAY,GAAG,OAAO,GAAG;EAC/B,QAAQ;EACR,OAAO;CACT;AACF;AAEA,MAAM,kBACJ,OACA,WACA,SAC0C;CAC1C,IAAI,MAAM,SAAS,SACjB,MAAM,IAAI,MAAM,GAAG,MAAM,KAAK,IAAI,MAAM,SAAS;CAEnD,IAAI,MAAM,SAAS,MACjB,MAAM,IAAI,MAAM,YAAY,KAAK,OAAO,UAAU,aAAa,MAAM,MAAM;CAE7E,IAAI,YAAY,KAAK,MAAM,WACzB,MAAM,IAAI,MAAM,yBAAyB,UAAU,aAAa,YAAY,KAAK,KAAK,QAAQ;CAEhG,OAAO;AACT;AAEA,MAAM,eAAe,UAA8C;CACjE,QAAQ,MAAM,MAAd;EACE,KAAK;EACL,KAAK;EACL,KAAK;EACL,KAAK;EACL,KAAK;EACL,KAAK,iBACH,OAAO,MAAM;EACf,KAAK,SACH,OAAO,MAAM;EACf,KAAK;EACL,KAAK;EACL,KAAK,aACH;CACJ;AACF"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"client-h6gZdeOk.d.mts","names":[],"sources":["../src/client.ts"],"mappings":";;;UAaiB,iBAAA;EACf,OAAA,CAAQ,KAAA,EAAO,kBAAA,GAAqB,OAAA,CAAQ,WAAA;AAAA;AAAA,UAG7B,cAAA;EACf,WAAA,CAAY,OAAA,EAAS,YAAA,GAAe,OAAA,CAAQ,WAAA;EAC5C,mBAAA,IAAuB,OAAA,CAAQ,WAAA;EALa;EAO5C,aAAA,CAAc,OAAA,EAAS,YAAA,GAAe,OAAA,CAAQ,WAAA;AAAA;AAAA,UAG/B,WAAA;EACf,KAAA,EAAO,QAAA;EACP,UAAA,CAAW,OAAA,EAAS,WAAA,GAAc,OAAA,CAAQ,UAAA;AAAA;;KAIhC,aAAA,GAAgB,WAAW;AAAA,UAEtB,UAAA;EACf,KAAA,EAAO,QAAA;EACP,MAAA,EAAQ,MAAA;EACR,SAAA,IAAa,OAAA,CAAQ,gBAAA;EACrB,gBAAA,CAAiB,GAAA,UAAa,IAAA,YAAgB,OAAA;EAC9C,OAAA,IAAW,OAAA;AAAA;AAAA,cAGA,eAAA,GAAmB,aAAA,aAAwB,WAItD;AAAA,UAEe,mBAAA;EACf,eAAe;AAAA;AAAA,cAGJ,YAAA,GACX,SAAA,EAAW,iBAAA,EACX,OAAA,GAAS,mBAAA,KACR,cAAA;AAAA,cA6BU,iBAAA,GACX,SAAA,EAAW,iBAAA,EACX,KAAA,EAAO,QAAA,EACP,aAAA,SAAqB,SAAA,KACpB,WAAA;;cAgBU,mBAAA,GAAmB,SAAA,EAnBnB,iBAAA,EAAiB,KAAA,EACrB,QAAA,EAAQ,aAAA,SACM,SAAA,KACpB,WAAA;AAAA,cAkBU,gBAAA,GACX,SAAA,EAAW,iBAAA,EACX,KAAA,EAAO,QAAA,EACP,MAAA,EAAQ,MAAA,EACR,aAAA,SAAqB,SAAA,KACpB,UAAA"}