@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
|
|
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
|
|
117
|
-
*
|
|
118
|
-
* registered on the
|
|
119
|
-
*
|
|
120
|
-
*
|
|
121
|
-
* `
|
|
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,
|
|
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
|
-
|
|
94
|
-
|
|
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
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
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;
|
|
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.
|
|
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.
|
|
74
|
-
"@hydranium/langium": "1.0.0-next.
|
|
75
|
-
"@hydranium/protocol": "1.0.0-next.
|
|
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.
|
|
86
|
-
"@hydranium/langium": "1.0.0-next.
|
|
87
|
-
"@hydranium/protocol": "1.0.0-next.
|
|
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
|
|
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
|
|
150
|
-
*
|
|
151
|
-
* registered on the
|
|
152
|
-
*
|
|
153
|
-
*
|
|
154
|
-
* `
|
|
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
|
-
|
|
212
|
-
|
|
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
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
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
|
}
|