@hydranium/data-client-theia 1.0.0-next.62 → 1.0.0-next.66
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +21 -22
- package/lib/browser/channel-connection.d.ts +2 -2
- package/lib/browser/index.d.ts +0 -3
- package/lib/browser/index.d.ts.map +1 -1
- package/lib/browser/index.js +0 -3
- package/lib/browser/index.js.map +1 -1
- package/lib/node/connection-container-module.d.ts +5 -4
- package/lib/node/connection-container-module.d.ts.map +1 -1
- package/lib/node/connection-container-module.js +5 -4
- package/lib/node/connection-container-module.js.map +1 -1
- package/package.json +7 -7
- package/src/browser/channel-connection.ts +2 -2
- package/src/browser/index.ts +0 -3
- package/src/node/connection-container-module.ts +5 -4
- package/lib/browser/data-service-frontend.d.ts +0 -96
- package/lib/browser/data-service-frontend.d.ts.map +0 -1
- package/lib/browser/data-service-frontend.js +0 -148
- package/lib/browser/data-service-frontend.js.map +0 -1
- package/lib/browser/diagnostics-data-service-frontend.d.ts +0 -35
- package/lib/browser/diagnostics-data-service-frontend.d.ts.map +0 -1
- package/lib/browser/diagnostics-data-service-frontend.js +0 -54
- package/lib/browser/diagnostics-data-service-frontend.js.map +0 -1
- package/lib/browser/references-data-service-frontend.d.ts +0 -45
- package/lib/browser/references-data-service-frontend.d.ts.map +0 -1
- package/lib/browser/references-data-service-frontend.js +0 -55
- package/lib/browser/references-data-service-frontend.js.map +0 -1
- package/src/browser/data-service-frontend.ts +0 -177
- package/src/browser/diagnostics-data-service-frontend.ts +0 -70
- package/src/browser/references-data-service-frontend.ts +0 -70
package/README.md
CHANGED
|
@@ -6,10 +6,12 @@ Theia client primitives for the hydranium **data head** — the companion of
|
|
|
6
6
|
|
|
7
7
|
The data head's frontend speaks the data server's own `vscode-jsonrpc` protocol
|
|
8
8
|
over a channel that the Theia backend relays byte-for-byte onto the server's
|
|
9
|
-
socket. This package is
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
9
|
+
socket. This package is the Theia-specific half of that arrangement: the browser-side
|
|
10
|
+
transport and the backend-side connection handler and forwarder. Everything above
|
|
11
|
+
the transport — the connection, its sessions, the event fan-out — is host-neutral
|
|
12
|
+
and lives in `@hydranium/protocol/client`. Install it if a Theia application needs
|
|
13
|
+
form editors, trees, or code-gen driven from the live AST rather than from LSP
|
|
14
|
+
text edits.
|
|
13
15
|
|
|
14
16
|
## What it gives you
|
|
15
17
|
|
|
@@ -22,19 +24,13 @@ code-gen driven from the live AST rather than from LSP text edits.
|
|
|
22
24
|
channel ever arrives on its own. Retries follow `DEFAULT_RECONNECT_DELAYS`,
|
|
23
25
|
escalating per consecutive loss and resetting after
|
|
24
26
|
`RECONNECT_ESCALATION_RESET_MS`.
|
|
25
|
-
- **`
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
-
|
|
32
|
-
**`AbstractReferencesDataServiceFrontend`** — the same base specialised for the
|
|
33
|
-
two protocol fragments an adopter most often keeps: each diagnostics
|
|
34
|
-
(`dumpServerState`, `writeHeapSnapshot`, `dumpPodMemory`, the profiling and
|
|
35
|
-
latency calls) and each reference method is implemented as a readiness-gated
|
|
36
|
-
pass-through, so you do not hand-write identical one-line bodies. They are
|
|
37
|
-
deliberately independent bases rather than chained.
|
|
27
|
+
- **`ChannelDataPort`** — the `DataPort` implementation over a Theia frontend
|
|
28
|
+
channel, and the only class a Theia adopter has to write against. Subclass it
|
|
29
|
+
with a `servicePath`; it supplies the channel, the workspace gate, the
|
|
30
|
+
reconnect signal and the `MessageService` error sink. Bind one per service path
|
|
31
|
+
in singleton scope. Hand it to `DataConnectionWithEvents` (from
|
|
32
|
+
`@hydranium/protocol`) and the connection, its sessions and its event fan-out
|
|
33
|
+
are the host-neutral ones every other shell uses.
|
|
38
34
|
- **`EmitterDataClient`** (on `./common`, not `./browser`) — the default
|
|
39
35
|
client-side implementation of the data protocol's inbound notifications,
|
|
40
36
|
fanning each one out to a Theia `Event`: `onDidUpdateDocument`,
|
|
@@ -81,17 +77,20 @@ This package declares no `theiaExtensions` — it is a library your own Theia
|
|
|
81
77
|
extension builds on. That extension's `package.json` declares the entries, and
|
|
82
78
|
each entry names one frontend/backend module pair:
|
|
83
79
|
|
|
84
|
-
- the **frontend** module binds your `
|
|
85
|
-
for the diagnostics commands,
|
|
80
|
+
- the **frontend** module binds your `ChannelDataPort` subclass and the
|
|
81
|
+
connection over it, both in singleton scope (and, for the diagnostics commands,
|
|
82
|
+
calls `bindHostDiagnostics`);
|
|
86
83
|
- the **backend** module is typically a one-liner:
|
|
87
84
|
`export default createDataServerConnectionContainerModule(MyHandler)`, where
|
|
88
85
|
`MyHandler` extends `DataServerConnectionHandler`.
|
|
89
86
|
|
|
90
87
|
More than one handler is the normal case, not an exotic one. Theia keys a
|
|
91
88
|
frontend channel by its service path and refuses a second channel on a path
|
|
92
|
-
already open, so every frontend abstraction reaching the data head
|
|
93
|
-
`servicePath` — while the shared `portCommand` still names
|
|
94
|
-
behind them all.
|
|
89
|
+
already open, so every frontend abstraction reaching the data head on its own
|
|
90
|
+
channel needs its own `servicePath` — while the shared `portCommand` still names
|
|
91
|
+
the one server process behind them all. Several participants over ONE channel
|
|
92
|
+
need no second handler: that is what `DataConnection`'s sessions are for, and it
|
|
93
|
+
is the cheaper arrangement.
|
|
95
94
|
|
|
96
95
|
The refusal is silent, which is what makes it expensive: the loser's promise is
|
|
97
96
|
left unsettled rather than rejected, so a frontend that shared a path hangs on
|
|
@@ -107,8 +107,8 @@ export interface ChannelConnectionHandle {
|
|
|
107
107
|
/**
|
|
108
108
|
* The current connection. Read it per use rather than caching it: after a
|
|
109
109
|
* reconnect this returns a NEW promise, and a cached one resolves to the
|
|
110
|
-
* dead connection forever. The same reasoning makes
|
|
111
|
-
*
|
|
110
|
+
* dead connection forever. The same reasoning makes `RpcConnection` rebuild
|
|
111
|
+
* its proxy per generation rather than hold one.
|
|
112
112
|
*/
|
|
113
113
|
readonly current: Promise<MessageConnection>;
|
|
114
114
|
/**
|
package/lib/browser/index.d.ts
CHANGED
|
@@ -8,9 +8,6 @@
|
|
|
8
8
|
********************************************************************************/
|
|
9
9
|
export * from './channel-connection';
|
|
10
10
|
export * from './channel-data-port';
|
|
11
|
-
export * from './data-service-frontend';
|
|
12
|
-
export * from './diagnostics-data-service-frontend';
|
|
13
11
|
export * from './host-diagnostics-frontend';
|
|
14
|
-
export * from './references-data-service-frontend';
|
|
15
12
|
export * from './workspace-gate';
|
|
16
13
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/browser/index.ts"],"names":[],"mappings":"AAAA;;;;;;;kFAOkF;AAElF,cAAc,sBAAsB,CAAC;AACrC,cAAc,qBAAqB,CAAC;AACpC,cAAc,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/browser/index.ts"],"names":[],"mappings":"AAAA;;;;;;;kFAOkF;AAElF,cAAc,sBAAsB,CAAC;AACrC,cAAc,qBAAqB,CAAC;AACpC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,kBAAkB,CAAC"}
|
package/lib/browser/index.js
CHANGED
|
@@ -24,9 +24,6 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
24
24
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
25
25
|
__exportStar(require("./channel-connection"), exports);
|
|
26
26
|
__exportStar(require("./channel-data-port"), exports);
|
|
27
|
-
__exportStar(require("./data-service-frontend"), exports);
|
|
28
|
-
__exportStar(require("./diagnostics-data-service-frontend"), exports);
|
|
29
27
|
__exportStar(require("./host-diagnostics-frontend"), exports);
|
|
30
|
-
__exportStar(require("./references-data-service-frontend"), exports);
|
|
31
28
|
__exportStar(require("./workspace-gate"), exports);
|
|
32
29
|
//# sourceMappingURL=index.js.map
|
package/lib/browser/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/browser/index.ts"],"names":[],"mappings":";AAAA;;;;;;;kFAOkF;;;;;;;;;;;;;;;;AAElF,uDAAqC;AACrC,sDAAoC;AACpC,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/browser/index.ts"],"names":[],"mappings":";AAAA;;;;;;;kFAOkF;;;;;;;;;;;;;;;;AAElF,uDAAqC;AACrC,sDAAoC;AACpC,8DAA4C;AAC5C,mDAAiC"}
|
|
@@ -24,11 +24,12 @@ import { ContainerModule, type interfaces } from '@theia/core/shared/inversify';
|
|
|
24
24
|
*
|
|
25
25
|
* **More than one handler is the normal case, not an exotic one.** Theia keys a
|
|
26
26
|
* frontend channel by its service path and refuses a second channel on a path
|
|
27
|
-
* already open, so every frontend abstraction reaching the data head
|
|
28
|
-
* own path and therefore its own handler
|
|
29
|
-
* Theia `AbstractDataServiceFrontend` is exactly that shape. They still forward
|
|
27
|
+
* already open, so every frontend abstraction reaching the data head on its own
|
|
28
|
+
* channel needs its own path and therefore its own handler. They still forward
|
|
30
29
|
* to the SAME data server: the path distinguishes the channel, the shared
|
|
31
|
-
* `portCommand` names the one process behind it.
|
|
30
|
+
* `portCommand` names the one process behind it. Several participants over ONE
|
|
31
|
+
* channel need no second handler — that is what `DataConnection`'s sessions are
|
|
32
|
+
* for, and it is the cheaper arrangement.
|
|
32
33
|
*/
|
|
33
34
|
export declare function createDataServerConnectionContainerModule(...handlerClasses: interfaces.Newable<ConnectionHandler>[]): ContainerModule;
|
|
34
35
|
//# sourceMappingURL=connection-container-module.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"connection-container-module.d.ts","sourceRoot":"","sources":["../../src/node/connection-container-module.ts"],"names":[],"mappings":"AAAA;;;;;;;kFAOkF;AAElF,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAEhD,OAAO,EAAE,eAAe,EAAE,KAAK,UAAU,EAAE,MAAM,8BAA8B,CAAC;AAEhF
|
|
1
|
+
{"version":3,"file":"connection-container-module.d.ts","sourceRoot":"","sources":["../../src/node/connection-container-module.ts"],"names":[],"mappings":"AAAA;;;;;;;kFAOkF;AAElF,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAEhD,OAAO,EAAE,eAAe,EAAE,KAAK,UAAU,EAAE,MAAM,8BAA8B,CAAC;AAEhF;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,yCAAyC,CAAC,GAAG,cAAc,EAAE,UAAU,CAAC,OAAO,CAAC,iBAAiB,CAAC,EAAE,GAAG,eAAe,CAerI"}
|
|
@@ -28,11 +28,12 @@ const inversify_1 = require("@theia/core/shared/inversify");
|
|
|
28
28
|
*
|
|
29
29
|
* **More than one handler is the normal case, not an exotic one.** Theia keys a
|
|
30
30
|
* frontend channel by its service path and refuses a second channel on a path
|
|
31
|
-
* already open, so every frontend abstraction reaching the data head
|
|
32
|
-
* own path and therefore its own handler
|
|
33
|
-
* Theia `AbstractDataServiceFrontend` is exactly that shape. They still forward
|
|
31
|
+
* already open, so every frontend abstraction reaching the data head on its own
|
|
32
|
+
* channel needs its own path and therefore its own handler. They still forward
|
|
34
33
|
* to the SAME data server: the path distinguishes the channel, the shared
|
|
35
|
-
* `portCommand` names the one process behind it.
|
|
34
|
+
* `portCommand` names the one process behind it. Several participants over ONE
|
|
35
|
+
* channel need no second handler — that is what `DataConnection`'s sessions are
|
|
36
|
+
* for, and it is the cheaper arrangement.
|
|
36
37
|
*/
|
|
37
38
|
function createDataServerConnectionContainerModule(...handlerClasses) {
|
|
38
39
|
const frontendScopedConnectionModule = connection_container_module_1.ConnectionContainerModule.create(({ bind }) => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"connection-container-module.js","sourceRoot":"","sources":["../../src/node/connection-container-module.ts"],"names":[],"mappings":";AAAA;;;;;;;kFAOkF;;
|
|
1
|
+
{"version":3,"file":"connection-container-module.js","sourceRoot":"","sources":["../../src/node/connection-container-module.ts"],"names":[],"mappings":";AAAA;;;;;;;kFAOkF;;AA6BlF,8FAeC;AA1CD,sCAAgD;AAChD,4GAAuG;AACvG,4DAAgF;AAEhF;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,SAAgB,yCAAyC,CAAC,GAAG,cAAuD;IACjH,MAAM,8BAA8B,GAAG,uDAAyB,CAAC,MAAM,CAAC,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE;QAClF,KAAK,MAAM,YAAY,IAAI,cAAc,EAAE,CAAC;YACzC,IAAI,CAAC,YAAY,CAAC,CAAC,MAAM,EAAE,CAAC,gBAAgB,EAAE,CAAC;YAC/C,mEAAmE;YACnE,mEAAmE;YACnE,oEAAoE;YACpE,IAAI,CAAC,wBAAiB,CAAC;iBACnB,cAAc,CAAC,OAAO,CAAC,EAAE,CAAC,OAAO,CAAC,SAAS,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;iBAC9D,gBAAgB,EAAE,CAAC;QAC1B,CAAC;IACJ,CAAC,CAAC,CAAC;IACH,OAAO,IAAI,2BAAe,CAAC,IAAI,CAAC,EAAE;QAC/B,IAAI,CAAC,uDAAyB,CAAC,CAAC,eAAe,CAAC,8BAA8B,CAAC,CAAC;IACnF,CAAC,CAAC,CAAC;AACN,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hydranium/data-client-theia",
|
|
3
|
-
"version": "1.0.0-next.
|
|
3
|
+
"version": "1.0.0-next.66",
|
|
4
4
|
"description": "Theia-coupled client primitives for the hydranium data-server protocol head; companion of @hydranium/data-server. Bridges framework typed errors (e.g. ConflictError) across Theia's RPC boundary so their code + data survive the wire.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"hydranium",
|
|
@@ -70,9 +70,9 @@
|
|
|
70
70
|
"watch": "tsc -b -w --preserveWatchOutput"
|
|
71
71
|
},
|
|
72
72
|
"devDependencies": {
|
|
73
|
-
"@hydranium/client-theia": "1.0.0-next.
|
|
74
|
-
"@hydranium/core": "1.0.0-next.
|
|
75
|
-
"@hydranium/protocol": "1.0.0-next.
|
|
73
|
+
"@hydranium/client-theia": "1.0.0-next.66",
|
|
74
|
+
"@hydranium/core": "1.0.0-next.66",
|
|
75
|
+
"@hydranium/protocol": "1.0.0-next.66",
|
|
76
76
|
"@theia/core": "^1.70.0",
|
|
77
77
|
"@theia/workspace": "^1.70.0",
|
|
78
78
|
"@types/node": "^22.0.0",
|
|
@@ -83,9 +83,9 @@
|
|
|
83
83
|
"vscode-jsonrpc": "9.0.1"
|
|
84
84
|
},
|
|
85
85
|
"peerDependencies": {
|
|
86
|
-
"@hydranium/client-theia": "1.0.0-next.
|
|
87
|
-
"@hydranium/core": "1.0.0-next.
|
|
88
|
-
"@hydranium/protocol": "1.0.0-next.
|
|
86
|
+
"@hydranium/client-theia": "1.0.0-next.66",
|
|
87
|
+
"@hydranium/core": "1.0.0-next.66",
|
|
88
|
+
"@hydranium/protocol": "1.0.0-next.66",
|
|
89
89
|
"@theia/core": "^1.70.0",
|
|
90
90
|
"@theia/workspace": "^1.70.0",
|
|
91
91
|
"inversify": "^6.0.0",
|
|
@@ -199,8 +199,8 @@ export interface ChannelConnectionHandle {
|
|
|
199
199
|
/**
|
|
200
200
|
* The current connection. Read it per use rather than caching it: after a
|
|
201
201
|
* reconnect this returns a NEW promise, and a cached one resolves to the
|
|
202
|
-
* dead connection forever. The same reasoning makes
|
|
203
|
-
*
|
|
202
|
+
* dead connection forever. The same reasoning makes `RpcConnection` rebuild
|
|
203
|
+
* its proxy per generation rather than hold one.
|
|
204
204
|
*/
|
|
205
205
|
readonly current: Promise<MessageConnection>;
|
|
206
206
|
|
package/src/browser/index.ts
CHANGED
|
@@ -9,8 +9,5 @@
|
|
|
9
9
|
|
|
10
10
|
export * from './channel-connection';
|
|
11
11
|
export * from './channel-data-port';
|
|
12
|
-
export * from './data-service-frontend';
|
|
13
|
-
export * from './diagnostics-data-service-frontend';
|
|
14
12
|
export * from './host-diagnostics-frontend';
|
|
15
|
-
export * from './references-data-service-frontend';
|
|
16
13
|
export * from './workspace-gate';
|
|
@@ -27,11 +27,12 @@ import { ContainerModule, type interfaces } from '@theia/core/shared/inversify';
|
|
|
27
27
|
*
|
|
28
28
|
* **More than one handler is the normal case, not an exotic one.** Theia keys a
|
|
29
29
|
* frontend channel by its service path and refuses a second channel on a path
|
|
30
|
-
* already open, so every frontend abstraction reaching the data head
|
|
31
|
-
* own path and therefore its own handler
|
|
32
|
-
* Theia `AbstractDataServiceFrontend` is exactly that shape. They still forward
|
|
30
|
+
* already open, so every frontend abstraction reaching the data head on its own
|
|
31
|
+
* channel needs its own path and therefore its own handler. They still forward
|
|
33
32
|
* to the SAME data server: the path distinguishes the channel, the shared
|
|
34
|
-
* `portCommand` names the one process behind it.
|
|
33
|
+
* `portCommand` names the one process behind it. Several participants over ONE
|
|
34
|
+
* channel need no second handler — that is what `DataConnection`'s sessions are
|
|
35
|
+
* for, and it is the cheaper arrangement.
|
|
35
36
|
*/
|
|
36
37
|
export function createDataServerConnectionContainerModule(...handlerClasses: interfaces.Newable<ConnectionHandler>[]): ContainerModule {
|
|
37
38
|
const frontendScopedConnectionModule = ConnectionContainerModule.create(({ bind }) => {
|
|
@@ -1,96 +0,0 @@
|
|
|
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
|
-
import { type DataPort, type ReadyServer, type ResolvedMessage, RpcConnection, type RpcProxy } from '@hydranium/protocol';
|
|
10
|
-
import { Emitter, type MessageService } from '@theia/core';
|
|
11
|
-
import type { ServiceConnectionProvider } from '@theia/core/lib/browser';
|
|
12
|
-
import type { WorkspaceService } from '@theia/workspace/lib/browser';
|
|
13
|
-
import { type ChannelConnectionHandle } from './channel-connection';
|
|
14
|
-
/**
|
|
15
|
-
* Base for a Theia frontend that owns the data-server vscode-jsonrpc
|
|
16
|
-
* connection directly (the data head's "frontend speaks the model-server's
|
|
17
|
-
* protocol over a relayed channel" pattern). Lifts the mechanical wiring —
|
|
18
|
-
* the workspace-gated connection, the combined server proxy + inbound client
|
|
19
|
-
* binding, and the lazy idempotent init gate — leaving the adopter to supply
|
|
20
|
-
* the connection seams and any progress UI / domain caching / request-method
|
|
21
|
-
* delegation on top.
|
|
22
|
-
*
|
|
23
|
-
* Generic over the server protocol `TServer` (must expose `waitForReady`) and
|
|
24
|
-
* the local notification target `TClient`. A subclass supplies the abstract
|
|
25
|
-
* members below, calls {@link start} from its `@postConstruct`, and awaits
|
|
26
|
-
* {@link ensureConnected} before its first `this.server.*` call.
|
|
27
|
-
*
|
|
28
|
-
* The lifecycle is `RpcConnection`'s — the same proxy, readiness gate and
|
|
29
|
-
* reconnect generation the host-neutral tier uses. What stays here is the Theia
|
|
30
|
-
* half: the channel, the workspace gate and the notification sink.
|
|
31
|
-
*/
|
|
32
|
-
export declare abstract class AbstractDataServiceFrontend<TServer extends ReadyServer, TClient extends object> {
|
|
33
|
-
protected abstract readonly connectionProvider: ServiceConnectionProvider;
|
|
34
|
-
protected abstract readonly workspaceService?: WorkspaceService;
|
|
35
|
-
protected abstract readonly client: TClient;
|
|
36
|
-
/** Frontend service path the backend forwarder for this head is registered under. */
|
|
37
|
-
protected abstract readonly servicePath: string;
|
|
38
|
-
protected abstract readonly methodNamespace: string;
|
|
39
|
-
/** Allowlist of {@link client} methods to bind as inbound handlers. */
|
|
40
|
-
protected abstract readonly clientMethods: readonly (keyof TClient & string)[];
|
|
41
|
-
/** Surfaces a transport failure. Optional: a frontend with no UI of its own omits it. */
|
|
42
|
-
protected readonly messageService?: MessageService;
|
|
43
|
-
/**
|
|
44
|
-
* Rebuild the connection when the current one is lost. Defaults to `true` —
|
|
45
|
-
* re-opening the channel is the only thing that recovers a restarted
|
|
46
|
-
* language server, which binds new ephemeral ports. Turn it off for a
|
|
47
|
-
* frontend that would rather tear itself down than show its warm-up twice.
|
|
48
|
-
*/
|
|
49
|
-
protected readonly reconnectOnConnectionLoss: boolean;
|
|
50
|
-
protected channel?: ChannelConnectionHandle;
|
|
51
|
-
protected connection?: RpcConnection<TServer, TClient>;
|
|
52
|
-
protected readonly lossEmitter: Emitter<void>;
|
|
53
|
-
/**
|
|
54
|
-
* Readiness gate for the connection — the channel opens only once the
|
|
55
|
-
* returned promise settles. Default: waits for a workspace when
|
|
56
|
-
* {@link workspaceService} is provided, otherwise opens immediately.
|
|
57
|
-
*/
|
|
58
|
-
protected connectionReadyGate(): Promise<void> | undefined;
|
|
59
|
-
/** A connection generation is opening, including on each reconnect. */
|
|
60
|
-
protected onConnecting(): void;
|
|
61
|
-
/** The server's readiness gate has settled for a generation. */
|
|
62
|
-
protected onReady(): void;
|
|
63
|
-
/** A generation failed; the awaiting caller still rejects. */
|
|
64
|
-
protected onFailed(_error: unknown): void;
|
|
65
|
-
/**
|
|
66
|
-
* Open the channel and build the connection over it. Call once, typically
|
|
67
|
-
* from the adopter's `@postConstruct`. Outbound calls and inbound
|
|
68
|
-
* notifications queue until the channel is live.
|
|
69
|
-
*/
|
|
70
|
-
protected start(): void;
|
|
71
|
-
/** The channel as a {@link DataPort} — the whole Theia-specific half. */
|
|
72
|
-
protected channelPort(): DataPort;
|
|
73
|
-
/** Surface a transport failure the way this host does. */
|
|
74
|
-
protected reportError(reported: ResolvedMessage): void;
|
|
75
|
-
/**
|
|
76
|
-
* The server proxy. Calls queue against the connection, so await
|
|
77
|
-
* {@link ensureConnected} first wherever the server's readiness matters.
|
|
78
|
-
*/
|
|
79
|
-
protected get server(): RpcProxy<TServer>;
|
|
80
|
-
/**
|
|
81
|
-
* Await the connection and the server's readiness gate, shared across
|
|
82
|
-
* concurrent callers and re-run once per connection generation.
|
|
83
|
-
*/
|
|
84
|
-
protected ensureConnected(): Promise<void>;
|
|
85
|
-
/**
|
|
86
|
-
* Release the connection and stop tracking the channel. Idempotent.
|
|
87
|
-
*
|
|
88
|
-
* Subclasses that are Theia `Disposable`s should route their own disposal
|
|
89
|
-
* here; nothing calls it automatically, because the base is not bound to a
|
|
90
|
-
* lifecycle of its own.
|
|
91
|
-
*/
|
|
92
|
-
dispose(): void;
|
|
93
|
-
protected requireConnection(): RpcConnection<TServer, TClient>;
|
|
94
|
-
protected requireChannel(): ChannelConnectionHandle;
|
|
95
|
-
}
|
|
96
|
-
//# sourceMappingURL=data-service-frontend.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"data-service-frontend.d.ts","sourceRoot":"","sources":["../../src/browser/data-service-frontend.ts"],"names":[],"mappings":"AAAA;;;;;;;kFAOkF;AAElF,OAAO,EACJ,KAAK,QAAQ,EACb,KAAK,WAAW,EAChB,KAAK,eAAe,EACpB,aAAa,EACb,KAAK,QAAQ,EAEf,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,OAAO,EAAO,KAAK,cAAc,EAAE,MAAM,aAAa,CAAC;AAChE,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,yBAAyB,CAAC;AACzE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AACrE,OAAO,EAAE,KAAK,uBAAuB,EAAyB,MAAM,sBAAsB,CAAC;AAG3F;;;;;;;;;;;;;;;;;GAiBG;AACH,8BAAsB,2BAA2B,CAAC,OAAO,SAAS,WAAW,EAAE,OAAO,SAAS,MAAM;IAClG,SAAS,CAAC,QAAQ,CAAC,QAAQ,CAAC,kBAAkB,EAAE,yBAAyB,CAAC;IAC1E,SAAS,CAAC,QAAQ,CAAC,QAAQ,CAAC,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;IAChE,SAAS,CAAC,QAAQ,CAAC,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IAC5C,qFAAqF;IACrF,SAAS,CAAC,QAAQ,CAAC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAChD,SAAS,CAAC,QAAQ,CAAC,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;IACpD,uEAAuE;IACvE,SAAS,CAAC,QAAQ,CAAC,QAAQ,CAAC,aAAa,EAAE,SAAS,CAAC,MAAM,OAAO,GAAG,MAAM,CAAC,EAAE,CAAC;IAE/E,yFAAyF;IACzF,SAAS,CAAC,QAAQ,CAAC,cAAc,CAAC,EAAE,cAAc,CAAC;IAEnD;;;;;OAKG;IACH,SAAS,CAAC,QAAQ,CAAC,yBAAyB,EAAE,OAAO,CAAQ;IAE7D,SAAS,CAAC,OAAO,CAAC,EAAE,uBAAuB,CAAC;IAC5C,SAAS,CAAC,UAAU,CAAC,EAAE,aAAa,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IACvD,SAAS,CAAC,QAAQ,CAAC,WAAW,gBAAuB;IAErD;;;;OAIG;IACH,SAAS,CAAC,mBAAmB,IAAI,OAAO,CAAC,IAAI,CAAC,GAAG,SAAS;IAI1D,uEAAuE;IACvE,SAAS,CAAC,YAAY,IAAI,IAAI;IAI9B,gEAAgE;IAChE,SAAS,CAAC,OAAO,IAAI,IAAI;IAIzB,8DAA8D;IAC9D,SAAS,CAAC,QAAQ,CAAC,MAAM,EAAE,OAAO,GAAG,IAAI;IAIzC;;;;OAIG;IACH,SAAS,CAAC,KAAK,IAAI,IAAI;IAoBvB,yEAAyE;IACzE,SAAS,CAAC,WAAW,IAAI,QAAQ;IAWjC,0DAA0D;IAC1D,SAAS,CAAC,WAAW,CAAC,QAAQ,EAAE,eAAe,GAAG,IAAI;IAItD;;;OAGG;IACH,SAAS,KAAK,MAAM,IAAI,QAAQ,CAAC,OAAO,CAAC,CAExC;IAED;;;OAGG;cACa,eAAe,IAAI,OAAO,CAAC,IAAI,CAAC;IAIhD;;;;;;OAMG;IACH,OAAO,IAAI,IAAI;IAQf,SAAS,CAAC,iBAAiB,IAAI,aAAa,CAAC,OAAO,EAAE,OAAO,CAAC;IAO9D,SAAS,CAAC,cAAc,IAAI,uBAAuB;CAMrD"}
|
|
@@ -1,148 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/********************************************************************************
|
|
3
|
-
* Copyright (c) 2026 CrossBreeze, 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.AbstractDataServiceFrontend = void 0;
|
|
12
|
-
const protocol_1 = require("@hydranium/protocol");
|
|
13
|
-
const core_1 = require("@theia/core");
|
|
14
|
-
const channel_connection_1 = require("./channel-connection");
|
|
15
|
-
const workspace_gate_1 = require("./workspace-gate");
|
|
16
|
-
/**
|
|
17
|
-
* Base for a Theia frontend that owns the data-server vscode-jsonrpc
|
|
18
|
-
* connection directly (the data head's "frontend speaks the model-server's
|
|
19
|
-
* protocol over a relayed channel" pattern). Lifts the mechanical wiring —
|
|
20
|
-
* the workspace-gated connection, the combined server proxy + inbound client
|
|
21
|
-
* binding, and the lazy idempotent init gate — leaving the adopter to supply
|
|
22
|
-
* the connection seams and any progress UI / domain caching / request-method
|
|
23
|
-
* delegation on top.
|
|
24
|
-
*
|
|
25
|
-
* Generic over the server protocol `TServer` (must expose `waitForReady`) and
|
|
26
|
-
* the local notification target `TClient`. A subclass supplies the abstract
|
|
27
|
-
* members below, calls {@link start} from its `@postConstruct`, and awaits
|
|
28
|
-
* {@link ensureConnected} before its first `this.server.*` call.
|
|
29
|
-
*
|
|
30
|
-
* The lifecycle is `RpcConnection`'s — the same proxy, readiness gate and
|
|
31
|
-
* reconnect generation the host-neutral tier uses. What stays here is the Theia
|
|
32
|
-
* half: the channel, the workspace gate and the notification sink.
|
|
33
|
-
*/
|
|
34
|
-
class AbstractDataServiceFrontend {
|
|
35
|
-
/** Surfaces a transport failure. Optional: a frontend with no UI of its own omits it. */
|
|
36
|
-
messageService;
|
|
37
|
-
/**
|
|
38
|
-
* Rebuild the connection when the current one is lost. Defaults to `true` —
|
|
39
|
-
* re-opening the channel is the only thing that recovers a restarted
|
|
40
|
-
* language server, which binds new ephemeral ports. Turn it off for a
|
|
41
|
-
* frontend that would rather tear itself down than show its warm-up twice.
|
|
42
|
-
*/
|
|
43
|
-
reconnectOnConnectionLoss = true;
|
|
44
|
-
channel;
|
|
45
|
-
connection;
|
|
46
|
-
lossEmitter = new core_1.Emitter();
|
|
47
|
-
/**
|
|
48
|
-
* Readiness gate for the connection — the channel opens only once the
|
|
49
|
-
* returned promise settles. Default: waits for a workspace when
|
|
50
|
-
* {@link workspaceService} is provided, otherwise opens immediately.
|
|
51
|
-
*/
|
|
52
|
-
connectionReadyGate() {
|
|
53
|
-
return this.workspaceService ? (0, workspace_gate_1.whenWorkspaceOpen)(this.workspaceService) : undefined;
|
|
54
|
-
}
|
|
55
|
-
/** A connection generation is opening, including on each reconnect. */
|
|
56
|
-
onConnecting() {
|
|
57
|
-
// nothing by default
|
|
58
|
-
}
|
|
59
|
-
/** The server's readiness gate has settled for a generation. */
|
|
60
|
-
onReady() {
|
|
61
|
-
// nothing by default
|
|
62
|
-
}
|
|
63
|
-
/** A generation failed; the awaiting caller still rejects. */
|
|
64
|
-
onFailed(_error) {
|
|
65
|
-
// nothing by default
|
|
66
|
-
}
|
|
67
|
-
/**
|
|
68
|
-
* Open the channel and build the connection over it. Call once, typically
|
|
69
|
-
* from the adopter's `@postConstruct`. Outbound calls and inbound
|
|
70
|
-
* notifications queue until the channel is live.
|
|
71
|
-
*/
|
|
72
|
-
start() {
|
|
73
|
-
this.channel = (0, channel_connection_1.openChannelConnection)(this.connectionProvider, this.servicePath, {
|
|
74
|
-
whenReady: this.connectionReadyGate(),
|
|
75
|
-
reconnect: this.reconnectOnConnectionLoss
|
|
76
|
-
});
|
|
77
|
-
// The LOSS, not the replacement's arrival: the connection drops its
|
|
78
|
-
// generation here, so a request made during the gap waits for the fresh
|
|
79
|
-
// one instead of addressing the dead one and never settling.
|
|
80
|
-
this.channel.onDidLoseConnection(() => this.lossEmitter.fire(undefined));
|
|
81
|
-
this.connection = new protocol_1.RpcConnection(this.channelPort(), this.client, {
|
|
82
|
-
methodNamespace: this.methodNamespace,
|
|
83
|
-
clientMethods: this.clientMethods,
|
|
84
|
-
lifecycle: {
|
|
85
|
-
onConnecting: () => this.onConnecting(),
|
|
86
|
-
onReady: () => this.onReady(),
|
|
87
|
-
onFailed: error => this.onFailed(error)
|
|
88
|
-
}
|
|
89
|
-
});
|
|
90
|
-
}
|
|
91
|
-
/** The channel as a {@link DataPort} — the whole Theia-specific half. */
|
|
92
|
-
channelPort() {
|
|
93
|
-
return {
|
|
94
|
-
// Read per call: `current` is repointed on every re-open, so reaching
|
|
95
|
-
// through the handle is what makes a later generation find the live
|
|
96
|
-
// server.
|
|
97
|
-
connect: () => this.requireChannel().current,
|
|
98
|
-
reportError: (_error, reported) => this.reportError(reported),
|
|
99
|
-
onDispose: this.lossEmitter.event
|
|
100
|
-
};
|
|
101
|
-
}
|
|
102
|
-
/** Surface a transport failure the way this host does. */
|
|
103
|
-
reportError(reported) {
|
|
104
|
-
this.messageService?.error((0, protocol_1.renderFrameworkMessage)(reported, core_1.nls.localization?.translations));
|
|
105
|
-
}
|
|
106
|
-
/**
|
|
107
|
-
* The server proxy. Calls queue against the connection, so await
|
|
108
|
-
* {@link ensureConnected} first wherever the server's readiness matters.
|
|
109
|
-
*/
|
|
110
|
-
get server() {
|
|
111
|
-
return this.requireConnection().server;
|
|
112
|
-
}
|
|
113
|
-
/**
|
|
114
|
-
* Await the connection and the server's readiness gate, shared across
|
|
115
|
-
* concurrent callers and re-run once per connection generation.
|
|
116
|
-
*/
|
|
117
|
-
async ensureConnected() {
|
|
118
|
-
await this.requireConnection().connected();
|
|
119
|
-
}
|
|
120
|
-
/**
|
|
121
|
-
* Release the connection and stop tracking the channel. Idempotent.
|
|
122
|
-
*
|
|
123
|
-
* Subclasses that are Theia `Disposable`s should route their own disposal
|
|
124
|
-
* here; nothing calls it automatically, because the base is not bound to a
|
|
125
|
-
* lifecycle of its own.
|
|
126
|
-
*/
|
|
127
|
-
dispose() {
|
|
128
|
-
this.connection?.dispose();
|
|
129
|
-
this.connection = undefined;
|
|
130
|
-
this.channel?.dispose();
|
|
131
|
-
this.channel = undefined;
|
|
132
|
-
this.lossEmitter.dispose();
|
|
133
|
-
}
|
|
134
|
-
requireConnection() {
|
|
135
|
-
if (!this.connection) {
|
|
136
|
-
throw new Error('the connection is not open: call start() first');
|
|
137
|
-
}
|
|
138
|
-
return this.connection;
|
|
139
|
-
}
|
|
140
|
-
requireChannel() {
|
|
141
|
-
if (!this.channel) {
|
|
142
|
-
throw new Error('the channel is not open: call start() first');
|
|
143
|
-
}
|
|
144
|
-
return this.channel;
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
|
-
exports.AbstractDataServiceFrontend = AbstractDataServiceFrontend;
|
|
148
|
-
//# sourceMappingURL=data-service-frontend.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"data-service-frontend.js","sourceRoot":"","sources":["../../src/browser/data-service-frontend.ts"],"names":[],"mappings":";AAAA;;;;;;;kFAOkF;;;AAElF,kDAO6B;AAC7B,sCAAgE;AAGhE,6DAA2F;AAC3F,qDAAqD;AAErD;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAsB,2BAA2B;IAU9C,yFAAyF;IACtE,cAAc,CAAkB;IAEnD;;;;;OAKG;IACgB,yBAAyB,GAAY,IAAI,CAAC;IAEnD,OAAO,CAA2B;IAClC,UAAU,CAAmC;IACpC,WAAW,GAAG,IAAI,cAAO,EAAQ,CAAC;IAErD;;;;OAIG;IACO,mBAAmB;QAC1B,OAAO,IAAI,CAAC,gBAAgB,CAAC,CAAC,CAAC,IAAA,kCAAiB,EAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IACvF,CAAC;IAED,uEAAuE;IAC7D,YAAY;QACnB,qBAAqB;IACxB,CAAC;IAED,gEAAgE;IACtD,OAAO;QACd,qBAAqB;IACxB,CAAC;IAED,8DAA8D;IACpD,QAAQ,CAAC,MAAe;QAC/B,qBAAqB;IACxB,CAAC;IAED;;;;OAIG;IACO,KAAK;QACZ,IAAI,CAAC,OAAO,GAAG,IAAA,0CAAqB,EAAC,IAAI,CAAC,kBAAkB,EAAE,IAAI,CAAC,WAAW,EAAE;YAC7E,SAAS,EAAE,IAAI,CAAC,mBAAmB,EAAE;YACrC,SAAS,EAAE,IAAI,CAAC,yBAAyB;SAC3C,CAAC,CAAC;QACH,oEAAoE;QACpE,wEAAwE;QACxE,6DAA6D;QAC7D,IAAI,CAAC,OAAO,CAAC,mBAAmB,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC;QACzE,IAAI,CAAC,UAAU,GAAG,IAAI,wBAAa,CAAmB,IAAI,CAAC,WAAW,EAAE,EAAE,IAAI,CAAC,MAAM,EAAE;YACpF,eAAe,EAAE,IAAI,CAAC,eAAe;YACrC,aAAa,EAAE,IAAI,CAAC,aAAa;YACjC,SAAS,EAAE;gBACR,YAAY,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,YAAY,EAAE;gBACvC,OAAO,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,OAAO,EAAE;gBAC7B,QAAQ,EAAE,KAAK,CAAC,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC;aACzC;SACH,CAAC,CAAC;IACN,CAAC;IAED,yEAAyE;IAC/D,WAAW;QAClB,OAAO;YACJ,sEAAsE;YACtE,oEAAoE;YACpE,UAAU;YACV,OAAO,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,cAAc,EAAE,CAAC,OAAO;YAC5C,WAAW,EAAE,CAAC,MAAM,EAAE,QAAQ,EAAE,EAAE,CAAC,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC;YAC7D,SAAS,EAAE,IAAI,CAAC,WAAW,CAAC,KAAK;SACnC,CAAC;IACL,CAAC;IAED,0DAA0D;IAChD,WAAW,CAAC,QAAyB;QAC5C,IAAI,CAAC,cAAc,EAAE,KAAK,CAAC,IAAA,iCAAsB,EAAC,QAAQ,EAAE,UAAG,CAAC,YAAY,EAAE,YAAY,CAAC,CAAC,CAAC;IAChG,CAAC;IAED;;;OAGG;IACH,IAAc,MAAM;QACjB,OAAO,IAAI,CAAC,iBAAiB,EAAE,CAAC,MAAM,CAAC;IAC1C,CAAC;IAED;;;OAGG;IACO,KAAK,CAAC,eAAe;QAC5B,MAAM,IAAI,CAAC,iBAAiB,EAAE,CAAC,SAAS,EAAE,CAAC;IAC9C,CAAC;IAED;;;;;;OAMG;IACH,OAAO;QACJ,IAAI,CAAC,UAAU,EAAE,OAAO,EAAE,CAAC;QAC3B,IAAI,CAAC,UAAU,GAAG,SAAS,CAAC;QAC5B,IAAI,CAAC,OAAO,EAAE,OAAO,EAAE,CAAC;QACxB,IAAI,CAAC,OAAO,GAAG,SAAS,CAAC;QACzB,IAAI,CAAC,WAAW,CAAC,OAAO,EAAE,CAAC;IAC9B,CAAC;IAES,iBAAiB;QACxB,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC;YACpB,MAAM,IAAI,KAAK,CAAC,gDAAgD,CAAC,CAAC;QACrE,CAAC;QACD,OAAO,IAAI,CAAC,UAAU,CAAC;IAC1B,CAAC;IAES,cAAc;QACrB,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;YACjB,MAAM,IAAI,KAAK,CAAC,6CAA6C,CAAC,CAAC;QAClE,CAAC;QACD,OAAO,IAAI,CAAC,OAAO,CAAC;IACvB,CAAC;CACH;AAvID,kEAuIC"}
|
|
@@ -1,35 +0,0 @@
|
|
|
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
|
-
import type { DataServerDiagnosticsProtocol, DumpServerStateArgs, LatencyReport, StartProfilingArgs, StopProfilingArgs, WriteServerHeapSnapshotArgs } from '@hydranium/protocol';
|
|
10
|
-
import { AbstractDataServiceFrontend } from './data-service-frontend';
|
|
11
|
-
/**
|
|
12
|
-
* {@link AbstractDataServiceFrontend} specialised for a server that also exposes
|
|
13
|
-
* the framework {@link DataServerDiagnosticsProtocol} (which the framework
|
|
14
|
-
* `DataServer` implements by default). It implements each diagnostics method as
|
|
15
|
-
* a readiness-gated pass-through — `await this.ensureConnected()`, then delegate
|
|
16
|
-
* to `this.server` — so every adopter frontend gets the memory / state /
|
|
17
|
-
* profiling / latency surface without hand-writing identical one-liner bodies.
|
|
18
|
-
*
|
|
19
|
-
* Extend this instead of {@link AbstractDataServiceFrontend} whenever the head's
|
|
20
|
-
* `DataServer` keeps the default diagnostics registration; the `TServer` bound
|
|
21
|
-
* carries `DataServerDiagnosticsProtocol`, so the delegates are type-checked
|
|
22
|
-
* (no casts). A head that dropped the diagnostics methods via
|
|
23
|
-
* `DataServerOptions.excludedMethods` should extend the plain base instead.
|
|
24
|
-
*/
|
|
25
|
-
export declare abstract class AbstractDiagnosticsDataServiceFrontend<TServer extends {
|
|
26
|
-
waitForReady(): Promise<void>;
|
|
27
|
-
} & DataServerDiagnosticsProtocol, TClient extends object> extends AbstractDataServiceFrontend<TServer, TClient> implements DataServerDiagnosticsProtocol {
|
|
28
|
-
dumpServerState(args: DumpServerStateArgs): Promise<string>;
|
|
29
|
-
writeHeapSnapshot(args: WriteServerHeapSnapshotArgs): Promise<string>;
|
|
30
|
-
dumpPodMemory(): Promise<string>;
|
|
31
|
-
startProfiling(args: StartProfilingArgs): Promise<void>;
|
|
32
|
-
stopProfiling(args: StopProfilingArgs): Promise<string>;
|
|
33
|
-
getLatency(): Promise<LatencyReport>;
|
|
34
|
-
}
|
|
35
|
-
//# sourceMappingURL=diagnostics-data-service-frontend.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"diagnostics-data-service-frontend.d.ts","sourceRoot":"","sources":["../../src/browser/diagnostics-data-service-frontend.ts"],"names":[],"mappings":"AAAA;;;;;;;kFAOkF;AAElF,OAAO,KAAK,EACT,6BAA6B,EAC7B,mBAAmB,EACnB,aAAa,EACb,kBAAkB,EAClB,iBAAiB,EACjB,2BAA2B,EAC7B,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,2BAA2B,EAAE,MAAM,yBAAyB,CAAC;AAEtE;;;;;;;;;;;;;GAaG;AACH,8BAAsB,sCAAsC,CACzD,OAAO,SAAS;IAAE,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;CAAE,GAAG,6BAA6B,EACjF,OAAO,SAAS,MAAM,CAEtB,SAAQ,2BAA2B,CAAC,OAAO,EAAE,OAAO,CACpD,YAAW,6BAA6B;IAElC,eAAe,CAAC,IAAI,EAAE,mBAAmB,GAAG,OAAO,CAAC,MAAM,CAAC;IAK3D,iBAAiB,CAAC,IAAI,EAAE,2BAA2B,GAAG,OAAO,CAAC,MAAM,CAAC;IAKrE,aAAa,IAAI,OAAO,CAAC,MAAM,CAAC;IAKhC,cAAc,CAAC,IAAI,EAAE,kBAAkB,GAAG,OAAO,CAAC,IAAI,CAAC;IAKvD,aAAa,CAAC,IAAI,EAAE,iBAAiB,GAAG,OAAO,CAAC,MAAM,CAAC;IAKvD,UAAU,IAAI,OAAO,CAAC,aAAa,CAAC;CAI5C"}
|
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/********************************************************************************
|
|
3
|
-
* Copyright (c) 2026 CrossBreeze, 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.AbstractDiagnosticsDataServiceFrontend = void 0;
|
|
12
|
-
const data_service_frontend_1 = require("./data-service-frontend");
|
|
13
|
-
/**
|
|
14
|
-
* {@link AbstractDataServiceFrontend} specialised for a server that also exposes
|
|
15
|
-
* the framework {@link DataServerDiagnosticsProtocol} (which the framework
|
|
16
|
-
* `DataServer` implements by default). It implements each diagnostics method as
|
|
17
|
-
* a readiness-gated pass-through — `await this.ensureConnected()`, then delegate
|
|
18
|
-
* to `this.server` — so every adopter frontend gets the memory / state /
|
|
19
|
-
* profiling / latency surface without hand-writing identical one-liner bodies.
|
|
20
|
-
*
|
|
21
|
-
* Extend this instead of {@link AbstractDataServiceFrontend} whenever the head's
|
|
22
|
-
* `DataServer` keeps the default diagnostics registration; the `TServer` bound
|
|
23
|
-
* carries `DataServerDiagnosticsProtocol`, so the delegates are type-checked
|
|
24
|
-
* (no casts). A head that dropped the diagnostics methods via
|
|
25
|
-
* `DataServerOptions.excludedMethods` should extend the plain base instead.
|
|
26
|
-
*/
|
|
27
|
-
class AbstractDiagnosticsDataServiceFrontend extends data_service_frontend_1.AbstractDataServiceFrontend {
|
|
28
|
-
async dumpServerState(args) {
|
|
29
|
-
await this.ensureConnected();
|
|
30
|
-
return this.server.dumpServerState(args);
|
|
31
|
-
}
|
|
32
|
-
async writeHeapSnapshot(args) {
|
|
33
|
-
await this.ensureConnected();
|
|
34
|
-
return this.server.writeHeapSnapshot(args);
|
|
35
|
-
}
|
|
36
|
-
async dumpPodMemory() {
|
|
37
|
-
await this.ensureConnected();
|
|
38
|
-
return this.server.dumpPodMemory();
|
|
39
|
-
}
|
|
40
|
-
async startProfiling(args) {
|
|
41
|
-
await this.ensureConnected();
|
|
42
|
-
return this.server.startProfiling(args);
|
|
43
|
-
}
|
|
44
|
-
async stopProfiling(args) {
|
|
45
|
-
await this.ensureConnected();
|
|
46
|
-
return this.server.stopProfiling(args);
|
|
47
|
-
}
|
|
48
|
-
async getLatency() {
|
|
49
|
-
await this.ensureConnected();
|
|
50
|
-
return this.server.getLatency();
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
exports.AbstractDiagnosticsDataServiceFrontend = AbstractDiagnosticsDataServiceFrontend;
|
|
54
|
-
//# sourceMappingURL=diagnostics-data-service-frontend.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"diagnostics-data-service-frontend.js","sourceRoot":"","sources":["../../src/browser/diagnostics-data-service-frontend.ts"],"names":[],"mappings":";AAAA;;;;;;;kFAOkF;;;AAUlF,mEAAsE;AAEtE;;;;;;;;;;;;;GAaG;AACH,MAAsB,sCAInB,SAAQ,mDAA6C;IAGrD,KAAK,CAAC,eAAe,CAAC,IAAyB;QAC5C,MAAM,IAAI,CAAC,eAAe,EAAE,CAAC;QAC7B,OAAO,IAAI,CAAC,MAAM,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC;IAC5C,CAAC;IAED,KAAK,CAAC,iBAAiB,CAAC,IAAiC;QACtD,MAAM,IAAI,CAAC,eAAe,EAAE,CAAC;QAC7B,OAAO,IAAI,CAAC,MAAM,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC;IAC9C,CAAC;IAED,KAAK,CAAC,aAAa;QAChB,MAAM,IAAI,CAAC,eAAe,EAAE,CAAC;QAC7B,OAAO,IAAI,CAAC,MAAM,CAAC,aAAa,EAAE,CAAC;IACtC,CAAC;IAED,KAAK,CAAC,cAAc,CAAC,IAAwB;QAC1C,MAAM,IAAI,CAAC,eAAe,EAAE,CAAC;QAC7B,OAAO,IAAI,CAAC,MAAM,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC;IAC3C,CAAC;IAED,KAAK,CAAC,aAAa,CAAC,IAAuB;QACxC,MAAM,IAAI,CAAC,eAAe,EAAE,CAAC;QAC7B,OAAO,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;IAC1C,CAAC;IAED,KAAK,CAAC,UAAU;QACb,MAAM,IAAI,CAAC,eAAe,EAAE,CAAC;QAC7B,OAAO,IAAI,CAAC,MAAM,CAAC,UAAU,EAAE,CAAC;IACnC,CAAC;CACH;AApCD,wFAoCC"}
|
|
@@ -1,45 +0,0 @@
|
|
|
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
|
-
import type { FindNextNameArgs, ReferenceCandidate, ReferenceContext, ReferenceRequest, ReferenceServerProtocol, ReferenceTarget, TransferElement } from '@hydranium/protocol';
|
|
10
|
-
import { AbstractDataServiceFrontend } from './data-service-frontend';
|
|
11
|
-
/**
|
|
12
|
-
* {@link AbstractDataServiceFrontend} specialised for a server that also
|
|
13
|
-
* composes the framework {@link ReferenceServerProtocol} fragment. It
|
|
14
|
-
* implements each reference method as a readiness-gated pass-through —
|
|
15
|
-
* `await this.ensureConnected()`, then delegate to `this.server` — so an
|
|
16
|
-
* adopter frontend gets the candidate / resolve / next-name surface without
|
|
17
|
-
* hand-writing identical one-liner bodies.
|
|
18
|
-
*
|
|
19
|
-
* The sibling of `AbstractDiagnosticsDataServiceFrontend`, and the same
|
|
20
|
-
* shape for the same reason: `this.server` is already a forwarding proxy, but
|
|
21
|
-
* it queues only on the channel being live, not on the server's `waitForReady`
|
|
22
|
-
* gate — so the gate has to be interposed per method.
|
|
23
|
-
*
|
|
24
|
-
* Extend this instead of {@link AbstractDataServiceFrontend} whenever the
|
|
25
|
-
* head's `DataServer` registers the reference fragment (typically via a
|
|
26
|
-
* subclass's `additionalMethods`, since
|
|
27
|
-
* `REFERENCE_SERVER_PROTOCOL_METHODS` is deliberately NOT part of
|
|
28
|
-
* `DATA_SERVER_PROTOCOL_METHODS`). The `TServer` bound carries
|
|
29
|
-
* `ReferenceServerProtocol`, so the delegates are type-checked without casts.
|
|
30
|
-
*
|
|
31
|
-
* A frontend needing both fragments extends the diagnostics base and mixes
|
|
32
|
-
* these three in, or vice versa — TypeScript allows only one base class, so
|
|
33
|
-
* the two bases are deliberately independent rather than chained. Chaining
|
|
34
|
-
* them would force every reference-fragment adopter to also carry the
|
|
35
|
-
* diagnostics surface, which a head that dropped those methods via
|
|
36
|
-
* `DataServerOptions.excludedMethods` cannot satisfy.
|
|
37
|
-
*/
|
|
38
|
-
export declare abstract class AbstractReferencesDataServiceFrontend<TTransfer extends TransferElement, TServer extends {
|
|
39
|
-
waitForReady(): Promise<void>;
|
|
40
|
-
} & ReferenceServerProtocol<TTransfer>, TClient extends object> extends AbstractDataServiceFrontend<TServer, TClient> implements ReferenceServerProtocol<TTransfer> {
|
|
41
|
-
findReferenceCandidates(ctx: ReferenceContext): Promise<ReferenceCandidate[]>;
|
|
42
|
-
resolveReference(ref: ReferenceRequest): Promise<ReferenceTarget<TTransfer> | undefined>;
|
|
43
|
-
findNextName(args: FindNextNameArgs): Promise<string>;
|
|
44
|
-
}
|
|
45
|
-
//# sourceMappingURL=references-data-service-frontend.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"references-data-service-frontend.d.ts","sourceRoot":"","sources":["../../src/browser/references-data-service-frontend.ts"],"names":[],"mappings":"AAAA;;;;;;;kFAOkF;AAElF,OAAO,KAAK,EACT,gBAAgB,EAChB,kBAAkB,EAClB,gBAAgB,EAChB,gBAAgB,EAChB,uBAAuB,EACvB,eAAe,EACf,eAAe,EACjB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,2BAA2B,EAAE,MAAM,yBAAyB,CAAC;AAEtE;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,8BAAsB,qCAAqC,CACxD,SAAS,SAAS,eAAe,EACjC,OAAO,SAAS;IAAE,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;CAAE,GAAG,uBAAuB,CAAC,SAAS,CAAC,EACtF,OAAO,SAAS,MAAM,CAEtB,SAAQ,2BAA2B,CAAC,OAAO,EAAE,OAAO,CACpD,YAAW,uBAAuB,CAAC,SAAS,CAAC;IAEvC,uBAAuB,CAAC,GAAG,EAAE,gBAAgB,GAAG,OAAO,CAAC,kBAAkB,EAAE,CAAC;IAK7E,gBAAgB,CAAC,GAAG,EAAE,gBAAgB,GAAG,OAAO,CAAC,eAAe,CAAC,SAAS,CAAC,GAAG,SAAS,CAAC;IAKxF,YAAY,CAAC,IAAI,EAAE,gBAAgB,GAAG,OAAO,CAAC,MAAM,CAAC;CAI7D"}
|
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/********************************************************************************
|
|
3
|
-
* Copyright (c) 2026 CrossBreeze, 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.AbstractReferencesDataServiceFrontend = void 0;
|
|
12
|
-
const data_service_frontend_1 = require("./data-service-frontend");
|
|
13
|
-
/**
|
|
14
|
-
* {@link AbstractDataServiceFrontend} specialised for a server that also
|
|
15
|
-
* composes the framework {@link ReferenceServerProtocol} fragment. It
|
|
16
|
-
* implements each reference method as a readiness-gated pass-through —
|
|
17
|
-
* `await this.ensureConnected()`, then delegate to `this.server` — so an
|
|
18
|
-
* adopter frontend gets the candidate / resolve / next-name surface without
|
|
19
|
-
* hand-writing identical one-liner bodies.
|
|
20
|
-
*
|
|
21
|
-
* The sibling of `AbstractDiagnosticsDataServiceFrontend`, and the same
|
|
22
|
-
* shape for the same reason: `this.server` is already a forwarding proxy, but
|
|
23
|
-
* it queues only on the channel being live, not on the server's `waitForReady`
|
|
24
|
-
* gate — so the gate has to be interposed per method.
|
|
25
|
-
*
|
|
26
|
-
* Extend this instead of {@link AbstractDataServiceFrontend} whenever the
|
|
27
|
-
* head's `DataServer` registers the reference fragment (typically via a
|
|
28
|
-
* subclass's `additionalMethods`, since
|
|
29
|
-
* `REFERENCE_SERVER_PROTOCOL_METHODS` is deliberately NOT part of
|
|
30
|
-
* `DATA_SERVER_PROTOCOL_METHODS`). The `TServer` bound carries
|
|
31
|
-
* `ReferenceServerProtocol`, so the delegates are type-checked without casts.
|
|
32
|
-
*
|
|
33
|
-
* A frontend needing both fragments extends the diagnostics base and mixes
|
|
34
|
-
* these three in, or vice versa — TypeScript allows only one base class, so
|
|
35
|
-
* the two bases are deliberately independent rather than chained. Chaining
|
|
36
|
-
* them would force every reference-fragment adopter to also carry the
|
|
37
|
-
* diagnostics surface, which a head that dropped those methods via
|
|
38
|
-
* `DataServerOptions.excludedMethods` cannot satisfy.
|
|
39
|
-
*/
|
|
40
|
-
class AbstractReferencesDataServiceFrontend extends data_service_frontend_1.AbstractDataServiceFrontend {
|
|
41
|
-
async findReferenceCandidates(ctx) {
|
|
42
|
-
await this.ensureConnected();
|
|
43
|
-
return this.server.findReferenceCandidates(ctx);
|
|
44
|
-
}
|
|
45
|
-
async resolveReference(ref) {
|
|
46
|
-
await this.ensureConnected();
|
|
47
|
-
return this.server.resolveReference(ref);
|
|
48
|
-
}
|
|
49
|
-
async findNextName(args) {
|
|
50
|
-
await this.ensureConnected();
|
|
51
|
-
return this.server.findNextName(args);
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
exports.AbstractReferencesDataServiceFrontend = AbstractReferencesDataServiceFrontend;
|
|
55
|
-
//# sourceMappingURL=references-data-service-frontend.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"references-data-service-frontend.js","sourceRoot":"","sources":["../../src/browser/references-data-service-frontend.ts"],"names":[],"mappings":";AAAA;;;;;;;kFAOkF;;;AAWlF,mEAAsE;AAEtE;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,MAAsB,qCAKnB,SAAQ,mDAA6C;IAGrD,KAAK,CAAC,uBAAuB,CAAC,GAAqB;QAChD,MAAM,IAAI,CAAC,eAAe,EAAE,CAAC;QAC7B,OAAO,IAAI,CAAC,MAAM,CAAC,uBAAuB,CAAC,GAAG,CAAC,CAAC;IACnD,CAAC;IAED,KAAK,CAAC,gBAAgB,CAAC,GAAqB;QACzC,MAAM,IAAI,CAAC,eAAe,EAAE,CAAC;QAC7B,OAAO,IAAI,CAAC,MAAM,CAAC,gBAAgB,CAAC,GAAG,CAAC,CAAC;IAC5C,CAAC;IAED,KAAK,CAAC,YAAY,CAAC,IAAsB;QACtC,MAAM,IAAI,CAAC,eAAe,EAAE,CAAC;QAC7B,OAAO,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC;IACzC,CAAC;CACH;AAtBD,sFAsBC"}
|
|
@@ -1,177 +0,0 @@
|
|
|
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 {
|
|
11
|
-
type DataPort,
|
|
12
|
-
type ReadyServer,
|
|
13
|
-
type ResolvedMessage,
|
|
14
|
-
RpcConnection,
|
|
15
|
-
type RpcProxy,
|
|
16
|
-
renderFrameworkMessage
|
|
17
|
-
} from '@hydranium/protocol';
|
|
18
|
-
import { Emitter, nls, type MessageService } from '@theia/core';
|
|
19
|
-
import type { ServiceConnectionProvider } from '@theia/core/lib/browser';
|
|
20
|
-
import type { WorkspaceService } from '@theia/workspace/lib/browser';
|
|
21
|
-
import { type ChannelConnectionHandle, openChannelConnection } from './channel-connection';
|
|
22
|
-
import { whenWorkspaceOpen } from './workspace-gate';
|
|
23
|
-
|
|
24
|
-
/**
|
|
25
|
-
* Base for a Theia frontend that owns the data-server vscode-jsonrpc
|
|
26
|
-
* connection directly (the data head's "frontend speaks the model-server's
|
|
27
|
-
* protocol over a relayed channel" pattern). Lifts the mechanical wiring —
|
|
28
|
-
* the workspace-gated connection, the combined server proxy + inbound client
|
|
29
|
-
* binding, and the lazy idempotent init gate — leaving the adopter to supply
|
|
30
|
-
* the connection seams and any progress UI / domain caching / request-method
|
|
31
|
-
* delegation on top.
|
|
32
|
-
*
|
|
33
|
-
* Generic over the server protocol `TServer` (must expose `waitForReady`) and
|
|
34
|
-
* the local notification target `TClient`. A subclass supplies the abstract
|
|
35
|
-
* members below, calls {@link start} from its `@postConstruct`, and awaits
|
|
36
|
-
* {@link ensureConnected} before its first `this.server.*` call.
|
|
37
|
-
*
|
|
38
|
-
* The lifecycle is `RpcConnection`'s — the same proxy, readiness gate and
|
|
39
|
-
* reconnect generation the host-neutral tier uses. What stays here is the Theia
|
|
40
|
-
* half: the channel, the workspace gate and the notification sink.
|
|
41
|
-
*/
|
|
42
|
-
export abstract class AbstractDataServiceFrontend<TServer extends ReadyServer, TClient extends object> {
|
|
43
|
-
protected abstract readonly connectionProvider: ServiceConnectionProvider;
|
|
44
|
-
protected abstract readonly workspaceService?: WorkspaceService;
|
|
45
|
-
protected abstract readonly client: TClient;
|
|
46
|
-
/** Frontend service path the backend forwarder for this head is registered under. */
|
|
47
|
-
protected abstract readonly servicePath: string;
|
|
48
|
-
protected abstract readonly methodNamespace: string;
|
|
49
|
-
/** Allowlist of {@link client} methods to bind as inbound handlers. */
|
|
50
|
-
protected abstract readonly clientMethods: readonly (keyof TClient & string)[];
|
|
51
|
-
|
|
52
|
-
/** Surfaces a transport failure. Optional: a frontend with no UI of its own omits it. */
|
|
53
|
-
protected readonly messageService?: MessageService;
|
|
54
|
-
|
|
55
|
-
/**
|
|
56
|
-
* Rebuild the connection when the current one is lost. Defaults to `true` —
|
|
57
|
-
* re-opening the channel is the only thing that recovers a restarted
|
|
58
|
-
* language server, which binds new ephemeral ports. Turn it off for a
|
|
59
|
-
* frontend that would rather tear itself down than show its warm-up twice.
|
|
60
|
-
*/
|
|
61
|
-
protected readonly reconnectOnConnectionLoss: boolean = true;
|
|
62
|
-
|
|
63
|
-
protected channel?: ChannelConnectionHandle;
|
|
64
|
-
protected connection?: RpcConnection<TServer, TClient>;
|
|
65
|
-
protected readonly lossEmitter = new Emitter<void>();
|
|
66
|
-
|
|
67
|
-
/**
|
|
68
|
-
* Readiness gate for the connection — the channel opens only once the
|
|
69
|
-
* returned promise settles. Default: waits for a workspace when
|
|
70
|
-
* {@link workspaceService} is provided, otherwise opens immediately.
|
|
71
|
-
*/
|
|
72
|
-
protected connectionReadyGate(): Promise<void> | undefined {
|
|
73
|
-
return this.workspaceService ? whenWorkspaceOpen(this.workspaceService) : undefined;
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
/** A connection generation is opening, including on each reconnect. */
|
|
77
|
-
protected onConnecting(): void {
|
|
78
|
-
// nothing by default
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
/** The server's readiness gate has settled for a generation. */
|
|
82
|
-
protected onReady(): void {
|
|
83
|
-
// nothing by default
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
/** A generation failed; the awaiting caller still rejects. */
|
|
87
|
-
protected onFailed(_error: unknown): void {
|
|
88
|
-
// nothing by default
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
/**
|
|
92
|
-
* Open the channel and build the connection over it. Call once, typically
|
|
93
|
-
* from the adopter's `@postConstruct`. Outbound calls and inbound
|
|
94
|
-
* notifications queue until the channel is live.
|
|
95
|
-
*/
|
|
96
|
-
protected start(): void {
|
|
97
|
-
this.channel = openChannelConnection(this.connectionProvider, this.servicePath, {
|
|
98
|
-
whenReady: this.connectionReadyGate(),
|
|
99
|
-
reconnect: this.reconnectOnConnectionLoss
|
|
100
|
-
});
|
|
101
|
-
// The LOSS, not the replacement's arrival: the connection drops its
|
|
102
|
-
// generation here, so a request made during the gap waits for the fresh
|
|
103
|
-
// one instead of addressing the dead one and never settling.
|
|
104
|
-
this.channel.onDidLoseConnection(() => this.lossEmitter.fire(undefined));
|
|
105
|
-
this.connection = new RpcConnection<TServer, TClient>(this.channelPort(), this.client, {
|
|
106
|
-
methodNamespace: this.methodNamespace,
|
|
107
|
-
clientMethods: this.clientMethods,
|
|
108
|
-
lifecycle: {
|
|
109
|
-
onConnecting: () => this.onConnecting(),
|
|
110
|
-
onReady: () => this.onReady(),
|
|
111
|
-
onFailed: error => this.onFailed(error)
|
|
112
|
-
}
|
|
113
|
-
});
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
/** The channel as a {@link DataPort} — the whole Theia-specific half. */
|
|
117
|
-
protected channelPort(): DataPort {
|
|
118
|
-
return {
|
|
119
|
-
// Read per call: `current` is repointed on every re-open, so reaching
|
|
120
|
-
// through the handle is what makes a later generation find the live
|
|
121
|
-
// server.
|
|
122
|
-
connect: () => this.requireChannel().current,
|
|
123
|
-
reportError: (_error, reported) => this.reportError(reported),
|
|
124
|
-
onDispose: this.lossEmitter.event
|
|
125
|
-
};
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
/** Surface a transport failure the way this host does. */
|
|
129
|
-
protected reportError(reported: ResolvedMessage): void {
|
|
130
|
-
this.messageService?.error(renderFrameworkMessage(reported, nls.localization?.translations));
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
/**
|
|
134
|
-
* The server proxy. Calls queue against the connection, so await
|
|
135
|
-
* {@link ensureConnected} first wherever the server's readiness matters.
|
|
136
|
-
*/
|
|
137
|
-
protected get server(): RpcProxy<TServer> {
|
|
138
|
-
return this.requireConnection().server;
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
/**
|
|
142
|
-
* Await the connection and the server's readiness gate, shared across
|
|
143
|
-
* concurrent callers and re-run once per connection generation.
|
|
144
|
-
*/
|
|
145
|
-
protected async ensureConnected(): Promise<void> {
|
|
146
|
-
await this.requireConnection().connected();
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
/**
|
|
150
|
-
* Release the connection and stop tracking the channel. Idempotent.
|
|
151
|
-
*
|
|
152
|
-
* Subclasses that are Theia `Disposable`s should route their own disposal
|
|
153
|
-
* here; nothing calls it automatically, because the base is not bound to a
|
|
154
|
-
* lifecycle of its own.
|
|
155
|
-
*/
|
|
156
|
-
dispose(): void {
|
|
157
|
-
this.connection?.dispose();
|
|
158
|
-
this.connection = undefined;
|
|
159
|
-
this.channel?.dispose();
|
|
160
|
-
this.channel = undefined;
|
|
161
|
-
this.lossEmitter.dispose();
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
protected requireConnection(): RpcConnection<TServer, TClient> {
|
|
165
|
-
if (!this.connection) {
|
|
166
|
-
throw new Error('the connection is not open: call start() first');
|
|
167
|
-
}
|
|
168
|
-
return this.connection;
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
protected requireChannel(): ChannelConnectionHandle {
|
|
172
|
-
if (!this.channel) {
|
|
173
|
-
throw new Error('the channel is not open: call start() first');
|
|
174
|
-
}
|
|
175
|
-
return this.channel;
|
|
176
|
-
}
|
|
177
|
-
}
|
|
@@ -1,70 +0,0 @@
|
|
|
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 type {
|
|
11
|
-
DataServerDiagnosticsProtocol,
|
|
12
|
-
DumpServerStateArgs,
|
|
13
|
-
LatencyReport,
|
|
14
|
-
StartProfilingArgs,
|
|
15
|
-
StopProfilingArgs,
|
|
16
|
-
WriteServerHeapSnapshotArgs
|
|
17
|
-
} from '@hydranium/protocol';
|
|
18
|
-
import { AbstractDataServiceFrontend } from './data-service-frontend';
|
|
19
|
-
|
|
20
|
-
/**
|
|
21
|
-
* {@link AbstractDataServiceFrontend} specialised for a server that also exposes
|
|
22
|
-
* the framework {@link DataServerDiagnosticsProtocol} (which the framework
|
|
23
|
-
* `DataServer` implements by default). It implements each diagnostics method as
|
|
24
|
-
* a readiness-gated pass-through — `await this.ensureConnected()`, then delegate
|
|
25
|
-
* to `this.server` — so every adopter frontend gets the memory / state /
|
|
26
|
-
* profiling / latency surface without hand-writing identical one-liner bodies.
|
|
27
|
-
*
|
|
28
|
-
* Extend this instead of {@link AbstractDataServiceFrontend} whenever the head's
|
|
29
|
-
* `DataServer` keeps the default diagnostics registration; the `TServer` bound
|
|
30
|
-
* carries `DataServerDiagnosticsProtocol`, so the delegates are type-checked
|
|
31
|
-
* (no casts). A head that dropped the diagnostics methods via
|
|
32
|
-
* `DataServerOptions.excludedMethods` should extend the plain base instead.
|
|
33
|
-
*/
|
|
34
|
-
export abstract class AbstractDiagnosticsDataServiceFrontend<
|
|
35
|
-
TServer extends { waitForReady(): Promise<void> } & DataServerDiagnosticsProtocol,
|
|
36
|
-
TClient extends object
|
|
37
|
-
>
|
|
38
|
-
extends AbstractDataServiceFrontend<TServer, TClient>
|
|
39
|
-
implements DataServerDiagnosticsProtocol
|
|
40
|
-
{
|
|
41
|
-
async dumpServerState(args: DumpServerStateArgs): Promise<string> {
|
|
42
|
-
await this.ensureConnected();
|
|
43
|
-
return this.server.dumpServerState(args);
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
async writeHeapSnapshot(args: WriteServerHeapSnapshotArgs): Promise<string> {
|
|
47
|
-
await this.ensureConnected();
|
|
48
|
-
return this.server.writeHeapSnapshot(args);
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
async dumpPodMemory(): Promise<string> {
|
|
52
|
-
await this.ensureConnected();
|
|
53
|
-
return this.server.dumpPodMemory();
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
async startProfiling(args: StartProfilingArgs): Promise<void> {
|
|
57
|
-
await this.ensureConnected();
|
|
58
|
-
return this.server.startProfiling(args);
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
async stopProfiling(args: StopProfilingArgs): Promise<string> {
|
|
62
|
-
await this.ensureConnected();
|
|
63
|
-
return this.server.stopProfiling(args);
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
async getLatency(): Promise<LatencyReport> {
|
|
67
|
-
await this.ensureConnected();
|
|
68
|
-
return this.server.getLatency();
|
|
69
|
-
}
|
|
70
|
-
}
|
|
@@ -1,70 +0,0 @@
|
|
|
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 type {
|
|
11
|
-
FindNextNameArgs,
|
|
12
|
-
ReferenceCandidate,
|
|
13
|
-
ReferenceContext,
|
|
14
|
-
ReferenceRequest,
|
|
15
|
-
ReferenceServerProtocol,
|
|
16
|
-
ReferenceTarget,
|
|
17
|
-
TransferElement
|
|
18
|
-
} from '@hydranium/protocol';
|
|
19
|
-
import { AbstractDataServiceFrontend } from './data-service-frontend';
|
|
20
|
-
|
|
21
|
-
/**
|
|
22
|
-
* {@link AbstractDataServiceFrontend} specialised for a server that also
|
|
23
|
-
* composes the framework {@link ReferenceServerProtocol} fragment. It
|
|
24
|
-
* implements each reference method as a readiness-gated pass-through —
|
|
25
|
-
* `await this.ensureConnected()`, then delegate to `this.server` — so an
|
|
26
|
-
* adopter frontend gets the candidate / resolve / next-name surface without
|
|
27
|
-
* hand-writing identical one-liner bodies.
|
|
28
|
-
*
|
|
29
|
-
* The sibling of `AbstractDiagnosticsDataServiceFrontend`, and the same
|
|
30
|
-
* shape for the same reason: `this.server` is already a forwarding proxy, but
|
|
31
|
-
* it queues only on the channel being live, not on the server's `waitForReady`
|
|
32
|
-
* gate — so the gate has to be interposed per method.
|
|
33
|
-
*
|
|
34
|
-
* Extend this instead of {@link AbstractDataServiceFrontend} whenever the
|
|
35
|
-
* head's `DataServer` registers the reference fragment (typically via a
|
|
36
|
-
* subclass's `additionalMethods`, since
|
|
37
|
-
* `REFERENCE_SERVER_PROTOCOL_METHODS` is deliberately NOT part of
|
|
38
|
-
* `DATA_SERVER_PROTOCOL_METHODS`). The `TServer` bound carries
|
|
39
|
-
* `ReferenceServerProtocol`, so the delegates are type-checked without casts.
|
|
40
|
-
*
|
|
41
|
-
* A frontend needing both fragments extends the diagnostics base and mixes
|
|
42
|
-
* these three in, or vice versa — TypeScript allows only one base class, so
|
|
43
|
-
* the two bases are deliberately independent rather than chained. Chaining
|
|
44
|
-
* them would force every reference-fragment adopter to also carry the
|
|
45
|
-
* diagnostics surface, which a head that dropped those methods via
|
|
46
|
-
* `DataServerOptions.excludedMethods` cannot satisfy.
|
|
47
|
-
*/
|
|
48
|
-
export abstract class AbstractReferencesDataServiceFrontend<
|
|
49
|
-
TTransfer extends TransferElement,
|
|
50
|
-
TServer extends { waitForReady(): Promise<void> } & ReferenceServerProtocol<TTransfer>,
|
|
51
|
-
TClient extends object
|
|
52
|
-
>
|
|
53
|
-
extends AbstractDataServiceFrontend<TServer, TClient>
|
|
54
|
-
implements ReferenceServerProtocol<TTransfer>
|
|
55
|
-
{
|
|
56
|
-
async findReferenceCandidates(ctx: ReferenceContext): Promise<ReferenceCandidate[]> {
|
|
57
|
-
await this.ensureConnected();
|
|
58
|
-
return this.server.findReferenceCandidates(ctx);
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
async resolveReference(ref: ReferenceRequest): Promise<ReferenceTarget<TTransfer> | undefined> {
|
|
62
|
-
await this.ensureConnected();
|
|
63
|
-
return this.server.resolveReference(ref);
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
async findNextName(args: FindNextNameArgs): Promise<string> {
|
|
67
|
-
await this.ensureConnected();
|
|
68
|
-
return this.server.findNextName(args);
|
|
69
|
-
}
|
|
70
|
-
}
|