@hydranium/glsp-server 1.0.0-next.31 → 1.0.0-next.315

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 (217) hide show
  1. package/README.md +80 -88
  2. package/lib/browser/start-glsp-server-in-worker.d.ts +43 -42
  3. package/lib/browser/start-glsp-server-in-worker.d.ts.map +1 -1
  4. package/lib/browser/start-glsp-server-in-worker.js +62 -13
  5. package/lib/browser/start-glsp-server-in-worker.js.map +1 -1
  6. package/lib/command/diagram-edit-dropped-error.d.ts +31 -0
  7. package/lib/command/diagram-edit-dropped-error.d.ts.map +1 -0
  8. package/lib/command/diagram-edit-dropped-error.js +48 -0
  9. package/lib/command/diagram-edit-dropped-error.js.map +1 -0
  10. package/lib/command/hydranium-glsp-command-stack.d.ts +33 -0
  11. package/lib/command/hydranium-glsp-command-stack.d.ts.map +1 -0
  12. package/lib/command/hydranium-glsp-command-stack.js +63 -0
  13. package/lib/command/hydranium-glsp-command-stack.js.map +1 -0
  14. package/lib/command/hydranium-glsp-operation-action-handler.d.ts +64 -0
  15. package/lib/command/hydranium-glsp-operation-action-handler.d.ts.map +1 -0
  16. package/lib/command/hydranium-glsp-operation-action-handler.js +142 -0
  17. package/lib/command/hydranium-glsp-operation-action-handler.js.map +1 -0
  18. package/lib/command/hydranium-glsp-operation-command.d.ts +250 -0
  19. package/lib/command/hydranium-glsp-operation-command.d.ts.map +1 -0
  20. package/lib/command/hydranium-glsp-operation-command.js +491 -0
  21. package/lib/command/hydranium-glsp-operation-command.js.map +1 -0
  22. package/lib/command/hydranium-glsp-recording-command.d.ts +26 -87
  23. package/lib/command/hydranium-glsp-recording-command.d.ts.map +1 -1
  24. package/lib/command/hydranium-glsp-recording-command.js +40 -117
  25. package/lib/command/hydranium-glsp-recording-command.js.map +1 -1
  26. package/lib/command/hydranium-glsp-undo-redo-action-handler.d.ts +23 -0
  27. package/lib/command/hydranium-glsp-undo-redo-action-handler.d.ts.map +1 -0
  28. package/lib/command/hydranium-glsp-undo-redo-action-handler.js +41 -0
  29. package/lib/command/hydranium-glsp-undo-redo-action-handler.js.map +1 -0
  30. package/lib/command/index.d.ts +5 -0
  31. package/lib/command/index.d.ts.map +1 -1
  32. package/lib/command/index.js +5 -0
  33. package/lib/command/index.js.map +1 -1
  34. package/lib/computed-bounds/hydranium-glsp-computed-bounds-action-handler.d.ts +1 -1
  35. package/lib/computed-bounds/hydranium-glsp-computed-bounds-action-handler.d.ts.map +1 -1
  36. package/lib/computed-bounds/hydranium-glsp-computed-bounds-action-handler.js +2 -2
  37. package/lib/computed-bounds/hydranium-glsp-computed-bounds-action-handler.js.map +1 -1
  38. package/lib/dispatcher/server-action-dispatcher.d.ts +25 -24
  39. package/lib/dispatcher/server-action-dispatcher.d.ts.map +1 -1
  40. package/lib/dispatcher/server-action-dispatcher.js +38 -26
  41. package/lib/dispatcher/server-action-dispatcher.js.map +1 -1
  42. package/lib/index.d.ts +1 -0
  43. package/lib/index.d.ts.map +1 -1
  44. package/lib/index.js +1 -0
  45. package/lib/index.js.map +1 -1
  46. package/lib/launcher/abstract-hydranium-glsp-diagram-module.d.ts +35 -59
  47. package/lib/launcher/abstract-hydranium-glsp-diagram-module.d.ts.map +1 -1
  48. package/lib/launcher/abstract-hydranium-glsp-diagram-module.js +60 -71
  49. package/lib/launcher/abstract-hydranium-glsp-diagram-module.js.map +1 -1
  50. package/lib/launcher/drop-notifications-to-gone-client.d.ts +23 -0
  51. package/lib/launcher/drop-notifications-to-gone-client.d.ts.map +1 -0
  52. package/lib/launcher/drop-notifications-to-gone-client.js +43 -0
  53. package/lib/launcher/drop-notifications-to-gone-client.js.map +1 -0
  54. package/lib/launcher/glsp-app-module.d.ts +1 -2
  55. package/lib/launcher/glsp-app-module.d.ts.map +1 -1
  56. package/lib/launcher/glsp-app-module.js.map +1 -1
  57. package/lib/launcher/glsp-connection-logger.d.ts +19 -0
  58. package/lib/launcher/glsp-connection-logger.d.ts.map +1 -0
  59. package/lib/launcher/glsp-connection-logger.js +24 -0
  60. package/lib/launcher/glsp-connection-logger.js.map +1 -0
  61. package/lib/launcher/glsp-server-overrides.d.ts +10 -8
  62. package/lib/launcher/glsp-server-overrides.d.ts.map +1 -1
  63. package/lib/launcher/glsp-server-overrides.js +25 -11
  64. package/lib/launcher/glsp-server-overrides.js.map +1 -1
  65. package/lib/launcher/hydranium-glsp-server.d.ts +60 -15
  66. package/lib/launcher/hydranium-glsp-server.d.ts.map +1 -1
  67. package/lib/launcher/hydranium-glsp-server.js +145 -22
  68. package/lib/launcher/hydranium-glsp-server.js.map +1 -1
  69. package/lib/launcher/index.d.ts +2 -0
  70. package/lib/launcher/index.d.ts.map +1 -1
  71. package/lib/launcher/index.js +5 -4
  72. package/lib/launcher/index.js.map +1 -1
  73. package/lib/logging/glsp-client-logger.d.ts +10 -6
  74. package/lib/logging/glsp-client-logger.d.ts.map +1 -1
  75. package/lib/logging/glsp-client-logger.js +14 -7
  76. package/lib/logging/glsp-client-logger.js.map +1 -1
  77. package/lib/messages/index.d.ts +11 -6
  78. package/lib/messages/index.d.ts.map +1 -1
  79. package/lib/messages/index.js +11 -6
  80. package/lib/messages/index.js.map +1 -1
  81. package/lib/node/start-glsp-server.d.ts +50 -15
  82. package/lib/node/start-glsp-server.d.ts.map +1 -1
  83. package/lib/node/start-glsp-server.js +97 -30
  84. package/lib/node/start-glsp-server.js.map +1 -1
  85. package/lib/state/abstract-hydranium-glsp-state.d.ts +326 -102
  86. package/lib/state/abstract-hydranium-glsp-state.d.ts.map +1 -1
  87. package/lib/state/abstract-hydranium-glsp-state.js +529 -139
  88. package/lib/state/abstract-hydranium-glsp-state.js.map +1 -1
  89. package/lib/state/diagram-status.d.ts +38 -0
  90. package/lib/state/diagram-status.d.ts.map +1 -0
  91. package/lib/state/diagram-status.js +27 -0
  92. package/lib/state/diagram-status.js.map +1 -0
  93. package/lib/state/full-text-hydranium-glsp-state.d.ts +22 -9
  94. package/lib/state/full-text-hydranium-glsp-state.d.ts.map +1 -1
  95. package/lib/state/full-text-hydranium-glsp-state.js +45 -18
  96. package/lib/state/full-text-hydranium-glsp-state.js.map +1 -1
  97. package/lib/state/hydranium-glsp-index.d.ts +40 -29
  98. package/lib/state/hydranium-glsp-index.d.ts.map +1 -1
  99. package/lib/state/hydranium-glsp-index.js +82 -45
  100. package/lib/state/hydranium-glsp-index.js.map +1 -1
  101. package/lib/state/hydranium-shared-core-services.d.ts +16 -29
  102. package/lib/state/hydranium-shared-core-services.d.ts.map +1 -1
  103. package/lib/state/hydranium-shared-core-services.js +15 -28
  104. package/lib/state/hydranium-shared-core-services.js.map +1 -1
  105. package/lib/state/index.d.ts +1 -0
  106. package/lib/state/index.d.ts.map +1 -1
  107. package/lib/state/index.js +1 -0
  108. package/lib/state/index.js.map +1 -1
  109. package/lib/state/model-ready-timeout-error.d.ts.map +1 -1
  110. package/lib/state/model-ready-timeout-error.js.map +1 -1
  111. package/lib/state/reconcile-source-model-write.d.ts +13 -27
  112. package/lib/state/reconcile-source-model-write.d.ts.map +1 -1
  113. package/lib/state/reconcile-source-model-write.js +44 -32
  114. package/lib/state/reconcile-source-model-write.js.map +1 -1
  115. package/lib/state/reconciling-multi-document-glsp-state.d.ts +125 -69
  116. package/lib/state/reconciling-multi-document-glsp-state.d.ts.map +1 -1
  117. package/lib/state/reconciling-multi-document-glsp-state.js +242 -100
  118. package/lib/state/reconciling-multi-document-glsp-state.js.map +1 -1
  119. package/lib/state/reconciling-transfer-hydranium-glsp-state.d.ts +36 -28
  120. package/lib/state/reconciling-transfer-hydranium-glsp-state.d.ts.map +1 -1
  121. package/lib/state/reconciling-transfer-hydranium-glsp-state.js +59 -42
  122. package/lib/state/reconciling-transfer-hydranium-glsp-state.js.map +1 -1
  123. package/lib/status/diagram-status-reporter.d.ts +44 -0
  124. package/lib/status/diagram-status-reporter.d.ts.map +1 -0
  125. package/lib/status/diagram-status-reporter.js +88 -0
  126. package/lib/status/diagram-status-reporter.js.map +1 -0
  127. package/lib/status/hydranium-glsp-request-model-action-handler.d.ts +27 -0
  128. package/lib/status/hydranium-glsp-request-model-action-handler.d.ts.map +1 -0
  129. package/lib/status/hydranium-glsp-request-model-action-handler.js +52 -0
  130. package/lib/status/hydranium-glsp-request-model-action-handler.js.map +1 -0
  131. package/lib/status/hydranium-glsp-set-edit-mode-action-handler.d.ts +27 -0
  132. package/lib/status/hydranium-glsp-set-edit-mode-action-handler.d.ts.map +1 -0
  133. package/lib/status/hydranium-glsp-set-edit-mode-action-handler.js +53 -0
  134. package/lib/status/hydranium-glsp-set-edit-mode-action-handler.js.map +1 -0
  135. package/lib/status/index.d.ts +12 -0
  136. package/lib/status/index.d.ts.map +1 -0
  137. package/lib/status/index.js +12 -0
  138. package/lib/status/index.js.map +1 -0
  139. package/lib/storage/hydranium-glsp-request-save-model-action-handler.d.ts +30 -0
  140. package/lib/storage/hydranium-glsp-request-save-model-action-handler.d.ts.map +1 -0
  141. package/lib/storage/hydranium-glsp-request-save-model-action-handler.js +47 -0
  142. package/lib/storage/hydranium-glsp-request-save-model-action-handler.js.map +1 -0
  143. package/lib/storage/hydranium-glsp-storage.d.ts +324 -143
  144. package/lib/storage/hydranium-glsp-storage.d.ts.map +1 -1
  145. package/lib/storage/hydranium-glsp-storage.js +569 -213
  146. package/lib/storage/hydranium-glsp-storage.js.map +1 -1
  147. package/lib/storage/index.d.ts +2 -1
  148. package/lib/storage/index.d.ts.map +1 -1
  149. package/lib/storage/index.js +2 -1
  150. package/lib/storage/index.js.map +1 -1
  151. package/lib/storage/save-delivery-policy.d.ts +51 -0
  152. package/lib/storage/save-delivery-policy.d.ts.map +1 -0
  153. package/lib/storage/{save-conflict-policy.js → save-delivery-policy.js} +7 -8
  154. package/lib/storage/save-delivery-policy.js.map +1 -0
  155. package/lib/submission/hydranium-glsp-submission-handler.d.ts +44 -4
  156. package/lib/submission/hydranium-glsp-submission-handler.d.ts.map +1 -1
  157. package/lib/submission/hydranium-glsp-submission-handler.js +82 -6
  158. package/lib/submission/hydranium-glsp-submission-handler.js.map +1 -1
  159. package/lib/testing/glsp-harness.d.ts +34 -7
  160. package/lib/testing/glsp-harness.d.ts.map +1 -1
  161. package/lib/testing/glsp-harness.js +47 -19
  162. package/lib/testing/glsp-harness.js.map +1 -1
  163. package/lib/validation/diagnostic-markers.d.ts +3 -3
  164. package/lib/validation/diagnostic-markers.d.ts.map +1 -1
  165. package/lib/validation/diagnostic-markers.js +1 -1
  166. package/lib/validation/diagnostic-markers.js.map +1 -1
  167. package/lib/validation/hydranium-glsp-model-validator.d.ts +1 -2
  168. package/lib/validation/hydranium-glsp-model-validator.d.ts.map +1 -1
  169. package/lib/validation/hydranium-glsp-model-validator.js +1 -1
  170. package/lib/validation/hydranium-glsp-model-validator.js.map +1 -1
  171. package/package.json +31 -52
  172. package/src/browser/start-glsp-server-in-worker.ts +79 -51
  173. package/src/command/diagram-edit-dropped-error.ts +51 -0
  174. package/src/command/hydranium-glsp-command-stack.ts +47 -0
  175. package/src/command/hydranium-glsp-operation-action-handler.ts +141 -0
  176. package/src/command/hydranium-glsp-operation-command.ts +602 -0
  177. package/src/command/hydranium-glsp-recording-command.ts +40 -121
  178. package/src/command/hydranium-glsp-undo-redo-action-handler.ts +29 -0
  179. package/src/command/index.ts +10 -0
  180. package/src/computed-bounds/hydranium-glsp-computed-bounds-action-handler.ts +2 -2
  181. package/src/dispatcher/server-action-dispatcher.ts +39 -31
  182. package/src/index.ts +1 -0
  183. package/src/launcher/abstract-hydranium-glsp-diagram-module.ts +79 -91
  184. package/src/launcher/drop-notifications-to-gone-client.ts +47 -0
  185. package/src/launcher/glsp-app-module.ts +1 -2
  186. package/src/launcher/glsp-connection-logger.ts +27 -0
  187. package/src/launcher/glsp-server-overrides.ts +27 -11
  188. package/src/launcher/hydranium-glsp-server.ts +153 -23
  189. package/src/launcher/index.ts +5 -4
  190. package/src/logging/glsp-client-logger.ts +16 -9
  191. package/src/messages/index.ts +16 -6
  192. package/src/node/start-glsp-server.ts +133 -40
  193. package/src/state/abstract-hydranium-glsp-state.ts +609 -154
  194. package/src/state/diagram-status.ts +41 -0
  195. package/src/state/full-text-hydranium-glsp-state.ts +46 -18
  196. package/src/state/hydranium-glsp-index.ts +85 -41
  197. package/src/state/hydranium-shared-core-services.ts +16 -29
  198. package/src/state/index.ts +1 -0
  199. package/src/state/reconcile-source-model-write.ts +51 -53
  200. package/src/state/reconciling-multi-document-glsp-state.ts +276 -102
  201. package/src/state/reconciling-transfer-hydranium-glsp-state.ts +67 -45
  202. package/src/status/diagram-status-reporter.ts +106 -0
  203. package/src/status/hydranium-glsp-request-model-action-handler.ts +43 -0
  204. package/src/status/hydranium-glsp-set-edit-mode-action-handler.ts +38 -0
  205. package/src/status/index.ts +12 -0
  206. package/src/storage/hydranium-glsp-request-save-model-action-handler.ts +40 -0
  207. package/src/storage/hydranium-glsp-storage.ts +647 -223
  208. package/src/storage/index.ts +2 -1
  209. package/src/storage/save-delivery-policy.ts +49 -0
  210. package/src/submission/hydranium-glsp-submission-handler.ts +91 -5
  211. package/src/testing/glsp-harness.ts +67 -25
  212. package/src/validation/diagnostic-markers.ts +3 -3
  213. package/src/validation/hydranium-glsp-model-validator.ts +4 -5
  214. package/lib/storage/save-conflict-policy.d.ts +0 -56
  215. package/lib/storage/save-conflict-policy.d.ts.map +0 -1
  216. package/lib/storage/save-conflict-policy.js.map +0 -1
  217. package/src/storage/save-conflict-policy.ts +0 -52
@@ -15,15 +15,61 @@ import {
15
15
  createAppModule,
16
16
  defaultSocketLaunchOptions
17
17
  } from '@eclipse-glsp/server/node.js';
18
- import { Container, type ContainerModule } from 'inversify';
19
- import type { Logger } from '@hydranium/protocol';
20
- import { Deferred } from '@hydranium/langium';
18
+ import { Container, ContainerModule, injectable } from 'inversify';
19
+ import { Deferred, describeError, describeErrorWithStack, sendByMethodName, type Logger } from '@hydranium/protocol';
21
20
  import type * as net from 'node:net';
22
- import type { IntegratedServer } from '@hydranium/core';
21
+ import { createMessageConnection, SocketMessageReader, SocketMessageWriter } from 'vscode-jsonrpc/node';
22
+ import {
23
+ initializeWorkspaceWithoutLsp,
24
+ type IntegratedServer,
25
+ type ServerSharedServicesMinimal,
26
+ type WorkspaceFolderInput
27
+ } from '@hydranium/core';
28
+ import { dropNotificationsToGoneClient } from '../launcher/drop-notifications-to-gone-client.js';
29
+ import { createGlspConnectionLogger } from '../launcher/glsp-connection-logger.js';
23
30
  import { createGlspFrameworkOverrides } from '../launcher/glsp-framework-overrides.js';
24
31
  import { createGlspServerOverrides } from '../launcher/glsp-server-overrides.js';
32
+ import { HydraniumTypes } from '../state/hydranium-shared-core-services.js';
25
33
  import type { LspConnectionLike } from '@hydranium/core/node';
26
34
 
35
+ /**
36
+ * The default socket launcher of {@link startGlspServer}: GLSP's own,
37
+ * with each connection built from this package's copy of `vscode-jsonrpc`, so a
38
+ * framework error thrown in a handler keeps its code. The connection sends
39
+ * GLSP's typed messages by method name, since GLSP builds them from its copy.
40
+ */
41
+ @injectable()
42
+ export class HydraniumGlspSocketServerLauncher extends SocketServerLauncher {
43
+ protected override createConnection(socket: net.Socket): ReturnType<SocketServerLauncher['createConnection']> {
44
+ return dropNotificationsToGoneClient(
45
+ sendByMethodName(
46
+ createMessageConnection(
47
+ new SocketMessageReader(socket),
48
+ new SocketMessageWriter(socket),
49
+ createGlspConnectionLogger(this.logger)
50
+ )
51
+ ),
52
+ this.logger
53
+ );
54
+ }
55
+ }
56
+
57
+ /**
58
+ * Binds GLSP's own `SocketServerLauncher` token to
59
+ * {@link HydraniumGlspSocketServerLauncher}. {@link startGlspServer} loads it
60
+ * before the adopter's `appModules`, so an adopter replaces the launcher with
61
+ * `rebind`; a second `bind` makes the resolve ambiguous and the start throws.
62
+ * A replacement extends {@link HydraniumGlspSocketServerLauncher}: GLSP's own
63
+ * launcher builds its connection from GLSP's copy, so framework errors lose
64
+ * their code, and GLSP's typed messages throw where its packages nest
65
+ * separate copies.
66
+ */
67
+ export function createGlspSocketLauncherModule(): ContainerModule {
68
+ return new ContainerModule(bind => {
69
+ bind(SocketServerLauncher).to(HydraniumGlspSocketServerLauncher);
70
+ });
71
+ }
72
+
27
73
  /**
28
74
  * Options for {@link startGlspServer}.
29
75
  *
@@ -65,12 +111,20 @@ export interface GlspServerOptions {
65
111
  /**
66
112
  * Additional Inversify modules to load on the app container AFTER GLSP's
67
113
  * own app module (via `createAppModule`, which binds `InjectionContainer`
68
- * plus the GLSP-version-specific app bindings) and the framework overrides
114
+ * plus the GLSP-version-specific app bindings), the framework overrides
69
115
  * that route GLSP's logger and logger factory through the adopter logger
70
- * and add the shared Tracer. Adopters wire language-services bindings
71
- * (e.g. their own shared-services symbol) here.
116
+ * and add the shared Tracer, and {@link createGlspSocketLauncherModule}.
117
+ * Adopters wire language-services bindings (e.g. their own shared-services
118
+ * symbol) here, and replace the launcher with `rebind`.
72
119
  */
73
120
  readonly appModules?: ReadonlyArray<ContainerModule>;
121
+ /**
122
+ * Workspace root(s) to initialize — a filesystem path or a `URI`. Required
123
+ * when no LSP head is composed, refused beside one: see
124
+ * `initializeWorkspaceWithoutLsp`. The shared services are the ones
125
+ * `HydraniumGlspAppModule` binds in {@link appModules}.
126
+ */
127
+ readonly workspace?: WorkspaceFolderInput | ReadonlyArray<WorkspaceFolderInput>;
74
128
  /**
75
129
  * Optional LSP connection used to register a port-discovery request
76
130
  * handler. When both `lspConnection` and `portCommand` are set, the
@@ -105,12 +159,14 @@ export interface GlspServerOptions {
105
159
  /**
106
160
  * Live GLSP server handle returned by {@link startGlspServer}.
107
161
  *
108
- * - {@link IntegratedServer.started} resolves once the GLSP socket is
109
- * listening AND (if configured) the port-discovery handler has been
110
- * registered on the LSP connection.
111
- * - {@link IntegratedServer.stopped} resolves once GLSP's
112
- * `SocketServerLauncher.start` promise settles (i.e. the underlying
113
- * `net.Server` has closed).
162
+ * - {@link IntegratedServer.started} resolves once the workspace is up,
163
+ * where the launcher brings it up, AND the GLSP socket is listening AND
164
+ * (if configured) the port-discovery handler has been registered on the
165
+ * LSP connection. It rejects, and nothing listens, when the bring-up fails.
166
+ * - {@link IntegratedServer.stopped} settles as GLSP's
167
+ * `SocketServerLauncher.start` promise does (i.e. once the underlying
168
+ * `net.Server` has closed), or resolves once a failed bring-up has
169
+ * rejected `started`.
114
170
  * - {@link port} is `undefined` until `started` resolves.
115
171
  */
116
172
  export interface StartedGlspServer extends IntegratedServer {
@@ -120,17 +176,22 @@ export interface StartedGlspServer extends IntegratedServer {
120
176
  /**
121
177
  * Start a GLSP socket head. Builds the GLSP app container with framework-
122
178
  * default `Logger` / `LoggerFactory` bindings, layers adopter modules,
123
- * resolves {@link SocketServerLauncher}, configures the adopter
179
+ * resolves the launcher bound to {@link SocketServerLauncher}, by default
180
+ * {@link HydraniumGlspSocketServerLauncher}, configures the adopter
124
181
  * {@link ServerModule}, and starts listening.
125
182
  *
126
183
  * **GLSP launcher coupling.** GLSP's {@link SocketServerLauncher} owns the
127
- * `net.Server` and per-connection `MessageConnection` construction;
184
+ * `net.Server` and each connection's server instance;
128
185
  * the framework wrapper composes ABOVE that launcher rather than replacing
129
186
  * it. The framework's own `startSocketServer`
130
187
  * helper is NOT used here — it's designed for stdio/raw-JSON-RPC heads
131
188
  * (data-server's pattern), not GLSP's Inversify-driven per-connection
132
189
  * server-instance model. Bridging the two would lose GLSP's action-handler
133
190
  * registry plumbing.
191
+ *
192
+ * **Without an LSP head the launcher brings the workspace up, then
193
+ * listens**, as `startSocketServer` does: a diagram loaded before the
194
+ * bring-up starts keeps its cross-file edges missing for good.
134
195
  */
135
196
  export function startGlspServer(options: GlspServerOptions): StartedGlspServer {
136
197
  const launchOptions: SocketLaunchOptions = {
@@ -150,20 +211,30 @@ export function startGlspServer(options: GlspServerOptions): StartedGlspServer {
150
211
  const glspAppModule = createAppModule({ ...launchOptions, consoleLog: false, fileLog: false });
151
212
 
152
213
  const appContainer = new Container();
153
- appContainer.load(glspAppModule, createGlspFrameworkOverrides(options.createLogger), ...(options.appModules ?? []));
214
+ appContainer.load(
215
+ glspAppModule,
216
+ createGlspFrameworkOverrides(options.createLogger),
217
+ createGlspSocketLauncherModule(),
218
+ ...(options.appModules ?? [])
219
+ );
154
220
 
155
- const launcher = appContainer.resolve<SocketServerLauncher>(SocketServerLauncher);
221
+ const launcher = appContainer.get<SocketServerLauncher>(SocketServerLauncher);
156
222
  // Passed as an additional module rather than folded into the app container:
157
223
  // the launcher loads these into the per-connection SERVER container, which is
158
- // the only tier where the adopter's `ServerModule` binding of `GLSPServer`
159
- // can be rebound.
224
+ // the tier where each connection gets a server of its own.
160
225
  launcher.configure(options.serverModule, createGlspServerOverrides());
161
226
 
162
227
  const started = new Deferred<void>();
228
+ const stopped = new Deferred<void>();
163
229
  const portHandle: { port: number | undefined } = { port: undefined };
164
230
 
165
- try {
166
- const stoppedPromise = Promise.resolve(launcher.start(launchOptions));
231
+ const listen = (): void => {
232
+ // `start` creates the `net.Server` and listens, so the listeners below
233
+ // attach to it synchronously after the call, before any event fires.
234
+ Promise.resolve(launcher.start(launchOptions)).then(
235
+ () => stopped.resolve(),
236
+ (error: unknown) => stopped.reject(error)
237
+ );
167
238
 
168
239
  // GLSP's `SocketServerLauncher.netServer` field is `protected`; we
169
240
  // access it via property indexing. The alternative is to fork the
@@ -177,7 +248,7 @@ export function startGlspServer(options: GlspServerOptions): StartedGlspServer {
177
248
  if (options.lspConnection && options.portCommand) {
178
249
  options.lspConnection.onRequest(options.portCommand, () => portHandle.port);
179
250
  }
180
- lifecycle?.info(`[GlspServer] Ready to accept new client requests on port: ${address.port}`);
251
+ lifecycle?.info(`[GlspServer] Ready to accept new client requests on ${address.address} port: ${address.port}`);
181
252
  started.resolve();
182
253
  } else {
183
254
  const message = address === null ? 'address is null' : `bound to non-TCP "${String(address)}"`;
@@ -187,28 +258,50 @@ export function startGlspServer(options: GlspServerOptions): StartedGlspServer {
187
258
  }
188
259
  });
189
260
  netServer.on('error', (err: Error) => {
190
- lifecycle?.error(`[GlspServer] Error: ${err.message}`);
261
+ lifecycle?.error(`[GlspServer] Error: ${describeErrorWithStack(err)}`);
191
262
  started.reject(err);
192
263
  });
193
264
  if (options.onClientConnection) {
194
265
  netServer.on('connection', options.onClientConnection);
195
266
  }
267
+ };
196
268
 
197
- return {
198
- get port() {
199
- return portHandle.port;
200
- },
201
- started: started.promise,
202
- stopped: stoppedPromise
203
- };
204
- } catch (error) {
205
- lifecycle?.error('Error in GLSP server launcher:', error);
206
- return {
207
- get port() {
208
- return portHandle.port;
209
- },
210
- started: Promise.reject(error),
211
- stopped: Promise.resolve()
212
- };
213
- }
269
+ // The workspace manager logs a failed initialization itself; a refused
270
+ // `workspace` throws before `initializing` is set.
271
+ let initializing = false;
272
+ const begin = async (): Promise<void> => {
273
+ const shared = appContainer.isBound(HydraniumTypes.SharedCoreServices)
274
+ ? appContainer.get<ServerSharedServicesMinimal>(HydraniumTypes.SharedCoreServices)
275
+ : undefined;
276
+ if (shared === undefined) {
277
+ throw new Error(
278
+ '[hydranium] startGlspServer found no shared services in its app container. Add `new HydraniumGlspAppModule({ shared })` to `appModules`.'
279
+ );
280
+ }
281
+ const initialization = initializeWorkspaceWithoutLsp(shared, options.workspace);
282
+ initializing = true;
283
+ await initialization;
284
+ initializing = false;
285
+ listen();
286
+ };
287
+ begin().catch((error: unknown) => {
288
+ if (initializing) {
289
+ lifecycle?.debug(`[GlspServer] Startup failed: the workspace did not initialize. ${describeError(error)}`);
290
+ } else {
291
+ lifecycle?.error(`[GlspServer] Startup failed: ${describeErrorWithStack(error)}`);
292
+ }
293
+ started.reject(error);
294
+ stopped.resolve();
295
+ });
296
+ // `started` is always observed internally, as `startStdioServer`'s is, so a
297
+ // caller that closes early and ignores it cannot crash the process.
298
+ void started.promise.catch(() => undefined);
299
+
300
+ return {
301
+ get port() {
302
+ return portHandle.port;
303
+ },
304
+ started: started.promise,
305
+ stopped: stopped.promise
306
+ };
214
307
  }