@hydranium/client-theia 1.0.0-next.244 → 1.0.0-next.246

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 (2) hide show
  1. package/README.md +50 -116
  2. package/package.json +3 -3
package/README.md CHANGED
@@ -1,81 +1,22 @@
1
1
  # `@hydranium/client-theia`
2
2
 
3
- Cross-head Theia client primitives for the
4
- [Hydranium](https://github.com/eclipse-emfcloud/hydranium) framework.
5
-
6
- This is the host-coupled layer every hydranium head shares when it runs inside a
7
- Theia application: the Output-channel logger, the log-threshold preference
8
- binding, the memory-diagnostics command set, and the backend base class that
9
- bridges a Theia frontend channel to a server socket. It carries no head-specific
10
- dependency — `@hydranium/data-client-theia` and `@hydranium/glsp-client-theia`
11
- both build on it. Install it if you are assembling a Theia extension around a
12
- hydranium server; a non-Theia host does not need it.
3
+ The Theia pieces every
4
+ [Hydranium](https://github.com/eclipse-emfcloud/hydranium) head shares: the
5
+ Output-channel logger, the editor's save handling, the diagnostics commands and
6
+ the backend's socket bridge. Install it when your language's editors live in a
7
+ Theia application, beside `@hydranium/data-client-theia` or
8
+ `@hydranium/glsp-client-theia`.
13
9
 
14
10
  ## What it gives you
15
11
 
16
- - **`ChannelLogger`** with `bindChannelLogger` — writes frontend log lines into a
17
- Theia Output channel, formatted to interleave with the server's own log so both
18
- sides of the conversation read as one transcript. The same call also binds
19
- `ChannelTracer`, the `Tracer` token frontend services inject when they time
20
- something.
21
- - **`ConnectionReporter`** with `bindConnectionReporter` — the slot every head
22
- reports its connection attempts through, reconnects included.
23
- `DefaultConnectionReporter` shows a progress notification for an attempt still
24
- running after 3 s and ends it in at most one notification, raising a failure
25
- once until the head connects again. Rebind the slot to report differently, or
26
- not at all; the heads keep their retries either way.
27
- - **`LogLevelPreferenceContribution`** with `bindLogLevelPreference` — applies the
28
- framework log threshold from a Theia preference once per application, and keeps
29
- it in sync on change. It is a `FrontendApplicationContribution` on purpose: the
30
- threshold is process-global, so applying it from a per-diagram container would
31
- leak one preference listener per container.
32
- - **`MemoryDiagnosticsContribution`** with `bindMemoryDiagnostics` — the whole
33
- diagnostics command set, parameterised by three branding strings
34
- (`MemoryDiagnosticsOptions`: `commandIdPrefix`, `category`, `channelName`):
35
- Dump Server State, Dump Pod Memory, Dump Frontend State, Write Heap Snapshot
36
- (Server), Start / Stop Profiling (Server), Record Performance Profile, and Dump
37
- RPC/LSP Latency. Two more — Dump Backend State and Write Heap Snapshot
38
- (Backend) — register only when the optional `HostMemoryDiagnosticsService` is
39
- bound. You bind `MemoryDiagnosticsService` to your own connected data-server
40
- frontend; the framework cannot, because that class is yours.
41
- - **`EditorDiskSync`** — keeps a dirty editor's save from applying edits its
42
- file already holds, as the file does once the server saves a document the
43
- editor shows unsaved. Before each save of the editor it drops the edits the
44
- file holds, so the save writes only the rest, a save participant's included;
45
- on each watched change of the file to the editor's text it marks the editor
46
- clean. Theia otherwise keeps the editor dirty, and its next save applies the
47
- editor's edits to a file that already holds them.
48
- `bindEditorDiskSync(bind, isBound, rebind)` binds it, with
49
- `HydraniumFileService`.
50
- - **`HydraniumFileService`** — Theia's `FileService`, refusing an editor's
51
- incremental save once the file's mtime has moved past the one the editor
52
- read, so the editor writes its whole text instead. Theia's own check passes a
53
- file of unchanged size, and the save then applies the editor's edits to a
54
- file that may already hold them; `write` keeps Theia's check. The safety net
55
- behind `EditorDiskSync`, for a save the sync cannot catch, and bound with it
56
- by `bindEditorDiskSync`.
57
- - **`captureBrowserRuntime` / `formatBrowserRuntime`** — the renderer's own memory
58
- reading as a `BrowserRuntimeReport`, preferring the standardized
59
- `performance.measureUserAgentSpecificMemory()` and falling back to Chromium's
60
- coarse `performance.memory`.
61
- - **`AbstractSocketForwardingConnectionHandler`** (Node side) — the abstract base for the
62
- Theia _backend_ half of a head's transport. It discovers the server's listening
63
- port by executing a registered command, opens a `net.Socket`, and relays bytes
64
- between the frontend channel and it. The one abstract hook is which byte
65
- forwarder bridges the two; port discovery, connect orchestration, and the
66
- buffer-and-replay fix for frontend writes that arrive before the forwarder is
67
- wired all live here.
68
- - **`SocketChannelForwarder`** (Node side) — the byte forwarder both heads plug
69
- into that hook. When the frontend channel closes, it finishes the writes it
70
- still has queued before it ends the socket, so a message sent just before a
71
- page goes away still reaches the server.
72
- - **`Clock`** (either side) — the protocol's `Clock` as an injection token.
73
- The frontend and backend classes above that time or bound something inject
74
- it as optional and use a `SystemClock` when the container binds none, so a
75
- container can supply another clock.
76
- - **`./testing`** — `makeStubOutputChannelManager` and `makeStubInversifyContext`,
77
- the doubles that let the pieces above be unit-tested without a Theia
78
- application.
12
+ - Your frontend's log lines in an Output channel you name, aligned with the
13
+ server's own log, and the log level driven by a Theia preference.
14
+ - Editors that stay correct when a server saves a file they show unsaved.
15
+ - Diagnostics commands for the server's memory, heap and profile, under your
16
+ own command prefix and category.
17
+ - Notifications while a head connects, and once when it fails.
18
+ - Messages held while the websocket is down, and the outage logged.
19
+ - The socket bridge the head packages build their backend handlers on.
79
20
 
80
21
  ## Install
81
22
 
@@ -83,9 +24,6 @@ hydranium server; a non-Theia host does not need it.
83
24
  npm install @hydranium/client-theia
84
25
  ```
85
26
 
86
- You must already have a Theia application (or a Theia extension inside one). The
87
- declared peer dependencies are:
88
-
89
27
  | Peer | Range |
90
28
  | --------------------- | ------------- |
91
29
  | `@hydranium/protocol` | `^1.0.0-next` |
@@ -96,56 +34,52 @@ declared peer dependencies are:
96
34
  | `inversify` | `^6.0.0` |
97
35
  | `vscode-jsonrpc` | `^9.0.0` |
98
36
 
99
- `@theia/output` is easy to miss: the memory-diagnostics commands and the channel
100
- logger both write to an Output channel, so a host that does not already depend on
101
- it has to add it.
37
+ `@theia/output` is easy to miss: the logger and the diagnostics commands both
38
+ write to an Output channel, so add it if your application does not have it yet.
102
39
 
103
40
  ## Wiring
104
41
 
105
- This package is a **library, not a Theia extension** — it declares no
106
- `theiaExtensions`, so dropping it into an application wires nothing on its own.
107
- Your own extension package declares the `theiaExtensions` entries and imports
108
- from here:
109
-
110
- - a **frontend** module (a `ContainerModule` in the extension's `browser/` tier)
111
- calls the `bind*` helpers — `bindChannelLogger`, `bindLogLevelPreference`,
112
- `bindMemoryDiagnostics`, and `bindEditorDiskSync` whenever a server writes
113
- files an editor can have open — and binds `MemoryDiagnosticsService` to your
114
- data-server frontend;
115
- - a **backend** module (the extension's `node/` tier) registers a
116
- `AbstractSocketForwardingConnectionHandler` subclass as a Theia `ConnectionHandler`. In
117
- practice you subclass one of the head-specific subclasses shipped by
42
+ This package is a library, not a Theia extension: it declares no
43
+ `theiaExtensions`. Your own extension declares them and binds from here.
44
+
45
+ - In a frontend module, call `bindChannelLogger` and `bindLogLevelPreference`.
46
+ Call `bindEditorDiskSync` whenever a server writes files an editor can have
47
+ open.
48
+ - For the diagnostics commands, bind `MemoryDiagnosticsService` to your own
49
+ data-server frontend, then call `bindMemoryDiagnostics`.
50
+ - For the websocket, call `bindConnectionResilience` in a `frontendPreload`
51
+ module and in a backend module, and `bindConnectionDiagnostics` beside the
52
+ logger. From a normal frontend module the first call comes too late and
53
+ silently does nothing.
54
+ - In the backend, you usually subclass a head-specific handler from
118
55
  `@hydranium/data-client-theia` or `@hydranium/glsp-client-theia` rather than
119
- this base directly.
56
+ the base here.
57
+
58
+ For the whole setup, see *Host in Theia* in
59
+ [Adopting Hydranium](https://github.com/eclipse-emfcloud/hydranium/blob/main/docs/ADOPTING.md).
120
60
 
121
61
  ## Entry points
122
62
 
123
- | Subpath | Holds | Environment |
124
- | ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------- |
125
- | `.` | Nothing. Deliberately empty, so an environment-specific import cannot reach the wrong bundle through a barrel. | browser-neutral (gated) |
126
- | `./browser` | `ChannelLogger`, `ChannelTracer`, `ConnectionReporter`, `DefaultConnectionReporter`, `LogLevelPreferenceContribution`, `MemoryDiagnosticsContribution`, `EditorDiskSync`, `HydraniumFileService`, the `bind*` helpers, `captureBrowserRuntime` | browser / Theia frontend (gated) |
127
- | `./common` | `Clock`, the framed socket write buffer and the connection-resilience options | browser-neutral (gated) |
128
- | `./node` | `AbstractSocketForwardingConnectionHandler` and its options, `SocketChannelForwarder` — imports `node:net` | Node / Theia backend |
129
- | `./testing` | `makeStubOutputChannelManager`, `makeStubInversifyContext` | browser-neutral (gated) |
130
-
131
- Resolve the subpaths with [a resolver that reads
132
- `exports`](../../docs/adopting/requirements.md#a-resolver-that-reads-exports);
133
- `"Node"` (node10) reaches none of them. "Gated" means the
134
- entry is enforced browser-neutral by the repository's neutral-bundle check: it
135
- must bundle for the browser with no `node:*` import, including transitive ones —
136
- and [what "gated neutral" does and does not promise](../../docs/contributing/design/browser-hosting.md#what-gated-neutral-does-and-does-not-promise).
137
- `./node` is deliberately not gated — that tier is where Node-only code belongs.
63
+ | Subpath | Use it for | Runs in |
64
+ | ----------- | ---------------------------------------------------------- | --------------- |
65
+ | `.` | Nothing; import a subpath | browser-neutral |
66
+ | `./browser` | The frontend bind helpers and the classes they bind | Theia frontend |
67
+ | `./common` | The pieces both sides share, such as the clock token | browser-neutral |
68
+ | `./node` | The backend socket bridge and the websocket hardening | Theia backend |
69
+ | `./testing` | Test doubles for the Output channel and Inversify contexts | browser-neutral |
70
+
71
+ The subpaths need a TypeScript `moduleResolution` that reads `exports`
72
+ (`NodeNext` or `Bundler`); see *Requirements* in
73
+ [Adopting Hydranium](https://github.com/eclipse-emfcloud/hydranium/blob/main/docs/ADOPTING.md).
138
74
 
139
75
  ## Status
140
76
 
141
- Alpha — pre-v0, published as a `1.0.0-next` prerelease on every merge to `main`.
142
- The API is not stable and may change without a deprecation cycle. See
143
- [Adopting Hydranium](../../docs/ADOPTING.md) for how the Theia client tier
144
- relates to the heads, and the [repository
145
- README](../../README.md) for current status and known limitations.
77
+ Alpha: every release is a prerelease that may break the API, so pin an exact
78
+ version. Guides and known limitations:
79
+ [Adopting Hydranium](https://github.com/eclipse-emfcloud/hydranium/blob/main/docs/ADOPTING.md).
146
80
 
147
81
  ## License
148
82
 
149
- `MIT` — see this package's [`LICENSE`](./LICENSE). Third-party notices for the
150
- runtime dependency closure are collected in the repository
151
- [`NOTICE.md`](../../NOTICE.md).
83
+ `MIT` — see this package's [`LICENSE`](./LICENSE), and the repository
84
+ [`NOTICE.md`](https://github.com/eclipse-emfcloud/hydranium/blob/main/NOTICE.md)
85
+ for third-party notices.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hydranium/client-theia",
3
- "version": "1.0.0-next.244",
3
+ "version": "1.0.0-next.246",
4
4
  "description": "Cross-head Theia client primitives shared by the hydranium protocol heads. Provides the socket-forwarding connection-handler base that the data-server and GLSP Theia integrations subclass, plus the preference-driven Output-channel logger; carries no head-specific dependency.",
5
5
  "keywords": [
6
6
  "hydranium",
@@ -65,7 +65,7 @@
65
65
  "watch": "tsc -b -w --preserveWatchOutput"
66
66
  },
67
67
  "devDependencies": {
68
- "@hydranium/protocol": "1.0.0-next.244",
68
+ "@hydranium/protocol": "1.0.0-next.246",
69
69
  "@theia/core": "^1.70.0",
70
70
  "@theia/editor": "^1.70.0",
71
71
  "@theia/filesystem": "^1.70.0",
@@ -78,7 +78,7 @@
78
78
  "vscode-jsonrpc": "9.0.0"
79
79
  },
80
80
  "peerDependencies": {
81
- "@hydranium/protocol": "1.0.0-next.244",
81
+ "@hydranium/protocol": "1.0.0-next.246",
82
82
  "@theia/core": "^1.70.0",
83
83
  "@theia/editor": "^1.70.0",
84
84
  "@theia/filesystem": "^1.70.0",