@hydranium/data-client-theia 1.0.0-next.18 → 1.0.0-next.181

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 (64) hide show
  1. package/README.md +35 -27
  2. package/lib/browser/channel-connection.d.ts +2 -2
  3. package/lib/browser/channel-connection.js.map +1 -1
  4. package/lib/browser/channel-data-port.d.ts +83 -0
  5. package/lib/browser/channel-data-port.d.ts.map +1 -0
  6. package/lib/browser/channel-data-port.js +179 -0
  7. package/lib/browser/channel-data-port.js.map +1 -0
  8. package/lib/browser/data-session-stop-contribution.d.ts +64 -0
  9. package/lib/browser/data-session-stop-contribution.d.ts.map +1 -0
  10. package/lib/browser/data-session-stop-contribution.js +117 -0
  11. package/lib/browser/data-session-stop-contribution.js.map +1 -0
  12. package/lib/browser/host-diagnostics-frontend.js.map +1 -1
  13. package/lib/browser/index.d.ts +2 -3
  14. package/lib/browser/index.d.ts.map +1 -1
  15. package/lib/browser/index.js +2 -3
  16. package/lib/browser/index.js.map +1 -1
  17. package/lib/browser/workspace-gate.js.map +1 -1
  18. package/lib/common/emitter-data-client.d.ts +13 -1
  19. package/lib/common/emitter-data-client.d.ts.map +1 -1
  20. package/lib/common/emitter-data-client.js +18 -0
  21. package/lib/common/emitter-data-client.js.map +1 -1
  22. package/lib/node/connection-container-module.d.ts +5 -4
  23. package/lib/node/connection-container-module.d.ts.map +1 -1
  24. package/lib/node/connection-container-module.js +5 -4
  25. package/lib/node/connection-container-module.js.map +1 -1
  26. package/lib/node/data-server-connection-handler.d.ts +9 -9
  27. package/lib/node/data-server-connection-handler.d.ts.map +1 -1
  28. package/lib/node/data-server-connection-handler.js +8 -12
  29. package/lib/node/data-server-connection-handler.js.map +1 -1
  30. package/lib/node/host-diagnostics-server.d.ts.map +1 -1
  31. package/lib/node/host-diagnostics-server.js.map +1 -1
  32. package/lib/node/index.d.ts +0 -1
  33. package/lib/node/index.d.ts.map +1 -1
  34. package/lib/node/index.js +0 -1
  35. package/lib/node/index.js.map +1 -1
  36. package/package.json +25 -24
  37. package/src/browser/channel-connection.ts +2 -2
  38. package/src/browser/channel-data-port.ts +173 -0
  39. package/src/browser/data-session-stop-contribution.ts +117 -0
  40. package/src/browser/index.ts +2 -3
  41. package/src/common/emitter-data-client.ts +27 -0
  42. package/src/node/connection-container-module.ts +5 -4
  43. package/src/node/data-server-connection-handler.ts +10 -13
  44. package/src/node/index.ts +0 -1
  45. package/lib/browser/data-service-frontend.d.ts +0 -154
  46. package/lib/browser/data-service-frontend.d.ts.map +0 -1
  47. package/lib/browser/data-service-frontend.js +0 -169
  48. package/lib/browser/data-service-frontend.js.map +0 -1
  49. package/lib/browser/diagnostics-data-service-frontend.d.ts +0 -35
  50. package/lib/browser/diagnostics-data-service-frontend.d.ts.map +0 -1
  51. package/lib/browser/diagnostics-data-service-frontend.js +0 -54
  52. package/lib/browser/diagnostics-data-service-frontend.js.map +0 -1
  53. package/lib/browser/references-data-service-frontend.d.ts +0 -45
  54. package/lib/browser/references-data-service-frontend.d.ts.map +0 -1
  55. package/lib/browser/references-data-service-frontend.js +0 -55
  56. package/lib/browser/references-data-service-frontend.js.map +0 -1
  57. package/lib/node/socket-channel-forwarder.d.ts +0 -34
  58. package/lib/node/socket-channel-forwarder.d.ts.map +0 -1
  59. package/lib/node/socket-channel-forwarder.js +0 -63
  60. package/lib/node/socket-channel-forwarder.js.map +0 -1
  61. package/src/browser/data-service-frontend.ts +0 -208
  62. package/src/browser/diagnostics-data-service-frontend.ts +0 -70
  63. package/src/browser/references-data-service-frontend.ts +0 -70
  64. package/src/node/socket-channel-forwarder.ts +0 -64
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 both halves of that arrangement: the browser-side
10
- connection and typed-frontend bases, and the backend-side connection handler and
11
- forwarder. Install it if a Theia application needs form editors, trees, or
12
- code-gen driven from the live AST rather than from LSP text edits.
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,15 @@ 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
- - **`AbstractDataServiceFrontend`** — base for a frontend that owns the
26
- data-server connection: the workspace-gated connect, the typed server proxy,
27
- the inbound client binding, and a lazy idempotent init gate (`ensureConnected`).
28
- You supply the connection seams (`connectionProvider`, `servicePath`,
29
- `methodNamespace`, `client`, `clientMethods`); progress UI and domain caching
30
- layer on top.
31
- - **`AbstractDiagnosticsDataServiceFrontend`** and
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 each connection reports through the
33
+ `ConnectionReporter`, a data server not ready after 30 s included; the
34
+ connection, its sessions and its event fan-out are the host-neutral ones every
35
+ other shell uses.
38
36
  - **`EmitterDataClient`** (on `./common`, not `./browser`) — the default
39
37
  client-side implementation of the data protocol's inbound notifications,
40
38
  fanning each one out to a Theia `Event`: `onDidUpdateDocument`,
@@ -45,8 +43,13 @@ code-gen driven from the live AST rather than from LSP text edits.
45
43
  - **`whenWorkspaceOpen`** — resolves once Theia reports a workspace root. The data
46
44
  server only starts once the LSP launches for a workspace, so connecting earlier
47
45
  would hang in port discovery; pass this as `whenReady`.
48
- - **Backend (`./node`)** — `DataServerConnectionHandler` (the socket bridge, with
49
- its own GLSP-free `SocketChannelForwarder`),
46
+ - **`DataSessionStopContribution`** — ends a frontend's data sessions with its
47
+ page, so the server ends them as closed rather than waiting for the connection
48
+ to go, and holds the page while one of them is saving. Bind it as a
49
+ `FrontendApplicationContribution` and call its `track(connection)` once, where
50
+ the connection is bound.
51
+ - **Backend (`./node`)** — `DataServerConnectionHandler` (the socket bridge,
52
+ over `@hydranium/client-theia`'s `SocketChannelForwarder`),
50
53
  `createDataServerConnectionContainerModule(...handlers)` for the
51
54
  frontend-scoped module boilerplate, and `HostDiagnosticsServer` with
52
55
  `createHostDiagnosticsBackendModule()` — which, paired with the browser-side
@@ -70,7 +73,7 @@ running hydranium data server to connect to. The declared peer dependencies are:
70
73
  | `@theia/core` | `^1.70.0` |
71
74
  | `@theia/workspace` | `^1.70.0` |
72
75
  | `inversify` | `^6.0.0` |
73
- | `vscode-jsonrpc` | `^8.0.0 \|\| ^9.0.0` |
76
+ | `vscode-jsonrpc` | `9.0.1` |
74
77
 
75
78
  `@hydranium/core` is reached only from the `./node` tier (the host-diagnostics
76
79
  service), so a frontend-only consumer never loads it.
@@ -81,17 +84,22 @@ This package declares no `theiaExtensions` — it is a library your own Theia
81
84
  extension builds on. That extension's `package.json` declares the entries, and
82
85
  each entry names one frontend/backend module pair:
83
86
 
84
- - the **frontend** module binds your `AbstractDataServiceFrontend` subclass (and,
85
- for the diagnostics commands, calls `bindHostDiagnostics`);
87
+ - the **frontend** module binds your `ChannelDataPort` subclass and the
88
+ connection over it, both in singleton scope, and calls
89
+ `bindConnectionReporter` and `bindChannelLogger` from `@hydranium/client-theia`
90
+ (the port logs the connection failures it leaves to the reporter there), and,
91
+ for the diagnostics commands, `bindHostDiagnostics`;
86
92
  - the **backend** module is typically a one-liner:
87
93
  `export default createDataServerConnectionContainerModule(MyHandler)`, where
88
94
  `MyHandler` extends `DataServerConnectionHandler`.
89
95
 
90
96
  More than one handler is the normal case, not an exotic one. Theia keys a
91
97
  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 needs its own
93
- `servicePath` — while the shared `portCommand` still names the one server process
94
- behind them all.
98
+ already open, so every frontend abstraction reaching the data head on its own
99
+ channel needs its own `servicePath` — while the shared `portCommand` still names
100
+ the one server process behind them all. Several participants over ONE channel
101
+ need no second handler: that is what `DataConnection`'s sessions are for, and it
102
+ is the cheaper arrangement.
95
103
 
96
104
  The refusal is silent, which is what makes it expensive: the loser's promise is
97
105
  left unsettled rather than rejected, so a frontend that shared a path hangs on
@@ -103,8 +111,8 @@ its loading state indefinitely with nothing in the server log to say why.
103
111
  | ----------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------- |
104
112
  | `.` | Nothing — the surface is split by environment, so the root barrel stays empty. | browser-neutral (gated) |
105
113
  | `./common` | `EmitterDataClient` — a module lands here only when values, types and relative imports are all neutral or Theia COMMON tier. No error-reconstruction bridge, and that is a property of the transport: the direct `vscode-jsonrpc` connection carries a typed error across the relay natively. | browser-neutral (gated) |
106
- | `./browser` | `openChannelConnection`, `createChannelConnection`, the three `Abstract*DataServiceFrontend` bases, `bindHostDiagnostics`, `whenWorkspaceOpen` | browser / Theia frontend (gated) |
107
- | `./node` | `DataServerConnectionHandler`, `createDataServerConnectionContainerModule`, `SocketChannelForwarder`, `HostDiagnosticsServer`, `createHostDiagnosticsBackendModule` | Node / Theia backend |
114
+ | `./browser` | `openChannelConnection`, `createChannelConnection`, the three `Abstract*DataServiceFrontend` bases, `bindHostDiagnostics`, `whenWorkspaceOpen`, `DataSessionStopContribution` | browser / Theia frontend (gated) |
115
+ | `./node` | `DataServerConnectionHandler`, `createDataServerConnectionContainerModule`, `HostDiagnosticsServer`, `createHostDiagnosticsBackendModule` | Node / Theia backend |
108
116
 
109
117
  Every subpath also has a `./lib/<name>` twin for consumers on
110
118
  `moduleResolution: "Node"`. "Gated" means the repository's neutral-bundle check
@@ -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
- * `AbstractDataServiceFrontend` rebuild its proxy rather than hold one.
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
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"channel-connection.js","sourceRoot":"","sources":["../../src/browser/channel-connection.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"channel-connection.js","sourceRoot":"","sources":["../../src/browser/channel-connection.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,83 @@
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 { ChannelLogger, ConnectionReporter, type ConnectionAttempt, type ConnectionTarget } from '@hydranium/client-theia/lib/browser';
10
+ import { type DataPort, type ResolvedMessage, type RpcConnectionLifecycle } from '@hydranium/protocol';
11
+ import { Emitter, MessageService, type Event } from '@theia/core';
12
+ import { type ServiceConnectionProvider } from '@theia/core/lib/browser';
13
+ import { WorkspaceService } from '@theia/workspace/lib/browser';
14
+ import type { MessageConnection } from 'vscode-jsonrpc';
15
+ import { type ChannelConnectionHandle } from './channel-connection';
16
+ /**
17
+ * A {@link DataPort} over a Theia frontend channel.
18
+ *
19
+ * Subclasses supply {@link servicePath}; everything above the port —
20
+ * `DataConnection`, its sessions, and whatever model a widget drives — is
21
+ * host-neutral and shared with the VS Code and browser shells.
22
+ *
23
+ * Bind one per service path and in singleton scope. Theia keys a frontend
24
+ * channel by its path and refuses a second on a path already open, and the
25
+ * throw escapes the `openChannelConnection` the loser is awaiting, leaving that
26
+ * promise unsettled rather than rejected.
27
+ */
28
+ export declare abstract class ChannelDataPort implements DataPort {
29
+ protected readonly connectionProvider: ServiceConnectionProvider;
30
+ protected readonly workspaceService: WorkspaceService;
31
+ protected readonly messageService: MessageService;
32
+ protected readonly connectionReporter: ConnectionReporter;
33
+ protected readonly logger: ChannelLogger;
34
+ /** Frontend service path the backend forwarder for this head is registered under. */
35
+ protected abstract readonly servicePath: string;
36
+ /**
37
+ * Re-open the channel when the current connection is lost. Default `true` —
38
+ * re-opening is the only thing that recovers a restarted language server,
39
+ * which binds new ephemeral ports. Turn it off for a frontend that tears
40
+ * itself down on transport loss instead.
41
+ */
42
+ protected readonly reconnectOnConnectionLoss: boolean;
43
+ protected readonly disposeEmitter: Emitter<void>;
44
+ readonly onDispose: Event<void>;
45
+ protected handle?: ChannelConnectionHandle;
46
+ /** How long a connection may take before it is reported as failed; it keeps trying after. */
47
+ protected readonly connectFailureNoticeMs: number;
48
+ protected attempt?: ConnectionAttempt;
49
+ protected attemptTimer?: ReturnType<typeof setTimeout>;
50
+ /** Set once {@link connectionLifecycle} reports, which then owns the connection failures. */
51
+ protected reportsConnections: boolean;
52
+ /** Reports each connection generation through the {@link ConnectionReporter}. */
53
+ readonly connectionLifecycle: RpcConnectionLifecycle;
54
+ /**
55
+ * Open the workspace-gated channel and hand back its listening connection.
56
+ *
57
+ * Gated because the backend forwarder discovers the head's port by executing
58
+ * a command the language server answers, and the language server only
59
+ * launches once there is a workspace to launch it for. Asking earlier polls
60
+ * a command nobody has registered.
61
+ */
62
+ connect(): Promise<MessageConnection>;
63
+ /**
64
+ * Surface a transport or write failure as a Theia notification.
65
+ *
66
+ * Swallowing it is the failure this exists to prevent: a dead connection and
67
+ * an empty document are indistinguishable in a widget.
68
+ *
69
+ * `reported` is already a complete sentence with the detail interpolated, so
70
+ * wrapping it in a sentence of the host's own would nest one owner's clause
71
+ * inside another's and leave no translator in control of the whole.
72
+ */
73
+ reportError(_error: unknown, reported: ResolvedMessage): void;
74
+ /** End the current attempt through `settle`, or cancel it. */
75
+ protected settleAttempt(settle?: (attempt: ConnectionAttempt) => void): void;
76
+ protected get connectionTarget(): ConnectionTarget;
77
+ /** One object per port: the reporter keys what it has shown on it. */
78
+ protected cachedConnectionTarget?: ConnectionTarget;
79
+ protected unreachableMessage(): string;
80
+ protected connectTimeoutMessage(): string;
81
+ dispose(): void;
82
+ }
83
+ //# sourceMappingURL=channel-data-port.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"channel-data-port.d.ts","sourceRoot":"","sources":["../../src/browser/channel-data-port.ts"],"names":[],"mappings":"AAAA;;;;;;;kFAOkF;AAElF,OAAO,EAAE,aAAa,EAAE,kBAAkB,EAAE,KAAK,iBAAiB,EAAE,KAAK,gBAAgB,EAAE,MAAM,qCAAqC,CAAC;AACvI,OAAO,EAIJ,KAAK,QAAQ,EACb,KAAK,eAAe,EACpB,KAAK,sBAAsB,EAC7B,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,OAAO,EAAE,cAAc,EAAO,KAAK,KAAK,EAAE,MAAM,aAAa,CAAC;AACvE,OAAO,EAAE,KAAK,yBAAyB,EAAE,MAAM,yBAAyB,CAAC;AAGzE,OAAO,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AAChE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACxD,OAAO,EAAE,KAAK,uBAAuB,EAAyB,MAAM,sBAAsB,CAAC;AAG3F;;;;;;;;;;;GAWG;AACH,8BACsB,eAAgB,YAAW,QAAQ;IACpB,SAAS,CAAC,QAAQ,CAAC,kBAAkB,EAAG,yBAAyB,CAAC;IAC1E,SAAS,CAAC,QAAQ,CAAC,gBAAgB,EAAG,gBAAgB,CAAC;IACzD,SAAS,CAAC,QAAQ,CAAC,cAAc,EAAG,cAAc,CAAC;IAC/C,SAAS,CAAC,QAAQ,CAAC,kBAAkB,EAAG,kBAAkB,CAAC;IAChE,SAAS,CAAC,QAAQ,CAAC,MAAM,EAAG,aAAa,CAAC;IAEjE,qFAAqF;IACrF,SAAS,CAAC,QAAQ,CAAC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAEhD;;;;;OAKG;IACH,SAAS,CAAC,QAAQ,CAAC,yBAAyB,EAAE,OAAO,CAAQ;IAE7D,SAAS,CAAC,QAAQ,CAAC,cAAc,gBAAuB;IACxD,QAAQ,CAAC,SAAS,EAAE,KAAK,CAAC,IAAI,CAAC,CAA6B;IAE5D,SAAS,CAAC,MAAM,CAAC,EAAE,uBAAuB,CAAC;IAE3C,6FAA6F;IAC7F,SAAS,CAAC,QAAQ,CAAC,sBAAsB,EAAE,MAAM,CAAU;IAC3D,SAAS,CAAC,OAAO,CAAC,EAAE,iBAAiB,CAAC;IACtC,SAAS,CAAC,YAAY,CAAC,EAAE,UAAU,CAAC,OAAO,UAAU,CAAC,CAAC;IACvD,6FAA6F;IAC7F,SAAS,CAAC,kBAAkB,UAAS;IAErC,iFAAiF;IACjF,QAAQ,CAAC,mBAAmB,EAAE,sBAAsB,CAclD;IAEF;;;;;;;OAOG;IACH,OAAO,IAAI,OAAO,CAAC,iBAAiB,CAAC,CAgBpC;IAED;;;;;;;;;OASG;IACH,WAAW,CAAC,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,eAAe,GAAG,IAAI,CAS5D;IAED,8DAA8D;IAC9D,SAAS,CAAC,aAAa,CAAC,MAAM,GAAE,CAAC,OAAO,EAAE,iBAAiB,KAAK,IAAqC,GAAG,IAAI,CAO3G;IAED,SAAS,KAAK,gBAAgB,IAAI,gBAAgB,CAKjD;IACD,sEAAsE;IACtE,SAAS,CAAC,sBAAsB,CAAC,EAAE,gBAAgB,CAAC;IAEpD,SAAS,CAAC,kBAAkB,IAAI,MAAM,CAErC;IAED,SAAS,CAAC,qBAAqB,IAAI,MAAM,CAMxC;IAED,OAAO,IAAI,IAAI,CAMd;CACH"}
@@ -0,0 +1,179 @@
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 __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
11
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
12
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
13
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
14
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
15
+ };
16
+ var __metadata = (this && this.__metadata) || function (k, v) {
17
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
18
+ };
19
+ Object.defineProperty(exports, "__esModule", { value: true });
20
+ exports.ChannelDataPort = void 0;
21
+ const browser_1 = require("@hydranium/client-theia/lib/browser");
22
+ const protocol_1 = require("@hydranium/protocol");
23
+ const core_1 = require("@theia/core");
24
+ const service_connection_provider_1 = require("@theia/core/lib/browser/messaging/service-connection-provider");
25
+ const inversify_1 = require("@theia/core/shared/inversify");
26
+ const browser_2 = require("@theia/workspace/lib/browser");
27
+ const channel_connection_1 = require("./channel-connection");
28
+ const workspace_gate_1 = require("./workspace-gate");
29
+ /**
30
+ * A {@link DataPort} over a Theia frontend channel.
31
+ *
32
+ * Subclasses supply {@link servicePath}; everything above the port —
33
+ * `DataConnection`, its sessions, and whatever model a widget drives — is
34
+ * host-neutral and shared with the VS Code and browser shells.
35
+ *
36
+ * Bind one per service path and in singleton scope. Theia keys a frontend
37
+ * channel by its path and refuses a second on a path already open, and the
38
+ * throw escapes the `openChannelConnection` the loser is awaiting, leaving that
39
+ * promise unsettled rather than rejected.
40
+ */
41
+ let ChannelDataPort = class ChannelDataPort {
42
+ connectionProvider;
43
+ workspaceService;
44
+ messageService;
45
+ connectionReporter;
46
+ logger;
47
+ /**
48
+ * Re-open the channel when the current connection is lost. Default `true` —
49
+ * re-opening is the only thing that recovers a restarted language server,
50
+ * which binds new ephemeral ports. Turn it off for a frontend that tears
51
+ * itself down on transport loss instead.
52
+ */
53
+ reconnectOnConnectionLoss = true;
54
+ disposeEmitter = new core_1.Emitter();
55
+ onDispose = this.disposeEmitter.event;
56
+ handle;
57
+ /** How long a connection may take before it is reported as failed; it keeps trying after. */
58
+ connectFailureNoticeMs = 30_000;
59
+ attempt;
60
+ attemptTimer;
61
+ /** Set once {@link connectionLifecycle} reports, which then owns the connection failures. */
62
+ reportsConnections = false;
63
+ /** Reports each connection generation through the {@link ConnectionReporter}. */
64
+ connectionLifecycle = {
65
+ onConnecting: () => {
66
+ this.reportsConnections = true;
67
+ this.settleAttempt();
68
+ const attempt = this.connectionReporter.connecting(this.connectionTarget);
69
+ this.attempt = attempt;
70
+ this.attemptTimer = setTimeout(() => {
71
+ attempt.failed(this.connectTimeoutMessage());
72
+ // The generation keeps waiting; a follow-up attempt reports it connecting.
73
+ this.attempt = this.connectionReporter.connecting(this.connectionTarget);
74
+ }, this.connectFailureNoticeMs);
75
+ },
76
+ onReady: () => this.settleAttempt(attempt => attempt.connected()),
77
+ onFailed: () => this.settleAttempt(attempt => attempt.failed(this.unreachableMessage()))
78
+ };
79
+ /**
80
+ * Open the workspace-gated channel and hand back its listening connection.
81
+ *
82
+ * Gated because the backend forwarder discovers the head's port by executing
83
+ * a command the language server answers, and the language server only
84
+ * launches once there is a workspace to launch it for. Asking earlier polls
85
+ * a command nobody has registered.
86
+ */
87
+ connect() {
88
+ // Read per call rather than cached: `current` is repointed at a fresh
89
+ // promise every time the channel is re-opened, so reading through the
90
+ // handle is what makes a later generation reach the live server.
91
+ if (!this.handle) {
92
+ this.handle = (0, channel_connection_1.openChannelConnection)(this.connectionProvider, this.servicePath, {
93
+ whenReady: (0, workspace_gate_1.whenWorkspaceOpen)(this.workspaceService),
94
+ reconnect: this.reconnectOnConnectionLoss
95
+ });
96
+ // A relaunched server binds new ephemeral ports; the handle re-opens
97
+ // and the forwarder rediscovers, but `DataConnection` caches its
98
+ // generation and would go on addressing the dead one. Its signal to
99
+ // drop that generation is this event.
100
+ this.handle.onDidLoseConnection(() => this.disposeEmitter.fire(undefined));
101
+ }
102
+ return this.handle.current;
103
+ }
104
+ /**
105
+ * Surface a transport or write failure as a Theia notification.
106
+ *
107
+ * Swallowing it is the failure this exists to prevent: a dead connection and
108
+ * an empty document are indistinguishable in a widget.
109
+ *
110
+ * `reported` is already a complete sentence with the detail interpolated, so
111
+ * wrapping it in a sentence of the host's own would nest one owner's clause
112
+ * inside another's and leave no translator in control of the whole.
113
+ */
114
+ reportError(_error, reported) {
115
+ const connectionFailure = reported.code === protocol_1.DATA_SERVER_CONNECT_FAILED.code || reported.code === protocol_1.DATA_SERVER_NOT_READY.code;
116
+ const message = (0, protocol_1.renderFrameworkMessage)(reported, core_1.nls.localization?.translations);
117
+ if (connectionFailure && this.reportsConnections) {
118
+ // The reporter shows the failure without its detail, so it is kept here.
119
+ this.logger.warn(message);
120
+ return;
121
+ }
122
+ this.messageService.error(message);
123
+ }
124
+ /** End the current attempt through `settle`, or cancel it. */
125
+ settleAttempt(settle = attempt => attempt.cancelled()) {
126
+ clearTimeout(this.attemptTimer);
127
+ const attempt = this.attempt;
128
+ this.attempt = undefined;
129
+ if (attempt) {
130
+ settle(attempt);
131
+ }
132
+ }
133
+ get connectionTarget() {
134
+ return (this.cachedConnectionTarget ??= {
135
+ connectingMessage: core_1.nls.localize('hydranium/data-client-theia/data-server-connecting', 'Connecting to the data server…'),
136
+ connectedMessage: core_1.nls.localize('hydranium/data-client-theia/data-server-connected', 'Connected to the data server.')
137
+ });
138
+ }
139
+ /** One object per port: the reporter keys what it has shown on it. */
140
+ cachedConnectionTarget;
141
+ unreachableMessage() {
142
+ return core_1.nls.localize('hydranium/data-client-theia/data-server-unreachable', 'Could not connect to the data server.');
143
+ }
144
+ connectTimeoutMessage() {
145
+ return core_1.nls.localize('hydranium/data-client-theia/data-server-timeout', 'The data server did not answer within {0} seconds.', String(Math.round(this.connectFailureNoticeMs / 1000)));
146
+ }
147
+ dispose() {
148
+ this.settleAttempt();
149
+ this.handle?.dispose();
150
+ this.handle = undefined;
151
+ this.disposeEmitter.fire(undefined);
152
+ this.disposeEmitter.dispose();
153
+ }
154
+ };
155
+ exports.ChannelDataPort = ChannelDataPort;
156
+ __decorate([
157
+ (0, inversify_1.inject)(service_connection_provider_1.RemoteConnectionProvider),
158
+ __metadata("design:type", Function)
159
+ ], ChannelDataPort.prototype, "connectionProvider", void 0);
160
+ __decorate([
161
+ (0, inversify_1.inject)(browser_2.WorkspaceService),
162
+ __metadata("design:type", browser_2.WorkspaceService)
163
+ ], ChannelDataPort.prototype, "workspaceService", void 0);
164
+ __decorate([
165
+ (0, inversify_1.inject)(core_1.MessageService),
166
+ __metadata("design:type", core_1.MessageService)
167
+ ], ChannelDataPort.prototype, "messageService", void 0);
168
+ __decorate([
169
+ (0, inversify_1.inject)(browser_1.ConnectionReporter),
170
+ __metadata("design:type", Object)
171
+ ], ChannelDataPort.prototype, "connectionReporter", void 0);
172
+ __decorate([
173
+ (0, inversify_1.inject)(browser_1.ChannelLogger),
174
+ __metadata("design:type", browser_1.ChannelLogger)
175
+ ], ChannelDataPort.prototype, "logger", void 0);
176
+ exports.ChannelDataPort = ChannelDataPort = __decorate([
177
+ (0, inversify_1.injectable)()
178
+ ], ChannelDataPort);
179
+ //# sourceMappingURL=channel-data-port.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"channel-data-port.js","sourceRoot":"","sources":["../../src/browser/channel-data-port.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,64 @@
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 { DataConnection, DataServerProtocol, DataSession, DiagnosticOf, TransferElement } from '@hydranium/protocol';
10
+ import type { FrontendApplicationContribution, OnWillStopAction } from '@theia/core/lib/browser';
11
+ /**
12
+ * Ends a Theia frontend's data sessions with its page, and holds the page
13
+ * while one of them is still saving. Bind it as a
14
+ * `FrontendApplicationContribution` in singleton scope and {@link track} each
15
+ * data connection the frontend binds, once.
16
+ *
17
+ * **Stop.** {@link onStop} disposes every tracked session, which sends its
18
+ * `closeSession`, so the server ends it as closed: each document it was the
19
+ * last to hold reverts at once. Otherwise the server learns of the page only
20
+ * when its connection goes, which Theia may hold open for its reconnect
21
+ * timeout, and then ends the sessions as lost, so their documents wait out the
22
+ * revert grace. The close is best effort: under load the page's last frames
23
+ * can be lost on the way, and the server then ends the sessions as lost. A
24
+ * session with calls still in flight at the stop closes after them, which is
25
+ * too late for a page going away, and is left to the server's connection-close
26
+ * cleanup. A call a session makes in the same tick as the stop is refused and
27
+ * never sent.
28
+ *
29
+ * **Veto.** While a tracked session has a save in flight, {@link onWillStop}
30
+ * vetoes, including a session disposed meanwhile. In Electron, Theia awaits
31
+ * the veto's action, which waits for the saves to answer, a save started during
32
+ * the wait included, up to {@link maxSettlePasses} times. The browser runs no
33
+ * action before unload, so there the veto shows the leave-page prompt and
34
+ * nothing more. Theia ignores every veto under
35
+ * `application.confirmExit: 'never'`, so there a save in flight at the stop
36
+ * may be cut off.
37
+ */
38
+ export declare class DataSessionStopContribution implements FrontendApplicationContribution {
39
+ /** The sessions to end at the stop, and to wait for while they save. */
40
+ protected readonly sessions: Set<DataSession<TransferElement, DataServerProtocol<TransferElement, import("@hydranium/protocol").TransferDiagnostic, import("@hydranium/protocol").Project>>>;
41
+ /**
42
+ * How many times the veto's action waits for the saves in flight before it
43
+ * lets the stop go. Each wait ends by the session's own bound, so a save
44
+ * that never answers holds the stop for a few bounds, not for good.
45
+ */
46
+ protected readonly maxSettlePasses: number;
47
+ /**
48
+ * Take every session of `connection` into the stop: the ones it has
49
+ * started already, and each one it starts from now on. Generic, so a
50
+ * connection of any transfer root, server and client fits.
51
+ */
52
+ track<TTransfer extends TransferElement, TServer extends DataServerProtocol<TTransfer, DiagnosticOf<TServer>>, TClient extends object>(connection: DataConnection<TTransfer, TServer, TClient>): void;
53
+ /**
54
+ * Take `session` into the stop. It leaves once it has ended and its saves
55
+ * have answered, so a session disposed with a save in flight still holds
56
+ * the page.
57
+ */
58
+ protected trackSession(session: DataSession<TransferElement>): void;
59
+ onWillStop(): OnWillStopAction | undefined;
60
+ /** The tracked sessions with a save in flight. */
61
+ protected savingSessions(): DataSession<TransferElement>[];
62
+ onStop(): void;
63
+ }
64
+ //# sourceMappingURL=data-session-stop-contribution.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"data-session-stop-contribution.d.ts","sourceRoot":"","sources":["../../src/browser/data-session-stop-contribution.ts"],"names":[],"mappings":"AAAA;;;;;;;kFAOkF;AAElF,OAAO,KAAK,EAAE,cAAc,EAAE,kBAAkB,EAAE,WAAW,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAG1H,OAAO,KAAK,EAAE,+BAA+B,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAGjG;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,qBACa,2BAA4B,YAAW,+BAA+B;IAChF,wEAAwE;IACxE,SAAS,CAAC,QAAQ,CAAC,QAAQ,kKAA2C;IACtE;;;;OAIG;IACH,SAAS,CAAC,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAK;IAE/C;;;;OAIG;IACH,KAAK,CAAC,SAAS,SAAS,eAAe,EAAE,OAAO,SAAS,kBAAkB,CAAC,SAAS,EAAE,YAAY,CAAC,OAAO,CAAC,CAAC,EAAE,OAAO,SAAS,MAAM,EAClI,UAAU,EAAE,cAAc,CAAC,SAAS,EAAE,OAAO,EAAE,OAAO,CAAC,GACvD,IAAI,CAGN;IAED;;;;OAIG;IACH,SAAS,CAAC,YAAY,CAAC,OAAO,EAAE,WAAW,CAAC,eAAe,CAAC,GAAG,IAAI,CAYlE;IAED,UAAU,IAAI,gBAAgB,GAAG,SAAS,CAoBzC;IAED,kDAAkD;IAClD,SAAS,CAAC,cAAc,IAAI,WAAW,CAAC,eAAe,CAAC,EAAE,CAEzD;IAED,MAAM,IAAI,IAAI,CAIb;CACH"}
@@ -0,0 +1,117 @@
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
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
11
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
12
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
13
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
14
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ exports.DataSessionStopContribution = void 0;
18
+ const inversify_1 = require("@theia/core/shared/inversify");
19
+ /**
20
+ * Ends a Theia frontend's data sessions with its page, and holds the page
21
+ * while one of them is still saving. Bind it as a
22
+ * `FrontendApplicationContribution` in singleton scope and {@link track} each
23
+ * data connection the frontend binds, once.
24
+ *
25
+ * **Stop.** {@link onStop} disposes every tracked session, which sends its
26
+ * `closeSession`, so the server ends it as closed: each document it was the
27
+ * last to hold reverts at once. Otherwise the server learns of the page only
28
+ * when its connection goes, which Theia may hold open for its reconnect
29
+ * timeout, and then ends the sessions as lost, so their documents wait out the
30
+ * revert grace. The close is best effort: under load the page's last frames
31
+ * can be lost on the way, and the server then ends the sessions as lost. A
32
+ * session with calls still in flight at the stop closes after them, which is
33
+ * too late for a page going away, and is left to the server's connection-close
34
+ * cleanup. A call a session makes in the same tick as the stop is refused and
35
+ * never sent.
36
+ *
37
+ * **Veto.** While a tracked session has a save in flight, {@link onWillStop}
38
+ * vetoes, including a session disposed meanwhile. In Electron, Theia awaits
39
+ * the veto's action, which waits for the saves to answer, a save started during
40
+ * the wait included, up to {@link maxSettlePasses} times. The browser runs no
41
+ * action before unload, so there the veto shows the leave-page prompt and
42
+ * nothing more. Theia ignores every veto under
43
+ * `application.confirmExit: 'never'`, so there a save in flight at the stop
44
+ * may be cut off.
45
+ */
46
+ let DataSessionStopContribution = class DataSessionStopContribution {
47
+ /** The sessions to end at the stop, and to wait for while they save. */
48
+ sessions = new Set();
49
+ /**
50
+ * How many times the veto's action waits for the saves in flight before it
51
+ * lets the stop go. Each wait ends by the session's own bound, so a save
52
+ * that never answers holds the stop for a few bounds, not for good.
53
+ */
54
+ maxSettlePasses = 3;
55
+ /**
56
+ * Take every session of `connection` into the stop: the ones it has
57
+ * started already, and each one it starts from now on. Generic, so a
58
+ * connection of any transfer root, server and client fits.
59
+ */
60
+ track(connection) {
61
+ connection.liveSessions.forEach(session => this.trackSession(session));
62
+ connection.onDidCreateSession(session => this.trackSession(session));
63
+ }
64
+ /**
65
+ * Take `session` into the stop. It leaves once it has ended and its saves
66
+ * have answered, so a session disposed with a save in flight still holds
67
+ * the page.
68
+ */
69
+ trackSession(session) {
70
+ this.sessions.add(session);
71
+ // A save can outlast the wait's bound, so the session stays until none
72
+ // is left in flight.
73
+ const release = () => void session.whenSavesSettled().then(() => (session.hasSavesInFlight ? release() : this.sessions.delete(session)));
74
+ // An ended session has fired its event already, and never fires it again.
75
+ if (session.isDisposed) {
76
+ release();
77
+ }
78
+ else {
79
+ session.onDidDispose(release);
80
+ }
81
+ }
82
+ onWillStop() {
83
+ if (this.savingSessions().length === 0) {
84
+ return undefined;
85
+ }
86
+ return {
87
+ // Theia logs the reason and shows it nowhere, so it is not translated.
88
+ reason: 'Data sessions are saving',
89
+ action: async () => {
90
+ // The page stays usable while Theia awaits this, so a save can
91
+ // start during a wait; each pass waits for the saves then in flight.
92
+ for (let pass = 0; pass < this.maxSettlePasses; pass++) {
93
+ const saving = this.savingSessions();
94
+ if (saving.length === 0) {
95
+ break;
96
+ }
97
+ await Promise.all(saving.map(session => session.whenSavesSettled()));
98
+ }
99
+ return true;
100
+ }
101
+ };
102
+ }
103
+ /** The tracked sessions with a save in flight. */
104
+ savingSessions() {
105
+ return [...this.sessions].filter(session => session.hasSavesInFlight);
106
+ }
107
+ onStop() {
108
+ for (const session of this.sessions) {
109
+ session.dispose();
110
+ }
111
+ }
112
+ };
113
+ exports.DataSessionStopContribution = DataSessionStopContribution;
114
+ exports.DataSessionStopContribution = DataSessionStopContribution = __decorate([
115
+ (0, inversify_1.injectable)()
116
+ ], DataSessionStopContribution);
117
+ //# sourceMappingURL=data-session-stop-contribution.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"data-session-stop-contribution.js","sourceRoot":"","sources":["../../src/browser/data-session-stop-contribution.ts"],"names":[],"mappings":";AAAA;;;;;;;kFAOkF;;;;;;;;;AAMlF,4DAA0D;AAE1D;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEI,IAAM,2BAA2B,GAAjC,MAAM,2BAA2B;IACrC,wEAAwE;IACrD,QAAQ,GAAG,IAAI,GAAG,EAAgC,CAAC;IACtE;;;;OAIG;IACgB,eAAe,GAAW,CAAC,CAAC;IAE/C;;;;OAIG;IACH,KAAK,CACF,UAAuD;QAEvD,UAAU,CAAC,YAAY,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC,CAAC;QACvE,UAAU,CAAC,kBAAkB,CAAC,OAAO,CAAC,EAAE,CAAC,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC,CAAC;IACxE,CAAC;IAED;;;;OAIG;IACO,YAAY,CAAC,OAAqC;QACzD,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QAC3B,uEAAuE;QACvE,qBAAqB;QACrB,MAAM,OAAO,GAAG,GAAS,EAAE,CACxB,KAAK,OAAO,CAAC,gBAAgB,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,OAAO,CAAC,gBAAgB,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;QACtH,0EAA0E;QAC1E,IAAI,OAAO,CAAC,UAAU,EAAE,CAAC;YACtB,OAAO,EAAE,CAAC;QACb,CAAC;aAAM,CAAC;YACL,OAAO,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC;QACjC,CAAC;IACJ,CAAC;IAED,UAAU;QACP,IAAI,IAAI,CAAC,cAAc,EAAE,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACtC,OAAO,SAAS,CAAC;QACpB,CAAC;QACD,OAAO;YACJ,uEAAuE;YACvE,MAAM,EAAE,0BAA0B;YAClC,MAAM,EAAE,KAAK,IAAI,EAAE;gBAChB,+DAA+D;gBAC/D,qEAAqE;gBACrE,KAAK,IAAI,IAAI,GAAG,CAAC,EAAE,IAAI,GAAG,IAAI,CAAC,eAAe,EAAE,IAAI,EAAE,EAAE,CAAC;oBACtD,MAAM,MAAM,GAAG,IAAI,CAAC,cAAc,EAAE,CAAC;oBACrC,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;wBACvB,MAAM;oBACT,CAAC;oBACD,MAAM,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAAC,CAAC;gBACxE,CAAC;gBACD,OAAO,IAAI,CAAC;YACf,CAAC;SACH,CAAC;IACL,CAAC;IAED,kDAAkD;IACxC,cAAc;QACrB,OAAO,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,OAAO,CAAC,gBAAgB,CAAC,CAAC;IACzE,CAAC;IAED,MAAM;QACH,KAAK,MAAM,OAAO,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YACnC,OAAO,CAAC,OAAO,EAAE,CAAC;QACrB,CAAC;IACJ,CAAC;CACH,CAAA;;sCAzEY,2BAA2B;IADvC,IAAA,sBAAU,GAAE;GACA,2BAA2B,CAyEvC"}
@@ -1 +1 @@
1
- {"version":3,"file":"host-diagnostics-frontend.js","sourceRoot":"","sources":["../../src/browser/host-diagnostics-frontend.ts"],"names":[],"mappings":";AAAA;;;;;;;kFAOkF;;AAelF,kDAOC;AApBD,iEAAmF;AACnF,kDAA0F;AAC1F,+GAAyI;AAGzI;;;;;;;GAOG;AACH,SAAgB,mBAAmB,CAAC,IAAqB;IACtD,IAAI,CAAC,sCAA4B,CAAC;SAC9B,cAAc,CAAC,OAAO,CAAC,EAAE;QACvB,MAAM,QAAQ,GAAG,OAAO,CAAC,SAAS,CAAC,GAAG,CAA4B,sDAAwB,CAAC,CAAC;QAC5F,OAAO,QAAQ,CAAC,WAAW,CAA0B,gCAAqB,CAAC,CAAC;IAC/E,CAAC,CAAC;SACD,gBAAgB,EAAE,CAAC;AAC1B,CAAC"}
1
+ {"version":3,"file":"host-diagnostics-frontend.js","sourceRoot":"","sources":["../../src/browser/host-diagnostics-frontend.ts"],"names":[],"mappings":";AAAA;;;;;;;kFAOkF;;;AAElF,iEAAmF;AACnF,kDAA0F;AAC1F,+GAAyI;AAGzI;;;;;;;GAOG;AACH,6BAAoC,IAAqB;IACtD,IAAI,CAAC,sCAA4B,CAAC;SAC9B,cAAc,CAAC,OAAO,CAAC,EAAE;QACvB,MAAM,QAAQ,GAAG,OAAO,CAAC,SAAS,CAAC,GAAG,CAA4B,sDAAwB,CAAC,CAAC;QAC5F,OAAO,QAAQ,CAAC,WAAW,CAA0B,gCAAqB,CAAC,CAAC;IAC/E,CAAC,CAAC;SACD,gBAAgB,EAAE,CAAC;AAC1B,CAAC"}