@trim21/personal-pi-extensions 0.0.356 → 0.0.358
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/package.json +1 -1
- package/src/lib/lsp/client.ts +53 -3
- package/src/lib/lsp/lsp.ts +7 -1
package/package.json
CHANGED
package/src/lib/lsp/client.ts
CHANGED
|
@@ -99,6 +99,7 @@ export interface LspClient {
|
|
|
99
99
|
version: number;
|
|
100
100
|
mode?: "document" | "full";
|
|
101
101
|
after?: number;
|
|
102
|
+
signal?: AbortSignal;
|
|
102
103
|
}): Promise<void>;
|
|
103
104
|
shutdown(): Promise<void>;
|
|
104
105
|
}
|
|
@@ -168,6 +169,11 @@ async function withTimeout<T>(promise: Promise<T>, ms: number): Promise<T> {
|
|
|
168
169
|
}
|
|
169
170
|
}
|
|
170
171
|
|
|
172
|
+
const sleep = (ms: number) => new Promise<void>((resolve) => setTimeout(resolve, ms));
|
|
173
|
+
|
|
174
|
+
/** pull 诊断失败后的重试间隔。 */
|
|
175
|
+
const PULL_RETRY_INTERVAL_MS = 100;
|
|
176
|
+
|
|
171
177
|
function stopProcess(process: LspServerHandle["process"]): Promise<void> {
|
|
172
178
|
if (process.exitCode !== null) return Promise.resolve();
|
|
173
179
|
try {
|
|
@@ -201,6 +207,14 @@ export async function create(input: CreateInput): Promise<LspClient> {
|
|
|
201
207
|
new StreamMessageWriter(input.server.process.stdin),
|
|
202
208
|
);
|
|
203
209
|
input.server.process.stderr?.resume();
|
|
210
|
+
/** 连接或服务器进程已关闭;pull 重试循环以此终止,避免无界等待。 */
|
|
211
|
+
let connectionClosed = false;
|
|
212
|
+
input.server.process.once("exit", () => {
|
|
213
|
+
connectionClosed = true;
|
|
214
|
+
});
|
|
215
|
+
connection.onDispose(() => {
|
|
216
|
+
connectionClosed = true;
|
|
217
|
+
});
|
|
204
218
|
|
|
205
219
|
// ── 连接状态 ────────────────────────────────────────────────────────────────
|
|
206
220
|
|
|
@@ -236,8 +250,11 @@ export async function create(input: CreateInput): Promise<LspClient> {
|
|
|
236
250
|
(params: { uri: string; version?: number; diagnostics: Diagnostic[] }) => {
|
|
237
251
|
const filePath = getFilePath(params.uri);
|
|
238
252
|
if (!filePath) return;
|
|
239
|
-
//
|
|
240
|
-
//
|
|
253
|
+
// 支持 pull 诊断的服务器:push 的结果可能来自旧内容(异步重算迟到),
|
|
254
|
+
// 直接忽略,只信任 pull 返回的当前文档结果,从源头避免 stale。
|
|
255
|
+
if (supportsPullDiagnostics()) return;
|
|
256
|
+
// 纯 push 服务器:服务器版本滞后于已发送版本时,该 push 对应的是旧内容
|
|
257
|
+
// (重算未完成时的迟到结果),同样忽略。
|
|
241
258
|
const currentVersion = documentVersions.get(filePath);
|
|
242
259
|
const isStalePush =
|
|
243
260
|
typeof params.version === "number" &&
|
|
@@ -416,6 +433,15 @@ export async function create(input: CreateInput): Promise<LspClient> {
|
|
|
416
433
|
return { handled: true, matched, byFile };
|
|
417
434
|
}
|
|
418
435
|
|
|
436
|
+
/** 是否支持文档级 pull 诊断:静态 diagnosticProvider 或动态注册的 document 诊断。 */
|
|
437
|
+
function supportsPullDiagnostics(): boolean {
|
|
438
|
+
if (hasStaticPullDiagnostics) return true;
|
|
439
|
+
for (const registration of diagnosticRegistrations.values()) {
|
|
440
|
+
if (registration.registerOptions?.workspaceDiagnostics !== true) return true;
|
|
441
|
+
}
|
|
442
|
+
return false;
|
|
443
|
+
}
|
|
444
|
+
|
|
419
445
|
function documentPullState() {
|
|
420
446
|
const documentRegistrations = [...diagnosticRegistrations.values()].filter(
|
|
421
447
|
(registration) => registration.registerOptions?.workspaceDiagnostics !== true,
|
|
@@ -424,7 +450,7 @@ export async function create(input: CreateInput): Promise<LspClient> {
|
|
|
424
450
|
documentIdentifiers: [
|
|
425
451
|
...new Set(documentRegistrations.flatMap((r) => r.registerOptions?.identifier ?? [])),
|
|
426
452
|
],
|
|
427
|
-
supported:
|
|
453
|
+
supported: supportsPullDiagnostics(),
|
|
428
454
|
};
|
|
429
455
|
}
|
|
430
456
|
|
|
@@ -577,8 +603,20 @@ export async function create(input: CreateInput): Promise<LspClient> {
|
|
|
577
603
|
path: string;
|
|
578
604
|
version: number;
|
|
579
605
|
after?: number;
|
|
606
|
+
signal?: AbortSignal;
|
|
580
607
|
}): Promise<void> {
|
|
581
608
|
const startedAt = request.after ?? Date.now();
|
|
609
|
+
// 支持 pull 的服务器:push 已被忽略,pull 是唯一通道。无窗口截断——
|
|
610
|
+
// 一直重试直到拿到当前文档结果(matched),确保诊断不因服务器重算慢而丢失。
|
|
611
|
+
if (supportsPullDiagnostics()) {
|
|
612
|
+
while (!connectionClosed && !request.signal?.aborted) {
|
|
613
|
+
const result = await requestDocumentDiagnostics(request.path);
|
|
614
|
+
if (result.matched) return;
|
|
615
|
+
await sleep(PULL_RETRY_INTERVAL_MS);
|
|
616
|
+
}
|
|
617
|
+
return;
|
|
618
|
+
}
|
|
619
|
+
|
|
582
620
|
const pushWait = waitForFreshPush({
|
|
583
621
|
path: request.path,
|
|
584
622
|
version: request.version,
|
|
@@ -605,8 +643,18 @@ export async function create(input: CreateInput): Promise<LspClient> {
|
|
|
605
643
|
path: string;
|
|
606
644
|
version: number;
|
|
607
645
|
after?: number;
|
|
646
|
+
signal?: AbortSignal;
|
|
608
647
|
}): Promise<void> {
|
|
609
648
|
const startedAt = request.after ?? Date.now();
|
|
649
|
+
if (supportsPullDiagnostics()) {
|
|
650
|
+
while (!connectionClosed && !request.signal?.aborted) {
|
|
651
|
+
const result = await requestFullDiagnostics(request.path);
|
|
652
|
+
if (result.handled || result.matched) return;
|
|
653
|
+
await sleep(PULL_RETRY_INTERVAL_MS);
|
|
654
|
+
}
|
|
655
|
+
return;
|
|
656
|
+
}
|
|
657
|
+
|
|
610
658
|
const pushWait = waitForFreshPush({
|
|
611
659
|
path: request.path,
|
|
612
660
|
version: request.version,
|
|
@@ -708,6 +756,7 @@ export async function create(input: CreateInput): Promise<LspClient> {
|
|
|
708
756
|
path: normalizedPath,
|
|
709
757
|
version: request.version,
|
|
710
758
|
after: request.after,
|
|
759
|
+
signal: request.signal,
|
|
711
760
|
});
|
|
712
761
|
return;
|
|
713
762
|
}
|
|
@@ -715,6 +764,7 @@ export async function create(input: CreateInput): Promise<LspClient> {
|
|
|
715
764
|
path: normalizedPath,
|
|
716
765
|
version: request.version,
|
|
717
766
|
after: request.after,
|
|
767
|
+
signal: request.signal,
|
|
718
768
|
});
|
|
719
769
|
},
|
|
720
770
|
async shutdown() {
|
package/src/lib/lsp/lsp.ts
CHANGED
|
@@ -348,7 +348,13 @@ export function createLspService(
|
|
|
348
348
|
const version = await client.notify.open({ path: file });
|
|
349
349
|
if (!diagnostics) return;
|
|
350
350
|
await abortable(
|
|
351
|
-
client.waitForDiagnostics({
|
|
351
|
+
client.waitForDiagnostics({
|
|
352
|
+
path: file,
|
|
353
|
+
version,
|
|
354
|
+
mode: diagnostics,
|
|
355
|
+
after,
|
|
356
|
+
signal: options?.signal,
|
|
357
|
+
}),
|
|
352
358
|
options?.signal,
|
|
353
359
|
);
|
|
354
360
|
}),
|