@hydranium/glsp-client-theia 1.0.0-next.13 → 1.0.0-next.135

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 (42) hide show
  1. package/README.md +23 -11
  2. package/lib/browser/diagram-loader.d.ts +16 -4
  3. package/lib/browser/diagram-loader.d.ts.map +1 -1
  4. package/lib/browser/diagram-loader.js +18 -5
  5. package/lib/browser/diagram-loader.js.map +1 -1
  6. package/lib/browser/diagram-widget.d.ts +13 -1
  7. package/lib/browser/diagram-widget.d.ts.map +1 -1
  8. package/lib/browser/diagram-widget.js +19 -0
  9. package/lib/browser/diagram-widget.js.map +1 -1
  10. package/lib/browser/glsp-diagram-manager.d.ts +22 -0
  11. package/lib/browser/glsp-diagram-manager.d.ts.map +1 -1
  12. package/lib/browser/glsp-diagram-manager.js +26 -0
  13. package/lib/browser/glsp-diagram-manager.js.map +1 -1
  14. package/lib/browser/glsp-message-service.d.ts +8 -0
  15. package/lib/browser/glsp-message-service.d.ts.map +1 -1
  16. package/lib/browser/glsp-message-service.js +8 -0
  17. package/lib/browser/glsp-message-service.js.map +1 -1
  18. package/lib/browser/glsp-saveable.d.ts +66 -0
  19. package/lib/browser/glsp-saveable.d.ts.map +1 -0
  20. package/lib/browser/glsp-saveable.js +109 -0
  21. package/lib/browser/glsp-saveable.js.map +1 -0
  22. package/lib/browser/hidden-bounds-updater.d.ts +2 -4
  23. package/lib/browser/hidden-bounds-updater.d.ts.map +1 -1
  24. package/lib/browser/hidden-bounds-updater.js +7 -3
  25. package/lib/browser/hidden-bounds-updater.js.map +1 -1
  26. package/lib/browser/index.d.ts +2 -0
  27. package/lib/browser/index.d.ts.map +1 -1
  28. package/lib/browser/index.js +1 -0
  29. package/lib/browser/index.js.map +1 -1
  30. package/lib/node/glsp-server-connection-handler.d.ts +16 -10
  31. package/lib/node/glsp-server-connection-handler.d.ts.map +1 -1
  32. package/lib/node/glsp-server-connection-handler.js +9 -15
  33. package/lib/node/glsp-server-connection-handler.js.map +1 -1
  34. package/package.json +17 -13
  35. package/src/browser/diagram-loader.ts +18 -5
  36. package/src/browser/diagram-widget.ts +24 -3
  37. package/src/browser/glsp-diagram-manager.ts +29 -0
  38. package/src/browser/glsp-message-service.ts +8 -0
  39. package/src/browser/glsp-saveable.ts +110 -0
  40. package/src/browser/hidden-bounds-updater.ts +5 -6
  41. package/src/browser/index.ts +6 -0
  42. package/src/node/glsp-server-connection-handler.ts +17 -15
@@ -20,6 +20,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
20
20
  exports.HydraniumHiddenBoundsUpdater = void 0;
21
21
  const client_1 = require("@eclipse-glsp/client");
22
22
  const browser_1 = require("@hydranium/client-theia/lib/browser");
23
+ const common_1 = require("@hydranium/client-theia/lib/common");
23
24
  const protocol_1 = require("@hydranium/protocol");
24
25
  const inversify_1 = require("@theia/core/shared/inversify");
25
26
  /** How many scoped element ids the log line names before summarising the rest.
@@ -66,9 +67,7 @@ const SCOPE_ID_CAP = 3;
66
67
  */
67
68
  let HydraniumHiddenBoundsUpdater = class HydraniumHiddenBoundsUpdater extends client_1.GLSPHiddenBoundsUpdater {
68
69
  channel;
69
- /** Not injected: the browser container binds no {@link Clock}, and this only
70
- * measures — no logic is gated on time, so there is nothing to fake in
71
- * production. Overridden in tests for a deterministic elapsed value. */
70
+ /** The diagram container's {@link Clock}, or a `SystemClock`; it only measures. */
72
71
  clock = new protocol_1.SystemClock();
73
72
  /**
74
73
  * Scope description for the in-flight request, read from the `cause` in
@@ -201,6 +200,11 @@ __decorate([
201
200
  (0, inversify_1.inject)(browser_1.ChannelLogger),
202
201
  __metadata("design:type", browser_1.ChannelLogger)
203
202
  ], HydraniumHiddenBoundsUpdater.prototype, "channel", void 0);
203
+ __decorate([
204
+ (0, inversify_1.inject)(common_1.Clock),
205
+ (0, inversify_1.optional)(),
206
+ __metadata("design:type", Object)
207
+ ], HydraniumHiddenBoundsUpdater.prototype, "clock", void 0);
204
208
  exports.HydraniumHiddenBoundsUpdater = HydraniumHiddenBoundsUpdater = __decorate([
205
209
  (0, inversify_1.injectable)()
206
210
  ], HydraniumHiddenBoundsUpdater);
@@ -1 +1 @@
1
- {"version":3,"file":"hidden-bounds-updater.js","sourceRoot":"","sources":["../../src/browser/hidden-bounds-updater.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"hidden-bounds-updater.js","sourceRoot":"","sources":["../../src/browser/hidden-bounds-updater.ts"],"names":[],"mappings":"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"}
@@ -14,7 +14,9 @@ export * from './diagram-widget';
14
14
  export * from './glsp-client-theia-module';
15
15
  export * from './glsp-diagram-manager';
16
16
  export * from './glsp-message-service';
17
+ export * from './glsp-saveable';
17
18
  export * from './glsp-theia-frontend-module';
18
19
  export * from './hidden-bounds-updater';
19
20
  export * from './hydranium-glsp-diagram-configuration';
21
+ export type { GLSPDiagramLanguage } from '@eclipse-glsp/theia-integration/lib/common';
20
22
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/browser/index.ts"],"names":[],"mappings":"AAAA;;;;;;;kFAOkF;AAIlF,cAAc,qBAAqB,CAAC;AACpC,cAAc,uBAAuB,CAAC;AACtC,cAAc,kBAAkB,CAAC;AACjC,cAAc,+BAA+B,CAAC;AAC9C,cAAc,kBAAkB,CAAC;AACjC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,wBAAwB,CAAC;AACvC,cAAc,wBAAwB,CAAC;AACvC,cAAc,8BAA8B,CAAC;AAC7C,cAAc,yBAAyB,CAAC;AACxC,cAAc,wCAAwC,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/browser/index.ts"],"names":[],"mappings":"AAAA;;;;;;;kFAOkF;AAIlF,cAAc,qBAAqB,CAAC;AACpC,cAAc,uBAAuB,CAAC;AACtC,cAAc,kBAAkB,CAAC;AACjC,cAAc,+BAA+B,CAAC;AAC9C,cAAc,kBAAkB,CAAC;AACjC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,wBAAwB,CAAC;AACvC,cAAc,wBAAwB,CAAC;AACvC,cAAc,iBAAiB,CAAC;AAChC,cAAc,8BAA8B,CAAC;AAC7C,cAAc,yBAAyB,CAAC;AACxC,cAAc,wCAAwC,CAAC;AAKvD,YAAY,EAAE,mBAAmB,EAAE,MAAM,4CAA4C,CAAC"}
@@ -32,6 +32,7 @@ __exportStar(require("./diagram-widget"), exports);
32
32
  __exportStar(require("./glsp-client-theia-module"), exports);
33
33
  __exportStar(require("./glsp-diagram-manager"), exports);
34
34
  __exportStar(require("./glsp-message-service"), exports);
35
+ __exportStar(require("./glsp-saveable"), exports);
35
36
  __exportStar(require("./glsp-theia-frontend-module"), exports);
36
37
  __exportStar(require("./hidden-bounds-updater"), exports);
37
38
  __exportStar(require("./hydranium-glsp-diagram-configuration"), exports);
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/browser/index.ts"],"names":[],"mappings":";AAAA;;;;;;;kFAOkF;;;;;;;;;;;;;;;;AAElF,gEAAgE;AAChE,mFAAmF;AACnF,sDAAoC;AACpC,wDAAsC;AACtC,mDAAiC;AACjC,gEAA8C;AAC9C,mDAAiC;AACjC,6DAA2C;AAC3C,yDAAuC;AACvC,yDAAuC;AACvC,+DAA6C;AAC7C,0DAAwC;AACxC,yEAAuD"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/browser/index.ts"],"names":[],"mappings":";AAAA;;;;;;;kFAOkF;;;;;;;;;;;;;;;;AAElF,gEAAgE;AAChE,mFAAmF;AACnF,sDAAoC;AACpC,wDAAsC;AACtC,mDAAiC;AACjC,gEAA8C;AAC9C,mDAAiC;AACjC,6DAA2C;AAC3C,yDAAuC;AACvC,yDAAuC;AACvC,kDAAgC;AAChC,+DAA6C;AAC7C,0DAAwC;AACxC,yEAAuD"}
@@ -7,7 +7,6 @@
7
7
  * SPDX-License-Identifier: MIT
8
8
  ********************************************************************************/
9
9
  import { AbstractSocketForwardingConnectionHandler } from '@hydranium/client-theia/lib/node';
10
- import { type Channel, type Disposable } from '@theia/core';
11
10
  import type * as net from 'net';
12
11
  /** Options for `GlspServerConnectionHandler`. The language contribution
13
12
  * id determines the per-language servicePath that Theia routes browser-frontend
@@ -16,6 +15,16 @@ import type * as net from 'net';
16
15
  export interface GlspServerConnectionHandlerOptions {
17
16
  readonly languageContributionId: string;
18
17
  readonly portCommand: string;
18
+ /**
19
+ * Product name for the connect-failure dialog this handler raises.
20
+ *
21
+ * It reaches the adopter's UI verbatim, so the framework default leaks a
22
+ * framework noun into a product that is not ours. Not a translation concern —
23
+ * routing it through a catalogue would ask an adopter to "translate" English
24
+ * into their own product name, and would make their branding
25
+ * locale-dependent.
26
+ */
27
+ readonly serverName?: string;
19
28
  readonly findPortTimeout?: number;
20
29
  readonly findPortAttempts?: number;
21
30
  readonly connectTimeoutMs?: number;
@@ -32,18 +41,15 @@ export interface GlspServerConnectionHandlerOptions {
32
41
  /**
33
42
  * Bridges a Theia browser-frontend channel to a GLSP server's TCP socket.
34
43
  *
35
- * The port-discovery + buffer-and-replay race fix + connect orchestration live
36
- * on the cross-head {@link AbstractSocketForwardingConnectionHandler} base; this
37
- * subclass supplies only the GLSP specifics — the per-language servicePath
44
+ * The port discovery, the buffer-and-replay race fix, the connect orchestration
45
+ * and the byte forwarder live on the cross-head
46
+ * {@link AbstractSocketForwardingConnectionHandler} base; this subclass supplies
47
+ * only the GLSP specifics — the per-language servicePath
38
48
  * (`GLSPContribution.servicePath + '/' + languageContributionId`), the port
39
- * command, the log labels — and plugs in `@eclipse-glsp/theia-integration`'s
40
- * `SocketConnectionForwarder` as the byte relay. Adopters with different
41
- * language ids or command names subclass with a one-line `super({...})` call.
42
- * Sibling of `@hydranium/data-client-theia`'s `DataServerConnectionHandler`,
43
- * which subclasses the same base with its own GLSP-free forwarder.
49
+ * command, the log labels. Adopters with different language ids or command
50
+ * names subclass with a one-line `super({...})` call.
44
51
  */
45
52
  export declare class GlspServerConnectionHandler extends AbstractSocketForwardingConnectionHandler {
46
53
  constructor(options: GlspServerConnectionHandlerOptions);
47
- protected forwardToSocketConnection(clientChannel: Channel, socket: net.Socket): Disposable;
48
54
  }
49
55
  //# sourceMappingURL=glsp-server-connection-handler.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"glsp-server-connection-handler.d.ts","sourceRoot":"","sources":["../../src/node/glsp-server-connection-handler.ts"],"names":[],"mappings":"AAAA;;;;;;;kFAOkF;AAIlF,OAAO,EAAE,yCAAyC,EAAE,MAAM,kCAAkC,CAAC;AAC7F,OAAO,EAAE,KAAK,OAAO,EAAE,KAAK,UAAU,EAAE,MAAM,aAAa,CAAC;AAE5D,OAAO,KAAK,KAAK,GAAG,MAAM,KAAK,CAAC;AAEhC;;;iDAGiD;AACjD,MAAM,WAAW,kCAAkC;IAChD,QAAQ,CAAC,sBAAsB,EAAE,MAAM,CAAC;IACxC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,CAAC;IAClC,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IACnC,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IACnC;;;;;;;OAOG;IACH,QAAQ,CAAC,eAAe,CAAC,EAAE,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,KAAK,IAAI,CAAC;CAC1D;AAED;;;;;;;;;;;;GAYG;AACH,qBACa,2BAA4B,SAAQ,yCAAyC;gBAC9D,OAAO,EAAE,kCAAkC;IAapE,SAAS,CAAC,yBAAyB,CAAC,aAAa,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,GAAG,UAAU;CAG7F"}
1
+ {"version":3,"file":"glsp-server-connection-handler.d.ts","sourceRoot":"","sources":["../../src/node/glsp-server-connection-handler.ts"],"names":[],"mappings":"AAAA;;;;;;;kFAOkF;AAGlF,OAAO,EAAE,yCAAyC,EAAE,MAAM,kCAAkC,CAAC;AAE7F,OAAO,KAAK,KAAK,GAAG,MAAM,KAAK,CAAC;AAEhC;;;iDAGiD;AACjD,MAAM,WAAW,kCAAkC;IAChD,QAAQ,CAAC,sBAAsB,EAAE,MAAM,CAAC;IACxC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B;;;;;;;;OAQG;IACH,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,CAAC;IAClC,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IACnC,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IACnC;;;;;;;OAOG;IACH,QAAQ,CAAC,eAAe,CAAC,EAAE,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,KAAK,IAAI,CAAC;CAC1D;AAED;;;;;;;;;;GAUG;AACH,qBACa,2BAA4B,SAAQ,yCAAyC;gBAC9D,OAAO,EAAE,kCAAkC;CAYtE"}
@@ -22,38 +22,32 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
22
22
  Object.defineProperty(exports, "__esModule", { value: true });
23
23
  exports.GlspServerConnectionHandler = void 0;
24
24
  const common_1 = require("@eclipse-glsp/theia-integration/lib/common");
25
- const node_1 = require("@eclipse-glsp/theia-integration/lib/node");
26
- const node_2 = require("@hydranium/client-theia/lib/node");
25
+ const node_1 = require("@hydranium/client-theia/lib/node");
27
26
  const inversify_1 = require("@theia/core/shared/inversify");
28
27
  /**
29
28
  * Bridges a Theia browser-frontend channel to a GLSP server's TCP socket.
30
29
  *
31
- * The port-discovery + buffer-and-replay race fix + connect orchestration live
32
- * on the cross-head {@link AbstractSocketForwardingConnectionHandler} base; this
33
- * subclass supplies only the GLSP specifics — the per-language servicePath
30
+ * The port discovery, the buffer-and-replay race fix, the connect orchestration
31
+ * and the byte forwarder live on the cross-head
32
+ * {@link AbstractSocketForwardingConnectionHandler} base; this subclass supplies
33
+ * only the GLSP specifics — the per-language servicePath
34
34
  * (`GLSPContribution.servicePath + '/' + languageContributionId`), the port
35
- * command, the log labels — and plugs in `@eclipse-glsp/theia-integration`'s
36
- * `SocketConnectionForwarder` as the byte relay. Adopters with different
37
- * language ids or command names subclass with a one-line `super({...})` call.
38
- * Sibling of `@hydranium/data-client-theia`'s `DataServerConnectionHandler`,
39
- * which subclasses the same base with its own GLSP-free forwarder.
35
+ * command, the log labels. Adopters with different language ids or command
36
+ * names subclass with a one-line `super({...})` call.
40
37
  */
41
- let GlspServerConnectionHandler = class GlspServerConnectionHandler extends node_2.AbstractSocketForwardingConnectionHandler {
38
+ let GlspServerConnectionHandler = class GlspServerConnectionHandler extends node_1.AbstractSocketForwardingConnectionHandler {
42
39
  constructor(options) {
43
40
  super({
44
41
  path: common_1.GLSPContribution.servicePath + '/' + options.languageContributionId,
45
42
  portCommand: options.portCommand,
46
43
  logComponent: 'GLSP',
47
- serverName: 'Graphical Server',
44
+ serverName: options.serverName ?? 'Graphical Server',
48
45
  findPortTimeout: options.findPortTimeout,
49
46
  findPortAttempts: options.findPortAttempts,
50
47
  connectTimeoutMs: options.connectTimeoutMs,
51
48
  onSocketCreated: options.onSocketCreated
52
49
  });
53
50
  }
54
- forwardToSocketConnection(clientChannel, socket) {
55
- return new node_1.SocketConnectionForwarder(clientChannel, socket);
56
- }
57
51
  };
58
52
  exports.GlspServerConnectionHandler = GlspServerConnectionHandler;
59
53
  exports.GlspServerConnectionHandler = GlspServerConnectionHandler = __decorate([
@@ -1 +1 @@
1
- {"version":3,"file":"glsp-server-connection-handler.js","sourceRoot":"","sources":["../../src/node/glsp-server-connection-handler.ts"],"names":[],"mappings":";AAAA;;;;;;;kFAOkF;;;;;;;;;;;;;;;AAElF,uEAA8E;AAC9E,mEAAqF;AACrF,2DAA6F;AAE7F,4DAAqE;AAwBrE;;;;;;;;;;;;GAYG;AAEI,IAAM,2BAA2B,GAAjC,MAAM,2BAA4B,SAAQ,gDAAyC;IACvF,YAAyB,OAA2C;QACjE,KAAK,CAAC;YACH,IAAI,EAAE,yBAAgB,CAAC,WAAW,GAAG,GAAG,GAAG,OAAO,CAAC,sBAAsB;YACzE,WAAW,EAAE,OAAO,CAAC,WAAW;YAChC,YAAY,EAAE,MAAM;YACpB,UAAU,EAAE,kBAAkB;YAC9B,eAAe,EAAE,OAAO,CAAC,eAAe;YACxC,gBAAgB,EAAE,OAAO,CAAC,gBAAgB;YAC1C,gBAAgB,EAAE,OAAO,CAAC,gBAAgB;YAC1C,eAAe,EAAE,OAAO,CAAC,eAAe;SAC1C,CAAC,CAAC;IACN,CAAC;IAES,yBAAyB,CAAC,aAAsB,EAAE,MAAkB;QAC3E,OAAO,IAAI,gCAAyB,CAAC,aAAa,EAAE,MAAM,CAAC,CAAC;IAC/D,CAAC;CACH,CAAA;AAjBY,kEAA2B;sCAA3B,2BAA2B;IADvC,IAAA,sBAAU,GAAE;IAEG,WAAA,IAAA,qBAAS,GAAE,CAAA;;GADd,2BAA2B,CAiBvC"}
1
+ {"version":3,"file":"glsp-server-connection-handler.js","sourceRoot":"","sources":["../../src/node/glsp-server-connection-handler.ts"],"names":[],"mappings":";AAAA;;;;;;;kFAOkF;;;;;;;;;;;;;;;AAElF,uEAA8E;AAC9E,2DAA6F;AAC7F,4DAAqE;AAkCrE;;;;;;;;;;GAUG;AAEI,IAAM,2BAA2B,GAAjC,MAAM,2BAA4B,SAAQ,gDAAyC;IACvF,YAAyB,OAA2C;QACjE,KAAK,CAAC;YACH,IAAI,EAAE,yBAAgB,CAAC,WAAW,GAAG,GAAG,GAAG,OAAO,CAAC,sBAAsB;YACzE,WAAW,EAAE,OAAO,CAAC,WAAW;YAChC,YAAY,EAAE,MAAM;YACpB,UAAU,EAAE,OAAO,CAAC,UAAU,IAAI,kBAAkB;YACpD,eAAe,EAAE,OAAO,CAAC,eAAe;YACxC,gBAAgB,EAAE,OAAO,CAAC,gBAAgB;YAC1C,gBAAgB,EAAE,OAAO,CAAC,gBAAgB;YAC1C,eAAe,EAAE,OAAO,CAAC,eAAe;SAC1C,CAAC,CAAC;IACN,CAAC;CACH,CAAA;AAbY,kEAA2B;sCAA3B,2BAA2B;IADvC,IAAA,sBAAU,GAAE;IAEG,WAAA,IAAA,qBAAS,GAAE,CAAA;;GADd,2BAA2B,CAavC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hydranium/glsp-client-theia",
3
- "version": "1.0.0-next.13",
3
+ "version": "1.0.0-next.135",
4
4
  "description": "Theia-coupled client primitives for GLSP heads built on @hydranium/glsp-server. Provides the action dispatcher, channel logger, and connection-handler bases that Theia-based adopters extend; companion of @hydranium/glsp-server.",
5
5
  "keywords": [
6
6
  "hydranium",
@@ -77,15 +77,19 @@
77
77
  },
78
78
  "devDependencies": {
79
79
  "@eclipse-glsp/client": "2.7.0",
80
+ "@eclipse-glsp/server": "2.7.0",
80
81
  "@eclipse-glsp/theia-integration": "2.7.0",
81
- "@hydranium/client-theia": "1.0.0-next.13",
82
- "@hydranium/protocol": "1.0.0-next.13",
83
- "@theia/core": "^1.71.0",
84
- "@theia/output": "^1.71.0",
85
- "@theia/process": "^1.71.0",
86
- "@theia/workspace": "^1.71.0",
82
+ "@hydranium/client-theia": "1.0.0-next.135",
83
+ "@hydranium/core": "1.0.0-next.135",
84
+ "@hydranium/glsp-server": "1.0.0-next.135",
85
+ "@hydranium/protocol": "1.0.0-next.135",
86
+ "@theia/core": "^1.70.0",
87
+ "@theia/output": "^1.70.0",
88
+ "@theia/process": "^1.70.0",
89
+ "@theia/workspace": "^1.70.0",
87
90
  "@types/node": "^22.0.0",
88
91
  "inversify": "6.2.2",
92
+ "reflect-metadata": "0.2.2",
89
93
  "rimraf": "^5.0.0",
90
94
  "snabbdom": "3.5.1",
91
95
  "typescript": "^5.8.0"
@@ -93,12 +97,12 @@
93
97
  "peerDependencies": {
94
98
  "@eclipse-glsp/client": "^2.6.0",
95
99
  "@eclipse-glsp/theia-integration": "^2.6.0",
96
- "@hydranium/client-theia": "1.0.0-next.13",
97
- "@hydranium/protocol": "1.0.0-next.13",
98
- "@theia/core": "^1.71.0",
99
- "@theia/output": "^1.71.0",
100
- "@theia/process": "^1.71.0",
101
- "@theia/workspace": "^1.71.0",
100
+ "@hydranium/client-theia": "1.0.0-next.135",
101
+ "@hydranium/protocol": "1.0.0-next.135",
102
+ "@theia/core": "^1.70.0",
103
+ "@theia/output": "^1.70.0",
104
+ "@theia/process": "^1.70.0",
105
+ "@theia/workspace": "^1.70.0",
102
106
  "inversify": "^6.0.0",
103
107
  "snabbdom": "^3.5.1"
104
108
  },
@@ -10,6 +10,7 @@
10
10
  import { DiagramLoader, type DiagramLoadingOptions, StatusAction } from '@eclipse-glsp/client';
11
11
  import { ChannelLogger } from '@hydranium/client-theia/lib/browser';
12
12
  import { Deferred } from '@hydranium/protocol';
13
+ import { nls } from '@theia/core';
13
14
  import { inject, injectable } from '@theia/core/shared/inversify';
14
15
 
15
16
  /**
@@ -156,13 +157,25 @@ export class HydraniumDiagramLoader extends DiagramLoader {
156
157
 
157
158
  /**
158
159
  * The sentence a failed load is reported with, on every surface that reports
159
- * it, and the only seam an adopter rewords or localizes it at. Public
160
- * because the canvas overlay is one of those surfaces and lives in another
161
- * class: it renders this failure exactly when the `StatusAction` did not
162
- * land, so a second copy of the sentence there could only ever drift unseen.
160
+ * it. Public because the canvas overlay is one of those surfaces and lives in
161
+ * another class: it renders this failure exactly when the `StatusAction` did
162
+ * not land, so a second copy of the sentence there could only ever drift
163
+ * unseen.
164
+ *
165
+ * **The seam and the catalogue key answer different questions, so it carries
166
+ * both.** Overriding this method changes the WORDING for every user of one
167
+ * adopter's product; the key is what gives a reader the sentence in their own
168
+ * language, and no override can supply that without an adopter writing a
169
+ * subclass per locale — which is the thing a catalogue exists to avoid. Two
170
+ * of the three surfaces this reaches are user-visible, so the audience
171
+ * triage answers it: a host-bound string a user sees takes an inline key.
172
+ *
173
+ * The Output-channel line is therefore localized too, which is deliberate
174
+ * rather than overlooked — the alternative is a second English copy of one
175
+ * sentence, and the reason for a single source here has not changed.
163
176
  */
164
177
  loadFailureLabel(err: unknown): string {
165
- return `Diagram failed to load: ${this.formatError(err)}`;
178
+ return nls.localize('hydranium/glsp-client-theia/diagram-load-failed', 'Diagram failed to load: {0}', this.formatError(err));
166
179
  }
167
180
 
168
181
  /** Render a thrown value as a message. Shared so the channel line, the status
@@ -7,13 +7,14 @@
7
7
  * SPDX-License-Identifier: MIT
8
8
  ********************************************************************************/
9
9
 
10
- import { DiagramLoader } from '@eclipse-glsp/client';
11
- import { GLSPDiagramWidget } from '@eclipse-glsp/theia-integration';
10
+ import { DiagramLoader, EditorContextService } from '@eclipse-glsp/client';
11
+ import { GLSPDiagramWidget, type GLSPDiagramWidgetOptions } from '@eclipse-glsp/theia-integration';
12
12
  // Type-only: the `@theia/core/lib/browser` barrel touches DOM globals at module
13
13
  // load, which the node-environment unit tests cannot provide.
14
14
  import { type Message } from '@theia/core/lib/browser';
15
- import { injectable } from '@theia/core/shared/inversify';
15
+ import { type Container, injectable } from '@theia/core/shared/inversify';
16
16
  import { type DiagramLoadOutcome, HydraniumDiagramLoader } from './diagram-loader';
17
+ import { HydraniumGlspSaveable } from './glsp-saveable';
17
18
  // Shipped by this package rather than left to adopters: an overlay whose
18
19
  // stylesheet was forgotten is an unstyled div in normal flow, which is a silent
19
20
  // failure. Adopters override individual rules from their own stylesheet.
@@ -56,11 +57,31 @@ export const DIAGRAM_LOADING_FAILED_CLASS = `${DIAGRAM_LOADING_CLASS}-failed`;
56
57
  * Bound unconditionally by `AbstractHydraniumGlspTheiaFrontendModule`. To opt out,
57
58
  * override {@link showLoadingOverlay} to a no-op; to change what is rendered,
58
59
  * override {@link createLoadingOverlay} or {@link loadingLabel}.
60
+ *
61
+ * Its saveable is a {@link HydraniumGlspSaveable}, which keeps a pending save
62
+ * dirty, so Theia's exit check still counts it; see {@link createSaveable}.
59
63
  */
60
64
  @injectable()
61
65
  export class HydraniumGlspDiagramWidget extends GLSPDiagramWidget {
62
66
  protected loadingOverlay?: HTMLElement;
63
67
 
68
+ /**
69
+ * Replaces the saveable GLSP's `configure` builds inline, with no factory
70
+ * seam. The widget factory calls `configure` before the widget reaches the
71
+ * shell, so Theia only ever tracks this one.
72
+ */
73
+ override configure(options: GLSPDiagramWidgetOptions, diContainer: Container): void {
74
+ super.configure(options, diContainer);
75
+ this.saveable.dispose();
76
+ this.saveable = this.createSaveable();
77
+ this.toDispose.push(this.saveable);
78
+ }
79
+
80
+ /** The widget's saveable. Override to change how saves and dirty state behave. */
81
+ protected createSaveable(): GLSPDiagramWidget['saveable'] {
82
+ return new HydraniumGlspSaveable(this.actionDispatcher, this.diContainer.get(EditorContextService));
83
+ }
84
+
64
85
  protected override onAfterAttach(msg: Message): void {
65
86
  // Before `super`, which is what starts the load on first attach — so the
66
87
  // overlay is already up when the round trip begins.
@@ -10,6 +10,8 @@
10
10
  import { codiconCSSString } from '@eclipse-glsp/client';
11
11
  import { GLSPDiagramManager } from '@eclipse-glsp/theia-integration';
12
12
  import { type GLSPDiagramLanguage } from '@eclipse-glsp/theia-integration/lib/common';
13
+ import { type GLSPDiagramWidget } from '@eclipse-glsp/theia-integration/lib/browser';
14
+ import { type WidgetOpenerOptions } from '@theia/core/lib/browser';
13
15
  import { injectable } from '@theia/core/shared/inversify';
14
16
 
15
17
  /**
@@ -64,4 +66,31 @@ export abstract class AbstractHydraniumGlspDiagramManager extends GLSPDiagramMan
64
66
  get label(): string {
65
67
  return this.managerLabel;
66
68
  }
69
+
70
+ /**
71
+ * Drops a `selection` key that is present but `undefined` before the base
72
+ * class reads it.
73
+ *
74
+ * Without this, opening a diagram from Theia's file picker throws and the
75
+ * editor never leaves "Loading diagram…". Upstream's
76
+ * `OptionsWithSelection.is` tests `'selection' in options`, which is true for
77
+ * a key explicitly set to `undefined`, and the branch it guards then calls
78
+ * `Object.keys` on that value. Theia's own `QuickFileOpenService` always sets
79
+ * the key — its `buildOpenerOptions` returns `{ selection: range }`, and
80
+ * `range` is `undefined` unless the query carried a `:line:column` suffix —
81
+ * so the crash is reached by the ordinary act of opening a diagram by name.
82
+ *
83
+ * Normalising the OPTIONS rather than rebinding
84
+ * `TheiaOpenerOptionsNavigationService`: the service is shared by every
85
+ * diagram type in the container, so replacing it would make one adopter's
86
+ * fix silently global, and the guard belongs where the value enters rather
87
+ * than where it is consumed. The base method stays the single implementation.
88
+ */
89
+ protected override handleNavigations(widget: GLSPDiagramWidget, options?: WidgetOpenerOptions): boolean {
90
+ if (options && 'selection' in options && (options as { selection?: unknown }).selection === undefined) {
91
+ const { selection: _dropped, ...rest } = options as WidgetOpenerOptions & { selection?: unknown };
92
+ return super.handleNavigations(widget, rest);
93
+ }
94
+ return super.handleNavigations(widget, options);
95
+ }
67
96
  }
@@ -24,6 +24,14 @@ import { type interfaces, injectable } from '@theia/core/shared/inversify';
24
24
  * Matching an English literal fails silently — no error, no log line, just the
25
25
  * duplicate progress popup back — so this needs keeping in step with
26
26
  * `RequestModelActionHandler` on every GLSP bump.
27
+ *
28
+ * **Exported to be imported, and it must NOT be externalized.** An adopter
29
+ * subclassing the message service needs the same literal to match on, and a
30
+ * second copy of it is a second thing to keep in step across that bump. It is
31
+ * also the one user-visible string in the framework that is deliberately excluded
32
+ * from the message catalogue: it exists to equal an upstream English literal that
33
+ * lives in no catalogue, so giving it a code and a translation would break the
34
+ * match it exists for.
27
35
  */
28
36
  export const MODEL_LOADING_PROGRESS_TITLE = 'Model loading in progress';
29
37
 
@@ -0,0 +1,110 @@
1
+ /********************************************************************************
2
+ * Copyright (c) 2026 CrossBreeze, EclipseSource and others.
3
+ *
4
+ * This program and the accompanying materials are made available under the
5
+ * terms of the MIT License which is available in the project root.
6
+ *
7
+ * SPDX-License-Identifier: MIT
8
+ ********************************************************************************/
9
+
10
+ import { RequestSaveModelAction } from '@hydranium/protocol';
11
+ // The module path, not the package root: the root also loads GLSP's diagram
12
+ // widget, which touches DOM globals at module load, and this module's unit tests
13
+ // load it in Node.
14
+ import { GLSPSaveable } from '@eclipse-glsp/theia-integration/lib/browser/diagram/glsp-saveable';
15
+
16
+ /**
17
+ * A `GLSPSaveable` whose every save is a request the server answers, and which
18
+ * stays dirty until that answer arrives.
19
+ *
20
+ * GLSP's sends a `SaveModelAction`, which the server does not answer. It takes
21
+ * the next dirty-state change to clean as the answer, but the editor context
22
+ * reports a change only when the dirty flag changes: the second of two saves
23
+ * gets no answer, and a failed save gets none either. Here each save sends a
24
+ * `RequestSaveModelAction` and settles on the response to that request only:
25
+ * it resolves when the server has saved, rejects when the server rejects it,
26
+ * and rejects when {@link saveTimeout} runs out. A save sent while another is
27
+ * pending is a request of its own, so an edit made between the two is saved.
28
+ *
29
+ * GLSP's also reports not dirty from the moment it sends a save. Theia's exit
30
+ * check asks only whether anything is dirty, so the window closes over a save
31
+ * the server has not finished, and a page reloaded right after Ctrl+S gives no
32
+ * warning. Here the saveable is dirty while any save is pending. GLSP's also
33
+ * gives up after 2 s, and Theia's Save All then counts the save as failed and
34
+ * closes the window anyway, so a slow save of a large model is cut off.
35
+ *
36
+ * The dirty flag still comes from the server. An edit whose dirty-state change
37
+ * has not arrived when Save All runs does not make the saveable dirty, so that
38
+ * edit is not saved.
39
+ *
40
+ * The server answers only where the diagram module registers the request's
41
+ * handler; `AbstractHydraniumGlspDiagramModule` does. A server without it does
42
+ * not advertise the request, and against such a server the saveable is GLSP's:
43
+ * it sends a `SaveModelAction` and reports dirty as GLSP's does. It does not
44
+ * keep only the dirty-while-pending half there, because GLSP's tracks one
45
+ * pending save and a second save overwrites it, so the first would never
46
+ * report clean.
47
+ *
48
+ * The answer means the server has done what its save does, which is not always
49
+ * the disk write: under the `fire-and-forget` `SaveDeliveryPolicy` the server
50
+ * answers before the write finishes and answers a failed write as saved, so a
51
+ * window closed on that answer can still lose the write.
52
+ */
53
+ export class HydraniumGlspSaveable extends GLSPSaveable {
54
+ /**
55
+ * How long a save waits for the server's response before it rejects.
56
+ * Long, because the wait only runs out when the server hangs, and a save
57
+ * that rejects in Theia's Save All lets the window close over it.
58
+ */
59
+ protected override saveTimeout = 10_000;
60
+ /** The saves sent and not yet settled. */
61
+ protected readonly pendingSaves = new Set<Promise<void>>();
62
+
63
+ override get dirty(): boolean {
64
+ if (!this.serverAnswersSaves()) {
65
+ return super.dirty;
66
+ }
67
+ return this.editorContextService.isDirty || this.pendingSaves.size > 0;
68
+ }
69
+
70
+ override save(): Promise<void> {
71
+ if (!this.serverAnswersSaves()) {
72
+ return super.save();
73
+ }
74
+ if (this.editorContextService.isDirty) {
75
+ return this.sendSave();
76
+ }
77
+ // Nothing new to save, but a save still pending has not finished.
78
+ return Promise.all(this.pendingSaves).then(() => undefined);
79
+ }
80
+
81
+ /**
82
+ * Whether the server answers a {@link RequestSaveModelAction}. GLSP's model
83
+ * source registers a handler for each kind the server advertises before it
84
+ * requests the model, so the dispatcher knows it from the first save on.
85
+ */
86
+ protected serverAnswersSaves(): boolean {
87
+ return this.actionDispatcher.hasHandler(RequestSaveModelAction.create());
88
+ }
89
+
90
+ protected sendSave(): Promise<void> {
91
+ // `request` with a bound of our own rather than GLSP's `requestUntil`:
92
+ // that one forgets a request when it times out, so a late response is
93
+ // dispatched as an action no client handler takes, which rejects.
94
+ // Here a late response settles the forgotten request and nothing else.
95
+ const response = this.actionDispatcher.request(RequestSaveModelAction.create());
96
+ let timer: ReturnType<typeof setTimeout> | undefined;
97
+ const timedOut = new Promise<never>((_resolve, reject) => {
98
+ timer = setTimeout(() => reject(new Error('Save operation timed out')), this.saveTimeout);
99
+ });
100
+ const saving: Promise<void> = Promise.race([response, timedOut])
101
+ .then(() => undefined)
102
+ .finally(() => {
103
+ clearTimeout(timer);
104
+ this.pendingSaves.delete(saving);
105
+ this.onDirtyChangedEmitter.fire(undefined);
106
+ });
107
+ this.pendingSaves.add(saving);
108
+ return saving;
109
+ }
110
+ }
@@ -20,8 +20,9 @@ import {
20
20
  isRoutable
21
21
  } from '@eclipse-glsp/client';
22
22
  import { ChannelLogger } from '@hydranium/client-theia/lib/browser';
23
- import { type Clock, SystemClock } from '@hydranium/protocol';
24
- import { inject, injectable } from '@theia/core/shared/inversify';
23
+ import { Clock } from '@hydranium/client-theia/lib/common';
24
+ import { SystemClock } from '@hydranium/protocol';
25
+ import { inject, injectable, optional } from '@theia/core/shared/inversify';
25
26
  import { type VNode } from 'snabbdom';
26
27
 
27
28
  /** How many scoped element ids the log line names before summarising the rest.
@@ -71,10 +72,8 @@ const SCOPE_ID_CAP = 3;
71
72
  export class HydraniumHiddenBoundsUpdater extends GLSPHiddenBoundsUpdater {
72
73
  @inject(ChannelLogger) protected readonly channel!: ChannelLogger;
73
74
 
74
- /** Not injected: the browser container binds no {@link Clock}, and this only
75
- * measures — no logic is gated on time, so there is nothing to fake in
76
- * production. Overridden in tests for a deterministic elapsed value. */
77
- protected readonly clock: Clock = new SystemClock();
75
+ /** The diagram container's {@link Clock}, or a `SystemClock`; it only measures. */
76
+ @inject(Clock) @optional() protected readonly clock: Clock = new SystemClock();
78
77
 
79
78
  /**
80
79
  * Scope description for the in-flight request, read from the `cause` in
@@ -17,6 +17,12 @@ export * from './diagram-widget';
17
17
  export * from './glsp-client-theia-module';
18
18
  export * from './glsp-diagram-manager';
19
19
  export * from './glsp-message-service';
20
+ export * from './glsp-saveable';
20
21
  export * from './glsp-theia-frontend-module';
21
22
  export * from './hidden-bounds-updater';
22
23
  export * from './hydranium-glsp-diagram-configuration';
24
+
25
+ // Upstream's root entry is its browser tier and re-exports no `lib/common`, so the
26
+ // type our abstract `diagramLanguage` members are declared with has no bare-specifier
27
+ // path — without this line every adopter implementing one deep-imports it.
28
+ export type { GLSPDiagramLanguage } from '@eclipse-glsp/theia-integration/lib/common';
@@ -8,9 +8,7 @@
8
8
  ********************************************************************************/
9
9
 
10
10
  import { GLSPContribution } from '@eclipse-glsp/theia-integration/lib/common';
11
- import { SocketConnectionForwarder } from '@eclipse-glsp/theia-integration/lib/node';
12
11
  import { AbstractSocketForwardingConnectionHandler } from '@hydranium/client-theia/lib/node';
13
- import { type Channel, type Disposable } from '@theia/core';
14
12
  import { injectable, unmanaged } from '@theia/core/shared/inversify';
15
13
  import type * as net from 'net';
16
14
 
@@ -21,6 +19,16 @@ import type * as net from 'net';
21
19
  export interface GlspServerConnectionHandlerOptions {
22
20
  readonly languageContributionId: string;
23
21
  readonly portCommand: string;
22
+ /**
23
+ * Product name for the connect-failure dialog this handler raises.
24
+ *
25
+ * It reaches the adopter's UI verbatim, so the framework default leaks a
26
+ * framework noun into a product that is not ours. Not a translation concern —
27
+ * routing it through a catalogue would ask an adopter to "translate" English
28
+ * into their own product name, and would make their branding
29
+ * locale-dependent.
30
+ */
31
+ readonly serverName?: string;
24
32
  readonly findPortTimeout?: number;
25
33
  readonly findPortAttempts?: number;
26
34
  readonly connectTimeoutMs?: number;
@@ -38,15 +46,13 @@ export interface GlspServerConnectionHandlerOptions {
38
46
  /**
39
47
  * Bridges a Theia browser-frontend channel to a GLSP server's TCP socket.
40
48
  *
41
- * The port-discovery + buffer-and-replay race fix + connect orchestration live
42
- * on the cross-head {@link AbstractSocketForwardingConnectionHandler} base; this
43
- * subclass supplies only the GLSP specifics — the per-language servicePath
49
+ * The port discovery, the buffer-and-replay race fix, the connect orchestration
50
+ * and the byte forwarder live on the cross-head
51
+ * {@link AbstractSocketForwardingConnectionHandler} base; this subclass supplies
52
+ * only the GLSP specifics — the per-language servicePath
44
53
  * (`GLSPContribution.servicePath + '/' + languageContributionId`), the port
45
- * command, the log labels — and plugs in `@eclipse-glsp/theia-integration`'s
46
- * `SocketConnectionForwarder` as the byte relay. Adopters with different
47
- * language ids or command names subclass with a one-line `super({...})` call.
48
- * Sibling of `@hydranium/data-client-theia`'s `DataServerConnectionHandler`,
49
- * which subclasses the same base with its own GLSP-free forwarder.
54
+ * command, the log labels. Adopters with different language ids or command
55
+ * names subclass with a one-line `super({...})` call.
50
56
  */
51
57
  @injectable()
52
58
  export class GlspServerConnectionHandler extends AbstractSocketForwardingConnectionHandler {
@@ -55,15 +61,11 @@ export class GlspServerConnectionHandler extends AbstractSocketForwardingConnect
55
61
  path: GLSPContribution.servicePath + '/' + options.languageContributionId,
56
62
  portCommand: options.portCommand,
57
63
  logComponent: 'GLSP',
58
- serverName: 'Graphical Server',
64
+ serverName: options.serverName ?? 'Graphical Server',
59
65
  findPortTimeout: options.findPortTimeout,
60
66
  findPortAttempts: options.findPortAttempts,
61
67
  connectTimeoutMs: options.connectTimeoutMs,
62
68
  onSocketCreated: options.onSocketCreated
63
69
  });
64
70
  }
65
-
66
- protected forwardToSocketConnection(clientChannel: Channel, socket: net.Socket): Disposable {
67
- return new SocketConnectionForwarder(clientChannel, socket);
68
- }
69
71
  }