@hydranium/glsp-client-vscode 0.0.0-stage → 1.0.0-next

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 (38) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +132 -2
  3. package/lib/browser/glsp-starter.d.ts +27 -0
  4. package/lib/browser/glsp-starter.d.ts.map +1 -0
  5. package/lib/browser/glsp-starter.js +38 -0
  6. package/lib/browser/glsp-starter.js.map +1 -0
  7. package/lib/browser/index.d.ts +10 -0
  8. package/lib/browser/index.d.ts.map +1 -0
  9. package/lib/browser/index.js +26 -0
  10. package/lib/browser/index.js.map +1 -0
  11. package/lib/diagram-container.d.ts +15 -0
  12. package/lib/diagram-container.d.ts.map +1 -0
  13. package/lib/diagram-container.js +18 -0
  14. package/lib/diagram-container.js.map +1 -0
  15. package/lib/index.d.ts +10 -0
  16. package/lib/index.d.ts.map +1 -0
  17. package/lib/index.js +29 -0
  18. package/lib/index.js.map +1 -0
  19. package/lib/node/glsp-editor-provider.d.ts +57 -0
  20. package/lib/node/glsp-editor-provider.d.ts.map +1 -0
  21. package/lib/node/glsp-editor-provider.js +131 -0
  22. package/lib/node/glsp-editor-provider.js.map +1 -0
  23. package/lib/node/glsp-vscode-server.d.ts +46 -0
  24. package/lib/node/glsp-vscode-server.d.ts.map +1 -0
  25. package/lib/node/glsp-vscode-server.js +93 -0
  26. package/lib/node/glsp-vscode-server.js.map +1 -0
  27. package/lib/node/index.d.ts +11 -0
  28. package/lib/node/index.d.ts.map +1 -0
  29. package/lib/node/index.js +27 -0
  30. package/lib/node/index.js.map +1 -0
  31. package/package.json +89 -4
  32. package/src/browser/glsp-starter.ts +39 -0
  33. package/src/browser/index.ts +10 -0
  34. package/src/diagram-container.ts +15 -0
  35. package/src/index.ts +13 -0
  36. package/src/node/glsp-editor-provider.ts +110 -0
  37. package/src/node/glsp-vscode-server.ts +73 -0
  38. package/src/node/index.ts +11 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 CrossBreeze, EclipseSource and others.
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,3 +1,133 @@
1
- # Temporary Holding Version
1
+ # `@hydranium/glsp-client-vscode`
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ The GLSP head's client side in a VS Code extension built on
4
+ [Hydranium](https://github.com/eclipse-emfcloud/hydranium). Install it when
5
+ your extension opens a diagram in a custom editor: it connects GLSP's VS Code
6
+ integration to the head's socket and hosts the diagram in a webview with the
7
+ framework's client classes.
8
+
9
+ ## What it gives you
10
+
11
+ - GLSP's VS Code server over the head's socket, with the port looked up when
12
+ the server starts rather than during activation.
13
+ - A custom editor whose webview document carries a Content-Security-Policy
14
+ that grants sprotty what it needs and no `eval`, and the element the diagram
15
+ mounts into.
16
+ - A webview starter that adds `@hydranium/glsp-client`'s classes to the
17
+ diagram container, after GLSP's VS Code modules and before your diagram's.
18
+
19
+ ## Install
20
+
21
+ ```bash
22
+ npm install @hydranium/glsp-client-vscode
23
+ ```
24
+
25
+ | Peer | Range |
26
+ | ------------------------------------------ | ------------- |
27
+ | `@eclipse-glsp/client` | `^2.6.0` |
28
+ | `@eclipse-glsp/vscode-integration` | `^2.6.0` |
29
+ | `@eclipse-glsp/vscode-integration-webview` | `^2.6.0` |
30
+ | `@hydranium/glsp-client` | `^1.0.0-next` |
31
+ | `@hydranium/protocol` | `^1.0.0-next` |
32
+ | `inversify` | `^6.0.0` |
33
+ | `vscode-jsonrpc` | `^9.0.0` |
34
+
35
+ ## Wiring
36
+
37
+ In the extension host, give GLSP's connector the server, start it without
38
+ awaiting it, report a failure off `onReady`, and register your editor, a
39
+ subclass naming the diagram type, the webview bundle and a title. `findPort`
40
+ is your lookup of the head's port, such as `findPort` from
41
+ `@hydranium/client-vscode/node` on your language client:
42
+
43
+ <!-- snippet-preamble
44
+ declare function findGlspPort(): Promise<number>;
45
+ -->
46
+
47
+ ```ts
48
+ import { GlspVscodeConnector } from '@eclipse-glsp/vscode-integration';
49
+ import { HydraniumGlspEditorProvider, HydraniumGlspVscodeServer } from '@hydranium/glsp-client-vscode/node';
50
+ import { ConsoleLogger } from '@hydranium/protocol';
51
+ import { window, type ExtensionContext } from 'vscode';
52
+
53
+ class MyDiagramEditorProvider extends HydraniumGlspEditorProvider {
54
+ override diagramType = 'my-diagram';
55
+ protected override readonly scriptPath = 'out/webview/diagram.js';
56
+ protected override readonly stylePath = 'out/webview/diagram.css';
57
+ protected override readonly title = 'My Diagram';
58
+ }
59
+
60
+ export function activate(context: ExtensionContext): void {
61
+ const server = new HydraniumGlspVscodeServer({
62
+ clientId: 'my-language-glsp',
63
+ clientName: 'My Language',
64
+ findPort: findGlspPort,
65
+ logger: new ConsoleLogger()
66
+ });
67
+ const connector = new GlspVscodeConnector({ server });
68
+ context.subscriptions.push(server, connector);
69
+ void server.start();
70
+ server.onReady.catch((error: unknown) => window.showErrorMessage(`Diagram unavailable: ${String(error)}`));
71
+ context.subscriptions.push(
72
+ window.registerCustomEditorProvider('myLanguage.diagram', new MyDiagramEditorProvider(connector, context.extensionUri), {
73
+ webviewOptions: { retainContextWhenHidden: true }
74
+ })
75
+ );
76
+ }
77
+ ```
78
+
79
+ The webview may load from the script's directory and the stylesheet's. The
80
+ diagram mounts into an element of class `DIAGRAM_CONTAINER_CLASS`, from the
81
+ package root, which your webview stylesheet sizes. In the webview bundle,
82
+ start the diagram with a `HydraniumGlspStarter` whose container appends your
83
+ diagram's own container module last:
84
+
85
+ <!-- snippet-preamble
86
+ import type { ContainerModule } from 'inversify';
87
+ declare const myDiagramModule: ContainerModule;
88
+ -->
89
+
90
+ ```ts
91
+ import { initializeDiagramContainer, type ContainerConfiguration } from '@eclipse-glsp/client';
92
+ import { HydraniumGlspStarter } from '@hydranium/glsp-client-vscode/browser';
93
+ import { Container } from 'inversify';
94
+
95
+ class MyDiagramStarter extends HydraniumGlspStarter {
96
+ createContainer(...containerConfiguration: ContainerConfiguration): Container {
97
+ // `myDiagramModule` is yours: the model and view registrations of your diagram.
98
+ return initializeDiagramContainer(new Container(), ...containerConfiguration, myDiagramModule);
99
+ }
100
+ }
101
+ new MyDiagramStarter();
102
+ ```
103
+
104
+ The extension host's tier never reaches `@eclipse-glsp/client`, whose
105
+ stylesheets Node cannot load. Keep your own extension host code off your
106
+ diagram module for the same reason.
107
+
108
+ For the whole setup, see *Host in VS Code* in
109
+ [Adopting Hydranium](https://github.com/eclipse-emfcloud/hydranium/blob/main/docs/ADOPTING.md).
110
+
111
+ ## Entry points
112
+
113
+ | Subpath | Use it for | Runs in |
114
+ | ----------- | ----------------------------------------------- | -------------------------- |
115
+ | `.` | The class name both tiers share | anywhere |
116
+ | `./node` | The GLSP server and the diagram's custom editor | the VS Code extension host |
117
+ | `./browser` | The diagram webview's starter | a webview |
118
+
119
+ The subpaths need a TypeScript `moduleResolution` that reads `exports`
120
+ (`NodeNext` or `Bundler`); see *Requirements* in
121
+ [Adopting Hydranium](https://github.com/eclipse-emfcloud/hydranium/blob/main/docs/ADOPTING.md).
122
+
123
+ ## Status
124
+
125
+ Alpha: every release is a prerelease that may break the API, so pin an exact
126
+ version. Guides and known limitations:
127
+ [Adopting Hydranium](https://github.com/eclipse-emfcloud/hydranium/blob/main/docs/ADOPTING.md).
128
+
129
+ ## License
130
+
131
+ `MIT` — see this package's [`LICENSE`](./LICENSE), and the repository
132
+ [`NOTICE.md`](https://github.com/eclipse-emfcloud/hydranium/blob/main/NOTICE.md)
133
+ for third-party notices.
@@ -0,0 +1,27 @@
1
+ /********************************************************************************
2
+ * Copyright (c) 2026 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
+ import type { ContainerConfiguration } from '@eclipse-glsp/client';
10
+ import { GLSPStarter } from '@eclipse-glsp/vscode-integration-webview';
11
+ import { type GlspClientModuleOptions } from '@hydranium/glsp-client';
12
+ /**
13
+ * The diagram webview's starter: GLSP's handshake with the extension host,
14
+ * with the framework's client module among the modules the container is built
15
+ * from.
16
+ *
17
+ * The module follows the host's own, since it replaces tokens they bind, and
18
+ * comes before whatever `createContainer` appends: GLSP's model and view
19
+ * registries give an element type to the module that registers it last, so a
20
+ * subclass appends its diagram definition last.
21
+ */
22
+ export declare abstract class HydraniumGlspStarter extends GLSPStarter {
23
+ protected getContainerConfiguration(): ContainerConfiguration;
24
+ /** Options for the framework's client module. Without a logger it logs to the webview's console, the only sink a webview has. */
25
+ protected glspClientModuleOptions(): GlspClientModuleOptions;
26
+ }
27
+ //# sourceMappingURL=glsp-starter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"glsp-starter.d.ts","sourceRoot":"","sources":["../../src/browser/glsp-starter.ts"],"names":[],"mappings":"AAAA;;;;;;;kFAOkF;AAElF,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AACnE,OAAO,EAAE,WAAW,EAAE,MAAM,0CAA0C,CAAC;AACvE,OAAO,EAA0B,KAAK,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AAG9F;;;;;;;;;GASG;AACH,8BAAsB,oBAAqB,SAAQ,WAAW;IAC3D,UAAmB,yBAAyB,IAAI,sBAAsB,CAOrE;IAED,iIAAiI;IACjI,SAAS,CAAC,uBAAuB,IAAI,uBAAuB,CAE3D;CACH"}
@@ -0,0 +1,38 @@
1
+ "use strict";
2
+ /********************************************************************************
3
+ * Copyright (c) 2026 EclipseSource and others.
4
+ *
5
+ * This program and the accompanying materials are made available under the
6
+ * terms of the MIT License which is available in the project root.
7
+ *
8
+ * SPDX-License-Identifier: MIT
9
+ ********************************************************************************/
10
+ Object.defineProperty(exports, "__esModule", { value: true });
11
+ exports.HydraniumGlspStarter = void 0;
12
+ const vscode_integration_webview_1 = require("@eclipse-glsp/vscode-integration-webview");
13
+ const glsp_client_1 = require("@hydranium/glsp-client");
14
+ const inversify_1 = require("inversify");
15
+ /**
16
+ * The diagram webview's starter: GLSP's handshake with the extension host,
17
+ * with the framework's client module among the modules the container is built
18
+ * from.
19
+ *
20
+ * The module follows the host's own, since it replaces tokens they bind, and
21
+ * comes before whatever `createContainer` appends: GLSP's model and view
22
+ * registries give an element type to the module that registers it last, so a
23
+ * subclass appends its diagram definition last.
24
+ */
25
+ class HydraniumGlspStarter extends vscode_integration_webview_1.GLSPStarter {
26
+ getContainerConfiguration() {
27
+ return [
28
+ ...super.getContainerConfiguration(),
29
+ new inversify_1.ContainerModule((bind, unbind, isBound, rebind) => (0, glsp_client_1.createGlspClientModule)({ bind, unbind, isBound, rebind }, this.glspClientModuleOptions()))
30
+ ];
31
+ }
32
+ /** Options for the framework's client module. Without a logger it logs to the webview's console, the only sink a webview has. */
33
+ glspClientModuleOptions() {
34
+ return {};
35
+ }
36
+ }
37
+ exports.HydraniumGlspStarter = HydraniumGlspStarter;
38
+ //# sourceMappingURL=glsp-starter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"glsp-starter.js","sourceRoot":"","sources":["../../src/browser/glsp-starter.ts"],"names":[],"mappings":";AAAA;;;;;;;kFAOkF;;;AAGlF,yFAAuE;AACvE,wDAA8F;AAC9F,yCAA4C;AAE5C;;;;;;;;;GASG;AACH,0BAA2C,SAAQ,wCAAW;IACxC,yBAAyB;QACzC,OAAO;YACJ,GAAG,KAAK,CAAC,yBAAyB,EAAE;YACpC,IAAI,2BAAe,CAAC,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE,CACnD,IAAA,oCAAsB,EAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE,IAAI,CAAC,uBAAuB,EAAE,CAAC,CAC3F;SACH,CAAC;IACL,CAAC;IAED,iIAAiI;IACvH,uBAAuB;QAC9B,OAAO,EAAE,CAAC;IACb,CAAC;CACH"}
@@ -0,0 +1,10 @@
1
+ /********************************************************************************
2
+ * Copyright (c) 2026 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
+ export * from './glsp-starter';
10
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/browser/index.ts"],"names":[],"mappings":"AAAA;;;;;;;kFAOkF;AAElF,cAAc,gBAAgB,CAAC"}
@@ -0,0 +1,26 @@
1
+ "use strict";
2
+ /********************************************************************************
3
+ * Copyright (c) 2026 EclipseSource and others.
4
+ *
5
+ * This program and the accompanying materials are made available under the
6
+ * terms of the MIT License which is available in the project root.
7
+ *
8
+ * SPDX-License-Identifier: MIT
9
+ ********************************************************************************/
10
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
11
+ if (k2 === undefined) k2 = k;
12
+ var desc = Object.getOwnPropertyDescriptor(m, k);
13
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
14
+ desc = { enumerable: true, get: function() { return m[k]; } };
15
+ }
16
+ Object.defineProperty(o, k2, desc);
17
+ }) : (function(o, m, k, k2) {
18
+ if (k2 === undefined) k2 = k;
19
+ o[k2] = m[k];
20
+ }));
21
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
22
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
23
+ };
24
+ Object.defineProperty(exports, "__esModule", { value: true });
25
+ __exportStar(require("./glsp-starter"), exports);
26
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/browser/index.ts"],"names":[],"mappings":";AAAA;;;;;;;kFAOkF;;;;;;;;;;;;;;;;AAElF,iDAA+B"}
@@ -0,0 +1,15 @@
1
+ /********************************************************************************
2
+ * Copyright (c) 2026 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
+ * The class on the element the diagram mounts into. The extension host writes
11
+ * it into the webview document and the webview's stylesheet sizes it, so it
12
+ * lives on the neutral root both tiers reach.
13
+ */
14
+ export declare const DIAGRAM_CONTAINER_CLASS = "hydranium-diagram-container";
15
+ //# sourceMappingURL=diagram-container.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"diagram-container.d.ts","sourceRoot":"","sources":["../src/diagram-container.ts"],"names":[],"mappings":"AAAA;;;;;;;kFAOkF;AAElF;;;;GAIG;AACH,eAAO,MAAM,uBAAuB,gCAAgC,CAAC"}
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ /********************************************************************************
3
+ * Copyright (c) 2026 EclipseSource and others.
4
+ *
5
+ * This program and the accompanying materials are made available under the
6
+ * terms of the MIT License which is available in the project root.
7
+ *
8
+ * SPDX-License-Identifier: MIT
9
+ ********************************************************************************/
10
+ Object.defineProperty(exports, "__esModule", { value: true });
11
+ exports.DIAGRAM_CONTAINER_CLASS = void 0;
12
+ /**
13
+ * The class on the element the diagram mounts into. The extension host writes
14
+ * it into the webview document and the webview's stylesheet sizes it, so it
15
+ * lives on the neutral root both tiers reach.
16
+ */
17
+ exports.DIAGRAM_CONTAINER_CLASS = 'hydranium-diagram-container';
18
+ //# sourceMappingURL=diagram-container.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"diagram-container.js","sourceRoot":"","sources":["../src/diagram-container.ts"],"names":[],"mappings":";AAAA;;;;;;;kFAOkF;;;AAElF;;;;GAIG;AACU,QAAA,uBAAuB,GAAG,6BAA6B,CAAC"}
package/lib/index.d.ts ADDED
@@ -0,0 +1,10 @@
1
+ /********************************************************************************
2
+ * Copyright (c) 2026 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
+ export * from './diagram-container';
10
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;kFAOkF;AAKlF,cAAc,qBAAqB,CAAC"}
package/lib/index.js ADDED
@@ -0,0 +1,29 @@
1
+ "use strict";
2
+ /********************************************************************************
3
+ * Copyright (c) 2026 EclipseSource and others.
4
+ *
5
+ * This program and the accompanying materials are made available under the
6
+ * terms of the MIT License which is available in the project root.
7
+ *
8
+ * SPDX-License-Identifier: MIT
9
+ ********************************************************************************/
10
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
11
+ if (k2 === undefined) k2 = k;
12
+ var desc = Object.getOwnPropertyDescriptor(m, k);
13
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
14
+ desc = { enumerable: true, get: function() { return m[k]; } };
15
+ }
16
+ Object.defineProperty(o, k2, desc);
17
+ }) : (function(o, m, k, k2) {
18
+ if (k2 === undefined) k2 = k;
19
+ o[k2] = m[k];
20
+ }));
21
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
22
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
23
+ };
24
+ Object.defineProperty(exports, "__esModule", { value: true });
25
+ // Neutral: what both tiers name. `./node` is the extension host's, and never
26
+ // reaches `@eclipse-glsp/client`, whose stylesheets Node cannot load;
27
+ // `./browser` is the webview's.
28
+ __exportStar(require("./diagram-container"), exports);
29
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA;;;;;;;kFAOkF;;;;;;;;;;;;;;;;AAElF,6EAA6E;AAC7E,sEAAsE;AACtE,gCAAgC;AAChC,sDAAoC"}
@@ -0,0 +1,57 @@
1
+ /********************************************************************************
2
+ * Copyright (c) 2026 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
+ import { GlspEditorProvider, type GlspVscodeConnector } from '@eclipse-glsp/vscode-integration';
10
+ import * as vscode from 'vscode';
11
+ /**
12
+ * A custom editor whose webview hosts a GLSP diagram: the webview document,
13
+ * its Content-Security-Policy and the element the diagram mounts into.
14
+ *
15
+ * `GlspEditorProvider` already mints the per-view `clientId`, registers the
16
+ * client on the connector and routes save, revert and dirty state; a subclass
17
+ * names the diagram type, the bundle and the title.
18
+ *
19
+ * The connector's messenger reaches each webview's endpoint through the base
20
+ * class. `GlspVscodeConnector` constructs it with `ignoreHiddenViews: false`;
21
+ * a messenger handed to the connector must repeat that, or a hidden diagram tab
22
+ * misses every message sent to it.
23
+ */
24
+ export declare abstract class HydraniumGlspEditorProvider extends GlspEditorProvider {
25
+ protected readonly extensionUri: vscode.Uri;
26
+ /** The webview's script bundle, relative to the extension root. */
27
+ protected abstract readonly scriptPath: string;
28
+ /** The webview's stylesheet, relative to the extension root, if the bundler emits one. */
29
+ protected readonly stylePath?: string;
30
+ /** The webview document's title. */
31
+ protected abstract readonly title: string;
32
+ constructor(connector: GlspVscodeConnector, extensionUri: vscode.Uri);
33
+ /**
34
+ * Populate the webview for one diagram view.
35
+ *
36
+ * `clientId` is the connector's: the diagram widget mounts into
37
+ * `#<clientId>_container`, so a document naming another id loads and renders
38
+ * nothing.
39
+ */
40
+ setUpWebview(_document: vscode.CustomDocument, webviewPanel: vscode.WebviewPanel, _token: vscode.CancellationToken, clientId: string): void;
41
+ /**
42
+ * Where the webview may load from: the script's directory and the
43
+ * stylesheet's. VS Code blocks anything outside them without an error, so a
44
+ * stylesheet elsewhere would leave the diagram unstyled.
45
+ */
46
+ protected localResourceRoots(): vscode.Uri[];
47
+ /**
48
+ * The webview document.
49
+ *
50
+ * The CSP relaxations are sprotty's: `style-src 'unsafe-inline'` because it
51
+ * writes inline `style` attributes on the SVG, without which every element is
52
+ * laid out at the origin, and `font-src data:` for the codicon font a bundler
53
+ * inlines. `'unsafe-eval'` is not granted; nothing in a GLSP bundle needs it.
54
+ */
55
+ protected render(webview: vscode.Webview, clientId: string): string;
56
+ }
57
+ //# sourceMappingURL=glsp-editor-provider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"glsp-editor-provider.d.ts","sourceRoot":"","sources":["../../src/node/glsp-editor-provider.ts"],"names":[],"mappings":"AAAA;;;;;;;kFAOkF;AAElF,OAAO,EAAE,kBAAkB,EAAE,KAAK,mBAAmB,EAAE,MAAM,kCAAkC,CAAC;AAEhG,OAAO,KAAK,MAAM,MAAM,QAAQ,CAAC;AAGjC;;;;;;;;;;;;GAYG;AACH,8BAAsB,2BAA4B,SAAQ,kBAAkB;IAUtE,SAAS,CAAC,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC,GAAG;IAT9C,mEAAmE;IACnE,SAAS,CAAC,QAAQ,CAAC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC/C,0FAA0F;IAC1F,SAAS,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IACtC,oCAAoC;IACpC,SAAS,CAAC,QAAQ,CAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IAE1C,YACG,SAAS,EAAE,mBAAmB,EACX,YAAY,EAAE,MAAM,CAAC,GAAG,EAG7C;IAED;;;;;;OAMG;IACH,YAAY,CACT,SAAS,EAAE,MAAM,CAAC,cAAc,EAChC,YAAY,EAAE,MAAM,CAAC,YAAY,EACjC,MAAM,EAAE,MAAM,CAAC,iBAAiB,EAChC,QAAQ,EAAE,MAAM,GAChB,IAAI,CAIN;IAED;;;;OAIG;IACH,SAAS,CAAC,kBAAkB,IAAI,MAAM,CAAC,GAAG,EAAE,CAS3C;IAED;;;;;;;OAOG;IACH,SAAS,CAAC,MAAM,CAAC,OAAO,EAAE,MAAM,CAAC,OAAO,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAoBlE;CACH"}
@@ -0,0 +1,131 @@
1
+ "use strict";
2
+ /********************************************************************************
3
+ * Copyright (c) 2026 EclipseSource and others.
4
+ *
5
+ * This program and the accompanying materials are made available under the
6
+ * terms of the MIT License which is available in the project root.
7
+ *
8
+ * SPDX-License-Identifier: MIT
9
+ ********************************************************************************/
10
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
11
+ if (k2 === undefined) k2 = k;
12
+ var desc = Object.getOwnPropertyDescriptor(m, k);
13
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
14
+ desc = { enumerable: true, get: function() { return m[k]; } };
15
+ }
16
+ Object.defineProperty(o, k2, desc);
17
+ }) : (function(o, m, k, k2) {
18
+ if (k2 === undefined) k2 = k;
19
+ o[k2] = m[k];
20
+ }));
21
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
22
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
23
+ }) : function(o, v) {
24
+ o["default"] = v;
25
+ });
26
+ var __importStar = (this && this.__importStar) || (function () {
27
+ var ownKeys = function(o) {
28
+ ownKeys = Object.getOwnPropertyNames || function (o) {
29
+ var ar = [];
30
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
31
+ return ar;
32
+ };
33
+ return ownKeys(o);
34
+ };
35
+ return function (mod) {
36
+ if (mod && mod.__esModule) return mod;
37
+ var result = {};
38
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
39
+ __setModuleDefault(result, mod);
40
+ return result;
41
+ };
42
+ })();
43
+ Object.defineProperty(exports, "__esModule", { value: true });
44
+ exports.HydraniumGlspEditorProvider = void 0;
45
+ const vscode_integration_1 = require("@eclipse-glsp/vscode-integration");
46
+ const node_crypto_1 = require("node:crypto");
47
+ const vscode = __importStar(require("vscode"));
48
+ const diagram_container_1 = require("../diagram-container");
49
+ /**
50
+ * A custom editor whose webview hosts a GLSP diagram: the webview document,
51
+ * its Content-Security-Policy and the element the diagram mounts into.
52
+ *
53
+ * `GlspEditorProvider` already mints the per-view `clientId`, registers the
54
+ * client on the connector and routes save, revert and dirty state; a subclass
55
+ * names the diagram type, the bundle and the title.
56
+ *
57
+ * The connector's messenger reaches each webview's endpoint through the base
58
+ * class. `GlspVscodeConnector` constructs it with `ignoreHiddenViews: false`;
59
+ * a messenger handed to the connector must repeat that, or a hidden diagram tab
60
+ * misses every message sent to it.
61
+ */
62
+ class HydraniumGlspEditorProvider extends vscode_integration_1.GlspEditorProvider {
63
+ extensionUri;
64
+ /** The webview's stylesheet, relative to the extension root, if the bundler emits one. */
65
+ stylePath;
66
+ constructor(connector, extensionUri) {
67
+ super(connector);
68
+ this.extensionUri = extensionUri;
69
+ }
70
+ /**
71
+ * Populate the webview for one diagram view.
72
+ *
73
+ * `clientId` is the connector's: the diagram widget mounts into
74
+ * `#<clientId>_container`, so a document naming another id loads and renders
75
+ * nothing.
76
+ */
77
+ setUpWebview(_document, webviewPanel, _token, clientId) {
78
+ const webview = webviewPanel.webview;
79
+ webview.options = { enableScripts: true, localResourceRoots: this.localResourceRoots() };
80
+ webview.html = this.render(webview, clientId);
81
+ }
82
+ /**
83
+ * Where the webview may load from: the script's directory and the
84
+ * stylesheet's. VS Code blocks anything outside them without an error, so a
85
+ * stylesheet elsewhere would leave the diagram unstyled.
86
+ */
87
+ localResourceRoots() {
88
+ const roots = [vscode.Uri.joinPath(this.extensionUri, this.scriptPath, '..')];
89
+ if (this.stylePath) {
90
+ const styleRoot = vscode.Uri.joinPath(this.extensionUri, this.stylePath, '..');
91
+ if (styleRoot.path !== roots[0].path) {
92
+ roots.push(styleRoot);
93
+ }
94
+ }
95
+ return roots;
96
+ }
97
+ /**
98
+ * The webview document.
99
+ *
100
+ * The CSP relaxations are sprotty's: `style-src 'unsafe-inline'` because it
101
+ * writes inline `style` attributes on the SVG, without which every element is
102
+ * laid out at the origin, and `font-src data:` for the codicon font a bundler
103
+ * inlines. `'unsafe-eval'` is not granted; nothing in a GLSP bundle needs it.
104
+ */
105
+ render(webview, clientId) {
106
+ const script = webview.asWebviewUri(vscode.Uri.joinPath(this.extensionUri, this.scriptPath));
107
+ const style = this.stylePath ? webview.asWebviewUri(vscode.Uri.joinPath(this.extensionUri, this.stylePath)) : undefined;
108
+ const nonce = (0, node_crypto_1.randomBytes)(16).toString('base64');
109
+ return `<!DOCTYPE html>
110
+ <html lang="en">
111
+ <head>
112
+ <meta charset="UTF-8" />
113
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
114
+ <meta
115
+ http-equiv="Content-Security-Policy"
116
+ content="default-src 'none'; style-src ${webview.cspSource} 'unsafe-inline'; font-src ${webview.cspSource} data:; img-src ${webview.cspSource} data:; script-src 'nonce-${nonce}';"
117
+ />
118
+ <title>${escapeHtml(this.title)}</title>${style ? `\n <link rel="stylesheet" href="${style}" />` : ''}
119
+ </head>
120
+ <body>
121
+ <div id="${clientId}_container" class="${diagram_container_1.DIAGRAM_CONTAINER_CLASS}"></div>
122
+ <script nonce="${nonce}" src="${script}"></script>
123
+ </body>
124
+ </html>`;
125
+ }
126
+ }
127
+ exports.HydraniumGlspEditorProvider = HydraniumGlspEditorProvider;
128
+ function escapeHtml(text) {
129
+ return text.replace(/[&<>"']/g, character => `&#${character.charCodeAt(0)};`);
130
+ }
131
+ //# sourceMappingURL=glsp-editor-provider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"glsp-editor-provider.js","sourceRoot":"","sources":["../../src/node/glsp-editor-provider.ts"],"names":[],"mappings":";AAAA;;;;;;;kFAOkF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAElF,yEAAgG;AAChG,6CAA0C;AAC1C,MAAY,MAAM,mCAAe;AACjC,4DAA+D;AAE/D;;;;;;;;;;;;GAYG;AACH,iCAAkD,SAAQ,uCAAkB;IAUnD,YAAY;IAPlC,0FAA0F;IACvE,SAAS,CAAU;IAItC,YACG,SAA8B,EACX,YAAwB;QAE3C,KAAK,CAAC,SAAS,CAAC,CAAC;4BAFE,YAAY;IAGlC,CAAC;IAED;;;;;;OAMG;IACH,YAAY,CACT,SAAgC,EAChC,YAAiC,EACjC,MAAgC,EAChC,QAAgB;QAEhB,MAAM,OAAO,GAAG,YAAY,CAAC,OAAO,CAAC;QACrC,OAAO,CAAC,OAAO,GAAG,EAAE,aAAa,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,CAAC,kBAAkB,EAAE,EAAE,CAAC;QACzF,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;IACjD,CAAC;IAED;;;;OAIG;IACO,kBAAkB;QACzB,MAAM,KAAK,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,YAAY,EAAE,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC,CAAC;QAC9E,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;YAClB,MAAM,SAAS,GAAG,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,YAAY,EAAE,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;YAC/E,IAAI,SAAS,CAAC,IAAI,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;gBACpC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;YACzB,CAAC;QACJ,CAAC;QACD,OAAO,KAAK,CAAC;IAChB,CAAC;IAED;;;;;;;OAOG;IACO,MAAM,CAAC,OAAuB,EAAE,QAAgB;QACvD,MAAM,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,YAAY,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC;QAC7F,MAAM,KAAK,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,YAAY,CAAC,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,YAAY,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QACxH,MAAM,KAAK,GAAG,IAAA,yBAAW,EAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;QACjD,OAAO;;;;;;;kDAOqC,OAAO,CAAC,SAAS,8BAA8B,OAAO,CAAC,SAAS,mBAAmB,OAAO,CAAC,SAAS,6BAA6B,KAAK;;eAEzK,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,WAAW,KAAK,CAAC,CAAC,CAAC,wCAAwC,KAAK,MAAM,CAAC,CAAC,CAAC,EAAE;;;iBAG/F,QAAQ,sBAAsB,2CAAuB;uBAC/C,KAAK,UAAU,MAAM;;QAEpC,CAAC;IACN,CAAC;CACH;;AAED,SAAS,UAAU,CAAC,IAAY;IAC7B,OAAO,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,SAAS,CAAC,EAAE,CAAC,KAAK,SAAS,CAAC,UAAU,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;AACjF,CAAC"}
@@ -0,0 +1,46 @@
1
+ /********************************************************************************
2
+ * Copyright (c) 2026 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
+ import { SocketGlspVscodeServer } from '@eclipse-glsp/vscode-integration';
10
+ import { type Logger } from '@hydranium/protocol';
11
+ /** What {@link HydraniumGlspVscodeServer} needs beyond the GLSP client identity. */
12
+ export interface HydraniumGlspVscodeServerOptions {
13
+ readonly clientId: string;
14
+ readonly clientName: string;
15
+ /**
16
+ * Resolve the GLSP head's listening port, typically `findPort` from
17
+ * `@hydranium/client-vscode/node`. Called when the connection is opened, so
18
+ * the poll runs at `start()` rather than during activation.
19
+ */
20
+ readonly findPort: () => Promise<number>;
21
+ /** Where the connection to the head logs its protocol faults. */
22
+ readonly logger: Logger;
23
+ }
24
+ /**
25
+ * The GLSP head reached over its ephemeral socket, with the port discovered
26
+ * rather than configured.
27
+ *
28
+ * `SocketGlspVscodeServer` takes a fixed `connectionOptions` at construction,
29
+ * but the head's port is assigned when it binds and published as an LSP
30
+ * request. Awaiting it in `activate` would block activation behind a poll that
31
+ * can take seconds, even for a user who never opens a diagram, so the lookup
32
+ * moves to `createConnection`, which the base class calls from `start()`.
33
+ * The `connectionOptions` handed to `super` is never read, and is an unusable
34
+ * port so that a refactor reintroducing the base implementation fails loudly
35
+ * instead of dialling something.
36
+ *
37
+ * Report a failure off `onReady`, not off `start()`: `start()` routes its own
38
+ * error into the readiness promise and resolves anyway.
39
+ */
40
+ export declare class HydraniumGlspVscodeServer extends SocketGlspVscodeServer {
41
+ protected readonly findPort: () => Promise<number>;
42
+ protected readonly logger: Logger;
43
+ constructor(options: HydraniumGlspVscodeServerOptions);
44
+ protected createConnection(): ReturnType<SocketGlspVscodeServer['createConnection']>;
45
+ }
46
+ //# sourceMappingURL=glsp-vscode-server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"glsp-vscode-server.d.ts","sourceRoot":"","sources":["../../src/node/glsp-vscode-server.ts"],"names":[],"mappings":"AAAA;;;;;;;kFAOkF;AAElF,OAAO,EAAE,sBAAsB,EAAE,MAAM,kCAAkC,CAAC;AAC1E,OAAO,EAAoB,KAAK,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAIpE,oFAAoF;AACpF,MAAM,WAAW,gCAAgC;IAC9C,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B;;;;OAIG;IACH,QAAQ,CAAC,QAAQ,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,CAAC;IACzC,iEAAiE;IACjE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CAC1B;AAED;;;;;;;;;;;;;;;GAeG;AACH,qBAAa,yBAA0B,SAAQ,sBAAsB;IAClE,SAAS,CAAC,QAAQ,CAAC,QAAQ,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,CAAC;IACnD,SAAS,CAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IAElC,YAAY,OAAO,EAAE,gCAAgC,EAQpD;IAED,UAAyB,gBAAgB,IAAI,UAAU,CAAC,sBAAsB,CAAC,kBAAkB,CAAC,CAAC,CAalG;CACH"}
@@ -0,0 +1,93 @@
1
+ "use strict";
2
+ /********************************************************************************
3
+ * Copyright (c) 2026 EclipseSource and others.
4
+ *
5
+ * This program and the accompanying materials are made available under the
6
+ * terms of the MIT License which is available in the project root.
7
+ *
8
+ * SPDX-License-Identifier: MIT
9
+ ********************************************************************************/
10
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
11
+ if (k2 === undefined) k2 = k;
12
+ var desc = Object.getOwnPropertyDescriptor(m, k);
13
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
14
+ desc = { enumerable: true, get: function() { return m[k]; } };
15
+ }
16
+ Object.defineProperty(o, k2, desc);
17
+ }) : (function(o, m, k, k2) {
18
+ if (k2 === undefined) k2 = k;
19
+ o[k2] = m[k];
20
+ }));
21
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
22
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
23
+ }) : function(o, v) {
24
+ o["default"] = v;
25
+ });
26
+ var __importStar = (this && this.__importStar) || (function () {
27
+ var ownKeys = function(o) {
28
+ ownKeys = Object.getOwnPropertyNames || function (o) {
29
+ var ar = [];
30
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
31
+ return ar;
32
+ };
33
+ return ownKeys(o);
34
+ };
35
+ return function (mod) {
36
+ if (mod && mod.__esModule) return mod;
37
+ var result = {};
38
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
39
+ __setModuleDefault(result, mod);
40
+ return result;
41
+ };
42
+ })();
43
+ Object.defineProperty(exports, "__esModule", { value: true });
44
+ exports.HydraniumGlspVscodeServer = void 0;
45
+ const vscode_integration_1 = require("@eclipse-glsp/vscode-integration");
46
+ const protocol_1 = require("@hydranium/protocol");
47
+ const net = __importStar(require("node:net"));
48
+ const node_1 = require("vscode-jsonrpc/node");
49
+ /**
50
+ * The GLSP head reached over its ephemeral socket, with the port discovered
51
+ * rather than configured.
52
+ *
53
+ * `SocketGlspVscodeServer` takes a fixed `connectionOptions` at construction,
54
+ * but the head's port is assigned when it binds and published as an LSP
55
+ * request. Awaiting it in `activate` would block activation behind a poll that
56
+ * can take seconds, even for a user who never opens a diagram, so the lookup
57
+ * moves to `createConnection`, which the base class calls from `start()`.
58
+ * The `connectionOptions` handed to `super` is never read, and is an unusable
59
+ * port so that a refactor reintroducing the base implementation fails loudly
60
+ * instead of dialling something.
61
+ *
62
+ * Report a failure off `onReady`, not off `start()`: `start()` routes its own
63
+ * error into the readiness promise and resolves anyway.
64
+ */
65
+ class HydraniumGlspVscodeServer extends vscode_integration_1.SocketGlspVscodeServer {
66
+ findPort;
67
+ logger;
68
+ constructor(options) {
69
+ super({
70
+ clientId: options.clientId,
71
+ clientName: options.clientName,
72
+ connectionOptions: { port: 0 }
73
+ });
74
+ this.findPort = options.findPort;
75
+ this.logger = options.logger;
76
+ }
77
+ async createConnection() {
78
+ const port = await this.findPort();
79
+ // `127.0.0.1`, not `localhost`, and it has to match the head: `startGlspServer`
80
+ // binds `127.0.0.1` by default, so on a dual-stack machine where `localhost`
81
+ // resolves to `::1` first the dial fails as ECONNREFUSED with nothing in the
82
+ // message naming the address family as the cause.
83
+ // Built here rather than by the base's `createSocketConnection`, which
84
+ // passes no logger. GLSP's client sends typed messages built by
85
+ // `@eclipse-glsp/protocol`'s copy of `vscode-jsonrpc`, so they go by name.
86
+ const socket = new net.Socket();
87
+ const connection = (0, node_1.createMessageConnection)(new node_1.SocketMessageReader(socket), new node_1.SocketMessageWriter(socket), this.logger);
88
+ socket.connect({ port, host: '127.0.0.1' });
89
+ return (0, protocol_1.sendByMethodName)(connection);
90
+ }
91
+ }
92
+ exports.HydraniumGlspVscodeServer = HydraniumGlspVscodeServer;
93
+ //# sourceMappingURL=glsp-vscode-server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"glsp-vscode-server.js","sourceRoot":"","sources":["../../src/node/glsp-vscode-server.ts"],"names":[],"mappings":";AAAA;;;;;;;kFAOkF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAElF,yEAA0E;AAC1E,kDAAoE;AACpE,MAAY,GAAG,qCAAiB;AAChC,8CAAwG;AAgBxG;;;;;;;;;;;;;;;GAeG;AACH,+BAAuC,SAAQ,2CAAsB;IAC/C,QAAQ,CAAwB;IAChC,MAAM,CAAS;IAElC,YAAY,OAAyC;QAClD,KAAK,CAAC;YACH,QAAQ,EAAE,OAAO,CAAC,QAAQ;YAC1B,UAAU,EAAE,OAAO,CAAC,UAAU;YAC9B,iBAAiB,EAAE,EAAE,IAAI,EAAE,CAAC,EAAE;SAChC,CAAC,CAAC;QACH,IAAI,CAAC,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC;QACjC,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAChC,CAAC;IAEkB,KAAK,CAAC,gBAAgB;QACtC,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,QAAQ,EAAE,CAAC;QACnC,gFAAgF;QAChF,6EAA6E;QAC7E,6EAA6E;QAC7E,kDAAkD;QAClD,uEAAuE;QACvE,gEAAgE;QAChE,2EAA2E;QAC3E,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,MAAM,EAAE,CAAC;QAChC,MAAM,UAAU,GAAG,IAAA,8BAAuB,EAAC,IAAI,0BAAmB,CAAC,MAAM,CAAC,EAAE,IAAI,0BAAmB,CAAC,MAAM,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;QAC1H,MAAM,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC,CAAC;QAC5C,OAAO,IAAA,2BAAgB,EAAC,UAAU,CAAC,CAAC;IACvC,CAAC;CACH"}
@@ -0,0 +1,11 @@
1
+ /********************************************************************************
2
+ * Copyright (c) 2026 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
+ export * from './glsp-editor-provider';
10
+ export * from './glsp-vscode-server';
11
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/node/index.ts"],"names":[],"mappings":"AAAA;;;;;;;kFAOkF;AAElF,cAAc,wBAAwB,CAAC;AACvC,cAAc,sBAAsB,CAAC"}
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+ /********************************************************************************
3
+ * Copyright (c) 2026 EclipseSource and others.
4
+ *
5
+ * This program and the accompanying materials are made available under the
6
+ * terms of the MIT License which is available in the project root.
7
+ *
8
+ * SPDX-License-Identifier: MIT
9
+ ********************************************************************************/
10
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
11
+ if (k2 === undefined) k2 = k;
12
+ var desc = Object.getOwnPropertyDescriptor(m, k);
13
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
14
+ desc = { enumerable: true, get: function() { return m[k]; } };
15
+ }
16
+ Object.defineProperty(o, k2, desc);
17
+ }) : (function(o, m, k, k2) {
18
+ if (k2 === undefined) k2 = k;
19
+ o[k2] = m[k];
20
+ }));
21
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
22
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
23
+ };
24
+ Object.defineProperty(exports, "__esModule", { value: true });
25
+ __exportStar(require("./glsp-editor-provider"), exports);
26
+ __exportStar(require("./glsp-vscode-server"), exports);
27
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/node/index.ts"],"names":[],"mappings":";AAAA;;;;;;;kFAOkF;;;;;;;;;;;;;;;;AAElF,yDAAuC;AACvC,uDAAqC"}
package/package.json CHANGED
@@ -1,6 +1,91 @@
1
1
  {
2
2
  "name": "@hydranium/glsp-client-vscode",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
6
- }
3
+ "version": "1.0.0-next",
4
+ "description": "VS Code client primitives for GLSP heads built on @hydranium/glsp-server: the extension host's GLSP server over a discovered socket port and a custom editor whose webview hosts the diagram, and a webview starter that binds @hydranium/glsp-client's host-neutral classes; companion of @hydranium/glsp-server.",
5
+ "keywords": [
6
+ "diagram",
7
+ "glsp",
8
+ "hydranium",
9
+ "langium",
10
+ "language-server",
11
+ "lsp",
12
+ "vscode",
13
+ "vscode-extension",
14
+ "webview"
15
+ ],
16
+ "homepage": "https://github.com/eclipse-emfcloud/hydranium/tree/main/packages/glsp-client-vscode",
17
+ "bugs": {
18
+ "url": "https://github.com/eclipse-emfcloud/hydranium/issues"
19
+ },
20
+ "license": "MIT",
21
+ "author": {
22
+ "name": "Hydranium Team"
23
+ },
24
+ "repository": {
25
+ "type": "git",
26
+ "url": "https://github.com/eclipse-emfcloud/hydranium.git",
27
+ "directory": "packages/glsp-client-vscode"
28
+ },
29
+ "files": [
30
+ "lib",
31
+ "src",
32
+ "!lib/**/*.tsbuildinfo"
33
+ ],
34
+ "sideEffects": false,
35
+ "main": "lib/index.js",
36
+ "types": "lib/index.d.ts",
37
+ "exports": {
38
+ ".": {
39
+ "types": "./lib/index.d.ts",
40
+ "default": "./lib/index.js"
41
+ },
42
+ "./browser": {
43
+ "types": "./lib/browser/index.d.ts",
44
+ "default": "./lib/browser/index.js"
45
+ },
46
+ "./node": {
47
+ "types": "./lib/node/index.d.ts",
48
+ "default": "./lib/node/index.js"
49
+ }
50
+ },
51
+ "publishConfig": {
52
+ "access": "public"
53
+ },
54
+ "scripts": {
55
+ "build": "tsc -b",
56
+ "clean": "rimraf lib tsconfig.tsbuildinfo",
57
+ "lint": "oxlint --format stylish --config ../../oxlint.config.cjs src test --max-warnings 0",
58
+ "prepack": "node -e \"const m=require('./package.json'),fs=require('node:fs');const missing=[m.main,...Object.values(m.bin||{})].filter(entry=>entry&&!fs.existsSync(entry));if(missing.length){console.error('prepack '+m.name+': not built ('+missing.join(', ')+' missing). Run the build before packing: a files entry that matches nothing is skipped silently, so the tarball would ship src only.');process.exit(1);}\"",
59
+ "test": "npm run typecheck:test && vitest run",
60
+ "typecheck:test": "tsc --noEmit -p tsconfig.test.json",
61
+ "watch": "tsc -b -w --preserveWatchOutput"
62
+ },
63
+ "devDependencies": {
64
+ "@eclipse-glsp/client": "2.7.0",
65
+ "@eclipse-glsp/vscode-integration": "2.7.0",
66
+ "@eclipse-glsp/vscode-integration-webview": "2.7.0",
67
+ "@hydranium/glsp-client": "1.0.0-next",
68
+ "@hydranium/protocol": "1.0.0-next",
69
+ "@types/node": "^22.0.0",
70
+ "@types/vscode": "^1.101.0",
71
+ "inversify": "6.2.2",
72
+ "rimraf": "^5.0.0",
73
+ "typescript": "^7.0.2",
74
+ "vscode-jsonrpc": "9.0.0"
75
+ },
76
+ "peerDependencies": {
77
+ "@eclipse-glsp/client": "^2.6.0",
78
+ "@eclipse-glsp/vscode-integration": "^2.6.0",
79
+ "@eclipse-glsp/vscode-integration-webview": "^2.6.0",
80
+ "@hydranium/glsp-client": "^1.0.0-next",
81
+ "@hydranium/protocol": "^1.0.0-next",
82
+ "inversify": "^6.0.0",
83
+ "vscode-jsonrpc": "^9.0.0"
84
+ },
85
+ "engines": {
86
+ "node": ">=22.13",
87
+ "vscode": "^1.101.0"
88
+ },
89
+ "//peerDependencies": "`vscode-jsonrpc` takes a caret, so the framework shares the transport the LSP connection resolves, which an `init` scaffold pins: each `vscode-languageserver-protocol` release pins its transport exactly, so an exact peer would name a copy a fresh install rarely holds. The caret excludes 8.x, so a tree whose top holds GLSP's copy fails the peer with a named ERESOLVE warning, an error under `--strict-peer-deps`, rather than resolving silently. No peer reaches a NESTED copy, such as GLSP's or one the LSP packages nest. The wire compares message types and `ResponseError`s by copy identity, so the framework sends typed messages by method name and recognises errors with `isResponseError` rather than `instanceof`.",
90
+ "//prepack": "The publish guard, a `prepack` rather than a `prepare`: `prepack` runs only when a tarball is made (`npm pack`, `npm publish`) and never on install, so it cannot break the install it has no business touching. What it defends against: `files` lists `lib`, `lib` is gitignored, and a `files` entry matching nothing is skipped SILENTLY — so `npm publish` from an unbuilt tree emits a tarball of `src` and nothing else, with no error."
91
+ }
@@ -0,0 +1,39 @@
1
+ /********************************************************************************
2
+ * Copyright (c) 2026 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 type { ContainerConfiguration } from '@eclipse-glsp/client';
11
+ import { GLSPStarter } from '@eclipse-glsp/vscode-integration-webview';
12
+ import { createGlspClientModule, type GlspClientModuleOptions } from '@hydranium/glsp-client';
13
+ import { ContainerModule } from 'inversify';
14
+
15
+ /**
16
+ * The diagram webview's starter: GLSP's handshake with the extension host,
17
+ * with the framework's client module among the modules the container is built
18
+ * from.
19
+ *
20
+ * The module follows the host's own, since it replaces tokens they bind, and
21
+ * comes before whatever `createContainer` appends: GLSP's model and view
22
+ * registries give an element type to the module that registers it last, so a
23
+ * subclass appends its diagram definition last.
24
+ */
25
+ export abstract class HydraniumGlspStarter extends GLSPStarter {
26
+ protected override getContainerConfiguration(): ContainerConfiguration {
27
+ return [
28
+ ...super.getContainerConfiguration(),
29
+ new ContainerModule((bind, unbind, isBound, rebind) =>
30
+ createGlspClientModule({ bind, unbind, isBound, rebind }, this.glspClientModuleOptions())
31
+ )
32
+ ];
33
+ }
34
+
35
+ /** Options for the framework's client module. Without a logger it logs to the webview's console, the only sink a webview has. */
36
+ protected glspClientModuleOptions(): GlspClientModuleOptions {
37
+ return {};
38
+ }
39
+ }
@@ -0,0 +1,10 @@
1
+ /********************************************************************************
2
+ * Copyright (c) 2026 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
+ export * from './glsp-starter';
@@ -0,0 +1,15 @@
1
+ /********************************************************************************
2
+ * Copyright (c) 2026 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
+ /**
11
+ * The class on the element the diagram mounts into. The extension host writes
12
+ * it into the webview document and the webview's stylesheet sizes it, so it
13
+ * lives on the neutral root both tiers reach.
14
+ */
15
+ export const DIAGRAM_CONTAINER_CLASS = 'hydranium-diagram-container';
package/src/index.ts ADDED
@@ -0,0 +1,13 @@
1
+ /********************************************************************************
2
+ * Copyright (c) 2026 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
+ // Neutral: what both tiers name. `./node` is the extension host's, and never
11
+ // reaches `@eclipse-glsp/client`, whose stylesheets Node cannot load;
12
+ // `./browser` is the webview's.
13
+ export * from './diagram-container';
@@ -0,0 +1,110 @@
1
+ /********************************************************************************
2
+ * Copyright (c) 2026 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 { GlspEditorProvider, type GlspVscodeConnector } from '@eclipse-glsp/vscode-integration';
11
+ import { randomBytes } from 'node:crypto';
12
+ import * as vscode from 'vscode';
13
+ import { DIAGRAM_CONTAINER_CLASS } from '../diagram-container';
14
+
15
+ /**
16
+ * A custom editor whose webview hosts a GLSP diagram: the webview document,
17
+ * its Content-Security-Policy and the element the diagram mounts into.
18
+ *
19
+ * `GlspEditorProvider` already mints the per-view `clientId`, registers the
20
+ * client on the connector and routes save, revert and dirty state; a subclass
21
+ * names the diagram type, the bundle and the title.
22
+ *
23
+ * The connector's messenger reaches each webview's endpoint through the base
24
+ * class. `GlspVscodeConnector` constructs it with `ignoreHiddenViews: false`;
25
+ * a messenger handed to the connector must repeat that, or a hidden diagram tab
26
+ * misses every message sent to it.
27
+ */
28
+ export abstract class HydraniumGlspEditorProvider extends GlspEditorProvider {
29
+ /** The webview's script bundle, relative to the extension root. */
30
+ protected abstract readonly scriptPath: string;
31
+ /** The webview's stylesheet, relative to the extension root, if the bundler emits one. */
32
+ protected readonly stylePath?: string;
33
+ /** The webview document's title. */
34
+ protected abstract readonly title: string;
35
+
36
+ constructor(
37
+ connector: GlspVscodeConnector,
38
+ protected readonly extensionUri: vscode.Uri
39
+ ) {
40
+ super(connector);
41
+ }
42
+
43
+ /**
44
+ * Populate the webview for one diagram view.
45
+ *
46
+ * `clientId` is the connector's: the diagram widget mounts into
47
+ * `#<clientId>_container`, so a document naming another id loads and renders
48
+ * nothing.
49
+ */
50
+ setUpWebview(
51
+ _document: vscode.CustomDocument,
52
+ webviewPanel: vscode.WebviewPanel,
53
+ _token: vscode.CancellationToken,
54
+ clientId: string
55
+ ): void {
56
+ const webview = webviewPanel.webview;
57
+ webview.options = { enableScripts: true, localResourceRoots: this.localResourceRoots() };
58
+ webview.html = this.render(webview, clientId);
59
+ }
60
+
61
+ /**
62
+ * Where the webview may load from: the script's directory and the
63
+ * stylesheet's. VS Code blocks anything outside them without an error, so a
64
+ * stylesheet elsewhere would leave the diagram unstyled.
65
+ */
66
+ protected localResourceRoots(): vscode.Uri[] {
67
+ const roots = [vscode.Uri.joinPath(this.extensionUri, this.scriptPath, '..')];
68
+ if (this.stylePath) {
69
+ const styleRoot = vscode.Uri.joinPath(this.extensionUri, this.stylePath, '..');
70
+ if (styleRoot.path !== roots[0].path) {
71
+ roots.push(styleRoot);
72
+ }
73
+ }
74
+ return roots;
75
+ }
76
+
77
+ /**
78
+ * The webview document.
79
+ *
80
+ * The CSP relaxations are sprotty's: `style-src 'unsafe-inline'` because it
81
+ * writes inline `style` attributes on the SVG, without which every element is
82
+ * laid out at the origin, and `font-src data:` for the codicon font a bundler
83
+ * inlines. `'unsafe-eval'` is not granted; nothing in a GLSP bundle needs it.
84
+ */
85
+ protected render(webview: vscode.Webview, clientId: string): string {
86
+ const script = webview.asWebviewUri(vscode.Uri.joinPath(this.extensionUri, this.scriptPath));
87
+ const style = this.stylePath ? webview.asWebviewUri(vscode.Uri.joinPath(this.extensionUri, this.stylePath)) : undefined;
88
+ const nonce = randomBytes(16).toString('base64');
89
+ return `<!DOCTYPE html>
90
+ <html lang="en">
91
+ <head>
92
+ <meta charset="UTF-8" />
93
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
94
+ <meta
95
+ http-equiv="Content-Security-Policy"
96
+ content="default-src 'none'; style-src ${webview.cspSource} 'unsafe-inline'; font-src ${webview.cspSource} data:; img-src ${webview.cspSource} data:; script-src 'nonce-${nonce}';"
97
+ />
98
+ <title>${escapeHtml(this.title)}</title>${style ? `\n <link rel="stylesheet" href="${style}" />` : ''}
99
+ </head>
100
+ <body>
101
+ <div id="${clientId}_container" class="${DIAGRAM_CONTAINER_CLASS}"></div>
102
+ <script nonce="${nonce}" src="${script}"></script>
103
+ </body>
104
+ </html>`;
105
+ }
106
+ }
107
+
108
+ function escapeHtml(text: string): string {
109
+ return text.replace(/[&<>"']/g, character => `&#${character.charCodeAt(0)};`);
110
+ }
@@ -0,0 +1,73 @@
1
+ /********************************************************************************
2
+ * Copyright (c) 2026 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 { SocketGlspVscodeServer } from '@eclipse-glsp/vscode-integration';
11
+ import { sendByMethodName, type Logger } from '@hydranium/protocol';
12
+ import * as net from 'node:net';
13
+ import { createMessageConnection, SocketMessageReader, SocketMessageWriter } from 'vscode-jsonrpc/node';
14
+
15
+ /** What {@link HydraniumGlspVscodeServer} needs beyond the GLSP client identity. */
16
+ export interface HydraniumGlspVscodeServerOptions {
17
+ readonly clientId: string;
18
+ readonly clientName: string;
19
+ /**
20
+ * Resolve the GLSP head's listening port, typically `findPort` from
21
+ * `@hydranium/client-vscode/node`. Called when the connection is opened, so
22
+ * the poll runs at `start()` rather than during activation.
23
+ */
24
+ readonly findPort: () => Promise<number>;
25
+ /** Where the connection to the head logs its protocol faults. */
26
+ readonly logger: Logger;
27
+ }
28
+
29
+ /**
30
+ * The GLSP head reached over its ephemeral socket, with the port discovered
31
+ * rather than configured.
32
+ *
33
+ * `SocketGlspVscodeServer` takes a fixed `connectionOptions` at construction,
34
+ * but the head's port is assigned when it binds and published as an LSP
35
+ * request. Awaiting it in `activate` would block activation behind a poll that
36
+ * can take seconds, even for a user who never opens a diagram, so the lookup
37
+ * moves to `createConnection`, which the base class calls from `start()`.
38
+ * The `connectionOptions` handed to `super` is never read, and is an unusable
39
+ * port so that a refactor reintroducing the base implementation fails loudly
40
+ * instead of dialling something.
41
+ *
42
+ * Report a failure off `onReady`, not off `start()`: `start()` routes its own
43
+ * error into the readiness promise and resolves anyway.
44
+ */
45
+ export class HydraniumGlspVscodeServer extends SocketGlspVscodeServer {
46
+ protected readonly findPort: () => Promise<number>;
47
+ protected readonly logger: Logger;
48
+
49
+ constructor(options: HydraniumGlspVscodeServerOptions) {
50
+ super({
51
+ clientId: options.clientId,
52
+ clientName: options.clientName,
53
+ connectionOptions: { port: 0 }
54
+ });
55
+ this.findPort = options.findPort;
56
+ this.logger = options.logger;
57
+ }
58
+
59
+ protected override async createConnection(): ReturnType<SocketGlspVscodeServer['createConnection']> {
60
+ const port = await this.findPort();
61
+ // `127.0.0.1`, not `localhost`, and it has to match the head: `startGlspServer`
62
+ // binds `127.0.0.1` by default, so on a dual-stack machine where `localhost`
63
+ // resolves to `::1` first the dial fails as ECONNREFUSED with nothing in the
64
+ // message naming the address family as the cause.
65
+ // Built here rather than by the base's `createSocketConnection`, which
66
+ // passes no logger. GLSP's client sends typed messages built by
67
+ // `@eclipse-glsp/protocol`'s copy of `vscode-jsonrpc`, so they go by name.
68
+ const socket = new net.Socket();
69
+ const connection = createMessageConnection(new SocketMessageReader(socket), new SocketMessageWriter(socket), this.logger);
70
+ socket.connect({ port, host: '127.0.0.1' });
71
+ return sendByMethodName(connection);
72
+ }
73
+ }
@@ -0,0 +1,11 @@
1
+ /********************************************************************************
2
+ * Copyright (c) 2026 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
+ export * from './glsp-editor-provider';
11
+ export * from './glsp-vscode-server';