@opentray/spec 0.1.0 → 0.2.0

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
@@ -5,6 +5,7 @@ Shared TypeScript protocol and contract package for OpenTray.
5
5
  ## Role
6
6
 
7
7
  - Define JSON-RPC payload shapes.
8
+ - Define broker protocol version and endpoint identity helpers.
8
9
  - Define public `Surface`, `Tray`, `Lease`, and extension contract types.
9
10
  - Keep protocol types reusable by the `opentray` package and official extensions.
10
11
 
@@ -17,3 +18,13 @@ Run a protocol parser example that shows successful server-frame parsing and mal
17
18
  ```bash
18
19
  pnpm --filter @opentray/spec example:parse
19
20
  ```
21
+
22
+ Endpoint identity is version-scoped during the current unstable broker stage:
23
+
24
+ ```ts
25
+ import { createBrokerEndpointIdentity, formatUnixSocketPath } from "@opentray/spec";
26
+
27
+ const identity = createBrokerEndpointIdentity({ packageVersion: "0.1.0" });
28
+ console.log(formatUnixSocketPath("~", identity));
29
+ // ~/.opentray/0.1.0/opentray-p1.sock
30
+ ```
package/dist/index.d.mts CHANGED
@@ -1,8 +1,27 @@
1
1
  //#region src/index.d.ts
2
2
  type LeaseId = string;
3
+ type RequestId = string;
3
4
  type SurfaceId = string;
4
5
  type TrayId = string;
5
6
  type MenuItemId = number;
7
+ declare const PROTOCOL_VERSION = 1;
8
+ interface BrokerEndpointIdentity {
9
+ packageVersion: string;
10
+ protocolVersion: number;
11
+ }
12
+ interface BrokerEndpointIdentityOptions {
13
+ packageVersion: string;
14
+ protocolVersion?: number;
15
+ }
16
+ declare const createBrokerEndpointIdentity: ({
17
+ packageVersion,
18
+ protocolVersion
19
+ }: BrokerEndpointIdentityOptions) => BrokerEndpointIdentity;
20
+ declare const isSupportedProtocolVersion: (protocolVersion: number) => boolean;
21
+ declare const formatBrokerEndpointName: (identity: BrokerEndpointIdentity) => string;
22
+ declare const formatBrokerStateRoot: (homeDir: string, identity: BrokerEndpointIdentity) => string;
23
+ declare const formatUnixSocketPath: (homeDir: string, identity: BrokerEndpointIdentity) => string;
24
+ declare const formatWindowsPipeName: (identity: BrokerEndpointIdentity) => string;
6
25
  interface SurfaceOptions {
7
26
  appId: string;
8
27
  title?: string;
@@ -104,67 +123,107 @@ interface ExtensionEnvelope<TData = unknown> {
104
123
  scope: ExtensionScope;
105
124
  data: TData;
106
125
  }
126
+ interface DaemonSessionHealth {
127
+ sessionId: number;
128
+ leaseId?: LeaseId;
129
+ initialized: boolean;
130
+ }
131
+ interface DaemonHealth {
132
+ pid: number;
133
+ packageVersion: string;
134
+ protocolVersion: number;
135
+ endpoint: string;
136
+ sessionCount: number;
137
+ sessions: DaemonSessionHealth[];
138
+ }
107
139
  type ClientFrame = {
108
140
  type: "init";
109
- version: number;
110
- } | ({
141
+ protocolVersion: number;
142
+ clientVersion: string;
143
+ } | ClientRequestFrame | {
144
+ type: "exit";
145
+ };
146
+ type ClientRequestFrame = ({
111
147
  type: "create-surface";
148
+ requestId: RequestId;
112
149
  } & SurfaceOptions) | {
113
150
  type: "resolve-default-surface";
151
+ requestId: RequestId;
114
152
  } | {
115
153
  type: "create-tray";
154
+ requestId: RequestId;
116
155
  surface: SurfaceRef;
117
156
  tray: TrayOptions;
118
157
  } | {
119
158
  type: "destroy-tray";
159
+ requestId: RequestId;
120
160
  surfaceId: SurfaceId;
121
161
  trayId: TrayId;
122
162
  } | {
123
163
  type: "set-tray-menu";
164
+ requestId: RequestId;
124
165
  surfaceId: SurfaceId;
125
166
  trayId: TrayId;
126
167
  menu: Menu;
127
168
  } | {
128
169
  type: "set-tray-icon";
170
+ requestId: RequestId;
129
171
  surfaceId: SurfaceId;
130
172
  trayId: TrayId;
131
173
  icon: Icon;
132
174
  } | {
133
175
  type: "set-tray-tooltip";
176
+ requestId: RequestId;
134
177
  surfaceId: SurfaceId;
135
178
  trayId: TrayId;
136
179
  tooltip: Tooltip;
137
180
  } | {
138
181
  type: "load-ext";
182
+ requestId: RequestId;
139
183
  surfaceId: SurfaceId;
140
184
  name: string;
141
185
  path: string;
142
186
  } | {
143
187
  type: "ext-command";
188
+ requestId: RequestId;
144
189
  surfaceId: SurfaceId;
145
190
  trayId: TrayId;
146
191
  ext: string;
147
192
  data: unknown;
148
193
  } | {
149
194
  type: "unload-ext";
195
+ requestId: RequestId;
150
196
  surfaceId: SurfaceId;
151
197
  name: string;
152
198
  } | {
153
- type: "exit";
199
+ type: "health";
200
+ requestId: RequestId;
154
201
  };
155
202
  type ServerFrame = {
156
203
  type: "ready";
157
- version: number;
204
+ protocolVersion: number;
205
+ brokerVersion: string;
206
+ leaseId: LeaseId;
158
207
  } | {
159
208
  type: "surface-created";
209
+ requestId: RequestId;
160
210
  surface: SurfaceRef;
161
211
  } | {
162
212
  type: "default-surface";
213
+ requestId: RequestId;
163
214
  surface: SurfaceRef;
164
215
  } | {
165
216
  type: "tray-created";
217
+ requestId: RequestId;
166
218
  surfaceId: SurfaceId;
167
219
  trayId: TrayId;
220
+ } | {
221
+ type: "ack";
222
+ requestId: RequestId;
223
+ } | {
224
+ type: "daemon-health";
225
+ requestId: RequestId;
226
+ health: DaemonHealth;
168
227
  } | {
169
228
  type: "event";
170
229
  event: TrayEvent;
@@ -176,6 +235,8 @@ type ServerFrame = {
176
235
  data: unknown;
177
236
  } | {
178
237
  type: "error";
238
+ requestId?: RequestId;
239
+ code: string;
179
240
  message: string;
180
241
  };
181
242
  interface ParseResult<T> {
@@ -186,5 +247,5 @@ interface ParseResult<T> {
186
247
  declare const parseServerFrame: (line: string) => ParseResult<ServerFrame>;
187
248
  declare const isServerFrame: (value: unknown) => value is ServerFrame;
188
249
  //#endregion
189
- export { ClientFrame, ExtensionEnvelope, ExtensionScope, Icon, LeaseId, Menu, MenuItem, MenuItemId, MouseButton, ParseResult, Rect, ServerFrame, SurfaceId, SurfaceOptions, SurfaceRef, Tooltip, TrayEvent, TrayId, TrayOptions, isServerFrame, parseServerFrame };
250
+ export { BrokerEndpointIdentity, BrokerEndpointIdentityOptions, ClientFrame, ClientRequestFrame, DaemonHealth, DaemonSessionHealth, ExtensionEnvelope, ExtensionScope, Icon, LeaseId, Menu, MenuItem, MenuItemId, MouseButton, PROTOCOL_VERSION, ParseResult, Rect, RequestId, ServerFrame, SurfaceId, SurfaceOptions, SurfaceRef, Tooltip, TrayEvent, TrayId, TrayOptions, createBrokerEndpointIdentity, formatBrokerEndpointName, formatBrokerStateRoot, formatUnixSocketPath, formatWindowsPipeName, isServerFrame, isSupportedProtocolVersion, parseServerFrame };
190
251
  //# sourceMappingURL=index.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.mts","names":[],"sources":["../src/index.ts"],"mappings":";KAAY,OAAA;AAAA,KACA,SAAA;AAAA,KACA,MAAA;AAAA,KACA,UAAA;AAAA,UAEK,cAAA;EACf,KAAA;EACA,KAAA;EACA,IAAA,GAAO,IAAI;EACX,OAAA;AAAA;AAAA,UAGe,UAAA;EACf,SAAA,EAAW,SAAS;EACpB,KAAA;AAAA;AAAA,UAGe,WAAA;EACf,MAAA,GAAS,MAAA;EACT,KAAA;EACA,KAAA;EACA,OAAA,GAAU,OAAA;EACV,IAAA,EAAM,IAAA;EACN,IAAA,GAAO,IAAA;AAAA;AAAA,UAGQ,OAAA;EACf,KAAA;EACA,WAAW;AAAA;AAAA,UAGI,IAAA;EACf,KAAA,EAAO,QAAQ;AAAA;AAAA,KAGL,QAAA;EAEN,IAAA;EACA,EAAA,EAAI,UAAA;EACJ,KAAA;EACA,OAAA;EACA,QAAA;AAAA;EAGA,IAAA;EACA,EAAA,EAAI,UAAA;EACJ,KAAA;EACA,OAAA;EACA,OAAA;AAAA;EAGA,IAAA;EACA,EAAA,EAAI,UAAA;EACJ,KAAA;EACA,OAAA;EACA,OAAA;EACA,KAAA;AAAA;EAGA,IAAA;AAAA;EAGA,IAAA;EACA,KAAA;EACA,OAAA;EACA,KAAA,EAAO,QAAA;AAAA;AAAA,KAGD,IAAA;EACN,IAAA;EAAc,IAAA,EAAM,UAAA;EAAuB,KAAA;EAAe,MAAA;AAAA;EAC1D,IAAA;EAAiB,IAAA,EAAM,UAAU;AAAA;EACjC,IAAA;EAAc,IAAA;AAAA;AAAA,UAEH,IAAA;EACf,CAAA;EACA,CAAA;EACA,KAAA;EACA,MAAA;AAAA;AAAA,KAGU,WAAA;AAAA,KAEA,SAAA;EACN,IAAA;EAAe,SAAA,EAAW,SAAA;AAAA;EAC1B,IAAA;EAAmB,SAAA,EAAW,SAAA;EAAW,MAAA,EAAQ,MAAA;EAAQ,MAAA,EAAQ,UAAA;AAAA;EACjE,IAAA;EAAmB,SAAA,EAAW,SAAA;EAAW,MAAA,EAAQ,WAAA;EAAa,CAAA;EAAW,CAAA;AAAA;EACzE,IAAA;EAAyB,SAAA,EAAW,SAAA;EAAW,MAAA,EAAQ,WAAA;EAAa,CAAA;EAAW,CAAA;AAAA;AAAA,UAEpE,cAAA;EACf,SAAA,EAAW,SAAA;EACX,MAAA,GAAS,MAAM;EACf,GAAA;AAAA;AAAA,UAGe,iBAAA;EACf,KAAA,EAAO,cAAA;EACP,IAAA,EAAM,KAAK;AAAA;AAAA,KAGD,WAAA;EACN,IAAA;EAAc,OAAA;AAAA;EACb,IAAA;AAAA,IAA2B,cAAA;EAC5B,IAAA;AAAA;EACA,IAAA;EAAqB,OAAA,EAAS,UAAA;EAAY,IAAA,EAAM,WAAA;AAAA;EAChD,IAAA;EAAsB,SAAA,EAAW,SAAA;EAAW,MAAA,EAAQ,MAAA;AAAA;EACpD,IAAA;EAAuB,SAAA,EAAW,SAAA;EAAW,MAAA,EAAQ,MAAA;EAAQ,IAAA,EAAM,IAAA;AAAA;EACnE,IAAA;EAAuB,SAAA,EAAW,SAAA;EAAW,MAAA,EAAQ,MAAA;EAAQ,IAAA,EAAM,IAAA;AAAA;EACnE,IAAA;EAA0B,SAAA,EAAW,SAAA;EAAW,MAAA,EAAQ,MAAA;EAAQ,OAAA,EAAS,OAAA;AAAA;EACzE,IAAA;EAAkB,SAAA,EAAW,SAAA;EAAW,IAAA;EAAc,IAAA;AAAA;EACtD,IAAA;EAAqB,SAAA,EAAW,SAAA;EAAW,MAAA,EAAQ,MAAA;EAAQ,GAAA;EAAa,IAAA;AAAA;EACxE,IAAA;EAAoB,SAAA,EAAW,SAAA;EAAW,IAAA;AAAA;EAC1C,IAAA;AAAA;AAAA,KAEM,WAAA;EACN,IAAA;EAAe,OAAA;AAAA;EACf,IAAA;EAAyB,OAAA,EAAS,UAAA;AAAA;EAClC,IAAA;EAAyB,OAAA,EAAS,UAAA;AAAA;EAClC,IAAA;EAAsB,SAAA,EAAW,SAAA;EAAW,MAAA,EAAQ,MAAA;AAAA;EACpD,IAAA;EAAe,KAAA,EAAO,SAAA;AAAA;EACtB,IAAA;EAAmB,SAAA,EAAW,SAAA;EAAW,MAAA,EAAQ,MAAA;EAAQ,GAAA;EAAa,IAAA;AAAA;EACtE,IAAA;EAAe,OAAA;AAAA;AAAA,UAEJ,WAAA;EACf,EAAA;EACA,KAAA,GAAQ,CAAC;EACT,KAAA;AAAA;AAAA,cAGW,gBAAA,GAAoB,IAAA,aAAe,WAAW,CAAC,WAAA;AAAA,cAkB/C,aAAA,GAAiB,KAAA,cAAiB,KAAA,IAAS,WACL"}
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../src/index.ts"],"mappings":";KAAY,OAAA;AAAA,KACA,SAAA;AAAA,KACA,SAAA;AAAA,KACA,MAAA;AAAA,KACA,UAAA;AAAA,cAEC,gBAAA;AAAA,UAEI,sBAAA;EACf,cAAA;EACA,eAAe;AAAA;AAAA,UAGA,6BAAA;EACf,cAAA;EACA,eAAe;AAAA;AAAA,cAGJ,4BAAA;EAAgC,cAAA;EAAA;AAAA,GAG1C,6BAAA,KAAgC,sBAAA;AAAA,cAYtB,0BAAA,GAA8B,eAAuB;AAAA,cAGrD,wBAAA,GAA4B,QAAgC,EAAtB,sBAAsB;AAAA,cAK5D,qBAAA,GAAyB,OAAA,UAAiB,QAAA,EAAU,sBAAsB;AAAA,cAU1E,oBAAA,GAAwB,OAAA,UAAiB,QAAA,EAAU,sBAAsB;AAAA,cAGzE,qBAAA,GAAyB,QAAgC,EAAtB,sBAAsB;AAAA,UAqBrD,cAAA;EACf,KAAA;EACA,KAAA;EACA,IAAA,GAAO,IAAI;EACX,OAAA;AAAA;AAAA,UAGe,UAAA;EACf,SAAA,EAAW,SAAS;EACpB,KAAA;AAAA;AAAA,UAGe,WAAA;EACf,MAAA,GAAS,MAAA;EACT,KAAA;EACA,KAAA;EACA,OAAA,GAAU,OAAA;EACV,IAAA,EAAM,IAAA;EACN,IAAA,GAAO,IAAA;AAAA;AAAA,UAGQ,OAAA;EACf,KAAA;EACA,WAAW;AAAA;AAAA,UAGI,IAAA;EACf,KAAA,EAAO,QAAQ;AAAA;AAAA,KAGL,QAAA;EAEN,IAAA;EACA,EAAA,EAAI,UAAA;EACJ,KAAA;EACA,OAAA;EACA,QAAA;AAAA;EAGA,IAAA;EACA,EAAA,EAAI,UAAA;EACJ,KAAA;EACA,OAAA;EACA,OAAA;AAAA;EAGA,IAAA;EACA,EAAA,EAAI,UAAA;EACJ,KAAA;EACA,OAAA;EACA,OAAA;EACA,KAAA;AAAA;EAGA,IAAA;AAAA;EAGA,IAAA;EACA,KAAA;EACA,OAAA;EACA,KAAA,EAAO,QAAA;AAAA;AAAA,KAGD,IAAA;EACN,IAAA;EAAc,IAAA,EAAM,UAAA;EAAuB,KAAA;EAAe,MAAA;AAAA;EAC1D,IAAA;EAAiB,IAAA,EAAM,UAAU;AAAA;EACjC,IAAA;EAAc,IAAA;AAAA;AAAA,UAEH,IAAA;EACf,CAAA;EACA,CAAA;EACA,KAAA;EACA,MAAA;AAAA;AAAA,KAGU,WAAA;AAAA,KAEA,SAAA;EACN,IAAA;EAAe,SAAA,EAAW,SAAA;AAAA;EAC1B,IAAA;EAAmB,SAAA,EAAW,SAAA;EAAW,MAAA,EAAQ,MAAA;EAAQ,MAAA,EAAQ,UAAA;AAAA;EACjE,IAAA;EAAmB,SAAA,EAAW,SAAA;EAAW,MAAA,EAAQ,WAAA;EAAa,CAAA;EAAW,CAAA;AAAA;EACzE,IAAA;EAAyB,SAAA,EAAW,SAAA;EAAW,MAAA,EAAQ,WAAA;EAAa,CAAA;EAAW,CAAA;AAAA;AAAA,UAEpE,cAAA;EACf,SAAA,EAAW,SAAA;EACX,MAAA,GAAS,MAAM;EACf,GAAA;AAAA;AAAA,UAGe,iBAAA;EACf,KAAA,EAAO,cAAA;EACP,IAAA,EAAM,KAAK;AAAA;AAAA,UAGI,mBAAA;EACf,SAAA;EACA,OAAA,GAAU,OAAO;EACjB,WAAA;AAAA;AAAA,UAGe,YAAA;EACf,GAAA;EACA,cAAA;EACA,eAAA;EACA,QAAA;EACA,YAAA;EACA,QAAA,EAAU,mBAAmB;AAAA;AAAA,KAGnB,WAAA;EACN,IAAA;EAAc,eAAA;EAAyB,aAAA;AAAA,IACzC,kBAAkB;EAChB,IAAA;AAAA;AAAA,KAEM,kBAAA;EACL,IAAA;EAAwB,SAAA,EAAW,SAAA;AAAA,IAAc,cAAA;EAClD,IAAA;EAAiC,SAAA,EAAW,SAAA;AAAA;EAC5C,IAAA;EAAqB,SAAA,EAAW,SAAA;EAAW,OAAA,EAAS,UAAA;EAAY,IAAA,EAAM,WAAA;AAAA;EACtE,IAAA;EAAsB,SAAA,EAAW,SAAA;EAAW,SAAA,EAAW,SAAA;EAAW,MAAA,EAAQ,MAAA;AAAA;EAC1E,IAAA;EAAuB,SAAA,EAAW,SAAA;EAAW,SAAA,EAAW,SAAA;EAAW,MAAA,EAAQ,MAAA;EAAQ,IAAA,EAAM,IAAA;AAAA;EACzF,IAAA;EAAuB,SAAA,EAAW,SAAA;EAAW,SAAA,EAAW,SAAA;EAAW,MAAA,EAAQ,MAAA;EAAQ,IAAA,EAAM,IAAA;AAAA;EACzF,IAAA;EAA0B,SAAA,EAAW,SAAA;EAAW,SAAA,EAAW,SAAA;EAAW,MAAA,EAAQ,MAAA;EAAQ,OAAA,EAAS,OAAA;AAAA;EAC/F,IAAA;EAAkB,SAAA,EAAW,SAAA;EAAW,SAAA,EAAW,SAAA;EAAW,IAAA;EAAc,IAAA;AAAA;EAC5E,IAAA;EAAqB,SAAA,EAAW,SAAA;EAAW,SAAA,EAAW,SAAA;EAAW,MAAA,EAAQ,MAAA;EAAQ,GAAA;EAAa,IAAA;AAAA;EAC9F,IAAA;EAAoB,SAAA,EAAW,SAAA;EAAW,SAAA,EAAW,SAAA;EAAW,IAAA;AAAA;EAChE,IAAA;EAAgB,SAAA,EAAW,SAAA;AAAA;AAAA,KAErB,WAAA;EACN,IAAA;EAAe,eAAA;EAAyB,aAAA;EAAuB,OAAA,EAAS,OAAA;AAAA;EACxE,IAAA;EAAyB,SAAA,EAAW,SAAA;EAAW,OAAA,EAAS,UAAA;AAAA;EACxD,IAAA;EAAyB,SAAA,EAAW,SAAA;EAAW,OAAA,EAAS,UAAA;AAAA;EACxD,IAAA;EAAsB,SAAA,EAAW,SAAA;EAAW,SAAA,EAAW,SAAA;EAAW,MAAA,EAAQ,MAAA;AAAA;EAC1E,IAAA;EAAa,SAAA,EAAW,SAAA;AAAA;EACxB,IAAA;EAAuB,SAAA,EAAW,SAAA;EAAW,MAAA,EAAQ,YAAA;AAAA;EACrD,IAAA;EAAe,KAAA,EAAO,SAAA;AAAA;EACtB,IAAA;EAAmB,SAAA,EAAW,SAAA;EAAW,MAAA,EAAQ,MAAA;EAAQ,GAAA;EAAa,IAAA;AAAA;EACtE,IAAA;EAAe,SAAA,GAAY,SAAA;EAAW,IAAA;EAAc,OAAA;AAAA;AAAA,UAEzC,WAAA;EACf,EAAA;EACA,KAAA,GAAQ,CAAC;EACT,KAAA;AAAA;AAAA,cAGW,gBAAA,GAAoB,IAAA,aAAe,WAAW,CAAC,WAAA;AAAA,cAkB/C,aAAA,GAAiB,KAAA,cAAiB,KAAA,IAAS,WA2CvD"}
package/dist/index.mjs CHANGED
@@ -1,4 +1,34 @@
1
1
  //#region src/index.ts
2
+ const PROTOCOL_VERSION = 1;
3
+ const createBrokerEndpointIdentity = ({ packageVersion, protocolVersion = 1 }) => {
4
+ assertEndpointComponent(packageVersion, "packageVersion");
5
+ if (!Number.isInteger(protocolVersion) || protocolVersion <= 0) throw new Error(`protocolVersion must be a positive integer: ${protocolVersion}`);
6
+ return {
7
+ packageVersion,
8
+ protocolVersion
9
+ };
10
+ };
11
+ const isSupportedProtocolVersion = (protocolVersion) => protocolVersion === 1;
12
+ const formatBrokerEndpointName = (identity) => {
13
+ assertEndpointIdentity(identity);
14
+ return `opentray-${identity.packageVersion}-p${identity.protocolVersion}`;
15
+ };
16
+ const formatBrokerStateRoot = (homeDir, identity) => {
17
+ assertEndpointIdentity(identity);
18
+ if (homeDir.length === 0) throw new Error("homeDir must not be empty");
19
+ return `${homeDir.replace(/[\\/]+$/u, "")}/.opentray/${identity.packageVersion}`;
20
+ };
21
+ const formatUnixSocketPath = (homeDir, identity) => `${formatBrokerStateRoot(homeDir, identity)}/opentray-p${identity.protocolVersion}.sock`;
22
+ const formatWindowsPipeName = (identity) => `\\\\.\\pipe\\${formatBrokerEndpointName(identity)}`;
23
+ const endpointComponentPattern = /^[0-9A-Za-z._+-]+$/u;
24
+ const assertEndpointIdentity = (identity) => {
25
+ assertEndpointComponent(identity.packageVersion, "packageVersion");
26
+ if (!Number.isInteger(identity.protocolVersion) || identity.protocolVersion <= 0) throw new Error(`protocolVersion must be a positive integer: ${identity.protocolVersion}`);
27
+ };
28
+ const assertEndpointComponent = (value, name) => {
29
+ if (value.length === 0) throw new Error(`${name} must not be empty`);
30
+ if (!endpointComponentPattern.test(value)) throw new Error(`${name} contains invalid endpoint characters: ${value}`);
31
+ };
2
32
  const parseServerFrame = (line) => {
3
33
  try {
4
34
  const value = JSON.parse(line);
@@ -18,8 +48,38 @@ const parseServerFrame = (line) => {
18
48
  }
19
49
  };
20
50
  const isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
21
- const isServerFrame = (value) => isRecord(value) && typeof value.type === "string";
51
+ const isServerFrame = (value) => {
52
+ if (!isRecord(value) || typeof value.type !== "string") return false;
53
+ switch (value.type) {
54
+ case "ready": return typeof value.protocolVersion === "number" && typeof value.brokerVersion === "string" && typeof value.leaseId === "string";
55
+ case "surface-created": return typeof value.requestId === "string" && isRecord(value.surface);
56
+ case "default-surface": return typeof value.requestId === "string" && isRecord(value.surface);
57
+ case "tray-created": return typeof value.requestId === "string" && typeof value.surfaceId === "string" && typeof value.trayId === "string";
58
+ case "ack": return typeof value.requestId === "string";
59
+ case "daemon-health": return typeof value.requestId === "string" && isDaemonHealth(value.health);
60
+ case "event": return isTrayEvent(value.event);
61
+ case "ext-event": return typeof value.surfaceId === "string" && typeof value.trayId === "string" && typeof value.ext === "string";
62
+ case "error": return (value.requestId === void 0 || typeof value.requestId === "string") && typeof value.code === "string" && typeof value.message === "string";
63
+ default: return false;
64
+ }
65
+ };
66
+ const isDaemonHealth = (value) => {
67
+ if (!isRecord(value)) return false;
68
+ return typeof value.pid === "number" && typeof value.packageVersion === "string" && typeof value.protocolVersion === "number" && typeof value.endpoint === "string" && typeof value.sessionCount === "number" && Array.isArray(value.sessions) && value.sessions.every(isDaemonSessionHealth);
69
+ };
70
+ const isDaemonSessionHealth = (value) => isRecord(value) && typeof value.sessionId === "number" && (value.leaseId === void 0 || typeof value.leaseId === "string") && typeof value.initialized === "boolean";
71
+ const isTrayEvent = (value) => {
72
+ if (!isRecord(value) || typeof value.type !== "string") return false;
73
+ switch (value.type) {
74
+ case "ready": return typeof value.surfaceId === "string";
75
+ case "menuClick": return typeof value.surfaceId === "string" && typeof value.trayId === "string" && typeof value.itemId === "number";
76
+ case "trayClick":
77
+ case "trayDoubleClick": return typeof value.surfaceId === "string" && isMouseButton(value.button) && typeof value.x === "number" && typeof value.y === "number";
78
+ default: return false;
79
+ }
80
+ };
81
+ const isMouseButton = (value) => value === "left" || value === "right" || value === "middle";
22
82
  //#endregion
23
- export { isServerFrame, parseServerFrame };
83
+ export { PROTOCOL_VERSION, createBrokerEndpointIdentity, formatBrokerEndpointName, formatBrokerStateRoot, formatUnixSocketPath, formatWindowsPipeName, isServerFrame, isSupportedProtocolVersion, parseServerFrame };
24
84
 
25
85
  //# sourceMappingURL=index.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":[],"sources":["../src/index.ts"],"sourcesContent":["export type LeaseId = string;\nexport type SurfaceId = string;\nexport type TrayId = string;\nexport type MenuItemId = number;\n\nexport interface SurfaceOptions {\n appId: string;\n title?: string;\n icon?: Icon;\n default?: boolean;\n}\n\nexport interface SurfaceRef {\n surfaceId: SurfaceId;\n appId: string;\n}\n\nexport interface TrayOptions {\n trayId?: TrayId;\n appId?: string;\n title?: string;\n tooltip?: Tooltip;\n icon: Icon;\n menu?: Menu;\n}\n\nexport interface Tooltip {\n title: string;\n description: string;\n}\n\nexport interface Menu {\n items: MenuItem[];\n}\n\nexport type MenuItem =\n | {\n type: \"item\";\n id: MenuItemId;\n title: string;\n enabled?: boolean;\n shortcut?: string;\n }\n | {\n type: \"check\";\n id: MenuItemId;\n title: string;\n enabled?: boolean;\n checked?: boolean;\n }\n | {\n type: \"radio\";\n id: MenuItemId;\n title: string;\n enabled?: boolean;\n checked?: boolean;\n group: number;\n }\n | {\n type: \"separator\";\n }\n | {\n type: \"submenu\";\n title: string;\n enabled?: boolean;\n items: MenuItem[];\n };\n\nexport type Icon =\n | { type: \"rgba\"; data: Uint8Array | number[]; width: number; height: number }\n | { type: \"encoded\"; data: Uint8Array | number[] }\n | { type: \"file\"; path: string };\n\nexport interface Rect {\n x: number;\n y: number;\n width: number;\n height: number;\n}\n\nexport type MouseButton = \"left\" | \"right\" | \"middle\";\n\nexport type TrayEvent =\n | { type: \"ready\"; surfaceId: SurfaceId }\n | { type: \"menuClick\"; surfaceId: SurfaceId; trayId: TrayId; itemId: MenuItemId }\n | { type: \"trayClick\"; surfaceId: SurfaceId; button: MouseButton; x: number; y: number }\n | { type: \"trayDoubleClick\"; surfaceId: SurfaceId; button: MouseButton; x: number; y: number };\n\nexport interface ExtensionScope {\n surfaceId: SurfaceId;\n trayId?: TrayId;\n ext: string;\n}\n\nexport interface ExtensionEnvelope<TData = unknown> {\n scope: ExtensionScope;\n data: TData;\n}\n\nexport type ClientFrame =\n | { type: \"init\"; version: number }\n | ({ type: \"create-surface\" } & SurfaceOptions)\n | { type: \"resolve-default-surface\" }\n | { type: \"create-tray\"; surface: SurfaceRef; tray: TrayOptions }\n | { type: \"destroy-tray\"; surfaceId: SurfaceId; trayId: TrayId }\n | { type: \"set-tray-menu\"; surfaceId: SurfaceId; trayId: TrayId; menu: Menu }\n | { type: \"set-tray-icon\"; surfaceId: SurfaceId; trayId: TrayId; icon: Icon }\n | { type: \"set-tray-tooltip\"; surfaceId: SurfaceId; trayId: TrayId; tooltip: Tooltip }\n | { type: \"load-ext\"; surfaceId: SurfaceId; name: string; path: string }\n | { type: \"ext-command\"; surfaceId: SurfaceId; trayId: TrayId; ext: string; data: unknown }\n | { type: \"unload-ext\"; surfaceId: SurfaceId; name: string }\n | { type: \"exit\" };\n\nexport type ServerFrame =\n | { type: \"ready\"; version: number }\n | { type: \"surface-created\"; surface: SurfaceRef }\n | { type: \"default-surface\"; surface: SurfaceRef }\n | { type: \"tray-created\"; surfaceId: SurfaceId; trayId: TrayId }\n | { type: \"event\"; event: TrayEvent }\n | { type: \"ext-event\"; surfaceId: SurfaceId; trayId: TrayId; ext: string; data: unknown }\n | { type: \"error\"; message: string };\n\nexport interface ParseResult<T> {\n ok: boolean;\n frame?: T;\n error?: string;\n}\n\nexport const parseServerFrame = (line: string): ParseResult<ServerFrame> => {\n try {\n const value: unknown = JSON.parse(line);\n if (!isServerFrame(value)) {\n return { ok: false, error: \"invalid server frame\" };\n }\n return { ok: true, frame: value };\n } catch (error) {\n return {\n ok: false,\n error: error instanceof Error ? error.message : \"unknown parse error\",\n };\n }\n};\n\nconst isRecord = (value: unknown): value is Record<string, unknown> =>\n typeof value === \"object\" && value !== null && !Array.isArray(value);\n\nexport const isServerFrame = (value: unknown): value is ServerFrame =>\n isRecord(value) && typeof value.type === \"string\";\n"],"mappings":";AAgIA,MAAa,oBAAoB,SAA2C;CAC1E,IAAI;EACF,MAAM,QAAiB,KAAK,MAAM,IAAI;EACtC,IAAI,CAAC,cAAc,KAAK,GACtB,OAAO;GAAE,IAAI;GAAO,OAAO;EAAuB;EAEpD,OAAO;GAAE,IAAI;GAAM,OAAO;EAAM;CAClC,SAAS,OAAO;EACd,OAAO;GACL,IAAI;GACJ,OAAO,iBAAiB,QAAQ,MAAM,UAAU;EAClD;CACF;AACF;AAEA,MAAM,YAAY,UAChB,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,KAAK;AAErE,MAAa,iBAAiB,UAC5B,SAAS,KAAK,KAAK,OAAO,MAAM,SAAS"}
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../src/index.ts"],"sourcesContent":["export type LeaseId = string;\nexport type RequestId = string;\nexport type SurfaceId = string;\nexport type TrayId = string;\nexport type MenuItemId = number;\n\nexport const PROTOCOL_VERSION = 1;\n\nexport interface BrokerEndpointIdentity {\n packageVersion: string;\n protocolVersion: number;\n}\n\nexport interface BrokerEndpointIdentityOptions {\n packageVersion: string;\n protocolVersion?: number;\n}\n\nexport const createBrokerEndpointIdentity = ({\n packageVersion,\n protocolVersion = PROTOCOL_VERSION,\n}: BrokerEndpointIdentityOptions): BrokerEndpointIdentity => {\n assertEndpointComponent(packageVersion, \"packageVersion\");\n if (!Number.isInteger(protocolVersion) || protocolVersion <= 0) {\n throw new Error(`protocolVersion must be a positive integer: ${protocolVersion}`);\n }\n\n return {\n packageVersion,\n protocolVersion,\n };\n};\n\nexport const isSupportedProtocolVersion = (protocolVersion: number): boolean =>\n protocolVersion === PROTOCOL_VERSION;\n\nexport const formatBrokerEndpointName = (identity: BrokerEndpointIdentity): string => {\n assertEndpointIdentity(identity);\n return `opentray-${identity.packageVersion}-p${identity.protocolVersion}`;\n};\n\nexport const formatBrokerStateRoot = (homeDir: string, identity: BrokerEndpointIdentity): string => {\n assertEndpointIdentity(identity);\n if (homeDir.length === 0) {\n throw new Error(\"homeDir must not be empty\");\n }\n\n const normalizedHome = homeDir.replace(/[\\\\/]+$/u, \"\");\n return `${normalizedHome}/.opentray/${identity.packageVersion}`;\n};\n\nexport const formatUnixSocketPath = (homeDir: string, identity: BrokerEndpointIdentity): string =>\n `${formatBrokerStateRoot(homeDir, identity)}/opentray-p${identity.protocolVersion}.sock`;\n\nexport const formatWindowsPipeName = (identity: BrokerEndpointIdentity): string =>\n `\\\\\\\\.\\\\pipe\\\\${formatBrokerEndpointName(identity)}`;\n\nconst endpointComponentPattern = /^[0-9A-Za-z._+-]+$/u;\n\nconst assertEndpointIdentity = (identity: BrokerEndpointIdentity): void => {\n assertEndpointComponent(identity.packageVersion, \"packageVersion\");\n if (!Number.isInteger(identity.protocolVersion) || identity.protocolVersion <= 0) {\n throw new Error(`protocolVersion must be a positive integer: ${identity.protocolVersion}`);\n }\n};\n\nconst assertEndpointComponent = (value: string, name: string): void => {\n if (value.length === 0) {\n throw new Error(`${name} must not be empty`);\n }\n if (!endpointComponentPattern.test(value)) {\n throw new Error(`${name} contains invalid endpoint characters: ${value}`);\n }\n};\n\nexport interface SurfaceOptions {\n appId: string;\n title?: string;\n icon?: Icon;\n default?: boolean;\n}\n\nexport interface SurfaceRef {\n surfaceId: SurfaceId;\n appId: string;\n}\n\nexport interface TrayOptions {\n trayId?: TrayId;\n appId?: string;\n title?: string;\n tooltip?: Tooltip;\n icon: Icon;\n menu?: Menu;\n}\n\nexport interface Tooltip {\n title: string;\n description: string;\n}\n\nexport interface Menu {\n items: MenuItem[];\n}\n\nexport type MenuItem =\n | {\n type: \"item\";\n id: MenuItemId;\n title: string;\n enabled?: boolean;\n shortcut?: string;\n }\n | {\n type: \"check\";\n id: MenuItemId;\n title: string;\n enabled?: boolean;\n checked?: boolean;\n }\n | {\n type: \"radio\";\n id: MenuItemId;\n title: string;\n enabled?: boolean;\n checked?: boolean;\n group: number;\n }\n | {\n type: \"separator\";\n }\n | {\n type: \"submenu\";\n title: string;\n enabled?: boolean;\n items: MenuItem[];\n };\n\nexport type Icon =\n | { type: \"rgba\"; data: Uint8Array | number[]; width: number; height: number }\n | { type: \"encoded\"; data: Uint8Array | number[] }\n | { type: \"file\"; path: string };\n\nexport interface Rect {\n x: number;\n y: number;\n width: number;\n height: number;\n}\n\nexport type MouseButton = \"left\" | \"right\" | \"middle\";\n\nexport type TrayEvent =\n | { type: \"ready\"; surfaceId: SurfaceId }\n | { type: \"menuClick\"; surfaceId: SurfaceId; trayId: TrayId; itemId: MenuItemId }\n | { type: \"trayClick\"; surfaceId: SurfaceId; button: MouseButton; x: number; y: number }\n | { type: \"trayDoubleClick\"; surfaceId: SurfaceId; button: MouseButton; x: number; y: number };\n\nexport interface ExtensionScope {\n surfaceId: SurfaceId;\n trayId?: TrayId;\n ext: string;\n}\n\nexport interface ExtensionEnvelope<TData = unknown> {\n scope: ExtensionScope;\n data: TData;\n}\n\nexport interface DaemonSessionHealth {\n sessionId: number;\n leaseId?: LeaseId;\n initialized: boolean;\n}\n\nexport interface DaemonHealth {\n pid: number;\n packageVersion: string;\n protocolVersion: number;\n endpoint: string;\n sessionCount: number;\n sessions: DaemonSessionHealth[];\n}\n\nexport type ClientFrame =\n | { type: \"init\"; protocolVersion: number; clientVersion: string }\n | ClientRequestFrame\n | { type: \"exit\" };\n\nexport type ClientRequestFrame =\n | ({ type: \"create-surface\"; requestId: RequestId } & SurfaceOptions)\n | { type: \"resolve-default-surface\"; requestId: RequestId }\n | { type: \"create-tray\"; requestId: RequestId; surface: SurfaceRef; tray: TrayOptions }\n | { type: \"destroy-tray\"; requestId: RequestId; surfaceId: SurfaceId; trayId: TrayId }\n | { type: \"set-tray-menu\"; requestId: RequestId; surfaceId: SurfaceId; trayId: TrayId; menu: Menu }\n | { type: \"set-tray-icon\"; requestId: RequestId; surfaceId: SurfaceId; trayId: TrayId; icon: Icon }\n | { type: \"set-tray-tooltip\"; requestId: RequestId; surfaceId: SurfaceId; trayId: TrayId; tooltip: Tooltip }\n | { type: \"load-ext\"; requestId: RequestId; surfaceId: SurfaceId; name: string; path: string }\n | { type: \"ext-command\"; requestId: RequestId; surfaceId: SurfaceId; trayId: TrayId; ext: string; data: unknown }\n | { type: \"unload-ext\"; requestId: RequestId; surfaceId: SurfaceId; name: string }\n | { type: \"health\"; requestId: RequestId };\n\nexport type ServerFrame =\n | { type: \"ready\"; protocolVersion: number; brokerVersion: string; leaseId: LeaseId }\n | { type: \"surface-created\"; requestId: RequestId; surface: SurfaceRef }\n | { type: \"default-surface\"; requestId: RequestId; surface: SurfaceRef }\n | { type: \"tray-created\"; requestId: RequestId; surfaceId: SurfaceId; trayId: TrayId }\n | { type: \"ack\"; requestId: RequestId }\n | { type: \"daemon-health\"; requestId: RequestId; health: DaemonHealth }\n | { type: \"event\"; event: TrayEvent }\n | { type: \"ext-event\"; surfaceId: SurfaceId; trayId: TrayId; ext: string; data: unknown }\n | { type: \"error\"; requestId?: RequestId; code: string; message: string };\n\nexport interface ParseResult<T> {\n ok: boolean;\n frame?: T;\n error?: string;\n}\n\nexport const parseServerFrame = (line: string): ParseResult<ServerFrame> => {\n try {\n const value: unknown = JSON.parse(line);\n if (!isServerFrame(value)) {\n return { ok: false, error: \"invalid server frame\" };\n }\n return { ok: true, frame: value };\n } catch (error) {\n return {\n ok: false,\n error: error instanceof Error ? error.message : \"unknown parse error\",\n };\n }\n};\n\nconst isRecord = (value: unknown): value is Record<string, unknown> =>\n typeof value === \"object\" && value !== null && !Array.isArray(value);\n\nexport const isServerFrame = (value: unknown): value is ServerFrame => {\n if (!isRecord(value) || typeof value.type !== \"string\") {\n return false;\n }\n\n switch (value.type) {\n case \"ready\":\n return (\n typeof value.protocolVersion === \"number\" &&\n typeof value.brokerVersion === \"string\" &&\n typeof value.leaseId === \"string\"\n );\n case \"surface-created\":\n return typeof value.requestId === \"string\" && isRecord(value.surface);\n case \"default-surface\":\n return typeof value.requestId === \"string\" && isRecord(value.surface);\n case \"tray-created\":\n return (\n typeof value.requestId === \"string\" &&\n typeof value.surfaceId === \"string\" &&\n typeof value.trayId === \"string\"\n );\n case \"ack\":\n return typeof value.requestId === \"string\";\n case \"daemon-health\":\n return typeof value.requestId === \"string\" && isDaemonHealth(value.health);\n case \"event\":\n return isTrayEvent(value.event);\n case \"ext-event\":\n return (\n typeof value.surfaceId === \"string\" &&\n typeof value.trayId === \"string\" &&\n typeof value.ext === \"string\"\n );\n case \"error\":\n return (\n (value.requestId === undefined || typeof value.requestId === \"string\") &&\n typeof value.code === \"string\" &&\n typeof value.message === \"string\"\n );\n default:\n return false;\n }\n};\n\nconst isDaemonHealth = (value: unknown): value is DaemonHealth => {\n if (!isRecord(value)) {\n return false;\n }\n\n return (\n typeof value.pid === \"number\" &&\n typeof value.packageVersion === \"string\" &&\n typeof value.protocolVersion === \"number\" &&\n typeof value.endpoint === \"string\" &&\n typeof value.sessionCount === \"number\" &&\n Array.isArray(value.sessions) &&\n value.sessions.every(isDaemonSessionHealth)\n );\n};\n\nconst isDaemonSessionHealth = (value: unknown): value is DaemonSessionHealth =>\n isRecord(value) &&\n typeof value.sessionId === \"number\" &&\n (value.leaseId === undefined || typeof value.leaseId === \"string\") &&\n typeof value.initialized === \"boolean\";\n\nconst isTrayEvent = (value: unknown): value is TrayEvent => {\n if (!isRecord(value) || typeof value.type !== \"string\") {\n return false;\n }\n\n switch (value.type) {\n case \"ready\":\n return typeof value.surfaceId === \"string\";\n case \"menuClick\":\n return (\n typeof value.surfaceId === \"string\" &&\n typeof value.trayId === \"string\" &&\n typeof value.itemId === \"number\"\n );\n case \"trayClick\":\n case \"trayDoubleClick\":\n return (\n typeof value.surfaceId === \"string\" &&\n isMouseButton(value.button) &&\n typeof value.x === \"number\" &&\n typeof value.y === \"number\"\n );\n default:\n return false;\n }\n};\n\nconst isMouseButton = (value: unknown): value is MouseButton =>\n value === \"left\" || value === \"right\" || value === \"middle\";\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@opentray/spec",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "description": "Shared TypeScript protocol and contract types for OpenTray.",
5
5
  "type": "module",
6
6
  "license": "MIT",