@hydranium/data-client-theia 1.0.0-next.28 → 1.0.0-next.280

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 (70) hide show
  1. package/README.md +57 -101
  2. package/lib/browser/channel-connection.d.ts +11 -8
  3. package/lib/browser/channel-connection.d.ts.map +1 -1
  4. package/lib/browser/channel-connection.js +7 -5
  5. package/lib/browser/channel-connection.js.map +1 -1
  6. package/lib/browser/channel-data-port.d.ts +92 -0
  7. package/lib/browser/channel-data-port.d.ts.map +1 -0
  8. package/lib/browser/channel-data-port.js +199 -0
  9. package/lib/browser/channel-data-port.js.map +1 -0
  10. package/lib/browser/data-session-stop-contribution.d.ts +76 -0
  11. package/lib/browser/data-session-stop-contribution.d.ts.map +1 -0
  12. package/lib/browser/data-session-stop-contribution.js +146 -0
  13. package/lib/browser/data-session-stop-contribution.js.map +1 -0
  14. package/lib/browser/host-diagnostics-frontend.js +1 -1
  15. package/lib/browser/host-diagnostics-frontend.js.map +1 -1
  16. package/lib/browser/index.d.ts +2 -3
  17. package/lib/browser/index.d.ts.map +1 -1
  18. package/lib/browser/index.js +2 -3
  19. package/lib/browser/index.js.map +1 -1
  20. package/lib/browser/workspace-gate.js.map +1 -1
  21. package/lib/common/emitter-data-client.d.ts +13 -1
  22. package/lib/common/emitter-data-client.d.ts.map +1 -1
  23. package/lib/common/emitter-data-client.js +18 -0
  24. package/lib/common/emitter-data-client.js.map +1 -1
  25. package/lib/node/connection-container-module.d.ts +5 -4
  26. package/lib/node/connection-container-module.d.ts.map +1 -1
  27. package/lib/node/connection-container-module.js +5 -4
  28. package/lib/node/connection-container-module.js.map +1 -1
  29. package/lib/node/data-server-connection-handler.d.ts +9 -19
  30. package/lib/node/data-server-connection-handler.d.ts.map +1 -1
  31. package/lib/node/data-server-connection-handler.js +9 -13
  32. package/lib/node/data-server-connection-handler.js.map +1 -1
  33. package/lib/node/host-diagnostics-server.d.ts.map +1 -1
  34. package/lib/node/host-diagnostics-server.js +1 -1
  35. package/lib/node/host-diagnostics-server.js.map +1 -1
  36. package/lib/node/index.d.ts +0 -1
  37. package/lib/node/index.d.ts.map +1 -1
  38. package/lib/node/index.js +0 -1
  39. package/lib/node/index.js.map +1 -1
  40. package/package.json +25 -39
  41. package/src/browser/channel-connection.ts +16 -12
  42. package/src/browser/channel-data-port.ts +189 -0
  43. package/src/browser/data-session-stop-contribution.ts +151 -0
  44. package/src/browser/host-diagnostics-frontend.ts +1 -1
  45. package/src/browser/index.ts +2 -3
  46. package/src/common/emitter-data-client.ts +27 -0
  47. package/src/node/connection-container-module.ts +5 -4
  48. package/src/node/data-server-connection-handler.ts +10 -23
  49. package/src/node/host-diagnostics-server.ts +1 -1
  50. package/src/node/index.ts +0 -1
  51. package/lib/browser/data-service-frontend.d.ts +0 -154
  52. package/lib/browser/data-service-frontend.d.ts.map +0 -1
  53. package/lib/browser/data-service-frontend.js +0 -169
  54. package/lib/browser/data-service-frontend.js.map +0 -1
  55. package/lib/browser/diagnostics-data-service-frontend.d.ts +0 -35
  56. package/lib/browser/diagnostics-data-service-frontend.d.ts.map +0 -1
  57. package/lib/browser/diagnostics-data-service-frontend.js +0 -54
  58. package/lib/browser/diagnostics-data-service-frontend.js.map +0 -1
  59. package/lib/browser/references-data-service-frontend.d.ts +0 -45
  60. package/lib/browser/references-data-service-frontend.d.ts.map +0 -1
  61. package/lib/browser/references-data-service-frontend.js +0 -55
  62. package/lib/browser/references-data-service-frontend.js.map +0 -1
  63. package/lib/node/socket-channel-forwarder.d.ts +0 -34
  64. package/lib/node/socket-channel-forwarder.d.ts.map +0 -1
  65. package/lib/node/socket-channel-forwarder.js +0 -68
  66. package/lib/node/socket-channel-forwarder.js.map +0 -1
  67. package/src/browser/data-service-frontend.ts +0 -208
  68. package/src/browser/diagnostics-data-service-frontend.ts +0 -70
  69. package/src/browser/references-data-service-frontend.ts +0 -70
  70. package/src/node/socket-channel-forwarder.ts +0 -69
package/README.md CHANGED
@@ -1,57 +1,20 @@
1
1
  # `@hydranium/data-client-theia`
2
2
 
3
- Theia client primitives for the hydranium **data head** — the companion of
4
- `@hydranium/data-server` in the
5
- [Hydranium](https://github.com/eclipse-emfcloud/hydranium) framework.
6
-
7
- The data head's frontend speaks the data server's own `vscode-jsonrpc` protocol
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.
3
+ The Theia connection for the
4
+ [Hydranium](https://github.com/eclipse-emfcloud/hydranium) data head, the
5
+ companion of `@hydranium/data-server`. Install it when forms, trees or views in
6
+ a Theia application work on the live model rather than on text. It builds on
7
+ `@hydranium/client-theia`.
13
8
 
14
9
  ## What it gives you
15
10
 
16
- - **`openChannelConnection`** with `createChannelConnection` and
17
- `ChannelConnectionHandle` — wraps a Theia `Channel` as a `vscode-jsonrpc`
18
- `MessageConnection`, gated on a `whenReady` promise, and by default
19
- re-establishes it by **re-opening the channel** when the connection is lost.
20
- Re-opening rather than rebuilding is what recovers a restarted language server:
21
- a server restart closes only the multiplexed sub-channel, so no replacement
22
- channel ever arrives on its own. Retries follow `DEFAULT_RECONNECT_DELAYS`,
23
- escalating per consecutive loss and resetting after
24
- `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.
38
- - **`EmitterDataClient`** (on `./common`, not `./browser`) — the default
39
- client-side implementation of the data protocol's inbound notifications,
40
- fanning each one out to a Theia `Event`: `onDidUpdateDocument`,
41
- `onDidSaveDocument`, `onDidChangeProjects`. Bind an instance as the
42
- `localTarget` of the frontend's RPC proxy. It sits on the common tier because
43
- its only runtime dependency is `@theia/core`'s root entry, which is Theia's own
44
- common tier, so a backend or a plain-Node consumer can bind it too.
45
- - **`whenWorkspaceOpen`** — resolves once Theia reports a workspace root. The data
46
- server only starts once the LSP launches for a workspace, so connecting earlier
47
- would hang in port discovery; pass this as `whenReady`.
48
- - **Backend (`./node`)** — `DataServerConnectionHandler` (the socket bridge, with
49
- its own GLSP-free `SocketChannelForwarder`),
50
- `createDataServerConnectionContainerModule(...handlers)` for the
51
- frontend-scoped module boilerplate, and `HostDiagnosticsServer` with
52
- `createHostDiagnosticsBackendModule()` — which, paired with the browser-side
53
- `bindHostDiagnostics`, lights up the "Backend" diagnostics commands in
54
- `@hydranium/client-theia`'s contribution.
11
+ - A data connection in the Theia frontend: you subclass `ChannelDataPort`, and
12
+ the connection and sessions from `@hydranium/protocol` run over it.
13
+ - A connection that waits for a workspace, and reconnects on its own when the
14
+ channel is lost, a restarted server included.
15
+ - Sessions that end with the page, and a page held while one of them saves.
16
+ - The backend handler that relays the channel to the data server's socket.
17
+ - Diagnostics commands for the Theia backend process, beside the server's.
55
18
 
56
19
  ## Install
57
20
 
@@ -59,68 +22,61 @@ code-gen driven from the live AST rather than from LSP text edits.
59
22
  npm install @hydranium/data-client-theia
60
23
  ```
61
24
 
62
- You must already have a Theia application with `@theia/workspace` available, and a
63
- running hydranium data server to connect to. The declared peer dependencies are:
64
-
65
- | Peer | Range |
66
- | ------------------------- | -------------------- |
67
- | `@hydranium/client-theia` | `^1.0.0-next` |
68
- | `@hydranium/core` | `^1.0.0-next` |
69
- | `@hydranium/protocol` | `^1.0.0-next` |
70
- | `@theia/core` | `^1.70.0` |
71
- | `@theia/workspace` | `^1.70.0` |
72
- | `inversify` | `^6.0.0` |
73
- | `vscode-jsonrpc` | `9.0.1` |
74
-
75
- `@hydranium/core` is reached only from the `./node` tier (the host-diagnostics
76
- service), so a frontend-only consumer never loads it.
25
+ | Peer | Range |
26
+ | ------------------------- | ------------- |
27
+ | `@hydranium/client-theia` | `^1.0.0-next` |
28
+ | `@hydranium/protocol` | `^1.0.0-next` |
29
+ | `@theia/core` | `^1.70.0` |
30
+ | `@theia/workspace` | `^1.70.0` |
31
+ | `inversify` | `^6.0.0` |
32
+ | `vscode-jsonrpc` | `^9.0.0` |
77
33
 
78
34
  ## Wiring
79
35
 
80
- This package declares no `theiaExtensions` — it is a library your own Theia
81
- extension builds on. That extension's `package.json` declares the entries, and
82
- each entry names one frontend/backend module pair:
83
-
84
- - the **frontend** module binds your `AbstractDataServiceFrontend` subclass (and,
85
- for the diagnostics commands, calls `bindHostDiagnostics`);
86
- - the **backend** module is typically a one-liner:
87
- `export default createDataServerConnectionContainerModule(MyHandler)`, where
88
- `MyHandler` extends `DataServerConnectionHandler`.
89
-
90
- More than one handler is the normal case, not an exotic one. Theia keys a
91
- 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.
95
-
96
- The refusal is silent, which is what makes it expensive: the loser's promise is
97
- left unsettled rather than rejected, so a frontend that shared a path hangs on
98
- its loading state indefinitely with nothing in the server log to say why.
36
+ This package declares no `theiaExtensions`; your own Theia extension declares
37
+ them and binds from here.
38
+
39
+ - In a frontend module, subclass `ChannelDataPort` with a `servicePath` and
40
+ bind it in singleton scope. Call `bindDataConnection` for the connection
41
+ over it.
42
+ - In the same frontend, call `bindChannelLogger` from
43
+ `@hydranium/client-theia`, and its `bindEditorDiskSync`, since a data server
44
+ save writes a file an editor can have open.
45
+ - For the backend diagnostics commands, call `bindHostDiagnostics` in the
46
+ frontend and export `createHostDiagnosticsBackendModule()` from a backend
47
+ module.
48
+ - In the backend, export
49
+ `createDataServerConnectionContainerModule(MyHandler)`, where `MyHandler`
50
+ extends `DataServerConnectionHandler` and names your server's port command.
51
+
52
+ Give each frontend channel its own `servicePath`. Theia refuses a second
53
+ channel on a path already open, silently: the frontend hangs with nothing in
54
+ the log. For several participants on one channel, use sessions instead.
55
+
56
+ For the whole setup, see *Host in Theia* in
57
+ [Adopting Hydranium](https://github.com/eclipse-emfcloud/hydranium/blob/main/docs/ADOPTING.md).
99
58
 
100
59
  ## Entry points
101
60
 
102
- | Subpath | Holds | Environment |
103
- | ----------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------- |
104
- | `.` | Nothing — the surface is split by environment, so the root barrel stays empty. | browser-neutral (gated) |
105
- | `./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 |
61
+ | Subpath | Use it for | Runs in |
62
+ | ----------- | ------------------------------------------------------------- | --------------- |
63
+ | `.` | Nothing; import a subpath | browser-neutral |
64
+ | `./common` | The data server's notifications as Theia events, on any side | browser-neutral |
65
+ | `./browser` | The port, the connection binding and the diagnostics proxy | Theia frontend |
66
+ | `./node` | The connection handler and the backend modules | Theia backend |
108
67
 
109
- Every subpath also has a `./lib/<name>` twin for consumers on
110
- `moduleResolution: "Node"`. "Gated" means the repository's neutral-bundle check
111
- enforces that the entry bundles for the browser with no `node:*` import,
112
- transitive ones included; `./node` is deliberately outside that gate. Also
113
- worth reading: [what "gated neutral" does and does not promise](../../docs/concepts/browser-hosting.md#a-note-on-what-gated-neutral-does-and-does-not-promise).
68
+ The subpaths need a TypeScript `moduleResolution` that reads `exports`
69
+ (`NodeNext` or `Bundler`); see *Requirements* in
70
+ [Adopting Hydranium](https://github.com/eclipse-emfcloud/hydranium/blob/main/docs/ADOPTING.md).
114
71
 
115
72
  ## Status
116
73
 
117
- Alpha — pre-v0, not yet published. The API is not stable and may change without a
118
- deprecation cycle. See [`docs/concepts/architecture.md`](../../docs/concepts/architecture.md) for
119
- the data head's place among the heads, and the
120
- [repository README](../../README.md) for current status and known limitations.
74
+ Alpha: every release is a prerelease that may break the API, so pin an exact
75
+ version. Guides and known limitations:
76
+ [Adopting Hydranium](https://github.com/eclipse-emfcloud/hydranium/blob/main/docs/ADOPTING.md).
121
77
 
122
78
  ## License
123
79
 
124
- `MIT` — see this package's [`LICENSE`](./LICENSE). Third-party notices for the
125
- runtime dependency closure are collected in the repository
126
- [`NOTICE.md`](../../NOTICE.md).
80
+ `MIT` — see this package's [`LICENSE`](./LICENSE), and the repository
81
+ [`NOTICE.md`](https://github.com/eclipse-emfcloud/hydranium/blob/main/NOTICE.md)
82
+ for third-party notices.
@@ -6,6 +6,7 @@
6
6
  *
7
7
  * SPDX-License-Identifier: MIT
8
8
  ********************************************************************************/
9
+ import { type Clock } from '@hydranium/protocol';
9
10
  import { type Channel, type Event } from '@theia/core';
10
11
  import { type ServiceConnectionProvider } from '@theia/core/lib/browser';
11
12
  import { type Logger, type MessageConnection } from 'vscode-jsonrpc/browser';
@@ -21,7 +22,7 @@ import { type Logger, type MessageConnection } from 'vscode-jsonrpc/browser';
21
22
  * Mirrors `@eclipse-glsp/theia-integration`'s `createChannelConnection`, but
22
23
  * lives here so the data-server head carries no GLSP dependency.
23
24
  */
24
- export declare function createChannelConnection(channel: Channel, logger?: Logger): MessageConnection;
25
+ export declare function createChannelConnection(channel: Channel, logger: Logger): MessageConnection;
25
26
  /** Options for {@link openChannelConnection}. */
26
27
  export interface OpenChannelConnectionOptions {
27
28
  /**
@@ -32,8 +33,10 @@ export interface OpenChannelConnectionOptions {
32
33
  * publishes the port) exists.
33
34
  */
34
35
  whenReady?: Promise<void>;
35
- /** Optional `vscode-jsonrpc` logger threaded into the connection. */
36
- logger?: Logger;
36
+ /** Where the connection logs its protocol faults; without one they leave no trace. */
37
+ logger: Logger;
38
+ /** Times the escalation reset. Default a `SystemClock`. */
39
+ clock?: Clock;
37
40
  /**
38
41
  * Re-establish the connection whenever the live one is lost, by RE-OPENING
39
42
  * the channel on `path` — not merely by rebuilding over a channel Theia hands
@@ -107,8 +110,8 @@ export interface ChannelConnectionHandle {
107
110
  /**
108
111
  * The current connection. Read it per use rather than caching it: after a
109
112
  * 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.
113
+ * dead connection forever. The same reasoning makes `RpcConnection` rebuild
114
+ * its proxy per generation rather than hold one.
112
115
  */
113
116
  readonly current: Promise<MessageConnection>;
114
117
  /**
@@ -120,10 +123,10 @@ export interface ChannelConnectionHandle {
120
123
  *
121
124
  * **This is the event a consumer wants, not {@link onDidReconnect}.** Anything
122
125
  * derived from a connection — an `createRpcProxy`, a readiness gate, a
123
- * `DataSession` generation — is dead from this moment, and a consumer that
126
+ * `DataConnection` generation — is dead from this moment, and a consumer that
124
127
  * waits for the replacement to be live instead keeps sending into the dead one
125
128
  * for the whole gap. A `DataPort` implementation translates this into the
126
- * port's own `onDispose`, which is what makes `DataSession` drop its
129
+ * port's own `onDispose`, which is what makes `DataConnection` drop its
127
130
  * generation.
128
131
  *
129
132
  * Never fires when {@link OpenChannelConnectionOptions.reconnect} is off.
@@ -170,5 +173,5 @@ export interface ChannelConnectionHandle {
170
173
  * so the consumer's request is left unsettled: a hang with a clean log, not an
171
174
  * error. Owning the re-open here means owning it exclusively.
172
175
  */
173
- export declare function openChannelConnection(connectionProvider: ServiceConnectionProvider, path: string, options?: OpenChannelConnectionOptions): ChannelConnectionHandle;
176
+ export declare function openChannelConnection(connectionProvider: ServiceConnectionProvider, path: string, options: OpenChannelConnectionOptions): ChannelConnectionHandle;
174
177
  //# sourceMappingURL=channel-connection.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"channel-connection.d.ts","sourceRoot":"","sources":["../../src/browser/channel-connection.ts"],"names":[],"mappings":"AAAA;;;;;;;kFAOkF;AAElF,OAAO,EAAE,KAAK,OAAO,EAAiC,KAAK,KAAK,EAAwB,MAAM,aAAa,CAAC;AAC5G,OAAO,EAAE,KAAK,yBAAyB,EAAE,MAAM,yBAAyB,CAAC;AAEzE,OAAO,EAMJ,KAAK,MAAM,EAEX,KAAK,iBAAiB,EAQxB,MAAM,wBAAwB,CAAC;AAkEhC;;;;;;;;;;;GAWG;AACH,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,OAAO,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,iBAAiB,CAI5F;AAED,iDAAiD;AACjD,MAAM,WAAW,4BAA4B;IAC1C;;;;;;OAMG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1B,qEAAqE;IACrE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;;;;;;;;;;;;;;;;;;;;;;;;;OA2BG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;IAEpB;;;;;;;;;;;;;;;;;;OAkBG;IACH,eAAe,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CACtC;AAED;;;;;;;;;;GAUG;AACH,eAAO,MAAM,wBAAwB,EAAE,SAAS,MAAM,EAA2C,CAAC;AAElG,iFAAiF;AACjF,eAAO,MAAM,6BAA6B,QAAS,CAAC;AAEpD;;;;GAIG;AACH,MAAM,WAAW,uBAAuB;IACrC;;;;;OAKG;IACH,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC,iBAAiB,CAAC,CAAC;IAE7C;;;;;;;;;;;;;;;;OAgBG;IACH,QAAQ,CAAC,mBAAmB,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;IAE1C;;;;;;;OAOG;IACH,QAAQ,CAAC,cAAc,EAAE,KAAK,CAAC,iBAAiB,CAAC,CAAC;IAElD;;;;;;OAMG;IACH,OAAO,IAAI,IAAI,CAAC;CAClB;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,qBAAqB,CAClC,kBAAkB,EAAE,yBAAyB,EAC7C,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE,4BAAiC,GAC1C,uBAAuB,CA4IzB"}
1
+ {"version":3,"file":"channel-connection.d.ts","sourceRoot":"","sources":["../../src/browser/channel-connection.ts"],"names":[],"mappings":"AAAA;;;;;;;kFAOkF;AAElF,OAAO,EAAE,KAAK,KAAK,EAA+B,MAAM,qBAAqB,CAAC;AAC9E,OAAO,EAAE,KAAK,OAAO,EAAiC,KAAK,KAAK,EAAwB,MAAM,aAAa,CAAC;AAC5G,OAAO,EAAE,KAAK,yBAAyB,EAAE,MAAM,yBAAyB,CAAC;AAEzE,OAAO,EAMJ,KAAK,MAAM,EAEX,KAAK,iBAAiB,EAQxB,MAAM,wBAAwB,CAAC;AAkEhC;;;;;;;;;;;GAWG;AACH,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,GAAG,iBAAiB,CAI3F;AAED,iDAAiD;AACjD,MAAM,WAAW,4BAA4B;IAC1C;;;;;;OAMG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1B,sFAAsF;IACtF,MAAM,EAAE,MAAM,CAAC;IACf,2DAA2D;IAC3D,KAAK,CAAC,EAAE,KAAK,CAAC;IACd;;;;;;;;;;;;;;;;;;;;;;;;;;;OA2BG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;IAEpB;;;;;;;;;;;;;;;;;;OAkBG;IACH,eAAe,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CACtC;AAED;;;;;;;;;;GAUG;AACH,eAAO,MAAM,wBAAwB,EAAE,SAAS,MAAM,EAA2C,CAAC;AAElG,iFAAiF;AACjF,eAAO,MAAM,6BAA6B,QAAS,CAAC;AAEpD;;;;GAIG;AACH,MAAM,WAAW,uBAAuB;IACrC;;;;;OAKG;IACH,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC,iBAAiB,CAAC,CAAC;IAE7C;;;;;;;;;;;;;;;;OAgBG;IACH,QAAQ,CAAC,mBAAmB,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;IAE1C;;;;;;;OAOG;IACH,QAAQ,CAAC,cAAc,EAAE,KAAK,CAAC,iBAAiB,CAAC,CAAC;IAElD;;;;;;OAMG;IACH,OAAO,IAAI,IAAI,CAAC;CAClB;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,qBAAqB,CAClC,kBAAkB,EAAE,yBAAyB,EAC7C,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,4BAA4B,GACrC,uBAAuB,CA6IzB"}
@@ -11,6 +11,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
11
11
  exports.RECONNECT_ESCALATION_RESET_MS = exports.DEFAULT_RECONNECT_DELAYS = void 0;
12
12
  exports.createChannelConnection = createChannelConnection;
13
13
  exports.openChannelConnection = openChannelConnection;
14
+ const protocol_1 = require("@hydranium/protocol");
14
15
  const core_1 = require("@theia/core");
15
16
  const promise_util_1 = require("@theia/core/lib/common/promise-util");
16
17
  const browser_1 = require("vscode-jsonrpc/browser");
@@ -126,7 +127,7 @@ exports.RECONNECT_ESCALATION_RESET_MS = 30_000;
126
127
  * so the consumer's request is left unsettled: a hang with a clean log, not an
127
128
  * error. Owning the re-open here means owning it exclusively.
128
129
  */
129
- function openChannelConnection(connectionProvider, path, options = {}) {
130
+ function openChannelConnection(connectionProvider, path, options) {
130
131
  const reconnect = options.reconnect ?? true;
131
132
  const reconnectDelays = options.reconnectDelays ?? exports.DEFAULT_RECONNECT_DELAYS;
132
133
  const reconnectEmitter = new core_1.Emitter();
@@ -139,8 +140,9 @@ function openChannelConnection(connectionProvider, path, options = {}) {
139
140
  let awaitingReplacement = false;
140
141
  /** Consecutive losses, indexing `reconnectDelays`. */
141
142
  let losses = 0;
142
- /** When the live connection was built, for the escalation reset. `0` before the first. */
143
- let liveSince = 0;
143
+ const clock = options.clock ?? new protocol_1.SystemClock();
144
+ /** Running since the live connection was built, for the escalation reset. */
145
+ let sinceLive;
144
146
  let reopenTimer;
145
147
  // Own synchronous flag, deliberately NOT `deferred.state`. Theia's
146
148
  // `Deferred` sets `state` inside a `.then()` on its own promise, so it is
@@ -153,7 +155,7 @@ function openChannelConnection(connectionProvider, path, options = {}) {
153
155
  // that; it takes counting the connections built per channel.
154
156
  let built = false;
155
157
  const scheduleReopen = () => {
156
- if (liveSince > 0 && Date.now() - liveSince >= exports.RECONNECT_ESCALATION_RESET_MS) {
158
+ if (sinceLive !== undefined && sinceLive.elapsedMs >= exports.RECONNECT_ESCALATION_RESET_MS) {
157
159
  losses = 0;
158
160
  }
159
161
  const delay = reconnectDelays[Math.min(losses, reconnectDelays.length - 1)];
@@ -208,7 +210,7 @@ function openChannelConnection(connectionProvider, path, options = {}) {
208
210
  built = true;
209
211
  awaitingReplacement = false;
210
212
  generation++;
211
- liveSince = Date.now();
213
+ sinceLive = clock.stopwatch();
212
214
  if (reconnect) {
213
215
  // Registered AFTER `createChannelConnection`, so the connection's own
214
216
  // reader and writer see the close first and `connection.onClose` still
@@ -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,92 @@
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/browser';
10
+ import { Clock } from '@hydranium/client-theia/common';
11
+ import { type DataPort, type ResolvedMessage, type RpcConnectionLifecycle } from '@hydranium/protocol';
12
+ import { Emitter, MessageService, type Event } from '@theia/core';
13
+ import { type ServiceConnectionProvider } from '@theia/core/lib/browser';
14
+ import { WorkspaceService } from '@theia/workspace/lib/browser';
15
+ import type { MessageConnection } from 'vscode-jsonrpc';
16
+ import { type ChannelConnectionHandle } from './channel-connection';
17
+ /**
18
+ * A {@link DataPort} over a Theia frontend channel.
19
+ *
20
+ * Subclasses supply {@link servicePath}; everything above the port —
21
+ * `DataConnection`, its sessions, and whatever model a widget drives — is
22
+ * host-neutral and shared with the VS Code and browser shells.
23
+ *
24
+ * Bind one per service path and in singleton scope. Theia keys a frontend
25
+ * channel by its path and refuses a second on a path already open, and the
26
+ * throw escapes the `openChannelConnection` the loser is awaiting, leaving that
27
+ * promise unsettled rather than rejected.
28
+ */
29
+ export declare abstract class ChannelDataPort implements DataPort {
30
+ protected readonly connectionProvider: ServiceConnectionProvider;
31
+ protected readonly workspaceService: WorkspaceService;
32
+ protected readonly messageService: MessageService;
33
+ protected readonly connectionReporter: ConnectionReporter;
34
+ readonly logger: ChannelLogger;
35
+ /** Times the channel's reconnect escalation: the container's {@link Clock}, or a `SystemClock`. */
36
+ protected readonly clock: Clock;
37
+ /** Frontend service path the backend forwarder for this head is registered under. */
38
+ protected abstract readonly servicePath: string;
39
+ /**
40
+ * Re-open the channel when the current connection is lost. Default `true` —
41
+ * re-opening is the only thing that recovers a restarted language server,
42
+ * which binds new ephemeral ports. Turn it off for a frontend that tears
43
+ * itself down on transport loss instead.
44
+ */
45
+ protected readonly reconnectOnConnectionLoss: boolean;
46
+ protected readonly disposeEmitter: Emitter<void>;
47
+ readonly onDispose: Event<void>;
48
+ protected handle?: ChannelConnectionHandle;
49
+ /** Set by {@link dispose}, after which {@link connect} rejects. */
50
+ protected disposed: boolean;
51
+ /** How long a connection may take before it is reported as failed; it keeps trying after. */
52
+ protected readonly connectFailureNoticeMs: number;
53
+ protected attempt?: ConnectionAttempt;
54
+ protected attemptTimer?: ReturnType<typeof setTimeout>;
55
+ /** Set once {@link connectionLifecycle} reports, which then owns the connection failures. */
56
+ protected reportsConnections: boolean;
57
+ /** Reports each connection generation through the {@link ConnectionReporter}. */
58
+ readonly connectionLifecycle: RpcConnectionLifecycle;
59
+ /**
60
+ * Open the workspace-gated channel and hand back its listening connection.
61
+ *
62
+ * Gated because the backend forwarder discovers the head's port by executing
63
+ * a command the language server answers, and the language server only
64
+ * launches once there is a workspace to launch it for. Asking earlier polls
65
+ * a command nobody has registered.
66
+ *
67
+ * Rejects once the port is disposed: the consumer reconnects when the
68
+ * dispose fires {@link onDispose}, and a channel opened then is closed by
69
+ * nothing.
70
+ */
71
+ connect(): Promise<MessageConnection>;
72
+ /**
73
+ * Surface a transport or write failure as a Theia notification.
74
+ *
75
+ * Swallowing it is the failure this exists to prevent: a dead connection and
76
+ * an empty document are indistinguishable in a widget.
77
+ *
78
+ * `reported` is already a complete sentence with the detail interpolated, so
79
+ * wrapping it in a sentence of the host's own would nest one owner's clause
80
+ * inside another's and leave no translator in control of the whole.
81
+ */
82
+ reportError(_error: unknown, reported: ResolvedMessage): void;
83
+ /** End the current attempt through `settle`, or cancel it. */
84
+ protected settleAttempt(settle?: (attempt: ConnectionAttempt) => void): void;
85
+ protected get connectionTarget(): ConnectionTarget;
86
+ /** One object per port: the reporter keys what it has shown on it. */
87
+ protected cachedConnectionTarget?: ConnectionTarget;
88
+ protected unreachableMessage(): string;
89
+ protected connectTimeoutMessage(): string;
90
+ dispose(): void;
91
+ }
92
+ //# 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,iCAAiC,CAAC;AACnI,OAAO,EAAE,KAAK,EAAE,MAAM,gCAAgC,CAAC;AACvD,OAAO,EAKJ,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,QAAQ,CAAC,MAAM,EAAG,aAAa,CAAC;IACvD,mGAAmG;IACxE,SAAS,CAAC,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAqB;IAE/E,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;IAC3C,mEAAmE;IACnE,SAAS,CAAC,QAAQ,UAAS;IAE3B,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;;;;;;;;;;;OAWG;IACH,OAAO,IAAI,OAAO,CAAC,iBAAiB,CAAC,CAqBpC;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,CAOd;CACH"}
@@ -0,0 +1,199 @@
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/browser");
22
+ const common_1 = require("@hydranium/client-theia/common");
23
+ const protocol_1 = require("@hydranium/protocol");
24
+ const core_1 = require("@theia/core");
25
+ const service_connection_provider_1 = require("@theia/core/lib/browser/messaging/service-connection-provider");
26
+ const inversify_1 = require("@theia/core/shared/inversify");
27
+ const browser_2 = require("@theia/workspace/lib/browser");
28
+ const channel_connection_1 = require("./channel-connection");
29
+ const workspace_gate_1 = require("./workspace-gate");
30
+ /**
31
+ * A {@link DataPort} over a Theia frontend channel.
32
+ *
33
+ * Subclasses supply {@link servicePath}; everything above the port —
34
+ * `DataConnection`, its sessions, and whatever model a widget drives — is
35
+ * host-neutral and shared with the VS Code and browser shells.
36
+ *
37
+ * Bind one per service path and in singleton scope. Theia keys a frontend
38
+ * channel by its path and refuses a second on a path already open, and the
39
+ * throw escapes the `openChannelConnection` the loser is awaiting, leaving that
40
+ * promise unsettled rather than rejected.
41
+ */
42
+ let ChannelDataPort = class ChannelDataPort {
43
+ connectionProvider;
44
+ workspaceService;
45
+ messageService;
46
+ connectionReporter;
47
+ logger;
48
+ /** Times the channel's reconnect escalation: the container's {@link Clock}, or a `SystemClock`. */
49
+ clock = new protocol_1.SystemClock();
50
+ /**
51
+ * Re-open the channel when the current connection is lost. Default `true` —
52
+ * re-opening is the only thing that recovers a restarted language server,
53
+ * which binds new ephemeral ports. Turn it off for a frontend that tears
54
+ * itself down on transport loss instead.
55
+ */
56
+ reconnectOnConnectionLoss = true;
57
+ disposeEmitter = new core_1.Emitter();
58
+ onDispose = this.disposeEmitter.event;
59
+ handle;
60
+ /** Set by {@link dispose}, after which {@link connect} rejects. */
61
+ disposed = false;
62
+ /** How long a connection may take before it is reported as failed; it keeps trying after. */
63
+ connectFailureNoticeMs = 30_000;
64
+ attempt;
65
+ attemptTimer;
66
+ /** Set once {@link connectionLifecycle} reports, which then owns the connection failures. */
67
+ reportsConnections = false;
68
+ /** Reports each connection generation through the {@link ConnectionReporter}. */
69
+ connectionLifecycle = {
70
+ onConnecting: () => {
71
+ this.reportsConnections = true;
72
+ this.settleAttempt();
73
+ const attempt = this.connectionReporter.connecting(this.connectionTarget);
74
+ this.attempt = attempt;
75
+ this.attemptTimer = setTimeout(() => {
76
+ attempt.failed(this.connectTimeoutMessage());
77
+ // The generation keeps waiting; a follow-up attempt reports it connecting.
78
+ this.attempt = this.connectionReporter.connecting(this.connectionTarget);
79
+ }, this.connectFailureNoticeMs);
80
+ },
81
+ onReady: () => this.settleAttempt(attempt => attempt.connected()),
82
+ onFailed: () => this.settleAttempt(attempt => attempt.failed(this.unreachableMessage()))
83
+ };
84
+ /**
85
+ * Open the workspace-gated channel and hand back its listening connection.
86
+ *
87
+ * Gated because the backend forwarder discovers the head's port by executing
88
+ * a command the language server answers, and the language server only
89
+ * launches once there is a workspace to launch it for. Asking earlier polls
90
+ * a command nobody has registered.
91
+ *
92
+ * Rejects once the port is disposed: the consumer reconnects when the
93
+ * dispose fires {@link onDispose}, and a channel opened then is closed by
94
+ * nothing.
95
+ */
96
+ connect() {
97
+ if (this.disposed) {
98
+ return Promise.reject(new Error(`${this.constructor.name}: the port is disposed`));
99
+ }
100
+ // Read per call rather than cached: `current` is repointed at a fresh
101
+ // promise every time the channel is re-opened, so reading through the
102
+ // handle is what makes a later generation reach the live server.
103
+ if (!this.handle) {
104
+ this.handle = (0, channel_connection_1.openChannelConnection)(this.connectionProvider, this.servicePath, {
105
+ whenReady: (0, workspace_gate_1.whenWorkspaceOpen)(this.workspaceService),
106
+ logger: this.logger,
107
+ clock: this.clock,
108
+ reconnect: this.reconnectOnConnectionLoss
109
+ });
110
+ // A relaunched server binds new ephemeral ports; the handle re-opens
111
+ // and the forwarder rediscovers, but `DataConnection` caches its
112
+ // generation and would go on addressing the dead one. Its signal to
113
+ // drop that generation is this event.
114
+ this.handle.onDidLoseConnection(() => this.disposeEmitter.fire(undefined));
115
+ }
116
+ return this.handle.current;
117
+ }
118
+ /**
119
+ * Surface a transport or write failure as a Theia notification.
120
+ *
121
+ * Swallowing it is the failure this exists to prevent: a dead connection and
122
+ * an empty document are indistinguishable in a widget.
123
+ *
124
+ * `reported` is already a complete sentence with the detail interpolated, so
125
+ * wrapping it in a sentence of the host's own would nest one owner's clause
126
+ * inside another's and leave no translator in control of the whole.
127
+ */
128
+ reportError(_error, reported) {
129
+ const connectionFailure = reported.code === protocol_1.DATA_SERVER_CONNECT_FAILED.code || reported.code === protocol_1.DATA_SERVER_NOT_READY.code;
130
+ const message = (0, protocol_1.renderFrameworkMessage)(reported, core_1.nls.localization?.translations);
131
+ if (connectionFailure && this.reportsConnections) {
132
+ // The reporter shows the failure without its detail, so it is kept here.
133
+ this.logger.warn(message);
134
+ return;
135
+ }
136
+ this.messageService.error(message);
137
+ }
138
+ /** End the current attempt through `settle`, or cancel it. */
139
+ settleAttempt(settle = attempt => attempt.cancelled()) {
140
+ clearTimeout(this.attemptTimer);
141
+ const attempt = this.attempt;
142
+ this.attempt = undefined;
143
+ if (attempt) {
144
+ settle(attempt);
145
+ }
146
+ }
147
+ get connectionTarget() {
148
+ return (this.cachedConnectionTarget ??= {
149
+ connectingMessage: core_1.nls.localize('hydranium/data-client-theia/data-server-connecting', 'Connecting to the data server…'),
150
+ connectedMessage: core_1.nls.localize('hydranium/data-client-theia/data-server-connected', 'Connected to the data server.')
151
+ });
152
+ }
153
+ /** One object per port: the reporter keys what it has shown on it. */
154
+ cachedConnectionTarget;
155
+ unreachableMessage() {
156
+ return core_1.nls.localize('hydranium/data-client-theia/data-server-unreachable', 'Could not connect to the data server.');
157
+ }
158
+ connectTimeoutMessage() {
159
+ 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)));
160
+ }
161
+ dispose() {
162
+ this.disposed = true;
163
+ this.settleAttempt();
164
+ this.handle?.dispose();
165
+ this.handle = undefined;
166
+ this.disposeEmitter.fire(undefined);
167
+ this.disposeEmitter.dispose();
168
+ }
169
+ };
170
+ exports.ChannelDataPort = ChannelDataPort;
171
+ __decorate([
172
+ (0, inversify_1.inject)(service_connection_provider_1.RemoteConnectionProvider),
173
+ __metadata("design:type", Function)
174
+ ], ChannelDataPort.prototype, "connectionProvider", void 0);
175
+ __decorate([
176
+ (0, inversify_1.inject)(browser_2.WorkspaceService),
177
+ __metadata("design:type", browser_2.WorkspaceService)
178
+ ], ChannelDataPort.prototype, "workspaceService", void 0);
179
+ __decorate([
180
+ (0, inversify_1.inject)(core_1.MessageService),
181
+ __metadata("design:type", core_1.MessageService)
182
+ ], ChannelDataPort.prototype, "messageService", void 0);
183
+ __decorate([
184
+ (0, inversify_1.inject)(browser_1.ConnectionReporter),
185
+ __metadata("design:type", Object)
186
+ ], ChannelDataPort.prototype, "connectionReporter", void 0);
187
+ __decorate([
188
+ (0, inversify_1.inject)(browser_1.ChannelLogger),
189
+ __metadata("design:type", browser_1.ChannelLogger)
190
+ ], ChannelDataPort.prototype, "logger", void 0);
191
+ __decorate([
192
+ (0, inversify_1.inject)(common_1.Clock),
193
+ (0, inversify_1.optional)(),
194
+ __metadata("design:type", Object)
195
+ ], ChannelDataPort.prototype, "clock", void 0);
196
+ exports.ChannelDataPort = ChannelDataPort = __decorate([
197
+ (0, inversify_1.injectable)()
198
+ ], ChannelDataPort);
199
+ //# sourceMappingURL=channel-data-port.js.map