diff --git a/CHANGELOG.md b/CHANGELOG.md index c3c08c81..52f70138 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -24,6 +24,13 @@ Changelog * No changes. +Version 0.1.37 -- 2025-Sep-17 +----------------------------- + +* Fix: avoid loading the same file twice in a row when the user clicks on a + link in the Client. +* Improve VSCode connection with the Server. + Version 0.1.36 -- 2025-Sep-17 ----------------------------- diff --git a/builder/Cargo.lock b/builder/Cargo.lock index 0748b384..7b802842 100644 --- a/builder/Cargo.lock +++ b/builder/Cargo.lock @@ -81,9 +81,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.47" +version = "4.5.48" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7eac00902d9d136acd712710d71823fb8ac8004ca445a89e73a41d45aa712931" +checksum = "e2134bb3ea021b78629caa971416385309e0131b351b25e01dc16fb54e1b5fae" dependencies = [ "clap_builder", "clap_derive", @@ -91,9 +91,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.47" +version = "4.5.48" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ad9bbf750e73b5884fb8a211a9424a1906c1e156724260fdae972f31d70e1d6" +checksum = "c2ba64afa3c0a6df7fa517765e31314e983f51dda798ffba27b988194fb65dc9" dependencies = [ "anstream", "anstyle", @@ -358,27 +358,27 @@ checksum = "caf4aa5b0f434c91fe5c7f1ecb6a5ece2130b02ad2a590589dda5146df959001" [[package]] name = "serde" -version = "1.0.225" +version = "1.0.226" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd6c24dee235d0da097043389623fb913daddf92c76e9f5a1db88607a0bcbd1d" +checksum = "0dca6411025b24b60bfa7ec1fe1f8e710ac09782dca409ee8237ba74b51295fd" dependencies = [ "serde_core", ] [[package]] name = "serde_core" -version = "1.0.225" +version = "1.0.226" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "659356f9a0cb1e529b24c01e43ad2bdf520ec4ceaf83047b83ddcc2251f96383" +checksum = "ba2ba63999edb9dac981fb34b3e5c0d111a69b0924e253ed29d83f7c99e966a4" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.225" +version = "1.0.226" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ea936adf78b1f766949a4977b91d2f5595825bd6ec079aa9543ad2685fc4516" +checksum = "8db53ae22f34573731bafa1db20f04027b2d25e02d8205921b569171699cdb33" dependencies = [ "proc-macro2", "quote", diff --git a/client/package.json5 b/client/package.json5 index e579173f..92774e56 100644 --- a/client/package.json5 +++ b/client/package.json5 @@ -43,7 +43,7 @@ url: 'https://github.com/bjones1/CodeChat_editor', }, type: 'module', - version: '0.1.36', + version: '0.1.37', dependencies: { '@codemirror/commands': '^6.8.1', '@codemirror/lang-cpp': '^6.0.3', @@ -59,28 +59,28 @@ '@codemirror/lang-rust': '^6.0.2', '@codemirror/lang-xml': '^6.1.0', '@codemirror/state': '^6.5.2', - '@codemirror/view': '^6.38.2', + '@codemirror/view': '^6.38.3', '@mathjax/mathjax-newcm-font': '4.0.0', codemirror: '^6.0.2', 'graphviz-webcomponent': 'github:bjones1/graphviz-webcomponent#dist', mathjax: '4.0.0', - mermaid: '^11.11.0', - 'npm-check-updates': '^18.1.1', + mermaid: '^11.12.0', + 'npm-check-updates': '^18.3.0', 'pdfjs-dist': '^5.4.149', - tinymce: '^8.1.1', + tinymce: '^8.1.2', 'toastify-js': '^1.12.0', }, devDependencies: { '@types/chai': '^5.2.2', '@types/js-beautify': '^1.14.3', '@types/mocha': '^10.0.10', - '@types/node': '^24.5.1', + '@types/node': '^24.5.2', '@types/toastify-js': '^1.12.4', - '@typescript-eslint/eslint-plugin': '^8.44.0', - '@typescript-eslint/parser': '^8.44.0', + '@typescript-eslint/eslint-plugin': '^8.44.1', + '@typescript-eslint/parser': '^8.44.1', chai: '^6.0.1', esbuild: '^0.25.10', - eslint: '^9.35.0', + eslint: '^9.36.0', 'eslint-config-prettier': '^10.1.8', 'eslint-plugin-import': '^2.32.0', 'eslint-plugin-prettier': '^5.5.4', diff --git a/client/pnpm-lock.yaml b/client/pnpm-lock.yaml index 29f5cd4c..3d91d613 100644 --- a/client/pnpm-lock.yaml +++ b/client/pnpm-lock.yaml @@ -51,8 +51,8 @@ importers: specifier: ^6.5.2 version: 6.5.2 '@codemirror/view': - specifier: ^6.38.2 - version: 6.38.2 + specifier: ^6.38.3 + version: 6.38.3 '@mathjax/mathjax-newcm-font': specifier: 4.0.0 version: 4.0.0 @@ -66,17 +66,17 @@ importers: specifier: 4.0.0 version: 4.0.0 mermaid: - specifier: ^11.11.0 - version: 11.11.0 + specifier: ^11.12.0 + version: 11.12.0 npm-check-updates: - specifier: ^18.1.1 - version: 18.1.1 + specifier: ^18.3.0 + version: 18.3.0 pdfjs-dist: specifier: ^5.4.149 version: 5.4.149 tinymce: - specifier: ^8.1.1 - version: 8.1.1 + specifier: ^8.1.2 + version: 8.1.2 toastify-js: specifier: ^1.12.0 version: 1.12.0 @@ -91,17 +91,17 @@ importers: specifier: ^10.0.10 version: 10.0.10 '@types/node': - specifier: ^24.5.1 - version: 24.5.1 + specifier: ^24.5.2 + version: 24.5.2 '@types/toastify-js': specifier: ^1.12.4 version: 1.12.4 '@typescript-eslint/eslint-plugin': - specifier: ^8.44.0 - version: 8.44.0(@typescript-eslint/parser@8.44.0(eslint@9.35.0)(typescript@5.9.2))(eslint@9.35.0)(typescript@5.9.2) + specifier: ^8.44.1 + version: 8.44.1(@typescript-eslint/parser@8.44.1(eslint@9.36.0)(typescript@5.9.2))(eslint@9.36.0)(typescript@5.9.2) '@typescript-eslint/parser': - specifier: ^8.44.0 - version: 8.44.0(eslint@9.35.0)(typescript@5.9.2) + specifier: ^8.44.1 + version: 8.44.1(eslint@9.36.0)(typescript@5.9.2) chai: specifier: ^6.0.1 version: 6.0.1 @@ -109,17 +109,17 @@ importers: specifier: ^0.25.10 version: 0.25.10 eslint: - specifier: ^9.35.0 - version: 9.35.0 + specifier: ^9.36.0 + version: 9.36.0 eslint-config-prettier: specifier: ^10.1.8 - version: 10.1.8(eslint@9.35.0) + version: 10.1.8(eslint@9.36.0) eslint-plugin-import: specifier: ^2.32.0 - version: 2.32.0(@typescript-eslint/parser@8.44.0(eslint@9.35.0)(typescript@5.9.2))(eslint@9.35.0) + version: 2.32.0(@typescript-eslint/parser@8.44.1(eslint@9.36.0)(typescript@5.9.2))(eslint@9.36.0) eslint-plugin-prettier: specifier: ^5.5.4 - version: 5.5.4(eslint-config-prettier@10.1.8(eslint@9.35.0))(eslint@9.35.0)(prettier@3.6.2) + version: 5.5.4(eslint-config-prettier@10.1.8(eslint@9.36.0))(eslint@9.36.0)(prettier@3.6.2) mocha: specifier: ^11.7.2 version: 11.7.2 @@ -135,8 +135,8 @@ packages: '@antfu/install-pkg@1.1.0': resolution: {integrity: sha512-MGQsmw10ZyI+EJo45CdSER4zEb+p31LpDAFp2Z3gkSd1yqVZGi0Ebx++YTEMonJy4oChEMLsxZ64j8FH6sSqtQ==} - '@antfu/utils@9.2.0': - resolution: {integrity: sha512-Oq1d9BGZakE/FyoEtcNeSwM7MpDO2vUBi11RWBZXf75zPsbUVWmUs03EqkRFrcgbXyKTas0BdZWC1wcuSoqSAw==} + '@antfu/utils@9.2.1': + resolution: {integrity: sha512-TMilPqXyii1AsiEii6l6ubRzbo76p6oshUSYPaKsmXDavyMLqjzVDkcp3pHp5ELMUNJHATcEOGxKTTsX9yYhGg==} '@braintree/sanitize-url@7.1.1': resolution: {integrity: sha512-i1L7noDNxtFyL5DmZafWy1wRVhGehQmzZaz1HiN5e7iylJMSZR7ekOV7NsIqa5qBldlLrsKv4HbgFUVlQrz8Mw==} @@ -210,8 +210,8 @@ packages: '@codemirror/state@6.5.2': resolution: {integrity: sha512-FVqsPqtPWKVVL3dPSxy8wEF/ymIEuVzF1PK3VbUgrxXpJUSHQWWZz4JMToquRxnkw+36LTamCZG2iua2Ptq0fA==} - '@codemirror/view@6.38.2': - resolution: {integrity: sha512-bTWAJxL6EOFLPzTx+O5P5xAO3gTqpatQ2b/ARQ8itfU/v2LlpS3pH2fkL0A3E/Fx8Y2St2KES7ZEV0sHTsSW/A==} + '@codemirror/view@6.38.3': + resolution: {integrity: sha512-x2t87+oqwB1mduiQZ6huIghjMt4uZKFEdj66IcXw7+a5iBEvv9lh7EWDRHI7crnD4BMGpnyq/RzmCGbiEZLcvQ==} '@esbuild/aix-ppc64@0.25.10': resolution: {integrity: sha512-0NFWnA+7l41irNuaSVlLfgNT12caWJVLzp5eAVhZ0z1qpxbockccEt3s+149rE64VUI3Ml2zt8Nv5JVc4QXTsw==} @@ -395,8 +395,8 @@ packages: resolution: {integrity: sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@eslint/js@9.35.0': - resolution: {integrity: sha512-30iXE9whjlILfWobBkNerJo+TXYsgVM5ERQwMcMKCHckHflCmf7wXDAHlARoWnh0s1U72WqlbeyE7iAcCzuCPw==} + '@eslint/js@9.36.0': + resolution: {integrity: sha512-uhCbYtYynH30iZErszX78U+nR3pJU3RHGQ57NXy5QupD4SBVwDeU8TNBy+MjMngc1UyIW9noKqsRqfjQTBU2dw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@eslint/object-schema@2.1.6': @@ -454,8 +454,8 @@ packages: '@lezer/java@1.1.3': resolution: {integrity: sha512-yHquUfujwg6Yu4Fd1GNHCvidIvJwi/1Xu2DaKl/pfWIA2c1oXkVvawH3NyXhCaFx4OdlYBVX5wvz2f7Aoa/4Xw==} - '@lezer/javascript@1.5.3': - resolution: {integrity: sha512-jexmlKq5NpGiB7t+0QkyhSXRgaiab5YisHIQW9C7EcU19KSUsDguZe9WY+rmRDg34nXoNH2LQ4SxpC+aJUchSQ==} + '@lezer/javascript@1.5.4': + resolution: {integrity: sha512-vvYx3MhWqeZtGPwDStM2dwgljd5smolYD2lR2UyFcHfxbBQebqx8yjmFmxtJ/E6nN6u1D9srOiVWm3Rb4tmcUA==} '@lezer/json@1.0.3': resolution: {integrity: sha512-BP9KzdF9Y35PDpv04r0VeSTKDeox5vVr3efE7eBbx3r4s3oNLfunchejZhjArmeieBH+nVOpgIiBJpEAv8ilqQ==} @@ -691,8 +691,8 @@ packages: '@types/mocha@10.0.10': resolution: {integrity: sha512-xPyYSz1cMPnJQhl0CLMH68j3gprKZaTjG3s5Vi+fDgx+uhG9NOXwbVt52eFS8ECyXhyKcjDLCBEqBExKuiZb7Q==} - '@types/node@24.5.1': - resolution: {integrity: sha512-/SQdmUP2xa+1rdx7VwB9yPq8PaKej8TD5cQ+XfKDPWWC+VDJU4rvVVagXqKUzhKjtFoNA8rXDJAkCxQPAe00+Q==} + '@types/node@24.5.2': + resolution: {integrity: sha512-FYxk1I7wPv3K2XBaoyH2cTnocQEu8AOZ60hPbsyukMPLv5/5qr7V1i8PLHdl6Zf87I+xZXFvPCXYjiTFq+YSDQ==} '@types/toastify-js@1.12.4': resolution: {integrity: sha512-zfZHU4tKffPCnZRe7pjv/eFKzTVHozKewFCKaCjZ4gFinKgJRz/t0bkZiMCXJxPhv/ZoeDGNOeRD09R0kQZ/nw==} @@ -700,63 +700,63 @@ packages: '@types/trusted-types@2.0.7': resolution: {integrity: sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==} - '@typescript-eslint/eslint-plugin@8.44.0': - resolution: {integrity: sha512-EGDAOGX+uwwekcS0iyxVDmRV9HX6FLSM5kzrAToLTsr9OWCIKG/y3lQheCq18yZ5Xh78rRKJiEpP0ZaCs4ryOQ==} + '@typescript-eslint/eslint-plugin@8.44.1': + resolution: {integrity: sha512-molgphGqOBT7t4YKCSkbasmu1tb1MgrZ2szGzHbclF7PNmOkSTQVHy+2jXOSnxvR3+Xe1yySHFZoqMpz3TfQsw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: - '@typescript-eslint/parser': ^8.44.0 + '@typescript-eslint/parser': ^8.44.1 eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/parser@8.44.0': - resolution: {integrity: sha512-VGMpFQGUQWYT9LfnPcX8ouFojyrZ/2w3K5BucvxL/spdNehccKhB4jUyB1yBCXpr2XFm0jkECxgrpXBW2ipoAw==} + '@typescript-eslint/parser@8.44.1': + resolution: {integrity: sha512-EHrrEsyhOhxYt8MTg4zTF+DJMuNBzWwgvvOYNj/zm1vnaD/IC5zCXFehZv94Piqa2cRFfXrTFxIvO95L7Qc/cw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/project-service@8.44.0': - resolution: {integrity: sha512-ZeaGNraRsq10GuEohKTo4295Z/SuGcSq2LzfGlqiuEvfArzo/VRrT0ZaJsVPuKZ55lVbNk8U6FcL+ZMH8CoyVA==} + '@typescript-eslint/project-service@8.44.1': + resolution: {integrity: sha512-ycSa60eGg8GWAkVsKV4E6Nz33h+HjTXbsDT4FILyL8Obk5/mx4tbvCNsLf9zret3ipSumAOG89UcCs/KRaKYrA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/scope-manager@8.44.0': - resolution: {integrity: sha512-87Jv3E+al8wpD+rIdVJm/ItDBe/Im09zXIjFoipOjr5gHUhJmTzfFLuTJ/nPTMc2Srsroy4IBXwcTCHyRR7KzA==} + '@typescript-eslint/scope-manager@8.44.1': + resolution: {integrity: sha512-NdhWHgmynpSvyhchGLXh+w12OMT308Gm25JoRIyTZqEbApiBiQHD/8xgb6LqCWCFcxFtWwaVdFsLPQI3jvhywg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/tsconfig-utils@8.44.0': - resolution: {integrity: sha512-x5Y0+AuEPqAInc6yd0n5DAcvtoQ/vyaGwuX5HE9n6qAefk1GaedqrLQF8kQGylLUb9pnZyLf+iEiL9fr8APDtQ==} + '@typescript-eslint/tsconfig-utils@8.44.1': + resolution: {integrity: sha512-B5OyACouEjuIvof3o86lRMvyDsFwZm+4fBOqFHccIctYgBjqR3qT39FBYGN87khcgf0ExpdCBeGKpKRhSFTjKQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/type-utils@8.44.0': - resolution: {integrity: sha512-9cwsoSxJ8Sak67Be/hD2RNt/fsqmWnNE1iHohG8lxqLSNY8xNfyY7wloo5zpW3Nu9hxVgURevqfcH6vvKCt6yg==} + '@typescript-eslint/type-utils@8.44.1': + resolution: {integrity: sha512-KdEerZqHWXsRNKjF9NYswNISnFzXfXNDfPxoTh7tqohU/PRIbwTmsjGK6V9/RTYWau7NZvfo52lgVk+sJh0K3g==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/types@8.44.0': - resolution: {integrity: sha512-ZSl2efn44VsYM0MfDQe68RKzBz75NPgLQXuGypmym6QVOWL5kegTZuZ02xRAT9T+onqvM6T8CdQk0OwYMB6ZvA==} + '@typescript-eslint/types@8.44.1': + resolution: {integrity: sha512-Lk7uj7y9uQUOEguiDIDLYLJOrYHQa7oBiURYVFqIpGxclAFQ78f6VUOM8lI2XEuNOKNB7XuvM2+2cMXAoq4ALQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/typescript-estree@8.44.0': - resolution: {integrity: sha512-lqNj6SgnGcQZwL4/SBJ3xdPEfcBuhCG8zdcwCPgYcmiPLgokiNDKlbPzCwEwu7m279J/lBYWtDYL+87OEfn8Jw==} + '@typescript-eslint/typescript-estree@8.44.1': + resolution: {integrity: sha512-qnQJ+mVa7szevdEyvfItbO5Vo+GfZ4/GZWWDRRLjrxYPkhM+6zYB2vRYwCsoJLzqFCdZT4mEqyJoyzkunsZ96A==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/utils@8.44.0': - resolution: {integrity: sha512-nktOlVcg3ALo0mYlV+L7sWUD58KG4CMj1rb2HUVOO4aL3K/6wcD+NERqd0rrA5Vg06b42YhF6cFxeixsp9Riqg==} + '@typescript-eslint/utils@8.44.1': + resolution: {integrity: sha512-DpX5Fp6edTlocMCwA+mHY8Mra+pPjRZ0TfHkXI8QFelIKcbADQz1LUPNtzOFUriBB2UYqw4Pi9+xV4w9ZczHFg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/visitor-keys@8.44.0': - resolution: {integrity: sha512-zaz9u8EJ4GBmnehlrpoKvj/E3dNbuQ7q0ucyZImm3cLqJ8INTc970B1qEqDX/Rzq65r3TvVTN7kHWPBoyW7DWw==} + '@typescript-eslint/visitor-keys@8.44.1': + resolution: {integrity: sha512-576+u0QD+Jp3tZzvfRfxon0EA2lzcDt3lhUbsC6Lgzy9x2VR4E+JUiNyGHi5T8vk0TV+fpJ5GLG1JsJuWCaKhw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} acorn-jsx@5.3.2: @@ -1260,8 +1260,8 @@ packages: resolution: {integrity: sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - eslint@9.35.0: - resolution: {integrity: sha512-QePbBFMJFjgmlE+cXAlbHZbHpdFVS2E/6vzCy7aKlebddvl1vadiC4JFV5u/wqTkNUwEV8WrQi257jf5f06hrg==} + eslint@9.36.0: + resolution: {integrity: sha512-hB4FIzXovouYzwzECDcUkJ4OcfOEkXTv2zRY6B9bkwjx/cprAq0uvm1nl7zvQ0/TsUk0zQiN4uPfJpB9m+rPMQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} hasBin: true peerDependencies: @@ -1656,9 +1656,9 @@ packages: lru-cache@10.4.3: resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} - marked@15.0.12: - resolution: {integrity: sha512-8dD6FusOQSrpv9Z1rdNMdlSgQOIP880DHqnohobOmYLElGEqAL/JvxvuxZO16r4HtjTlfPRDC1hbvxC9dPN2nA==} - engines: {node: '>= 18'} + marked@16.3.0: + resolution: {integrity: sha512-K3UxuKu6l6bmA5FUwYho8CfJBlsUWAooKtdGgMcERSpF7gcBUrCGsLH7wDaaNOzwq18JzSUDyoEb/YsrqMac3w==} + engines: {node: '>= 20'} hasBin: true math-intrinsics@1.1.0: @@ -1672,8 +1672,8 @@ packages: resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} engines: {node: '>= 8'} - mermaid@11.11.0: - resolution: {integrity: sha512-9lb/VNkZqWTRjVgCV+l1N+t4kyi94y+l5xrmBmbbxZYkfRl5hEDaTPMOcaWKCl1McG8nBEaMlWwkcAEEgjhBgg==} + mermaid@11.12.0: + resolution: {integrity: sha512-ZudVx73BwrMJfCFmSSJT84y6u5brEoV8DOItdHomNLz32uBjNrelm7mg95X7g+C6UoQH/W6mBLGDEDv73JdxBg==} micromatch@4.0.8: resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} @@ -1707,8 +1707,8 @@ packages: natural-compare@1.4.0: resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} - npm-check-updates@18.1.1: - resolution: {integrity: sha512-sr+z5tEZop9n+uxAv/FVbpIdrayfG3Dr/D91igb+GyBl9eiudYUfGUZEBsmHq6kMOGEssSM3YWrP3njQjVU4Gw==} + npm-check-updates@18.3.0: + resolution: {integrity: sha512-Wcm90Af5JuzxwPTtdLl0OH2O1TCeqPTYBch1M3bePmfqylRMiFXXh+uglE4sfMjwdTjw7aIReMwudXeqoYvh2Q==} engines: {node: ^18.18.0 || >=20.0.0, npm: '>=8.12.1'} hasBin: true @@ -2012,8 +2012,8 @@ packages: tinyexec@1.0.1: resolution: {integrity: sha512-5uC6DDlmeqiOwCPmK9jMSdOuZTh8bU39Ys6yidB+UTt5hfZUPGAypSgFRiEp+jbi9qH40BLDvy85jIU88wKSqw==} - tinymce@8.1.1: - resolution: {integrity: sha512-+uJFY9TWBpP4/dRwylkQz2fnCxuYpAISXNbq05+ej+0x6OQNyhwKnzWT9R68ZjmBjqzIW6pe+cMaj9Zxo7Iihg==} + tinymce@8.1.2: + resolution: {integrity: sha512-KITxHEEHRlxC5xOnxA123eAJ67NgsWxNphtItWt9TRu07DiTZrWIqJeIKRX9euE51/l3kJO4WQiqoBXKTJJGsA==} to-regex-range@5.0.1: resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} @@ -2163,7 +2163,7 @@ snapshots: package-manager-detector: 1.3.0 tinyexec: 1.0.1 - '@antfu/utils@9.2.0': {} + '@antfu/utils@9.2.1': {} '@braintree/sanitize-url@7.1.1': {} @@ -2188,14 +2188,14 @@ snapshots: dependencies: '@codemirror/language': 6.11.3 '@codemirror/state': 6.5.2 - '@codemirror/view': 6.38.2 + '@codemirror/view': 6.38.3 '@lezer/common': 1.2.3 '@codemirror/commands@6.8.1': dependencies: '@codemirror/language': 6.11.3 '@codemirror/state': 6.5.2 - '@codemirror/view': 6.38.2 + '@codemirror/view': 6.38.3 '@lezer/common': 1.2.3 '@codemirror/lang-cpp@6.0.3': @@ -2226,7 +2226,7 @@ snapshots: '@codemirror/lang-javascript': 6.2.4 '@codemirror/language': 6.11.3 '@codemirror/state': 6.5.2 - '@codemirror/view': 6.38.2 + '@codemirror/view': 6.38.3 '@lezer/common': 1.2.3 '@lezer/css': 1.3.0 '@lezer/html': 1.3.10 @@ -2242,9 +2242,9 @@ snapshots: '@codemirror/language': 6.11.3 '@codemirror/lint': 6.8.5 '@codemirror/state': 6.5.2 - '@codemirror/view': 6.38.2 + '@codemirror/view': 6.38.3 '@lezer/common': 1.2.3 - '@lezer/javascript': 1.5.3 + '@lezer/javascript': 1.5.4 '@codemirror/lang-json@6.0.2': dependencies: @@ -2257,7 +2257,7 @@ snapshots: '@codemirror/lang-html': 6.4.10 '@codemirror/language': 6.11.3 '@codemirror/state': 6.5.2 - '@codemirror/view': 6.38.2 + '@codemirror/view': 6.38.3 '@lezer/common': 1.2.3 '@lezer/markdown': 1.4.3 @@ -2287,14 +2287,14 @@ snapshots: '@codemirror/autocomplete': 6.18.7 '@codemirror/language': 6.11.3 '@codemirror/state': 6.5.2 - '@codemirror/view': 6.38.2 + '@codemirror/view': 6.38.3 '@lezer/common': 1.2.3 '@lezer/xml': 1.0.6 '@codemirror/language@6.11.3': dependencies: '@codemirror/state': 6.5.2 - '@codemirror/view': 6.38.2 + '@codemirror/view': 6.38.3 '@lezer/common': 1.2.3 '@lezer/highlight': 1.2.1 '@lezer/lr': 1.4.2 @@ -2303,20 +2303,20 @@ snapshots: '@codemirror/lint@6.8.5': dependencies: '@codemirror/state': 6.5.2 - '@codemirror/view': 6.38.2 + '@codemirror/view': 6.38.3 crelt: 1.0.6 '@codemirror/search@6.5.11': dependencies: '@codemirror/state': 6.5.2 - '@codemirror/view': 6.38.2 + '@codemirror/view': 6.38.3 crelt: 1.0.6 '@codemirror/state@6.5.2': dependencies: '@marijn/find-cluster-break': 1.0.2 - '@codemirror/view@6.38.2': + '@codemirror/view@6.38.3': dependencies: '@codemirror/state': 6.5.2 crelt: 1.0.6 @@ -2401,9 +2401,9 @@ snapshots: '@esbuild/win32-x64@0.25.10': optional: true - '@eslint-community/eslint-utils@4.9.0(eslint@9.35.0)': + '@eslint-community/eslint-utils@4.9.0(eslint@9.36.0)': dependencies: - eslint: 9.35.0 + eslint: 9.36.0 eslint-visitor-keys: 3.4.3 '@eslint-community/regexpp@4.12.1': {} @@ -2436,7 +2436,7 @@ snapshots: transitivePeerDependencies: - supports-color - '@eslint/js@9.35.0': {} + '@eslint/js@9.36.0': {} '@eslint/object-schema@2.1.6': {} @@ -2461,7 +2461,7 @@ snapshots: '@iconify/utils@3.0.2': dependencies: '@antfu/install-pkg': 1.1.0 - '@antfu/utils': 9.2.0 + '@antfu/utils': 9.2.1 '@iconify/types': 2.0.0 debug: 4.4.3(supports-color@8.1.1) globals: 15.15.0 @@ -2516,7 +2516,7 @@ snapshots: '@lezer/highlight': 1.2.1 '@lezer/lr': 1.4.2 - '@lezer/javascript@1.5.3': + '@lezer/javascript@1.5.4': dependencies: '@lezer/common': 1.2.3 '@lezer/highlight': 1.2.1 @@ -2767,7 +2767,7 @@ snapshots: '@types/mocha@10.0.10': {} - '@types/node@24.5.1': + '@types/node@24.5.2': dependencies: undici-types: 7.12.0 @@ -2776,15 +2776,15 @@ snapshots: '@types/trusted-types@2.0.7': optional: true - '@typescript-eslint/eslint-plugin@8.44.0(@typescript-eslint/parser@8.44.0(eslint@9.35.0)(typescript@5.9.2))(eslint@9.35.0)(typescript@5.9.2)': + '@typescript-eslint/eslint-plugin@8.44.1(@typescript-eslint/parser@8.44.1(eslint@9.36.0)(typescript@5.9.2))(eslint@9.36.0)(typescript@5.9.2)': dependencies: '@eslint-community/regexpp': 4.12.1 - '@typescript-eslint/parser': 8.44.0(eslint@9.35.0)(typescript@5.9.2) - '@typescript-eslint/scope-manager': 8.44.0 - '@typescript-eslint/type-utils': 8.44.0(eslint@9.35.0)(typescript@5.9.2) - '@typescript-eslint/utils': 8.44.0(eslint@9.35.0)(typescript@5.9.2) - '@typescript-eslint/visitor-keys': 8.44.0 - eslint: 9.35.0 + '@typescript-eslint/parser': 8.44.1(eslint@9.36.0)(typescript@5.9.2) + '@typescript-eslint/scope-manager': 8.44.1 + '@typescript-eslint/type-utils': 8.44.1(eslint@9.36.0)(typescript@5.9.2) + '@typescript-eslint/utils': 8.44.1(eslint@9.36.0)(typescript@5.9.2) + '@typescript-eslint/visitor-keys': 8.44.1 + eslint: 9.36.0 graphemer: 1.4.0 ignore: 7.0.5 natural-compare: 1.4.0 @@ -2793,56 +2793,56 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@8.44.0(eslint@9.35.0)(typescript@5.9.2)': + '@typescript-eslint/parser@8.44.1(eslint@9.36.0)(typescript@5.9.2)': dependencies: - '@typescript-eslint/scope-manager': 8.44.0 - '@typescript-eslint/types': 8.44.0 - '@typescript-eslint/typescript-estree': 8.44.0(typescript@5.9.2) - '@typescript-eslint/visitor-keys': 8.44.0 + '@typescript-eslint/scope-manager': 8.44.1 + '@typescript-eslint/types': 8.44.1 + '@typescript-eslint/typescript-estree': 8.44.1(typescript@5.9.2) + '@typescript-eslint/visitor-keys': 8.44.1 debug: 4.4.3(supports-color@8.1.1) - eslint: 9.35.0 + eslint: 9.36.0 typescript: 5.9.2 transitivePeerDependencies: - supports-color - '@typescript-eslint/project-service@8.44.0(typescript@5.9.2)': + '@typescript-eslint/project-service@8.44.1(typescript@5.9.2)': dependencies: - '@typescript-eslint/tsconfig-utils': 8.44.0(typescript@5.9.2) - '@typescript-eslint/types': 8.44.0 + '@typescript-eslint/tsconfig-utils': 8.44.1(typescript@5.9.2) + '@typescript-eslint/types': 8.44.1 debug: 4.4.3(supports-color@8.1.1) typescript: 5.9.2 transitivePeerDependencies: - supports-color - '@typescript-eslint/scope-manager@8.44.0': + '@typescript-eslint/scope-manager@8.44.1': dependencies: - '@typescript-eslint/types': 8.44.0 - '@typescript-eslint/visitor-keys': 8.44.0 + '@typescript-eslint/types': 8.44.1 + '@typescript-eslint/visitor-keys': 8.44.1 - '@typescript-eslint/tsconfig-utils@8.44.0(typescript@5.9.2)': + '@typescript-eslint/tsconfig-utils@8.44.1(typescript@5.9.2)': dependencies: typescript: 5.9.2 - '@typescript-eslint/type-utils@8.44.0(eslint@9.35.0)(typescript@5.9.2)': + '@typescript-eslint/type-utils@8.44.1(eslint@9.36.0)(typescript@5.9.2)': dependencies: - '@typescript-eslint/types': 8.44.0 - '@typescript-eslint/typescript-estree': 8.44.0(typescript@5.9.2) - '@typescript-eslint/utils': 8.44.0(eslint@9.35.0)(typescript@5.9.2) + '@typescript-eslint/types': 8.44.1 + '@typescript-eslint/typescript-estree': 8.44.1(typescript@5.9.2) + '@typescript-eslint/utils': 8.44.1(eslint@9.36.0)(typescript@5.9.2) debug: 4.4.3(supports-color@8.1.1) - eslint: 9.35.0 + eslint: 9.36.0 ts-api-utils: 2.1.0(typescript@5.9.2) typescript: 5.9.2 transitivePeerDependencies: - supports-color - '@typescript-eslint/types@8.44.0': {} + '@typescript-eslint/types@8.44.1': {} - '@typescript-eslint/typescript-estree@8.44.0(typescript@5.9.2)': + '@typescript-eslint/typescript-estree@8.44.1(typescript@5.9.2)': dependencies: - '@typescript-eslint/project-service': 8.44.0(typescript@5.9.2) - '@typescript-eslint/tsconfig-utils': 8.44.0(typescript@5.9.2) - '@typescript-eslint/types': 8.44.0 - '@typescript-eslint/visitor-keys': 8.44.0 + '@typescript-eslint/project-service': 8.44.1(typescript@5.9.2) + '@typescript-eslint/tsconfig-utils': 8.44.1(typescript@5.9.2) + '@typescript-eslint/types': 8.44.1 + '@typescript-eslint/visitor-keys': 8.44.1 debug: 4.4.3(supports-color@8.1.1) fast-glob: 3.3.3 is-glob: 4.0.3 @@ -2853,20 +2853,20 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/utils@8.44.0(eslint@9.35.0)(typescript@5.9.2)': + '@typescript-eslint/utils@8.44.1(eslint@9.36.0)(typescript@5.9.2)': dependencies: - '@eslint-community/eslint-utils': 4.9.0(eslint@9.35.0) - '@typescript-eslint/scope-manager': 8.44.0 - '@typescript-eslint/types': 8.44.0 - '@typescript-eslint/typescript-estree': 8.44.0(typescript@5.9.2) - eslint: 9.35.0 + '@eslint-community/eslint-utils': 4.9.0(eslint@9.36.0) + '@typescript-eslint/scope-manager': 8.44.1 + '@typescript-eslint/types': 8.44.1 + '@typescript-eslint/typescript-estree': 8.44.1(typescript@5.9.2) + eslint: 9.36.0 typescript: 5.9.2 transitivePeerDependencies: - supports-color - '@typescript-eslint/visitor-keys@8.44.0': + '@typescript-eslint/visitor-keys@8.44.1': dependencies: - '@typescript-eslint/types': 8.44.0 + '@typescript-eslint/types': 8.44.1 eslint-visitor-keys: 4.2.1 acorn-jsx@5.3.2(acorn@8.15.0): @@ -3027,7 +3027,7 @@ snapshots: '@codemirror/lint': 6.8.5 '@codemirror/search': 6.5.11 '@codemirror/state': 6.5.2 - '@codemirror/view': 6.38.2 + '@codemirror/view': 6.38.3 color-convert@2.0.1: dependencies: @@ -3432,9 +3432,9 @@ snapshots: escape-string-regexp@4.0.0: {} - eslint-config-prettier@10.1.8(eslint@9.35.0): + eslint-config-prettier@10.1.8(eslint@9.36.0): dependencies: - eslint: 9.35.0 + eslint: 9.36.0 eslint-import-resolver-node@0.3.9: dependencies: @@ -3444,17 +3444,17 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-module-utils@2.12.1(@typescript-eslint/parser@8.44.0(eslint@9.35.0)(typescript@5.9.2))(eslint-import-resolver-node@0.3.9)(eslint@9.35.0): + eslint-module-utils@2.12.1(@typescript-eslint/parser@8.44.1(eslint@9.36.0)(typescript@5.9.2))(eslint-import-resolver-node@0.3.9)(eslint@9.36.0): dependencies: debug: 3.2.7 optionalDependencies: - '@typescript-eslint/parser': 8.44.0(eslint@9.35.0)(typescript@5.9.2) - eslint: 9.35.0 + '@typescript-eslint/parser': 8.44.1(eslint@9.36.0)(typescript@5.9.2) + eslint: 9.36.0 eslint-import-resolver-node: 0.3.9 transitivePeerDependencies: - supports-color - eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.44.0(eslint@9.35.0)(typescript@5.9.2))(eslint@9.35.0): + eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.44.1(eslint@9.36.0)(typescript@5.9.2))(eslint@9.36.0): dependencies: '@rtsao/scc': 1.1.0 array-includes: 3.1.9 @@ -3463,9 +3463,9 @@ snapshots: array.prototype.flatmap: 1.3.3 debug: 3.2.7 doctrine: 2.1.0 - eslint: 9.35.0 + eslint: 9.36.0 eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.12.1(@typescript-eslint/parser@8.44.0(eslint@9.35.0)(typescript@5.9.2))(eslint-import-resolver-node@0.3.9)(eslint@9.35.0) + eslint-module-utils: 2.12.1(@typescript-eslint/parser@8.44.1(eslint@9.36.0)(typescript@5.9.2))(eslint-import-resolver-node@0.3.9)(eslint@9.36.0) hasown: 2.0.2 is-core-module: 2.16.1 is-glob: 4.0.3 @@ -3477,20 +3477,20 @@ snapshots: string.prototype.trimend: 1.0.9 tsconfig-paths: 3.15.0 optionalDependencies: - '@typescript-eslint/parser': 8.44.0(eslint@9.35.0)(typescript@5.9.2) + '@typescript-eslint/parser': 8.44.1(eslint@9.36.0)(typescript@5.9.2) transitivePeerDependencies: - eslint-import-resolver-typescript - eslint-import-resolver-webpack - supports-color - eslint-plugin-prettier@5.5.4(eslint-config-prettier@10.1.8(eslint@9.35.0))(eslint@9.35.0)(prettier@3.6.2): + eslint-plugin-prettier@5.5.4(eslint-config-prettier@10.1.8(eslint@9.36.0))(eslint@9.36.0)(prettier@3.6.2): dependencies: - eslint: 9.35.0 + eslint: 9.36.0 prettier: 3.6.2 prettier-linter-helpers: 1.0.0 synckit: 0.11.11 optionalDependencies: - eslint-config-prettier: 10.1.8(eslint@9.35.0) + eslint-config-prettier: 10.1.8(eslint@9.36.0) eslint-scope@8.4.0: dependencies: @@ -3501,15 +3501,15 @@ snapshots: eslint-visitor-keys@4.2.1: {} - eslint@9.35.0: + eslint@9.36.0: dependencies: - '@eslint-community/eslint-utils': 4.9.0(eslint@9.35.0) + '@eslint-community/eslint-utils': 4.9.0(eslint@9.36.0) '@eslint-community/regexpp': 4.12.1 '@eslint/config-array': 0.21.0 '@eslint/config-helpers': 0.3.1 '@eslint/core': 0.15.2 '@eslint/eslintrc': 3.3.1 - '@eslint/js': 9.35.0 + '@eslint/js': 9.36.0 '@eslint/plugin-kit': 0.3.5 '@humanfs/node': 0.16.7 '@humanwhocodes/module-importer': 1.0.1 @@ -3921,7 +3921,7 @@ snapshots: lru-cache@10.4.3: {} - marked@15.0.12: {} + marked@16.3.0: {} math-intrinsics@1.1.0: {} @@ -3931,7 +3931,7 @@ snapshots: merge2@1.4.1: {} - mermaid@11.11.0: + mermaid@11.12.0: dependencies: '@braintree/sanitize-url': 7.1.1 '@iconify/utils': 3.0.2 @@ -3948,7 +3948,7 @@ snapshots: katex: 0.16.22 khroma: 2.1.0 lodash-es: 4.17.21 - marked: 15.0.12 + marked: 16.3.0 roughjs: 4.6.6 stylis: 4.3.6 ts-dedent: 2.2.0 @@ -4007,7 +4007,7 @@ snapshots: natural-compare@1.4.0: {} - npm-check-updates@18.1.1: {} + npm-check-updates@18.3.0: {} object-inspect@1.13.4: {} @@ -4345,7 +4345,7 @@ snapshots: tinyexec@1.0.1: {} - tinymce@8.1.1: {} + tinymce@8.1.2: {} to-regex-range@5.0.1: dependencies: diff --git a/client/src/CodeChatEditor.mts b/client/src/CodeChatEditor.mts index d65dee0b..902d6662 100644 --- a/client/src/CodeChatEditor.mts +++ b/client/src/CodeChatEditor.mts @@ -387,7 +387,7 @@ const on_save = async (only_if_dirty: boolean = false) => { // Save the provided contents back to the filesystem, by // sending an update message over the websocket. const webSocketComm = parent.window.CodeChatEditorFramework.webSocketComm; - console_log("Sent Update - saving document."); + console_log("CodeChat Editor Client: sent Update - saving document."); await new Promise(async (resolve) => { webSocketComm.send_message({ Update: save_lp(is_dirty) }, () => resolve(0), @@ -425,7 +425,7 @@ export const startAutosaveTimer = () => { clearAutosaveTimer(); // ...then start another timeout which saves the document when it expires. autosaveTimeoutId = window.setTimeout(() => { - console_log("Autosaving."); + console_log("CodeChat Editor Client: autosaving."); on_save(); }, 1000); }; @@ -472,7 +472,7 @@ const on_navigate = (navigateEvent: NavigateEvent) => { // Intercept this navigation so we can save the document first. navigateEvent.intercept(); - console_log("CodeChat Editor: saving document before navigation."); + console_log("CodeChat Editor Client: saving document before navigation."); save_then_navigate(new URL(navigateEvent.destination.url)); }; diff --git a/client/src/CodeChatEditorFramework.mts b/client/src/CodeChatEditorFramework.mts index 1e4a172f..e653cb03 100644 --- a/client/src/CodeChatEditorFramework.mts +++ b/client/src/CodeChatEditorFramework.mts @@ -63,7 +63,7 @@ let webSocketComm: WebSocketComm; class WebSocketComm { // Use a unique ID for each websocket message sent. See the Implementation // section on Message IDs for more information. - ws_id = -9007199254740988; + ws_id = 4; // The websocket used by this class. Really a `ReconnectingWebSocket`, but // that's not a type. @@ -101,19 +101,19 @@ class WebSocketComm { this.ws = new ReconnectingWebSocket!(ws_url); // Identify this client on connection. this.ws.onopen = () => { - console_log(`CodeChat Client: websocket to CodeChat Server open.`); + console_log(`CodeChat Editor Client: websocket to CodeChat Server open.`); }; // Provide logging to help track down errors. this.ws.onerror = (event: Event) => { report_error( - `CodeChat Client: websocket error.`, event + `CodeChat Editor Client: websocket error.`, event ); }; this.ws.onclose = (event: CloseEvent) => { console_log( - `CodeChat Client: websocket ${event.wasClean ? "" : "*NOT*"} cleanly closed ${event.reason}. This should only happen on shutdown.` + `CodeChat Editor Client: websocket ${event.wasClean ? "" : "*NOT*"} cleanly closed ${event.reason}. This should only happen on shutdown.` ); console_log(event); }; @@ -125,7 +125,7 @@ class WebSocketComm { const joint_message = JSON.parse(event.data) as EditorMessage; const { id, message } = joint_message; console_log( - `Received data id = ${id}, message = ${format_struct(message)}`, + `CodeChat Editor Client: received data id = ${id}, message = ${format_struct(message)}`, ); assert(id !== undefined); assert(message !== undefined); @@ -304,7 +304,7 @@ class WebSocketComm { assert(this.current_filename !== undefined); message.Update.file_path = this.current_filename!; } - console_log(`Sent message ${id}, ${format_struct(message)}`); + console_log(`CodeChat Editor Client: sent message ${id}, ${format_struct(message)}`); const jm: EditorMessage = { id: id, message: message, @@ -351,7 +351,7 @@ class WebSocketComm { Result: result === null ? { Ok: "Void" } : { Err: result }, }; console_log( - `Sending result id = ${id}, message = ${format_struct(message)}`, + `CodeChat Client: sending result id = ${id}, message = ${format_struct(message)}`, ); // We can't simply call `send_message` because that function expects a // result message back from the server. diff --git a/extensions/VSCode/Cargo.lock b/extensions/VSCode/Cargo.lock index f50c407b..ff2ae591 100644 --- a/extensions/VSCode/Cargo.lock +++ b/extensions/VSCode/Cargo.lock @@ -338,9 +338,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.99" +version = "1.0.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0674a1ddeecb70197781e945de4b3b8ffb61fa939a5597bcf48503737663100" +checksum = "a23eb6b1614318a8071c9b2521f36b424b2c83db5eb3a0fead4a6c0809af6e61" [[package]] name = "arc-swap" @@ -460,9 +460,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.2.37" +version = "1.2.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "65193589c6404eb80b450d618eaf9a2cafaaafd57ecce47370519ef674a7bd44" +checksum = "80f41ae168f955c12fb8960b057d70d0ca153fb83182b57d86380443527be7e9" dependencies = [ "find-msvc-tools", "jobserver", @@ -497,9 +497,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.47" +version = "4.5.48" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7eac00902d9d136acd712710d71823fb8ac8004ca445a89e73a41d45aa712931" +checksum = "e2134bb3ea021b78629caa971416385309e0131b351b25e01dc16fb54e1b5fae" dependencies = [ "clap_builder", "clap_derive", @@ -507,9 +507,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.47" +version = "4.5.48" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ad9bbf750e73b5884fb8a211a9424a1906c1e156724260fdae972f31d70e1d6" +checksum = "c2ba64afa3c0a6df7fa517765e31314e983f51dda798ffba27b988194fb65dc9" dependencies = [ "anstream", "anstyle", @@ -537,7 +537,7 @@ checksum = "b94f61472cee1439c0b966b47e3aca9ae07e45d070759512cd390ea2bebc6675" [[package]] name = "codechat-editor-server" -version = "0.1.36" +version = "0.1.37" dependencies = [ "actix-files", "actix-http", @@ -580,7 +580,7 @@ dependencies = [ [[package]] name = "codechat-editor-vscode-extension" -version = "0.1.36" +version = "0.1.37" dependencies = [ "actix-server", "actix-web", @@ -807,9 +807,9 @@ dependencies = [ [[package]] name = "find-msvc-tools" -version = "0.1.1" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fd99930f64d146689264c637b5af2f0233a933bef0d8570e2526bf9e083192d" +checksum = "1ced73b1dacfc750a6db6c0a0c3a3853c8b41997e2e2c563dc90804ae6867959" [[package]] name = "flate2" @@ -961,6 +961,12 @@ dependencies = [ "foldhash", ] +[[package]] +name = "hashbrown" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5419bdc4f6a9207fbeba6d11b604d481addf78ecd10c11ad51e76c2f6482748d" + [[package]] name = "heck" version = "0.5.0" @@ -1148,7 +1154,7 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2f01d462f766df78ab820dd06f5eb700233c51f0f4c2e846520eaf4ba6aa5c5c" dependencies = [ - "hashbrown", + "hashbrown 0.15.5", "memchr", ] @@ -1160,12 +1166,12 @@ checksum = "e8a5a9a0ff0086c7a148acb942baaabeadf9504d10400b5a05645853729b9cd2" [[package]] name = "indexmap" -version = "2.11.3" +version = "2.11.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92119844f513ffa41556430369ab02c295a3578af21cf945caa3e9e0c2481ac3" +checksum = "4b0f83760fb341a774ed326568e19f5a863af4a952def8c39f9ab92fd95b88e5" dependencies = [ "equivalent", - "hashbrown", + "hashbrown 0.16.0", ] [[package]] @@ -1299,12 +1305,12 @@ checksum = "6a82ae493e598baaea5209805c49bbf2ea7de956d50d7da0da1164f9c6d28543" [[package]] name = "libloading" -version = "0.8.8" +version = "0.8.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07033963ba89ebaf1584d767badaa2e8fcec21aedea6b8c0346d487d49c28667" +checksum = "d7c4b02199fee7c5d21a5ae7d8cfa79a6ef5bb2fc834d6e9058e89c825efdc55" dependencies = [ "cfg-if", - "windows-targets 0.53.3", + "windows-link 0.2.0", ] [[package]] @@ -1973,9 +1979,9 @@ checksum = "d767eb0aabc880b29956c35734170f26ed551a859dbd361d140cdbeca61ab1e2" [[package]] name = "serde" -version = "1.0.225" +version = "1.0.226" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd6c24dee235d0da097043389623fb913daddf92c76e9f5a1db88607a0bcbd1d" +checksum = "0dca6411025b24b60bfa7ec1fe1f8e710ac09782dca409ee8237ba74b51295fd" dependencies = [ "serde_core", "serde_derive", @@ -1993,18 +1999,18 @@ dependencies = [ [[package]] name = "serde_core" -version = "1.0.225" +version = "1.0.226" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "659356f9a0cb1e529b24c01e43ad2bdf520ec4ceaf83047b83ddcc2251f96383" +checksum = "ba2ba63999edb9dac981fb34b3e5c0d111a69b0924e253ed29d83f7c99e966a4" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.225" +version = "1.0.226" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ea936adf78b1f766949a4977b91d2f5595825bd6ec079aa9543ad2685fc4516" +checksum = "8db53ae22f34573731bafa1db20f04027b2d25e02d8205921b569171699cdb33" dependencies = [ "proc-macro2", "quote", @@ -2247,11 +2253,12 @@ dependencies = [ [[package]] name = "time" -version = "0.3.43" +version = "0.3.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83bde6f1ec10e72d583d91623c939f623002284ef622b87de38cfd546cbf2031" +checksum = "91e7d9e3bb61134e77bde20dd4825b97c010155709965fedf0f49bb138e52a9d" dependencies = [ "deranged", + "itoa", "num-conv", "powerfmt", "serde", diff --git a/extensions/VSCode/Cargo.toml b/extensions/VSCode/Cargo.toml index 64251679..91e83302 100644 --- a/extensions/VSCode/Cargo.toml +++ b/extensions/VSCode/Cargo.toml @@ -32,7 +32,7 @@ license = "GPL-3.0-only" name = "codechat-editor-vscode-extension" readme = "../README.md" repository = "https://github.com/bjones1/CodeChat_Editor" -version = "0.1.36" +version = "0.1.37" [lib] crate-type = ["cdylib"] diff --git a/extensions/VSCode/package.json b/extensions/VSCode/package.json index b6c02cd1..9b999f49 100644 --- a/extensions/VSCode/package.json +++ b/extensions/VSCode/package.json @@ -39,7 +39,7 @@ "type": "git", "url": "https://github.com/bjones1/CodeChat_Editor" }, - "version": "0.1.36", + "version": "0.1.37", "activationEvents": [ "onCommand:extension.codeChatEditorActivate", "onCommand:extension.codeChatEditorDeactivate" @@ -95,14 +95,14 @@ "@napi-rs/cli": "^3.2.0", "@tybys/wasm-util": "^0.10.1", "@types/escape-html": "^1.0.4", - "@types/node": "^24.5.1", + "@types/node": "^24.5.2", "@types/vscode": "1.61.0", - "@typescript-eslint/eslint-plugin": "^8.44.0", - "@typescript-eslint/parser": "^8.44.0", + "@typescript-eslint/eslint-plugin": "^8.44.1", + "@typescript-eslint/parser": "^8.44.1", "@vscode/vsce": "^3.6.0", "chalk": "^5.6.2", "esbuild": "^0.25.10", - "eslint": "^9.35.0", + "eslint": "^9.36.0", "eslint-config-prettier": "^10.1.8", "eslint-plugin-import": "^2.32.0", "eslint-plugin-node": "^11.1.0", diff --git a/extensions/VSCode/pnpm-lock.yaml b/extensions/VSCode/pnpm-lock.yaml index b780ca00..c2ec08b9 100644 --- a/extensions/VSCode/pnpm-lock.yaml +++ b/extensions/VSCode/pnpm-lock.yaml @@ -20,7 +20,7 @@ importers: version: 1.5.0 '@napi-rs/cli': specifier: ^3.2.0 - version: 3.2.0(@emnapi/runtime@1.5.0)(@types/node@24.5.1) + version: 3.2.0(@emnapi/runtime@1.5.0)(@types/node@24.5.2) '@tybys/wasm-util': specifier: ^0.10.1 version: 0.10.1 @@ -28,17 +28,17 @@ importers: specifier: ^1.0.4 version: 1.0.4 '@types/node': - specifier: ^24.5.1 - version: 24.5.1 + specifier: ^24.5.2 + version: 24.5.2 '@types/vscode': specifier: 1.61.0 version: 1.61.0 '@typescript-eslint/eslint-plugin': - specifier: ^8.44.0 - version: 8.44.0(@typescript-eslint/parser@8.44.0(eslint@9.35.0)(typescript@5.9.2))(eslint@9.35.0)(typescript@5.9.2) + specifier: ^8.44.1 + version: 8.44.1(@typescript-eslint/parser@8.44.1(eslint@9.36.0)(typescript@5.9.2))(eslint@9.36.0)(typescript@5.9.2) '@typescript-eslint/parser': - specifier: ^8.44.0 - version: 8.44.0(eslint@9.35.0)(typescript@5.9.2) + specifier: ^8.44.1 + version: 8.44.1(eslint@9.36.0)(typescript@5.9.2) '@vscode/vsce': specifier: ^3.6.0 version: 3.6.0 @@ -49,17 +49,17 @@ importers: specifier: ^0.25.10 version: 0.25.10 eslint: - specifier: ^9.35.0 - version: 9.35.0 + specifier: ^9.36.0 + version: 9.36.0 eslint-config-prettier: specifier: ^10.1.8 - version: 10.1.8(eslint@9.35.0) + version: 10.1.8(eslint@9.36.0) eslint-plugin-import: specifier: ^2.32.0 - version: 2.32.0(@typescript-eslint/parser@8.44.0(eslint@9.35.0)(typescript@5.9.2))(eslint@9.35.0) + version: 2.32.0(@typescript-eslint/parser@8.44.1(eslint@9.36.0)(typescript@5.9.2))(eslint@9.36.0) eslint-plugin-node: specifier: ^11.1.0 - version: 11.1.0(eslint@9.35.0) + version: 11.1.0(eslint@9.36.0) npm-run-all2: specifier: ^8.0.4 version: 8.0.4 @@ -328,8 +328,8 @@ packages: resolution: {integrity: sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@eslint/js@9.35.0': - resolution: {integrity: sha512-30iXE9whjlILfWobBkNerJo+TXYsgVM5ERQwMcMKCHckHflCmf7wXDAHlARoWnh0s1U72WqlbeyE7iAcCzuCPw==} + '@eslint/js@9.36.0': + resolution: {integrity: sha512-uhCbYtYynH30iZErszX78U+nR3pJU3RHGQ57NXy5QupD4SBVwDeU8TNBy+MjMngc1UyIW9noKqsRqfjQTBU2dw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@eslint/object-schema@2.1.6': @@ -1080,8 +1080,8 @@ packages: '@types/json5@0.0.29': resolution: {integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==} - '@types/node@24.5.1': - resolution: {integrity: sha512-/SQdmUP2xa+1rdx7VwB9yPq8PaKej8TD5cQ+XfKDPWWC+VDJU4rvVVagXqKUzhKjtFoNA8rXDJAkCxQPAe00+Q==} + '@types/node@24.5.2': + resolution: {integrity: sha512-FYxk1I7wPv3K2XBaoyH2cTnocQEu8AOZ60hPbsyukMPLv5/5qr7V1i8PLHdl6Zf87I+xZXFvPCXYjiTFq+YSDQ==} '@types/normalize-package-data@2.4.4': resolution: {integrity: sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==} @@ -1092,116 +1092,116 @@ packages: '@types/vscode@1.61.0': resolution: {integrity: sha512-9k5Nwq45hkRwdfCFY+eKXeQQSbPoA114mF7U/4uJXRBJeGIO7MuJdhF1PnaDN+lllL9iKGQtd6FFXShBXMNaFg==} - '@typescript-eslint/eslint-plugin@8.44.0': - resolution: {integrity: sha512-EGDAOGX+uwwekcS0iyxVDmRV9HX6FLSM5kzrAToLTsr9OWCIKG/y3lQheCq18yZ5Xh78rRKJiEpP0ZaCs4ryOQ==} + '@typescript-eslint/eslint-plugin@8.44.1': + resolution: {integrity: sha512-molgphGqOBT7t4YKCSkbasmu1tb1MgrZ2szGzHbclF7PNmOkSTQVHy+2jXOSnxvR3+Xe1yySHFZoqMpz3TfQsw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: - '@typescript-eslint/parser': ^8.44.0 + '@typescript-eslint/parser': ^8.44.1 eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/parser@8.44.0': - resolution: {integrity: sha512-VGMpFQGUQWYT9LfnPcX8ouFojyrZ/2w3K5BucvxL/spdNehccKhB4jUyB1yBCXpr2XFm0jkECxgrpXBW2ipoAw==} + '@typescript-eslint/parser@8.44.1': + resolution: {integrity: sha512-EHrrEsyhOhxYt8MTg4zTF+DJMuNBzWwgvvOYNj/zm1vnaD/IC5zCXFehZv94Piqa2cRFfXrTFxIvO95L7Qc/cw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/project-service@8.44.0': - resolution: {integrity: sha512-ZeaGNraRsq10GuEohKTo4295Z/SuGcSq2LzfGlqiuEvfArzo/VRrT0ZaJsVPuKZ55lVbNk8U6FcL+ZMH8CoyVA==} + '@typescript-eslint/project-service@8.44.1': + resolution: {integrity: sha512-ycSa60eGg8GWAkVsKV4E6Nz33h+HjTXbsDT4FILyL8Obk5/mx4tbvCNsLf9zret3ipSumAOG89UcCs/KRaKYrA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/scope-manager@8.44.0': - resolution: {integrity: sha512-87Jv3E+al8wpD+rIdVJm/ItDBe/Im09zXIjFoipOjr5gHUhJmTzfFLuTJ/nPTMc2Srsroy4IBXwcTCHyRR7KzA==} + '@typescript-eslint/scope-manager@8.44.1': + resolution: {integrity: sha512-NdhWHgmynpSvyhchGLXh+w12OMT308Gm25JoRIyTZqEbApiBiQHD/8xgb6LqCWCFcxFtWwaVdFsLPQI3jvhywg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/tsconfig-utils@8.44.0': - resolution: {integrity: sha512-x5Y0+AuEPqAInc6yd0n5DAcvtoQ/vyaGwuX5HE9n6qAefk1GaedqrLQF8kQGylLUb9pnZyLf+iEiL9fr8APDtQ==} + '@typescript-eslint/tsconfig-utils@8.44.1': + resolution: {integrity: sha512-B5OyACouEjuIvof3o86lRMvyDsFwZm+4fBOqFHccIctYgBjqR3qT39FBYGN87khcgf0ExpdCBeGKpKRhSFTjKQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/type-utils@8.44.0': - resolution: {integrity: sha512-9cwsoSxJ8Sak67Be/hD2RNt/fsqmWnNE1iHohG8lxqLSNY8xNfyY7wloo5zpW3Nu9hxVgURevqfcH6vvKCt6yg==} + '@typescript-eslint/type-utils@8.44.1': + resolution: {integrity: sha512-KdEerZqHWXsRNKjF9NYswNISnFzXfXNDfPxoTh7tqohU/PRIbwTmsjGK6V9/RTYWau7NZvfo52lgVk+sJh0K3g==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/types@8.44.0': - resolution: {integrity: sha512-ZSl2efn44VsYM0MfDQe68RKzBz75NPgLQXuGypmym6QVOWL5kegTZuZ02xRAT9T+onqvM6T8CdQk0OwYMB6ZvA==} + '@typescript-eslint/types@8.44.1': + resolution: {integrity: sha512-Lk7uj7y9uQUOEguiDIDLYLJOrYHQa7oBiURYVFqIpGxclAFQ78f6VUOM8lI2XEuNOKNB7XuvM2+2cMXAoq4ALQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/typescript-estree@8.44.0': - resolution: {integrity: sha512-lqNj6SgnGcQZwL4/SBJ3xdPEfcBuhCG8zdcwCPgYcmiPLgokiNDKlbPzCwEwu7m279J/lBYWtDYL+87OEfn8Jw==} + '@typescript-eslint/typescript-estree@8.44.1': + resolution: {integrity: sha512-qnQJ+mVa7szevdEyvfItbO5Vo+GfZ4/GZWWDRRLjrxYPkhM+6zYB2vRYwCsoJLzqFCdZT4mEqyJoyzkunsZ96A==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/utils@8.44.0': - resolution: {integrity: sha512-nktOlVcg3ALo0mYlV+L7sWUD58KG4CMj1rb2HUVOO4aL3K/6wcD+NERqd0rrA5Vg06b42YhF6cFxeixsp9Riqg==} + '@typescript-eslint/utils@8.44.1': + resolution: {integrity: sha512-DpX5Fp6edTlocMCwA+mHY8Mra+pPjRZ0TfHkXI8QFelIKcbADQz1LUPNtzOFUriBB2UYqw4Pi9+xV4w9ZczHFg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/visitor-keys@8.44.0': - resolution: {integrity: sha512-zaz9u8EJ4GBmnehlrpoKvj/E3dNbuQ7q0ucyZImm3cLqJ8INTc970B1qEqDX/Rzq65r3TvVTN7kHWPBoyW7DWw==} + '@typescript-eslint/visitor-keys@8.44.1': + resolution: {integrity: sha512-576+u0QD+Jp3tZzvfRfxon0EA2lzcDt3lhUbsC6Lgzy9x2VR4E+JUiNyGHi5T8vk0TV+fpJ5GLG1JsJuWCaKhw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@typespec/ts-http-runtime@0.3.1': resolution: {integrity: sha512-SnbaqayTVFEA6/tYumdF0UmybY0KHyKwGPBXnyckFlrrKdhWFrL3a2HIPXHjht5ZOElKGcXfD2D63P36btb+ww==} engines: {node: '>=20.0.0'} - '@vscode/vsce-sign-alpine-arm64@2.0.5': - resolution: {integrity: sha512-XVmnF40APwRPXSLYA28Ye+qWxB25KhSVpF2eZVtVOs6g7fkpOxsVnpRU1Bz2xG4ySI79IRuapDJoAQFkoOgfdQ==} + '@vscode/vsce-sign-alpine-arm64@2.0.6': + resolution: {integrity: sha512-wKkJBsvKF+f0GfsUuGT0tSW0kZL87QggEiqNqK6/8hvqsXvpx8OsTEc3mnE1kejkh5r+qUyQ7PtF8jZYN0mo8Q==} cpu: [arm64] os: [alpine] - '@vscode/vsce-sign-alpine-x64@2.0.5': - resolution: {integrity: sha512-JuxY3xcquRsOezKq6PEHwCgd1rh1GnhyH6urVEWUzWn1c1PC4EOoyffMD+zLZtFuZF5qR1I0+cqDRNKyPvpK7Q==} + '@vscode/vsce-sign-alpine-x64@2.0.6': + resolution: {integrity: sha512-YoAGlmdK39vKi9jA18i4ufBbd95OqGJxRvF3n6ZbCyziwy3O+JgOpIUPxv5tjeO6gQfx29qBivQ8ZZTUF2Ba0w==} cpu: [x64] os: [alpine] - '@vscode/vsce-sign-darwin-arm64@2.0.5': - resolution: {integrity: sha512-z2Q62bk0ptADFz8a0vtPvnm6vxpyP3hIEYMU+i1AWz263Pj8Mc38cm/4sjzxu+LIsAfhe9HzvYNS49lV+KsatQ==} + '@vscode/vsce-sign-darwin-arm64@2.0.6': + resolution: {integrity: sha512-5HMHaJRIQuozm/XQIiJiA0W9uhdblwwl2ZNDSSAeXGO9YhB9MH5C4KIHOmvyjUnKy4UCuiP43VKpIxW1VWP4tQ==} cpu: [arm64] os: [darwin] - '@vscode/vsce-sign-darwin-x64@2.0.5': - resolution: {integrity: sha512-ma9JDC7FJ16SuPXlLKkvOD2qLsmW/cKfqK4zzM2iJE1PbckF3BlR08lYqHV89gmuoTpYB55+z8Y5Fz4wEJBVDA==} + '@vscode/vsce-sign-darwin-x64@2.0.6': + resolution: {integrity: sha512-25GsUbTAiNfHSuRItoQafXOIpxlYj+IXb4/qarrXu7kmbH94jlm5sdWSCKrrREs8+GsXF1b+l3OB7VJy5jsykw==} cpu: [x64] os: [darwin] - '@vscode/vsce-sign-linux-arm64@2.0.5': - resolution: {integrity: sha512-Hr1o0veBymg9SmkCqYnfaiUnes5YK6k/lKFA5MhNmiEN5fNqxyPUCdRZMFs3Ajtx2OFW4q3KuYVRwGA7jdLo7Q==} + '@vscode/vsce-sign-linux-arm64@2.0.6': + resolution: {integrity: sha512-cfb1qK7lygtMa4NUl2582nP7aliLYuDEVpAbXJMkDq1qE+olIw/es+C8j1LJwvcRq1I2yWGtSn3EkDp9Dq5FdA==} cpu: [arm64] os: [linux] - '@vscode/vsce-sign-linux-arm@2.0.5': - resolution: {integrity: sha512-cdCwtLGmvC1QVrkIsyzv01+o9eR+wodMJUZ9Ak3owhcGxPRB53/WvrDHAFYA6i8Oy232nuen1YqWeEohqBuSzA==} + '@vscode/vsce-sign-linux-arm@2.0.6': + resolution: {integrity: sha512-UndEc2Xlq4HsuMPnwu7420uqceXjs4yb5W8E2/UkaHBB9OWCwMd3/bRe/1eLe3D8kPpxzcaeTyXiK3RdzS/1CA==} cpu: [arm] os: [linux] - '@vscode/vsce-sign-linux-x64@2.0.5': - resolution: {integrity: sha512-XLT0gfGMcxk6CMRLDkgqEPTyG8Oa0OFe1tPv2RVbphSOjFWJwZgK3TYWx39i/7gqpDHlax0AP6cgMygNJrA6zg==} + '@vscode/vsce-sign-linux-x64@2.0.6': + resolution: {integrity: sha512-/olerl1A4sOqdP+hjvJ1sbQjKN07Y3DVnxO4gnbn/ahtQvFrdhUi0G1VsZXDNjfqmXw57DmPi5ASnj/8PGZhAA==} cpu: [x64] os: [linux] - '@vscode/vsce-sign-win32-arm64@2.0.5': - resolution: {integrity: sha512-hco8eaoTcvtmuPhavyCZhrk5QIcLiyAUhEso87ApAWDllG7djIrWiOCtqn48k4pHz+L8oCQlE0nwNHfcYcxOPw==} + '@vscode/vsce-sign-win32-arm64@2.0.6': + resolution: {integrity: sha512-ivM/MiGIY0PJNZBoGtlRBM/xDpwbdlCWomUWuLmIxbi1Cxe/1nooYrEQoaHD8ojVRgzdQEUzMsRbyF5cJJgYOg==} cpu: [arm64] os: [win32] - '@vscode/vsce-sign-win32-x64@2.0.5': - resolution: {integrity: sha512-1ixKFGM2FwM+6kQS2ojfY3aAelICxjiCzeg4nTHpkeU1Tfs4RC+lVLrgq5NwcBC7ZLr6UfY3Ct3D6suPeOf7BQ==} + '@vscode/vsce-sign-win32-x64@2.0.6': + resolution: {integrity: sha512-mgth9Kvze+u8CruYMmhHw6Zgy3GRX2S+Ed5oSokDEK5vPEwGGKnmuXua9tmFhomeAnhgJnL4DCna3TiNuGrBTQ==} cpu: [x64] os: [win32] - '@vscode/vsce-sign@2.0.6': - resolution: {integrity: sha512-j9Ashk+uOWCDHYDxgGsqzKq5FXW9b9MW7QqOIYZ8IYpneJclWTBeHZz2DJCSKQgo+JAqNcaRRE1hzIx0dswqAw==} + '@vscode/vsce-sign@2.0.7': + resolution: {integrity: sha512-cz0GFW8qCxpypOy3y509u26K1FIPMlDIHBwGmDyvEbgoma2v3y5YIHHuijr8zCYBp9kzCCOJd28s/0PG7cA7ew==} '@vscode/vsce@3.6.0': resolution: {integrity: sha512-u2ZoMfymRNJb14aHNawnXJtXHLXDVKc1oKZaH4VELKT/9iWKRVgtQOdwxCgtwSxJoqYvuK4hGlBWQJ05wxADhg==} @@ -1672,8 +1672,8 @@ packages: resolution: {integrity: sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - eslint@9.35.0: - resolution: {integrity: sha512-QePbBFMJFjgmlE+cXAlbHZbHpdFVS2E/6vzCy7aKlebddvl1vadiC4JFV5u/wqTkNUwEV8WrQi257jf5f06hrg==} + eslint@9.36.0: + resolution: {integrity: sha512-hB4FIzXovouYzwzECDcUkJ4OcfOEkXTv2zRY6B9bkwjx/cprAq0uvm1nl7zvQ0/TsUk0zQiN4uPfJpB9m+rPMQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} hasBin: true peerDependencies: @@ -3129,9 +3129,9 @@ snapshots: '@esbuild/win32-x64@0.25.10': optional: true - '@eslint-community/eslint-utils@4.9.0(eslint@9.35.0)': + '@eslint-community/eslint-utils@4.9.0(eslint@9.36.0)': dependencies: - eslint: 9.35.0 + eslint: 9.36.0 eslint-visitor-keys: 3.4.3 '@eslint-community/regexpp@4.12.1': {} @@ -3164,7 +3164,7 @@ snapshots: transitivePeerDependencies: - supports-color - '@eslint/js@9.35.0': {} + '@eslint/js@9.36.0': {} '@eslint/object-schema@2.1.6': {} @@ -3186,128 +3186,128 @@ snapshots: '@inquirer/ansi@1.0.0': {} - '@inquirer/checkbox@4.2.4(@types/node@24.5.1)': + '@inquirer/checkbox@4.2.4(@types/node@24.5.2)': dependencies: '@inquirer/ansi': 1.0.0 - '@inquirer/core': 10.2.2(@types/node@24.5.1) + '@inquirer/core': 10.2.2(@types/node@24.5.2) '@inquirer/figures': 1.0.13 - '@inquirer/type': 3.0.8(@types/node@24.5.1) + '@inquirer/type': 3.0.8(@types/node@24.5.2) yoctocolors-cjs: 2.1.3 optionalDependencies: - '@types/node': 24.5.1 + '@types/node': 24.5.2 - '@inquirer/confirm@5.1.18(@types/node@24.5.1)': + '@inquirer/confirm@5.1.18(@types/node@24.5.2)': dependencies: - '@inquirer/core': 10.2.2(@types/node@24.5.1) - '@inquirer/type': 3.0.8(@types/node@24.5.1) + '@inquirer/core': 10.2.2(@types/node@24.5.2) + '@inquirer/type': 3.0.8(@types/node@24.5.2) optionalDependencies: - '@types/node': 24.5.1 + '@types/node': 24.5.2 - '@inquirer/core@10.2.2(@types/node@24.5.1)': + '@inquirer/core@10.2.2(@types/node@24.5.2)': dependencies: '@inquirer/ansi': 1.0.0 '@inquirer/figures': 1.0.13 - '@inquirer/type': 3.0.8(@types/node@24.5.1) + '@inquirer/type': 3.0.8(@types/node@24.5.2) cli-width: 4.1.0 mute-stream: 2.0.0 signal-exit: 4.1.0 wrap-ansi: 6.2.0 yoctocolors-cjs: 2.1.3 optionalDependencies: - '@types/node': 24.5.1 + '@types/node': 24.5.2 - '@inquirer/editor@4.2.20(@types/node@24.5.1)': + '@inquirer/editor@4.2.20(@types/node@24.5.2)': dependencies: - '@inquirer/core': 10.2.2(@types/node@24.5.1) - '@inquirer/external-editor': 1.0.2(@types/node@24.5.1) - '@inquirer/type': 3.0.8(@types/node@24.5.1) + '@inquirer/core': 10.2.2(@types/node@24.5.2) + '@inquirer/external-editor': 1.0.2(@types/node@24.5.2) + '@inquirer/type': 3.0.8(@types/node@24.5.2) optionalDependencies: - '@types/node': 24.5.1 + '@types/node': 24.5.2 - '@inquirer/expand@4.0.20(@types/node@24.5.1)': + '@inquirer/expand@4.0.20(@types/node@24.5.2)': dependencies: - '@inquirer/core': 10.2.2(@types/node@24.5.1) - '@inquirer/type': 3.0.8(@types/node@24.5.1) + '@inquirer/core': 10.2.2(@types/node@24.5.2) + '@inquirer/type': 3.0.8(@types/node@24.5.2) yoctocolors-cjs: 2.1.3 optionalDependencies: - '@types/node': 24.5.1 + '@types/node': 24.5.2 - '@inquirer/external-editor@1.0.2(@types/node@24.5.1)': + '@inquirer/external-editor@1.0.2(@types/node@24.5.2)': dependencies: chardet: 2.1.0 iconv-lite: 0.7.0 optionalDependencies: - '@types/node': 24.5.1 + '@types/node': 24.5.2 '@inquirer/figures@1.0.13': {} - '@inquirer/input@4.2.4(@types/node@24.5.1)': + '@inquirer/input@4.2.4(@types/node@24.5.2)': dependencies: - '@inquirer/core': 10.2.2(@types/node@24.5.1) - '@inquirer/type': 3.0.8(@types/node@24.5.1) + '@inquirer/core': 10.2.2(@types/node@24.5.2) + '@inquirer/type': 3.0.8(@types/node@24.5.2) optionalDependencies: - '@types/node': 24.5.1 + '@types/node': 24.5.2 - '@inquirer/number@3.0.20(@types/node@24.5.1)': + '@inquirer/number@3.0.20(@types/node@24.5.2)': dependencies: - '@inquirer/core': 10.2.2(@types/node@24.5.1) - '@inquirer/type': 3.0.8(@types/node@24.5.1) + '@inquirer/core': 10.2.2(@types/node@24.5.2) + '@inquirer/type': 3.0.8(@types/node@24.5.2) optionalDependencies: - '@types/node': 24.5.1 + '@types/node': 24.5.2 - '@inquirer/password@4.0.20(@types/node@24.5.1)': + '@inquirer/password@4.0.20(@types/node@24.5.2)': dependencies: '@inquirer/ansi': 1.0.0 - '@inquirer/core': 10.2.2(@types/node@24.5.1) - '@inquirer/type': 3.0.8(@types/node@24.5.1) + '@inquirer/core': 10.2.2(@types/node@24.5.2) + '@inquirer/type': 3.0.8(@types/node@24.5.2) optionalDependencies: - '@types/node': 24.5.1 - - '@inquirer/prompts@7.8.6(@types/node@24.5.1)': - dependencies: - '@inquirer/checkbox': 4.2.4(@types/node@24.5.1) - '@inquirer/confirm': 5.1.18(@types/node@24.5.1) - '@inquirer/editor': 4.2.20(@types/node@24.5.1) - '@inquirer/expand': 4.0.20(@types/node@24.5.1) - '@inquirer/input': 4.2.4(@types/node@24.5.1) - '@inquirer/number': 3.0.20(@types/node@24.5.1) - '@inquirer/password': 4.0.20(@types/node@24.5.1) - '@inquirer/rawlist': 4.1.8(@types/node@24.5.1) - '@inquirer/search': 3.1.3(@types/node@24.5.1) - '@inquirer/select': 4.3.4(@types/node@24.5.1) + '@types/node': 24.5.2 + + '@inquirer/prompts@7.8.6(@types/node@24.5.2)': + dependencies: + '@inquirer/checkbox': 4.2.4(@types/node@24.5.2) + '@inquirer/confirm': 5.1.18(@types/node@24.5.2) + '@inquirer/editor': 4.2.20(@types/node@24.5.2) + '@inquirer/expand': 4.0.20(@types/node@24.5.2) + '@inquirer/input': 4.2.4(@types/node@24.5.2) + '@inquirer/number': 3.0.20(@types/node@24.5.2) + '@inquirer/password': 4.0.20(@types/node@24.5.2) + '@inquirer/rawlist': 4.1.8(@types/node@24.5.2) + '@inquirer/search': 3.1.3(@types/node@24.5.2) + '@inquirer/select': 4.3.4(@types/node@24.5.2) optionalDependencies: - '@types/node': 24.5.1 + '@types/node': 24.5.2 - '@inquirer/rawlist@4.1.8(@types/node@24.5.1)': + '@inquirer/rawlist@4.1.8(@types/node@24.5.2)': dependencies: - '@inquirer/core': 10.2.2(@types/node@24.5.1) - '@inquirer/type': 3.0.8(@types/node@24.5.1) + '@inquirer/core': 10.2.2(@types/node@24.5.2) + '@inquirer/type': 3.0.8(@types/node@24.5.2) yoctocolors-cjs: 2.1.3 optionalDependencies: - '@types/node': 24.5.1 + '@types/node': 24.5.2 - '@inquirer/search@3.1.3(@types/node@24.5.1)': + '@inquirer/search@3.1.3(@types/node@24.5.2)': dependencies: - '@inquirer/core': 10.2.2(@types/node@24.5.1) + '@inquirer/core': 10.2.2(@types/node@24.5.2) '@inquirer/figures': 1.0.13 - '@inquirer/type': 3.0.8(@types/node@24.5.1) + '@inquirer/type': 3.0.8(@types/node@24.5.2) yoctocolors-cjs: 2.1.3 optionalDependencies: - '@types/node': 24.5.1 + '@types/node': 24.5.2 - '@inquirer/select@4.3.4(@types/node@24.5.1)': + '@inquirer/select@4.3.4(@types/node@24.5.2)': dependencies: '@inquirer/ansi': 1.0.0 - '@inquirer/core': 10.2.2(@types/node@24.5.1) + '@inquirer/core': 10.2.2(@types/node@24.5.2) '@inquirer/figures': 1.0.13 - '@inquirer/type': 3.0.8(@types/node@24.5.1) + '@inquirer/type': 3.0.8(@types/node@24.5.2) yoctocolors-cjs: 2.1.3 optionalDependencies: - '@types/node': 24.5.1 + '@types/node': 24.5.2 - '@inquirer/type@3.0.8(@types/node@24.5.1)': + '@inquirer/type@3.0.8(@types/node@24.5.2)': optionalDependencies: - '@types/node': 24.5.1 + '@types/node': 24.5.2 '@isaacs/balanced-match@4.0.1': {} @@ -3324,9 +3324,9 @@ snapshots: wrap-ansi: 8.1.0 wrap-ansi-cjs: wrap-ansi@7.0.0 - '@napi-rs/cli@3.2.0(@emnapi/runtime@1.5.0)(@types/node@24.5.1)': + '@napi-rs/cli@3.2.0(@emnapi/runtime@1.5.0)(@types/node@24.5.2)': dependencies: - '@inquirer/prompts': 7.8.6(@types/node@24.5.1) + '@inquirer/prompts': 7.8.6(@types/node@24.5.2) '@napi-rs/cross-toolchain': 1.0.3 '@napi-rs/wasm-tools': 1.0.1 '@octokit/rest': 22.0.0 @@ -3835,7 +3835,7 @@ snapshots: '@types/json5@0.0.29': {} - '@types/node@24.5.1': + '@types/node@24.5.2': dependencies: undici-types: 7.12.0 @@ -3845,15 +3845,15 @@ snapshots: '@types/vscode@1.61.0': {} - '@typescript-eslint/eslint-plugin@8.44.0(@typescript-eslint/parser@8.44.0(eslint@9.35.0)(typescript@5.9.2))(eslint@9.35.0)(typescript@5.9.2)': + '@typescript-eslint/eslint-plugin@8.44.1(@typescript-eslint/parser@8.44.1(eslint@9.36.0)(typescript@5.9.2))(eslint@9.36.0)(typescript@5.9.2)': dependencies: '@eslint-community/regexpp': 4.12.1 - '@typescript-eslint/parser': 8.44.0(eslint@9.35.0)(typescript@5.9.2) - '@typescript-eslint/scope-manager': 8.44.0 - '@typescript-eslint/type-utils': 8.44.0(eslint@9.35.0)(typescript@5.9.2) - '@typescript-eslint/utils': 8.44.0(eslint@9.35.0)(typescript@5.9.2) - '@typescript-eslint/visitor-keys': 8.44.0 - eslint: 9.35.0 + '@typescript-eslint/parser': 8.44.1(eslint@9.36.0)(typescript@5.9.2) + '@typescript-eslint/scope-manager': 8.44.1 + '@typescript-eslint/type-utils': 8.44.1(eslint@9.36.0)(typescript@5.9.2) + '@typescript-eslint/utils': 8.44.1(eslint@9.36.0)(typescript@5.9.2) + '@typescript-eslint/visitor-keys': 8.44.1 + eslint: 9.36.0 graphemer: 1.4.0 ignore: 7.0.5 natural-compare: 1.4.0 @@ -3862,56 +3862,56 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@8.44.0(eslint@9.35.0)(typescript@5.9.2)': + '@typescript-eslint/parser@8.44.1(eslint@9.36.0)(typescript@5.9.2)': dependencies: - '@typescript-eslint/scope-manager': 8.44.0 - '@typescript-eslint/types': 8.44.0 - '@typescript-eslint/typescript-estree': 8.44.0(typescript@5.9.2) - '@typescript-eslint/visitor-keys': 8.44.0 + '@typescript-eslint/scope-manager': 8.44.1 + '@typescript-eslint/types': 8.44.1 + '@typescript-eslint/typescript-estree': 8.44.1(typescript@5.9.2) + '@typescript-eslint/visitor-keys': 8.44.1 debug: 4.4.3 - eslint: 9.35.0 + eslint: 9.36.0 typescript: 5.9.2 transitivePeerDependencies: - supports-color - '@typescript-eslint/project-service@8.44.0(typescript@5.9.2)': + '@typescript-eslint/project-service@8.44.1(typescript@5.9.2)': dependencies: - '@typescript-eslint/tsconfig-utils': 8.44.0(typescript@5.9.2) - '@typescript-eslint/types': 8.44.0 + '@typescript-eslint/tsconfig-utils': 8.44.1(typescript@5.9.2) + '@typescript-eslint/types': 8.44.1 debug: 4.4.3 typescript: 5.9.2 transitivePeerDependencies: - supports-color - '@typescript-eslint/scope-manager@8.44.0': + '@typescript-eslint/scope-manager@8.44.1': dependencies: - '@typescript-eslint/types': 8.44.0 - '@typescript-eslint/visitor-keys': 8.44.0 + '@typescript-eslint/types': 8.44.1 + '@typescript-eslint/visitor-keys': 8.44.1 - '@typescript-eslint/tsconfig-utils@8.44.0(typescript@5.9.2)': + '@typescript-eslint/tsconfig-utils@8.44.1(typescript@5.9.2)': dependencies: typescript: 5.9.2 - '@typescript-eslint/type-utils@8.44.0(eslint@9.35.0)(typescript@5.9.2)': + '@typescript-eslint/type-utils@8.44.1(eslint@9.36.0)(typescript@5.9.2)': dependencies: - '@typescript-eslint/types': 8.44.0 - '@typescript-eslint/typescript-estree': 8.44.0(typescript@5.9.2) - '@typescript-eslint/utils': 8.44.0(eslint@9.35.0)(typescript@5.9.2) + '@typescript-eslint/types': 8.44.1 + '@typescript-eslint/typescript-estree': 8.44.1(typescript@5.9.2) + '@typescript-eslint/utils': 8.44.1(eslint@9.36.0)(typescript@5.9.2) debug: 4.4.3 - eslint: 9.35.0 + eslint: 9.36.0 ts-api-utils: 2.1.0(typescript@5.9.2) typescript: 5.9.2 transitivePeerDependencies: - supports-color - '@typescript-eslint/types@8.44.0': {} + '@typescript-eslint/types@8.44.1': {} - '@typescript-eslint/typescript-estree@8.44.0(typescript@5.9.2)': + '@typescript-eslint/typescript-estree@8.44.1(typescript@5.9.2)': dependencies: - '@typescript-eslint/project-service': 8.44.0(typescript@5.9.2) - '@typescript-eslint/tsconfig-utils': 8.44.0(typescript@5.9.2) - '@typescript-eslint/types': 8.44.0 - '@typescript-eslint/visitor-keys': 8.44.0 + '@typescript-eslint/project-service': 8.44.1(typescript@5.9.2) + '@typescript-eslint/tsconfig-utils': 8.44.1(typescript@5.9.2) + '@typescript-eslint/types': 8.44.1 + '@typescript-eslint/visitor-keys': 8.44.1 debug: 4.4.3 fast-glob: 3.3.3 is-glob: 4.0.3 @@ -3922,20 +3922,20 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/utils@8.44.0(eslint@9.35.0)(typescript@5.9.2)': + '@typescript-eslint/utils@8.44.1(eslint@9.36.0)(typescript@5.9.2)': dependencies: - '@eslint-community/eslint-utils': 4.9.0(eslint@9.35.0) - '@typescript-eslint/scope-manager': 8.44.0 - '@typescript-eslint/types': 8.44.0 - '@typescript-eslint/typescript-estree': 8.44.0(typescript@5.9.2) - eslint: 9.35.0 + '@eslint-community/eslint-utils': 4.9.0(eslint@9.36.0) + '@typescript-eslint/scope-manager': 8.44.1 + '@typescript-eslint/types': 8.44.1 + '@typescript-eslint/typescript-estree': 8.44.1(typescript@5.9.2) + eslint: 9.36.0 typescript: 5.9.2 transitivePeerDependencies: - supports-color - '@typescript-eslint/visitor-keys@8.44.0': + '@typescript-eslint/visitor-keys@8.44.1': dependencies: - '@typescript-eslint/types': 8.44.0 + '@typescript-eslint/types': 8.44.1 eslint-visitor-keys: 4.2.1 '@typespec/ts-http-runtime@0.3.1': @@ -3946,44 +3946,44 @@ snapshots: transitivePeerDependencies: - supports-color - '@vscode/vsce-sign-alpine-arm64@2.0.5': + '@vscode/vsce-sign-alpine-arm64@2.0.6': optional: true - '@vscode/vsce-sign-alpine-x64@2.0.5': + '@vscode/vsce-sign-alpine-x64@2.0.6': optional: true - '@vscode/vsce-sign-darwin-arm64@2.0.5': + '@vscode/vsce-sign-darwin-arm64@2.0.6': optional: true - '@vscode/vsce-sign-darwin-x64@2.0.5': + '@vscode/vsce-sign-darwin-x64@2.0.6': optional: true - '@vscode/vsce-sign-linux-arm64@2.0.5': + '@vscode/vsce-sign-linux-arm64@2.0.6': optional: true - '@vscode/vsce-sign-linux-arm@2.0.5': + '@vscode/vsce-sign-linux-arm@2.0.6': optional: true - '@vscode/vsce-sign-linux-x64@2.0.5': + '@vscode/vsce-sign-linux-x64@2.0.6': optional: true - '@vscode/vsce-sign-win32-arm64@2.0.5': + '@vscode/vsce-sign-win32-arm64@2.0.6': optional: true - '@vscode/vsce-sign-win32-x64@2.0.5': + '@vscode/vsce-sign-win32-x64@2.0.6': optional: true - '@vscode/vsce-sign@2.0.6': + '@vscode/vsce-sign@2.0.7': optionalDependencies: - '@vscode/vsce-sign-alpine-arm64': 2.0.5 - '@vscode/vsce-sign-alpine-x64': 2.0.5 - '@vscode/vsce-sign-darwin-arm64': 2.0.5 - '@vscode/vsce-sign-darwin-x64': 2.0.5 - '@vscode/vsce-sign-linux-arm': 2.0.5 - '@vscode/vsce-sign-linux-arm64': 2.0.5 - '@vscode/vsce-sign-linux-x64': 2.0.5 - '@vscode/vsce-sign-win32-arm64': 2.0.5 - '@vscode/vsce-sign-win32-x64': 2.0.5 + '@vscode/vsce-sign-alpine-arm64': 2.0.6 + '@vscode/vsce-sign-alpine-x64': 2.0.6 + '@vscode/vsce-sign-darwin-arm64': 2.0.6 + '@vscode/vsce-sign-darwin-x64': 2.0.6 + '@vscode/vsce-sign-linux-arm': 2.0.6 + '@vscode/vsce-sign-linux-arm64': 2.0.6 + '@vscode/vsce-sign-linux-x64': 2.0.6 + '@vscode/vsce-sign-win32-arm64': 2.0.6 + '@vscode/vsce-sign-win32-x64': 2.0.6 '@vscode/vsce@3.6.0': dependencies: @@ -3992,7 +3992,7 @@ snapshots: '@secretlint/secretlint-formatter-sarif': 10.2.2 '@secretlint/secretlint-rule-no-dotenv': 10.2.2 '@secretlint/secretlint-rule-preset-recommend': 10.2.2 - '@vscode/vsce-sign': 2.0.6 + '@vscode/vsce-sign': 2.0.7 azure-devops-node-api: 12.5.0 chalk: 4.1.2 cheerio: 1.1.2 @@ -4517,9 +4517,9 @@ snapshots: escape-string-regexp@4.0.0: {} - eslint-config-prettier@10.1.8(eslint@9.35.0): + eslint-config-prettier@10.1.8(eslint@9.36.0): dependencies: - eslint: 9.35.0 + eslint: 9.36.0 eslint-import-resolver-node@0.3.9: dependencies: @@ -4529,23 +4529,23 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-module-utils@2.12.1(@typescript-eslint/parser@8.44.0(eslint@9.35.0)(typescript@5.9.2))(eslint-import-resolver-node@0.3.9)(eslint@9.35.0): + eslint-module-utils@2.12.1(@typescript-eslint/parser@8.44.1(eslint@9.36.0)(typescript@5.9.2))(eslint-import-resolver-node@0.3.9)(eslint@9.36.0): dependencies: debug: 3.2.7 optionalDependencies: - '@typescript-eslint/parser': 8.44.0(eslint@9.35.0)(typescript@5.9.2) - eslint: 9.35.0 + '@typescript-eslint/parser': 8.44.1(eslint@9.36.0)(typescript@5.9.2) + eslint: 9.36.0 eslint-import-resolver-node: 0.3.9 transitivePeerDependencies: - supports-color - eslint-plugin-es@3.0.1(eslint@9.35.0): + eslint-plugin-es@3.0.1(eslint@9.36.0): dependencies: - eslint: 9.35.0 + eslint: 9.36.0 eslint-utils: 2.1.0 regexpp: 3.2.0 - eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.44.0(eslint@9.35.0)(typescript@5.9.2))(eslint@9.35.0): + eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.44.1(eslint@9.36.0)(typescript@5.9.2))(eslint@9.36.0): dependencies: '@rtsao/scc': 1.1.0 array-includes: 3.1.9 @@ -4554,9 +4554,9 @@ snapshots: array.prototype.flatmap: 1.3.3 debug: 3.2.7 doctrine: 2.1.0 - eslint: 9.35.0 + eslint: 9.36.0 eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.12.1(@typescript-eslint/parser@8.44.0(eslint@9.35.0)(typescript@5.9.2))(eslint-import-resolver-node@0.3.9)(eslint@9.35.0) + eslint-module-utils: 2.12.1(@typescript-eslint/parser@8.44.1(eslint@9.36.0)(typescript@5.9.2))(eslint-import-resolver-node@0.3.9)(eslint@9.36.0) hasown: 2.0.2 is-core-module: 2.16.1 is-glob: 4.0.3 @@ -4568,16 +4568,16 @@ snapshots: string.prototype.trimend: 1.0.9 tsconfig-paths: 3.15.0 optionalDependencies: - '@typescript-eslint/parser': 8.44.0(eslint@9.35.0)(typescript@5.9.2) + '@typescript-eslint/parser': 8.44.1(eslint@9.36.0)(typescript@5.9.2) transitivePeerDependencies: - eslint-import-resolver-typescript - eslint-import-resolver-webpack - supports-color - eslint-plugin-node@11.1.0(eslint@9.35.0): + eslint-plugin-node@11.1.0(eslint@9.36.0): dependencies: - eslint: 9.35.0 - eslint-plugin-es: 3.0.1(eslint@9.35.0) + eslint: 9.36.0 + eslint-plugin-es: 3.0.1(eslint@9.36.0) eslint-utils: 2.1.0 ignore: 5.3.2 minimatch: 3.1.2 @@ -4599,15 +4599,15 @@ snapshots: eslint-visitor-keys@4.2.1: {} - eslint@9.35.0: + eslint@9.36.0: dependencies: - '@eslint-community/eslint-utils': 4.9.0(eslint@9.35.0) + '@eslint-community/eslint-utils': 4.9.0(eslint@9.36.0) '@eslint-community/regexpp': 4.12.1 '@eslint/config-array': 0.21.0 '@eslint/config-helpers': 0.3.1 '@eslint/core': 0.15.2 '@eslint/eslintrc': 3.3.1 - '@eslint/js': 9.35.0 + '@eslint/js': 9.36.0 '@eslint/plugin-kit': 0.3.5 '@humanfs/node': 0.16.7 '@humanwhocodes/module-importer': 1.0.1 diff --git a/extensions/VSCode/src/extension.ts b/extensions/VSCode/src/extension.ts index eace1641..12fdc5f4 100644 --- a/extensions/VSCode/src/extension.ts +++ b/extensions/VSCode/src/extension.ts @@ -35,7 +35,6 @@ import { CodeChatEditorServer, initServer } from "./index"; // ### Local packages import { EditorMessage, - EditorMessageContents, MessageResult, UpdateMessageContents, } from "../../../client/src/shared_types.mjs"; @@ -48,10 +47,8 @@ enum CodeChatEditorClientLocation { } // The max length of a message to show in the console. const MAX_MESSAGE_LENGTH = 200; -// The timeout for a websocket `Response`, in ms. -const RESPONSE_TIMEOUT_MS = 15000; // True to enable additional debug logging. -const DEBUG_ENABLED = false; +const DEBUG_ENABLED = true; // True on Windows, false on OS X / Linux. const is_windows = process.platform === "win32"; @@ -74,17 +71,6 @@ let webview_panel: vscode.WebviewPanel | undefined; // A timer used to wait for additional events (keystrokes, etc.) before // performing a render. let idle_timer: NodeJS.Timeout | undefined; -// Use a unique ID for each websocket message sent. See the Implementation -// section on Message IDs for more information. -let message_id = -9007199254740989; -// A map of message id to (timer id, callback) for all pending messages. -const pending_messages: Record< - number, - { - timer_id: NodeJS.Timeout; - callback: (succeeded: boolean) => void; - } -> = {}; // The text editor containing the current file. let current_editor: vscode.TextEditor | undefined; // True to ignore the next change event, which is produced by applying an @@ -127,7 +113,7 @@ export const activate = (context: vscode.ExtensionContext) => { vscode.commands.registerCommand( "extension.codeChatEditorActivate", async () => { - console_log("CodeChat Editor extension starting."); + console_log("CodeChat Editor extension: starting."); if (!subscribed) { subscribed = true; @@ -141,6 +127,10 @@ export const activate = (context: vscode.ExtensionContext) => { if (event.contentChanges.length === 0) { return; } + if (ignore_text_document_change) { + ignore_text_document_change = false; + return; + } console_log( `CodeChat Editor extension: text changed - ${ event.reason @@ -152,7 +142,12 @@ export const activate = (context: vscode.ExtensionContext) => { // Render when the active editor changes. context.subscriptions.push( - vscode.window.onDidChangeActiveTextEditor((_event) => { + vscode.window.onDidChangeActiveTextEditor((event) => { + // If no text editor is active (for example, the + // CodeChat Editor has focus), ignore this update. + if (event === undefined) { + return; + } if (ignore_active_editor_change) { ignore_active_editor_change = false; return; @@ -285,14 +280,13 @@ export const activate = (context: vscode.ExtensionContext) => { console_log("CodeChat Editor extension: starting server."); codeChatEditorServer = new CodeChatEditorServer(get_port()); - console_log("CodeChat Editor extension: connected to server."); - await send_message({ - Opened: { - VSCode: - codechat_client_location === - CodeChatEditorClientLocation.html, - }, - }); + const hosted_in_ide = + codechat_client_location === + CodeChatEditorClientLocation.html; + console_log( + `CodeChat Editor extension: sending message Opened(${hosted_in_ide}).`, + ); + await codeChatEditorServer.sendMessageOpened(hosted_in_ide); // For the external browser, we can immediately send the // `CurrentFile` message. For the WebView, we must first wait to // receive the HTML for the WebView (the `ClientHtml` message). @@ -406,7 +400,6 @@ export const activate = (context: vscode.ExtensionContext) => { // The VSCode line is zero-based; the // CodeMirror line is one-based. line -= 1; - console_log(`Moving to line ${line}.`); const position = new vscode.Position( line, line, @@ -430,23 +423,27 @@ export const activate = (context: vscode.ExtensionContext) => { const current_file = value[0] as string; const is_text = value[1] as boolean | undefined; if (is_text) { - vscode.workspace - .openTextDocument(current_file) - .then( - (document) => { - ignore_active_editor_change = true; - vscode.window.showTextDocument( - document, - current_editor?.viewColumn, - ); - sendResult(id); - }, - (reason) => - sendResult( - id, - `Error: unable to open file ${current_file}: ${reason}`, - ), + let document; + try { + document = + await vscode.workspace.openTextDocument( + current_file, + ); + } catch (e) { + sendResult( + id, + `Error: unable to open file ${current_file}: ${e}`, ); + continue; + } + ignore_active_editor_change = true; + current_editor = + await vscode.window.showTextDocument( + document, + current_editor?.viewColumn, + ); + ignore_active_editor_change = false; + sendResult(id); } else { // TODO: open using a custom document editor. // See @@ -482,19 +479,6 @@ export const activate = (context: vscode.ExtensionContext) => { } case "Result": { - // Cancel the timer for this message and remove it - // from `pending_messages`. - const pending_message = pending_messages[id]; - if (pending_message !== undefined) { - const { timer_id, callback } = - pending_messages[id]; - clearTimeout(timer_id); - // eslint-disable-next-line - // n/no-callback-literal - callback(true); - delete pending_messages[id]; - } - // Report if this was an error. const result_contents = value as MessageResult; if ("Err" in result_contents) { @@ -512,6 +496,9 @@ export const activate = (context: vscode.ExtensionContext) => { const doc = get_document(load_file); const load_file_result = doc === undefined ? null : doc.getText(); + console_log( + `CodeChat Editor extension: Result(LoadFile(${format_struct(load_file_result)}))`, + ); codeChatEditorServer.sendResultLoadfile( id, load_file_result, @@ -546,41 +533,15 @@ export const activate = (context: vscode.ExtensionContext) => { // On deactivation, close everything down. export const deactivate = async () => { - console_log("CodeChat extension: deactivating."); + console_log("CodeChat Editor extension: deactivating."); await stop_client(); webview_panel?.dispose(); - console_log("CodeChat extension: deactivated."); + console_log("CodeChat Editor extension: deactivated."); }; // Supporting functions // -------------------- // -// Send a message expecting a result to the server. -const send_message = async ( - message: EditorMessageContents, - callback: (succeeded: boolean) => void = (_) => 0, -) => { - const id = message_id; - message_id += 3; - const jm: EditorMessage = { - id, - message, - }; - assert(codeChatEditorServer); - console_log( - `CodeChat Editor extension: sending message ${format_struct(jm)}.`, - ); - try { - await codeChatEditorServer.sendMessage(JSON.stringify(jm)); - } catch (e) { - console.error(`send_message: ${e}`); - } - pending_messages[id] = { - timer_id: setTimeout(report_server_timeout, RESPONSE_TIMEOUT_MS, id), - callback, - }; -}; - // Format a complex data structure as a string when in debug mode. const format_struct = (complex_data_structure: any): string => DEBUG_ENABLED @@ -590,21 +551,11 @@ const format_struct = (complex_data_structure: any): string => ) : ""; -// Report an error from the server. -const report_server_timeout = (message_id: number) => { - // Invoke the callback with an error. - pending_messages[message_id]?.callback(false); - - // Remove the message from the pending messages and report the error. - delete pending_messages[message_id]; - console.error(`Error: server timeout for message id ${message_id}`); -}; - // Send a result (a response to a message from the server) back to the server. const sendResult = (id: number, result: string | null = null) => { assert(codeChatEditorServer); console_log( - `CodeChat Editor extension: sending result ${format_struct(result)}.`, + `CodeChat Editor extension: sending result ${id}, ${format_struct(result)}.`, ); codeChatEditorServer.sendResult(id, result); }; @@ -627,10 +578,17 @@ const send_update = (this_is_dirty: boolean) => { // Send a new current file after a short delay; this allows // the user to rapidly cycle through several editors without // needing to reload the Client with each cycle. + console_log( + `CodeChat Editor extension: current_editor = ${current_editor?.document.fileName}, ate = ${ate.document.fileName}.`, + ); current_editor = ate; - await send_message({ - CurrentFile: [ate!.document.fileName, null], - }); + const current_file = ate!.document.fileName; + console_log( + `CodeChat Editor extension: sending CurrentFile(${current_file}}).`, + ); + await codeChatEditorServer!.sendMessageCurrentFile( + current_file, + ); // Since we just requested a new file, the contents are // clean by definition. is_dirty = false; @@ -646,26 +604,22 @@ const send_update = (this_is_dirty: boolean) => { // [Text.line](https://codemirror.net/docs/ref/#state.Text.line) // is 1-based. const current_line = ate.selection.active.line + 1; - const Update: UpdateMessageContents = { - file_path: ate.document.fileName, - cursor_position: current_line, - }; + const file_path = ate.document.fileName; + const cursor_position = current_line; // Send contents only if necessary. - if (is_dirty) { - Update.contents = { - metadata: { mode: "" }, - source: { - Plain: { - doc: ate.document.getText(), - doc_blocks: [], - }, - }, - }; - is_dirty = false; - } - await send_message({ - Update, - }); + const option_contents = is_dirty + ? ate.document.getText() + : null; + is_dirty = false; + console_log( + `CodeChat Editor extension: sending Update(${file_path}, ${cursor_position}, ${format_struct(cursor_position)})`, + ); + await codeChatEditorServer!.sendMessageUpdatePlain( + file_path, + option_contents, + cursor_position, + null, + ); } }, 300); } @@ -676,7 +630,7 @@ const send_update = (this_is_dirty: boolean) => { const stop_client = async () => { console_log("CodeChat Editor extension: stopping client."); if (codeChatEditorServer !== undefined) { - console_log("CodeChat Editor extension: ending connection."); + console_log("CodeChat Editor extension: stopping server."); await codeChatEditorServer.stopServer(); codeChatEditorServer = undefined; } diff --git a/extensions/VSCode/src/lib.rs b/extensions/VSCode/src/lib.rs index e32ae908..462c151e 100644 --- a/extensions/VSCode/src/lib.rs +++ b/extensions/VSCode/src/lib.rs @@ -22,6 +22,7 @@ // // ### Standard library use std::{ + collections::HashMap, net::{IpAddr, Ipv4Addr, SocketAddr}, path::PathBuf, sync::Arc, @@ -34,16 +35,26 @@ use log::LevelFilter; use napi::{Error, Status}; use napi_derive::napi; use rand::random; -use tokio::sync::{ - Mutex, - mpsc::{Receiver, Sender}, +use tokio::{ + runtime::Handle, + select, + sync::{ + Mutex, + mpsc::{self, Receiver, Sender}, + }, + task::JoinHandle, + time::sleep, }; // ### Local use code_chat_editor::{ ide::vscode::{connection_id_raw_to_str, vscode_ide_core}, + processing::{CodeChatForWeb, CodeMirror, CodeMirrorDiffable, SourceFileMetadata}, translation::{CreatedTranslationQueues, create_translation_queues}, - webserver::{self, EditorMessage, ResultOkTypes, WebAppState, setup_server}, + webserver::{ + self, EditorMessage, EditorMessageContents, INITIAL_IDE_MESSAGE_ID, MESSAGE_ID_INCREMENT, + REPLY_TIMEOUT_MS, ResultOkTypes, UpdateMessageContents, WebAppState, setup_server, + }, }; // Code @@ -65,7 +76,9 @@ pub fn init_server( } // Using this macro is critical -- otherwise, the Actix system doesn't get -// correctly initialized, which makes calls to `actix_rt::spawn` fail. +// correctly initialized, which makes calls to `actix_rt::spawn` fail. In +// addition, this ensures that the server runs in a separate thread, rather than +// depending on the extension to yield it time to run in the current thread. #[actix_web::main] async fn start_server( connection_id_raw: String, @@ -84,6 +97,10 @@ struct CodeChatEditorServer { server_handle: ServerHandle, from_ide_tx: Sender, to_ide_rx: Arc>>, + current_id: Arc>, + pending_messages: Arc>>>, + expired_messages_tx: Sender, + expired_messages_rx: Arc>>, } #[napi] @@ -131,10 +148,17 @@ impl CodeChatEditorServer { std::io::Error::other(format!("Unable to find queue named {connection_id}")) })?; + let (expired_messages_tx, expired_messages_rx) = mpsc::channel(100); Ok(CodeChatEditorServer { server_handle, from_ide_tx: websocket_queues.from_websocket_tx, to_ide_rx: Arc::new(Mutex::new(websocket_queues.to_websocket_rx)), + // Use a unique ID for each websocket message sent. See the + // Implementation section on Message IDs for more information. + current_id: Arc::new(Mutex::new(INITIAL_IDE_MESSAGE_ID)), + pending_messages: Arc::new(Mutex::new(HashMap::new())), + expired_messages_tx, + expired_messages_rx: Arc::new(Mutex::new(expired_messages_rx)), }) } @@ -143,7 +167,32 @@ impl CodeChatEditorServer { // otherwise. #[napi] pub async fn get_message(&self) -> Result, Error> { - match self.to_ide_rx.lock().await.recv().await { + // Get a message -- either an expired message result or an incoming + // message. + let mut to_ide_rx = self.to_ide_rx.lock().await; + let mut expired_messages_rx = self.expired_messages_rx.lock().await; + let editor_message = select! { + Some(m) = to_ide_rx.recv() => { + // Cancel the timer on this pending message. + if let Some(task) = self.pending_messages.lock().await.remove(&m.id.to_bits()) { + task.abort(); + } + // Return it. + Some(m) + }, + Some(id) = expired_messages_rx.recv() => + // Report this unacknowledged message. + Some( + EditorMessage { + id, + message: EditorMessageContents::Result(Err(format!("Timeout: message id {id} unacknowledged."))) + } + ), + else => None, + }; + + // Encode then deliver it. + match editor_message { Some(editor_message) => match serde_json::to_string(&editor_message) { Ok(v) => Ok(Some(v)), Err(err) => Err(Error::new(Status::GenericFailure, err.to_string())), @@ -152,38 +201,102 @@ impl CodeChatEditorServer { } } - // TODO: wait for a response; produce an error if no response after a timeout. - // Automatically generate an ID for each message. - async fn send_editor_message(&self, editor_message: EditorMessage) -> std::io::Result<()> { + // Send the provided message contents; add in an ID and add this to the list + // of pending messages. This produces a timeout of a matching `Result` + // message isn't received with the timeout. + async fn send_message_timeout( + &self, + editor_message_contents: EditorMessageContents, + ) -> std::io::Result<()> { + // Get and update the current ID. + let id = { + let mut id = self.current_id.lock().await; + let old_id = *id; + *id += MESSAGE_ID_INCREMENT; + old_id + }; + // Build the resulting message to send. + let editor_message = EditorMessage { + id, + message: editor_message_contents, + }; + + // Start a timeout in case the message isn't acknowledged. + let expired_messages_tx = self.expired_messages_tx.clone(); + // Important: there's already a Tokio runtime since this is an async + // function. Use that to spawn a new task; there's not an Actix + // System/Arbiter running in this thread. + let waiting_task = Handle::current().spawn(async move { + sleep(REPLY_TIMEOUT_MS).await; + // Since the websocket failed to send a `Result`, produce a timeout + // `Result` for it. + match expired_messages_tx.send(id).await { + Ok(join_handle) => join_handle, + Err(err) => { + eprintln!("Error -- unable to send expired message: {err}"); + } + } + }); + // Add this to the list of pending message. + self.pending_messages + .lock() + .await + .insert(editor_message.id.to_bits(), waiting_task); + + self.send_message_raw(editor_message).await + } + + // Send a message with no timeout or other additional steps. + async fn send_message_raw(&self, editor_message: EditorMessage) -> std::io::Result<()> { self.from_ide_tx .send(editor_message) .await .map_err(|e| std::io::Error::other(e.to_string())) } - // Given a JSON-encoded message, send it to the Client. This returns an - // error if string's contents can't be JSON decoded to an `EditorMessage`. #[napi] - pub async fn send_message( - &self, - // The `EditorMessage` to send, as a JSON-encoded string. - message: String, - ) -> std::io::Result<()> { - let editor_message = serde_json::from_str::(&message)?; - self.send_editor_message(editor_message).await + pub async fn send_message_opened(&self, hosted_in_ide: bool) -> std::io::Result<()> { + self.send_message_timeout(EditorMessageContents::Opened(webserver::IdeType::VSCode( + hosted_in_ide, + ))) + .await } - // TODO: not used yet; need to integrate in auto-result tracking, auto ID - // generation. #[napi] - pub async fn send_message_opened(&self, id: f64, hosted_in_ide: bool) -> std::io::Result<()> { - let editor_message = EditorMessage { - id, - message: webserver::EditorMessageContents::Opened(webserver::IdeType::VSCode( - hosted_in_ide, - )), - }; - self.send_editor_message(editor_message).await + // Send a `CurrentFile` message. The other parameter (true if text/false if + // binary/None if ignored) is ignored by the server, so it's always sent as + // `None`. + pub async fn send_message_current_file(&self, url: String) -> std::io::Result<()> { + self.send_message_timeout(EditorMessageContents::CurrentFile(url, None)) + .await + } + + #[napi] + // Send an `Update` message, optionally with plain text (instead of a diff) + // containing the source code from the IDE. + pub async fn send_message_update_plain( + &self, + file_path: String, + // `null` to send no source code; a string to send the source code. + option_contents: Option, + cursor_position: Option, + scroll_position: Option, + ) -> std::io::Result<()> { + self.send_message_timeout(EditorMessageContents::Update(UpdateMessageContents { + file_path, + contents: option_contents.map(|contents| CodeChatForWeb { + metadata: SourceFileMetadata { + mode: "".to_string(), + }, + source: CodeMirrorDiffable::Plain(CodeMirror { + doc: contents, + doc_blocks: vec![], + }), + }), + cursor_position, + scroll_position: scroll_position.map(|x| x as f32), + })) + .await } // Send either an Ok(Void) or an Error result to the Client. @@ -203,7 +316,7 @@ impl CodeChatEditorServer { }, ), }; - self.send_editor_message(editor_message).await + self.send_message_raw(editor_message).await } #[napi] @@ -212,18 +325,22 @@ impl CodeChatEditorServer { id: f64, load_file: Option, ) -> std::io::Result<()> { - let editor_message = EditorMessage { + self.send_message_raw(EditorMessage { id, - message: webserver::EditorMessageContents::Result(Ok(ResultOkTypes::LoadFile( - load_file, - ))), - }; - self.send_editor_message(editor_message).await + message: EditorMessageContents::Result(Ok(ResultOkTypes::LoadFile(load_file))), + }) + .await } // This returns after the server shuts down. #[napi] pub async fn stop_server(&self) { self.server_handle.stop(true).await; + // Stop all running timers. + for (_id, join_handle) in self.pending_messages.lock().await.drain() { + join_handle.abort(); + } + // Since the server is closing, don't report any expired message. + self.expired_messages_rx.lock().await.close(); } } diff --git a/server/Cargo.lock b/server/Cargo.lock index 2fafadc7..0de0f3ce 100644 --- a/server/Cargo.lock +++ b/server/Cargo.lock @@ -338,9 +338,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.99" +version = "1.0.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0674a1ddeecb70197781e945de4b3b8ffb61fa939a5597bcf48503737663100" +checksum = "a23eb6b1614318a8071c9b2521f36b424b2c83db5eb3a0fead4a6c0809af6e61" [[package]] name = "arc-swap" @@ -508,9 +508,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.2.37" +version = "1.2.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "65193589c6404eb80b450d618eaf9a2cafaaafd57ecce47370519ef674a7bd44" +checksum = "80f41ae168f955c12fb8960b057d70d0ca153fb83182b57d86380443527be7e9" dependencies = [ "find-msvc-tools", "jobserver", @@ -545,9 +545,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.47" +version = "4.5.48" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7eac00902d9d136acd712710d71823fb8ac8004ca445a89e73a41d45aa712931" +checksum = "e2134bb3ea021b78629caa971416385309e0131b351b25e01dc16fb54e1b5fae" dependencies = [ "clap_builder", "clap_derive", @@ -555,9 +555,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.47" +version = "4.5.48" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ad9bbf750e73b5884fb8a211a9424a1906c1e156724260fdae972f31d70e1d6" +checksum = "c2ba64afa3c0a6df7fa517765e31314e983f51dda798ffba27b988194fb65dc9" dependencies = [ "anstream", "anstyle", @@ -585,7 +585,7 @@ checksum = "b94f61472cee1439c0b966b47e3aca9ae07e45d070759512cd390ea2bebc6675" [[package]] name = "codechat-editor-server" -version = "0.1.36" +version = "0.1.37" dependencies = [ "actix-files", "actix-http", @@ -870,9 +870,9 @@ dependencies = [ [[package]] name = "find-msvc-tools" -version = "0.1.1" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fd99930f64d146689264c637b5af2f0233a933bef0d8570e2526bf9e083192d" +checksum = "1ced73b1dacfc750a6db6c0a0c3a3853c8b41997e2e2c563dc90804ae6867959" [[package]] name = "flate2" @@ -1057,6 +1057,12 @@ dependencies = [ "foldhash", ] +[[package]] +name = "hashbrown" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5419bdc4f6a9207fbeba6d11b604d481addf78ecd10c11ad51e76c2f6482748d" + [[package]] name = "heck" version = "0.5.0" @@ -1271,7 +1277,7 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2f01d462f766df78ab820dd06f5eb700233c51f0f4c2e846520eaf4ba6aa5c5c" dependencies = [ - "hashbrown", + "hashbrown 0.15.5", "memchr", ] @@ -1283,12 +1289,12 @@ checksum = "e8a5a9a0ff0086c7a148acb942baaabeadf9504d10400b5a05645853729b9cd2" [[package]] name = "indexmap" -version = "2.11.3" +version = "2.11.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92119844f513ffa41556430369ab02c295a3578af21cf945caa3e9e0c2481ac3" +checksum = "4b0f83760fb341a774ed326568e19f5a863af4a952def8c39f9ab92fd95b88e5" dependencies = [ "equivalent", - "hashbrown", + "hashbrown 0.16.0", ] [[package]] @@ -2070,9 +2076,9 @@ checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[package]] name = "serde" -version = "1.0.225" +version = "1.0.226" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd6c24dee235d0da097043389623fb913daddf92c76e9f5a1db88607a0bcbd1d" +checksum = "0dca6411025b24b60bfa7ec1fe1f8e710ac09782dca409ee8237ba74b51295fd" dependencies = [ "serde_core", "serde_derive", @@ -2090,18 +2096,18 @@ dependencies = [ [[package]] name = "serde_core" -version = "1.0.225" +version = "1.0.226" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "659356f9a0cb1e529b24c01e43ad2bdf520ec4ceaf83047b83ddcc2251f96383" +checksum = "ba2ba63999edb9dac981fb34b3e5c0d111a69b0924e253ed29d83f7c99e966a4" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.225" +version = "1.0.226" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ea936adf78b1f766949a4977b91d2f5595825bd6ec079aa9543ad2685fc4516" +checksum = "8db53ae22f34573731bafa1db20f04027b2d25e02d8205921b569171699cdb33" dependencies = [ "proc-macro2", "quote", @@ -2363,11 +2369,12 @@ dependencies = [ [[package]] name = "time" -version = "0.3.43" +version = "0.3.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83bde6f1ec10e72d583d91623c939f623002284ef622b87de38cfd546cbf2031" +checksum = "91e7d9e3bb61134e77bde20dd4825b97c010155709965fedf0f49bb138e52a9d" dependencies = [ "deranged", + "itoa", "num-conv", "powerfmt", "serde", diff --git a/server/Cargo.toml b/server/Cargo.toml index d429ee81..2b3f6451 100644 --- a/server/Cargo.toml +++ b/server/Cargo.toml @@ -32,7 +32,7 @@ license = "GPL-3.0-only" name = "codechat-editor-server" readme = "../README.md" repository = "https://github.com/bjones1/CodeChat_Editor" -version = "0.1.36" +version = "0.1.37" # This library allows other packages to use core CodeChat Editor features. [lib] diff --git a/server/src/ide/filewatcher.rs b/server/src/ide/filewatcher.rs index 4a8a34ca..af7af222 100644 --- a/server/src/ide/filewatcher.rs +++ b/server/src/ide/filewatcher.rs @@ -747,9 +747,10 @@ mod tests { }, test_utils::{check_logger_errors, configure_testing_logger}, webserver::{ - EditorMessage, EditorMessageContents, IdeType, ResultOkTypes, UpdateMessageContents, - WebAppState, WebsocketQueues, configure_app, drop_leading_slash, make_app_data, - send_response, set_root_path, tests::IP_PORT, + EditorMessage, EditorMessageContents, INITIAL_CLIENT_MESSAGE_ID, + INITIAL_IDE_MESSAGE_ID, INITIAL_MESSAGE_ID, IdeType, MESSAGE_ID_INCREMENT, + ResultOkTypes, UpdateMessageContents, WebAppState, WebsocketQueues, configure_app, + drop_leading_slash, make_app_data, send_response, set_root_path, tests::IP_PORT, }, }; @@ -821,14 +822,14 @@ mod tests { // The initial web request for the Client framework produces a // `CurrentFile`. // - // Message ids: IDE - 3->6, Server - 4, Client - 2. + // Message ids: IDE - 0->1, Server - 2, Client - 0. let (id, (url_string, is_text)) = get_message_as!( to_client_rx, EditorMessageContents::CurrentFile, file_name, is_text ); - assert_eq!(id, 3.0); + assert_eq!(id, INITIAL_IDE_MESSAGE_ID); assert_eq!(is_text, Some(true)); // Acknowledge it. send_response(&from_client_tx, id, Ok(ResultOkTypes::Void)).await; @@ -854,11 +855,9 @@ mod tests { let url_path = url_path.canonicalize().unwrap(); assert_eq!(url_path, test_path); - // 2. After fetching the file, we should get an update. The Server - // sends a `LoadFile` to the IDE using message id 4; therefore, the - // `Update` is ID 7, and the next message is ID 10. + // 2. After fetching the file, we should get an update. // - // Message ids: IDE - 6, Server - 4->10, Client - 2. + // Message ids: IDE - 1, Server - 2->3, Client - 0. let uri = format!( "/fw/fsc/1/{}/test.py", drop_leading_slash(&test_dir.to_slash().unwrap()) @@ -867,7 +866,7 @@ mod tests { let resp = test::call_service(&app, req).await; assert!(resp.status().is_success()); let (id, umc) = get_message_as!(to_client_rx, EditorMessageContents::Update); - assert_eq!(id, 7.0); + assert_eq!(id, INITIAL_MESSAGE_ID + 2.0 * MESSAGE_ID_INCREMENT); send_response(&from_client_tx, id, Ok(ResultOkTypes::Void)).await; // Check the contents. @@ -891,21 +890,21 @@ mod tests { // 1. The initial web request for the Client framework produces a // `CurrentFile`. // - // Message ids: IDE - 3->6, Server - 4, Client - 2. + // Message ids: IDE - 0->1, Server - 2, Client - 0. let (id, (..)) = get_message_as!( to_client_rx, EditorMessageContents::CurrentFile, file_name, is_text ); - assert_eq!(id, 3.0); + assert_eq!(id, INITIAL_IDE_MESSAGE_ID); send_response(&from_client_tx, id, Ok(ResultOkTypes::Void)).await; // 2. After fetching the file, we should get an update. The Server - // sends a `LoadFile` to the IDE using message id 4; therefore, the - // `Update` is ID 7, and the next message is ID 10. + // sends a `LoadFile` to the IDE using message the next ID; + // therefore, this consumes two IDs. // - // Message ids: IDE - 6, Server - 4->10, Client - 2. + // Message ids: IDE - 1, Server - 2->3, Client - 0. let mut file_path = test_dir.clone(); file_path.push("test.py"); let file_path = simplified(&file_path.canonicalize().unwrap()) @@ -920,15 +919,15 @@ mod tests { let resp = test::call_service(&app, req).await; assert!(resp.status().is_success()); let (id, _) = get_message_as!(to_client_rx, EditorMessageContents::Update); - assert_eq!(id, 7.0); + assert_eq!(id, INITIAL_MESSAGE_ID + 2.0 * MESSAGE_ID_INCREMENT); send_response(&from_client_tx, id, Ok(ResultOkTypes::Void)).await; // 3. Send an update message with no contents. // - // Message ids: IDE - 6, Server - 10, Client - 2->5. + // Message ids: IDE - 1, Server - 3, Client - 0->1. from_client_tx .send(EditorMessage { - id: 2.0, + id: INITIAL_CLIENT_MESSAGE_ID, message: EditorMessageContents::Update(UpdateMessageContents { file_path: file_path.clone(), contents: None, @@ -942,16 +941,25 @@ mod tests { // Check that it produces no error. assert_eq!( get_message_as!(to_client_rx, EditorMessageContents::Result), - (2.0, Ok(ResultOkTypes::Void)) + (INITIAL_CLIENT_MESSAGE_ID, Ok(ResultOkTypes::Void)) ); // 4. Send invalid messages. // - // Message ids: IDE - 6, Server - 10, Client - 5->14. + // Message ids: IDE - 1, Server - 3, Client - 1->4. for (id, msg) in [ - (5.0, EditorMessageContents::Opened(IdeType::VSCode(true))), - (8.0, EditorMessageContents::ClientHtml("".to_string())), - (11.0, EditorMessageContents::RequestClose), + ( + INITIAL_CLIENT_MESSAGE_ID + MESSAGE_ID_INCREMENT, + EditorMessageContents::Opened(IdeType::VSCode(true)), + ), + ( + INITIAL_CLIENT_MESSAGE_ID + 2.0 * MESSAGE_ID_INCREMENT, + EditorMessageContents::ClientHtml("".to_string()), + ), + ( + INITIAL_CLIENT_MESSAGE_ID + 3.0 * MESSAGE_ID_INCREMENT, + EditorMessageContents::RequestClose, + ), ] { from_client_tx .send(EditorMessage { id, message: msg }) @@ -964,10 +972,10 @@ mod tests { // 5. Send an update message with no path. // - // Message ids: IDE - 6, Server - 10, Client - 14->17. + // Message ids: IDE - 1, Server - 3, Client - 4->5. from_client_tx .send(EditorMessage { - id: 14.0, + id: INITIAL_CLIENT_MESSAGE_ID + 4.0 * MESSAGE_ID_INCREMENT, message: EditorMessageContents::Update(UpdateMessageContents { file_path: "".to_string(), contents: Some(CodeChatForWeb { @@ -988,7 +996,7 @@ mod tests { // Check that it produces an error. let (id, err_msg) = get_message_as!(to_client_rx, EditorMessageContents::Result); - assert_eq!(id, 14.0); + assert_eq!(id, INITIAL_CLIENT_MESSAGE_ID + 4.0 * MESSAGE_ID_INCREMENT); assert_starts_with!( cast!(err_msg, Err), "Update for file '' doesn't match current file" @@ -996,10 +1004,10 @@ mod tests { // 6. Send an update message with unknown source language. // - // Message ids: IDE - 6, Server - 10, Client - 17->20. + // Message ids: IDE - 1, Server - 3, Client - 5->6. from_client_tx .send(EditorMessage { - id: 17.0, + id: INITIAL_CLIENT_MESSAGE_ID + 5.0 * MESSAGE_ID_INCREMENT, message: EditorMessageContents::Update(UpdateMessageContents { file_path: file_path.clone(), contents: Some(CodeChatForWeb { @@ -1022,17 +1030,17 @@ mod tests { assert_eq!( get_message_as!(to_client_rx, EditorMessageContents::Result), ( - 17.0, + INITIAL_CLIENT_MESSAGE_ID + 5.0 * MESSAGE_ID_INCREMENT, Err("Unable to translate to source: Invalid mode".to_string()) ) ); // 7. Send a valid message. // - // Message ids: IDE - 6, Server - 10, Client - 20->23. + // Message ids: IDE - 1, Server - 3, Client - 6->7. from_client_tx .send(EditorMessage { - id: 20.0, + id: INITIAL_CLIENT_MESSAGE_ID + 6.0 * MESSAGE_ID_INCREMENT, message: EditorMessageContents::Update(UpdateMessageContents { file_path: file_path.clone(), contents: Some(CodeChatForWeb { @@ -1052,7 +1060,10 @@ mod tests { .unwrap(); assert_eq!( get_message_as!(to_client_rx, EditorMessageContents::Result), - (20.0, Ok(ResultOkTypes::Void)) + ( + INITIAL_CLIENT_MESSAGE_ID + 6.0 * MESSAGE_ID_INCREMENT, + Ok(ResultOkTypes::Void) + ) ); // Check that the requested file was written. @@ -1061,7 +1072,7 @@ mod tests { // 8. Change this file and verify that this produces an update. // - // Message ids: IDE - 6->9, Server - 10, Client - 23. + // Message ids: IDE - 1->2, Server - 3, Client - 7. s.push_str("123"); fs::write(&file_path, s).unwrap(); // Wait for the filewatcher to debounce this file write. @@ -1069,7 +1080,7 @@ mod tests { assert_eq!( get_message_as!(to_client_rx, EditorMessageContents::Update), ( - 6.0, + INITIAL_IDE_MESSAGE_ID + MESSAGE_ID_INCREMENT, UpdateMessageContents { file_path: file_path.clone(), contents: Some(CodeChatForWeb { @@ -1087,21 +1098,31 @@ mod tests { ) ); // Acknowledge this message. - send_response(&from_client_tx, 6.0, Ok(ResultOkTypes::Void)).await; + send_response( + &from_client_tx, + INITIAL_IDE_MESSAGE_ID + MESSAGE_ID_INCREMENT, + Ok(ResultOkTypes::Void), + ) + .await; // 9. Rename it and check for an close (the file watcher can't detect // the destination file, so it's treated as the file is deleted). // - // Message ids: IDE - 9->12, Server - 10, Client - 23. + // Message ids: IDE - 2->3, Server - 3, Client - 7. let mut dest = PathBuf::from(&file_path).parent().unwrap().to_path_buf(); dest.push("test2.py"); fs::rename(file_path, dest.as_path()).unwrap(); // Wait for the filewatcher to debounce this file write. sleep(Duration::from_secs(1)).await; let m = get_message(&mut to_client_rx).await; - assert_eq!(m.id, 9.0); + assert_eq!(m.id, INITIAL_IDE_MESSAGE_ID + 2.0 * MESSAGE_ID_INCREMENT); assert!(matches!(m.message, EditorMessageContents::Closed)); - send_response(&from_client_tx, 9.0, Ok(ResultOkTypes::Void)).await; + send_response( + &from_client_tx, + INITIAL_IDE_MESSAGE_ID + 2.0 * MESSAGE_ID_INCREMENT, + Ok(ResultOkTypes::Void), + ) + .await; // Each of the three invalid message types produces one error. check_logger_errors(5); diff --git a/server/src/ide/vscode.rs b/server/src/ide/vscode.rs index 19f23259..a3ce3c6f 100644 --- a/server/src/ide/vscode.rs +++ b/server/src/ide/vscode.rs @@ -45,9 +45,9 @@ use crate::{ translation_task, }, webserver::{ - EditorMessage, EditorMessageContents, IdeType, ResultOkTypes, WebAppState, - client_websocket, escape_html, filesystem_endpoint, get_client_framework, get_server_url, - html_wrapper, send_response, + EditorMessage, EditorMessageContents, IdeType, RESERVED_MESSAGE_ID, ResultOkTypes, + WebAppState, client_websocket, escape_html, filesystem_endpoint, get_client_framework, + get_server_url, html_wrapper, send_response, }, }; @@ -130,7 +130,7 @@ pub fn vscode_ide_core( send_response(&to_ide_tx, first_message.id, Err(msg)).await; // Send a `Closed` message to shut down the websocket. - queue_send!(to_ide_tx.send(EditorMessage { id: 0.0, message: EditorMessageContents::Closed}), 'task); + queue_send!(to_ide_tx.send(EditorMessage { id: RESERVED_MESSAGE_ID, message: EditorMessageContents::Closed}), 'task); break 'task; }; debug!("Received IDE Opened message."); @@ -169,7 +169,7 @@ pub fn vscode_ide_core( ); debug!("Sending ClientHtml message to IDE: {client_html}"); queue_send!(to_ide_tx.send(EditorMessage { - id: 0.0, + id: RESERVED_MESSAGE_ID, message: EditorMessageContents::ClientHtml(client_html) }), 'task); @@ -204,7 +204,7 @@ pub fn vscode_ide_core( error!("{err}"); // Send a `Closed` message. queue_send!(to_ide_tx.send(EditorMessage { - id: 1.0, + id: RESERVED_MESSAGE_ID + 1.0, message: EditorMessageContents::Closed }), 'task); break 'task; @@ -220,7 +220,7 @@ pub fn vscode_ide_core( // Send a `Closed` message. queue_send!(to_ide_tx.send(EditorMessage{ - id: 0.0, + id: RESERVED_MESSAGE_ID, message: EditorMessageContents::Closed }), 'task); break 'task; @@ -230,13 +230,13 @@ pub fn vscode_ide_core( } } _ => { - // This is the wrong IDE type. Report then error. + // This is the wrong IDE type. Report the error. let msg = format!("Invalid IDE type: {ide_type:?}"); error!("{msg}"); send_response(&to_ide_tx, first_message.id, Err(msg)).await; // Close the connection. - queue_send!(to_ide_tx.send(EditorMessage { id: 0.0, message: EditorMessageContents::Closed}), 'task); + queue_send!(to_ide_tx.send(EditorMessage { id: RESERVED_MESSAGE_ID, message: EditorMessageContents::Closed}), 'task); break 'task; } } diff --git a/server/src/ide/vscode/tests.rs b/server/src/ide/vscode/tests.rs index f41c963f..68168574 100644 --- a/server/src/ide/vscode/tests.rs +++ b/server/src/ide/vscode/tests.rs @@ -47,7 +47,10 @@ use tokio_tungstenite::{ tungstenite::{http::StatusCode, protocol::Message}, }; -use crate::webserver::{EditorMessage, EditorMessageContents, IdeType, tests::IP_PORT}; +use crate::webserver::{ + EditorMessage, EditorMessageContents, INITIAL_CLIENT_MESSAGE_ID, INITIAL_IDE_MESSAGE_ID, + INITIAL_MESSAGE_ID, IdeType, MESSAGE_ID_INCREMENT, tests::IP_PORT, +}; use crate::{ cast, processing::{ @@ -247,7 +250,7 @@ async fn test_vscode_ide_websocket1() { send_message( &mut ws_ide, &EditorMessage { - id: 0.0, + id: INITIAL_IDE_MESSAGE_ID, message: EditorMessageContents::Update(UpdateMessageContents { file_path: "".to_string(), contents: None, @@ -289,7 +292,7 @@ async fn test_vscode_ide_websocket2() { send_message( &mut ws_ide, &EditorMessage { - id: 0.0, + id: INITIAL_IDE_MESSAGE_ID, message: EditorMessageContents::Opened(IdeType::VSCode(false)), }, ) @@ -332,19 +335,19 @@ async fn test_vscode_ide_websocket3() { // The HTTP request produces a `LoadFile` message. // - // Message ids: IDE - 4, Server - 4->7, Client - 2. + // Message ids: IDE - 0, Server - 1->2, Client - 0. let em = read_message(&mut ws_ide).await; let msg = cast!(em.message, EditorMessageContents::LoadFile); // Compare these as strings -- we want to ensure the path separator is // correct for the current platform. assert_eq!(file_path.to_string_lossy(), msg.to_string_lossy()); - assert_eq!(em.id, 4.0); + assert_eq!(em.id, INITIAL_MESSAGE_ID + MESSAGE_ID_INCREMENT); // Reply to the `LoadFile` message -- the file isn't present. send_message( &mut ws_ide, &EditorMessage { - id: 4.0, + id: INITIAL_IDE_MESSAGE_ID, message: EditorMessageContents::Result(Ok(ResultOkTypes::LoadFile(None))), }, ) @@ -389,17 +392,17 @@ async fn test_vscode_ide_websocket3a() { // The HTTP request produces a `LoadFile` message. // - // Message ids: IDE - 4, Server - 4->7, Client - 2. + // Message ids: IDE - 0, Server - 0->2, Client - 0. let em = read_message(&mut ws_ide).await; cast!(em.message, EditorMessageContents::LoadFile); // Skip comparing the file names, due to the backslash encoding. - assert_eq!(em.id, 4.0); + assert_eq!(em.id, INITIAL_MESSAGE_ID + MESSAGE_ID_INCREMENT); // Reply to the `LoadFile` message -- the file isn't present. send_message( &mut ws_ide, &EditorMessage { - id: 4.0, + id: INITIAL_IDE_MESSAGE_ID, message: EditorMessageContents::Result(Ok(ResultOkTypes::LoadFile(None))), }, ) @@ -421,13 +424,13 @@ async fn test_vscode_ide_websocket8() { let (temp_dir, test_dir, mut ws_ide, mut ws_client) = prep_test!(connection_id).await; open_client(&mut ws_ide).await; - // Message ids: IDE - 4->7, Server - 4, Client - 2. + // Message ids: IDE - 0->1, Server - 0, Client - 0. let file_path = test_dir.join("only-in-ide.py"); let file_path_str = file_path.to_str().unwrap().to_string(); send_message( &mut ws_ide, &EditorMessage { - id: 4.0, + id: INITIAL_IDE_MESSAGE_ID, message: EditorMessageContents::CurrentFile(file_path_str.clone(), None), }, ) @@ -435,7 +438,7 @@ async fn test_vscode_ide_websocket8() { // This should be passed to the Client. let em = read_message(&mut ws_client).await; - assert_eq!(em.id, 4.0); + assert_eq!(em.id, INITIAL_IDE_MESSAGE_ID); assert_ends_with!( cast!( &em.message, @@ -451,7 +454,7 @@ async fn test_vscode_ide_websocket8() { send_message( &mut ws_client, &EditorMessage { - id: 4.0, + id: INITIAL_IDE_MESSAGE_ID, message: EditorMessageContents::Result(Ok(ResultOkTypes::Void)), }, ) @@ -461,7 +464,7 @@ async fn test_vscode_ide_websocket8() { assert_eq!( read_message(&mut ws_ide).await, EditorMessage { - id: 4.0, + id: INITIAL_IDE_MESSAGE_ID, message: EditorMessageContents::Result(Ok(ResultOkTypes::Void)) } ); @@ -483,20 +486,20 @@ async fn test_vscode_ide_websocket8() { // This should produce a `LoadFile` message. // - // Message ids: IDE - 7, Server - 4->7, Client - 2. + // Message ids: IDE - 1, Server - 1->2, Client - 0. let em = read_message(&mut ws_ide).await; let msg = cast!(em.message, EditorMessageContents::LoadFile); assert_eq!( path::absolute(Path::new(&msg)).unwrap(), path::absolute(&file_path).unwrap() ); - assert_eq!(em.id, 4.0); + assert_eq!(em.id, INITIAL_MESSAGE_ID + MESSAGE_ID_INCREMENT); // Reply to the `LoadFile` message with the file's contents. send_message( &mut ws_ide, &EditorMessage { - id: 4.0, + id: INITIAL_MESSAGE_ID + MESSAGE_ID_INCREMENT, message: EditorMessageContents::Result(Ok(ResultOkTypes::LoadFile(Some( "# testing".to_string(), )))), @@ -507,11 +510,11 @@ async fn test_vscode_ide_websocket8() { // This should also produce an `Update` message sent from the Server. // - // Message ids: IDE - 7, Server - 7->10, Client - 2. + // Message ids: IDE - 1, Server - 2->3, Client - 0. assert_eq!( read_message(&mut ws_client).await, EditorMessage { - id: 7.0, + id: INITIAL_MESSAGE_ID + 2.0 * MESSAGE_ID_INCREMENT, message: EditorMessageContents::Update(UpdateMessageContents { file_path: file_path_str.clone(), contents: Some(CodeChatForWeb { @@ -537,7 +540,7 @@ async fn test_vscode_ide_websocket8() { send_message( &mut ws_client, &EditorMessage { - id: 7.0, + id: INITIAL_MESSAGE_ID + 2.0 * MESSAGE_ID_INCREMENT, message: EditorMessageContents::Result(Ok(ResultOkTypes::Void)), }, ) @@ -548,7 +551,7 @@ async fn test_vscode_ide_websocket8() { assert_eq!( read_message(&mut ws_ide).await, EditorMessage { - id: 7.0, + id: INITIAL_MESSAGE_ID + 2.0 * MESSAGE_ID_INCREMENT, message: EditorMessageContents::Result(Ok(ResultOkTypes::Void)) } ); @@ -567,13 +570,13 @@ async fn test_vscode_ide_websocket7() { // Set the current file, so a subsequent `Update` message can be translated. // - // Message ids: IDE - 4, Server - 3, Client - 2->5. + // Message ids: IDE - 0, Server - 1, Client - 0->1. let file_path = test_dir.join("test.py"); let file_path_str = file_path.to_str().unwrap().to_string(); send_message( &mut ws_client, &EditorMessage { - id: 2.0, + id: INITIAL_CLIENT_MESSAGE_ID, message: EditorMessageContents::CurrentFile( format!( "http://localhost:8080/vsc/fs/{connection_id}/{}", @@ -594,12 +597,12 @@ async fn test_vscode_ide_websocket7() { assert_eq!(path::absolute(Path::new(&cf)).unwrap(), file_path); // Since the file doesn't exist, it's classified as binary by default. assert_eq!(is_text, Some(false)); - assert_eq!(em.id, 2.0); + assert_eq!(em.id, INITIAL_CLIENT_MESSAGE_ID); send_message( &mut ws_ide, &EditorMessage { - id: 2.0, + id: INITIAL_CLIENT_MESSAGE_ID, message: EditorMessageContents::Result(Ok(ResultOkTypes::Void)), }, ) @@ -607,18 +610,18 @@ async fn test_vscode_ide_websocket7() { assert_eq!( read_message(&mut ws_client).await, EditorMessage { - id: 2.0, + id: INITIAL_CLIENT_MESSAGE_ID, message: EditorMessageContents::Result(Ok(ResultOkTypes::Void)) } ); // Send an `Update` message. // - // Message ids: IDE - 4->7, Server - 3, Client - 5. + // Message ids: IDE - 0->1, Server - 1, Client - 1. send_message( &mut ws_ide, &EditorMessage { - id: 4.0, + id: INITIAL_IDE_MESSAGE_ID, message: EditorMessageContents::Update(UpdateMessageContents { file_path: file_path_str.clone(), contents: Some(CodeChatForWeb { @@ -639,7 +642,7 @@ async fn test_vscode_ide_websocket7() { assert_eq!( read_message(&mut ws_client).await, EditorMessage { - id: 4.0, + id: INITIAL_IDE_MESSAGE_ID, message: EditorMessageContents::Update(UpdateMessageContents { file_path: file_path_str.clone(), contents: Some(CodeChatForWeb { @@ -665,7 +668,7 @@ async fn test_vscode_ide_websocket7() { send_message( &mut ws_client, &EditorMessage { - id: 4.0, + id: INITIAL_IDE_MESSAGE_ID, message: EditorMessageContents::Result(Ok(ResultOkTypes::Void)), }, ) @@ -673,18 +676,18 @@ async fn test_vscode_ide_websocket7() { assert_eq!( read_message(&mut ws_ide).await, EditorMessage { - id: 4.0, + id: INITIAL_IDE_MESSAGE_ID, message: EditorMessageContents::Result(Ok(ResultOkTypes::Void)) } ); // Send a message with an update that produces a diff. // - // Message ids: IDE - 7->10, Server - 3, Client - 5. + // Message ids: IDE - 1->2, Server - 1, Client - 1. send_message( &mut ws_ide, &EditorMessage { - id: 7.0, + id: INITIAL_IDE_MESSAGE_ID + 2.0 * MESSAGE_ID_INCREMENT, message: EditorMessageContents::Update(UpdateMessageContents { file_path: file_path_str.clone(), contents: Some(CodeChatForWeb { @@ -711,7 +714,7 @@ async fn test_vscode_ide_websocket7() { assert_eq!( read_message(&mut ws_client).await, EditorMessage { - id: 7.0, + id: INITIAL_IDE_MESSAGE_ID + 2.0 * MESSAGE_ID_INCREMENT, message: EditorMessageContents::Update(UpdateMessageContents { file_path: file_path_str.clone(), contents: Some(CodeChatForWeb { @@ -741,7 +744,7 @@ async fn test_vscode_ide_websocket7() { send_message( &mut ws_client, &EditorMessage { - id: 7.0, + id: INITIAL_IDE_MESSAGE_ID + 2.0 * MESSAGE_ID_INCREMENT, message: EditorMessageContents::Result(Ok(ResultOkTypes::Void)), }, ) @@ -749,7 +752,7 @@ async fn test_vscode_ide_websocket7() { assert_eq!( read_message(&mut ws_ide).await, EditorMessage { - id: 7.0, + id: INITIAL_IDE_MESSAGE_ID + 2.0 * MESSAGE_ID_INCREMENT, message: EditorMessageContents::Result(Ok(ResultOkTypes::Void)) } ); @@ -766,12 +769,12 @@ async fn test_vscode_ide_websocket6() { let (temp_dir, test_dir, mut ws_ide, mut ws_client) = prep_test!(connection_id).await; open_client(&mut ws_ide).await; - // Message ids: IDE - 4, Server - 3, Client - 2->5. + // Message ids: IDE - 0, Server - 1, Client - 0->1. let file_path = test_dir.join("foo.py").to_string_lossy().to_string(); send_message( &mut ws_client, &EditorMessage { - id: 2.0, + id: INITIAL_CLIENT_MESSAGE_ID, message: EditorMessageContents::Update(UpdateMessageContents { file_path: file_path.clone(), contents: Some(CodeChatForWeb { @@ -798,7 +801,7 @@ async fn test_vscode_ide_websocket6() { assert_eq!( read_message(&mut ws_ide).await, EditorMessage { - id: 2.0, + id: INITIAL_CLIENT_MESSAGE_ID, message: EditorMessageContents::Update(UpdateMessageContents { file_path, contents: Some(CodeChatForWeb { @@ -818,7 +821,7 @@ async fn test_vscode_ide_websocket6() { send_message( &mut ws_ide, &EditorMessage { - id: 2.0, + id: INITIAL_CLIENT_MESSAGE_ID, message: EditorMessageContents::Result(Ok(ResultOkTypes::Void)), }, ) @@ -826,7 +829,7 @@ async fn test_vscode_ide_websocket6() { assert_eq!( read_message(&mut ws_client).await, EditorMessage { - id: 2.0, + id: INITIAL_CLIENT_MESSAGE_ID, message: EditorMessageContents::Result(Ok(ResultOkTypes::Void)) } ); @@ -844,14 +847,14 @@ async fn test_vscode_ide_websocket4() { let (temp_dir, test_dir, mut ws_ide, mut ws_client) = prep_test!(connection_id).await; open_client(&mut ws_ide).await; - // Message ids: IDE - 4, Server - 4, Client - 2->5. + // Message ids: IDE - 0, Server - 1, Client - 0->1. let file_path_temp = fs::canonicalize(test_dir.join("test.py")).unwrap(); let file_path = simplified(&file_path_temp); let file_path_str = file_path.to_str().unwrap().to_string(); send_message( &mut ws_client, &EditorMessage { - id: 2.0, + id: INITIAL_CLIENT_MESSAGE_ID, message: EditorMessageContents::CurrentFile( format!( "http://localhost:8080/vsc/fs/{connection_id}/{}", @@ -865,7 +868,7 @@ async fn test_vscode_ide_websocket4() { assert_eq!( read_message(&mut ws_ide).await, EditorMessage { - id: 2.0, + id: INITIAL_CLIENT_MESSAGE_ID, message: EditorMessageContents::CurrentFile(file_path_str.clone(), Some(true)) } ); @@ -873,7 +876,7 @@ async fn test_vscode_ide_websocket4() { send_message( &mut ws_ide, &EditorMessage { - id: 2.0, + id: INITIAL_CLIENT_MESSAGE_ID, message: EditorMessageContents::Result(Ok(ResultOkTypes::Void)), }, ) @@ -881,7 +884,7 @@ async fn test_vscode_ide_websocket4() { assert_eq!( read_message(&mut ws_client).await, EditorMessage { - id: 2.0, + id: INITIAL_CLIENT_MESSAGE_ID, message: EditorMessageContents::Result(Ok(ResultOkTypes::Void)) } ); @@ -907,17 +910,17 @@ async fn test_vscode_ide_websocket4() { // This should produce a `LoadFile` message. // - // Message ids: IDE - 4, Server - 4->7, Client - 5. + // Message ids: IDE - 0, Server - 1->2, Client - 1. let em = read_message(&mut ws_ide).await; let msg = cast!(em.message, EditorMessageContents::LoadFile); assert_eq!(fs::canonicalize(&msg).unwrap(), file_path_temp); - assert_eq!(em.id, 4.0); + assert_eq!(em.id, INITIAL_MESSAGE_ID + MESSAGE_ID_INCREMENT); // Reply to the `LoadFile` message: the IDE doesn't have the file. send_message( &mut ws_ide, &EditorMessage { - id: 4.0, + id: INITIAL_MESSAGE_ID + MESSAGE_ID_INCREMENT, message: EditorMessageContents::Result(Ok(ResultOkTypes::LoadFile(None))), }, ) @@ -926,11 +929,11 @@ async fn test_vscode_ide_websocket4() { // This should also produce an `Update` message sent from the Server. // - // Message ids: IDE - 4, Server - 7->10, Client - 5. + // Message ids: IDE - 0, Server - 2->3, Client - 0. assert_eq!( read_message(&mut ws_client).await, EditorMessage { - id: 7.0, + id: INITIAL_MESSAGE_ID + 2.0 * MESSAGE_ID_INCREMENT, message: EditorMessageContents::Update(UpdateMessageContents { file_path: file_path_str.clone(), contents: Some(CodeChatForWeb { @@ -956,7 +959,7 @@ async fn test_vscode_ide_websocket4() { send_message( &mut ws_client, &EditorMessage { - id: 7.0, + id: INITIAL_MESSAGE_ID + 2.0 * MESSAGE_ID_INCREMENT, message: EditorMessageContents::Result(Ok(ResultOkTypes::Void)), }, ) @@ -964,7 +967,7 @@ async fn test_vscode_ide_websocket4() { assert_eq!( read_message(&mut ws_ide).await, EditorMessage { - id: 7.0, + id: INITIAL_MESSAGE_ID + 2.0 * MESSAGE_ID_INCREMENT, message: EditorMessageContents::Result(Ok(ResultOkTypes::Void)), } ); @@ -986,20 +989,20 @@ async fn test_vscode_ide_websocket4() { // This should also produce a `LoadFile` message. // - // Message ids: IDE - 4, Server - 10->13, Client - 5. + // Message ids: IDE - 0, Server - 3->4, Client - 0. let em = read_message(&mut ws_ide).await; let msg = cast!(em.message, EditorMessageContents::LoadFile); assert_eq!( fs::canonicalize(&msg).unwrap(), fs::canonicalize(test_dir.join("toc.md")).unwrap() ); - assert_eq!(em.id, 10.0); + assert_eq!(em.id, INITIAL_MESSAGE_ID + 3.0 * MESSAGE_ID_INCREMENT); // Reply to the `LoadFile` message: the IDE doesn't have the file. send_message( &mut ws_ide, &EditorMessage { - id: 10.0, + id: INITIAL_MESSAGE_ID + 3.0 * MESSAGE_ID_INCREMENT, message: EditorMessageContents::Result(Ok(ResultOkTypes::LoadFile(None))), }, ) @@ -1008,11 +1011,11 @@ async fn test_vscode_ide_websocket4() { // Send an update from the Client, which should produce a diff. // - // Message ids: IDE - 4, Server - 13, Client - 5->8. + // Message ids: IDE - 0, Server - 4, Client - 0->1. send_message( &mut ws_client, &EditorMessage { - id: 5.0, + id: INITIAL_CLIENT_MESSAGE_ID + MESSAGE_ID_INCREMENT, message: EditorMessageContents::Update(UpdateMessageContents { file_path: file_path_str.clone(), contents: Some(CodeChatForWeb { @@ -1039,7 +1042,7 @@ async fn test_vscode_ide_websocket4() { assert_eq!( read_message(&mut ws_ide).await, EditorMessage { - id: 5.0, + id: INITIAL_CLIENT_MESSAGE_ID + MESSAGE_ID_INCREMENT, message: EditorMessageContents::Update(UpdateMessageContents { file_path: file_path_str.clone(), contents: Some(CodeChatForWeb { @@ -1063,7 +1066,7 @@ async fn test_vscode_ide_websocket4() { send_message( &mut ws_ide, &EditorMessage { - id: 5.0, + id: INITIAL_CLIENT_MESSAGE_ID + MESSAGE_ID_INCREMENT, message: EditorMessageContents::Result(Ok(ResultOkTypes::Void)), }, ) @@ -1071,7 +1074,7 @@ async fn test_vscode_ide_websocket4() { assert_eq!( read_message(&mut ws_client).await, EditorMessage { - id: 5.0, + id: INITIAL_CLIENT_MESSAGE_ID + MESSAGE_ID_INCREMENT, message: EditorMessageContents::Result(Ok(ResultOkTypes::Void)) } ); @@ -1089,14 +1092,14 @@ async fn test_vscode_ide_websocket4a() { let (temp_dir, test_dir, mut ws_ide, mut ws_client) = prep_test!(connection_id).await; open_client(&mut ws_ide).await; - // Message ids: IDE - 4, Server - 4, Client - 2->5. + // Message ids: IDE - 0, Server - 1, Client - 0->1. let hw = "helloworld.pdf"; let file_path_temp = fs::canonicalize(test_dir.join(hw)).unwrap(); let file_path = simplified(&file_path_temp); send_message( &mut ws_client, &EditorMessage { - id: 2.0, + id: INITIAL_CLIENT_MESSAGE_ID, message: EditorMessageContents::CurrentFile( format!( "http://localhost:8080/vsc/fs/{connection_id}/{}", @@ -1111,7 +1114,7 @@ async fn test_vscode_ide_websocket4a() { assert_eq!( read_message(&mut ws_ide).await, EditorMessage { - id: 2.0, + id: INITIAL_CLIENT_MESSAGE_ID, message: EditorMessageContents::CurrentFile( file_path.to_str().unwrap().to_string(), // `helloworld.pdf` is a text file! (But perhaps should mark all @@ -1124,7 +1127,7 @@ async fn test_vscode_ide_websocket4a() { send_message( &mut ws_ide, &EditorMessage { - id: 2.0, + id: INITIAL_CLIENT_MESSAGE_ID, message: EditorMessageContents::Result(Ok(ResultOkTypes::Void)), }, ) @@ -1132,7 +1135,7 @@ async fn test_vscode_ide_websocket4a() { assert_eq!( read_message(&mut ws_client).await, EditorMessage { - id: 2.0, + id: INITIAL_CLIENT_MESSAGE_ID, message: EditorMessageContents::Result(Ok(ResultOkTypes::Void)) } ); @@ -1160,17 +1163,17 @@ async fn test_vscode_ide_websocket4a() { // This should produce a `LoadFile` message. // - // Message ids: IDE - 4, Server - 4->7, Client - 5. + // Message ids: IDE - 0, Server - 1->2, Client - 1. let em = read_message(&mut ws_ide).await; let msg = cast!(em.message, EditorMessageContents::LoadFile); assert_eq!(fs::canonicalize(&msg).unwrap(), file_path_temp); - assert_eq!(em.id, 4.0); + assert_eq!(em.id, INITIAL_MESSAGE_ID + MESSAGE_ID_INCREMENT); // Reply to the `LoadFile` message: the IDE doesn't have the file. send_message( &mut ws_ide, &EditorMessage { - id: 4.0, + id: INITIAL_MESSAGE_ID + MESSAGE_ID_INCREMENT, message: EditorMessageContents::Result(Ok(ResultOkTypes::LoadFile(None))), }, ) @@ -1190,14 +1193,14 @@ async fn test_vscode_ide_websocket4b() { let (temp_dir, test_dir, mut ws_ide, mut ws_client) = prep_test!(connection_id).await; open_client(&mut ws_ide).await; - // Message ids: IDE - 4, Server - 4, Client - 2->5. + // Message ids: IDE - 0, Server - 1, Client - 0->1. let hw = "helloworld.pdf"; let file_path_temp = fs::canonicalize(test_dir.join(hw)).unwrap(); let file_path = simplified(&file_path_temp); send_message( &mut ws_client, &EditorMessage { - id: 2.0, + id: INITIAL_CLIENT_MESSAGE_ID, message: EditorMessageContents::CurrentFile( format!( "http://localhost:8080/vsc/fs/{connection_id}/{}", @@ -1212,7 +1215,7 @@ async fn test_vscode_ide_websocket4b() { assert_eq!( read_message(&mut ws_ide).await, EditorMessage { - id: 2.0, + id: INITIAL_CLIENT_MESSAGE_ID, message: EditorMessageContents::CurrentFile( file_path.to_str().unwrap().to_string(), // `helloworld.pdf` is a text file! (But perhaps should mark all @@ -1225,7 +1228,7 @@ async fn test_vscode_ide_websocket4b() { send_message( &mut ws_ide, &EditorMessage { - id: 2.0, + id: INITIAL_CLIENT_MESSAGE_ID, message: EditorMessageContents::Result(Ok(ResultOkTypes::Void)), }, ) @@ -1233,7 +1236,7 @@ async fn test_vscode_ide_websocket4b() { assert_eq!( read_message(&mut ws_client).await, EditorMessage { - id: 2.0, + id: INITIAL_CLIENT_MESSAGE_ID, message: EditorMessageContents::Result(Ok(ResultOkTypes::Void)) } ); @@ -1274,17 +1277,17 @@ async fn test_vscode_ide_websocket4b() { // This should produce a `LoadFile` message. // - // Message ids: IDE - 4, Server - 4->7, Client - 5. + // Message ids: IDE - 0, Server - 1->2, Client - 1. let em = read_message(&mut ws_ide).await; let msg = cast!(em.message, EditorMessageContents::LoadFile); assert_eq!(fs::canonicalize(&msg).unwrap(), file_path_temp); - assert_eq!(em.id, 4.0); + assert_eq!(em.id, INITIAL_MESSAGE_ID + MESSAGE_ID_INCREMENT); // Reply to the `LoadFile` message: the IDE doesn't have the file. send_message( &mut ws_ide, &EditorMessage { - id: 4.0, + id: INITIAL_MESSAGE_ID + MESSAGE_ID_INCREMENT, message: EditorMessageContents::Result(Ok(ResultOkTypes::LoadFile(None))), }, ) diff --git a/server/src/translation.rs b/server/src/translation.rs index 4e69b388..21a656fe 100644 --- a/server/src/translation.rs +++ b/server/src/translation.rs @@ -391,7 +391,6 @@ pub async fn translation_task( mut from_client_rx: Receiver, ) { // Start the processing task. - let connection_id = format!("{connection_id_prefix}{connection_id_raw}"); if !shutdown_only { // Use a [labeled block diff --git a/server/src/webserver.rs b/server/src/webserver.rs index ec8fa664..5efdae22 100644 --- a/server/src/webserver.rs +++ b/server/src/webserver.rs @@ -318,13 +318,13 @@ pub struct Credentials { #[macro_export] macro_rules! oneshot_send { // Provide two options: `break` or `break 'label`. - ($tx: expr_2021) => { + ($tx: expr) => { if let Err(err) = $tx { error!("Unable to enqueue: {err:?}"); break; } }; - ($tx: expr_2021, $label: tt) => { + ($tx: expr, $label: tt) => { if let Err(err) = $tx { error!("Unable to enqueue: {err:?}"); break $label; @@ -334,10 +334,10 @@ macro_rules! oneshot_send { #[macro_export] macro_rules! queue_send { - ($tx: expr_2021) => { + ($tx: expr) => { $crate::oneshot_send!($tx.await) }; - ($tx: expr_2021, $label: tt) => { + ($tx: expr, $label: tt) => { $crate::oneshot_send!($tx.await, $label) }; } @@ -346,7 +346,7 @@ macro_rules! queue_send { /// ------- // The timeout for a reply from a websocket, in ms. Use a short timeout to speed // up unit tests. -const REPLY_TIMEOUT_MS: Duration = if cfg!(test) { +pub const REPLY_TIMEOUT_MS: Duration = if cfg!(test) { Duration::from_millis(500) } else { Duration::from_millis(15000) @@ -356,18 +356,10 @@ const REPLY_TIMEOUT_MS: Duration = if cfg!(test) { /// this server. const WEBSOCKET_PING_DELAY: Duration = Duration::from_secs(2); -/// A message ID which won't be used by anything but a `Result` produced by an -/// error not produced in response to a message. -pub const RESERVED_MESSAGE_ID: f64 = if cfg!(test) { - // A simpler value when testing. - 0.0 -} else { - // In production, start with the smallest whole number exactly - // representable. This is -9007199254740991. - -((1i64 << f64::MANTISSA_DIGITS) - 1) as f64 -}; +/// A few message IDs reserve for used during startup or for sending errors. +pub const RESERVED_MESSAGE_ID: f64 = 0.0; /// The initial value for the server's message ID. -pub const INITIAL_MESSAGE_ID: f64 = RESERVED_MESSAGE_ID + 1.0; +pub const INITIAL_MESSAGE_ID: f64 = RESERVED_MESSAGE_ID + 3.0; // The initial value for a Client. pub const INITIAL_CLIENT_MESSAGE_ID: f64 = INITIAL_MESSAGE_ID + 1.0; // The initial value for an IDE. @@ -1273,6 +1265,11 @@ pub fn client_websocket( while let Some(m) = to_websocket_rx.recv().await { warn!("Dropped queued message {m:?}"); } + to_websocket_rx.close(); + // Stop all timers. + for (_id, join_handle) in pending_messages.drain() { + join_handle.abort(); + } } else { info!("Websocket re-enqueued."); websocket_queues.lock().unwrap().insert( @@ -1308,9 +1305,11 @@ pub async fn main( // called before the server is run. pub fn init_server(extension_base_path: Option<&Path>, level: LevelFilter) -> std::io::Result<()> { set_root_path(extension_base_path)?; - #[cfg(debug_assertions)] + // The unit tests include a test logger; don't config the logger in a test + // build. + #[cfg(test)] let _ = level; - #[cfg(not(debug_assertions))] + #[cfg(not(test))] configure_logger(level).map_err(|e| std::io::Error::other(e.to_string()))?; Ok(()) }