@hydranium/glsp-server 1.0.0-next.309 → 1.0.0-next.313

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.
package/README.md CHANGED
@@ -44,7 +44,9 @@ decorators need it.
44
44
  your diagram modules in `serverModule`,
45
45
  `new HydraniumGlspAppModule({ shared })` in `appModules`, and a
46
46
  `GlspClientLogger` from `createLogger`. Pass `lspConnection` and
47
- `portCommand` to tell the client its port.
47
+ `portCommand` to tell the client its port. Without an LSP head, pass the
48
+ workspace root as `workspace`: the head brings the workspace up before it
49
+ listens.
48
50
  3. In a browser, start it with `startGlspServerInWorker` from `./browser`
49
51
  instead, on a transferred `MessagePort`.
50
52
 
@@ -10,7 +10,7 @@ import { type Logger as GlspLogger, type ServerModule, SocketServerLauncher } fr
10
10
  import { ContainerModule } from 'inversify';
11
11
  import { type Logger } from '@hydranium/protocol';
12
12
  import type * as net from 'node:net';
13
- import type { IntegratedServer } from '@hydranium/core';
13
+ import { type IntegratedServer, type WorkspaceFolderInput } from '@hydranium/core';
14
14
  import type { LspConnectionLike } from '@hydranium/core/node';
15
15
  /**
16
16
  * The default socket launcher of {@link startGlspServer}: GLSP's own,
@@ -80,6 +80,13 @@ export interface GlspServerOptions {
80
80
  * symbol) here, and replace the launcher with `rebind`.
81
81
  */
82
82
  readonly appModules?: ReadonlyArray<ContainerModule>;
83
+ /**
84
+ * Workspace root(s) to initialize — a filesystem path or a `URI`. Required
85
+ * when no LSP head is composed, refused beside one: see
86
+ * `initializeWorkspaceWithoutLsp`. The shared services are the ones
87
+ * `HydraniumGlspAppModule` binds in {@link appModules}.
88
+ */
89
+ readonly workspace?: WorkspaceFolderInput | ReadonlyArray<WorkspaceFolderInput>;
83
90
  /**
84
91
  * Optional LSP connection used to register a port-discovery request
85
92
  * handler. When both `lspConnection` and `portCommand` are set, the
@@ -113,12 +120,14 @@ export interface GlspServerOptions {
113
120
  /**
114
121
  * Live GLSP server handle returned by {@link startGlspServer}.
115
122
  *
116
- * - {@link IntegratedServer.started} resolves once the GLSP socket is
117
- * listening AND (if configured) the port-discovery handler has been
118
- * registered on the LSP connection.
119
- * - {@link IntegratedServer.stopped} resolves once GLSP's
120
- * `SocketServerLauncher.start` promise settles (i.e. the underlying
121
- * `net.Server` has closed).
123
+ * - {@link IntegratedServer.started} resolves once the workspace is up,
124
+ * where the launcher brings it up, AND the GLSP socket is listening AND
125
+ * (if configured) the port-discovery handler has been registered on the
126
+ * LSP connection. It rejects, and nothing listens, when the bring-up fails.
127
+ * - {@link IntegratedServer.stopped} settles as GLSP's
128
+ * `SocketServerLauncher.start` promise does (i.e. once the underlying
129
+ * `net.Server` has closed), or resolves once a failed bring-up has
130
+ * rejected `started`.
122
131
  * - {@link port} is `undefined` until `started` resolves.
123
132
  */
124
133
  export interface StartedGlspServer extends IntegratedServer {
@@ -139,6 +148,10 @@ export interface StartedGlspServer extends IntegratedServer {
139
148
  * (data-server's pattern), not GLSP's Inversify-driven per-connection
140
149
  * server-instance model. Bridging the two would lose GLSP's action-handler
141
150
  * registry plumbing.
151
+ *
152
+ * **Without an LSP head the launcher brings the workspace up, then
153
+ * listens**, as `startSocketServer` does: a diagram loaded before the
154
+ * bring-up starts keeps its cross-file edges missing for good.
142
155
  */
143
156
  export declare function startGlspServer(options: GlspServerOptions): StartedGlspServer;
144
157
  //# sourceMappingURL=start-glsp-server.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"start-glsp-server.d.ts","sourceRoot":"","sources":["../../src/node/start-glsp-server.ts"],"names":[],"mappings":"AAAA;;;;;;;kFAOkF;AAElF,OAAO,EACJ,KAAK,MAAM,IAAI,UAAU,EACzB,KAAK,YAAY,EAEjB,oBAAoB,EAGtB,MAAM,8BAA8B,CAAC;AACtC,OAAO,EAAa,eAAe,EAAc,MAAM,WAAW,CAAC;AACnE,OAAO,EAAsD,KAAK,MAAM,EAAE,MAAM,qBAAqB,CAAC;AACtG,OAAO,KAAK,KAAK,GAAG,MAAM,UAAU,CAAC;AAErC,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAKxD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAE9D;;;;;GAKG;AACH,qBACa,iCAAkC,SAAQ,oBAAoB;IACxE,UAAmB,gBAAgB,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,GAAG,UAAU,CAAC,oBAAoB,CAAC,kBAAkB,CAAC,CAAC,CAW5G;CACH;AAED;;;;;;;;;GASG;AACH,wBAAgB,8BAA8B,IAAI,eAAe,CAIhE;AAED;;;;GAIG;AACH,MAAM,WAAW,iBAAiB;IAC/B;;;;OAIG;IACH,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB;;;;;OAKG;IACH,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB;;;;;;;;;;;;OAYG;IACH,QAAQ,CAAC,YAAY,EAAE,CAAC,MAAM,CAAC,EAAE,MAAM,KAAK,UAAU,CAAC;IACvD;;;OAGG;IACH,QAAQ,CAAC,YAAY,EAAE,YAAY,CAAC;IACpC;;;;;;;;OAQG;IACH,QAAQ,CAAC,UAAU,CAAC,EAAE,aAAa,CAAC,eAAe,CAAC,CAAC;IACrD;;;;;;OAMG;IACH,QAAQ,CAAC,aAAa,CAAC,EAAE,iBAAiB,CAAC;IAC3C;;;OAGG;IACH,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B;;;;OAIG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB;;;;;;;;OAQG;IACH,QAAQ,CAAC,kBAAkB,CAAC,EAAE,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,KAAK,IAAI,CAAC;CAC7D;AAED;;;;;;;;;;GAUG;AACH,MAAM,WAAW,iBAAkB,SAAQ,gBAAgB;IACxD,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,CAAC;CACpC;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,iBAAiB,GAAG,iBAAiB,CAmF7E"}
1
+ {"version":3,"file":"start-glsp-server.d.ts","sourceRoot":"","sources":["../../src/node/start-glsp-server.ts"],"names":[],"mappings":"AAAA;;;;;;;kFAOkF;AAElF,OAAO,EACJ,KAAK,MAAM,IAAI,UAAU,EACzB,KAAK,YAAY,EAEjB,oBAAoB,EAGtB,MAAM,8BAA8B,CAAC;AACtC,OAAO,EAAa,eAAe,EAAc,MAAM,WAAW,CAAC;AACnE,OAAO,EAAqE,KAAK,MAAM,EAAE,MAAM,qBAAqB,CAAC;AACrH,OAAO,KAAK,KAAK,GAAG,MAAM,UAAU,CAAC;AAErC,OAAO,EAEJ,KAAK,gBAAgB,EAErB,KAAK,oBAAoB,EAC3B,MAAM,iBAAiB,CAAC;AAMzB,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAE9D;;;;;GAKG;AACH,qBACa,iCAAkC,SAAQ,oBAAoB;IACxE,UAAmB,gBAAgB,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,GAAG,UAAU,CAAC,oBAAoB,CAAC,kBAAkB,CAAC,CAAC,CAW5G;CACH;AAED;;;;;;;;;GASG;AACH,wBAAgB,8BAA8B,IAAI,eAAe,CAIhE;AAED;;;;GAIG;AACH,MAAM,WAAW,iBAAiB;IAC/B;;;;OAIG;IACH,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB;;;;;OAKG;IACH,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB;;;;;;;;;;;;OAYG;IACH,QAAQ,CAAC,YAAY,EAAE,CAAC,MAAM,CAAC,EAAE,MAAM,KAAK,UAAU,CAAC;IACvD;;;OAGG;IACH,QAAQ,CAAC,YAAY,EAAE,YAAY,CAAC;IACpC;;;;;;;;OAQG;IACH,QAAQ,CAAC,UAAU,CAAC,EAAE,aAAa,CAAC,eAAe,CAAC,CAAC;IACrD;;;;;OAKG;IACH,QAAQ,CAAC,SAAS,CAAC,EAAE,oBAAoB,GAAG,aAAa,CAAC,oBAAoB,CAAC,CAAC;IAChF;;;;;;OAMG;IACH,QAAQ,CAAC,aAAa,CAAC,EAAE,iBAAiB,CAAC;IAC3C;;;OAGG;IACH,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B;;;;OAIG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB;;;;;;;;OAQG;IACH,QAAQ,CAAC,kBAAkB,CAAC,EAAE,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,KAAK,IAAI,CAAC;CAC7D;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,WAAW,iBAAkB,SAAQ,gBAAgB;IACxD,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,CAAC;CACpC;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,iBAAiB,GAAG,iBAAiB,CA+G7E"}
@@ -14,12 +14,14 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
14
14
  };
15
15
  import { SocketServerLauncher, createAppModule, defaultSocketLaunchOptions } from '@eclipse-glsp/server/node.js';
16
16
  import { Container, ContainerModule, injectable } from 'inversify';
17
- import { Deferred, describeErrorWithStack, sendByMethodName } from '@hydranium/protocol';
17
+ import { Deferred, describeError, describeErrorWithStack, sendByMethodName } from '@hydranium/protocol';
18
18
  import { createMessageConnection, SocketMessageReader, SocketMessageWriter } from 'vscode-jsonrpc/node';
19
+ import { initializeWorkspaceWithoutLsp } from '@hydranium/core';
19
20
  import { dropNotificationsToGoneClient } from '../launcher/drop-notifications-to-gone-client.js';
20
21
  import { createGlspConnectionLogger } from '../launcher/glsp-connection-logger.js';
21
22
  import { createGlspFrameworkOverrides } from '../launcher/glsp-framework-overrides.js';
22
23
  import { createGlspServerOverrides } from '../launcher/glsp-server-overrides.js';
24
+ import { HydraniumTypes } from '../state/hydranium-shared-core-services.js';
23
25
  /**
24
26
  * The default socket launcher of {@link startGlspServer}: GLSP's own,
25
27
  * with each connection built from this package's copy of `vscode-jsonrpc`, so a
@@ -65,6 +67,10 @@ export function createGlspSocketLauncherModule() {
65
67
  * (data-server's pattern), not GLSP's Inversify-driven per-connection
66
68
  * server-instance model. Bridging the two would lose GLSP's action-handler
67
69
  * registry plumbing.
70
+ *
71
+ * **Without an LSP head the launcher brings the workspace up, then
72
+ * listens**, as `startSocketServer` does: a diagram loaded before the
73
+ * bring-up starts keeps its cross-file edges missing for good.
68
74
  */
69
75
  export function startGlspServer(options) {
70
76
  const launchOptions = {
@@ -89,9 +95,12 @@ export function startGlspServer(options) {
89
95
  // the tier where each connection gets a server of its own.
90
96
  launcher.configure(options.serverModule, createGlspServerOverrides());
91
97
  const started = new Deferred();
98
+ const stopped = new Deferred();
92
99
  const portHandle = { port: undefined };
93
- try {
94
- const stoppedPromise = Promise.resolve(launcher.start(launchOptions));
100
+ const listen = () => {
101
+ // `start` creates the `net.Server` and listens, so the listeners below
102
+ // attach to it synchronously after the call, before any event fires.
103
+ Promise.resolve(launcher.start(launchOptions)).then(() => stopped.resolve(), (error) => stopped.reject(error));
95
104
  // GLSP's `SocketServerLauncher.netServer` field is `protected`; we
96
105
  // access it via property indexing. The alternative is to fork the
97
106
  // launcher or add a 'listening' callback to GLSP upstream.
@@ -120,23 +129,42 @@ export function startGlspServer(options) {
120
129
  if (options.onClientConnection) {
121
130
  netServer.on('connection', options.onClientConnection);
122
131
  }
123
- return {
124
- get port() {
125
- return portHandle.port;
126
- },
127
- started: started.promise,
128
- stopped: stoppedPromise
129
- };
130
- }
131
- catch (error) {
132
- lifecycle?.error('Error in GLSP server launcher:', error);
133
- return {
134
- get port() {
135
- return portHandle.port;
136
- },
137
- started: Promise.reject(error),
138
- stopped: Promise.resolve()
139
- };
140
- }
132
+ };
133
+ // The workspace manager logs a failed initialization itself; a refused
134
+ // `workspace` throws before `initializing` is set.
135
+ let initializing = false;
136
+ const begin = async () => {
137
+ const shared = appContainer.isBound(HydraniumTypes.SharedCoreServices)
138
+ ? appContainer.get(HydraniumTypes.SharedCoreServices)
139
+ : undefined;
140
+ if (shared === undefined) {
141
+ throw new Error('[hydranium] startGlspServer found no shared services in its app container. Add `new HydraniumGlspAppModule({ shared })` to `appModules`.');
142
+ }
143
+ const initialization = initializeWorkspaceWithoutLsp(shared, options.workspace);
144
+ initializing = true;
145
+ await initialization;
146
+ initializing = false;
147
+ listen();
148
+ };
149
+ begin().catch((error) => {
150
+ if (initializing) {
151
+ lifecycle?.debug(`[GlspServer] Startup failed: the workspace did not initialize. ${describeError(error)}`);
152
+ }
153
+ else {
154
+ lifecycle?.error(`[GlspServer] Startup failed: ${describeErrorWithStack(error)}`);
155
+ }
156
+ started.reject(error);
157
+ stopped.resolve();
158
+ });
159
+ // `started` is always observed internally, as `startStdioServer`'s is, so a
160
+ // caller that closes early and ignores it cannot crash the process.
161
+ void started.promise.catch(() => undefined);
162
+ return {
163
+ get port() {
164
+ return portHandle.port;
165
+ },
166
+ started: started.promise,
167
+ stopped: stopped.promise
168
+ };
141
169
  }
142
170
  //# sourceMappingURL=start-glsp-server.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"start-glsp-server.js","sourceRoot":"","sources":["../../src/node/start-glsp-server.ts"],"names":[],"mappings":"AAAA;;;;;;;kFAOkF;;;;;;;AAElF,OAAO,EAIJ,oBAAoB,EACpB,eAAe,EACf,0BAA0B,EAC5B,MAAM,8BAA8B,CAAC;AACtC,OAAO,EAAE,SAAS,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AACnE,OAAO,EAAE,QAAQ,EAAE,sBAAsB,EAAE,gBAAgB,EAAe,MAAM,qBAAqB,CAAC;AAEtG,OAAO,EAAE,uBAAuB,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAExG,OAAO,EAAE,6BAA6B,EAAE,MAAM,kDAAkD,CAAC;AACjG,OAAO,EAAE,0BAA0B,EAAE,MAAM,uCAAuC,CAAC;AACnF,OAAO,EAAE,4BAA4B,EAAE,MAAM,yCAAyC,CAAC;AACvF,OAAO,EAAE,yBAAyB,EAAE,MAAM,sCAAsC,CAAC;AAGjF;;;;;GAKG;AAEI,IAAM,iCAAiC,GAAvC,MAAM,iCAAkC,SAAQ,oBAAoB;IACrD,gBAAgB,CAAC,MAAkB;QACnD,OAAO,6BAA6B,CACjC,gBAAgB,CACb,uBAAuB,CACpB,IAAI,mBAAmB,CAAC,MAAM,CAAC,EAC/B,IAAI,mBAAmB,CAAC,MAAM,CAAC,EAC/B,0BAA0B,CAAC,IAAI,CAAC,MAAM,CAAC,CACzC,CACH,EACD,IAAI,CAAC,MAAM,CACb,CAAC;IACL,CAAC;CACH,CAAA;AAbY,iCAAiC;IAD7C,UAAU,EAAE;GACA,iCAAiC,CAa7C;;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,8BAA8B;IAC3C,OAAO,IAAI,eAAe,CAAC,IAAI,CAAC,EAAE;QAC/B,IAAI,CAAC,oBAAoB,CAAC,CAAC,EAAE,CAAC,iCAAiC,CAAC,CAAC;IACpE,CAAC,CAAC,CAAC;AACN,CAAC;AAgGD;;;;;;;;;;;;;;;GAeG;AACH,MAAM,UAAU,eAAe,CAAC,OAA0B;IACvD,MAAM,aAAa,GAAwB;QACxC,GAAG,0BAA0B;QAC7B,IAAI,EAAE,OAAO,CAAC,IAAI,IAAI,WAAW;QACjC,IAAI,EAAE,OAAO,CAAC,IAAI,IAAI,CAAC;KACzB,CAAC;IACF,MAAM,SAAS,GAAG,OAAO,CAAC,MAAM,CAAC;IAEjC,2EAA2E;IAC3E,4EAA4E;IAC5E,+EAA+E;IAC/E,iFAAiF;IACjF,8EAA8E;IAC9E,6EAA6E;IAC7E,2EAA2E;IAC3E,MAAM,aAAa,GAAG,eAAe,CAAC,EAAE,GAAG,aAAa,EAAE,UAAU,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC;IAE/F,MAAM,YAAY,GAAG,IAAI,SAAS,EAAE,CAAC;IACrC,YAAY,CAAC,IAAI,CACd,aAAa,EACb,4BAA4B,CAAC,OAAO,CAAC,YAAY,CAAC,EAClD,8BAA8B,EAAE,EAChC,GAAG,CAAC,OAAO,CAAC,UAAU,IAAI,EAAE,CAAC,CAC/B,CAAC;IAEF,MAAM,QAAQ,GAAG,YAAY,CAAC,GAAG,CAAuB,oBAAoB,CAAC,CAAC;IAC9E,4EAA4E;IAC5E,8EAA8E;IAC9E,2DAA2D;IAC3D,QAAQ,CAAC,SAAS,CAAC,OAAO,CAAC,YAAY,EAAE,yBAAyB,EAAE,CAAC,CAAC;IAEtE,MAAM,OAAO,GAAG,IAAI,QAAQ,EAAQ,CAAC;IACrC,MAAM,UAAU,GAAiC,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;IAErE,IAAI,CAAC;QACF,MAAM,cAAc,GAAG,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC,CAAC;QAEtE,mEAAmE;QACnE,kEAAkE;QAClE,2DAA2D;QAC3D,MAAM,SAAS,GAAI,QAAiD,CAAC,SAAS,CAAC;QAE/E,SAAS,CAAC,EAAE,CAAC,WAAW,EAAE,GAAG,EAAE;YAC5B,MAAM,OAAO,GAAG,SAAS,CAAC,OAAO,EAAE,CAAC;YACpC,IAAI,OAAO,IAAI,OAAO,OAAO,KAAK,QAAQ,EAAE,CAAC;gBAC1C,UAAU,CAAC,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;gBAC/B,IAAI,OAAO,CAAC,aAAa,IAAI,OAAO,CAAC,WAAW,EAAE,CAAC;oBAChD,OAAO,CAAC,aAAa,CAAC,SAAS,CAAC,OAAO,CAAC,WAAW,EAAE,GAAG,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;gBAC/E,CAAC;gBACD,SAAS,EAAE,IAAI,CAAC,uDAAuD,OAAO,CAAC,OAAO,UAAU,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;gBAChH,OAAO,CAAC,OAAO,EAAE,CAAC;YACrB,CAAC;iBAAM,CAAC;gBACL,MAAM,OAAO,GAAG,OAAO,KAAK,IAAI,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC,CAAC,qBAAqB,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC;gBAC/F,SAAS,EAAE,KAAK,CAAC,iDAAiD,OAAO,kBAAkB,CAAC,CAAC;gBAC7F,OAAO,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,oDAAoD,OAAO,EAAE,CAAC,CAAC,CAAC;gBACzF,SAAS,CAAC,KAAK,EAAE,CAAC;YACrB,CAAC;QACJ,CAAC,CAAC,CAAC;QACH,SAAS,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,GAAU,EAAE,EAAE;YAClC,SAAS,EAAE,KAAK,CAAC,uBAAuB,sBAAsB,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YACvE,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QACvB,CAAC,CAAC,CAAC;QACH,IAAI,OAAO,CAAC,kBAAkB,EAAE,CAAC;YAC9B,SAAS,CAAC,EAAE,CAAC,YAAY,EAAE,OAAO,CAAC,kBAAkB,CAAC,CAAC;QAC1D,CAAC;QAED,OAAO;YACJ,IAAI,IAAI;gBACL,OAAO,UAAU,CAAC,IAAI,CAAC;YAC1B,CAAC;YACD,OAAO,EAAE,OAAO,CAAC,OAAO;YACxB,OAAO,EAAE,cAAc;SACzB,CAAC;IACL,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACd,SAAS,EAAE,KAAK,CAAC,gCAAgC,EAAE,KAAK,CAAC,CAAC;QAC1D,OAAO;YACJ,IAAI,IAAI;gBACL,OAAO,UAAU,CAAC,IAAI,CAAC;YAC1B,CAAC;YACD,OAAO,EAAE,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC;YAC9B,OAAO,EAAE,OAAO,CAAC,OAAO,EAAE;SAC5B,CAAC;IACL,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"start-glsp-server.js","sourceRoot":"","sources":["../../src/node/start-glsp-server.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hydranium/glsp-server",
3
- "version": "1.0.0-next.309",
3
+ "version": "1.0.0-next.313",
4
4
  "description": "GLSP protocol head for the hydranium framework. Peer of @hydranium/core/lsp and @hydranium/data-server; built on @hydranium/core.",
5
5
  "keywords": [
6
6
  "diagram",
@@ -70,9 +70,9 @@
70
70
  },
71
71
  "devDependencies": {
72
72
  "@eclipse-glsp/server": "2.7.0",
73
- "@hydranium/core": "1.0.0-next.309",
74
- "@hydranium/langium": "1.0.0-next.309",
75
- "@hydranium/protocol": "1.0.0-next.309",
73
+ "@hydranium/core": "1.0.0-next.313",
74
+ "@hydranium/langium": "1.0.0-next.313",
75
+ "@hydranium/protocol": "1.0.0-next.313",
76
76
  "inversify": "6.2.2",
77
77
  "reflect-metadata": "0.2.2",
78
78
  "rimraf": "^5.0.0",
@@ -82,9 +82,9 @@
82
82
  },
83
83
  "peerDependencies": {
84
84
  "@eclipse-glsp/server": "^2.6.0",
85
- "@hydranium/core": "1.0.0-next.309",
86
- "@hydranium/langium": "1.0.0-next.309",
87
- "@hydranium/protocol": "1.0.0-next.309",
85
+ "@hydranium/core": "1.0.0-next.313",
86
+ "@hydranium/langium": "1.0.0-next.313",
87
+ "@hydranium/protocol": "1.0.0-next.313",
88
88
  "inversify": "^6.0.0",
89
89
  "reflect-metadata": "^0.2.2",
90
90
  "vscode-jsonrpc": "^9.0.0",
@@ -16,14 +16,20 @@ import {
16
16
  defaultSocketLaunchOptions
17
17
  } from '@eclipse-glsp/server/node.js';
18
18
  import { Container, ContainerModule, injectable } from 'inversify';
19
- import { Deferred, describeErrorWithStack, sendByMethodName, type Logger } from '@hydranium/protocol';
19
+ import { Deferred, describeError, describeErrorWithStack, sendByMethodName, type Logger } from '@hydranium/protocol';
20
20
  import type * as net from 'node:net';
21
21
  import { createMessageConnection, SocketMessageReader, SocketMessageWriter } from 'vscode-jsonrpc/node';
22
- import type { IntegratedServer } from '@hydranium/core';
22
+ import {
23
+ initializeWorkspaceWithoutLsp,
24
+ type IntegratedServer,
25
+ type ServerSharedServicesMinimal,
26
+ type WorkspaceFolderInput
27
+ } from '@hydranium/core';
23
28
  import { dropNotificationsToGoneClient } from '../launcher/drop-notifications-to-gone-client.js';
24
29
  import { createGlspConnectionLogger } from '../launcher/glsp-connection-logger.js';
25
30
  import { createGlspFrameworkOverrides } from '../launcher/glsp-framework-overrides.js';
26
31
  import { createGlspServerOverrides } from '../launcher/glsp-server-overrides.js';
32
+ import { HydraniumTypes } from '../state/hydranium-shared-core-services.js';
27
33
  import type { LspConnectionLike } from '@hydranium/core/node';
28
34
 
29
35
  /**
@@ -112,6 +118,13 @@ export interface GlspServerOptions {
112
118
  * symbol) here, and replace the launcher with `rebind`.
113
119
  */
114
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>;
115
128
  /**
116
129
  * Optional LSP connection used to register a port-discovery request
117
130
  * handler. When both `lspConnection` and `portCommand` are set, the
@@ -146,12 +159,14 @@ export interface GlspServerOptions {
146
159
  /**
147
160
  * Live GLSP server handle returned by {@link startGlspServer}.
148
161
  *
149
- * - {@link IntegratedServer.started} resolves once the GLSP socket is
150
- * listening AND (if configured) the port-discovery handler has been
151
- * registered on the LSP connection.
152
- * - {@link IntegratedServer.stopped} resolves once GLSP's
153
- * `SocketServerLauncher.start` promise settles (i.e. the underlying
154
- * `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`.
155
170
  * - {@link port} is `undefined` until `started` resolves.
156
171
  */
157
172
  export interface StartedGlspServer extends IntegratedServer {
@@ -173,6 +188,10 @@ export interface StartedGlspServer extends IntegratedServer {
173
188
  * (data-server's pattern), not GLSP's Inversify-driven per-connection
174
189
  * server-instance model. Bridging the two would lose GLSP's action-handler
175
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.
176
195
  */
177
196
  export function startGlspServer(options: GlspServerOptions): StartedGlspServer {
178
197
  const launchOptions: SocketLaunchOptions = {
@@ -206,10 +225,16 @@ export function startGlspServer(options: GlspServerOptions): StartedGlspServer {
206
225
  launcher.configure(options.serverModule, createGlspServerOverrides());
207
226
 
208
227
  const started = new Deferred<void>();
228
+ const stopped = new Deferred<void>();
209
229
  const portHandle: { port: number | undefined } = { port: undefined };
210
230
 
211
- try {
212
- 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
+ );
213
238
 
214
239
  // GLSP's `SocketServerLauncher.netServer` field is `protected`; we
215
240
  // access it via property indexing. The alternative is to fork the
@@ -239,22 +264,44 @@ export function startGlspServer(options: GlspServerOptions): StartedGlspServer {
239
264
  if (options.onClientConnection) {
240
265
  netServer.on('connection', options.onClientConnection);
241
266
  }
267
+ };
242
268
 
243
- return {
244
- get port() {
245
- return portHandle.port;
246
- },
247
- started: started.promise,
248
- stopped: stoppedPromise
249
- };
250
- } catch (error) {
251
- lifecycle?.error('Error in GLSP server launcher:', error);
252
- return {
253
- get port() {
254
- return portHandle.port;
255
- },
256
- started: Promise.reject(error),
257
- stopped: Promise.resolve()
258
- };
259
- }
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
+ };
260
307
  }