# Core Client

Core client classes and lifecycle management for establishing and maintaining language server connections.

## Capabilities

### BaseLanguageClient

Abstract base class providing core functionality for all language clients.

```typescript { .api }
/**
 * Abstract base class for all language clients providing core LSP functionality
 */
abstract class BaseLanguageClient {
  /** Client name identifier */
  readonly name: string;
  
  /** Current client state */
  readonly state: State;
  
  /** Initialization result from the language server */
  readonly initializeResult: InitializeResult | undefined;
  
  /** Client configuration options */
  readonly clientOptions: LanguageClientOptions;
  
  /** Middleware configuration for feature customization */
  readonly middleware: Middleware;
  
  /** Output channel for client messages */
  readonly outputChannel: OutputChannel;
  
  /** Output channel for trace messages */
  readonly traceOutputChannel: OutputChannel;
  
  /** Diagnostic collection for server diagnostics */
  readonly diagnostics: DiagnosticCollection | undefined;
  
  /** Protocol to code converter instance */
  readonly protocol2CodeConverter: Protocol2CodeConverter;
  
  /** Code to protocol converter instance */
  readonly code2ProtocolConverter: Code2ProtocolConverter;
  
  /** Event emitted when client state changes */
  readonly onDidChangeState: Event<StateChangeEvent>;
  
  /** Event emitted for telemetry data from server */
  readonly onTelemetry: Event<any>;
  
  /** Start the language client and establish connection to server */
  start(): Promise<void>;
  
  /** Stop the language client with optional timeout */
  stop(timeout?: number): Promise<void>;
  
  /** Dispose the client and cleanup resources */
  dispose(timeout?: number): Promise<void>;
  
  /** Send a request to the language server */
  sendRequest<R, PR, E>(type: ProtocolRequestType<PR, R, E, any>, params: PR, token?: CancellationToken): Promise<R>;
  sendRequest<R, E>(type: RequestType0<R, E>, token?: CancellationToken): Promise<R>;
  sendRequest<R, P, E>(type: RequestType<P, R, E>, params: P, token?: CancellationToken): Promise<R>;
  
  /** Send a notification to the language server */
  sendNotification<RO>(type: ProtocolNotificationType<RO, any>, params?: RO): Promise<void>;
  sendNotification<P>(type: NotificationType<P>, params?: P): Promise<void>;
  sendNotification(type: NotificationType0): Promise<void>;
  
  /** Register a request handler for server requests */
  onRequest<R, PR, E>(type: ProtocolRequestType<PR, R, E, any>, handler: RequestHandler<PR, R, E>): Disposable;
  onRequest<R, E>(type: RequestType0<R, E>, handler: RequestHandler0<R, E>): Disposable;
  onRequest<R, P, E>(type: RequestType<P, R, E>, handler: RequestHandler<P, R, E>): Disposable;
  onRequest(method: string, handler: GenericRequestHandler): Disposable;
  
  /** Register a notification handler for server notifications */
  onNotification<RO>(type: ProtocolNotificationType<RO, any>, handler: NotificationHandler<RO>): Disposable;
  onNotification<P>(type: NotificationType<P>, handler: NotificationHandler<P>): Disposable;
  onNotification(type: NotificationType0, handler: NotificationHandler0): Disposable;
  onNotification(method: string, handler: GenericNotificationHandler): Disposable;
  
  /** Send progress notification */
  sendProgress<P>(type: ProgressType<P>, token: ProgressToken, value: P): Promise<void>;
  
  /** Register progress handler */
  onProgress<P>(type: ProgressType<P>, token: ProgressToken, handler: NotificationHandler<P>): Disposable;
  
  /** Set trace level for debugging */
  setTrace(value: Trace): Promise<void>;
  
  /** Register a feature with the client */
  registerFeature(feature: StaticFeature | DynamicFeature<any>): void;
  
  /** Get a registered feature by request method */
  getFeature(request: string): DynamicFeature<any> | undefined;
  
  /** Create message transports for communication (implemented by subclasses) */
  protected abstract createMessageTransports(encoding: string): Promise<MessageTransports>;
  
  /** Handle connection errors */
  protected handleConnectionError(error: Error, message: Message | undefined, count: number | undefined): void;
  
  /** Handle connection closed */
  protected handleConnectionClosed(): void;
}
```

**Usage Examples:**

Basic client lifecycle:

```typescript
import { LanguageClient } from "vscode-languageclient/node";

const client = new LanguageClient(
  'my-language-client',
  'My Language Client', 
  serverOptions,
  clientOptions
);

// Start the client
await client.start();
console.log(`Client state: ${client.state}`); // State.Running

// Send a custom request
const result = await client.sendRequest('custom/method', { param: 'value' });

// Stop the client
await client.stop();
```

Request/notification handling:

```typescript
// Handle server requests
client.onRequest('workspace/configuration', (params) => {
  return [{ setting: 'value' }];
});

// Handle server notifications
client.onNotification('window/logMessage', (params) => {
  console.log(`Server: ${params.message}`);
});

// Send custom notification
await client.sendNotification('custom/notification', { data: 'value' });
```

### LanguageClient (Node.js)

Node.js implementation of the language client supporting various transport mechanisms.

```typescript { .api }
/**
 * Node.js implementation of LanguageClient supporting stdio, IPC, pipe, and socket transports
 */
class LanguageClient extends BaseLanguageClient {
  /** Whether the client is running in debug mode */
  readonly isInDebugMode: boolean;
  
  /**
   * Create a language client for Node.js environment
   * @param name - Client name (also used as ID)
   * @param serverOptions - Server configuration options
   * @param clientOptions - Client configuration options  
   * @param forceDebug - Force debug mode regardless of environment
   */
  constructor(name: string, serverOptions: ServerOptions, clientOptions: LanguageClientOptions, forceDebug?: boolean);
  
  /**
   * Create a language client with explicit ID and name
   * @param id - Client identifier
   * @param name - Display name for the client
   * @param serverOptions - Server configuration options
   * @param clientOptions - Client configuration options
   * @param forceDebug - Force debug mode regardless of environment
   */
  constructor(id: string, name: string, serverOptions: ServerOptions, clientOptions: LanguageClientOptions, forceDebug?: boolean);
  
  /** Create message transports based on server options */
  protected createMessageTransports(encoding: string): Promise<MessageTransports>;
}
```

### LanguageClient (Browser)

Browser implementation of the language client using Web Workers for communication.

```typescript { .api }
/**
 * Browser implementation of LanguageClient using Web Worker communication
 */
class LanguageClient extends BaseLanguageClient {
  /** The Web Worker running the language server */
  private readonly worker: Worker;
  
  /**
   * Create a language client for browser environment
   * @param id - Client identifier
   * @param name - Display name for the client
   * @param clientOptions - Client configuration options
   * @param worker - Web Worker instance running the language server
   */
  constructor(id: string, name: string, clientOptions: LanguageClientOptions, worker: Worker);
  
  /** Create message transports using browser message readers/writers */
  protected createMessageTransports(encoding: string): Promise<MessageTransports>;
}
```

**Usage Examples:**

Node.js client with stdio transport:

```typescript
import { LanguageClient, ServerOptions, TransportKind } from "vscode-languageclient/node";

const serverOptions: ServerOptions = {
  run: { command: 'language-server', transport: TransportKind.stdio },
  debug: { command: 'language-server', args: ['--debug'], transport: TransportKind.stdio }
};

const client = new LanguageClient(
  'example-client',
  'Example Language Client',
  serverOptions,
  clientOptions
);
```

Browser client with Web Worker:

```typescript
import { LanguageClient } from "vscode-languageclient/browser";

const worker = new Worker('./language-server-worker.js');
const client = new LanguageClient(
  'example-browser-client',
  'Example Browser Client',
  clientOptions,
  worker
);
```

## Types

### State Management

```typescript { .api }
enum State {
  /** Client is stopped */
  Stopped = 1,
  /** Client is starting up */
  Starting = 3,
  /** Client is running and connected */
  Running = 2
}

interface StateChangeEvent {
  /** Previous client state */
  oldState: State;
  /** New client state */
  newState: State;
}
```

### Message Transports

```typescript { .api }
interface MessageTransports {
  /** Message reader for receiving from server */
  reader: MessageReader;
  /** Message writer for sending to server */  
  writer: MessageWriter;
  /** Whether the transport is detached from the client lifecycle */
  detached?: boolean;
}
```