@gtkx/mcp 1.0.0-rc.1 → 1.0.0-rc.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.
Files changed (47) hide show
  1. package/bin/gtkx-mcp.js +1 -0
  2. package/dist/app-router.d.ts +14 -14
  3. package/dist/app-router.d.ts.map +1 -1
  4. package/dist/app-router.js +73 -60
  5. package/dist/app-router.js.map +1 -1
  6. package/dist/connection-registry.d.ts +3 -3
  7. package/dist/connection-registry.d.ts.map +1 -1
  8. package/dist/connection-registry.js +8 -7
  9. package/dist/connection-registry.js.map +1 -1
  10. package/dist/protocol/errors.d.ts +12 -11
  11. package/dist/protocol/errors.d.ts.map +1 -1
  12. package/dist/protocol/errors.js +25 -24
  13. package/dist/protocol/errors.js.map +1 -1
  14. package/dist/protocol/schemas.d.ts +46 -42
  15. package/dist/protocol/schemas.d.ts.map +1 -1
  16. package/dist/protocol/schemas.js +20 -13
  17. package/dist/protocol/schemas.js.map +1 -1
  18. package/dist/reference.d.ts +6 -6
  19. package/dist/reference.d.ts.map +1 -1
  20. package/dist/reference.js +166 -123
  21. package/dist/reference.js.map +1 -1
  22. package/dist/server.d.ts +4 -4
  23. package/dist/server.d.ts.map +1 -1
  24. package/dist/server.js +73 -49
  25. package/dist/server.js.map +1 -1
  26. package/dist/socket-server.d.ts +2 -1
  27. package/dist/socket-server.d.ts.map +1 -1
  28. package/dist/socket-server.js +26 -15
  29. package/dist/socket-server.js.map +1 -1
  30. package/dist/tool.d.ts +8 -8
  31. package/dist/tool.d.ts.map +1 -1
  32. package/dist/tool.js +14 -10
  33. package/dist/tool.js.map +1 -1
  34. package/dist/transport.d.ts +30 -22
  35. package/dist/transport.d.ts.map +1 -1
  36. package/dist/transport.js +94 -63
  37. package/dist/transport.js.map +1 -1
  38. package/package.json +5 -7
  39. package/src/app-router.ts +114 -77
  40. package/src/connection-registry.ts +22 -7
  41. package/src/protocol/errors.ts +45 -32
  42. package/src/protocol/schemas.ts +91 -66
  43. package/src/reference.ts +248 -139
  44. package/src/server.ts +120 -67
  45. package/src/socket-server.ts +41 -18
  46. package/src/tool.ts +28 -21
  47. package/src/transport.ts +163 -86
package/bin/gtkx-mcp.js CHANGED
@@ -1,4 +1,5 @@
1
1
  #!/usr/bin/env node
2
+ import process from "node:process";
2
3
  import { log, main } from "../dist/server.js";
3
4
 
4
5
  try {
@@ -1,16 +1,15 @@
1
- import EventEmitter from "node:events";
2
1
  import { type AppInfo } from "./protocol/schemas.js";
3
2
  import { type AppConnections, type ProtocolConnection } from "./transport.js";
4
- type AppRouterEventMap = {
5
- appRegistered: [AppInfo];
6
- appUnregistered: [string];
7
- };
3
+ type AppRegisteredEvent = CustomEvent<AppInfo>;
4
+ type AppUnregisteredEvent = CustomEvent<string>;
8
5
  type RegisteredApp = {
9
6
  info: AppInfo;
10
7
  connection: ProtocolConnection;
11
8
  };
12
- export declare class AppRouter extends EventEmitter<AppRouterEventMap> {
13
- private static DEFAULT_WAIT_TIMEOUT;
9
+ declare function appRegisteredEvent(info: AppInfo): AppRegisteredEvent;
10
+ declare function appUnregisteredEvent(applicationId: string): AppUnregisteredEvent;
11
+ declare class AppRouter extends EventTarget {
12
+ private static defaultWaitTimeout;
14
13
  private apps;
15
14
  private connectionToApp;
16
15
  private requestTimeout;
@@ -18,18 +17,19 @@ export declare class AppRouter extends EventEmitter<AppRouterEventMap> {
18
17
  constructor(connections: AppConnections, options?: {
19
18
  requestTimeout?: number;
20
19
  });
21
- getApps(): AppInfo[];
22
- hasConnectedApps(): boolean;
23
- getDefaultApp(): RegisteredApp | undefined;
24
- getProjectRoot(): string | undefined;
25
- waitForApp(timeout?: number): Promise<AppInfo>;
26
- sendToApp<T>(applicationId: string | undefined, method: string, params?: unknown): Promise<T>;
20
+ private resolveTargetApp;
27
21
  private handleRequest;
28
22
  private handleRegister;
29
23
  private handleUnregister;
30
24
  private acknowledge;
31
25
  private sendError;
32
26
  private removeApp;
27
+ getApps(): AppInfo[];
28
+ hasConnectedApps(): boolean;
29
+ getDefaultApp(): RegisteredApp | undefined;
30
+ getProjectRoot(): string | undefined;
31
+ waitForApp(timeout?: number): Promise<AppInfo>;
32
+ sendToApp<T>(applicationId: string | undefined, method: string, params?: unknown): Promise<T>;
33
33
  }
34
- export {};
34
+ export { AppRouter, appRegisteredEvent, appUnregisteredEvent, type AppRegisteredEvent, type AppUnregisteredEvent };
35
35
  //# sourceMappingURL=app-router.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"app-router.d.ts","sourceRoot":"","sources":["../src/app-router.ts"],"names":[],"mappings":"AAAA,OAAO,YAAY,MAAM,aAAa,CAAC;AASvC,OAAO,EAAE,KAAK,OAAO,EAAqD,MAAM,uBAAuB,CAAC;AACxG,OAAO,EAAE,KAAK,cAAc,EAAyB,KAAK,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAErG,KAAK,iBAAiB,GAAG;IACrB,aAAa,EAAE,CAAC,OAAO,CAAC,CAAC;IACzB,eAAe,EAAE,CAAC,MAAM,CAAC,CAAC;CAC7B,CAAC;AAEF,KAAK,aAAa,GAAG;IACjB,IAAI,EAAE,OAAO,CAAC;IACd,UAAU,EAAE,kBAAkB,CAAC;CAClC,CAAC;AAIF,qBAAa,SAAU,SAAQ,YAAY,CAAC,iBAAiB,CAAC;IAC1D,OAAO,CAAC,MAAM,CAAC,oBAAoB,CAAS;IAE5C,OAAO,CAAC,IAAI,CAAyC;IACrD,OAAO,CAAC,eAAe,CAAkC;IACzD,OAAO,CAAC,cAAc,CAAS;IAC/B,OAAO,CAAC,WAAW,CAAiB;IAEpC,YAAY,WAAW,EAAE,cAAc,EAAE,OAAO,GAAE;QAAE,cAAc,CAAC,EAAE,MAAM,CAAA;KAAO,EAYjF;IAED,OAAO,IAAI,OAAO,EAAE,CAEnB;IAED,gBAAgB,IAAI,OAAO,CAE1B;IAED,aAAa,IAAI,aAAa,GAAG,SAAS,CAGzC;IAED,cAAc,IAAI,MAAM,GAAG,SAAS,CAEnC;IAED,UAAU,CAAC,OAAO,GAAE,MAAuC,GAAG,OAAO,CAAC,OAAO,CAAC,CAyB7E;IAEK,SAAS,CAAC,CAAC,EAAE,aAAa,EAAE,MAAM,GAAG,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,CAAC,CAAC,CAmBlG;IAED,OAAO,CAAC,aAAa;IAUrB,OAAO,CAAC,cAAc;IAsBtB,OAAO,CAAC,gBAAgB;IAKxB,OAAO,CAAC,WAAW;IAQnB,OAAO,CAAC,SAAS;IAOjB,OAAO,CAAC,SAAS;CAQpB"}
1
+ {"version":3,"file":"app-router.d.ts","sourceRoot":"","sources":["../src/app-router.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,KAAK,OAAO,EAAqD,MAAM,uBAAuB,CAAC;AACxG,OAAO,EACH,KAAK,cAAc,EAInB,KAAK,kBAAkB,EAC1B,MAAM,gBAAgB,CAAC;AAExB,KAAK,kBAAkB,GAAG,WAAW,CAAC,OAAO,CAAC,CAAC;AAC/C,KAAK,oBAAoB,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC;AAEhD,KAAK,aAAa,GAAG;IACjB,IAAI,EAAE,OAAO,CAAC;IACd,UAAU,EAAE,kBAAkB,CAAC;CAClC,CAAC;AAIF,iBAAS,kBAAkB,CAAC,IAAI,EAAE,OAAO,GAAG,kBAAkB,CAE7D;AAED,iBAAS,oBAAoB,CAAC,aAAa,EAAE,MAAM,GAAG,oBAAoB,CAEzE;AAED,cAAM,SAAU,SAAQ,WAAW;IAC/B,OAAO,CAAC,MAAM,CAAC,kBAAkB,CAAU;IAE3C,OAAO,CAAC,IAAI,CAAyC;IAErD,OAAO,CAAC,eAAe,CAAkC;IAEzD,OAAO,CAAC,cAAc,CAAS;IAE/B,OAAO,CAAC,WAAW,CAAiB;gBAExB,WAAW,EAAE,cAAc,EAAE,OAAO,GAAE;QAAE,cAAc,CAAC,EAAE,MAAM,CAAA;KAAO;IAelF,OAAO,CAAC,gBAAgB;IAcxB,OAAO,CAAC,aAAa;IAUrB,OAAO,CAAC,cAAc;IAuBtB,OAAO,CAAC,gBAAgB;IAKxB,OAAO,CAAC,WAAW;IASnB,OAAO,CAAC,SAAS;IAOjB,OAAO,CAAC,SAAS;IAgBjB,OAAO,IAAI,OAAO,EAAE;IAIpB,gBAAgB,IAAI,OAAO;IAI3B,aAAa,IAAI,aAAa,GAAG,SAAS;IAM1C,cAAc,IAAI,MAAM,GAAG,SAAS;IAIpC,UAAU,CAAC,OAAO,GAAE,MAAqC,GAAG,OAAO,CAAC,OAAO,CAAC;IA6BtE,SAAS,CAAC,CAAC,EAAE,aAAa,EAAE,MAAM,GAAG,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,CAAC,CAAC;CActG;AAED,OAAO,EAAE,SAAS,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,KAAK,kBAAkB,EAAE,KAAK,oBAAoB,EAAE,CAAC"}
@@ -1,10 +1,15 @@
1
- import EventEmitter from "node:events";
2
1
  import { appNotFoundError, connectionWriteFailedError, invalidRequestError, methodNotFoundError, noAppConnectedError, } from "./protocol/errors.js";
3
2
  import { RegisterParamsSchema } from "./protocol/schemas.js";
4
- import { ConnectionClosedError } from "./transport.js";
5
- const DEFAULT_REQUEST_TIMEOUT_MS = 30000;
6
- export class AppRouter extends EventEmitter {
7
- static DEFAULT_WAIT_TIMEOUT = 10000;
3
+ import { ConnectionClosedError, } from "./transport.js";
4
+ const DEFAULT_REQUEST_TIMEOUT_MS = 30_000;
5
+ function appRegisteredEvent(info) {
6
+ return new CustomEvent("appRegistered", { detail: info });
7
+ }
8
+ function appUnregisteredEvent(applicationId) {
9
+ return new CustomEvent("appUnregistered", { detail: applicationId });
10
+ }
11
+ class AppRouter extends EventTarget {
12
+ static defaultWaitTimeout = 10_000;
8
13
  apps = new Map();
9
14
  connectionToApp = new Map();
10
15
  requestTimeout;
@@ -13,63 +18,23 @@ export class AppRouter extends EventEmitter {
13
18
  super();
14
19
  this.connections = connections;
15
20
  this.requestTimeout = options.requestTimeout ?? DEFAULT_REQUEST_TIMEOUT_MS;
16
- this.connections.on("request", (connection, request) => {
21
+ this.connections.addEventListener("request", (event) => {
22
+ const { connection, request } = event.detail;
17
23
  this.handleRequest(connection, request);
18
24
  });
19
- this.connections.on("disconnection", (connection) => {
20
- this.removeApp(connection);
21
- });
22
- }
23
- getApps() {
24
- return Array.from(this.apps.values()).map((app) => app.info);
25
- }
26
- hasConnectedApps() {
27
- return this.apps.size > 0;
28
- }
29
- getDefaultApp() {
30
- const first = this.apps.values().next();
31
- return first.done ? undefined : first.value;
32
- }
33
- getProjectRoot() {
34
- return this.getDefaultApp()?.info.projectRoot;
35
- }
36
- waitForApp(timeout = AppRouter.DEFAULT_WAIT_TIMEOUT) {
37
- const defaultApp = this.getDefaultApp();
38
- if (defaultApp) {
39
- return Promise.resolve(defaultApp.info);
40
- }
41
- return new Promise((resolve, reject) => {
42
- const timeoutId = setTimeout(() => {
43
- this.off("appRegistered", onRegister);
44
- reject(new Error(`Timeout waiting for app registration after ${timeout}ms. ` +
45
- "Make sure your GTKX app is running with 'gtkx dev'."));
46
- }, timeout);
47
- const onRegister = (appInfo) => {
48
- clearTimeout(timeoutId);
49
- this.off("appRegistered", onRegister);
50
- resolve(appInfo);
51
- };
52
- this.on("appRegistered", onRegister);
25
+ this.connections.addEventListener("disconnection", (event) => {
26
+ this.removeApp(event.detail);
53
27
  });
54
28
  }
55
- async sendToApp(applicationId, method, params) {
29
+ resolveTargetApp(applicationId) {
56
30
  const app = applicationId ? this.apps.get(applicationId) : this.getDefaultApp();
57
- if (!app) {
58
- if (applicationId) {
59
- throw appNotFoundError(applicationId);
60
- }
61
- throw noAppConnectedError();
31
+ if (app) {
32
+ return app;
62
33
  }
63
- try {
64
- return await app.connection.send(method, params, this.requestTimeout);
65
- }
66
- catch (error) {
67
- if (error instanceof ConnectionClosedError) {
68
- this.removeApp(app.connection);
69
- throw connectionWriteFailedError(app.info.applicationId);
70
- }
71
- throw error;
34
+ if (applicationId) {
35
+ throw appNotFoundError(applicationId);
72
36
  }
37
+ throw noAppConnectedError();
73
38
  }
74
39
  handleRequest(connection, request) {
75
40
  if (request.method === "app.register") {
@@ -92,12 +57,12 @@ export class AppRouter extends EventEmitter {
92
57
  const appInfo = {
93
58
  applicationId: params.applicationId,
94
59
  pid: params.pid,
95
- ...(params.projectRoot === undefined ? {} : { projectRoot: params.projectRoot }),
60
+ ...(params.projectRoot !== undefined && { projectRoot: params.projectRoot }),
96
61
  };
97
62
  this.apps.set(params.applicationId, { info: appInfo, connection });
98
63
  this.connectionToApp.set(connection.id, params.applicationId);
99
64
  this.acknowledge(connection, request);
100
- this.emit("appRegistered", appInfo);
65
+ this.dispatchEvent(appRegisteredEvent(appInfo));
101
66
  }
102
67
  handleUnregister(connection, request) {
103
68
  this.removeApp(connection);
@@ -119,12 +84,60 @@ export class AppRouter extends EventEmitter {
119
84
  removeApp(connection) {
120
85
  const applicationId = this.connectionToApp.get(connection.id);
121
86
  this.connectionToApp.delete(connection.id);
122
- if (applicationId === undefined)
87
+ if (applicationId === undefined) {
123
88
  return;
124
- if (this.apps.get(applicationId)?.connection !== connection)
89
+ }
90
+ if (this.apps.get(applicationId)?.connection !== connection) {
125
91
  return;
92
+ }
126
93
  this.apps.delete(applicationId);
127
- this.emit("appUnregistered", applicationId);
94
+ this.dispatchEvent(appUnregisteredEvent(applicationId));
95
+ }
96
+ getApps() {
97
+ return this.apps.values().map((app) => app.info).toArray();
98
+ }
99
+ hasConnectedApps() {
100
+ return this.apps.size > 0;
101
+ }
102
+ getDefaultApp() {
103
+ const first = this.apps.values().next();
104
+ return first.done ? undefined : first.value;
105
+ }
106
+ getProjectRoot() {
107
+ return this.getDefaultApp()?.info.projectRoot;
108
+ }
109
+ waitForApp(timeout = AppRouter.defaultWaitTimeout) {
110
+ const defaultApp = this.getDefaultApp();
111
+ if (defaultApp) {
112
+ return Promise.resolve(defaultApp.info);
113
+ }
114
+ return new Promise((resolve, reject) => {
115
+ const timeoutId = setTimeout(() => {
116
+ this.removeEventListener("appRegistered", onRegister);
117
+ reject(new Error(`Timeout waiting for app registration after ${String(timeout)}ms. ` +
118
+ "Make sure your GTKX app is running with 'gtkx dev'."));
119
+ }, timeout);
120
+ const onRegister = (event) => {
121
+ clearTimeout(timeoutId);
122
+ this.removeEventListener("appRegistered", onRegister);
123
+ resolve(event.detail);
124
+ };
125
+ this.addEventListener("appRegistered", onRegister);
126
+ });
127
+ }
128
+ async sendToApp(applicationId, method, params) {
129
+ const app = this.resolveTargetApp(applicationId);
130
+ try {
131
+ return await app.connection.send(method, params, this.requestTimeout);
132
+ }
133
+ catch (error) {
134
+ if (error instanceof ConnectionClosedError) {
135
+ this.removeApp(app.connection);
136
+ throw connectionWriteFailedError(app.info.applicationId);
137
+ }
138
+ throw error;
139
+ }
128
140
  }
129
141
  }
142
+ export { AppRouter, appRegisteredEvent, appUnregisteredEvent };
130
143
  //# sourceMappingURL=app-router.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"app-router.js","sourceRoot":"","sources":["../src/app-router.ts"],"names":[],"mappings":"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","sourcesContent":["import EventEmitter from \"node:events\";\nimport {\n appNotFoundError,\n connectionWriteFailedError,\n invalidRequestError,\n methodNotFoundError,\n noAppConnectedError,\n type ProtocolError,\n} from \"./protocol/errors.js\";\nimport { type AppInfo, RegisterParamsSchema, type Request, type Response } from \"./protocol/schemas.js\";\nimport { type AppConnections, ConnectionClosedError, type ProtocolConnection } from \"./transport.js\";\n\ntype AppRouterEventMap = {\n appRegistered: [AppInfo];\n appUnregistered: [string];\n};\n\ntype RegisteredApp = {\n info: AppInfo;\n connection: ProtocolConnection;\n};\n\nconst DEFAULT_REQUEST_TIMEOUT_MS = 30000;\n\nexport class AppRouter extends EventEmitter<AppRouterEventMap> {\n private static DEFAULT_WAIT_TIMEOUT = 10000;\n\n private apps: Map<string, RegisteredApp> = new Map();\n private connectionToApp: Map<string, string> = new Map();\n private requestTimeout: number;\n private connections: AppConnections;\n\n constructor(connections: AppConnections, options: { requestTimeout?: number } = {}) {\n super();\n this.connections = connections;\n this.requestTimeout = options.requestTimeout ?? DEFAULT_REQUEST_TIMEOUT_MS;\n\n this.connections.on(\"request\", (connection, request) => {\n this.handleRequest(connection, request);\n });\n\n this.connections.on(\"disconnection\", (connection) => {\n this.removeApp(connection);\n });\n }\n\n getApps(): AppInfo[] {\n return Array.from(this.apps.values()).map((app) => app.info);\n }\n\n hasConnectedApps(): boolean {\n return this.apps.size > 0;\n }\n\n getDefaultApp(): RegisteredApp | undefined {\n const first = this.apps.values().next();\n return first.done ? undefined : first.value;\n }\n\n getProjectRoot(): string | undefined {\n return this.getDefaultApp()?.info.projectRoot;\n }\n\n waitForApp(timeout: number = AppRouter.DEFAULT_WAIT_TIMEOUT): Promise<AppInfo> {\n const defaultApp = this.getDefaultApp();\n if (defaultApp) {\n return Promise.resolve(defaultApp.info);\n }\n\n return new Promise((resolve, reject) => {\n const timeoutId = setTimeout(() => {\n this.off(\"appRegistered\", onRegister);\n reject(\n new Error(\n `Timeout waiting for app registration after ${timeout}ms. ` +\n \"Make sure your GTKX app is running with 'gtkx dev'.\",\n ),\n );\n }, timeout);\n\n const onRegister = (appInfo: AppInfo) => {\n clearTimeout(timeoutId);\n this.off(\"appRegistered\", onRegister);\n resolve(appInfo);\n };\n\n this.on(\"appRegistered\", onRegister);\n });\n }\n\n async sendToApp<T>(applicationId: string | undefined, method: string, params?: unknown): Promise<T> {\n const app = applicationId ? this.apps.get(applicationId) : this.getDefaultApp();\n\n if (!app) {\n if (applicationId) {\n throw appNotFoundError(applicationId);\n }\n throw noAppConnectedError();\n }\n\n try {\n return await app.connection.send<T>(method, params, this.requestTimeout);\n } catch (error) {\n if (error instanceof ConnectionClosedError) {\n this.removeApp(app.connection);\n throw connectionWriteFailedError(app.info.applicationId);\n }\n throw error;\n }\n }\n\n private handleRequest(connection: ProtocolConnection, request: Request): void {\n if (request.method === \"app.register\") {\n this.handleRegister(connection, request);\n } else if (request.method === \"app.unregister\") {\n this.handleUnregister(connection, request);\n } else {\n this.sendError(connection, request, methodNotFoundError(request.method));\n }\n }\n\n private handleRegister(connection: ProtocolConnection, request: Request): void {\n const parseResult = RegisterParamsSchema.safeParse(request.params);\n if (!parseResult.success) {\n this.sendError(connection, request, invalidRequestError(parseResult.error.message));\n return;\n }\n\n const params = parseResult.data;\n const appInfo: AppInfo = {\n applicationId: params.applicationId,\n pid: params.pid,\n ...(params.projectRoot === undefined ? {} : { projectRoot: params.projectRoot }),\n };\n\n this.apps.set(params.applicationId, { info: appInfo, connection });\n this.connectionToApp.set(connection.id, params.applicationId);\n\n this.acknowledge(connection, request);\n\n this.emit(\"appRegistered\", appInfo);\n }\n\n private handleUnregister(connection: ProtocolConnection, request: Request): void {\n this.removeApp(connection);\n this.acknowledge(connection, request);\n }\n\n private acknowledge(connection: ProtocolConnection, request: Request): void {\n const response: Response = {\n id: request.id,\n result: { success: true },\n };\n this.connections.send(connection.id, response);\n }\n\n private sendError(connection: ProtocolConnection, request: Request, error: ProtocolError): void {\n this.connections.send(connection.id, {\n id: request.id,\n error: error.toErrorObject(),\n });\n }\n\n private removeApp(connection: ProtocolConnection): void {\n const applicationId = this.connectionToApp.get(connection.id);\n this.connectionToApp.delete(connection.id);\n if (applicationId === undefined) return;\n if (this.apps.get(applicationId)?.connection !== connection) return;\n this.apps.delete(applicationId);\n this.emit(\"appUnregistered\", applicationId);\n }\n}\n"]}
1
+ {"version":3,"file":"app-router.js","sourceRoot":"","sources":["../src/app-router.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n appNotFoundError,\n connectionWriteFailedError,\n invalidRequestError,\n methodNotFoundError,\n noAppConnectedError,\n type ProtocolError,\n} from \"./protocol/errors.js\";\nimport { type AppInfo, RegisterParamsSchema, type Request, type Response } from \"./protocol/schemas.js\";\nimport {\n type AppConnections,\n ConnectionClosedError,\n type ConnectionEvent,\n type ConnectionRequestEvent,\n type ProtocolConnection,\n} from \"./transport.js\";\n\ntype AppRegisteredEvent = CustomEvent<AppInfo>;\ntype AppUnregisteredEvent = CustomEvent<string>;\n\ntype RegisteredApp = {\n info: AppInfo;\n connection: ProtocolConnection;\n};\n\nconst DEFAULT_REQUEST_TIMEOUT_MS = 30_000;\n\nfunction appRegisteredEvent(info: AppInfo): AppRegisteredEvent {\n return new CustomEvent(\"appRegistered\", { detail: info });\n}\n\nfunction appUnregisteredEvent(applicationId: string): AppUnregisteredEvent {\n return new CustomEvent(\"appUnregistered\", { detail: applicationId });\n}\n\nclass AppRouter extends EventTarget {\n private static defaultWaitTimeout = 10_000;\n\n private apps: Map<string, RegisteredApp> = new Map();\n\n private connectionToApp: Map<string, string> = new Map();\n\n private requestTimeout: number;\n\n private connections: AppConnections;\n\n constructor(connections: AppConnections, options: { requestTimeout?: number } = {}) {\n super();\n this.connections = connections;\n this.requestTimeout = options.requestTimeout ?? DEFAULT_REQUEST_TIMEOUT_MS;\n\n this.connections.addEventListener(\"request\", (event) => {\n const { connection, request } = (event as ConnectionRequestEvent).detail;\n this.handleRequest(connection, request);\n });\n\n this.connections.addEventListener(\"disconnection\", (event) => {\n this.removeApp((event as ConnectionEvent).detail);\n });\n }\n\n private resolveTargetApp(applicationId: string | undefined): RegisteredApp {\n const app = applicationId ? this.apps.get(applicationId) : this.getDefaultApp();\n\n if (app) {\n return app;\n }\n\n if (applicationId) {\n throw appNotFoundError(applicationId);\n }\n\n throw noAppConnectedError();\n }\n\n private handleRequest(connection: ProtocolConnection, request: Request): void {\n if (request.method === \"app.register\") {\n this.handleRegister(connection, request);\n } else if (request.method === \"app.unregister\") {\n this.handleUnregister(connection, request);\n } else {\n this.sendError(connection, request, methodNotFoundError(request.method));\n }\n }\n\n private handleRegister(connection: ProtocolConnection, request: Request): void {\n const parseResult = RegisterParamsSchema.safeParse(request.params);\n\n if (!parseResult.success) {\n this.sendError(connection, request, invalidRequestError(parseResult.error.message));\n\n return;\n }\n\n const params = parseResult.data;\n\n const appInfo: AppInfo = {\n applicationId: params.applicationId,\n pid: params.pid,\n ...(params.projectRoot !== undefined && { projectRoot: params.projectRoot }),\n };\n\n this.apps.set(params.applicationId, { info: appInfo, connection });\n this.connectionToApp.set(connection.id, params.applicationId);\n this.acknowledge(connection, request);\n this.dispatchEvent(appRegisteredEvent(appInfo));\n }\n\n private handleUnregister(connection: ProtocolConnection, request: Request): void {\n this.removeApp(connection);\n this.acknowledge(connection, request);\n }\n\n private acknowledge(connection: ProtocolConnection, request: Request): void {\n const response: Response = {\n id: request.id,\n result: { success: true },\n };\n\n this.connections.send(connection.id, response);\n }\n\n private sendError(connection: ProtocolConnection, request: Request, error: ProtocolError): void {\n this.connections.send(connection.id, {\n id: request.id,\n error: error.toErrorObject(),\n });\n }\n\n private removeApp(connection: ProtocolConnection): void {\n const applicationId = this.connectionToApp.get(connection.id);\n this.connectionToApp.delete(connection.id);\n\n if (applicationId === undefined) {\n return;\n }\n\n if (this.apps.get(applicationId)?.connection !== connection) {\n return;\n }\n\n this.apps.delete(applicationId);\n this.dispatchEvent(appUnregisteredEvent(applicationId));\n }\n\n getApps(): AppInfo[] {\n return this.apps.values().map((app) => app.info).toArray();\n }\n\n hasConnectedApps(): boolean {\n return this.apps.size > 0;\n }\n\n getDefaultApp(): RegisteredApp | undefined {\n const first = this.apps.values().next();\n\n return first.done ? undefined : first.value;\n }\n\n getProjectRoot(): string | undefined {\n return this.getDefaultApp()?.info.projectRoot;\n }\n\n waitForApp(timeout: number = AppRouter.defaultWaitTimeout): Promise<AppInfo> {\n const defaultApp = this.getDefaultApp();\n\n if (defaultApp) {\n return Promise.resolve(defaultApp.info);\n }\n\n return new Promise((resolve, reject) => {\n const timeoutId = setTimeout(() => {\n this.removeEventListener(\"appRegistered\", onRegister);\n\n reject(\n new Error(\n `Timeout waiting for app registration after ${String(timeout)}ms. ` +\n \"Make sure your GTKX app is running with 'gtkx dev'.\",\n ),\n );\n }, timeout);\n\n const onRegister = (event: Event): void => {\n clearTimeout(timeoutId);\n this.removeEventListener(\"appRegistered\", onRegister);\n resolve((event as AppRegisteredEvent).detail);\n };\n\n this.addEventListener(\"appRegistered\", onRegister);\n });\n }\n\n async sendToApp<T>(applicationId: string | undefined, method: string, params?: unknown): Promise<T> {\n const app = this.resolveTargetApp(applicationId);\n\n try {\n return await app.connection.send<T>(method, params, this.requestTimeout);\n } catch (error) {\n if (error instanceof ConnectionClosedError) {\n this.removeApp(app.connection);\n throw connectionWriteFailedError(app.info.applicationId);\n }\n\n throw error;\n }\n }\n}\n\nexport { AppRouter, appRegisteredEvent, appUnregisteredEvent, type AppRegisteredEvent, type AppUnregisteredEvent };\n"]}
@@ -1,12 +1,12 @@
1
- import EventEmitter from "node:events";
2
1
  import type { Socket } from "node:net";
3
2
  import type { Message } from "./protocol/schemas.js";
4
- import { type AppConnectionEvents, type AppConnections, ProtocolConnection } from "./transport.js";
5
- export declare class ConnectionRegistry extends EventEmitter<AppConnectionEvents> implements AppConnections {
3
+ import { type AppConnections, ProtocolConnection } from "./transport.js";
4
+ declare class ConnectionRegistry extends EventTarget implements AppConnections {
6
5
  private connections;
7
6
  private sockets;
8
7
  register(socket: Socket): ProtocolConnection;
9
8
  send(connectionId: string, message: Message): void;
10
9
  dispose(reason: string): void;
11
10
  }
11
+ export { ConnectionRegistry };
12
12
  //# sourceMappingURL=connection-registry.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"connection-registry.d.ts","sourceRoot":"","sources":["../src/connection-registry.ts"],"names":[],"mappings":"AAAA,OAAO,YAAY,MAAM,aAAa,CAAC;AACvC,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AACvC,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AACrD,OAAO,EAAE,KAAK,mBAAmB,EAAE,KAAK,cAAc,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAEnG,qBAAa,kBAAmB,SAAQ,YAAY,CAAC,mBAAmB,CAAE,YAAW,cAAc;IAC/F,OAAO,CAAC,WAAW,CAA8C;IACjE,OAAO,CAAC,OAAO,CAAkC;IAEjD,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,kBAAkB,CAgB3C;IAED,IAAI,CAAC,YAAY,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,IAAI,CAIjD;IAED,OAAO,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAO5B;CACJ"}
1
+ {"version":3,"file":"connection-registry.d.ts","sourceRoot":"","sources":["../src/connection-registry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AACvC,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AACrD,OAAO,EACH,KAAK,cAAc,EAInB,kBAAkB,EACrB,MAAM,gBAAgB,CAAC;AAExB,cAAM,kBAAmB,SAAQ,WAAY,YAAW,cAAc;IAClE,OAAO,CAAC,WAAW,CAA8C;IACjE,OAAO,CAAC,OAAO,CAAkC;IAEjD,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,kBAAkB;IAqB5C,IAAI,CAAC,YAAY,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,IAAI;IAUlD,OAAO,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;CAShC;AAED,OAAO,EAAE,kBAAkB,EAAE,CAAC"}
@@ -1,6 +1,5 @@
1
- import EventEmitter from "node:events";
2
- import { ProtocolConnection } from "./transport.js";
3
- export class ConnectionRegistry extends EventEmitter {
1
+ import { connectionDisconnectionEvent, connectionErrorEvent, connectionRequestEvent, ProtocolConnection, } from "./transport.js";
2
+ class ConnectionRegistry extends EventTarget {
4
3
  connections = new Map();
5
4
  sockets = new Map();
6
5
  register(socket) {
@@ -8,13 +7,13 @@ export class ConnectionRegistry extends EventEmitter {
8
7
  onClose: () => {
9
8
  this.connections.delete(connection.id);
10
9
  this.sockets.delete(connection.id);
11
- this.emit("disconnection", connection);
10
+ this.dispatchEvent(connectionDisconnectionEvent(connection));
12
11
  },
13
- onError: (error) => this.emit("error", error),
12
+ onError: (error) => this.dispatchEvent(connectionErrorEvent(error)),
14
13
  });
15
14
  this.connections.set(connection.id, connection);
16
15
  this.sockets.set(connection.id, socket);
17
- connection.on("request", (request) => this.emit("request", connection, request));
16
+ connection.on("request", (request) => this.dispatchEvent(connectionRequestEvent(connection, request)));
18
17
  connection.on("invalid", ({ id: badId, error }) => {
19
18
  connection.write({ id: badId, error: error.toErrorObject() });
20
19
  });
@@ -22,8 +21,9 @@ export class ConnectionRegistry extends EventEmitter {
22
21
  }
23
22
  send(connectionId, message) {
24
23
  const connection = this.connections.get(connectionId);
25
- if (!connection)
24
+ if (!connection) {
26
25
  return;
26
+ }
27
27
  connection.write(message);
28
28
  }
29
29
  dispose(reason) {
@@ -35,4 +35,5 @@ export class ConnectionRegistry extends EventEmitter {
35
35
  }
36
36
  }
37
37
  }
38
+ export { ConnectionRegistry };
38
39
  //# sourceMappingURL=connection-registry.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"connection-registry.js","sourceRoot":"","sources":["../src/connection-registry.ts"],"names":[],"mappings":"AAAA,OAAO,YAAY,MAAM,aAAa,CAAC;AAGvC,OAAO,EAAiD,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAEnG,MAAM,OAAO,kBAAmB,SAAQ,YAAiC;IAC7D,WAAW,GAAoC,IAAI,GAAG,EAAE,CAAC;IACzD,OAAO,GAAwB,IAAI,GAAG,EAAE,CAAC;IAEjD,QAAQ,CAAC,MAAc;QACnB,MAAM,UAAU,GAAG,kBAAkB,CAAC,UAAU,CAAC,MAAM,EAAE;YACrD,OAAO,EAAE,GAAG,EAAE;gBACV,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;gBACvC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;gBACnC,IAAI,CAAC,IAAI,CAAC,eAAe,EAAE,UAAU,CAAC,CAAC;YAC3C,CAAC;YACD,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,KAAK,CAAC;SAChD,CAAC,CAAC;QACH,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,EAAE,UAAU,CAAC,CAAC;QAChD,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC;QACxC,UAAU,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,UAAU,EAAE,OAAO,CAAC,CAAC,CAAC;QACjF,UAAU,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,EAAE;YAC9C,UAAU,CAAC,KAAK,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC,aAAa,EAAE,EAAE,CAAC,CAAC;QAClE,CAAC,CAAC,CAAC;QACH,OAAO,UAAU,CAAC;IACtB,CAAC;IAED,IAAI,CAAC,YAAoB,EAAE,OAAgB;QACvC,MAAM,UAAU,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;QACtD,IAAI,CAAC,UAAU;YAAE,OAAO;QACxB,UAAU,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IAC9B,CAAC;IAED,OAAO,CAAC,MAAc;QAClB,KAAK,MAAM,UAAU,IAAI,IAAI,CAAC,WAAW,CAAC,MAAM,EAAE,EAAE,CAAC;YACjD,UAAU,CAAC,aAAa,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC;QAChD,CAAC;QACD,KAAK,MAAM,MAAM,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC;YACzC,MAAM,CAAC,OAAO,EAAE,CAAC;QACrB,CAAC;IACL,CAAC;CACJ","sourcesContent":["import EventEmitter from \"node:events\";\nimport type { Socket } from \"node:net\";\nimport type { Message } from \"./protocol/schemas.js\";\nimport { type AppConnectionEvents, type AppConnections, ProtocolConnection } from \"./transport.js\";\n\nexport class ConnectionRegistry extends EventEmitter<AppConnectionEvents> implements AppConnections {\n private connections: Map<string, ProtocolConnection> = new Map();\n private sockets: Map<string, Socket> = new Map();\n\n register(socket: Socket): ProtocolConnection {\n const connection = ProtocolConnection.fromSocket(socket, {\n onClose: () => {\n this.connections.delete(connection.id);\n this.sockets.delete(connection.id);\n this.emit(\"disconnection\", connection);\n },\n onError: (error) => this.emit(\"error\", error),\n });\n this.connections.set(connection.id, connection);\n this.sockets.set(connection.id, socket);\n connection.on(\"request\", (request) => this.emit(\"request\", connection, request));\n connection.on(\"invalid\", ({ id: badId, error }) => {\n connection.write({ id: badId, error: error.toErrorObject() });\n });\n return connection;\n }\n\n send(connectionId: string, message: Message): void {\n const connection = this.connections.get(connectionId);\n if (!connection) return;\n connection.write(message);\n }\n\n dispose(reason: string): void {\n for (const connection of this.connections.values()) {\n connection.rejectPending(new Error(reason));\n }\n for (const socket of this.sockets.values()) {\n socket.destroy();\n }\n }\n}\n"]}
1
+ {"version":3,"file":"connection-registry.js","sourceRoot":"","sources":["../src/connection-registry.ts"],"names":[],"mappings":"AAEA,OAAO,EAEH,4BAA4B,EAC5B,oBAAoB,EACpB,sBAAsB,EACtB,kBAAkB,GACrB,MAAM,gBAAgB,CAAC;AAExB,MAAM,kBAAmB,SAAQ,WAAW;IAChC,WAAW,GAAoC,IAAI,GAAG,EAAE,CAAC;IACzD,OAAO,GAAwB,IAAI,GAAG,EAAE,CAAC;IAEjD,QAAQ,CAAC,MAAc;QACnB,MAAM,UAAU,GAAG,kBAAkB,CAAC,UAAU,CAAC,MAAM,EAAE;YACrD,OAAO,EAAE,GAAG,EAAE;gBACV,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;gBACvC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;gBACnC,IAAI,CAAC,aAAa,CAAC,4BAA4B,CAAC,UAAU,CAAC,CAAC,CAAC;YACjE,CAAC;YACD,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,IAAI,CAAC,aAAa,CAAC,oBAAoB,CAAC,KAAK,CAAC,CAAC;SACtE,CAAC,CAAC;QAEH,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,EAAE,UAAU,CAAC,CAAC;QAChD,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC;QACxC,UAAU,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC,IAAI,CAAC,aAAa,CAAC,sBAAsB,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC;QAEvG,UAAU,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,EAAE;YAC9C,UAAU,CAAC,KAAK,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC,aAAa,EAAE,EAAE,CAAC,CAAC;QAClE,CAAC,CAAC,CAAC;QAEH,OAAO,UAAU,CAAC;IACtB,CAAC;IAED,IAAI,CAAC,YAAoB,EAAE,OAAgB;QACvC,MAAM,UAAU,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;QAEtD,IAAI,CAAC,UAAU,EAAE,CAAC;YACd,OAAO;QACX,CAAC;QAED,UAAU,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IAC9B,CAAC;IAED,OAAO,CAAC,MAAc;QAClB,KAAK,MAAM,UAAU,IAAI,IAAI,CAAC,WAAW,CAAC,MAAM,EAAE,EAAE,CAAC;YACjD,UAAU,CAAC,aAAa,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC;QAChD,CAAC;QAED,KAAK,MAAM,MAAM,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC;YACzC,MAAM,CAAC,OAAO,EAAE,CAAC;QACrB,CAAC;IACL,CAAC;CACJ;AAED,OAAO,EAAE,kBAAkB,EAAE,CAAC","sourcesContent":["import type { Socket } from \"node:net\";\nimport type { Message } from \"./protocol/schemas.js\";\nimport {\n type AppConnections,\n connectionDisconnectionEvent,\n connectionErrorEvent,\n connectionRequestEvent,\n ProtocolConnection,\n} from \"./transport.js\";\n\nclass ConnectionRegistry extends EventTarget implements AppConnections {\n private connections: Map<string, ProtocolConnection> = new Map();\n private sockets: Map<string, Socket> = new Map();\n\n register(socket: Socket): ProtocolConnection {\n const connection = ProtocolConnection.fromSocket(socket, {\n onClose: () => {\n this.connections.delete(connection.id);\n this.sockets.delete(connection.id);\n this.dispatchEvent(connectionDisconnectionEvent(connection));\n },\n onError: (error) => this.dispatchEvent(connectionErrorEvent(error)),\n });\n\n this.connections.set(connection.id, connection);\n this.sockets.set(connection.id, socket);\n connection.on(\"request\", (request) => this.dispatchEvent(connectionRequestEvent(connection, request)));\n\n connection.on(\"invalid\", ({ id: badId, error }) => {\n connection.write({ id: badId, error: error.toErrorObject() });\n });\n\n return connection;\n }\n\n send(connectionId: string, message: Message): void {\n const connection = this.connections.get(connectionId);\n\n if (!connection) {\n return;\n }\n\n connection.write(message);\n }\n\n dispose(reason: string): void {\n for (const connection of this.connections.values()) {\n connection.rejectPending(new Error(reason));\n }\n\n for (const socket of this.sockets.values()) {\n socket.destroy();\n }\n }\n}\n\nexport { ConnectionRegistry };\n"]}
@@ -1,4 +1,5 @@
1
- export declare const ErrorCode: {
1
+ type ErrorCode = (typeof ErrorCode)[keyof typeof ErrorCode];
2
+ declare const ErrorCode: {
2
3
  readonly INTERNAL_ERROR: 1000;
3
4
  readonly NO_APP_CONNECTED: 1001;
4
5
  readonly APP_NOT_FOUND: 1002;
@@ -8,9 +9,15 @@ export declare const ErrorCode: {
8
9
  readonly INVALID_REQUEST: 1006;
9
10
  readonly METHOD_NOT_FOUND: 1007;
10
11
  };
11
- export type ErrorCode = (typeof ErrorCode)[keyof typeof ErrorCode];
12
- export declare function isErrorCode(code: number): code is ErrorCode;
13
- export declare class ProtocolError extends Error {
12
+ declare function isErrorCode(code: number): code is ErrorCode;
13
+ declare function noAppConnectedError(): ProtocolError;
14
+ declare function appNotFoundError(applicationId: string): ProtocolError;
15
+ declare function connectionWriteFailedError(applicationId: string): ProtocolError;
16
+ declare function widgetNotFoundError(widgetId: string): ProtocolError;
17
+ declare function requestTimeoutError(timeout: number): ProtocolError;
18
+ declare function invalidRequestError(reason: string): ProtocolError;
19
+ declare function methodNotFoundError(method: string): ProtocolError;
20
+ declare class ProtocolError extends Error {
14
21
  code: ErrorCode;
15
22
  data?: unknown;
16
23
  constructor(code: ErrorCode, message: string, data?: unknown);
@@ -20,11 +27,5 @@ export declare class ProtocolError extends Error {
20
27
  data?: unknown;
21
28
  };
22
29
  }
23
- export declare function noAppConnectedError(): ProtocolError;
24
- export declare function appNotFoundError(applicationId: string): ProtocolError;
25
- export declare function connectionWriteFailedError(applicationId: string): ProtocolError;
26
- export declare function widgetNotFoundError(widgetId: string): ProtocolError;
27
- export declare function requestTimeoutError(timeout: number): ProtocolError;
28
- export declare function invalidRequestError(reason: string): ProtocolError;
29
- export declare function methodNotFoundError(method: string): ProtocolError;
30
+ export { ErrorCode, isErrorCode, noAppConnectedError, appNotFoundError, connectionWriteFailedError, widgetNotFoundError, requestTimeoutError, invalidRequestError, methodNotFoundError, ProtocolError, };
30
31
  //# sourceMappingURL=errors.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/protocol/errors.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,SAAS;aAClB,cAAc,EAAE,IAAI;aACpB,gBAAgB,EAAE,IAAI;aACtB,aAAa,EAAE,IAAI;aACnB,gBAAgB,EAAE,IAAI;aACtB,uBAAuB,EAAE,IAAI;aAC7B,eAAe,EAAE,IAAI;aACrB,eAAe,EAAE,IAAI;aACrB,gBAAgB,EAAE,IAAI;CAChB,CAAC;AAEX,MAAM,MAAM,SAAS,GAAG,CAAC,OAAO,SAAS,CAAC,CAAC,MAAM,OAAO,SAAS,CAAC,CAAC;AAEnE,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,IAAI,SAAS,CAE3D;AAED,qBAAa,aAAc,SAAQ,KAAK;IACpC,IAAI,EAAE,SAAS,CAAC;IAChB,IAAI,CAAC,EAAE,OAAO,CAAC;IAEf,YAAY,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,EAK3D;IAED,aAAa,IAAI;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,OAAO,CAAA;KAAE,CAMjE;CACJ;AAED,wBAAgB,mBAAmB,IAAI,aAAa,CAMnD;AAED,wBAAgB,gBAAgB,CAAC,aAAa,EAAE,MAAM,GAAG,aAAa,CAErE;AAED,wBAAgB,0BAA0B,CAAC,aAAa,EAAE,MAAM,GAAG,aAAa,CAM/E;AAED,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,aAAa,CAEnE;AAED,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,GAAG,aAAa,CAElE;AAED,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,GAAG,aAAa,CAEjE;AAED,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,GAAG,aAAa,CAEjE"}
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/protocol/errors.ts"],"names":[],"mappings":"AAAA,KAAK,SAAS,GAAG,CAAC,OAAO,SAAS,CAAC,CAAC,MAAM,OAAO,SAAS,CAAC,CAAC;AAE5D,QAAA,MAAM,SAAS;;;;;;;;;CASL,CAAC;AAEX,iBAAS,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,IAAI,SAAS,CAEpD;AAED,iBAAS,mBAAmB,IAAI,aAAa,CAM5C;AAED,iBAAS,gBAAgB,CAAC,aAAa,EAAE,MAAM,GAAG,aAAa,CAE9D;AAED,iBAAS,0BAA0B,CAAC,aAAa,EAAE,MAAM,GAAG,aAAa,CAMxE;AAED,iBAAS,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,aAAa,CAE5D;AAED,iBAAS,mBAAmB,CAAC,OAAO,EAAE,MAAM,GAAG,aAAa,CAE3D;AAED,iBAAS,mBAAmB,CAAC,MAAM,EAAE,MAAM,GAAG,aAAa,CAE1D;AAED,iBAAS,mBAAmB,CAAC,MAAM,EAAE,MAAM,GAAG,aAAa,CAE1D;AAED,cAAM,aAAc,SAAQ,KAAK;IAC7B,IAAI,EAAE,SAAS,CAAC;IAChB,IAAI,CAAC,EAAE,OAAO,CAAC;gBAEH,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO;IAO5D,aAAa,IAAI;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,OAAO,CAAA;KAAE;CAOrE;AAED,OAAO,EACH,SAAS,EACT,WAAW,EACX,mBAAmB,EACnB,gBAAgB,EAChB,0BAA0B,EAC1B,mBAAmB,EACnB,mBAAmB,EACnB,mBAAmB,EACnB,mBAAmB,EACnB,aAAa,GAChB,CAAC"}
@@ -1,4 +1,4 @@
1
- export const ErrorCode = {
1
+ const ErrorCode = {
2
2
  INTERNAL_ERROR: 1000,
3
3
  NO_APP_CONNECTED: 1001,
4
4
  APP_NOT_FOUND: 1002,
@@ -8,10 +8,31 @@ export const ErrorCode = {
8
8
  INVALID_REQUEST: 1006,
9
9
  METHOD_NOT_FOUND: 1007,
10
10
  };
11
- export function isErrorCode(code) {
11
+ function isErrorCode(code) {
12
12
  return Object.values(ErrorCode).includes(code);
13
13
  }
14
- export class ProtocolError extends Error {
14
+ function noAppConnectedError() {
15
+ return new ProtocolError(ErrorCode.NO_APP_CONNECTED, "No GTKX application connected: start an app with 'gtkx dev' to connect", { hint: "Run 'gtkx dev' in your project directory" });
16
+ }
17
+ function appNotFoundError(applicationId) {
18
+ return new ProtocolError(ErrorCode.APP_NOT_FOUND, `Application '${applicationId}' not found`, { applicationId });
19
+ }
20
+ function connectionWriteFailedError(applicationId) {
21
+ return new ProtocolError(ErrorCode.CONNECTION_WRITE_FAILED, `Connection to application '${applicationId}' is no longer writable`, { applicationId });
22
+ }
23
+ function widgetNotFoundError(widgetId) {
24
+ return new ProtocolError(ErrorCode.WIDGET_NOT_FOUND, `Widget '${widgetId}' not found`, { widgetId });
25
+ }
26
+ function requestTimeoutError(timeout) {
27
+ return new ProtocolError(ErrorCode.REQUEST_TIMEOUT, `Request timed out after ${String(timeout)}ms`, { timeout });
28
+ }
29
+ function invalidRequestError(reason) {
30
+ return new ProtocolError(ErrorCode.INVALID_REQUEST, `Invalid request: ${reason}`, { reason });
31
+ }
32
+ function methodNotFoundError(method) {
33
+ return new ProtocolError(ErrorCode.METHOD_NOT_FOUND, `Method '${method}' not found`, { method });
34
+ }
35
+ class ProtocolError extends Error {
15
36
  code;
16
37
  data;
17
38
  constructor(code, message, data) {
@@ -28,25 +49,5 @@ export class ProtocolError extends Error {
28
49
  };
29
50
  }
30
51
  }
31
- export function noAppConnectedError() {
32
- return new ProtocolError(ErrorCode.NO_APP_CONNECTED, "No GTKX application connected: start an app with 'gtkx dev' to connect", { hint: "Run 'gtkx dev' in your project directory" });
33
- }
34
- export function appNotFoundError(applicationId) {
35
- return new ProtocolError(ErrorCode.APP_NOT_FOUND, `Application '${applicationId}' not found`, { applicationId });
36
- }
37
- export function connectionWriteFailedError(applicationId) {
38
- return new ProtocolError(ErrorCode.CONNECTION_WRITE_FAILED, `Connection to application '${applicationId}' is no longer writable`, { applicationId });
39
- }
40
- export function widgetNotFoundError(widgetId) {
41
- return new ProtocolError(ErrorCode.WIDGET_NOT_FOUND, `Widget '${widgetId}' not found`, { widgetId });
42
- }
43
- export function requestTimeoutError(timeout) {
44
- return new ProtocolError(ErrorCode.REQUEST_TIMEOUT, `Request timed out after ${timeout}ms`, { timeout });
45
- }
46
- export function invalidRequestError(reason) {
47
- return new ProtocolError(ErrorCode.INVALID_REQUEST, `Invalid request: ${reason}`, { reason });
48
- }
49
- export function methodNotFoundError(method) {
50
- return new ProtocolError(ErrorCode.METHOD_NOT_FOUND, `Method '${method}' not found`, { method });
51
- }
52
+ export { ErrorCode, isErrorCode, noAppConnectedError, appNotFoundError, connectionWriteFailedError, widgetNotFoundError, requestTimeoutError, invalidRequestError, methodNotFoundError, ProtocolError, };
52
53
  //# sourceMappingURL=errors.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/protocol/errors.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,SAAS,GAAG;IACrB,cAAc,EAAE,IAAI;IACpB,gBAAgB,EAAE,IAAI;IACtB,aAAa,EAAE,IAAI;IACnB,gBAAgB,EAAE,IAAI;IACtB,uBAAuB,EAAE,IAAI;IAC7B,eAAe,EAAE,IAAI;IACrB,eAAe,EAAE,IAAI;IACrB,gBAAgB,EAAE,IAAI;CAChB,CAAC;AAIX,MAAM,UAAU,WAAW,CAAC,IAAY;IACpC,OAAQ,MAAM,CAAC,MAAM,CAAC,SAAS,CAAc,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;AACjE,CAAC;AAED,MAAM,OAAO,aAAc,SAAQ,KAAK;IACpC,IAAI,CAAY;IAChB,IAAI,CAAW;IAEf,YAAY,IAAe,EAAE,OAAe,EAAE,IAAc;QACxD,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,IAAI,GAAG,eAAe,CAAC;IAChC,CAAC;IAED,aAAa;QACT,OAAO;YACH,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,OAAO,EAAE,IAAI,CAAC,OAAO;YACrB,GAAG,CAAC,IAAI,CAAC,IAAI,KAAK,SAAS,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC;SACtD,CAAC;IACN,CAAC;CACJ;AAED,MAAM,UAAU,mBAAmB;IAC/B,OAAO,IAAI,aAAa,CACpB,SAAS,CAAC,gBAAgB,EAC1B,wEAAwE,EACxE,EAAE,IAAI,EAAE,0CAA0C,EAAE,CACvD,CAAC;AACN,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,aAAqB;IAClD,OAAO,IAAI,aAAa,CAAC,SAAS,CAAC,aAAa,EAAE,gBAAgB,aAAa,aAAa,EAAE,EAAE,aAAa,EAAE,CAAC,CAAC;AACrH,CAAC;AAED,MAAM,UAAU,0BAA0B,CAAC,aAAqB;IAC5D,OAAO,IAAI,aAAa,CACpB,SAAS,CAAC,uBAAuB,EACjC,8BAA8B,aAAa,yBAAyB,EACpE,EAAE,aAAa,EAAE,CACpB,CAAC;AACN,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,QAAgB;IAChD,OAAO,IAAI,aAAa,CAAC,SAAS,CAAC,gBAAgB,EAAE,WAAW,QAAQ,aAAa,EAAE,EAAE,QAAQ,EAAE,CAAC,CAAC;AACzG,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,OAAe;IAC/C,OAAO,IAAI,aAAa,CAAC,SAAS,CAAC,eAAe,EAAE,2BAA2B,OAAO,IAAI,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC;AAC7G,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,MAAc;IAC9C,OAAO,IAAI,aAAa,CAAC,SAAS,CAAC,eAAe,EAAE,oBAAoB,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC;AAClG,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,MAAc;IAC9C,OAAO,IAAI,aAAa,CAAC,SAAS,CAAC,gBAAgB,EAAE,WAAW,MAAM,aAAa,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC;AACrG,CAAC","sourcesContent":["export const ErrorCode = {\n INTERNAL_ERROR: 1000,\n NO_APP_CONNECTED: 1001,\n APP_NOT_FOUND: 1002,\n WIDGET_NOT_FOUND: 1003,\n CONNECTION_WRITE_FAILED: 1004,\n REQUEST_TIMEOUT: 1005,\n INVALID_REQUEST: 1006,\n METHOD_NOT_FOUND: 1007,\n} as const;\n\nexport type ErrorCode = (typeof ErrorCode)[keyof typeof ErrorCode];\n\nexport function isErrorCode(code: number): code is ErrorCode {\n return (Object.values(ErrorCode) as number[]).includes(code);\n}\n\nexport class ProtocolError extends Error {\n code: ErrorCode;\n data?: unknown;\n\n constructor(code: ErrorCode, message: string, data?: unknown) {\n super(message);\n this.code = code;\n this.data = data;\n this.name = \"ProtocolError\";\n }\n\n toErrorObject(): { code: number; message: string; data?: unknown } {\n return {\n code: this.code,\n message: this.message,\n ...(this.data !== undefined && { data: this.data }),\n };\n }\n}\n\nexport function noAppConnectedError(): ProtocolError {\n return new ProtocolError(\n ErrorCode.NO_APP_CONNECTED,\n \"No GTKX application connected: start an app with 'gtkx dev' to connect\",\n { hint: \"Run 'gtkx dev' in your project directory\" },\n );\n}\n\nexport function appNotFoundError(applicationId: string): ProtocolError {\n return new ProtocolError(ErrorCode.APP_NOT_FOUND, `Application '${applicationId}' not found`, { applicationId });\n}\n\nexport function connectionWriteFailedError(applicationId: string): ProtocolError {\n return new ProtocolError(\n ErrorCode.CONNECTION_WRITE_FAILED,\n `Connection to application '${applicationId}' is no longer writable`,\n { applicationId },\n );\n}\n\nexport function widgetNotFoundError(widgetId: string): ProtocolError {\n return new ProtocolError(ErrorCode.WIDGET_NOT_FOUND, `Widget '${widgetId}' not found`, { widgetId });\n}\n\nexport function requestTimeoutError(timeout: number): ProtocolError {\n return new ProtocolError(ErrorCode.REQUEST_TIMEOUT, `Request timed out after ${timeout}ms`, { timeout });\n}\n\nexport function invalidRequestError(reason: string): ProtocolError {\n return new ProtocolError(ErrorCode.INVALID_REQUEST, `Invalid request: ${reason}`, { reason });\n}\n\nexport function methodNotFoundError(method: string): ProtocolError {\n return new ProtocolError(ErrorCode.METHOD_NOT_FOUND, `Method '${method}' not found`, { method });\n}\n"]}
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/protocol/errors.ts"],"names":[],"mappings":"AAEA,MAAM,SAAS,GAAG;IACd,cAAc,EAAE,IAAI;IACpB,gBAAgB,EAAE,IAAI;IACtB,aAAa,EAAE,IAAI;IACnB,gBAAgB,EAAE,IAAI;IACtB,uBAAuB,EAAE,IAAI;IAC7B,eAAe,EAAE,IAAI;IACrB,eAAe,EAAE,IAAI;IACrB,gBAAgB,EAAE,IAAI;CAChB,CAAC;AAEX,SAAS,WAAW,CAAC,IAAY;IAC7B,OAAQ,MAAM,CAAC,MAAM,CAAC,SAAS,CAAc,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;AACjE,CAAC;AAED,SAAS,mBAAmB;IACxB,OAAO,IAAI,aAAa,CACpB,SAAS,CAAC,gBAAgB,EAC1B,wEAAwE,EACxE,EAAE,IAAI,EAAE,0CAA0C,EAAE,CACvD,CAAC;AACN,CAAC;AAED,SAAS,gBAAgB,CAAC,aAAqB;IAC3C,OAAO,IAAI,aAAa,CAAC,SAAS,CAAC,aAAa,EAAE,gBAAgB,aAAa,aAAa,EAAE,EAAE,aAAa,EAAE,CAAC,CAAC;AACrH,CAAC;AAED,SAAS,0BAA0B,CAAC,aAAqB;IACrD,OAAO,IAAI,aAAa,CACpB,SAAS,CAAC,uBAAuB,EACjC,8BAA8B,aAAa,yBAAyB,EACpE,EAAE,aAAa,EAAE,CACpB,CAAC;AACN,CAAC;AAED,SAAS,mBAAmB,CAAC,QAAgB;IACzC,OAAO,IAAI,aAAa,CAAC,SAAS,CAAC,gBAAgB,EAAE,WAAW,QAAQ,aAAa,EAAE,EAAE,QAAQ,EAAE,CAAC,CAAC;AACzG,CAAC;AAED,SAAS,mBAAmB,CAAC,OAAe;IACxC,OAAO,IAAI,aAAa,CAAC,SAAS,CAAC,eAAe,EAAE,2BAA2B,MAAM,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC;AACrH,CAAC;AAED,SAAS,mBAAmB,CAAC,MAAc;IACvC,OAAO,IAAI,aAAa,CAAC,SAAS,CAAC,eAAe,EAAE,oBAAoB,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC;AAClG,CAAC;AAED,SAAS,mBAAmB,CAAC,MAAc;IACvC,OAAO,IAAI,aAAa,CAAC,SAAS,CAAC,gBAAgB,EAAE,WAAW,MAAM,aAAa,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC;AACrG,CAAC;AAED,MAAM,aAAc,SAAQ,KAAK;IAC7B,IAAI,CAAY;IAChB,IAAI,CAAW;IAEf,YAAY,IAAe,EAAE,OAAe,EAAE,IAAc;QACxD,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,IAAI,GAAG,eAAe,CAAC;IAChC,CAAC;IAED,aAAa;QACT,OAAO;YACH,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,OAAO,EAAE,IAAI,CAAC,OAAO;YACrB,GAAG,CAAC,IAAI,CAAC,IAAI,KAAK,SAAS,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC;SACtD,CAAC;IACN,CAAC;CACJ;AAED,OAAO,EACH,SAAS,EACT,WAAW,EACX,mBAAmB,EACnB,gBAAgB,EAChB,0BAA0B,EAC1B,mBAAmB,EACnB,mBAAmB,EACnB,mBAAmB,EACnB,mBAAmB,EACnB,aAAa,GAChB,CAAC","sourcesContent":["type ErrorCode = (typeof ErrorCode)[keyof typeof ErrorCode];\n\nconst ErrorCode = {\n INTERNAL_ERROR: 1000,\n NO_APP_CONNECTED: 1001,\n APP_NOT_FOUND: 1002,\n WIDGET_NOT_FOUND: 1003,\n CONNECTION_WRITE_FAILED: 1004,\n REQUEST_TIMEOUT: 1005,\n INVALID_REQUEST: 1006,\n METHOD_NOT_FOUND: 1007,\n} as const;\n\nfunction isErrorCode(code: number): code is ErrorCode {\n return (Object.values(ErrorCode) as number[]).includes(code);\n}\n\nfunction noAppConnectedError(): ProtocolError {\n return new ProtocolError(\n ErrorCode.NO_APP_CONNECTED,\n \"No GTKX application connected: start an app with 'gtkx dev' to connect\",\n { hint: \"Run 'gtkx dev' in your project directory\" },\n );\n}\n\nfunction appNotFoundError(applicationId: string): ProtocolError {\n return new ProtocolError(ErrorCode.APP_NOT_FOUND, `Application '${applicationId}' not found`, { applicationId });\n}\n\nfunction connectionWriteFailedError(applicationId: string): ProtocolError {\n return new ProtocolError(\n ErrorCode.CONNECTION_WRITE_FAILED,\n `Connection to application '${applicationId}' is no longer writable`,\n { applicationId },\n );\n}\n\nfunction widgetNotFoundError(widgetId: string): ProtocolError {\n return new ProtocolError(ErrorCode.WIDGET_NOT_FOUND, `Widget '${widgetId}' not found`, { widgetId });\n}\n\nfunction requestTimeoutError(timeout: number): ProtocolError {\n return new ProtocolError(ErrorCode.REQUEST_TIMEOUT, `Request timed out after ${String(timeout)}ms`, { timeout });\n}\n\nfunction invalidRequestError(reason: string): ProtocolError {\n return new ProtocolError(ErrorCode.INVALID_REQUEST, `Invalid request: ${reason}`, { reason });\n}\n\nfunction methodNotFoundError(method: string): ProtocolError {\n return new ProtocolError(ErrorCode.METHOD_NOT_FOUND, `Method '${method}' not found`, { method });\n}\n\nclass ProtocolError extends Error {\n code: ErrorCode;\n data?: unknown;\n\n constructor(code: ErrorCode, message: string, data?: unknown) {\n super(message);\n this.code = code;\n this.data = data;\n this.name = \"ProtocolError\";\n }\n\n toErrorObject(): { code: number; message: string; data?: unknown } {\n return {\n code: this.code,\n message: this.message,\n ...(this.data !== undefined && { data: this.data }),\n };\n }\n}\n\nexport {\n ErrorCode,\n isErrorCode,\n noAppConnectedError,\n appNotFoundError,\n connectionWriteFailedError,\n widgetNotFoundError,\n requestTimeoutError,\n invalidRequestError,\n methodNotFoundError,\n ProtocolError,\n};\n"]}