@effected/lsp

中文文档
0.9.0发布于 2026/11/10MITTypeScriptES Module零依赖构建来源已验证近 30 天下载 3954

Effect v4 语言服务器协议基础- protocol 框架,外加一个装入的安装初始化探测器,用于语言服务器本

中文使用文档
文档目录7 节
  1. 安装
  2. 长发
  3. LspStdio 语言
  4. 长发
  5. 长相探测器( L) @effected/lsp/testing (中文(简体) )
  6. 流程( E) @effected/lsp/testing (中文(简体) )
  7. 许可证

@ effect/ lsp

Effect v4 语言服务器协议基础-protocol框架 - Content-Length 框由字节长度编码,并逐步解码——一个Stdio发射装置,使LSP线条和出口保持有规格要求的代码,a ./testing 其子路径 LspProbe 证明语言服务器的 bin 靴子 LspProcess 逐帧驱动.

npm License: MIT Node.js %3E%3D24.11.0 TypeScript 7.0

预1.0.0。 。 。 . 此软件包是 @effected/* 在稳定基础上建造的工具包 效应v4(effect ~4.1.0) 并仍在 0.x 发展。 稳定效果 制作一个工具箱 1.0.0 可能,不是自动的。 为了保持你的 effect 财务报告和审定财务报表 @effect/* 该工具包在线上构建和测试、安装 @effected/pnpm-plugin-effected。 。 。 .

稳定:不稳定. 此软件包的 API 表面尚未考虑 完成并可能改变 0.x 释放 定一个确切的版本——甚至 标记软件包 稳定 在此之前 1.0.0 可以引入突破性更改 和精确的针 变成一个类型检查错误 而不是一个 跑步时间惊喜。 完全政策: 释放策略。 。 。 .

安装

npm install @effected/lsp effect
pnpm add @effected/lsp effect

需要节点.js~~24.11.0.

全体 @effected/* 软件包仅为无害环境管理:只公布出口地图 import 条件,所以 require() 节点失败 ERR_PACKAGE_PATH_NOT_EXPORTED从ES模块导入.

effect v4是唯一的对等依赖. 边界分级:主要输入是纯的,以及 ./testing 只通过核心运行一个儿童进程 ChildProcessSpawner,您提供一个平台层(NodeServices.layer 从 @effect/platform-node) (中文(简体) ).

这不是 LSP 服务器框架 。 它会设定线条, 发射一个您所写的服务器, 并测试本站; 消息循环和每个处理器 都与您所服务的协议一起 .

长发

LSP信息作为头条块、空白行和UTF-8 JSON的躯体而行走 Content-Length 计数 字节。一个手卷框,写着 body.length 对 ASCII 是正确的,对多字节字符的每个多字节字节都错误一个字节,所以服务器读取到下一个框架. LspFrame.encode 计数编码 :

import { LspFrame } from "@effected/lsp";

const frame = LspFrame.encode({ jsonrpc: "2.0", method: "note", params: { text: "✓" } });
console.log(new TextDecoder().decode(frame));
// => Content-Length: 57
//
//    {"jsonrpc":"2.0","method":"note","params":{"text":"✓"}}

解码是渐进的. LspFrame.decodeResult 取出任何已到达的字节,然后返回每个完整的框加上一个不完整的框的字节,所以一个块可能会在一个头,一个正体或一个字符内结束,并可能携带几个框. LspFrame.decodeStream 横穿一线 Stream 块,和 LspFrame.decodeAllResult 解码一个收集的 stdout in one go:

import { LspFrame } from "@effected/lsp";
import { Result } from "effect";

const decoded = LspFrame.decodeAllResult('Content-Length: 2\r\n\r\n{}Content-Length: 5\r\n\r\n"✓"');
console.log(Result.getOrThrow(decoded));
// => [ {}, '✓' ]

输入的流格式错误失败 LspFrameError 谁 code 说哪条规则被打破了MissingContentLength, (中文(简体) ), InvalidContentLength, (中文(简体) ), InvalidHeader, (中文(简体) ), HeaderTooLarge, (中文(简体) ), InvalidBody, (中文(简体) ), Truncated(b) 其国家 offset 是框架的溪流位置,并且 excerpt 呼应了帧的起步——在第一帧出现前写成的一行记录出场. decode 财务报告和审定财务报表 decodeAll 这是 Effect 表单.

LspStdio 语言

效果语言服务器在 stdio 上有三个陷阱 LspStdio 关闭每个 :

  • runMain 报告 stdout 上的失败程序. 其报告在外 Effect.provide 程序适用,所以 LogToStderr 内出不来:无法建造的地层(缺失) HOME将报告打印到线上. LspStdio.launch 提供 LogToStderr 对整个程序,报告stderr本身的失败, 并重新评价它标记为已报告, 保留其退出代码.
  • 出口代码是规格的. exit 没有前一个 shutdown 1号出口 其他0号出口. LspStdio.exitCode 这是规则,和 launch 应用到 LspSessionEnd 您的消息循环返回 .
  • 一个干净的出入口从不单独发生. runMain 结束过程本身只针对一个非零码或信号,将代码0留给事件循环排出,在stdin打开时它从未这样做——然后 exitstdin还开着呢. LspStdio.teardown(process) 明确结束进程,将SIGINT和SIGTERM的地图绘制为0而不是130.
import * as NodeRuntime from "@effect/platform-node/NodeRuntime";
import { LspStdio } from "@effected/lsp";
import { Effect } from "effect";
import { AppLayer, serve } from "./server.js";

// `serve` is your server: it runs the message loop and returns how the session ended.
NodeRuntime.runMain(LspStdio.launch(serve.pipe(Effect.provide(AppLayer))), {
  teardown: LspStdio.teardown(process),
});

工具箱不拥有消息循环, 因此无法看到 shutdown 或者说 exit 本身:你的循环记录它们并返回 { reason: "exit" | "closed", shutdownReceived }A级 vscode-languageserver 连接报告通过 onShutdown 财务报告和审定财务报表 onExit。 。 。 .

LogToStderr 达到 Effect 的默认日志 Logger.consolePretty。 。 。 . Logger.consoleJson, (中文(简体) ), consoleLogFmt 财务报告和审定财务报表 consoleStructured 写入 console.log 不管怎样 —— 将一个前题包入 Logger.withConsoleError 相反——和 Console.log 仍写作出出.

长发

LSP 名称文档 file: URI,文件系统按路径排列. LspUri 转换双向 node:url因此,它也运行在一个工人:

import { LspUri } from "@effected/lsp";

const platform = process.platform === "win32" ? "win32" : "posix";

LspUri.toPath("file:///home/me/My%20Project/a.ts", { platform }); // Option.some("/home/me/My Project/a.ts")
LspUri.toPath("untitled:Untitled-1", { platform }); // Option.none()
LspUri.fromPath("C:\\Users\\me\\a.ts", { platform: "win32" }); // "file:///c:/Users/me/a.ts"

toPath 答题 Option.none() 而不是向一个没有路径命名的 URI 投放: 另一种方案, 一个错误的逃生, a %2F 一个名字,一个主机在posix. . 财务报告和审定财务报表 .. 永远不要爬到根上,一个驱动器或一个UNC共享. 驱动信件会回小写, 但客户端拼写它(C:, (中文(简体) ), c: 或 VS 代码 c%3A),所以关键文档通过路径,而不是客户端的URI字符串.

长相探测器( L)@effected/lsp/testing(中文(简体) )

语言服务器本的装入式安装证明 @effected/mcp-kit/testing是因为 McpProbe它产生命令,运行一个编辑运行的生命周期—— initialize, (中文(简体) ), initialized, (中文(简体) ), shutdown, (中文(简体) ), exit ——然后等待服务器退出:

import * as NodeServices from "@effect/platform-node/NodeServices";
import { LspProbe } from "@effected/lsp/testing";
import { Effect } from "effect";
import { ChildProcess } from "effect/process";

const program = Effect.gen(function* () {
  const probe = yield* LspProbe.initialize(ChildProcess.make("my-lsp", ["--stdio"]));
  // A clean boot: no JSON-RPC error, exit code 0 (shutdown preceded exit), nothing on stderr.
  return probe.response.error === undefined && probe.exitCode === 0 && probe.stderr === "";
}).pipe(Effect.provide(NodeServices.layer));
  • initialize 约会 processId 财务报告和审定财务报表 rootUri null 和空客户端能力,除非 LspProbeOptions 说不然.
  • 之后 Stdin 保持开放 exit: 服务器必须停止 exit因为它必须在编辑之下。 等待 stdin 关闭的服务器失败 TimedOut。 。 。 .
  • 服务器发送的每封信都在 messages,顺序;它向客户发送的请求被记录下来,从未回答.
  • 它从不挂起: 结束早的失败 StreamEnded 带有退出代码和 stderr, 非帧的字节失败 InvalidFrame,整个交换 运行在 timeout (默认为30秒). 打开它 it.live - 超时读取 Clock。 。 。 .

流程( E)@effected/lsp/testing(中文(简体) )

一个产入的服务器 一个测试驱动框架的帧——LSP双人 @effected/mcp-kit/testing是因为 McpProcess. 儿童为以下附加范围而活:

import * as NodeServices from "@effect/platform-node/NodeServices";
import { LspProcess } from "@effected/lsp/testing";
import { Effect } from "effect";
import { ChildProcess } from "effect/process";

const program = Effect.gen(function* () {
  const server = yield* LspProcess.spawn(ChildProcess.make("my-lsp", ["--stdio"]));
  yield* server.send({ jsonrpc: "2.0", id: 1, method: "initialize", params: { processId: null, rootUri: null, capabilities: {} } });
  const { response, seen } = yield* server.readUntilResponse(1);
  yield* server.send({ jsonrpc: "2.0", method: "initialized", params: {} });
  yield* server.send({ jsonrpc: "2.0", id: 2, method: "shutdown" });
  yield* server.readUntilResponse(2);
  yield* server.send({ jsonrpc: "2.0", method: "exit" });
  const exitCode = yield* server.exitCode;
  // Stdout held nothing but frames: no stray byte before, between or after them.
  const messages = yield* server.assertOnlyFrames;
  return { response, seen, exitCode, messages };
}).pipe(Effect.scoped, Effect.provide(NodeServices.layer));
  • send 框架为 LspFrame.encode· ; sendRaw 将字节写成给定的字节,用于错误的或分框.
  • nextMessage 财务报告和审定财务报表 readUntilResponse 从不挂起: 句尾失败的 stdout StreamEnded (在框架内),不是框架失败的字节 InvalidFrame,一个不是 JSON-RPC 的身体失败 NotJsonRpc。 。 。 .
  • stderrUntil(predicate, { timeout }) 等待一个报告 降落在后一滴, 被每个板块 而不是一个投票计时器唤醒 StreamEnded 或者说 TimedOut 和目前为止的钢铁。 打开它 it.live。 。 。 .
  • stdoutSoFar 财务报告和审定财务报表 stdoutFinal 返回生字节; assertOnlyFrames 等待 stdout 结束和失败 InvalidFrame,命名偏移字节并引用这些字节,除非每个字节都属于一个很好的框架.

许可证

麻省理工学院

版本与发布记录

@effected/lsp 共发布 12 个版本,首次发布于 2026/10/06;过去 12 个月发布了 12 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
0.9.0latest2026/11/102 天前
0.8.02026/11/0310 天前
0.7.02026/11/0112 天前
0.6.02026/10/2915 天前
0.5.02026/10/2321 天前
0.4.02026/10/1924 天前

关于 @effected/lsp 的常见问题

@effected/lsp 是什么?

Effect v4 语言服务器协议基础- protocol 框架,外加一个装入的安装初始化探测器,用于语言服务器本

如何安装 @effected/lsp?

在项目目录运行 npm install @effected/lsp,或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖:effect(~4.1.0)。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖,Yarn 需要手动安装。

@effected/lsp 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@effected/lsp 支持 ESM 还是 CommonJS?

以 ES Module 形式发布,推荐使用 import 引入。在 CommonJS 项目中,Node.js 20.19+ / 22.12+ 可以直接 require() 不含顶层 await 的 ES Module,更早的版本需要改用动态 import()。

@effected/lsp 需要什么版本的 Node.js?

package.json 的 engines 字段要求 Node.js >=24.11.0。版本不符时 npm 默认只给出警告,开启 engine-strict 后会拒绝安装。

@effected/lsp 可以商用吗?

@effected/lsp 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@effected/lsp 的下载量有多少?

根据 npm 官方下载统计,@effected/lsp 在 2026/10/13 – 2026/11/11 这 30 天内被下载 3,954 次,日均约 132 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@effected/lsp 还在维护吗?

最新版本 0.9.0 发布于 2026/11/10(2 天前);至今共发布 12 个版本,其中过去 12 个月发布了 12 个;首次发布于 2026/10/06。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。