Big News: Socket raises $60M Series C at a $1B valuation to secure software supply chains for AI-driven development.Announcement
Sign In

@ridit/relay

Package Overview
Dependencies
Maintainers
1
Versions
6
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@ridit/relay - npm Package Compare versions

Comparing version
0.1.1
to
0.1.2
+52
examples/bun.lock
{
"lockfileVersion": 1,
"configVersion": 1,
"workspaces": {
"": {
"name": "examples",
"dependencies": {
"@ridit/relay": "^0.1.1",
"monaco-editor": "^0.55.1",
},
"devDependencies": {
"@types/bun": "latest",
},
"peerDependencies": {
"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=="],
"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=="],
}
}
{
"name": "examples",
"module": "index.ts",
"type": "module",
"private": true,
"devDependencies": {
"@types/bun": "latest"
},
"peerDependencies": {
"typescript": "^5"
},
"dependencies": {
"@ridit/relay": "^0.1.1",
"monaco-editor": "^0.55.1"
}
}
import { Server } from "@ridit/relay";
const server = new Server();
server.register({
command:
"C:\\Users\\Time Machine\\AppData\\Roaming\\npm\\pyright-langserver.cmd", // use your own path
languageId: "python",
args: ["--stdio"],
});
server.start();
{
"compilerOptions": {
// Environment setup & latest features
"lib": ["ESNext"],
"target": "ESNext",
"module": "Preserve",
"moduleDetection": "force",
"jsx": "react-jsx",
"allowJs": true,
// Bundler mode
"moduleResolution": "bundler",
"allowImportingTsExtensions": true,
"verbatimModuleSyntax": true,
"noEmit": true,
// Best practices
"strict": true,
"skipLibCheck": true,
"noFallthroughCasesInSwitch": true,
"noUncheckedIndexedAccess": true,
"noImplicitOverride": true,
// Some stricter flags (disabled by default)
"noUnusedLocals": false,
"noUnusedParameters": false,
"noPropertyAccessFromIndexSignature": false
}
}
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>web-example</title>
</head>
<body>
<div id="app" style="height: 100vh; width: 100%"></div>
<script type="module" src="/src/main.ts"></script>
</body>
</html>
{
"name": "web-example",
"version": "0.0.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "web-example",
"version": "0.0.0",
"dependencies": {
"vite-plugin-monaco-editor": "^1.1.0"
},
"devDependencies": {
"typescript": "~5.9.3",
"vite": "^7.3.1"
}
},
"node_modules/@esbuild/aix-ppc64": {
"version": "0.27.3",
"resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.3.tgz",
"integrity": "sha512-9fJMTNFTWZMh5qwrBItuziu834eOCUcEqymSH7pY+zoMVEZg3gcPuBNxH1EvfVYe9h0x/Ptw8KBzv7qxb7l8dg==",
"cpu": [
"ppc64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"aix"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/android-arm": {
"version": "0.27.3",
"resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.27.3.tgz",
"integrity": "sha512-i5D1hPY7GIQmXlXhs2w8AWHhenb00+GxjxRncS2ZM7YNVGNfaMxgzSGuO8o8SJzRc/oZwU2bcScvVERk03QhzA==",
"cpu": [
"arm"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"android"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/android-arm64": {
"version": "0.27.3",
"resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.27.3.tgz",
"integrity": "sha512-YdghPYUmj/FX2SYKJ0OZxf+iaKgMsKHVPF1MAq/P8WirnSpCStzKJFjOjzsW0QQ7oIAiccHdcqjbHmJxRb/dmg==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"android"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/android-x64": {
"version": "0.27.3",
"resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.27.3.tgz",
"integrity": "sha512-IN/0BNTkHtk8lkOM8JWAYFg4ORxBkZQf9zXiEOfERX/CzxW3Vg1ewAhU7QSWQpVIzTW+b8Xy+lGzdYXV6UZObQ==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"android"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/darwin-arm64": {
"version": "0.27.3",
"resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.27.3.tgz",
"integrity": "sha512-Re491k7ByTVRy0t3EKWajdLIr0gz2kKKfzafkth4Q8A5n1xTHrkqZgLLjFEHVD+AXdUGgQMq+Godfq45mGpCKg==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"darwin"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/darwin-x64": {
"version": "0.27.3",
"resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.27.3.tgz",
"integrity": "sha512-vHk/hA7/1AckjGzRqi6wbo+jaShzRowYip6rt6q7VYEDX4LEy1pZfDpdxCBnGtl+A5zq8iXDcyuxwtv3hNtHFg==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"darwin"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/freebsd-arm64": {
"version": "0.27.3",
"resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.27.3.tgz",
"integrity": "sha512-ipTYM2fjt3kQAYOvo6vcxJx3nBYAzPjgTCk7QEgZG8AUO3ydUhvelmhrbOheMnGOlaSFUoHXB6un+A7q4ygY9w==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"freebsd"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/freebsd-x64": {
"version": "0.27.3",
"resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.27.3.tgz",
"integrity": "sha512-dDk0X87T7mI6U3K9VjWtHOXqwAMJBNN2r7bejDsc+j03SEjtD9HrOl8gVFByeM0aJksoUuUVU9TBaZa2rgj0oA==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"freebsd"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/linux-arm": {
"version": "0.27.3",
"resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.27.3.tgz",
"integrity": "sha512-s6nPv2QkSupJwLYyfS+gwdirm0ukyTFNl3KTgZEAiJDd+iHZcbTPPcWCcRYH+WlNbwChgH2QkE9NSlNrMT8Gfw==",
"cpu": [
"arm"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/linux-arm64": {
"version": "0.27.3",
"resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.27.3.tgz",
"integrity": "sha512-sZOuFz/xWnZ4KH3YfFrKCf1WyPZHakVzTiqji3WDc0BCl2kBwiJLCXpzLzUBLgmp4veFZdvN5ChW4Eq/8Fc2Fg==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/linux-ia32": {
"version": "0.27.3",
"resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.27.3.tgz",
"integrity": "sha512-yGlQYjdxtLdh0a3jHjuwOrxQjOZYD/C9PfdbgJJF3TIZWnm/tMd/RcNiLngiu4iwcBAOezdnSLAwQDPqTmtTYg==",
"cpu": [
"ia32"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/linux-loong64": {
"version": "0.27.3",
"resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.27.3.tgz",
"integrity": "sha512-WO60Sn8ly3gtzhyjATDgieJNet/KqsDlX5nRC5Y3oTFcS1l0KWba+SEa9Ja1GfDqSF1z6hif/SkpQJbL63cgOA==",
"cpu": [
"loong64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/linux-mips64el": {
"version": "0.27.3",
"resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.27.3.tgz",
"integrity": "sha512-APsymYA6sGcZ4pD6k+UxbDjOFSvPWyZhjaiPyl/f79xKxwTnrn5QUnXR5prvetuaSMsb4jgeHewIDCIWljrSxw==",
"cpu": [
"mips64el"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/linux-ppc64": {
"version": "0.27.3",
"resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.27.3.tgz",
"integrity": "sha512-eizBnTeBefojtDb9nSh4vvVQ3V9Qf9Df01PfawPcRzJH4gFSgrObw+LveUyDoKU3kxi5+9RJTCWlj4FjYXVPEA==",
"cpu": [
"ppc64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/linux-riscv64": {
"version": "0.27.3",
"resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.27.3.tgz",
"integrity": "sha512-3Emwh0r5wmfm3ssTWRQSyVhbOHvqegUDRd0WhmXKX2mkHJe1SFCMJhagUleMq+Uci34wLSipf8Lagt4LlpRFWQ==",
"cpu": [
"riscv64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/linux-s390x": {
"version": "0.27.3",
"resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.27.3.tgz",
"integrity": "sha512-pBHUx9LzXWBc7MFIEEL0yD/ZVtNgLytvx60gES28GcWMqil8ElCYR4kvbV2BDqsHOvVDRrOxGySBM9Fcv744hw==",
"cpu": [
"s390x"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/linux-x64": {
"version": "0.27.3",
"resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.27.3.tgz",
"integrity": "sha512-Czi8yzXUWIQYAtL/2y6vogER8pvcsOsk5cpwL4Gk5nJqH5UZiVByIY8Eorm5R13gq+DQKYg0+JyQoytLQas4dA==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/netbsd-arm64": {
"version": "0.27.3",
"resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.27.3.tgz",
"integrity": "sha512-sDpk0RgmTCR/5HguIZa9n9u+HVKf40fbEUt+iTzSnCaGvY9kFP0YKBWZtJaraonFnqef5SlJ8/TiPAxzyS+UoA==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"netbsd"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/netbsd-x64": {
"version": "0.27.3",
"resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.27.3.tgz",
"integrity": "sha512-P14lFKJl/DdaE00LItAukUdZO5iqNH7+PjoBm+fLQjtxfcfFE20Xf5CrLsmZdq5LFFZzb5JMZ9grUwvtVYzjiA==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"netbsd"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/openbsd-arm64": {
"version": "0.27.3",
"resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.27.3.tgz",
"integrity": "sha512-AIcMP77AvirGbRl/UZFTq5hjXK+2wC7qFRGoHSDrZ5v5b8DK/GYpXW3CPRL53NkvDqb9D+alBiC/dV0Fb7eJcw==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"openbsd"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/openbsd-x64": {
"version": "0.27.3",
"resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.27.3.tgz",
"integrity": "sha512-DnW2sRrBzA+YnE70LKqnM3P+z8vehfJWHXECbwBmH/CU51z6FiqTQTHFenPlHmo3a8UgpLyH3PT+87OViOh1AQ==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"openbsd"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/openharmony-arm64": {
"version": "0.27.3",
"resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.27.3.tgz",
"integrity": "sha512-NinAEgr/etERPTsZJ7aEZQvvg/A6IsZG/LgZy+81wON2huV7SrK3e63dU0XhyZP4RKGyTm7aOgmQk0bGp0fy2g==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"openharmony"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/sunos-x64": {
"version": "0.27.3",
"resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.27.3.tgz",
"integrity": "sha512-PanZ+nEz+eWoBJ8/f8HKxTTD172SKwdXebZ0ndd953gt1HRBbhMsaNqjTyYLGLPdoWHy4zLU7bDVJztF5f3BHA==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"sunos"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/win32-arm64": {
"version": "0.27.3",
"resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.27.3.tgz",
"integrity": "sha512-B2t59lWWYrbRDw/tjiWOuzSsFh1Y/E95ofKz7rIVYSQkUYBjfSgf6oeYPNWHToFRr2zx52JKApIcAS/D5TUBnA==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"win32"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/win32-ia32": {
"version": "0.27.3",
"resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.27.3.tgz",
"integrity": "sha512-QLKSFeXNS8+tHW7tZpMtjlNb7HKau0QDpwm49u0vUp9y1WOF+PEzkU84y9GqYaAVW8aH8f3GcBck26jh54cX4Q==",
"cpu": [
"ia32"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"win32"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/win32-x64": {
"version": "0.27.3",
"resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.27.3.tgz",
"integrity": "sha512-4uJGhsxuptu3OcpVAzli+/gWusVGwZZHTlS63hh++ehExkVT8SgiEf7/uC/PclrPPkLhZqGgCTjd0VWLo6xMqA==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"win32"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@rollup/rollup-android-arm-eabi": {
"version": "4.59.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.59.0.tgz",
"integrity": "sha512-upnNBkA6ZH2VKGcBj9Fyl9IGNPULcjXRlg0LLeaioQWueH30p6IXtJEbKAgvyv+mJaMxSm1l6xwDXYjpEMiLMg==",
"cpu": [
"arm"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"android"
]
},
"node_modules/@rollup/rollup-android-arm64": {
"version": "4.59.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.59.0.tgz",
"integrity": "sha512-hZ+Zxj3SySm4A/DylsDKZAeVg0mvi++0PYVceVyX7hemkw7OreKdCvW2oQ3T1FMZvCaQXqOTHb8qmBShoqk69Q==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"android"
]
},
"node_modules/@rollup/rollup-darwin-arm64": {
"version": "4.59.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.59.0.tgz",
"integrity": "sha512-W2Psnbh1J8ZJw0xKAd8zdNgF9HRLkdWwwdWqubSVk0pUuQkoHnv7rx4GiF9rT4t5DIZGAsConRE3AxCdJ4m8rg==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"darwin"
]
},
"node_modules/@rollup/rollup-darwin-x64": {
"version": "4.59.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.59.0.tgz",
"integrity": "sha512-ZW2KkwlS4lwTv7ZVsYDiARfFCnSGhzYPdiOU4IM2fDbL+QGlyAbjgSFuqNRbSthybLbIJ915UtZBtmuLrQAT/w==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"darwin"
]
},
"node_modules/@rollup/rollup-freebsd-arm64": {
"version": "4.59.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.59.0.tgz",
"integrity": "sha512-EsKaJ5ytAu9jI3lonzn3BgG8iRBjV4LxZexygcQbpiU0wU0ATxhNVEpXKfUa0pS05gTcSDMKpn3Sx+QB9RlTTA==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"freebsd"
]
},
"node_modules/@rollup/rollup-freebsd-x64": {
"version": "4.59.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.59.0.tgz",
"integrity": "sha512-d3DuZi2KzTMjImrxoHIAODUZYoUUMsuUiY4SRRcJy6NJoZ6iIqWnJu9IScV9jXysyGMVuW+KNzZvBLOcpdl3Vg==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"freebsd"
]
},
"node_modules/@rollup/rollup-linux-arm-gnueabihf": {
"version": "4.59.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.59.0.tgz",
"integrity": "sha512-t4ONHboXi/3E0rT6OZl1pKbl2Vgxf9vJfWgmUoCEVQVxhW6Cw/c8I6hbbu7DAvgp82RKiH7TpLwxnJeKv2pbsw==",
"cpu": [
"arm"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
]
},
"node_modules/@rollup/rollup-linux-arm-musleabihf": {
"version": "4.59.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.59.0.tgz",
"integrity": "sha512-CikFT7aYPA2ufMD086cVORBYGHffBo4K8MQ4uPS/ZnY54GKj36i196u8U+aDVT2LX4eSMbyHtyOh7D7Zvk2VvA==",
"cpu": [
"arm"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
]
},
"node_modules/@rollup/rollup-linux-arm64-gnu": {
"version": "4.59.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.59.0.tgz",
"integrity": "sha512-jYgUGk5aLd1nUb1CtQ8E+t5JhLc9x5WdBKew9ZgAXg7DBk0ZHErLHdXM24rfX+bKrFe+Xp5YuJo54I5HFjGDAA==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
]
},
"node_modules/@rollup/rollup-linux-arm64-musl": {
"version": "4.59.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.59.0.tgz",
"integrity": "sha512-peZRVEdnFWZ5Bh2KeumKG9ty7aCXzzEsHShOZEFiCQlDEepP1dpUl/SrUNXNg13UmZl+gzVDPsiCwnV1uI0RUA==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
]
},
"node_modules/@rollup/rollup-linux-loong64-gnu": {
"version": "4.59.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.59.0.tgz",
"integrity": "sha512-gbUSW/97f7+r4gHy3Jlup8zDG190AuodsWnNiXErp9mT90iCy9NKKU0Xwx5k8VlRAIV2uU9CsMnEFg/xXaOfXg==",
"cpu": [
"loong64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
]
},
"node_modules/@rollup/rollup-linux-loong64-musl": {
"version": "4.59.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.59.0.tgz",
"integrity": "sha512-yTRONe79E+o0FWFijasoTjtzG9EBedFXJMl888NBEDCDV9I2wGbFFfJQQe63OijbFCUZqxpHz1GzpbtSFikJ4Q==",
"cpu": [
"loong64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
]
},
"node_modules/@rollup/rollup-linux-ppc64-gnu": {
"version": "4.59.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.59.0.tgz",
"integrity": "sha512-sw1o3tfyk12k3OEpRddF68a1unZ5VCN7zoTNtSn2KndUE+ea3m3ROOKRCZxEpmT9nsGnogpFP9x6mnLTCaoLkA==",
"cpu": [
"ppc64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
]
},
"node_modules/@rollup/rollup-linux-ppc64-musl": {
"version": "4.59.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.59.0.tgz",
"integrity": "sha512-+2kLtQ4xT3AiIxkzFVFXfsmlZiG5FXYW7ZyIIvGA7Bdeuh9Z0aN4hVyXS/G1E9bTP/vqszNIN/pUKCk/BTHsKA==",
"cpu": [
"ppc64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
]
},
"node_modules/@rollup/rollup-linux-riscv64-gnu": {
"version": "4.59.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.59.0.tgz",
"integrity": "sha512-NDYMpsXYJJaj+I7UdwIuHHNxXZ/b/N2hR15NyH3m2qAtb/hHPA4g4SuuvrdxetTdndfj9b1WOmy73kcPRoERUg==",
"cpu": [
"riscv64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
]
},
"node_modules/@rollup/rollup-linux-riscv64-musl": {
"version": "4.59.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.59.0.tgz",
"integrity": "sha512-nLckB8WOqHIf1bhymk+oHxvM9D3tyPndZH8i8+35p/1YiVoVswPid2yLzgX7ZJP0KQvnkhM4H6QZ5m0LzbyIAg==",
"cpu": [
"riscv64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
]
},
"node_modules/@rollup/rollup-linux-s390x-gnu": {
"version": "4.59.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.59.0.tgz",
"integrity": "sha512-oF87Ie3uAIvORFBpwnCvUzdeYUqi2wY6jRFWJAy1qus/udHFYIkplYRW+wo+GRUP4sKzYdmE1Y3+rY5Gc4ZO+w==",
"cpu": [
"s390x"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
]
},
"node_modules/@rollup/rollup-linux-x64-gnu": {
"version": "4.59.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.59.0.tgz",
"integrity": "sha512-3AHmtQq/ppNuUspKAlvA8HtLybkDflkMuLK4DPo77DfthRb71V84/c4MlWJXixZz4uruIH4uaa07IqoAkG64fg==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
]
},
"node_modules/@rollup/rollup-linux-x64-musl": {
"version": "4.59.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.59.0.tgz",
"integrity": "sha512-2UdiwS/9cTAx7qIUZB/fWtToJwvt0Vbo0zmnYt7ED35KPg13Q0ym1g442THLC7VyI6JfYTP4PiSOWyoMdV2/xg==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
]
},
"node_modules/@rollup/rollup-openbsd-x64": {
"version": "4.59.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.59.0.tgz",
"integrity": "sha512-M3bLRAVk6GOwFlPTIxVBSYKUaqfLrn8l0psKinkCFxl4lQvOSz8ZrKDz2gxcBwHFpci0B6rttydI4IpS4IS/jQ==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"openbsd"
]
},
"node_modules/@rollup/rollup-openharmony-arm64": {
"version": "4.59.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.59.0.tgz",
"integrity": "sha512-tt9KBJqaqp5i5HUZzoafHZX8b5Q2Fe7UjYERADll83O4fGqJ49O1FsL6LpdzVFQcpwvnyd0i+K/VSwu/o/nWlA==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"openharmony"
]
},
"node_modules/@rollup/rollup-win32-arm64-msvc": {
"version": "4.59.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.59.0.tgz",
"integrity": "sha512-V5B6mG7OrGTwnxaNUzZTDTjDS7F75PO1ae6MJYdiMu60sq0CqN5CVeVsbhPxalupvTX8gXVSU9gq+Rx1/hvu6A==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"win32"
]
},
"node_modules/@rollup/rollup-win32-ia32-msvc": {
"version": "4.59.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.59.0.tgz",
"integrity": "sha512-UKFMHPuM9R0iBegwzKF4y0C4J9u8C6MEJgFuXTBerMk7EJ92GFVFYBfOZaSGLu6COf7FxpQNqhNS4c4icUPqxA==",
"cpu": [
"ia32"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"win32"
]
},
"node_modules/@rollup/rollup-win32-x64-gnu": {
"version": "4.59.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.59.0.tgz",
"integrity": "sha512-laBkYlSS1n2L8fSo1thDNGrCTQMmxjYY5G0WFWjFFYZkKPjsMBsgJfGf4TLxXrF6RyhI60L8TMOjBMvXiTcxeA==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"win32"
]
},
"node_modules/@rollup/rollup-win32-x64-msvc": {
"version": "4.59.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.59.0.tgz",
"integrity": "sha512-2HRCml6OztYXyJXAvdDXPKcawukWY2GpR5/nxKp4iBgiO3wcoEGkAaqctIbZcNB6KlUQBIqt8VYkNSj2397EfA==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"win32"
]
},
"node_modules/@types/estree": {
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz",
"integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==",
"dev": true,
"license": "MIT"
},
"node_modules/@types/trusted-types": {
"version": "2.0.7",
"resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.7.tgz",
"integrity": "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==",
"license": "MIT",
"optional": true
},
"node_modules/dompurify": {
"version": "3.2.7",
"resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.2.7.tgz",
"integrity": "sha512-WhL/YuveyGXJaerVlMYGWhvQswa7myDG17P7Vu65EWC05o8vfeNbvNf4d/BOvH99+ZW+LlQsc1GDKMa1vNK6dw==",
"license": "(MPL-2.0 OR Apache-2.0)",
"optionalDependencies": {
"@types/trusted-types": "^2.0.7"
}
},
"node_modules/esbuild": {
"version": "0.27.3",
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.27.3.tgz",
"integrity": "sha512-8VwMnyGCONIs6cWue2IdpHxHnAjzxnw2Zr7MkVxB2vjmQ2ivqGFb4LEG3SMnv0Gb2F/G/2yA8zUaiL1gywDCCg==",
"dev": true,
"hasInstallScript": true,
"license": "MIT",
"bin": {
"esbuild": "bin/esbuild"
},
"engines": {
"node": ">=18"
},
"optionalDependencies": {
"@esbuild/aix-ppc64": "0.27.3",
"@esbuild/android-arm": "0.27.3",
"@esbuild/android-arm64": "0.27.3",
"@esbuild/android-x64": "0.27.3",
"@esbuild/darwin-arm64": "0.27.3",
"@esbuild/darwin-x64": "0.27.3",
"@esbuild/freebsd-arm64": "0.27.3",
"@esbuild/freebsd-x64": "0.27.3",
"@esbuild/linux-arm": "0.27.3",
"@esbuild/linux-arm64": "0.27.3",
"@esbuild/linux-ia32": "0.27.3",
"@esbuild/linux-loong64": "0.27.3",
"@esbuild/linux-mips64el": "0.27.3",
"@esbuild/linux-ppc64": "0.27.3",
"@esbuild/linux-riscv64": "0.27.3",
"@esbuild/linux-s390x": "0.27.3",
"@esbuild/linux-x64": "0.27.3",
"@esbuild/netbsd-arm64": "0.27.3",
"@esbuild/netbsd-x64": "0.27.3",
"@esbuild/openbsd-arm64": "0.27.3",
"@esbuild/openbsd-x64": "0.27.3",
"@esbuild/openharmony-arm64": "0.27.3",
"@esbuild/sunos-x64": "0.27.3",
"@esbuild/win32-arm64": "0.27.3",
"@esbuild/win32-ia32": "0.27.3",
"@esbuild/win32-x64": "0.27.3"
}
},
"node_modules/fdir": {
"version": "6.5.0",
"resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz",
"integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=12.0.0"
},
"peerDependencies": {
"picomatch": "^3 || ^4"
},
"peerDependenciesMeta": {
"picomatch": {
"optional": true
}
}
},
"node_modules/fsevents": {
"version": "2.3.3",
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
"integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
"dev": true,
"hasInstallScript": true,
"license": "MIT",
"optional": true,
"os": [
"darwin"
],
"engines": {
"node": "^8.16.0 || ^10.6.0 || >=11.0.0"
}
},
"node_modules/marked": {
"version": "14.0.0",
"resolved": "https://registry.npmjs.org/marked/-/marked-14.0.0.tgz",
"integrity": "sha512-uIj4+faQ+MgHgwUW1l2PsPglZLOLOT1uErt06dAPtx2kjteLAkbsd/0FiYg/MGS+i7ZKLb7w2WClxHkzOOuryQ==",
"license": "MIT",
"bin": {
"marked": "bin/marked.js"
},
"engines": {
"node": ">= 18"
}
},
"node_modules/monaco-editor": {
"version": "0.55.1",
"resolved": "https://registry.npmjs.org/monaco-editor/-/monaco-editor-0.55.1.tgz",
"integrity": "sha512-jz4x+TJNFHwHtwuV9vA9rMujcZRb0CEilTEwG2rRSpe/A7Jdkuj8xPKttCgOh+v/lkHy7HsZ64oj+q3xoAFl9A==",
"license": "MIT",
"peer": true,
"dependencies": {
"dompurify": "3.2.7",
"marked": "14.0.0"
}
},
"node_modules/nanoid": {
"version": "3.3.11",
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz",
"integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==",
"dev": true,
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/ai"
}
],
"license": "MIT",
"bin": {
"nanoid": "bin/nanoid.cjs"
},
"engines": {
"node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
}
},
"node_modules/picocolors": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
"integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==",
"dev": true,
"license": "ISC"
},
"node_modules/picomatch": {
"version": "4.0.3",
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz",
"integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==",
"dev": true,
"license": "MIT",
"peer": true,
"engines": {
"node": ">=12"
},
"funding": {
"url": "https://github.com/sponsors/jonschlinkert"
}
},
"node_modules/postcss": {
"version": "8.5.8",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.8.tgz",
"integrity": "sha512-OW/rX8O/jXnm82Ey1k44pObPtdblfiuWnrd8X7GJ7emImCOstunGbXUpp7HdBrFQX6rJzn3sPT397Wp5aCwCHg==",
"dev": true,
"funding": [
{
"type": "opencollective",
"url": "https://opencollective.com/postcss/"
},
{
"type": "tidelift",
"url": "https://tidelift.com/funding/github/npm/postcss"
},
{
"type": "github",
"url": "https://github.com/sponsors/ai"
}
],
"license": "MIT",
"dependencies": {
"nanoid": "^3.3.11",
"picocolors": "^1.1.1",
"source-map-js": "^1.2.1"
},
"engines": {
"node": "^10 || ^12 || >=14"
}
},
"node_modules/rollup": {
"version": "4.59.0",
"resolved": "https://registry.npmjs.org/rollup/-/rollup-4.59.0.tgz",
"integrity": "sha512-2oMpl67a3zCH9H79LeMcbDhXW/UmWG/y2zuqnF2jQq5uq9TbM9TVyXvA4+t+ne2IIkBdrLpAaRQAvo7YI/Yyeg==",
"dev": true,
"license": "MIT",
"dependencies": {
"@types/estree": "1.0.8"
},
"bin": {
"rollup": "dist/bin/rollup"
},
"engines": {
"node": ">=18.0.0",
"npm": ">=8.0.0"
},
"optionalDependencies": {
"@rollup/rollup-android-arm-eabi": "4.59.0",
"@rollup/rollup-android-arm64": "4.59.0",
"@rollup/rollup-darwin-arm64": "4.59.0",
"@rollup/rollup-darwin-x64": "4.59.0",
"@rollup/rollup-freebsd-arm64": "4.59.0",
"@rollup/rollup-freebsd-x64": "4.59.0",
"@rollup/rollup-linux-arm-gnueabihf": "4.59.0",
"@rollup/rollup-linux-arm-musleabihf": "4.59.0",
"@rollup/rollup-linux-arm64-gnu": "4.59.0",
"@rollup/rollup-linux-arm64-musl": "4.59.0",
"@rollup/rollup-linux-loong64-gnu": "4.59.0",
"@rollup/rollup-linux-loong64-musl": "4.59.0",
"@rollup/rollup-linux-ppc64-gnu": "4.59.0",
"@rollup/rollup-linux-ppc64-musl": "4.59.0",
"@rollup/rollup-linux-riscv64-gnu": "4.59.0",
"@rollup/rollup-linux-riscv64-musl": "4.59.0",
"@rollup/rollup-linux-s390x-gnu": "4.59.0",
"@rollup/rollup-linux-x64-gnu": "4.59.0",
"@rollup/rollup-linux-x64-musl": "4.59.0",
"@rollup/rollup-openbsd-x64": "4.59.0",
"@rollup/rollup-openharmony-arm64": "4.59.0",
"@rollup/rollup-win32-arm64-msvc": "4.59.0",
"@rollup/rollup-win32-ia32-msvc": "4.59.0",
"@rollup/rollup-win32-x64-gnu": "4.59.0",
"@rollup/rollup-win32-x64-msvc": "4.59.0",
"fsevents": "~2.3.2"
}
},
"node_modules/source-map-js": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
"integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==",
"dev": true,
"license": "BSD-3-Clause",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/tinyglobby": {
"version": "0.2.15",
"resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz",
"integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"fdir": "^6.5.0",
"picomatch": "^4.0.3"
},
"engines": {
"node": ">=12.0.0"
},
"funding": {
"url": "https://github.com/sponsors/SuperchupuDev"
}
},
"node_modules/typescript": {
"version": "5.9.3",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz",
"integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==",
"dev": true,
"license": "Apache-2.0",
"bin": {
"tsc": "bin/tsc",
"tsserver": "bin/tsserver"
},
"engines": {
"node": ">=14.17"
}
},
"node_modules/vite": {
"version": "7.3.1",
"resolved": "https://registry.npmjs.org/vite/-/vite-7.3.1.tgz",
"integrity": "sha512-w+N7Hifpc3gRjZ63vYBXA56dvvRlNWRczTdmCBBa+CotUzAPf5b7YMdMR/8CQoeYE5LX3W4wj6RYTgonm1b9DA==",
"dev": true,
"license": "MIT",
"dependencies": {
"esbuild": "^0.27.0",
"fdir": "^6.5.0",
"picomatch": "^4.0.3",
"postcss": "^8.5.6",
"rollup": "^4.43.0",
"tinyglobby": "^0.2.15"
},
"bin": {
"vite": "bin/vite.js"
},
"engines": {
"node": "^20.19.0 || >=22.12.0"
},
"funding": {
"url": "https://github.com/vitejs/vite?sponsor=1"
},
"optionalDependencies": {
"fsevents": "~2.3.3"
},
"peerDependencies": {
"@types/node": "^20.19.0 || >=22.12.0",
"jiti": ">=1.21.0",
"less": "^4.0.0",
"lightningcss": "^1.21.0",
"sass": "^1.70.0",
"sass-embedded": "^1.70.0",
"stylus": ">=0.54.8",
"sugarss": "^5.0.0",
"terser": "^5.16.0",
"tsx": "^4.8.1",
"yaml": "^2.4.2"
},
"peerDependenciesMeta": {
"@types/node": {
"optional": true
},
"jiti": {
"optional": true
},
"less": {
"optional": true
},
"lightningcss": {
"optional": true
},
"sass": {
"optional": true
},
"sass-embedded": {
"optional": true
},
"stylus": {
"optional": true
},
"sugarss": {
"optional": true
},
"terser": {
"optional": true
},
"tsx": {
"optional": true
},
"yaml": {
"optional": true
}
}
},
"node_modules/vite-plugin-monaco-editor": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/vite-plugin-monaco-editor/-/vite-plugin-monaco-editor-1.1.0.tgz",
"integrity": "sha512-IvtUqZotrRoVqwT0PBBDIZPNraya3BxN/bfcNfnxZ5rkJiGcNtO5eAOWWSgT7zullIAEqQwxMU83yL9J5k7gww==",
"license": "MIT",
"peerDependencies": {
"monaco-editor": ">=0.33.0"
}
}
}
}
{
"name": "web-example",
"private": true,
"version": "0.0.0",
"type": "module",
"scripts": {
"dev": "vite",
"build": "tsc && vite build",
"preview": "vite preview"
},
"devDependencies": {
"typescript": "~5.9.3",
"vite": "^7.3.1"
},
"dependencies": {
"vite-plugin-monaco-editor": "^1.1.0"
}
}
import * as monaco from "monaco-editor";
import { Client } from "../../../src/client/client";
import "monaco-editor/min/vs/editor/editor.main.css";
import "./style.css";
const el = document.querySelector<HTMLDivElement>("#app")!;
const editor = monaco.editor.create(el, {
automaticLayout: true,
fontFamily: "monospace",
});
const model = monaco.editor.createModel(
"print('hello relay')",
"python",
monaco.Uri.file("C:/workspace/test.py"),
);
editor.setModel(model);
const lspClient = new Client(monaco);
lspClient.register({ languageId: "python" });
lspClient.start("C:\\workspace");
:root {
font-family: system-ui, Avenir, Helvetica, Arial, sans-serif;
line-height: 1.5;
font-weight: 400;
color-scheme: light dark;
color: rgba(255, 255, 255, 0.87);
background-color: #242424;
font-synthesis: none;
text-rendering: optimizeLegibility;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
a {
font-weight: 500;
color: #646cff;
text-decoration: inherit;
}
a:hover {
color: #535bf2;
}
body {
margin: 0;
display: flex;
place-items: center;
min-width: 320px;
min-height: 100vh;
}
h1 {
font-size: 3.2em;
line-height: 1.1;
}
#app {
max-width: 1280px;
margin: 0 auto;
padding: 2rem;
text-align: center;
}
.logo {
height: 6em;
padding: 1.5em;
will-change: filter;
transition: filter 300ms;
}
.logo:hover {
filter: drop-shadow(0 0 2em #646cffaa);
}
.logo.vanilla:hover {
filter: drop-shadow(0 0 2em #3178c6aa);
}
.card {
padding: 2em;
}
.read-the-docs {
color: #888;
}
button {
border-radius: 8px;
border: 1px solid transparent;
padding: 0.6em 1.2em;
font-size: 1em;
font-weight: 500;
font-family: inherit;
background-color: #1a1a1a;
cursor: pointer;
transition: border-color 0.25s;
}
button:hover {
border-color: #646cff;
}
button:focus,
button:focus-visible {
outline: 4px auto -webkit-focus-ring-color;
}
@media (prefers-color-scheme: light) {
:root {
color: #213547;
background-color: #ffffff;
}
a:hover {
color: #747bff;
}
button {
background-color: #f9f9f9;
}
}
{
"compilerOptions": {
"target": "ES2022",
"useDefineForClassFields": true,
"module": "ESNext",
"lib": ["ES2022", "DOM", "DOM.Iterable"],
"types": ["vite/client"],
"skipLibCheck": true,
/* Bundler mode */
"moduleResolution": "bundler",
"allowImportingTsExtensions": true,
"verbatimModuleSyntax": true,
"moduleDetection": "force",
"noEmit": true,
/* Linting */
"strict": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"erasableSyntaxOnly": true,
"noFallthroughCasesInSwitch": true,
"noUncheckedSideEffectImports": true
},
"include": ["src"]
}
import { defineConfig } from "vite";
import monacoEditorPlugin from "vite-plugin-monaco-editor";
export default defineConfig({
plugins: [(monacoEditorPlugin as any).default({})],
});
+4
-3
{
"name": "@ridit/relay",
"version": "0.1.1",
"version": "0.1.2",
"description": "One port. Any language. Monaco-ready LSP bridge.",

@@ -9,3 +9,3 @@ "author": "Ridit Jangra <riditjangra09@gmail.com> (https://ridit.space)",

"type": "git",
"url": "https://github.com/ridit-jangra/relay"
"url": "https://github.com/ridit-jangra/Relay"
},

@@ -24,3 +24,3 @@ "module": "src/index.ts",

"prepublishOnly": "bun run typecheck",
"publish": "npm publish --access public"
"release": "npm publish --access public"
},

@@ -41,2 +41,3 @@ "devDependencies": {

"dependencies": {
"@ridit/relay": "^0.1.1",
"vscode-languageserver-protocol": "^3.17.5",

@@ -43,0 +44,0 @@ "vscode-ws-jsonrpc": "^3.5.0",

@@ -21,3 +21,2 @@ import type * as Monaco from "monaco-editor";

DocumentFormattingRequest,
DiagnosticSeverity,
} from "vscode-languageserver-protocol";

@@ -59,3 +58,6 @@ import {

function make_ready_promise(timeoutMs = 8000): { ready: Promise<void>; markReady: () => void } {
function make_ready_promise(timeoutMs = 8000): {
ready: Promise<void>;
markReady: () => void;
} {
let resolved = false;

@@ -70,7 +72,13 @@ let markReady!: () => void;

});
setTimeout(() => { if (!resolved) markReady(); }, timeoutMs);
setTimeout(() => {
if (!resolved) markReady();
}, timeoutMs);
return { ready, markReady };
}
function send_request(conn: LspConnection, method: string, params: unknown): Promise<unknown> {
function send_request(
conn: LspConnection,
method: string,
params: unknown,
): Promise<unknown> {
const id = conn.nextId++;

@@ -83,3 +91,7 @@ return new Promise((resolve, reject) => {

function send_notification(conn: LspConnection, method: string, params: unknown): void {
function send_notification(
conn: LspConnection,
method: string,
params: unknown,
): void {
conn.writer.write({ jsonrpc: "2.0", method, params } as never);

@@ -98,3 +110,6 @@ }

private model_timers = new Map<string, ReturnType<typeof setTimeout>>();
private lensEmitters = new Map<string, Monaco.Emitter<Monaco.languages.CodeLensProvider>>();
private lensEmitters = new Map<
string,
Monaco.Emitter<Monaco.languages.CodeLensProvider>
>();

@@ -132,5 +147,7 @@ /**

this.started = false;
for (const disps of this.disposables.values()) disps.forEach((d) => d.dispose());
for (const disps of this.disposables.values())
disps.forEach((d) => d.dispose());
this.disposables.clear();
for (const disps of this.model_listeners.values()) disps.forEach((d) => d.dispose());
for (const disps of this.model_listeners.values())
disps.forEach((d) => d.dispose());
this.model_listeners.clear();

@@ -153,9 +170,19 @@ for (const t of this.model_timers.values()) clearTimeout(t);

await conn.ready;
const edits = await send_request(conn, DocumentFormattingRequest.type.method, {
textDocument: { uri: normalize_uri(model_uri(model)) },
options: {
tabSize: model.getOptions().tabSize,
insertSpaces: model.getOptions().insertSpaces ?? true,
const edits = (await send_request(
conn,
DocumentFormattingRequest.type.method,
{
textDocument: { uri: normalize_uri(model_uri(model)) },
options: {
tabSize: model.getOptions().tabSize,
insertSpaces: model.getOptions().insertSpaces ?? true,
},
},
}) as Array<{ range: { start: { line: number; character: number }; end: { line: number; character: number } }; newText: string }> | null;
)) as Array<{
range: {
start: { line: number; character: number };
end: { line: number; character: number };
};
newText: string;
}> | null;
if (!edits?.length) return false;

@@ -184,2 +211,7 @@ apply_lsp_edits(model, edits);

ws.onmessage = (e) => {
const m = JSON.parse(e.data);
console.log("[raw]", JSON.stringify(m).slice(0, 300));
};
ws.onopen = async () => {

@@ -192,4 +224,10 @@ const socket = toSocket(ws);

const conn: LspConnection = {
reader, writer, nextId: 1, pending: new Map(),
initialized: false, languageId: def.languageId, ready, markReady,
reader,
writer,
nextId: 1,
pending: new Map(),
initialized: false,
languageId: def.languageId,
ready,
markReady,
};

@@ -201,7 +239,10 @@ this.connections.set(def.languageId, conn);

if (m["id"] != null && "method" in m) {
conn.writer.write({ jsonrpc: "2.0", id: m["id"], result: null } as never);
this.handle_server_request(conn, m);
return;
}
if (m["id"] != null && !("method" in m)) {
const id = typeof m["id"] === "string" ? parseInt(m["id"], 10) : m["id"] as number;
const id =
typeof m["id"] === "string"
? parseInt(m["id"], 10)
: (m["id"] as number);
const p = conn.pending.get(id);

@@ -235,3 +276,6 @@ if (p) {

completion: {
completionItem: { snippetSupport: true, documentationFormat: ["plaintext", "markdown"] },
completionItem: {
snippetSupport: true,
documentationFormat: ["plaintext", "markdown"],
},
contextSupport: true,

@@ -241,3 +285,5 @@ },

signatureHelp: {
signatureInformation: { documentationFormat: ["plaintext", "markdown"] },
signatureInformation: {
documentationFormat: ["plaintext", "markdown"],
},
},

@@ -249,3 +295,7 @@ formatting: { dynamicRegistration: false },

},
workspace: { workspaceFolders: true, workDoneProgress: true, configuration: true },
workspace: {
workspaceFolders: true,
workDoneProgress: true,
configuration: true,
},
window: { workDoneProgress: true },

@@ -278,3 +328,4 @@ },

ws.onerror = (e) => console.error(`[relay:client:${def.languageId}] ws error`, e);
ws.onerror = (e) =>
console.error(`[relay:client:${def.languageId}] ws error`, e);
ws.onclose = () => {

@@ -286,3 +337,7 @@ this.sockets.delete(def.languageId);

private bind_model(def: LspClientDefinition, conn: LspConnection, model: Monaco.editor.ITextModel): void {
private bind_model(
def: LspClientDefinition,
conn: LspConnection,
model: Monaco.editor.ITextModel,
): void {
const key = model.uri.toString();

@@ -298,9 +353,12 @@ if (this.model_listeners.has(key)) return;

if (existing) clearTimeout(existing);
this.model_timers.set(key, setTimeout(() => {
this.model_timers.delete(key);
send_notification(c, DidChangeTextDocumentNotification.type.method, {
textDocument: { uri, version: model.getVersionId() },
contentChanges: [{ text: model.getValue() }],
});
}, 150));
this.model_timers.set(
key,
setTimeout(() => {
this.model_timers.delete(key);
send_notification(c, DidChangeTextDocumentNotification.type.method, {
textDocument: { uri, version: model.getVersionId() },
contentChanges: [{ text: model.getValue() }],
});
}, 150),
);
});

@@ -312,3 +370,6 @@

const t = this.model_timers.get(key);
if (t) { clearTimeout(t); this.model_timers.delete(key); }
if (t) {
clearTimeout(t);
this.model_timers.delete(key);
}
this.model_listeners.get(key)?.forEach((d) => d.dispose());

@@ -321,6 +382,46 @@ this.model_listeners.delete(key);

private handle_notification(def: LspClientDefinition, conn: LspConnection, msg: Record<string, unknown>): void {
private handle_server_request(
conn: LspConnection,
msg: Record<string, unknown>,
): void {
const method = msg["method"] as string;
const params = msg["params"] as Record<string, unknown> | undefined;
// workspace/configuration — Pyright and other servers need real config back, not null
if (method === "workspace/configuration") {
const items = (params?.["items"] as Array<Record<string, unknown>>) ?? [];
// Return one empty config object per requested item
const result = items.map(() => ({}));
conn.writer.write({ jsonrpc: "2.0", id: msg["id"], result } as never);
return;
}
// workspace/workspaceFolders
if (method === "workspace/workspaceFolders") {
conn.writer.write({
jsonrpc: "2.0",
id: msg["id"],
result: [{ uri: this.workspaceUri, name: "workspace" }],
} as never);
return;
}
// Default: respond with null for any other server→client request
conn.writer.write({ jsonrpc: "2.0", id: msg["id"], result: null } as never);
}
private handle_notification(
def: LspClientDefinition,
conn: LspConnection,
msg: Record<string, unknown>,
): void {
if (msg["method"] === "$/progress") {
if ((msg["params"] as Record<string, unknown> | undefined)?.["value"] as Record<string, unknown> | undefined) {
const value = ((msg["params"] as Record<string, unknown>)["value"] as Record<string, unknown>);
if (
(msg["params"] as Record<string, unknown> | undefined)?.["value"] as
| Record<string, unknown>
| undefined
) {
const value = (msg["params"] as Record<string, unknown>)[
"value"
] as Record<string, unknown>;
if (value["kind"] === "end") conn.markReady();

@@ -332,13 +433,21 @@ }

if (msg["method"] === PublishDiagnosticsNotification.type.method) {
const { uri, diagnostics } = msg["params"] as { uri: string; diagnostics: Record<string, unknown>[] };
const { uri, diagnostics } = msg["params"] as {
uri: string;
diagnostics: Record<string, unknown>[];
};
conn.markReady();
const model = this.monaco.editor.getModels().find((m) =>
normalize_uri(model_uri(m)) === normalize_uri(uri)
);
const model = this.monaco.editor
.getModels()
.find((m) => normalize_uri(model_uri(m)) === normalize_uri(uri));
if (!model) return;
this.monaco.editor.setModelMarkers(model, def.languageId,
this.monaco.editor.setModelMarkers(
model,
def.languageId,
diagnostics.map((d) => {
const range = d["range"] as { start: { line: number; character: number }; end: { line: number; character: number } };
const range = d["range"] as {
start: { line: number; character: number };
end: { line: number; character: number };
};
return {

@@ -350,3 +459,6 @@ startLineNumber: range.start.line + 1,

message: d["message"] as string,
severity: lsp_severity_to_monaco(d["severity"] as DiagnosticSeverity | undefined, this.monaco),
severity: lsp_severity_to_monaco(
d["severity"] as any | undefined,
this.monaco,
),
source: d["source"] as string | undefined,

@@ -372,3 +484,6 @@ };

private did_close(conn: LspConnection, model: Monaco.editor.ITextModel): void {
private did_close(
conn: LspConnection,
model: Monaco.editor.ITextModel,
): void {
send_notification(conn, DidCloseTextDocumentNotification.type.method, {

@@ -379,7 +494,11 @@ textDocument: { uri: normalize_uri(model_uri(model)) },

private register_providers(def: LspClientDefinition, _conn: LspConnection): Monaco.IDisposable[] {
private register_providers(
def: LspClientDefinition,
_conn: LspConnection,
): Monaco.IDisposable[] {
const selector = def.languageId;
const disps: Monaco.IDisposable[] = [];
const monaco = this.monaco;
const getConn = (): LspConnection | null => this.connections.get(def.languageId) ?? null;
const getConn = (): LspConnection | null =>
this.connections.get(def.languageId) ?? null;

@@ -390,214 +509,397 @@ const emitter = new monaco.Emitter<Monaco.languages.CodeLensProvider>();

const lensDataMap = new Map<string, Map<string, { model: Monaco.editor.ITextModel; pos: { line: number; character: number } }>>();
const lensDataMap = new Map<
string,
Map<
string,
{
model: Monaco.editor.ITextModel;
pos: { line: number; character: number };
}
>
>();
// Code Lens
disps.push(monaco.languages.registerCodeLensProvider(selector, {
onDidChange: emitter.event,
async provideCodeLenses(model) {
const conn = getConn();
if (!conn?.initialized) return { lenses: [], dispose: () => {} };
await conn.ready;
const uri = normalize_uri(model_uri(model));
try {
const symbols = await send_request(conn, "textDocument/documentSymbol", { textDocument: { uri } }) as unknown[] | null;
if (!symbols) return { lenses: [], dispose: () => {} };
disps.push(
monaco.languages.registerCodeLensProvider(selector, {
onDidChange: emitter.event,
async provideCodeLenses(model) {
const conn = getConn();
if (!conn?.initialized) return { lenses: [], dispose: () => {} };
await conn.ready;
const uri = normalize_uri(model_uri(model));
try {
const symbols = (await send_request(
conn,
"textDocument/documentSymbol",
{ textDocument: { uri } },
)) as unknown[] | null;
if (!symbols) return { lenses: [], dispose: () => {} };
const fileMap = new Map<string, { model: Monaco.editor.ITextModel; pos: { line: number; character: number } }>();
lensDataMap.set(uri, fileMap);
const lenses: Monaco.languages.CodeLens[] = [];
const SYMBOL_KINDS_WITH_REFS = new Set([5, 6, 9, 12]);
const fileMap = new Map<
string,
{
model: Monaco.editor.ITextModel;
pos: { line: number; character: number };
}
>();
lensDataMap.set(uri, fileMap);
const lenses: Monaco.languages.CodeLens[] = [];
const SYMBOL_KINDS_WITH_REFS = new Set([5, 6, 9, 12]);
function collect(syms: unknown[]) {
for (const sym of syms) {
const s = sym as Record<string, unknown>;
if (SYMBOL_KINDS_WITH_REFS.has(s["kind"] as number)) {
const range = (s["range"] ?? (s["location"] as Record<string, unknown> | undefined)?.["range"]) as { start: { line: number; character: number }; end: { line: number; character: number } } | undefined;
if (!range) { if ((s["children"] as unknown[] | undefined)?.length) collect(s["children"] as unknown[]); continue; }
const pos = get_name_position(model, s);
const id = `${s["name"] as string}:${pos.line}:${pos.character}`;
fileMap.set(id, { model, pos });
const lens = { range: to_monaco_range(range) } as Monaco.languages.CodeLens;
(lens as unknown as Record<string, unknown>)["_id"] = id;
lenses.push(lens);
function collect(syms: unknown[]) {
for (const sym of syms) {
const s = sym as Record<string, unknown>;
if (SYMBOL_KINDS_WITH_REFS.has(s["kind"] as number)) {
const range = (s["range"] ??
(s["location"] as Record<string, unknown> | undefined)?.[
"range"
]) as
| {
start: { line: number; character: number };
end: { line: number; character: number };
}
| undefined;
if (!range) {
if ((s["children"] as unknown[] | undefined)?.length)
collect(s["children"] as unknown[]);
continue;
}
const pos = get_name_position(model, s);
const id = `${s["name"] as string}:${pos.line}:${pos.character}`;
fileMap.set(id, { model, pos });
const lens = {
range: to_monaco_range(range),
} as Monaco.languages.CodeLens;
(lens as unknown as Record<string, unknown>)["_id"] = id;
lenses.push(lens);
}
if ((s["children"] as unknown[] | undefined)?.length)
collect(s["children"] as unknown[]);
}
if ((s["children"] as unknown[] | undefined)?.length) collect(s["children"] as unknown[]);
}
collect(Array.isArray(symbols) ? symbols : [symbols]);
return { lenses, dispose: () => {} };
} catch (err) {
console.error("[relay:client] provideCodeLenses error", err);
return { lenses: [], dispose: () => {} };
}
},
async resolveCodeLens(model, lens) {
const conn = getConn();
const noop: Monaco.languages.Command = { id: "", title: "0 usages" };
if (!conn) {
lens.command = noop;
return lens;
}
const uri = normalize_uri(model_uri(model));
const id = (lens as unknown as Record<string, unknown>)["_id"] as
| string
| undefined;
const data = id ? lensDataMap.get(uri)?.get(id) : undefined;
if (!data) {
lens.command = noop;
return lens;
}
try {
const refs = (await send_request(
conn,
ReferencesRequest.type.method,
{
textDocument: { uri },
position: data.pos,
context: { includeDeclaration: false },
},
)) as unknown[] | null;
const count = refs?.length ?? 0;
lens.command = {
id: "editor.action.referenceSearch.trigger",
title: `${count} usage${count === 1 ? "" : "s"}`,
arguments: [
data.model.uri,
{
lineNumber: data.pos.line + 1,
column: data.pos.character + 1,
},
],
};
return lens;
} catch {
lens.command = noop;
return lens;
}
},
}),
);
collect(Array.isArray(symbols) ? symbols : [symbols]);
return { lenses, dispose: () => {} };
} catch (err) {
console.error("[relay:client] provideCodeLenses error", err);
return { lenses: [], dispose: () => {} };
}
},
async resolveCodeLens(model, lens) {
const conn = getConn();
const noop: Monaco.languages.Command = { id: "", title: "0 usages" };
if (!conn) { lens.command = noop; return lens; }
const uri = normalize_uri(model_uri(model));
const id = (lens as unknown as Record<string, unknown>)["_id"] as string | undefined;
const data = id ? lensDataMap.get(uri)?.get(id) : undefined;
if (!data) { lens.command = noop; return lens; }
try {
const refs = await send_request(conn, ReferencesRequest.type.method, {
textDocument: { uri },
position: data.pos,
context: { includeDeclaration: false },
}) as unknown[] | null;
const count = refs?.length ?? 0;
lens.command = {
id: "editor.action.referenceSearch.trigger",
title: `${count} usage${count === 1 ? "" : "s"}`,
arguments: [data.model.uri, { lineNumber: data.pos.line + 1, column: data.pos.character + 1 }],
};
return lens;
} catch { lens.command = noop; return lens; }
},
}));
// Completion
disps.push(monaco.languages.registerCompletionItemProvider(selector, {
triggerCharacters: [".", '"', "'", "`", "/", "@", "<", "#"],
async provideCompletionItems(model, position, context) {
const conn = getConn();
if (!conn?.initialized) return null;
if (model.getValue().trim().length === 0) return null;
await conn.ready;
try {
const result = await send_request(conn, CompletionRequest.type.method, {
textDocument: { uri: normalize_uri(model_uri(model)) },
position: to_lsp_position(position, model),
context: to_lsp_completion_context(context),
}) as { items?: unknown[]; isIncomplete?: boolean } | unknown[] | null;
if (!result) return null;
const items = Array.isArray(result) ? result : ((result as { items?: unknown[] }).items ?? []);
return {
suggestions: items.map((item) => lsp_completion_to_monaco(item as Record<string, unknown>, model, position, monaco)),
incomplete: (result as { isIncomplete?: boolean }).isIncomplete ?? false,
};
} catch { return null; }
},
}));
disps.push(
monaco.languages.registerCompletionItemProvider(selector, {
triggerCharacters: [".", '"', "'", "`", "/", "@", "<", "#"],
async provideCompletionItems(model, position, context) {
const conn = getConn();
if (!conn?.initialized) return null;
if (model.getValue().trim().length === 0) return null;
await conn.ready;
try {
const result = (await send_request(
conn,
CompletionRequest.type.method,
{
textDocument: { uri: normalize_uri(model_uri(model)) },
position: to_lsp_position(position, model),
context: to_lsp_completion_context(context),
},
)) as
| { items?: unknown[]; isIncomplete?: boolean }
| unknown[]
| null;
if (!result) return null;
const items = Array.isArray(result)
? result
: ((result as { items?: unknown[] }).items ?? []);
return {
suggestions: items.map((item) =>
lsp_completion_to_monaco(
item as Record<string, unknown>,
model,
position,
monaco,
),
),
incomplete:
(result as { isIncomplete?: boolean }).isIncomplete ?? false,
};
} catch {
return null;
}
},
}),
);
// Hover
disps.push(monaco.languages.registerHoverProvider(selector, {
async provideHover(model, position) {
const conn = getConn();
if (!conn?.initialized) return null;
await conn.ready;
try {
const result = await send_request(conn, HoverRequest.type.method, {
textDocument: { uri: normalize_uri(model_uri(model)) },
position: to_lsp_position(position, model),
}) as { contents: unknown; range?: { start: { line: number; character: number }; end: { line: number; character: number } } } | null;
if (!result?.contents) return null;
const contents = Array.isArray(result.contents) ? result.contents : [result.contents];
return {
contents: contents.map((c: unknown) => ({ value: typeof c === "string" ? c : ((c as { value?: string }).value ?? "") })),
range: result.range ? to_monaco_range(result.range) : undefined,
};
} catch { return null; }
},
}));
disps.push(
monaco.languages.registerHoverProvider(selector, {
async provideHover(model, position) {
const conn = getConn();
if (!conn?.initialized) return null;
await conn.ready;
try {
const result = (await send_request(conn, HoverRequest.type.method, {
textDocument: { uri: normalize_uri(model_uri(model)) },
position: to_lsp_position(position, model),
})) as {
contents: unknown;
range?: {
start: { line: number; character: number };
end: { line: number; character: number };
};
} | null;
if (!result?.contents) return null;
const contents = Array.isArray(result.contents)
? result.contents
: [result.contents];
return {
contents: contents.map((c: unknown) => ({
value:
typeof c === "string"
? c
: ((c as { value?: string }).value ?? ""),
})),
range: result.range ? to_monaco_range(result.range) : undefined,
};
} catch {
return null;
}
},
}),
);
// Signature Help
disps.push(monaco.languages.registerSignatureHelpProvider(selector, {
signatureHelpTriggerCharacters: ["(", ","],
async provideSignatureHelp(model, position) {
const conn = getConn();
if (!conn?.initialized) return null;
await conn.ready;
try {
const result = await send_request(conn, SignatureHelpRequest.type.method, {
textDocument: { uri: normalize_uri(model_uri(model)) },
position: to_lsp_position(position, model),
}) as { signatures: unknown[]; activeSignature?: number; activeParameter?: number } | null;
if (!result?.signatures?.length) return null;
return {
value: {
signatures: result.signatures.map((s: unknown) => {
const sig = s as Record<string, unknown>;
return {
label: sig["label"] as string,
documentation: sig["documentation"] ? { value: typeof sig["documentation"] === "string" ? sig["documentation"] : (sig["documentation"] as { value: string }).value } : undefined,
parameters: ((sig["parameters"] as unknown[]) ?? []).map((p: unknown) => {
const param = p as Record<string, unknown>;
return {
label: param["label"] as string,
documentation: param["documentation"] ? { value: typeof param["documentation"] === "string" ? param["documentation"] : (param["documentation"] as { value: string }).value } : undefined,
};
}),
};
}),
activeSignature: result.activeSignature ?? 0,
activeParameter: result.activeParameter ?? 0,
},
dispose: () => {},
};
} catch { return null; }
},
}));
disps.push(
monaco.languages.registerSignatureHelpProvider(selector, {
signatureHelpTriggerCharacters: ["(", ","],
async provideSignatureHelp(model, position) {
const conn = getConn();
if (!conn?.initialized) return null;
await conn.ready;
try {
const result = (await send_request(
conn,
SignatureHelpRequest.type.method,
{
textDocument: { uri: normalize_uri(model_uri(model)) },
position: to_lsp_position(position, model),
},
)) as {
signatures: unknown[];
activeSignature?: number;
activeParameter?: number;
} | null;
if (!result?.signatures?.length) return null;
return {
value: {
signatures: result.signatures.map((s: unknown) => {
const sig = s as Record<string, unknown>;
return {
label: sig["label"] as string,
documentation: sig["documentation"]
? {
value:
typeof sig["documentation"] === "string"
? sig["documentation"]
: (sig["documentation"] as { value: string })
.value,
}
: undefined,
parameters: ((sig["parameters"] as unknown[]) ?? []).map(
(p: unknown) => {
const param = p as Record<string, unknown>;
return {
label: param["label"] as string,
documentation: param["documentation"]
? {
value:
typeof param["documentation"] === "string"
? param["documentation"]
: (
param["documentation"] as {
value: string;
}
).value,
}
: undefined,
};
},
),
};
}),
activeSignature: result.activeSignature ?? 0,
activeParameter: result.activeParameter ?? 0,
},
dispose: () => {},
};
} catch {
return null;
}
},
}),
);
// Go to Definition
disps.push(monaco.languages.registerDefinitionProvider(selector, {
async provideDefinition(model, position) {
const conn = getConn();
if (!conn?.initialized) return null;
await conn.ready;
try {
const result = await send_request(conn, DefinitionRequest.type.method, {
textDocument: { uri: normalize_uri(model_uri(model)) },
position: to_lsp_position(position, model),
}) as unknown[] | null;
if (!result) return null;
const locs = Array.isArray(result) ? result : [result];
return locs.map((loc: unknown) => {
const l = loc as { uri: string; range: { start: { line: number; character: number }; end: { line: number; character: number } } };
return { uri: monaco.Uri.parse(l.uri), range: to_monaco_range(l.range) };
});
} catch { return null; }
},
}));
disps.push(
monaco.languages.registerDefinitionProvider(selector, {
async provideDefinition(model, position) {
const conn = getConn();
if (!conn?.initialized) return null;
await conn.ready;
try {
const result = (await send_request(
conn,
DefinitionRequest.type.method,
{
textDocument: { uri: normalize_uri(model_uri(model)) },
position: to_lsp_position(position, model),
},
)) as unknown[] | null;
if (!result) return null;
const locs = Array.isArray(result) ? result : [result];
return locs.map((loc: unknown) => {
const l = loc as {
uri: string;
range: {
start: { line: number; character: number };
end: { line: number; character: number };
};
};
return {
uri: monaco.Uri.parse(l.uri),
range: to_monaco_range(l.range),
};
});
} catch {
return null;
}
},
}),
);
// References
disps.push(monaco.languages.registerReferenceProvider(selector, {
async provideReferences(model, position) {
const conn = getConn();
if (!conn?.initialized) return null;
await conn.ready;
try {
const result = await send_request(conn, ReferencesRequest.type.method, {
textDocument: { uri: normalize_uri(model_uri(model)) },
position: to_lsp_position(position, model),
context: { includeDeclaration: true },
}) as unknown[] | null;
if (!result) return null;
return result.map((loc: unknown) => {
const l = loc as { uri: string; range: { start: { line: number; character: number }; end: { line: number; character: number } } };
return { uri: monaco.Uri.parse(l.uri), range: to_monaco_range(l.range) };
});
} catch { return null; }
},
}));
disps.push(
monaco.languages.registerReferenceProvider(selector, {
async provideReferences(model, position) {
const conn = getConn();
if (!conn?.initialized) return null;
await conn.ready;
try {
const result = (await send_request(
conn,
ReferencesRequest.type.method,
{
textDocument: { uri: normalize_uri(model_uri(model)) },
position: to_lsp_position(position, model),
context: { includeDeclaration: true },
},
)) as unknown[] | null;
if (!result) return null;
return result.map((loc: unknown) => {
const l = loc as {
uri: string;
range: {
start: { line: number; character: number };
end: { line: number; character: number };
};
};
return {
uri: monaco.Uri.parse(l.uri),
range: to_monaco_range(l.range),
};
});
} catch {
return null;
}
},
}),
);
// Formatting
disps.push(monaco.languages.registerDocumentFormattingEditProvider(selector, {
async provideDocumentFormattingEdits(model) {
const conn = getConn();
if (!conn?.initialized) return [];
await conn.ready;
try {
const edits = await send_request(conn, DocumentFormattingRequest.type.method, {
textDocument: { uri: normalize_uri(model_uri(model)) },
options: { tabSize: model.getOptions().tabSize, insertSpaces: model.getOptions().insertSpaces ?? true },
}) as Array<{ range: { start: { line: number; character: number }; end: { line: number; character: number } }; newText: string }> | null;
if (!edits?.length) return [];
return edits.map((e) => ({ range: to_monaco_range(e.range), text: e.newText }));
} catch (err) {
console.error("[relay:client] provideDocumentFormattingEdits error", err);
return [];
}
},
}));
disps.push(
monaco.languages.registerDocumentFormattingEditProvider(selector, {
async provideDocumentFormattingEdits(model) {
const conn = getConn();
if (!conn?.initialized) return [];
await conn.ready;
try {
const edits = (await send_request(
conn,
DocumentFormattingRequest.type.method,
{
textDocument: { uri: normalize_uri(model_uri(model)) },
options: {
tabSize: model.getOptions().tabSize,
insertSpaces: model.getOptions().insertSpaces ?? true,
},
},
)) as Array<{
range: {
start: { line: number; character: number };
end: { line: number; character: number };
};
newText: string;
}> | null;
if (!edits?.length) return [];
return edits.map((e) => ({
range: to_monaco_range(e.range),
text: e.newText,
}));
} catch (err) {
console.error(
"[relay:client] provideDocumentFormattingEdits error",
err,
);
return [];
}
},
}),
);

@@ -607,3 +909,6 @@ return disps;

private model_matches(model: Monaco.editor.ITextModel, def: LspClientDefinition): boolean {
private model_matches(
model: Monaco.editor.ITextModel,
def: LspClientDefinition,
): boolean {
const lang = model.getLanguageId();

@@ -614,2 +919,2 @@ if (lang === def.languageId) return true;

}
}
}

@@ -24,3 +24,3 @@ import * as http from "node:http";

register(def: LspServerDefinition) {
register(def: LspServerDefinition): this {
this.definitions.set(def.languageId, def);

@@ -30,7 +30,8 @@ return this;

setWorkspacePath(p: string) {
setWorkspacePath(p: string): this {
this.workspacePath = p;
return this;
}
start(port: number = 9721): Promise<void> {
start(port = 9721): Promise<void> {
this.httpServer = http.createServer((_req, res) => {

@@ -66,2 +67,26 @@ res.writeHead(200, { "Content-Type": "application/json" });

// Resolve command — static definition takes priority, then resolver
let command: string;
let args: string[];
if (def.command) {
command = def.command;
args = [...(def.args ?? [])];
} else if (def.resolve) {
const resolved = def.resolve();
if (!resolved) {
const msg = `[relay] resolver returned null for "${languageId}" — language server not available`;
console.error(msg);
ws.close(1011, msg);
return;
}
command = resolved.command;
args = [...(resolved.args ?? [])];
} else {
const msg = `[relay] no command or resolver provided for "${languageId}"`;
console.error(msg);
ws.close(1011, msg);
return;
}
const prevChild = this.activeChildren.get(languageId);

@@ -76,3 +101,3 @@ if (prevChild && !prevChild.killed) {

this.spawnAndBridge(def, workspacePath, ws);
this.spawnAndBridge(def, command, args, workspacePath, ws);
});

@@ -107,9 +132,9 @@

def: LspServerDefinition,
command: string,
args: string[],
workspacePath: string,
ws: WebSocket,
) {
): void {
const tag = `:${def.languageId}`;
const env = { ...process.env, ...def.env };
const command = def.command;
const args = [...(def.args ?? [])];

@@ -116,0 +141,0 @@ console.log(`[relay${tag}] spawning: "${command}" cwd="${workspacePath}"`);

export interface LspServerDefinition {
languageId: string;
command: string;
/** Static command — used directly if provided. */
command?: string;
args?: string[];
env?: Record<string, string>;
/**
* Optional resolver called per connection.
* Return null to reject the connection with a descriptive error.
* Use this when the command must be discovered at runtime
* (e.g. finding a Python interpreter + pylsp).
*/
resolve?: () => { command: string; args?: string[] } | null;
}

@@ -28,3 +28,4 @@ {

"noPropertyAccessFromIndexSignature": false
}
},
"exclude": ["examples"]
}
{
"lockfileVersion": 1,
"configVersion": 1,
"workspaces": {
"": {
"name": "@ridit/relay",
"dependencies": {
"monaco-editor": "^0.55.1",
"vscode-languageserver-protocol": "^3.17.5",
"vscode-ws-jsonrpc": "^3.5.0",
},
"devDependencies": {
"@types/bun": "latest",
"@types/ws": "^8.18.1",
},
"peerDependencies": {
"typescript": "^5",
},
},
},
"packages": {
"@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=="],
"vscode-ws-jsonrpc/vscode-jsonrpc": ["vscode-jsonrpc@8.2.1", "", {}, "sha512-kdjOSJ2lLIn7r1rtrMbbNCHjyMPfRnowdKjBQ+mGq6NAW5QY2bEZC/khaC5OR8svbbjvLEaIXkOq45e2X9BIbQ=="],
}
}