Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion packages/typescript/src/api/async/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,8 @@ export class API<FromLSP extends boolean = false> implements FormatDiagnosticsHo

/**
* Create an API instance from an existing LSP connection's API session.
* Use this when connecting to an API pipe provided by an LSP server via custom/initializeAPISession.
* Use this with the pipe returned by custom/initializeAPISession. The
* requested session transport must match the async or sync API variant.
*/
static async fromLSPConnection(options: LSPConnectionOptions): Promise<API<true>> {
const api = new API<true>(options);
Expand Down
7 changes: 6 additions & 1 deletion packages/typescript/src/api/options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,12 @@ import getExePath from "#getExePath";
import type { FileSystem } from "./fs.ts";

export interface ClientSocketOptions {
/** Path to the Unix domain socket or Windows named pipe for API communication */
/**
* Path returned by custom/initializeAPISession.
*
* The async API connects to a Unix domain socket or Windows named pipe.
* The sync API connects to a FIFO pair on Unix or a named pipe on Windows.
*/
pipe: string;
/** Maximum encoded byte size of each batch response page. Defaults to 300 million bytes. Individual responses can be larger than this size, but this controls where batch pages are cutoff. */
maxResponseBytesPerPage?: number;
Expand Down
3 changes: 2 additions & 1 deletion packages/typescript/src/api/sync/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -264,7 +264,8 @@ export class API<FromLSP extends boolean = false> implements FormatDiagnosticsHo

/**
* Create an API instance from an existing LSP connection's API session.
* Use this when connecting to an API pipe provided by an LSP server via custom/initializeAPISession.
* Use this with the pipe returned by custom/initializeAPISession. The
* requested session transport must match the async or sync API variant.
*/
static get fromLSPConnection(): {
(options: LSPConnectionOptions): API<true>;
Expand Down
54 changes: 33 additions & 21 deletions packages/typescript/src/api/sync/client.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
import { fsCallbackNames } from "../fs.ts";
import {
type FileSystem,
fsCallbackNames,
} from "../fs.ts";
import {
type ClientOptions,
type ClientSocketOptions,
Expand Down Expand Up @@ -32,39 +35,48 @@ export class Client {
private maxResponseBytesPerPage: number | undefined;

constructor(options: ClientOptions) {
if (!isSpawnOptions(options)) {
throw new Error("Socket connections are not yet supported in the sync client");
}
let enabledCallbacks: (typeof fsCallbackNames[number])[] = [];
let channel: SyncRpcChannel;
let fs: FileSystem | undefined;
let collectTiming = false;

const args = getAPIProcessArgs(options, false);
this.maxResponseBytesPerPage = options.maxResponseBytesPerPage;

// Enable virtual FS callbacks for each provided FS function
const enabledCallbacks: (typeof fsCallbackNames[number])[] = [];
if (options.fs) {
for (const name of fsCallbackNames) {
if (options.fs[name]) {
enabledCallbacks.push(name);
if (isSpawnOptions(options)) {
const args = getAPIProcessArgs(options, false);

// Enable virtual FS callbacks for each provided FS function
if (options.fs) {
for (const name of fsCallbackNames) {
if (options.fs[name]) {
enabledCallbacks.push(name);
}
}
}
if (enabledCallbacks.length > 0) {
args.push(`--callbacks=${enabledCallbacks.join(",")}`);
}

collectTiming = options.collectTiming ?? false;
fs = options.fs;
channel = new SyncRpcChannel({
exe: resolveExePath(options),
args,
}, collectTiming);
}
if (enabledCallbacks.length > 0) {
args.push(`--callbacks=${enabledCallbacks.join(",")}`);
else {
channel = new SyncRpcChannel({ pipe: options.pipe }, collectTiming);
}

const collectTiming = options.collectTiming ?? false;
if (collectTiming) {
this.timing = new TimingCollector();
}

const channel = new SyncRpcChannel(resolveExePath(options), args, collectTiming);
this.channel = channel;

if (options.fs) {
if (fs) {
for (const name of enabledCallbacks) {
if (name === "writeFile") {
if (!options.fs.writeFile) continue;
const callback = options.fs.writeFile;
if (!fs.writeFile) continue;
const callback = fs.writeFile;

channel.registerCallback(name, (_, arg) => {
const { path, data } = JSON.parse(arg);
Expand All @@ -75,7 +87,7 @@ export class Client {
continue;
}

const callback = options.fs[name]!;
const callback = fs[name]!;
channel.registerCallback(name, (_, arg) => {
const result = callback(JSON.parse(arg));
if (name === "readFile") {
Expand Down
Loading