@lspeasy/server 4.0.1 → 4.0.3

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/dist/index.js CHANGED
@@ -1,5 +1,56 @@
1
1
  /**
2
- * @lspeasy/server - Build LSP servers with simple, typed API
2
+ * LSP server package for hosting Language Server Protocol (LSP) servers.
3
+ *
4
+ * @remarks
5
+ * Use `@lspeasy/server` when you need to build the **provider** side of the
6
+ * Language Server Protocol — a daemon that editors and language-client tooling
7
+ * connect to in order to get diagnostics, completions, hover, go-to-definition,
8
+ * and other language intelligence features.
9
+ *
10
+ * The primary entry point is {@link LSPServer}. Construct it with
11
+ * {@link ServerOptions}, call `registerCapabilities(caps)` to declare what
12
+ * the server supports, register handlers with `onRequest` / `onNotification`,
13
+ * then call `listen(transport)` to accept the first client connection.
14
+ *
15
+ * ### Transport Decision Tree
16
+ *
17
+ * **Stdio** (`StdioTransport` from `@lspeasy/core/node`)
18
+ * — Use when: the client spawns your server as a child process (the canonical
19
+ * VS Code extension pattern). No network, no port management. Failure mode:
20
+ * `ConsoleLogger` writes to stdout and corrupts the LSP stream — always use
21
+ * `NullLogger` or a file-based logger with stdio.
22
+ *
23
+ * **WebSocket** (`WebSocketTransport` from `@lspeasy/core`)
24
+ * — Use when: multiple clients connect over a network, or the server must be
25
+ * browser-accessible. Each accepted WebSocket connection needs its own
26
+ * `LSPServer` instance. Failure mode: one client crash should not affect
27
+ * others — wrap each `wss.on('connection')` callback in try/catch and
28
+ * create a fresh `LSPServer` per socket.
29
+ *
30
+ * **TCP** (`TcpTransport` from `@lspeasy/core/node`)
31
+ * — Use when: building a persistent local daemon (e.g. a formatting server
32
+ * shared across editor sessions). Failure mode: client disconnect fires
33
+ * `close()` on the server instance — use `mode: 'server'` and create a new
34
+ * `LSPServer` on each reconnect.
35
+ *
36
+ * **DedicatedWorkerTransport** (`DedicatedWorkerTransport` from `@lspeasy/core`)
37
+ * — Use when: running the server logic in a Web Worker for in-process browser
38
+ * isolation. Zero serialization overhead. Failure mode: worker crash is
39
+ * silent from the server side — monitor the worker's `onerror` in the host.
40
+ *
41
+ * ### Typed capability namespaces
42
+ * After `registerCapabilities({ hoverProvider: true })`, TypeScript exposes
43
+ * `server.textDocument.onHover(handler)` — methods that are absent unless the
44
+ * corresponding capability is declared. This prevents accidentally registering
45
+ * handlers for capabilities the server never advertised.
46
+ *
47
+ * ### Handler conventions
48
+ * - {@link RequestHandler} — async, throws {@link ResponseError} for
49
+ * structured errors, checks `token.isCancellationRequested` for early exit.
50
+ * - {@link NotificationHandler} — fire-and-forget; unhandled rejections
51
+ * surface via `server.onError()`.
52
+ *
53
+ * @packageDocumentation
3
54
  */
4
55
  // Main server class
5
56
  export { LSPServer } from './server.js';
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,oBAAoB;AACpB,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAaxC,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAEzC,+BAA+B;AAC/B,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,EAAE,mBAAmB,EAAE,MAAM,qCAAqC,CAAC;AA0B1E,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAEzF,uGAAuG;AACvG,gDAAgD"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqDG;AAEH,oBAAoB;AACpB,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAaxC,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAEzC,+BAA+B;AAC/B,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,EAAE,mBAAmB,EAAE,MAAM,qCAAqC,CAAC;AA0B1E,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAEzF,uGAAuG;AACvG,gDAAgD"}
@@ -1 +1 @@
1
- {"version":3,"file":"lifecycle.js","sourceRoot":"","sources":["../src/lifecycle.ts"],"names":[],"mappings":"AAAA;;GAEG;AAWH;;GAEG;AACH,MAAM,OAAO,gBAAgB;IAIR,IAAI;IACJ,OAAO;IACP,MAAM;IALjB,kBAAkB,GAAuB,EAAE,CAAC;IAEpD,YACmB,IAAY,EACZ,OAAe,EACf,MAAc,EAC/B;oBAHiB,IAAI;uBACJ,OAAO;sBACP,MAAM;IACtB,CAAC;IAEJ;;OAEG;IACH,oBAAoB,CAAC,YAAgC,EAAQ;QAC3D,IAAI,CAAC,kBAAkB,GAAG,YAAY,CAAC;IAAA,CACxC;IAED;;OAEG;IACH,eAAe,GAAuB;QACpC,OAAO,IAAI,CAAC,kBAAkB,CAAC;IAAA,CAChC;IAED;;OAEG;IACH,KAAK,CAAC,gBAAgB,CACpB,MAAwB,EACxB,UAAqB,EACrB,GAAoB,EACO;QAC3B,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,wBAAwB,CAAC,CAAC;QAC3C,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,oBAAoB,EAAE,MAAM,CAAC,CAAC;QAEhD,MAAM,MAAM,GAAqB;YAC/B,YAAY,EAAE,IAAI,CAAC,kBAAkB;YACrC,UAAU,EAAE;gBACV,IAAI,EAAE,IAAI,CAAC,IAAI;gBACf,OAAO,EAAE,IAAI,CAAC,OAAO;aACtB;SACF,CAAC;QAEF,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC;QACvC,OAAO,MAAM,CAAC;IAAA,CACf;IAED;;OAEG;IACH,iBAAiB,CAAC,MAAyB,EAAQ;QACjD,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,sCAAsC,CAAC,CAAC;QACzD,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,qBAAqB,EAAE,MAAM,CAAC,CAAC;IAAA,CAClD;IAED;;OAEG;IACH,KAAK,CAAC,cAAc,CAAC,UAAqB,EAAE,GAAoB,EAAiB;QAC/E,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,yBAAyB,CAAC,CAAC;QAC5C,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,0BAA0B,CAAC,CAAC;IAAA,CAC9C;IAED;;OAEG;IACH,UAAU,GAAS;QACjB,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;IAAA,CACjC;CACF"}
1
+ {"version":3,"file":"lifecycle.js","sourceRoot":"","sources":["../src/lifecycle.ts"],"names":[],"mappings":"AAAA;;GAEG;AAWH;;GAEG;AACH,MAAM,OAAO,gBAAgB;IAIR,IAAI;IACJ,OAAO;IACP,MAAM;IALjB,kBAAkB,GAAuB,EAAE,CAAC;IAEpD,YACmB,IAAY,EACZ,OAAe,EACf,MAAc;oBAFd,IAAI;uBACJ,OAAO;sBACP,MAAM;IACtB,CAAC;IAEJ;;OAEG;IACH,oBAAoB,CAAC,YAAgC;QACnD,IAAI,CAAC,kBAAkB,GAAG,YAAY,CAAC;IACzC,CAAC;IAED;;OAEG;IACH,eAAe;QACb,OAAO,IAAI,CAAC,kBAAkB,CAAC;IACjC,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,gBAAgB,CACpB,MAAwB,EACxB,UAAqB,EACrB,GAAoB;QAEpB,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,wBAAwB,CAAC,CAAC;QAC3C,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,oBAAoB,EAAE,MAAM,CAAC,CAAC;QAEhD,MAAM,MAAM,GAAqB;YAC/B,YAAY,EAAE,IAAI,CAAC,kBAAkB;YACrC,UAAU,EAAE;gBACV,IAAI,EAAE,IAAI,CAAC,IAAI;gBACf,OAAO,EAAE,IAAI,CAAC,OAAO;aACtB;SACF,CAAC;QAEF,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC;QACvC,OAAO,MAAM,CAAC;IAChB,CAAC;IAED;;OAEG;IACH,iBAAiB,CAAC,MAAyB;QACzC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,sCAAsC,CAAC,CAAC;QACzD,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,qBAAqB,EAAE,MAAM,CAAC,CAAC;IACnD,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,cAAc,CAAC,UAAqB,EAAE,GAAoB;QAC9D,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,yBAAyB,CAAC,CAAC;QAC5C,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,0BAA0B,CAAC,CAAC;IAC/C,CAAC;IAED;;OAEG;IACH,UAAU;QACR,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;IAClC,CAAC;CACF"}
@@ -1,9 +1,38 @@
1
1
  import type { ProgressToken } from '@lspeasy/core';
2
2
  import type { BaseLSPServer } from '../server.js';
3
- /** Helper for emitting typed `$/progress` partial result batches from server handlers. */
3
+ /**
4
+ * Emits typed `$/progress` partial-result batches from server-side request handlers.
5
+ *
6
+ * @remarks
7
+ * Use `PartialResultSender` inside a `RequestHandler` when the client has
8
+ * supplied a `partialResultToken` (e.g. for `textDocument/references` or
9
+ * `workspace/symbol`). Call `send(token, value)` to stream result batches
10
+ * before returning the final response.
11
+ *
12
+ * @useWhen
13
+ * The client sets `partialResultToken` in the request params and you want to
14
+ * stream intermediate results (e.g. symbols found so far) rather than waiting
15
+ * for the complete set.
16
+ *
17
+ * @never
18
+ * NEVER call `send` after the handler has already returned a response — the
19
+ * `$/progress` notification will arrive after the client has closed the
20
+ * partial-result channel, and the client will silently discard or error on it.
21
+ *
22
+ * NEVER send partial results without a `partialResultToken` — the client has
23
+ * no way to correlate the `$/progress` notification to the pending request.
24
+ *
25
+ * @category Server
26
+ */
4
27
  export declare class PartialResultSender {
5
28
  private readonly server;
6
29
  constructor(server: BaseLSPServer);
30
+ /**
31
+ * Send a batch of partial results to the client.
32
+ *
33
+ * @param token - The `partialResultToken` from the originating request params.
34
+ * @param value - The partial result batch to stream to the client via `$/progress`.
35
+ */
7
36
  send<T>(token: ProgressToken, value: T): Promise<void>;
8
37
  }
9
38
  //# sourceMappingURL=partial-result-sender.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"partial-result-sender.d.ts","sourceRoot":"","sources":["../../src/progress/partial-result-sender.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAyB,aAAa,EAAE,MAAM,eAAe,CAAC;AAC1E,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAElD,0FAA0F;AAC1F,qBAAa,mBAAmB;IAClB,OAAO,CAAC,QAAQ,CAAC,MAAM;IAAnC,YAA6B,MAAM,EAAE,aAAa,EAAI;IAEhD,IAAI,CAAC,CAAC,EAAE,KAAK,EAAE,aAAa,EAAE,KAAK,EAAE,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAS3D;CACF"}
1
+ {"version":3,"file":"partial-result-sender.d.ts","sourceRoot":"","sources":["../../src/progress/partial-result-sender.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAyB,aAAa,EAAE,MAAM,eAAe,CAAC;AAC1E,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAElD;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,qBAAa,mBAAmB;IAClB,OAAO,CAAC,QAAQ,CAAC,MAAM;IAAnC,YAA6B,MAAM,EAAE,aAAa,EAAI;IAEtD;;;;;OAKG;IACG,IAAI,CAAC,CAAC,EAAE,KAAK,EAAE,aAAa,EAAE,KAAK,EAAE,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAS3D;CACF"}
@@ -1,9 +1,38 @@
1
- /** Helper for emitting typed `$/progress` partial result batches from server handlers. */
1
+ /**
2
+ * Emits typed `$/progress` partial-result batches from server-side request handlers.
3
+ *
4
+ * @remarks
5
+ * Use `PartialResultSender` inside a `RequestHandler` when the client has
6
+ * supplied a `partialResultToken` (e.g. for `textDocument/references` or
7
+ * `workspace/symbol`). Call `send(token, value)` to stream result batches
8
+ * before returning the final response.
9
+ *
10
+ * @useWhen
11
+ * The client sets `partialResultToken` in the request params and you want to
12
+ * stream intermediate results (e.g. symbols found so far) rather than waiting
13
+ * for the complete set.
14
+ *
15
+ * @never
16
+ * NEVER call `send` after the handler has already returned a response — the
17
+ * `$/progress` notification will arrive after the client has closed the
18
+ * partial-result channel, and the client will silently discard or error on it.
19
+ *
20
+ * NEVER send partial results without a `partialResultToken` — the client has
21
+ * no way to correlate the `$/progress` notification to the pending request.
22
+ *
23
+ * @category Server
24
+ */
2
25
  export class PartialResultSender {
3
26
  server;
4
27
  constructor(server) {
5
28
  this.server = server;
6
29
  }
30
+ /**
31
+ * Send a batch of partial results to the client.
32
+ *
33
+ * @param token - The `partialResultToken` from the originating request params.
34
+ * @param value - The partial result batch to stream to the client via `$/progress`.
35
+ */
7
36
  async send(token, value) {
8
37
  const payload = {
9
38
  token,
@@ -1 +1 @@
1
- {"version":3,"file":"partial-result-sender.js","sourceRoot":"","sources":["../../src/progress/partial-result-sender.ts"],"names":[],"mappings":"AAGA,0FAA0F;AAC1F,MAAM,OAAO,mBAAmB;IACD,MAAM;IAAnC,YAA6B,MAAqB,EAAE;sBAAvB,MAAM;IAAkB,CAAC;IAEtD,KAAK,CAAC,IAAI,CAAI,KAAoB,EAAE,KAAQ,EAAiB;QAC3D,MAAM,OAAO,GAAG;YACd,KAAK;YACL,KAAK;SAC4C,CAAC;QAEpD,MAAM,IAAI,CAAC,MAAM,CAAC,gBAAgB,CAAC,YAAY,EAAE;YAC/C,GAAG,OAAO;SACX,CAAC,CAAC;IAAA,CACJ;CACF"}
1
+ {"version":3,"file":"partial-result-sender.js","sourceRoot":"","sources":["../../src/progress/partial-result-sender.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,MAAM,OAAO,mBAAmB;IACD,MAAM;IAAnC,YAA6B,MAAqB;sBAArB,MAAM;IAAkB,CAAC;IAEtD;;;;;OAKG;IACH,KAAK,CAAC,IAAI,CAAI,KAAoB,EAAE,KAAQ;QAC1C,MAAM,OAAO,GAAG;YACd,KAAK;YACL,KAAK;SAC4C,CAAC;QAEpD,MAAM,IAAI,CAAC,MAAM,CAAC,gBAAgB,CAAC,YAAY,EAAE;YAC/C,GAAG,OAAO;SACX,CAAC,CAAC;IACL,CAAC;CACF"}
@@ -1 +1 @@
1
- {"version":3,"file":"progress.js","sourceRoot":"","sources":["../src/progress.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EACL,mBAAmB,EACnB,oBAAoB,EACpB,iBAAiB,EACjB,mBAAmB,EACpB,MAAM,eAAe,CAAC;AA6BvB;;GAEG;AACH,MAAM,oBAAoB;IAEd,KAAK;IACL,MAAM;IAFhB,YACU,KAAoB,EACpB,MAAsB,EAC9B;qBAFQ,KAAK;sBACL,MAAM;IACb,CAAC;IAEJ,KAAK,CAAC,KAAK,CACT,KAAa,EACb,WAAqB,EACrB,OAAgB,EAChB,UAAmB,EACJ;QACf,MAAM,KAAK,GAAG,mBAAmB,CAAC,KAAK,EAAE,WAAW,EAAE,OAAO,EAAE,UAAU,CAAC,CAAC;QAC3E,MAAM,IAAI,CAAC,MAAM,CAAC,gBAAgB,CAAC,YAAY,EAAE;YAC/C,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,KAAK;SACN,CAAC,CAAC;IAAA,CACJ;IAED,KAAK,CAAC,MAAM,CAAC,OAAgB,EAAE,UAAmB,EAAiB;QACjE,MAAM,KAAK,GAAG,oBAAoB,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC;QACxD,MAAM,IAAI,CAAC,MAAM,CAAC,gBAAgB,CAAC,YAAY,EAAE;YAC/C,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,KAAK;SACN,CAAC,CAAC;IAAA,CACJ;IAED,KAAK,CAAC,GAAG,CAAC,OAAgB,EAAiB;QACzC,MAAM,KAAK,GAAG,iBAAiB,CAAC,OAAO,CAAC,CAAC;QACzC,MAAM,IAAI,CAAC,MAAM,CAAC,gBAAgB,CAAC,YAAY,EAAE;YAC/C,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,KAAK;SACN,CAAC,CAAC;IAAA,CACJ;CACF;AAED;;;GAGG;AACH,MAAM,UAAU,sBAAsB,CACpC,KAAoB,EACpB,MAAsB,EACJ;IAClB,OAAO,IAAI,oBAAoB,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;AAAA,CAChD;AAED;;GAEG;AACH,OAAO,EAAE,mBAAmB,EAAE,CAAC"}
1
+ {"version":3,"file":"progress.js","sourceRoot":"","sources":["../src/progress.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EACL,mBAAmB,EACnB,oBAAoB,EACpB,iBAAiB,EACjB,mBAAmB,EACpB,MAAM,eAAe,CAAC;AA6BvB;;GAEG;AACH,MAAM,oBAAoB;IAEd,KAAK;IACL,MAAM;IAFhB,YACU,KAAoB,EACpB,MAAsB;qBADtB,KAAK;sBACL,MAAM;IACb,CAAC;IAEJ,KAAK,CAAC,KAAK,CACT,KAAa,EACb,WAAqB,EACrB,OAAgB,EAChB,UAAmB;QAEnB,MAAM,KAAK,GAAG,mBAAmB,CAAC,KAAK,EAAE,WAAW,EAAE,OAAO,EAAE,UAAU,CAAC,CAAC;QAC3E,MAAM,IAAI,CAAC,MAAM,CAAC,gBAAgB,CAAC,YAAY,EAAE;YAC/C,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,KAAK;SACN,CAAC,CAAC;IACL,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,OAAgB,EAAE,UAAmB;QAChD,MAAM,KAAK,GAAG,oBAAoB,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC;QACxD,MAAM,IAAI,CAAC,MAAM,CAAC,gBAAgB,CAAC,YAAY,EAAE;YAC/C,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,KAAK;SACN,CAAC,CAAC;IACL,CAAC;IAED,KAAK,CAAC,GAAG,CAAC,OAAgB;QACxB,MAAM,KAAK,GAAG,iBAAiB,CAAC,OAAO,CAAC,CAAC;QACzC,MAAM,IAAI,CAAC,MAAM,CAAC,gBAAgB,CAAC,YAAY,EAAE;YAC/C,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,KAAK;SACN,CAAC,CAAC;IACL,CAAC;CACF;AAED;;;GAGG;AACH,MAAM,UAAU,sBAAsB,CACpC,KAAoB,EACpB,MAAsB;IAEtB,OAAO,IAAI,oBAAoB,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;AACjD,CAAC;AAED;;GAEG;AACH,OAAO,EAAE,mBAAmB,EAAE,CAAC"}
package/dist/server.d.ts CHANGED
@@ -5,18 +5,75 @@ import type { Transport, Disposable, ServerCapabilities, ClientCapabilities, LSP
5
5
  import type { ServerOptions, RequestHandler, NotificationHandler, NotebookDocumentHandlerNamespace } from './types.js';
6
6
  import { ServerState } from './types.js';
7
7
  /**
8
- * LSP Server class with dynamic capability-aware typing
8
+ * Full-featured LSP server with automatic lifecycle management, typed handlers,
9
+ * capability-aware namespaces, and pluggable middleware.
9
10
  *
10
- * This class dynamically provides handler registration and send methods based on capabilities.
11
- * Methods are type-safe and conditionally available based on the Capabilities type parameter.
11
+ * @remarks
12
+ * `LSPServer` manages the complete LSP lifecycle (`initialize` / `initialized`
13
+ * / `shutdown` / `exit`) automatically. Register your handlers with
14
+ * `onRequest` / `onNotification`, declare capabilities with
15
+ * `registerCapabilities`, then start the server with `listen(transport)`.
12
16
  *
13
- * @template Capabilities - Server capabilities (defaults to ServerCapabilities)
17
+ * ### Capability-aware namespaces
18
+ *
19
+ * After calling `registerCapabilities(caps)`, the server exposes typed
20
+ * namespaces — e.g. `server.textDocument.onHover(handler)` — that are only
21
+ * present when the corresponding capability is declared. TypeScript enforces
22
+ * this at compile time so you cannot accidentally register a handler for a
23
+ * capability you never advertised.
24
+ *
25
+ * ### Transport selection
26
+ *
27
+ * - **Browser / universal**: `WebSocketTransport` (from `@lspeasy/core`)
28
+ * - **Node.js**: `StdioTransport`, `TcpTransport`, `IpcTransport` (from `@lspeasy/core/node`)
29
+ * - **Web Workers**: `DedicatedWorkerTransport`, `SharedWorkerTransport` (from `@lspeasy/core`)
30
+ *
31
+ * @useWhen
32
+ * You are building an LSP language server that editors and language-client
33
+ * tooling will connect to. `LSPServer` is the primary entry point for all
34
+ * server implementations.
35
+ *
36
+ * @avoidWhen
37
+ * You need a bare JSON-RPC layer without LSP semantics — use the transport
38
+ * and framing utilities directly instead.
39
+ *
40
+ * @never
41
+ * NEVER call `server.shutdown()` or `server.close()` from inside a request
42
+ * or notification handler — doing so attempts to close the transport while it
43
+ * is actively dispatching, causing a deadlock.
44
+ *
45
+ * NEVER mutate `ServerCapabilities` after `initialized` has been received.
46
+ * The client cached the `InitializeResult` at handshake time; runtime changes
47
+ * are invisible to it.
48
+ *
49
+ * NEVER share one `LSPServer` instance across multiple transports or
50
+ * connections. Each connection requires its own server instance to maintain
51
+ * independent protocol state (lifecycle phase, pending request IDs, etc.).
52
+ *
53
+ * NEVER send a server-to-client notification before the `initialize` response
54
+ * has been dispatched. Use the `initialized` notification handler as the
55
+ * earliest safe point for server-initiated messages.
14
56
  *
15
57
  * @example
16
- * // Create a server with specific capabilities
17
- * type MyCaps = { hoverProvider: true; completionProvider: { triggerCharacters: ['.'] } };
18
- * const server = new LSPServer<MyCaps>();
19
- * server.registerCapabilities({ hoverProvider: true, completionProvider: { triggerCharacters: ['.'] } });
58
+ * ```ts
59
+ * import { LSPServer } from '@lspeasy/server';
60
+ * // Node.js: import { StdioTransport } from '@lspeasy/core/node';
61
+ * // Browser: import { WebSocketTransport } from '@lspeasy/core';
62
+ *
63
+ * const server = new LSPServer({ name: 'my-lsp', version: '1.0.0' })
64
+ * .registerCapabilities({ hoverProvider: true });
65
+ *
66
+ * server.textDocument.onHover(async (params, token) => {
67
+ * if (token.isCancellationRequested) return null;
68
+ * return { contents: { kind: 'plaintext', value: 'Hello from my-lsp' } };
69
+ * });
70
+ *
71
+ * const transport = new StdioTransport();
72
+ * await server.listen(transport);
73
+ * ```
74
+ *
75
+ * @template Capabilities - Shape of the server capabilities, defaults to `ServerCapabilities`.
76
+ * @category Server
20
77
  */
21
78
  export declare class BaseLSPServer<Capabilities extends Partial<ServerCapabilities> = ServerCapabilities> {
22
79
  private readonly logger;
@@ -104,19 +161,56 @@ export declare class BaseLSPServer<Capabilities extends Partial<ServerCapabiliti
104
161
  */
105
162
  expect<C extends Partial<ClientCapabilities>>(): this & Server<C, Capabilities>;
106
163
  /**
107
- * Send a server-to-client request.
164
+ * Send a server-to-client request and await the client's response.
165
+ *
166
+ * @param method - The LSP request method name (server-to-client direction).
167
+ * @param params - Optional request parameters.
168
+ * @returns A promise resolving to the client's result.
169
+ * @throws {Error} When not listening (transport not attached). Fix: only call `sendRequest` from inside a handler or after the `listening` event fires.
170
+ * @throws {Error} When the client returns a JSON-RPC error response. Fix: catch and inspect `error.code`; `window/showMessageRequest` rejections are user-initiated (user dismissed), not bugs.
171
+ * @throws {Error} When the request times out (if `requestTimeout` is configured). Fix: increase `ServerOptions.requestTimeout` for slow UI interactions like `window/showMessageRequest`.
172
+ *
173
+ * @category Server
108
174
  */
109
175
  sendRequest<Method extends LSPRequestMethod<'serverToClient'>>(method: Method, params?: ParamsForRequest<Method>): Promise<ResultForRequest<Method>>;
110
176
  /**
111
- * Send a server-to-client notification.
177
+ * Send a server-to-client notification (fire-and-forget).
178
+ *
179
+ * @param method - The LSP notification method name (server-to-client direction).
180
+ * @param params - Optional notification parameters.
181
+ * @throws {Error} When not listening. Fix: only send notifications after `listen()` resolves and before `shutdown()` is called; guard with `isListening()`.
182
+ * @throws {Error} When the transport's underlying `send()` fails (e.g. broken socket). Fix: subscribe to `server.onError()` to catch transport-level write failures.
183
+ *
184
+ * @category Server
112
185
  */
113
186
  sendNotification<Method extends LSPNotificationMethod<'serverToClient'>>(method: Method, params?: ParamsForNotification<Method>): Promise<void>;
114
187
  /**
115
- * Start listening on a transport
188
+ * Attaches the server to a transport and begins processing messages.
189
+ *
190
+ * @remarks
191
+ * After `listen()` returns the server is ready to receive the `initialize`
192
+ * request from the client. The LSP handshake proceeds automatically.
193
+ *
194
+ * @param transport - The transport to listen on.
195
+ * @throws {Error} When already listening. Fix: call `close()` then create a fresh `LSPServer` instance — do not reuse a single instance across connections.
196
+ *
197
+ * @category Lifecycle
116
198
  */
117
199
  listen(transport: Transport): Promise<void>;
118
200
  /**
119
- * Graceful shutdown
201
+ * Initiates graceful shutdown, waits for in-flight handlers, then closes
202
+ * the transport.
203
+ *
204
+ * @remarks
205
+ * Waits up to `timeout` ms for pending handlers to complete, then
206
+ * cancels any remaining in-flight requests before closing. Use this method
207
+ * to shut down in response to an OS signal or editor session end.
208
+ *
209
+ * @param timeout - Maximum milliseconds to wait for in-flight handlers before
210
+ * force-cancelling them.
211
+ * @defaultValue 5000
212
+ *
213
+ * @category Lifecycle
120
214
  */
121
215
  shutdown(timeout?: number): Promise<void>;
122
216
  /**
@@ -165,6 +259,68 @@ export declare class BaseLSPServer<Capabilities extends Partial<ServerCapabiliti
165
259
  */
166
260
  private handleResponse;
167
261
  }
262
+ /**
263
+ * Full-featured LSP server with automatic lifecycle management, typed handlers,
264
+ * capability-aware namespaces, and pluggable middleware.
265
+ *
266
+ * @remarks
267
+ * `LSPServer` manages the complete LSP lifecycle (`initialize` / `initialized`
268
+ * / `shutdown` / `exit`) automatically. Register handlers with `onRequest` /
269
+ * `onNotification`, declare capabilities with `registerCapabilities`, then
270
+ * start with `listen(transport)`.
271
+ *
272
+ * ### Capability-aware namespaces
273
+ * After `registerCapabilities({ hoverProvider: true })`, TypeScript exposes
274
+ * `server.textDocument.onHover(handler)` — methods absent unless the
275
+ * corresponding capability is declared.
276
+ *
277
+ * @useWhen
278
+ * You are building an LSP language server that editors and language-client
279
+ * tooling will connect to.
280
+ *
281
+ * @avoidWhen
282
+ * You need a bare JSON-RPC layer without LSP semantics — use the transport
283
+ * and framing utilities from `@lspeasy/core` directly.
284
+ *
285
+ * @never
286
+ * NEVER call `server.shutdown()` or `server.close()` from inside a request
287
+ * or notification handler — doing so attempts to close the transport while it
288
+ * is actively dispatching, causing a deadlock.
289
+ *
290
+ * NEVER mutate `ServerCapabilities` after `initialized` has been received.
291
+ * The client cached the `InitializeResult` at handshake time; runtime changes
292
+ * are invisible to it.
293
+ *
294
+ * NEVER share one `LSPServer` instance across multiple transports or connections.
295
+ * Each connection requires its own server instance to maintain independent state.
296
+ *
297
+ * @example
298
+ * ```ts
299
+ * import { LSPServer } from '@lspeasy/server';
300
+ * import { StdioTransport } from '@lspeasy/core/node';
301
+ *
302
+ * const server = new LSPServer({ name: 'my-lsp', version: '1.0.0' })
303
+ * .registerCapabilities({ hoverProvider: true });
304
+ *
305
+ * server.textDocument.onHover(async (params, token) => {
306
+ * if (token.isCancellationRequested) return null;
307
+ * return { contents: { kind: 'plaintext', value: 'Hello from my-lsp' } };
308
+ * });
309
+ *
310
+ * await server.listen(new StdioTransport());
311
+ * ```
312
+ *
313
+ * @template ServerCaps - Shape of the server capabilities.
314
+ * @category Server
315
+ */
168
316
  export type LSPServer<ServerCaps extends Partial<ServerCapabilities> = ServerCapabilities> = BaseLSPServer<ServerCaps> & Server<ClientCapabilities, ServerCaps>;
317
+ /**
318
+ * Constructs an {@link LSPServer} instance.
319
+ *
320
+ * @param options - Optional {@link ServerOptions} to configure the server.
321
+ * @returns A new `LSPServer` instance.
322
+ *
323
+ * @category Server
324
+ */
169
325
  export declare const LSPServer: new <ServerCaps extends Partial<ServerCapabilities> = ServerCapabilities>(options?: ServerOptions<ServerCaps>) => LSPServer<ServerCaps>;
170
326
  //# sourceMappingURL=server.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
package/dist/server.js CHANGED
@@ -11,18 +11,75 @@ import { validateParams } from './validation.js';
11
11
  import { CapabilityGuard, ClientCapabilityGuard } from './capability-guard.js';
12
12
  import { initializeServerHandlerMethods, initializeServerSendMethods } from './capability-proxy.js';
13
13
  /**
14
- * LSP Server class with dynamic capability-aware typing
14
+ * Full-featured LSP server with automatic lifecycle management, typed handlers,
15
+ * capability-aware namespaces, and pluggable middleware.
15
16
  *
16
- * This class dynamically provides handler registration and send methods based on capabilities.
17
- * Methods are type-safe and conditionally available based on the Capabilities type parameter.
17
+ * @remarks
18
+ * `LSPServer` manages the complete LSP lifecycle (`initialize` / `initialized`
19
+ * / `shutdown` / `exit`) automatically. Register your handlers with
20
+ * `onRequest` / `onNotification`, declare capabilities with
21
+ * `registerCapabilities`, then start the server with `listen(transport)`.
18
22
  *
19
- * @template Capabilities - Server capabilities (defaults to ServerCapabilities)
23
+ * ### Capability-aware namespaces
24
+ *
25
+ * After calling `registerCapabilities(caps)`, the server exposes typed
26
+ * namespaces — e.g. `server.textDocument.onHover(handler)` — that are only
27
+ * present when the corresponding capability is declared. TypeScript enforces
28
+ * this at compile time so you cannot accidentally register a handler for a
29
+ * capability you never advertised.
30
+ *
31
+ * ### Transport selection
32
+ *
33
+ * - **Browser / universal**: `WebSocketTransport` (from `@lspeasy/core`)
34
+ * - **Node.js**: `StdioTransport`, `TcpTransport`, `IpcTransport` (from `@lspeasy/core/node`)
35
+ * - **Web Workers**: `DedicatedWorkerTransport`, `SharedWorkerTransport` (from `@lspeasy/core`)
36
+ *
37
+ * @useWhen
38
+ * You are building an LSP language server that editors and language-client
39
+ * tooling will connect to. `LSPServer` is the primary entry point for all
40
+ * server implementations.
41
+ *
42
+ * @avoidWhen
43
+ * You need a bare JSON-RPC layer without LSP semantics — use the transport
44
+ * and framing utilities directly instead.
45
+ *
46
+ * @never
47
+ * NEVER call `server.shutdown()` or `server.close()` from inside a request
48
+ * or notification handler — doing so attempts to close the transport while it
49
+ * is actively dispatching, causing a deadlock.
50
+ *
51
+ * NEVER mutate `ServerCapabilities` after `initialized` has been received.
52
+ * The client cached the `InitializeResult` at handshake time; runtime changes
53
+ * are invisible to it.
54
+ *
55
+ * NEVER share one `LSPServer` instance across multiple transports or
56
+ * connections. Each connection requires its own server instance to maintain
57
+ * independent protocol state (lifecycle phase, pending request IDs, etc.).
58
+ *
59
+ * NEVER send a server-to-client notification before the `initialize` response
60
+ * has been dispatched. Use the `initialized` notification handler as the
61
+ * earliest safe point for server-initiated messages.
20
62
  *
21
63
  * @example
22
- * // Create a server with specific capabilities
23
- * type MyCaps = { hoverProvider: true; completionProvider: { triggerCharacters: ['.'] } };
24
- * const server = new LSPServer<MyCaps>();
25
- * server.registerCapabilities({ hoverProvider: true, completionProvider: { triggerCharacters: ['.'] } });
64
+ * ```ts
65
+ * import { LSPServer } from '@lspeasy/server';
66
+ * // Node.js: import { StdioTransport } from '@lspeasy/core/node';
67
+ * // Browser: import { WebSocketTransport } from '@lspeasy/core';
68
+ *
69
+ * const server = new LSPServer({ name: 'my-lsp', version: '1.0.0' })
70
+ * .registerCapabilities({ hoverProvider: true });
71
+ *
72
+ * server.textDocument.onHover(async (params, token) => {
73
+ * if (token.isCancellationRequested) return null;
74
+ * return { contents: { kind: 'plaintext', value: 'Hello from my-lsp' } };
75
+ * });
76
+ *
77
+ * const transport = new StdioTransport();
78
+ * await server.listen(transport);
79
+ * ```
80
+ *
81
+ * @template Capabilities - Shape of the server capabilities, defaults to `ServerCapabilities`.
82
+ * @category Server
26
83
  */
27
84
  export class BaseLSPServer {
28
85
  logger;
@@ -165,7 +222,16 @@ export class BaseLSPServer {
165
222
  return this;
166
223
  }
167
224
  /**
168
- * Send a server-to-client request.
225
+ * Send a server-to-client request and await the client's response.
226
+ *
227
+ * @param method - The LSP request method name (server-to-client direction).
228
+ * @param params - Optional request parameters.
229
+ * @returns A promise resolving to the client's result.
230
+ * @throws {Error} When not listening (transport not attached). Fix: only call `sendRequest` from inside a handler or after the `listening` event fires.
231
+ * @throws {Error} When the client returns a JSON-RPC error response. Fix: catch and inspect `error.code`; `window/showMessageRequest` rejections are user-initiated (user dismissed), not bugs.
232
+ * @throws {Error} When the request times out (if `requestTimeout` is configured). Fix: increase `ServerOptions.requestTimeout` for slow UI interactions like `window/showMessageRequest`.
233
+ *
234
+ * @category Server
169
235
  */
170
236
  async sendRequest(method, params) {
171
237
  if (!this.transport) {
@@ -199,7 +265,14 @@ export class BaseLSPServer {
199
265
  return promise;
200
266
  }
201
267
  /**
202
- * Send a server-to-client notification.
268
+ * Send a server-to-client notification (fire-and-forget).
269
+ *
270
+ * @param method - The LSP notification method name (server-to-client direction).
271
+ * @param params - Optional notification parameters.
272
+ * @throws {Error} When not listening. Fix: only send notifications after `listen()` resolves and before `shutdown()` is called; guard with `isListening()`.
273
+ * @throws {Error} When the transport's underlying `send()` fails (e.g. broken socket). Fix: subscribe to `server.onError()` to catch transport-level write failures.
274
+ *
275
+ * @category Server
203
276
  */
204
277
  async sendNotification(method, params) {
205
278
  if (!this.transport) {
@@ -224,7 +297,16 @@ export class BaseLSPServer {
224
297
  });
225
298
  }
226
299
  /**
227
- * Start listening on a transport
300
+ * Attaches the server to a transport and begins processing messages.
301
+ *
302
+ * @remarks
303
+ * After `listen()` returns the server is ready to receive the `initialize`
304
+ * request from the client. The LSP handshake proceeds automatically.
305
+ *
306
+ * @param transport - The transport to listen on.
307
+ * @throws {Error} When already listening. Fix: call `close()` then create a fresh `LSPServer` instance — do not reuse a single instance across connections.
308
+ *
309
+ * @category Lifecycle
228
310
  */
229
311
  async listen(transport) {
230
312
  if (this.transport) {
@@ -248,7 +330,19 @@ export class BaseLSPServer {
248
330
  this.events.emit('listening');
249
331
  }
250
332
  /**
251
- * Graceful shutdown
333
+ * Initiates graceful shutdown, waits for in-flight handlers, then closes
334
+ * the transport.
335
+ *
336
+ * @remarks
337
+ * Waits up to `timeout` ms for pending handlers to complete, then
338
+ * cancels any remaining in-flight requests before closing. Use this method
339
+ * to shut down in response to an OS signal or editor session end.
340
+ *
341
+ * @param timeout - Maximum milliseconds to wait for in-flight handlers before
342
+ * force-cancelling them.
343
+ * @defaultValue 5000
344
+ *
345
+ * @category Lifecycle
252
346
  */
253
347
  async shutdown(timeout = 5000) {
254
348
  if (this.state === ServerState.Shutdown) {
@@ -521,6 +615,14 @@ export class BaseLSPServer {
521
615
  this.pendingRequests.reject(String(id), new Error('Invalid response message'));
522
616
  }
523
617
  }
618
+ /**
619
+ * Constructs an {@link LSPServer} instance.
620
+ *
621
+ * @param options - Optional {@link ServerOptions} to configure the server.
622
+ * @returns A new `LSPServer` instance.
623
+ *
624
+ * @category Server
625
+ */
524
626
  // Generic constructor that preserves type parameters
525
627
  export const LSPServer = BaseLSPServer;
526
628
  //# sourceMappingURL=server.js.map