@hydranium/client-theia 1.0.0-next.38 → 1.0.0-next.381

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 (95) hide show
  1. package/README.md +53 -81
  2. package/lib/browser/browser-capture.js.map +1 -1
  3. package/lib/browser/channel-logger.d.ts +4 -3
  4. package/lib/browser/channel-logger.d.ts.map +1 -1
  5. package/lib/browser/channel-logger.js +11 -19
  6. package/lib/browser/channel-logger.js.map +1 -1
  7. package/lib/browser/connection-diagnostics-contribution.d.ts +73 -0
  8. package/lib/browser/connection-diagnostics-contribution.d.ts.map +1 -0
  9. package/lib/browser/connection-diagnostics-contribution.js +162 -0
  10. package/lib/browser/connection-diagnostics-contribution.js.map +1 -0
  11. package/lib/browser/connection-reporter.d.ts +57 -0
  12. package/lib/browser/connection-reporter.d.ts.map +1 -0
  13. package/lib/browser/connection-reporter.js +104 -0
  14. package/lib/browser/connection-reporter.js.map +1 -0
  15. package/lib/browser/editor-disk-sync.d.ts +142 -0
  16. package/lib/browser/editor-disk-sync.d.ts.map +1 -0
  17. package/lib/browser/editor-disk-sync.js +250 -0
  18. package/lib/browser/editor-disk-sync.js.map +1 -0
  19. package/lib/browser/hydranium-file-service.d.ts +44 -0
  20. package/lib/browser/hydranium-file-service.d.ts.map +1 -0
  21. package/lib/browser/hydranium-file-service.js +61 -0
  22. package/lib/browser/hydranium-file-service.js.map +1 -0
  23. package/lib/browser/index.d.ts +5 -0
  24. package/lib/browser/index.d.ts.map +1 -1
  25. package/lib/browser/index.js +5 -0
  26. package/lib/browser/index.js.map +1 -1
  27. package/lib/browser/log-level-preference.d.ts.map +1 -1
  28. package/lib/browser/log-level-preference.js +11 -0
  29. package/lib/browser/log-level-preference.js.map +1 -1
  30. package/lib/browser/memory-diagnostics-contribution.d.ts +1 -1
  31. package/lib/browser/memory-diagnostics-contribution.d.ts.map +1 -1
  32. package/lib/browser/memory-diagnostics-contribution.js +1 -1
  33. package/lib/browser/memory-diagnostics-contribution.js.map +1 -1
  34. package/lib/browser/session-aware-connection-source.d.ts +104 -0
  35. package/lib/browser/session-aware-connection-source.d.ts.map +1 -0
  36. package/lib/browser/session-aware-connection-source.js +193 -0
  37. package/lib/browser/session-aware-connection-source.js.map +1 -0
  38. package/lib/common/clock.d.ts +19 -0
  39. package/lib/common/clock.d.ts.map +1 -0
  40. package/lib/common/clock.js +13 -0
  41. package/lib/common/clock.js.map +1 -0
  42. package/lib/common/connection-resilience-options.d.ts +30 -0
  43. package/lib/common/connection-resilience-options.d.ts.map +1 -0
  44. package/lib/common/connection-resilience-options.js +11 -0
  45. package/lib/common/connection-resilience-options.js.map +1 -0
  46. package/lib/common/framed-socket-write-buffer.d.ts +173 -0
  47. package/lib/common/framed-socket-write-buffer.d.ts.map +1 -0
  48. package/lib/common/framed-socket-write-buffer.js +293 -0
  49. package/lib/common/framed-socket-write-buffer.js.map +1 -0
  50. package/lib/common/inbound-message-sequence.d.ts +56 -0
  51. package/lib/common/inbound-message-sequence.d.ts.map +1 -0
  52. package/lib/common/inbound-message-sequence.js +98 -0
  53. package/lib/common/inbound-message-sequence.js.map +1 -0
  54. package/lib/common/index.d.ts +13 -0
  55. package/lib/common/index.d.ts.map +1 -0
  56. package/lib/common/index.js +32 -0
  57. package/lib/common/index.js.map +1 -0
  58. package/lib/node/abstract-socket-forwarding-connection-handler.d.ts +16 -12
  59. package/lib/node/abstract-socket-forwarding-connection-handler.d.ts.map +1 -1
  60. package/lib/node/abstract-socket-forwarding-connection-handler.js +94 -31
  61. package/lib/node/abstract-socket-forwarding-connection-handler.js.map +1 -1
  62. package/lib/node/index.d.ts +2 -0
  63. package/lib/node/index.d.ts.map +1 -1
  64. package/lib/node/index.js +2 -0
  65. package/lib/node/index.js.map +1 -1
  66. package/lib/node/session-bound-frontend-connection-service.d.ts +122 -0
  67. package/lib/node/session-bound-frontend-connection-service.d.ts.map +1 -0
  68. package/lib/node/session-bound-frontend-connection-service.js +236 -0
  69. package/lib/node/session-bound-frontend-connection-service.js.map +1 -0
  70. package/lib/node/socket-channel-forwarder.d.ts +54 -0
  71. package/lib/node/socket-channel-forwarder.d.ts.map +1 -0
  72. package/lib/node/socket-channel-forwarder.js +95 -0
  73. package/lib/node/socket-channel-forwarder.js.map +1 -0
  74. package/lib/testing/stub-inversify-context.js.map +1 -1
  75. package/lib/testing/stub-output-channel.js.map +1 -1
  76. package/package.json +33 -34
  77. package/src/browser/browser-capture.ts +1 -1
  78. package/src/browser/channel-logger.ts +11 -19
  79. package/src/browser/connection-diagnostics-contribution.ts +146 -0
  80. package/src/browser/connection-reporter.ts +121 -0
  81. package/src/browser/editor-disk-sync.ts +253 -0
  82. package/src/browser/hydranium-file-service.ts +56 -0
  83. package/src/browser/index.ts +5 -0
  84. package/src/browser/log-level-preference.ts +11 -0
  85. package/src/browser/memory-diagnostics-contribution.ts +4 -3
  86. package/src/browser/session-aware-connection-source.ts +205 -0
  87. package/src/common/clock.ts +20 -0
  88. package/src/common/connection-resilience-options.ts +30 -0
  89. package/src/common/framed-socket-write-buffer.ts +345 -0
  90. package/src/common/inbound-message-sequence.ts +102 -0
  91. package/src/common/index.ts +16 -0
  92. package/src/node/abstract-socket-forwarding-connection-handler.ts +85 -36
  93. package/src/node/index.ts +2 -0
  94. package/src/node/session-bound-frontend-connection-service.ts +264 -0
  95. package/src/node/socket-channel-forwarder.ts +101 -0
package/README.md CHANGED
@@ -1,51 +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
- - **`LogLevelPreferenceContribution`** with `bindLogLevelPreference` — applies the
22
- framework log threshold from a Theia preference once per application, and keeps
23
- it in sync on change. It is a `FrontendApplicationContribution` on purpose: the
24
- threshold is process-global, so applying it from a per-diagram container would
25
- leak one preference listener per container.
26
- - **`MemoryDiagnosticsContribution`** with `bindMemoryDiagnostics` — the whole
27
- diagnostics command set, parameterised by three branding strings
28
- (`MemoryDiagnosticsOptions`: `commandIdPrefix`, `category`, `channelName`):
29
- Dump Server State, Dump Pod Memory, Dump Frontend State, Write Heap Snapshot
30
- (Server), Start / Stop Profiling (Server), Record Performance Profile, and Dump
31
- RPC/LSP Latency. Two more — Dump Backend State and Write Heap Snapshot
32
- (Backend) — register only when the optional `HostMemoryDiagnosticsService` is
33
- bound. You bind `MemoryDiagnosticsService` to your own connected data-server
34
- frontend; the framework cannot, because that class is yours.
35
- - **`captureBrowserRuntime` / `formatBrowserRuntime`** — the renderer's own memory
36
- reading as a `BrowserRuntimeReport`, preferring the standardized
37
- `performance.measureUserAgentSpecificMemory()` and falling back to Chromium's
38
- coarse `performance.memory`.
39
- - **`AbstractSocketForwardingConnectionHandler`** (Node side) — the abstract base for the
40
- Theia _backend_ half of a head's transport. It discovers the server's listening
41
- port by executing a registered command, opens a `net.Socket`, and relays bytes
42
- between the frontend channel and it. The one abstract hook is which byte
43
- forwarder bridges the two; port discovery, connect orchestration, and the
44
- buffer-and-replay fix for frontend writes that arrive before the forwarder is
45
- wired all live here.
46
- - **`./testing`** — `makeStubOutputChannelManager` and `makeStubInversifyContext`,
47
- the doubles that let the pieces above be unit-tested without a Theia
48
- 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.
49
20
 
50
21
  ## Install
51
22
 
@@ -53,61 +24,62 @@ hydranium server; a non-Theia host does not need it.
53
24
  npm install @hydranium/client-theia
54
25
  ```
55
26
 
56
- You must already have a Theia application (or a Theia extension inside one). The
57
- declared peer dependencies are:
58
-
59
27
  | Peer | Range |
60
28
  | --------------------- | ------------- |
61
29
  | `@hydranium/protocol` | `^1.0.0-next` |
62
30
  | `@theia/core` | `^1.70.0` |
31
+ | `@theia/editor` | `^1.70.0` |
32
+ | `@theia/filesystem` | `^1.70.0` |
63
33
  | `@theia/output` | `^1.70.0` |
64
- | `inversify` | `^6.0.0` |
34
+ | `inversify` | `^6.1.3` |
35
+ | `vscode-jsonrpc` | `^9.0.0` |
65
36
 
66
- `@theia/output` is easy to miss: the memory-diagnostics commands and the channel
67
- logger both write to an Output channel, so a host that does not already depend on
68
- 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.
69
39
 
70
40
  ## Wiring
71
41
 
72
- This package is a **library, not a Theia extension** — it declares no
73
- `theiaExtensions`, so dropping it into an application wires nothing on its own.
74
- Your own extension package declares the `theiaExtensions` entries and imports
75
- from here:
76
-
77
- - a **frontend** module (a `ContainerModule` in the extension's `browser/` tier)
78
- calls the `bind*` helpers — `bindChannelLogger`, `bindLogLevelPreference`,
79
- `bindMemoryDiagnostics` — and binds `MemoryDiagnosticsService` to your
80
- data-server frontend;
81
- - a **backend** module (the extension's `node/` tier) registers a
82
- `AbstractSocketForwardingConnectionHandler` subclass as a Theia `ConnectionHandler`. In
83
- 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; in Electron it does nothing by design.
54
+ - In the backend, you usually subclass a head-specific handler from
84
55
  `@hydranium/data-client-theia` or `@hydranium/glsp-client-theia` rather than
85
- 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).
86
60
 
87
61
  ## Entry points
88
62
 
89
- | Subpath | Holds | Environment |
90
- | ----------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------- |
91
- | `.` | Nothing. Deliberately empty, so an environment-specific import cannot reach the wrong bundle through a barrel. | browser-neutral (gated) |
92
- | `./browser` | `ChannelLogger`, `ChannelTracer`, `LogLevelPreferenceContribution`, `MemoryDiagnosticsContribution`, the `bind*` helpers, `captureBrowserRuntime` | browser / Theia frontend (gated) |
93
- | `./node` | `AbstractSocketForwardingConnectionHandler` and its options — imports `node:net` | Node / Theia backend |
94
- | `./testing` | `makeStubOutputChannelManager`, `makeStubInversifyContext` | browser-neutral (gated) |
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 |
95
70
 
96
- Every subpath also has a `./lib/<name>` twin, so a consumer on
97
- `moduleResolution: "Node"` can reach it. "Gated" means the entry is enforced
98
- browser-neutral by the repository's neutral-bundle check: it must bundle for the
99
- browser with no `node:*` import, including transitive ones — and [what "gated neutral" does and does not promise](../../docs/concepts/browser-hosting.md#a-note-on-what-gated-neutral-does-and-does-not-promise).
100
- `./node` is deliberately not gated — that tier is where Node-only code belongs.
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).
101
74
 
102
75
  ## Status
103
76
 
104
- Alpha — pre-v0, not yet published. The API is not stable and may change without a
105
- deprecation cycle. See [`docs/concepts/architecture.md`](../../docs/concepts/architecture.md) for
106
- how the Theia client tier relates to the heads, and the
107
- [repository 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).
108
80
 
109
81
  ## License
110
82
 
111
- `MIT` — see this package's [`LICENSE`](./LICENSE). Third-party notices for the
112
- runtime dependency closure are collected in the repository
113
- [`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.
@@ -1 +1 @@
1
- {"version":3,"file":"browser-capture.js","sourceRoot":"","sources":["../../src/browser/browser-capture.ts"],"names":[],"mappings":";AAAA;;;;;;;kFAOkF;;AA2BlF,sDAqBC;AAOD,oDAYC;AAhDD;;;;;;;GAOG;AACI,KAAK,UAAU,qBAAqB;IACxC,MAAM,IAAI,GAAG,UAAU,CAAC,WAAmE,CAAC;IAC5F,IAAI,IAAI,EAAE,8BAA8B,EAAE,CAAC;QACxC,IAAI,CAAC;YACF,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,8BAA8B,EAAE,CAAC;YAC3D,OAAO,EAAE,MAAM,EAAE,gCAAgC,EAAE,KAAK,EAAE,EAAE,UAAU,EAAE,MAAM,CAAC,KAAK,EAAE,SAAS,EAAE,MAAM,CAAC,SAAS,EAAE,EAAE,CAAC;QACzH,CAAC;QAAC,MAAM,CAAC;YACN,qEAAqE;QACxE,CAAC;IACJ,CAAC;IACD,IAAI,IAAI,EAAE,MAAM,EAAE,CAAC;QAChB,OAAO;YACJ,MAAM,EAAE,oBAAoB;YAC5B,KAAK,EAAE;gBACJ,eAAe,EAAE,IAAI,CAAC,MAAM,CAAC,cAAc;gBAC3C,gBAAgB,EAAE,IAAI,CAAC,MAAM,CAAC,eAAe;gBAC7C,gBAAgB,EAAE,IAAI,CAAC,MAAM,CAAC,eAAe;aAC/C;SACH,CAAC;IACL,CAAC;IACD,OAAO,EAAE,MAAM,EAAE,aAAa,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC;AAC/C,CAAC;AAED,SAAS,EAAE,CAAC,KAAa;IACtB,OAAO,GAAG,CAAC,KAAK,GAAG,CAAC,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC;AACrD,CAAC;AAED,yFAAyF;AACzF,SAAgB,oBAAoB,CAAC,MAA4B;IAC9D,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,CAAC;IACzB,IAAI,MAAM,CAAC,MAAM,KAAK,gCAAgC,IAAI,KAAK,CAAC,UAAU,KAAK,SAAS,EAAE,CAAC;QACxF,OAAO,sCAAsC,EAAE,CAAC,KAAK,CAAC,UAAU,CAAC,+BAA+B,CAAC;IACpG,CAAC;IACD,IAAI,MAAM,CAAC,MAAM,KAAK,oBAAoB,IAAI,KAAK,CAAC,eAAe,KAAK,SAAS,EAAE,CAAC;QACjF,MAAM,IAAI,GAAG,KAAK,CAAC,eAAe,CAAC;QACnC,MAAM,KAAK,GAAG,KAAK,CAAC,gBAAgB,IAAI,CAAC,CAAC;QAC1C,MAAM,KAAK,GAAG,KAAK,CAAC,gBAAgB,IAAI,CAAC,CAAC;QAC1C,OAAO,oBAAoB,EAAE,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,YAAY,EAAE,CAAC,KAAK,CAAC,+CAA+C,CAAC;IAC/H,CAAC;IACD,OAAO,8GAA8G,CAAC;AACzH,CAAC"}
1
+ {"version":3,"file":"browser-capture.js","sourceRoot":"","sources":["../../src/browser/browser-capture.ts"],"names":[],"mappings":";AAAA;;;;;;;kFAOkF;;;;AAmBlF;;;;;;;GAOG;AACI,KAAK;IACT,MAAM,IAAI,GAAG,UAAU,CAAC,WAAmD,CAAC;IAC5E,IAAI,IAAI,EAAE,8BAA8B,EAAE,CAAC;QACxC,IAAI,CAAC;YACF,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,8BAA8B,EAAE,CAAC;YAC3D,OAAO,EAAE,MAAM,EAAE,gCAAgC,EAAE,KAAK,EAAE,EAAE,UAAU,EAAE,MAAM,CAAC,KAAK,EAAE,SAAS,EAAE,MAAM,CAAC,SAAS,EAAE,EAAE,CAAC;QACzH,CAAC;QAAC,MAAM,CAAC;YACN,qEAAqE;QACxE,CAAC;IACJ,CAAC;IACD,IAAI,IAAI,EAAE,MAAM,EAAE,CAAC;QAChB,OAAO;YACJ,MAAM,EAAE,oBAAoB;YAC5B,KAAK,EAAE;gBACJ,eAAe,EAAE,IAAI,CAAC,MAAM,CAAC,cAAc;gBAC3C,gBAAgB,EAAE,IAAI,CAAC,MAAM,CAAC,eAAe;gBAC7C,gBAAgB,EAAE,IAAI,CAAC,MAAM,CAAC,eAAe;aAC/C;SACH,CAAC;IACL,CAAC;IACD,OAAO,EAAE,MAAM,EAAE,aAAa,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC;AAC/C,CAAC;AAED,SAAS,EAAE,CAAC,KAAa;IACtB,OAAO,GAAG,CAAC,KAAK,GAAG,CAAC,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC;AACrD,CAAC;AAED,yFAAyF;AACzF,8BAAqC,MAA4B;IAC9D,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,CAAC;IACzB,IAAI,MAAM,CAAC,MAAM,KAAK,gCAAgC,IAAI,KAAK,CAAC,UAAU,KAAK,SAAS,EAAE,CAAC;QACxF,OAAO,sCAAsC,EAAE,CAAC,KAAK,CAAC,UAAU,CAAC,+BAA+B,CAAC;IACpG,CAAC;IACD,IAAI,MAAM,CAAC,MAAM,KAAK,oBAAoB,IAAI,KAAK,CAAC,eAAe,KAAK,SAAS,EAAE,CAAC;QACjF,MAAM,IAAI,GAAG,KAAK,CAAC,eAAe,CAAC;QACnC,MAAM,KAAK,GAAG,KAAK,CAAC,gBAAgB,IAAI,CAAC,CAAC;QAC1C,MAAM,KAAK,GAAG,KAAK,CAAC,gBAAgB,IAAI,CAAC,CAAC;QAC1C,OAAO,oBAAoB,EAAE,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,YAAY,EAAE,CAAC,KAAK,CAAC,+CAA+C,CAAC;IAC/H,CAAC;IACD,OAAO,8GAA8G,CAAC;AACzH,CAAC"}
@@ -61,9 +61,10 @@ export declare class ChannelLogger extends AbstractLogger {
61
61
  }
62
62
  /**
63
63
  * Inversify token for the browser `Tracer` — a {@link DefaultTracer} over
64
- * the {@link ChannelLogger} (emit sink) + a {@link SystemClock} + a browser
65
- * heap reader. The browser head has no Langium `services.Tracer` slot, so this
66
- * is how frontend services that time obtain a tracer: `@inject(ChannelTracer)`.
64
+ * the {@link ChannelLogger} (emit sink) + the container's {@link Clock}, or a
65
+ * `SystemClock` when it binds none, + a browser heap reader. The browser head
66
+ * has no Langium `services.Tracer` slot, so this is how frontend services that
67
+ * time obtain a tracer: `@inject(ChannelTracer)`.
67
68
  * Bound by {@link bindChannelLogger}.
68
69
  */
69
70
  export declare const ChannelTracer: unique symbol;
@@ -1 +1 @@
1
- {"version":3,"file":"channel-logger.d.ts","sourceRoot":"","sources":["../../src/browser/channel-logger.ts"],"names":[],"mappings":"AAAA;;;;;;;kFAOkF;AAElF,OAAO,EAAE,cAAc,EAAiB,KAAK,QAAQ,EAAkC,MAAM,qBAAqB,CAAC;AACnH,OAAO,EAAc,KAAK,UAAU,EAAqB,MAAM,8BAA8B,CAAC;AAC9F,OAAO,EAAE,KAAK,aAAa,EAAE,oBAAoB,EAAE,MAAM,0CAA0C,CAAC;AAEpG;;;;;;;;GAQG;AACH,MAAM,WAAW,oBAAoB;IAClC,6DAA6D;IAC7D,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,0DAA0D;IAC1D,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;CAC9B;AAED;sFACsF;AACtF,eAAO,MAAM,oBAAoB,eAAiC,CAAC;AAEnE;;;;;;;;;;;;;;;;GAgBG;AACH,qBACa,aAAc,SAAQ,cAAc;IAIb,SAAS,CAAC,QAAQ,CAAC,cAAc,EAAE,oBAAoB;IACvD,SAAS,CAAC,QAAQ,CAAC,OAAO,EAAE,oBAAoB;IAJjF,SAAS,CAAC,QAAQ,CAAC,EAAE,aAAa,CAAC;gBAGiB,cAAc,EAAE,oBAAoB,EACpC,OAAO,EAAE,oBAAoB,EACjE,SAAS,GAAE,MAAM,GAAG,SAA6B;IAKjE,SAAS,KAAK,OAAO,IAAI,aAAa,CAErC;IAED,SAAS,CAAC,IAAI,CAAC,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,OAAO,EAAE,GAAG,IAAI;IAOhG;;;;;OAKG;IACH,SAAS,CAAC,MAAM,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;CAQ3C;AAOD;;;;;;GAMG;AACH,eAAO,MAAM,aAAa,eAA0B,CAAC;AAErD;gDACgD;AAChD,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,UAAU,CAAC,OAAO,GAAG,MAAM,GAAG,SAAS,CAOpF;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,UAAU,CAAC,IAAI,EAAE,OAAO,EAAE,oBAAoB,GAAG,IAAI,CAW5F"}
1
+ {"version":3,"file":"channel-logger.d.ts","sourceRoot":"","sources":["../../src/browser/channel-logger.ts"],"names":[],"mappings":"AAAA;;;;;;;kFAOkF;AAElF,OAAO,EAAE,cAAc,EAAiB,KAAK,QAAQ,EAAkC,MAAM,qBAAqB,CAAC;AACnH,OAAO,EAAc,KAAK,UAAU,EAAqB,MAAM,8BAA8B,CAAC;AAC9F,OAAO,EAAE,KAAK,aAAa,EAAE,oBAAoB,EAAE,MAAM,0CAA0C,CAAC;AAGpG;;;;;;;;GAQG;AACH,MAAM,WAAW,oBAAoB;IAClC,6DAA6D;IAC7D,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,0DAA0D;IAC1D,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;CAC9B;AAED;sFACsF;AACtF,eAAO,MAAM,oBAAoB,eAAiC,CAAC;AAEnE;;;;;;;;;;;;;;;;GAgBG;AACH,qBACa,aAAc,SAAQ,cAAc;IAIb,SAAS,CAAC,QAAQ,CAAC,cAAc,EAAE,oBAAoB;IACvD,SAAS,CAAC,QAAQ,CAAC,OAAO,EAAE,oBAAoB;IAJjF,SAAS,CAAC,QAAQ,CAAC,EAAE,aAAa,CAAC;IAEnC,YACoD,cAAc,EAAE,oBAAoB,EACpC,OAAO,EAAE,oBAAoB,EACjE,SAAS,GAAE,MAAM,GAAG,SAA6B,EAGhE;IAED,SAAS,KAAK,OAAO,IAAI,aAAa,CAErC;IAED,SAAS,CAAC,IAAI,CAAC,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,OAAO,EAAE,GAAG,IAAI,CAG/F;IAED;;;;;OAKG;IACH,SAAS,CAAC,MAAM,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAOxC;CACH;AAOD;;;;;;;GAOG;AACH,eAAO,MAAM,aAAa,eAA0B,CAAC;AAErD;gDACgD;AAChD,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,UAAU,CAAC,OAAO,GAAG,MAAM,GAAG,SAAS,CAOpF;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,UAAU,CAAC,IAAI,EAAE,OAAO,EAAE,oBAAoB,GAAG,IAAI,CAc5F"}
@@ -26,6 +26,7 @@ exports.bindChannelLogger = bindChannelLogger;
26
26
  const protocol_1 = require("@hydranium/protocol");
27
27
  const inversify_1 = require("@theia/core/shared/inversify");
28
28
  const output_channel_1 = require("@theia/output/lib/browser/output-channel");
29
+ const clock_1 = require("../common/clock");
29
30
  /** Inversify token for the {@link ChannelLoggerOptions} constant (merged with the
30
31
  * interface name — the standard Theia "type + token under one identifier" idiom). */
31
32
  exports.ChannelLoggerOptions = Symbol('ChannelLoggerOptions');
@@ -59,10 +60,8 @@ let ChannelLogger = class ChannelLogger extends protocol_1.AbstractLogger {
59
60
  return (this._channel ??= this.outputChannels.getChannel(this.options.channelName));
60
61
  }
61
62
  emit(_level, label, message, args) {
62
- const componentSegment = this.component ? ` [${this.component}]` : '';
63
- const formattedArgs = args.length > 0 ? ' ' + args.map(stringifyArg).join(' ') : '';
64
- // Pad to match the server's 5-char label width so timestamps align across sources.
65
- this.channel.appendLine(`[${label.padEnd(5)} - ${this.timestamp()}]${componentSegment} ${message}${formattedArgs}`);
63
+ const formattedArgs = args.length > 0 ? ' ' + args.map(arg => this.formatArg(arg)).join(' ') : '';
64
+ this.channel.appendLine(`${this.formatLinePrefix(label)} ${message}${formattedArgs}`);
66
65
  }
67
66
  /**
68
67
  * Allocates a free instance bypassing Inversify, so a derived logger inherits
@@ -89,9 +88,10 @@ exports.ChannelLogger = ChannelLogger = __decorate([
89
88
  const ChannelLoggerBase = Symbol('ChannelLoggerBase');
90
89
  /**
91
90
  * Inversify token for the browser `Tracer` — a {@link DefaultTracer} over
92
- * the {@link ChannelLogger} (emit sink) + a {@link SystemClock} + a browser
93
- * heap reader. The browser head has no Langium `services.Tracer` slot, so this
94
- * is how frontend services that time obtain a tracer: `@inject(ChannelTracer)`.
91
+ * the {@link ChannelLogger} (emit sink) + the container's {@link Clock}, or a
92
+ * `SystemClock` when it binds none, + a browser heap reader. The browser head
93
+ * has no Langium `services.Tracer` slot, so this is how frontend services that
94
+ * time obtain a tracer: `@inject(ChannelTracer)`.
95
95
  * Bound by {@link bindChannelLogger}.
96
96
  */
97
97
  exports.ChannelTracer = Symbol('ChannelTracer');
@@ -127,7 +127,10 @@ function bindChannelLogger(bind, options) {
127
127
  return parentName ? base.for(parentName) : base;
128
128
  });
129
129
  bind(exports.ChannelTracer)
130
- .toDynamicValue(ctx => new protocol_1.DefaultTracer(ctx.container.get(ChannelLoggerBase), new protocol_1.SystemClock(), readBrowserMemory))
130
+ .toDynamicValue(ctx => {
131
+ const clock = ctx.container.isBound(clock_1.Clock) ? ctx.container.get(clock_1.Clock) : new protocol_1.SystemClock();
132
+ return new protocol_1.DefaultTracer(ctx.container.get(ChannelLoggerBase), clock, readBrowserMemory);
133
+ })
131
134
  .inSingletonScope();
132
135
  }
133
136
  /** Browser heap reader for {@link ChannelTracer}, backed by Chromium's non-standard `performance.memory`. */
@@ -135,15 +138,4 @@ const readBrowserMemory = () => {
135
138
  const mem = performance.memory;
136
139
  return mem ? { usedBytes: mem.usedJSHeapSize, totalBytes: mem.totalJSHeapSize } : undefined;
137
140
  };
138
- function stringifyArg(arg) {
139
- if (typeof arg === 'string') {
140
- return arg;
141
- }
142
- try {
143
- return JSON.stringify(arg);
144
- }
145
- catch {
146
- return String(arg);
147
- }
148
- }
149
141
  //# sourceMappingURL=channel-logger.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"channel-logger.js","sourceRoot":"","sources":["../../src/browser/channel-logger.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"channel-logger.js","sourceRoot":"","sources":["../../src/browser/channel-logger.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,73 @@
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 Stopwatch } from '@hydranium/protocol';
10
+ import { MessageService } from '@theia/core';
11
+ import { FrontendApplicationContribution } from '@theia/core/lib/browser/frontend-application-contribution';
12
+ import { ConnectionStatus, ConnectionStatusService } from '@theia/core/lib/browser/connection-status-service';
13
+ import { WebSocketConnectionSource } from '@theia/core/lib/browser/messaging/ws-connection-source';
14
+ import { type interfaces } from '@theia/core/shared/inversify';
15
+ import { Clock } from '../common/clock';
16
+ import { type ConnectionBufferOverflow } from '../common/framed-socket-write-buffer';
17
+ import { ChannelLogger } from './channel-logger';
18
+ /**
19
+ * Records the browser side of the websocket lifecycle into the adopter's Output
20
+ * channel, and tells the user the one thing they cannot recover from on their
21
+ * own.
22
+ *
23
+ * Theia reports an outage only as an "Offline" status-bar item, which cannot
24
+ * distinguish a plain network drop from the server having stopped answering on a
25
+ * socket that is still up. The latter is what a connection defect looks like
26
+ * from here, so the two are logged differently — that distinction is what says
27
+ * whether reopening an editor helps or only a reload does.
28
+ *
29
+ * Purely observational apart from the overflow message: nothing here changes how
30
+ * the connection behaves.
31
+ */
32
+ export declare class ConnectionDiagnosticsContribution implements FrontendApplicationContribution {
33
+ protected readonly connectionSource: WebSocketConnectionSource;
34
+ protected readonly connectionStatus: ConnectionStatusService;
35
+ protected readonly logger: ChannelLogger;
36
+ protected readonly messageService: MessageService;
37
+ /** Times the outages the log reports: the container's {@link Clock}, or a `SystemClock`. */
38
+ protected readonly clock: Clock;
39
+ /** Main channels created so far; more than one means the server did not recognise this frontend. */
40
+ protected channelCount: number;
41
+ protected sinceSocketClosed?: Stopwatch;
42
+ protected sinceOffline?: Stopwatch;
43
+ initialize(): void;
44
+ protected handleSocketOpen(): void;
45
+ protected handleSocketClose(): void;
46
+ /**
47
+ * A second channel means the reconnect was refused and the session discarded.
48
+ * Only reachable with `reloadOnReconnect` off — with it on, Theia reloads the
49
+ * page instead of opening another channel.
50
+ */
51
+ protected handleChannelOpen(): void;
52
+ protected handleStatusChange(status: ConnectionStatus): void;
53
+ /**
54
+ * The outage outlasted what the buffer can hold, so changes made from here on
55
+ * are being thrown away rather than queued. Reconnecting resumes sending but
56
+ * cannot bring those back, which leaves the editor disagreeing with the
57
+ * server — and without a message the user would see nothing but an editor
58
+ * that has quietly stopped saving, so say it plainly.
59
+ */
60
+ protected handleBufferOverflow(overflow: ConnectionBufferOverflow): void;
61
+ protected socketId(): string;
62
+ protected statusName(status: ConnectionStatus): string;
63
+ }
64
+ /**
65
+ * Bind {@link ConnectionDiagnosticsContribution} as a `FrontendApplicationContribution`.
66
+ *
67
+ * Needs a {@link ChannelLogger} binding, so call it from a module that has also
68
+ * called `bindChannelLogger`. Unlike `bindConnectionResilience` this belongs in a
69
+ * normal frontend module: it only observes, so it has no reason to run during
70
+ * preload, and `MessageService` is not available that early.
71
+ */
72
+ export declare function bindConnectionDiagnostics(bind: interfaces.Bind): void;
73
+ //# sourceMappingURL=connection-diagnostics-contribution.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"connection-diagnostics-contribution.d.ts","sourceRoot":"","sources":["../../src/browser/connection-diagnostics-contribution.ts"],"names":[],"mappings":"AAAA;;;;;;;kFAOkF;AAElF,OAAO,EAAE,KAAK,SAAS,EAAe,MAAM,qBAAqB,CAAC;AAClE,OAAO,EAAE,cAAc,EAAO,MAAM,aAAa,CAAC;AAClD,OAAO,EAAE,+BAA+B,EAAE,MAAM,2DAA2D,CAAC;AAC5G,OAAO,EAAE,gBAAgB,EAAE,uBAAuB,EAAE,MAAM,mDAAmD,CAAC;AAC9G,OAAO,EAAE,yBAAyB,EAAE,MAAM,wDAAwD,CAAC;AACnG,OAAO,EAAgC,KAAK,UAAU,EAAE,MAAM,8BAA8B,CAAC;AAC7F,OAAO,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAC;AACxC,OAAO,EAAE,KAAK,wBAAwB,EAAE,MAAM,sCAAsC,CAAC;AACrF,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAGjD;;;;;;;;;;;;;GAaG;AACH,qBACa,iCAAkC,YAAW,+BAA+B;IACnD,SAAS,CAAC,QAAQ,CAAC,gBAAgB,EAAE,yBAAyB,CAAC;IACjE,SAAS,CAAC,QAAQ,CAAC,gBAAgB,EAAE,uBAAuB,CAAC;IACvE,SAAS,CAAC,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAC;IACxC,SAAS,CAAC,QAAQ,CAAC,cAAc,EAAE,cAAc,CAAC;IAC1E,4FAA4F;IACjE,SAAS,CAAC,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAqB;IAE/E,oGAAoG;IACpG,SAAS,CAAC,YAAY,SAAK;IAC3B,SAAS,CAAC,iBAAiB,CAAC,EAAE,SAAS,CAAC;IACxC,SAAS,CAAC,YAAY,CAAC,EAAE,SAAS,CAAC;IAEnC,UAAU,IAAI,IAAI,CAWjB;IAED,SAAS,CAAC,gBAAgB,IAAI,IAAI,CAIjC;IAED,SAAS,CAAC,iBAAiB,IAAI,IAAI,CAGlC;IAED;;;;OAIG;IACH,SAAS,CAAC,iBAAiB,IAAI,IAAI,CAUlC;IAED,SAAS,CAAC,kBAAkB,CAAC,MAAM,EAAE,gBAAgB,GAAG,IAAI,CAiB3D;IAED;;;;;;OAMG;IACH,SAAS,CAAC,oBAAoB,CAAC,QAAQ,EAAE,wBAAwB,GAAG,IAAI,CAQvE;IAED,SAAS,CAAC,QAAQ,IAAI,MAAM,CAE3B;IAED,SAAS,CAAC,UAAU,CAAC,MAAM,EAAE,gBAAgB,GAAG,MAAM,CAErD;CACH;AAED;;;;;;;GAOG;AACH,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,UAAU,CAAC,IAAI,GAAG,IAAI,CAGrE"}
@@ -0,0 +1,162 @@
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
+ 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.ConnectionDiagnosticsContribution = void 0;
21
+ exports.bindConnectionDiagnostics = bindConnectionDiagnostics;
22
+ const protocol_1 = require("@hydranium/protocol");
23
+ const core_1 = require("@theia/core");
24
+ const frontend_application_contribution_1 = require("@theia/core/lib/browser/frontend-application-contribution");
25
+ const connection_status_service_1 = require("@theia/core/lib/browser/connection-status-service");
26
+ const ws_connection_source_1 = require("@theia/core/lib/browser/messaging/ws-connection-source");
27
+ const inversify_1 = require("@theia/core/shared/inversify");
28
+ const clock_1 = require("../common/clock");
29
+ const channel_logger_1 = require("./channel-logger");
30
+ const session_aware_connection_source_1 = require("./session-aware-connection-source");
31
+ /**
32
+ * Records the browser side of the websocket lifecycle into the adopter's Output
33
+ * channel, and tells the user the one thing they cannot recover from on their
34
+ * own.
35
+ *
36
+ * Theia reports an outage only as an "Offline" status-bar item, which cannot
37
+ * distinguish a plain network drop from the server having stopped answering on a
38
+ * socket that is still up. The latter is what a connection defect looks like
39
+ * from here, so the two are logged differently — that distinction is what says
40
+ * whether reopening an editor helps or only a reload does.
41
+ *
42
+ * Purely observational apart from the overflow message: nothing here changes how
43
+ * the connection behaves.
44
+ */
45
+ let ConnectionDiagnosticsContribution = class ConnectionDiagnosticsContribution {
46
+ connectionSource;
47
+ connectionStatus;
48
+ logger;
49
+ messageService;
50
+ /** Times the outages the log reports: the container's {@link Clock}, or a `SystemClock`. */
51
+ clock = new protocol_1.SystemClock();
52
+ /** Main channels created so far; more than one means the server did not recognise this frontend. */
53
+ channelCount = 0;
54
+ sinceSocketClosed;
55
+ sinceOffline;
56
+ initialize() {
57
+ this.connectionSource.onSocketDidOpen(() => this.handleSocketOpen());
58
+ this.connectionSource.onSocketDidClose(() => this.handleSocketClose());
59
+ this.connectionSource.onConnectionDidOpen(() => this.handleChannelOpen());
60
+ this.connectionStatus.onStatusChange(status => this.handleStatusChange(status));
61
+ if (this.connectionSource instanceof session_aware_connection_source_1.SessionAwareConnectionSource) {
62
+ this.connectionSource.onBufferOverflow(overflow => this.handleBufferOverflow(overflow));
63
+ }
64
+ // The socket is opened by the preloader, before this contribution exists, so the first
65
+ // `onSocketDidOpen` has already fired; state the current situation instead.
66
+ this.logger.debug(`diagnostics active; socket ${this.socketId()}, backend ${this.statusName(this.connectionStatus.currentStatus)}`);
67
+ }
68
+ handleSocketOpen() {
69
+ const downFor = this.sinceSocketClosed === undefined ? '' : ` after ${Math.round(this.sinceSocketClosed.elapsedMs)} ms down`;
70
+ this.sinceSocketClosed = undefined;
71
+ this.logger.info(`websocket connected: socket ${this.socketId()}${downFor}`);
72
+ }
73
+ handleSocketClose() {
74
+ this.sinceSocketClosed = this.clock.stopwatch();
75
+ this.logger.info(`websocket disconnected: socket ${this.socketId()}; outgoing messages are buffered until it returns`);
76
+ }
77
+ /**
78
+ * A second channel means the reconnect was refused and the session discarded.
79
+ * Only reachable with `reloadOnReconnect` off — with it on, Theia reloads the
80
+ * page instead of opening another channel.
81
+ */
82
+ handleChannelOpen() {
83
+ this.channelCount++;
84
+ if (this.channelCount === 1) {
85
+ this.logger.debug(`initial channel opened on socket ${this.socketId()}`);
86
+ return;
87
+ }
88
+ this.logger.warn(`new channel #${this.channelCount} on socket ${this.socketId()}: the backend did not recognise this frontend, ` +
89
+ 'so its session was discarded and every pending request rejected');
90
+ }
91
+ handleStatusChange(status) {
92
+ if (status === connection_status_service_1.ConnectionStatus.ONLINE) {
93
+ const offlineFor = this.sinceOffline === undefined ? '' : ` after ${Math.round(this.sinceOffline.elapsedMs)} ms`;
94
+ this.sinceOffline = undefined;
95
+ this.logger.info(`backend reachable again${offlineFor}`);
96
+ return;
97
+ }
98
+ this.sinceOffline = this.clock.stopwatch();
99
+ const socket = this.connectionSource.socket;
100
+ if (socket?.connected) {
101
+ this.logger.warn(`backend stopped answering while socket ${socket.id} is still connected: nothing this session sends will ` +
102
+ 'arrive, and socket.io will not reconnect on its own. Reload the page to recover.');
103
+ return;
104
+ }
105
+ this.logger.info(`backend unreachable; websocket is disconnected (socket ${this.socketId()})`);
106
+ }
107
+ /**
108
+ * The outage outlasted what the buffer can hold, so changes made from here on
109
+ * are being thrown away rather than queued. Reconnecting resumes sending but
110
+ * cannot bring those back, which leaves the editor disagreeing with the
111
+ * server — and without a message the user would see nothing but an editor
112
+ * that has quietly stopped saving, so say it plainly.
113
+ */
114
+ handleBufferOverflow(overflow) {
115
+ this.logger.error(`buffer full at ${overflow.maxBytes} bytes holding ${overflow.messages} message(s)`);
116
+ this.messageService.error(core_1.nls.localize('hydranium/connection/offlineLimitReached', 'Disconnected for too long: recent changes were not sent. Reload the page before continuing.'));
117
+ }
118
+ socketId() {
119
+ return this.connectionSource.socket?.id ?? ws_connection_source_1.WebSocketConnectionSource.NO_CONNECTION;
120
+ }
121
+ statusName(status) {
122
+ return status === connection_status_service_1.ConnectionStatus.ONLINE ? 'online' : 'offline';
123
+ }
124
+ };
125
+ exports.ConnectionDiagnosticsContribution = ConnectionDiagnosticsContribution;
126
+ __decorate([
127
+ (0, inversify_1.inject)(ws_connection_source_1.WebSocketConnectionSource),
128
+ __metadata("design:type", ws_connection_source_1.WebSocketConnectionSource)
129
+ ], ConnectionDiagnosticsContribution.prototype, "connectionSource", void 0);
130
+ __decorate([
131
+ (0, inversify_1.inject)(connection_status_service_1.ConnectionStatusService),
132
+ __metadata("design:type", Object)
133
+ ], ConnectionDiagnosticsContribution.prototype, "connectionStatus", void 0);
134
+ __decorate([
135
+ (0, inversify_1.inject)(channel_logger_1.ChannelLogger),
136
+ __metadata("design:type", channel_logger_1.ChannelLogger)
137
+ ], ConnectionDiagnosticsContribution.prototype, "logger", void 0);
138
+ __decorate([
139
+ (0, inversify_1.inject)(core_1.MessageService),
140
+ __metadata("design:type", core_1.MessageService)
141
+ ], ConnectionDiagnosticsContribution.prototype, "messageService", void 0);
142
+ __decorate([
143
+ (0, inversify_1.inject)(clock_1.Clock),
144
+ (0, inversify_1.optional)(),
145
+ __metadata("design:type", Object)
146
+ ], ConnectionDiagnosticsContribution.prototype, "clock", void 0);
147
+ exports.ConnectionDiagnosticsContribution = ConnectionDiagnosticsContribution = __decorate([
148
+ (0, inversify_1.injectable)()
149
+ ], ConnectionDiagnosticsContribution);
150
+ /**
151
+ * Bind {@link ConnectionDiagnosticsContribution} as a `FrontendApplicationContribution`.
152
+ *
153
+ * Needs a {@link ChannelLogger} binding, so call it from a module that has also
154
+ * called `bindChannelLogger`. Unlike `bindConnectionResilience` this belongs in a
155
+ * normal frontend module: it only observes, so it has no reason to run during
156
+ * preload, and `MessageService` is not available that early.
157
+ */
158
+ function bindConnectionDiagnostics(bind) {
159
+ bind(ConnectionDiagnosticsContribution).toSelf().inSingletonScope();
160
+ bind(frontend_application_contribution_1.FrontendApplicationContribution).toService(ConnectionDiagnosticsContribution);
161
+ }
162
+ //# sourceMappingURL=connection-diagnostics-contribution.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"connection-diagnostics-contribution.js","sourceRoot":"","sources":["../../src/browser/connection-diagnostics-contribution.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,57 @@
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 { MessageService, type Progress } from '@theia/core';
10
+ import { type interfaces } from '@theia/core/shared/inversify';
11
+ /** What a head connects to, as the whole sentences reported about it. */
12
+ export interface ConnectionTarget {
13
+ readonly connectingMessage: string;
14
+ readonly connectedMessage: string;
15
+ }
16
+ /** One connection attempt; it reports exactly one end. */
17
+ export interface ConnectionAttempt {
18
+ connected(): void;
19
+ /** Ends the attempt with nothing to report, as when its head is disposed
20
+ * or a newer attempt takes over. */
21
+ cancelled(): void;
22
+ /**
23
+ * `message` is the whole sentence to report. `retry`, when given, starts a
24
+ * fresh attempt at once; a head without one keeps retrying on its own.
25
+ */
26
+ failed(message: string, retry?: () => void): void;
27
+ }
28
+ /**
29
+ * How a head's connection attempts reach the user. A head calls
30
+ * {@link connecting} for every attempt, a reconnect included, and keeps the
31
+ * attempt's retries and bounds itself; this decides only what is shown. Rebind
32
+ * the slot to show nothing, or something other than notifications.
33
+ */
34
+ export interface ConnectionReporter {
35
+ connecting(target: ConnectionTarget): ConnectionAttempt;
36
+ }
37
+ export declare const ConnectionReporter: unique symbol;
38
+ /**
39
+ * Reports through Theia notifications: an attempt still running after
40
+ * {@link connectingNoticeDelayMs} shows its progress, and an attempt ends in at
41
+ * most one notification. A failure is shown once per target until it connects
42
+ * again, so a head that keeps retrying does not raise one per attempt.
43
+ */
44
+ export declare class DefaultConnectionReporter implements ConnectionReporter {
45
+ protected readonly messageService: MessageService;
46
+ protected readonly connectingNoticeDelayMs: number;
47
+ /** Targets whose last reported attempt failed. */
48
+ protected readonly failing: Set<ConnectionTarget>;
49
+ connecting(target: ConnectionTarget): ConnectionAttempt;
50
+ protected showConnecting(target: ConnectionTarget): Promise<Progress>;
51
+ protected showConnected(target: ConnectionTarget): void;
52
+ protected showFailed(target: ConnectionTarget, message: string, retry?: () => void): Promise<void>;
53
+ protected retryLabel(): string;
54
+ }
55
+ /** Bind {@link DefaultConnectionReporter} unless the slot is bound already; every head calls this. */
56
+ export declare function bindConnectionReporter(bind: interfaces.Bind, isBound: interfaces.IsBound): void;
57
+ //# sourceMappingURL=connection-reporter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"connection-reporter.d.ts","sourceRoot":"","sources":["../../src/browser/connection-reporter.ts"],"names":[],"mappings":"AAAA;;;;;;;kFAOkF;AAElF,OAAO,EAAE,cAAc,EAAO,KAAK,QAAQ,EAAE,MAAM,aAAa,CAAC;AACjE,OAAO,EAAsB,KAAK,UAAU,EAAE,MAAM,8BAA8B,CAAC;AAEnF,yEAAyE;AACzE,MAAM,WAAW,gBAAgB;IAC9B,QAAQ,CAAC,iBAAiB,EAAE,MAAM,CAAC;IACnC,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;CACpC;AAED,0DAA0D;AAC1D,MAAM,WAAW,iBAAiB;IAC/B,SAAS,IAAI,IAAI,CAAC;IAClB;yCACqC;IACrC,SAAS,IAAI,IAAI,CAAC;IAClB;;;OAGG;IACH,MAAM,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,IAAI,GAAG,IAAI,CAAC;CACpD;AAED;;;;;GAKG;AACH,MAAM,WAAW,kBAAkB;IAChC,UAAU,CAAC,MAAM,EAAE,gBAAgB,GAAG,iBAAiB,CAAC;CAC1D;AACD,eAAO,MAAM,kBAAkB,eAA+B,CAAC;AAE/D;;;;;GAKG;AACH,qBACa,yBAA0B,YAAW,kBAAkB;IACzC,SAAS,CAAC,QAAQ,CAAC,cAAc,EAAG,cAAc,CAAC;IAE3E,SAAS,CAAC,QAAQ,CAAC,uBAAuB,EAAE,MAAM,CAAS;IAC3D,kDAAkD;IAClD,SAAS,CAAC,QAAQ,CAAC,OAAO,wBAA+B;IAEzD,UAAU,CAAC,MAAM,EAAE,gBAAgB,GAAG,iBAAiB,CA+BtD;IAED,SAAS,CAAC,cAAc,CAAC,MAAM,EAAE,gBAAgB,GAAG,OAAO,CAAC,QAAQ,CAAC,CAEpE;IAED,SAAS,CAAC,aAAa,CAAC,MAAM,EAAE,gBAAgB,GAAG,IAAI,CAEtD;IAED,UAAgB,UAAU,CAAC,MAAM,EAAE,gBAAgB,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAWvG;IAED,SAAS,CAAC,UAAU,IAAI,MAAM,CAE7B;CACH;AAED,sGAAsG;AACtG,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,UAAU,CAAC,IAAI,EAAE,OAAO,EAAE,UAAU,CAAC,OAAO,GAAG,IAAI,CAI/F"}