@ridit/relay
Advanced tools
+1
-1
| { | ||
| "name": "@ridit/relay", | ||
| "version": "0.1.5", | ||
| "version": "0.1.6", | ||
| "description": "One port. Any language. Monaco-ready LSP bridge.", | ||
@@ -5,0 +5,0 @@ "author": "Ridit Jangra <riditjangra09@gmail.com> (https://ridit.space)", |
+53
-1
@@ -15,2 +15,3 @@ import type * as Monaco from "monaco-editor"; | ||
| CompletionRequest, | ||
| CompletionResolveRequest, | ||
| HoverRequest, | ||
@@ -27,2 +28,3 @@ PublishDiagnosticsNotification, | ||
| normalize_uri, | ||
| canonical_uri, | ||
| model_uri, | ||
@@ -271,2 +273,9 @@ to_lsp_position, | ||
| documentationFormat: ["plaintext", "markdown"], | ||
| resolveSupport: { | ||
| properties: [ | ||
| "documentation", | ||
| "detail", | ||
| "additionalTextEdits", | ||
| ], | ||
| }, | ||
| }, | ||
@@ -424,5 +433,6 @@ contextSupport: true, | ||
| const target = canonical_uri(uri); | ||
| const model = this.monaco.editor | ||
| .getModels() | ||
| .find((m) => normalize_uri(model_uri(m)) === normalize_uri(uri)); | ||
| .find((m) => canonical_uri(model_uri(m)) === target); | ||
| if (!model) return; | ||
@@ -658,2 +668,44 @@ | ||
| }, | ||
| async resolveCompletionItem(item) { | ||
| const conn = getConn(); | ||
| const raw = (item as { __lsp_item?: Record<string, unknown> }) | ||
| .__lsp_item; | ||
| if (!conn?.initialized || !raw) return item; | ||
| try { | ||
| const resolved = (await send_request( | ||
| conn, | ||
| CompletionResolveRequest.type.method, | ||
| raw, | ||
| )) as Record<string, unknown> | null; | ||
| if (!resolved) return item; | ||
| const edits = resolved.additionalTextEdits as | ||
| | Array<{ | ||
| range: { | ||
| start: { line: number; character: number }; | ||
| end: { line: number; character: number }; | ||
| }; | ||
| newText: string; | ||
| }> | ||
| | undefined; | ||
| if (edits?.length) { | ||
| item.additionalTextEdits = edits.map((e) => ({ | ||
| range: to_monaco_range(e.range), | ||
| text: e.newText, | ||
| })); | ||
| } | ||
| if (resolved.detail) item.detail = resolved.detail as string; | ||
| if (resolved.documentation) { | ||
| item.documentation = { | ||
| value: | ||
| typeof resolved.documentation === "string" | ||
| ? resolved.documentation | ||
| : ((resolved.documentation as { value?: string }).value ?? | ||
| ""), | ||
| }; | ||
| } | ||
| } catch { | ||
| /* keep the unresolved item */ | ||
| } | ||
| return item; | ||
| }, | ||
| }), | ||
@@ -660,0 +712,0 @@ ); |
+39
-1
@@ -39,2 +39,18 @@ import type * as monaco from "monaco-editor"; | ||
| // Canonical form for comparing two file URIs that may differ only in | ||
| // percent-encoding. The relay client emits unencoded URIs (path_to_uri does no | ||
| // escaping) while language servers route through vscode-uri, which escapes | ||
| // spaces and other reserved characters (e.g. "My Project" → "My%20Project"). | ||
| // Without decoding, the reverse match used to route server-pushed diagnostics | ||
| // back to a model fails for any workspace path containing such characters. | ||
| export function canonical_uri(uri: string): string { | ||
| let decoded = uri; | ||
| try { | ||
| decoded = decodeURIComponent(uri); | ||
| } catch { | ||
| /* malformed escape — fall back to the raw string */ | ||
| } | ||
| return normalize_uri(decoded); | ||
| } | ||
| export function to_lsp_position( | ||
@@ -93,2 +109,10 @@ pos: monaco.Position, | ||
| // Auto-import / additional edits. tsserver usually supplies these lazily via | ||
| // completionItem/resolve, but honour them here too in case a server is eager. | ||
| const additionalTextEdits = item.additionalTextEdits as | ||
| | Array<{ range: { start: { line: number; character: number }; end: { line: number; character: number } }; newText: string }> | ||
| | undefined; | ||
| const command = item.command as { id?: string; command?: string; title?: string; arguments?: unknown[] } | undefined; | ||
| return { | ||
@@ -115,3 +139,17 @@ label: item.label as string, | ||
| tags: item.deprecated ? [1] : undefined, | ||
| }; | ||
| additionalTextEdits: additionalTextEdits?.map((e) => ({ | ||
| range: to_monaco_range(e.range), | ||
| text: e.newText, | ||
| })), | ||
| command: command | ||
| ? { | ||
| id: (command.command ?? command.id) as string, | ||
| title: command.title ?? "", | ||
| arguments: command.arguments as unknown[] | undefined, | ||
| } | ||
| : undefined, | ||
| // Retained so resolveCompletionItem can round-trip the original LSP item | ||
| // back to the server (needed for tsserver's lazy auto-import edits). | ||
| __lsp_item: item, | ||
| } as monaco.languages.CompletionItem; | ||
| } | ||
@@ -118,0 +156,0 @@ |
-56
| { | ||
| "lockfileVersion": 1, | ||
| "configVersion": 1, | ||
| "workspaces": { | ||
| "": { | ||
| "name": "@ridit/relay", | ||
| "dependencies": { | ||
| "@ridit/relay": "^0.1.1", | ||
| "vscode-languageserver-protocol": "^3.17.5", | ||
| "vscode-ws-jsonrpc": "^3.5.0", | ||
| "ws": "^8.18.0", | ||
| }, | ||
| "devDependencies": { | ||
| "@types/bun": "latest", | ||
| "@types/ws": "^8.18.1", | ||
| "monaco-editor": ">=0.30.0", | ||
| "typescript": "^5", | ||
| }, | ||
| }, | ||
| }, | ||
| "packages": { | ||
| "@ridit/relay": ["@ridit/relay@0.1.1", "", { "dependencies": { "vscode-languageserver-protocol": "^3.17.5", "vscode-ws-jsonrpc": "^3.5.0", "ws": "^8.18.0" }, "peerDependencies": { "monaco-editor": ">=0.30.0" }, "optionalPeers": ["monaco-editor"] }, "sha512-dA+T53aR8eHGP40BY/urQc3wdxLksJAjDlEDkKh1qKSggeF72iOoPnZKu2YbpJ54D1ES1BYM8F44tFJjdrSo2Q=="], | ||
| "@types/bun": ["@types/bun@1.3.10", "", { "dependencies": { "bun-types": "1.3.10" } }, "sha512-0+rlrUrOrTSskibryHbvQkDOWRJwJZqZlxrUs1u4oOoTln8+WIXBPmAuCF35SWB2z4Zl3E84Nl/D0P7803nigQ=="], | ||
| "@types/node": ["@types/node@25.4.0", "", { "dependencies": { "undici-types": "~7.18.0" } }, "sha512-9wLpoeWuBlcbBpOY3XmzSTG3oscB6xjBEEtn+pYXTfhyXhIxC5FsBer2KTopBlvKEiW9l13po9fq+SJY/5lkhw=="], | ||
| "@types/trusted-types": ["@types/trusted-types@2.0.7", "", {}, "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw=="], | ||
| "@types/ws": ["@types/ws@8.18.1", "", { "dependencies": { "@types/node": "*" } }, "sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg=="], | ||
| "bun-types": ["bun-types@1.3.10", "", { "dependencies": { "@types/node": "*" } }, "sha512-tcpfCCl6XWo6nCVnpcVrxQ+9AYN1iqMIzgrSKYMB/fjLtV2eyAVEg7AxQJuCq/26R6HpKWykQXuSOq/21RYcbg=="], | ||
| "dompurify": ["dompurify@3.2.7", "", { "optionalDependencies": { "@types/trusted-types": "^2.0.7" } }, "sha512-WhL/YuveyGXJaerVlMYGWhvQswa7myDG17P7Vu65EWC05o8vfeNbvNf4d/BOvH99+ZW+LlQsc1GDKMa1vNK6dw=="], | ||
| "marked": ["marked@14.0.0", "", { "bin": { "marked": "bin/marked.js" } }, "sha512-uIj4+faQ+MgHgwUW1l2PsPglZLOLOT1uErt06dAPtx2kjteLAkbsd/0FiYg/MGS+i7ZKLb7w2WClxHkzOOuryQ=="], | ||
| "monaco-editor": ["monaco-editor@0.55.1", "", { "dependencies": { "dompurify": "3.2.7", "marked": "14.0.0" } }, "sha512-jz4x+TJNFHwHtwuV9vA9rMujcZRb0CEilTEwG2rRSpe/A7Jdkuj8xPKttCgOh+v/lkHy7HsZ64oj+q3xoAFl9A=="], | ||
| "typescript": ["typescript@5.9.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw=="], | ||
| "undici-types": ["undici-types@7.18.2", "", {}, "sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w=="], | ||
| "vscode-jsonrpc": ["vscode-jsonrpc@8.2.0", "", {}, "sha512-C+r0eKJUIfiDIfwJhria30+TYWPtuHJXHtI7J0YlOmKAo7ogxP20T0zxB7HZQIFhIyvoBPwWskjxrvAtfjyZfA=="], | ||
| "vscode-languageserver-protocol": ["vscode-languageserver-protocol@3.17.5", "", { "dependencies": { "vscode-jsonrpc": "8.2.0", "vscode-languageserver-types": "3.17.5" } }, "sha512-mb1bvRJN8SVznADSGWM9u/b07H7Ecg0I3OgXDuLdn307rl/J3A9YD6/eYOssqhecL27hK1IPZAsaqh00i/Jljg=="], | ||
| "vscode-languageserver-types": ["vscode-languageserver-types@3.17.5", "", {}, "sha512-Ld1VelNuX9pdF39h2Hgaeb5hEZM2Z3jUrrMgWQAu82jMtZp7p3vJT3BzToKtZI7NgQssZje5o0zryOrhQvzQAg=="], | ||
| "vscode-ws-jsonrpc": ["vscode-ws-jsonrpc@3.5.0", "", { "dependencies": { "vscode-jsonrpc": "~8.2.1" } }, "sha512-13ZDy7Od4AfEPK2HIfY3DtyRi4FVsvFql1yobVJrpIoHOKGGJpIjVvIJpMxkrHzCZzWlYlg+WEu2hrYkCTvM0Q=="], | ||
| "ws": ["ws@8.19.0", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": ">=5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-blAT2mjOEIi0ZzruJfIhb3nps74PRWTCz1IjglWEEpQl5XS/UNama6u2/rjFkDDouqr4L67ry+1aGIALViWjDg=="], | ||
| "vscode-ws-jsonrpc/vscode-jsonrpc": ["vscode-jsonrpc@8.2.1", "", {}, "sha512-kdjOSJ2lLIn7r1rtrMbbNCHjyMPfRnowdKjBQ+mGq6NAW5QY2bEZC/khaC5OR8svbbjvLEaIXkOq45e2X9BIbQ=="], | ||
| } | ||
| } |
2695
3.34%101628
-0.41%20
-4.76%