From 18f0616d670d948739c9669934e805cd57e0c38f Mon Sep 17 00:00:00 2001 From: Isak Date: Mon, 28 Apr 2025 13:27:56 +0200 Subject: [PATCH 01/10] creates the lint-worker package WIP --- packages/lint-worker/LICENSE.md | 201 +++++++++++++++++++++++++ packages/lint-worker/README.md | 3 + packages/lint-worker/package-lock.json | 91 +++++++++++ packages/lint-worker/package.json | 51 +++++++ packages/lint-worker/src/index.ts | 1 + packages/lint-worker/src/lintWorker.ts | 67 +++++++++ packages/lint-worker/tsconfig.json | 11 ++ 7 files changed, 425 insertions(+) create mode 100644 packages/lint-worker/LICENSE.md create mode 100644 packages/lint-worker/README.md create mode 100644 packages/lint-worker/package-lock.json create mode 100644 packages/lint-worker/package.json create mode 100644 packages/lint-worker/src/index.ts create mode 100644 packages/lint-worker/src/lintWorker.ts create mode 100644 packages/lint-worker/tsconfig.json diff --git a/packages/lint-worker/LICENSE.md b/packages/lint-worker/LICENSE.md new file mode 100644 index 000000000..684e2f094 --- /dev/null +++ b/packages/lint-worker/LICENSE.md @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + https://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright 2023 Neo4j Inc. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + https://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/packages/lint-worker/README.md b/packages/lint-worker/README.md new file mode 100644 index 000000000..9f74d616d --- /dev/null +++ b/packages/lint-worker/README.md @@ -0,0 +1,3 @@ +# Language Support + +This package contains the cypher lint worker used in both the language server and react-codemirror. diff --git a/packages/lint-worker/package-lock.json b/packages/lint-worker/package-lock.json new file mode 100644 index 000000000..6fa0377c7 --- /dev/null +++ b/packages/lint-worker/package-lock.json @@ -0,0 +1,91 @@ +{ + "name": "@neo4j-cypher/lint-worker", + "version": "5.25.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "@neo4j-cypher/lint-worker", + "version": "5.25.0", + "license": "Apache-2.0", + "dependencies": { + "@neo4j-cypher/language-support": "2.0.0-next.10", + "workerpool": "^9.0.4" + }, + "devDependencies": { + "@types/lodash.debounce": "^4.0.9" + }, + "engines": { + "node": ">=18.18.2" + } + }, + "node_modules/@neo4j-cypher/language-support": { + "version": "2.0.0-next.10", + "resolved": "https://registry.npmjs.org/@neo4j-cypher/language-support/-/language-support-2.0.0-next.10.tgz", + "integrity": "sha512-KQuyVBTEzYJQYjqcKDiqVDavJgbG1HWDRH5clgnnbsWt/2pmy8NbT3OoycdiuPjvsG6QVLHZkcFIsVThHAgrxw==", + "dependencies": { + "antlr4": "*", + "antlr4-c3": "*", + "fastest-levenshtein": "^1.0.16", + "vscode-languageserver-types": "^3.17.3" + }, + "engines": { + "node": ">=18.18.2" + } + }, + "node_modules/@types/lodash": { + "version": "4.17.16", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.16.tgz", + "integrity": "sha512-HX7Em5NYQAXKW+1T+FiuG27NGwzJfCX3s1GjOa7ujxZa52kjJLOr4FUxT+giF6Tgxv1e+/czV/iTtBw27WTU9g==", + "dev": true + }, + "node_modules/@types/lodash.debounce": { + "version": "4.0.9", + "resolved": "https://registry.npmjs.org/@types/lodash.debounce/-/lodash.debounce-4.0.9.tgz", + "integrity": "sha512-Ma5JcgTREwpLRwMM+XwBR7DaWe96nC38uCBDFKZWbNKD+osjVzdpnUSwBcqCptrp16sSOLBAUb50Car5I0TCsQ==", + "dev": true, + "dependencies": { + "@types/lodash": "*" + } + }, + "node_modules/antlr4": { + "version": "4.13.2", + "resolved": "https://registry.npmjs.org/antlr4/-/antlr4-4.13.2.tgz", + "integrity": "sha512-QiVbZhyy4xAZ17UPEuG3YTOt8ZaoeOR1CvEAqrEsDBsOqINslaB147i9xqljZqoyf5S+EUlGStaj+t22LT9MOg==", + "engines": { + "node": ">=16" + } + }, + "node_modules/antlr4-c3": { + "version": "3.4.4", + "resolved": "https://registry.npmjs.org/antlr4-c3/-/antlr4-c3-3.4.4.tgz", + "integrity": "sha512-ixp1i17ypbRzZnffdarIfCVEXJwPydtDt61SHMGkc+UCD7rrbfvHESTMTgx8jFhUgKAgcHyt9060kQ8nU3vlxA==", + "dependencies": { + "antlr4ng": "3.0.16" + } + }, + "node_modules/antlr4ng": { + "version": "3.0.16", + "resolved": "https://registry.npmjs.org/antlr4ng/-/antlr4ng-3.0.16.tgz", + "integrity": "sha512-DQuJkC7kX3xunfF4K2KsWTSvoxxslv+FQp/WHQZTJSsH2Ec3QfFmrxC3Nky2ok9yglXn6nHM4zUaVDxcN5f6kA==" + }, + "node_modules/fastest-levenshtein": { + "version": "1.0.16", + "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz", + "integrity": "sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==", + "engines": { + "node": ">= 4.9.1" + } + }, + "node_modules/vscode-languageserver-types": { + "version": "3.17.5", + "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.17.5.tgz", + "integrity": "sha512-Ld1VelNuX9pdF39h2Hgaeb5hEZM2Z3jUrrMgWQAu82jMtZp7p3vJT3BzToKtZI7NgQssZje5o0zryOrhQvzQAg==" + }, + "node_modules/workerpool": { + "version": "9.2.0", + "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-9.2.0.tgz", + "integrity": "sha512-PKZqBOCo6CYkVOwAxWxQaSF2Fvb5Iv2fCeTP7buyWI2GiynWr46NcXSgK/idoV6e60dgCBfgYc+Un3HMvmqP8w==" + } + } +} diff --git a/packages/lint-worker/package.json b/packages/lint-worker/package.json new file mode 100644 index 000000000..ea4afd85a --- /dev/null +++ b/packages/lint-worker/package.json @@ -0,0 +1,51 @@ +{ + "name": "@neo4j-cypher/lint-worker", + "description": "Cypher Lint Worker", + "author": "Neo4j Inc.", + "license": "Apache-2.0", + "files": [ + "./dist/for-language-server/lintWorker.js", + "./src", + "package.json", + "README.md", + "LICENSE.md", + "CHANGELOG.md" + ], + "keywords": [ + "neo4j", + "cypher", + "lint worker" + ], + "version": "6.26.0", + "repository": { + "type": "git", + "url": "git://github.com/neo4j/cypher-language-support.git" + }, + "bugs": { + "url": "https://github.com/neo4j/cypher-language-support/issues" + }, + "engineStrict": true, + "engines": { + "node": ">=18.18.2" + }, + "dependencies": { + "@neo4j-cypher/language-support": "2.0.0-next.4", + "@neo4j-cypher/language-support-new": "npm:@neo4j-cypher/language-support@2.0.0-next.19", + "workerpool": "^9.0.4" + }, + "scripts": { + "build": "esbuild ./src/index.ts --bundle --platform=node --outfile=dist/index.mjs --format=esm --minify && pnpm bundle-for-language-server", + "bundle-for-language-server": "esbuild ./src/lintWorker.ts --bundle --format=cjs --platform=node --outfile=dist/for-language-server/lintWorker.js --minify", + "clean": "rm -rf dist" + }, + "devDependencies": { + "@types/lodash.debounce": "^4.0.9" + }, + "exports": { + ".": { + "require": "./dist/index.mjs", + "import": "./dist/index.mjs", + "default": "./dist/index.mjs" + } + } +} diff --git a/packages/lint-worker/src/index.ts b/packages/lint-worker/src/index.ts new file mode 100644 index 000000000..489097adf --- /dev/null +++ b/packages/lint-worker/src/index.ts @@ -0,0 +1 @@ +export * from './lintWorker'; diff --git a/packages/lint-worker/src/lintWorker.ts b/packages/lint-worker/src/lintWorker.ts new file mode 100644 index 000000000..07eae3aab --- /dev/null +++ b/packages/lint-worker/src/lintWorker.ts @@ -0,0 +1,67 @@ +import { + DbSchema as DbSchemaNew, + Neo4jFunction, +} from '@neo4j-cypher/language-support-new'; +import { + DbSchema, + // lintCypherQuery as _lintCypherQuery, + // _internalFeatureFlags, + validateSyntax, + validateSemantics, + Neo4jProcedure, +} from '@neo4j-cypher/language-support'; +import workerpool from 'workerpool'; + +export default new URL('./lintWorker.ts?worker', import.meta.url).href; + +function lintCypherQuery( + query: string, + dbSchema: DbSchemaNew, + //featureFlags: { consoleCommands?: boolean; cypher25?: boolean } = {}, +) { + //console.log("Entering lintCypherQuery in worker with featureflags", featureFlags) + // We allow to override the consoleCommands feature flag + // if (featureFlags.consoleCommands !== undefined) { + // _internalFeatureFlags.consoleCommands = featureFlags.consoleCommands; + // } + // if (featureFlags.cypher25 !== undefined) { + // _internalFeatureFlags.cypher25 = featureFlags.cypher25; + // } + if (dbSchema.procedures && dbSchema.functions) { + const oldSchema: DbSchema = { + procedures: dbSchema.procedures['CYPHER 5'] as Record< + string, + Neo4jProcedure + >, + functions: dbSchema.functions['CYPHER 5'] as Record< + string, + Neo4jFunction + >, + labels: dbSchema.labels, + relationshipTypes: dbSchema.relationshipTypes, + databaseNames: dbSchema.databaseNames, + aliasNames: dbSchema.aliasNames, + // userNames: dbSchema.userNames, + // roleNames: dbSchema.roleNames, + parameters: dbSchema.parameters, + propertyKeys: dbSchema.propertyKeys, + }; + const syntaxErrors = validateSyntax(query, oldSchema); + const semanticErrors = + syntaxErrors.length > 0 ? [] : validateSemantics(query, oldSchema); + + return syntaxErrors.concat(semanticErrors); + } + + return validateSyntax(query, {}); +} + +workerpool.worker({ lintCypherQuery }); + +type LinterArgs = Parameters; + +export type LinterTask = workerpool.Promise>; + +export type LintWorker = { + lintCypherQuery: (...args: LinterArgs) => LinterTask; +}; diff --git a/packages/lint-worker/tsconfig.json b/packages/lint-worker/tsconfig.json new file mode 100644 index 000000000..76c8668a9 --- /dev/null +++ b/packages/lint-worker/tsconfig.json @@ -0,0 +1,11 @@ +{ + "extends": "../../tsconfig.base.json", + "include": ["src"], + "exclude": [], + "compilerOptions": { + "outDir": "dist", + "declaration": true, + "esModuleInterop": true, + "module": "esnext" + } +} From 23f118802b04eccef32bf6fd8a3eedcf5f464a9f Mon Sep 17 00:00:00 2001 From: Isak Date: Mon, 28 Apr 2025 16:21:11 +0200 Subject: [PATCH 02/10] fixes types and adds some react-codemirror testing --- packages/lint-worker/package.json | 10 ++++++---- packages/lint-worker/src/index.ts | 1 + packages/lint-worker/src/lintWorker.ts | 5 ++++- packages/lint-worker/tsconfig.json | 7 ++++--- packages/react-codemirror/package.json | 1 + .../react-codemirror/src/lang-cypher/autocomplete.ts | 4 ++++ .../src/lang-cypher/syntaxValidation.ts | 2 ++ 7 files changed, 22 insertions(+), 8 deletions(-) diff --git a/packages/lint-worker/package.json b/packages/lint-worker/package.json index ea4afd85a..97ef8f407 100644 --- a/packages/lint-worker/package.json +++ b/packages/lint-worker/package.json @@ -4,7 +4,7 @@ "author": "Neo4j Inc.", "license": "Apache-2.0", "files": [ - "./dist/for-language-server/lintWorker.js", + "./dist", "./src", "package.json", "README.md", @@ -16,7 +16,7 @@ "cypher", "lint worker" ], - "version": "6.26.0", + "version": "9.26.0", "repository": { "type": "git", "url": "git://github.com/neo4j/cypher-language-support.git" @@ -34,13 +34,15 @@ "workerpool": "^9.0.4" }, "scripts": { - "build": "esbuild ./src/index.ts --bundle --platform=node --outfile=dist/index.mjs --format=esm --minify && pnpm bundle-for-language-server", + "build": "pnpm build-types && esbuild ./src/index.ts --bundle --platform=node --outfile=dist/index.mjs --format=esm --minify && pnpm bundle-for-language-server", "bundle-for-language-server": "esbuild ./src/lintWorker.ts --bundle --format=cjs --platform=node --outfile=dist/for-language-server/lintWorker.js --minify", - "clean": "rm -rf dist" + "clean": "rm -rf dist", + "build-types": "tsc --emitDeclarationOnly --outDir dist/types" }, "devDependencies": { "@types/lodash.debounce": "^4.0.9" }, + "types": "./dist/types/index.d.ts", "exports": { ".": { "require": "./dist/index.mjs", diff --git a/packages/lint-worker/src/index.ts b/packages/lint-worker/src/index.ts index 489097adf..5fd84112b 100644 --- a/packages/lint-worker/src/index.ts +++ b/packages/lint-worker/src/index.ts @@ -1 +1,2 @@ export * from './lintWorker'; +export { WorkerURL } from './lintWorker'; diff --git a/packages/lint-worker/src/lintWorker.ts b/packages/lint-worker/src/lintWorker.ts index 07eae3aab..b77bb8eb4 100644 --- a/packages/lint-worker/src/lintWorker.ts +++ b/packages/lint-worker/src/lintWorker.ts @@ -12,7 +12,10 @@ import { } from '@neo4j-cypher/language-support'; import workerpool from 'workerpool'; -export default new URL('./lintWorker.ts?worker', import.meta.url).href; +export function returnFive() { + return 5; +} +export const WorkerURL = new URL('./lintWorker.ts?worker', import.meta.url).href; function lintCypherQuery( query: string, diff --git a/packages/lint-worker/tsconfig.json b/packages/lint-worker/tsconfig.json index 76c8668a9..a5eef0c49 100644 --- a/packages/lint-worker/tsconfig.json +++ b/packages/lint-worker/tsconfig.json @@ -3,9 +3,10 @@ "include": ["src"], "exclude": [], "compilerOptions": { - "outDir": "dist", + "outDir": "./dist", "declaration": true, "esModuleInterop": true, - "module": "esnext" + "module": "esnext", + "moduleResolution": "node" } -} +} \ No newline at end of file diff --git a/packages/react-codemirror/package.json b/packages/react-codemirror/package.json index 820ad3648..355be573e 100644 --- a/packages/react-codemirror/package.json +++ b/packages/react-codemirror/package.json @@ -52,6 +52,7 @@ "@lezer/common": "^1.0.2", "@lezer/highlight": "^1.1.3", "@neo4j-cypher/language-support": "workspace:*", + "@neo4j-cypher/lint-worker": "workspace:*", "@types/prismjs": "^1.26.3", "@types/workerpool": "^6.4.7", "fastest-levenshtein": "^1.0.16", diff --git a/packages/react-codemirror/src/lang-cypher/autocomplete.ts b/packages/react-codemirror/src/lang-cypher/autocomplete.ts index 41d10b72d..413d0fa40 100644 --- a/packages/react-codemirror/src/lang-cypher/autocomplete.ts +++ b/packages/react-codemirror/src/lang-cypher/autocomplete.ts @@ -14,6 +14,8 @@ import { import { CompletionItemIcons } from '../icons'; import type { CypherConfig } from './langCypher'; import { getDocString } from './utils'; +import { WorkerURL } from '@neo4j-cypher/lint-worker' +import { returnFive } from '@neo4j-cypher/lint-worker' const completionKindToCodemirrorIcon = (c: CompletionItemKind) => { const map: Record = { @@ -60,6 +62,8 @@ export const completionStyles: ( export const cypherAutocomplete: (config: CypherConfig) => CompletionSource = (config) => (context) => { + console.log("calling test method", returnFive()) + console.log("getting url", WorkerURL) const documentText = context.state.doc.toString(); const offset = context.pos; const triggerCharacters = ['.', ':', '{', '$', ')']; diff --git a/packages/react-codemirror/src/lang-cypher/syntaxValidation.ts b/packages/react-codemirror/src/lang-cypher/syntaxValidation.ts index 5a3604391..494165a6d 100644 --- a/packages/react-codemirror/src/lang-cypher/syntaxValidation.ts +++ b/packages/react-codemirror/src/lang-cypher/syntaxValidation.ts @@ -5,6 +5,7 @@ import workerpool from 'workerpool'; import type { CypherConfig } from './langCypher'; import type { LinterTask, LintWorker } from './lintWorker'; import WorkerURL from './lintWorker?worker&url'; +import {returnFive} from '@neo4j-cypher/lint-worker'; const pool = workerpool.pool(WorkerURL, { minWorkers: 2, @@ -16,6 +17,7 @@ let lastSemanticJob: LinterTask | undefined; export const cypherLinter: (config: CypherConfig) => Extension = (config) => linter(async (view) => { + console.log("Calling imported method: ", returnFive()) if (!config.lint) { return []; } From 607c838e421f6a8eab61351acfc3f70a3d69b13f Mon Sep 17 00:00:00 2001 From: Nacho Cordon Date: Mon, 28 Apr 2025 17:08:55 +0100 Subject: [PATCH 03/10] Makes it work --- package.json | 2 +- packages/lint-worker/package.json | 5 +- packages/lint-worker/src/index.ts | 2 +- packages/lint-worker/src/lintWorker.ts | 1 - .../src/lang-cypher/autocomplete.ts | 3 +- .../src/lang-cypher/lintWorker.ts | 31 ----------- .../src/lang-cypher/syntaxValidation.ts | 6 +-- pnpm-lock.yaml | 52 +++++++++++++++++++ 8 files changed, 60 insertions(+), 42 deletions(-) delete mode 100644 packages/react-codemirror/src/lang-cypher/lintWorker.ts diff --git a/package.json b/package.json index 9ecbf64d4..bb4ff4b75 100644 --- a/package.json +++ b/package.json @@ -16,7 +16,7 @@ "dev-codemirror": "pnpm --filter='...@neo4j-cypher/react-codemirror-playground' build && pnpm --filter='@neo4j-cypher/react-codemirror-playground' dev", "release": "pnpm build && pnpm publish -r --tag next --access=public", "snapshot-release": "pnpm changeset pre exit && pnpm changeset version --snapshot canary && pnpm install --frozen-lockfile=false && pnpm build && pnpm publish -r --tag canary --no-git-checks --access=public", - "deep-clean": "rimraf -g **/{node_modules,dist}", + "deep-clean": "pnpm clean && rimraf -g **/{node_modules,dist}", "clean": "pnpm --recursive --parallel clean", "test": "pnpm --recursive --parallel test", "test:e2e": "pnpm --recursive test:e2e", diff --git a/packages/lint-worker/package.json b/packages/lint-worker/package.json index 97ef8f407..d861ed371 100644 --- a/packages/lint-worker/package.json +++ b/packages/lint-worker/package.json @@ -34,15 +34,14 @@ "workerpool": "^9.0.4" }, "scripts": { - "build": "pnpm build-types && esbuild ./src/index.ts --bundle --platform=node --outfile=dist/index.mjs --format=esm --minify && pnpm bundle-for-language-server", - "bundle-for-language-server": "esbuild ./src/lintWorker.ts --bundle --format=cjs --platform=node --outfile=dist/for-language-server/lintWorker.js --minify", + "build": "pnpm build-types && esbuild ./src/index.ts --bundle --platform=node --outfile=dist/index.mjs --format=esm --minify", "clean": "rm -rf dist", "build-types": "tsc --emitDeclarationOnly --outDir dist/types" }, "devDependencies": { "@types/lodash.debounce": "^4.0.9" }, - "types": "./dist/types/index.d.ts", + "types": "./dist/types/src/index.d.ts", "exports": { ".": { "require": "./dist/index.mjs", diff --git a/packages/lint-worker/src/index.ts b/packages/lint-worker/src/index.ts index 5fd84112b..0e4dd271c 100644 --- a/packages/lint-worker/src/index.ts +++ b/packages/lint-worker/src/index.ts @@ -1,2 +1,2 @@ export * from './lintWorker'; -export { WorkerURL } from './lintWorker'; +export const WorkerURL = new URL('./index', import.meta.url).href; diff --git a/packages/lint-worker/src/lintWorker.ts b/packages/lint-worker/src/lintWorker.ts index b77bb8eb4..65889b1b0 100644 --- a/packages/lint-worker/src/lintWorker.ts +++ b/packages/lint-worker/src/lintWorker.ts @@ -15,7 +15,6 @@ import workerpool from 'workerpool'; export function returnFive() { return 5; } -export const WorkerURL = new URL('./lintWorker.ts?worker', import.meta.url).href; function lintCypherQuery( query: string, diff --git a/packages/react-codemirror/src/lang-cypher/autocomplete.ts b/packages/react-codemirror/src/lang-cypher/autocomplete.ts index 413d0fa40..b3bbb8066 100644 --- a/packages/react-codemirror/src/lang-cypher/autocomplete.ts +++ b/packages/react-codemirror/src/lang-cypher/autocomplete.ts @@ -14,8 +14,7 @@ import { import { CompletionItemIcons } from '../icons'; import type { CypherConfig } from './langCypher'; import { getDocString } from './utils'; -import { WorkerURL } from '@neo4j-cypher/lint-worker' -import { returnFive } from '@neo4j-cypher/lint-worker' +import { returnFive, WorkerURL } from '@neo4j-cypher/lint-worker' const completionKindToCodemirrorIcon = (c: CompletionItemKind) => { const map: Record = { diff --git a/packages/react-codemirror/src/lang-cypher/lintWorker.ts b/packages/react-codemirror/src/lang-cypher/lintWorker.ts deleted file mode 100644 index 67aa41606..000000000 --- a/packages/react-codemirror/src/lang-cypher/lintWorker.ts +++ /dev/null @@ -1,31 +0,0 @@ -import { - DbSchema, - lintCypherQuery as _lintCypherQuery, - _internalFeatureFlags, -} from '@neo4j-cypher/language-support'; -import workerpool from 'workerpool'; - -function lintCypherQuery( - query: string, - dbSchema: DbSchema, - featureFlags: { consoleCommands?: boolean; cypher25?: boolean } = {}, -) { - // We allow to override the consoleCommands feature flag - if (featureFlags.consoleCommands !== undefined) { - _internalFeatureFlags.consoleCommands = featureFlags.consoleCommands; - } - if (featureFlags.cypher25 !== undefined) { - _internalFeatureFlags.cypher25 = featureFlags.cypher25; - } - return _lintCypherQuery(query, dbSchema); -} - -workerpool.worker({ lintCypherQuery }); - -type LinterArgs = Parameters; - -export type LinterTask = workerpool.Promise>; - -export type LintWorker = { - lintCypherQuery: (...args: LinterArgs) => LinterTask; -}; diff --git a/packages/react-codemirror/src/lang-cypher/syntaxValidation.ts b/packages/react-codemirror/src/lang-cypher/syntaxValidation.ts index 494165a6d..5072021d7 100644 --- a/packages/react-codemirror/src/lang-cypher/syntaxValidation.ts +++ b/packages/react-codemirror/src/lang-cypher/syntaxValidation.ts @@ -3,8 +3,8 @@ import { Extension } from '@codemirror/state'; import { DiagnosticSeverity, DiagnosticTag } from 'vscode-languageserver-types'; import workerpool from 'workerpool'; import type { CypherConfig } from './langCypher'; -import type { LinterTask, LintWorker } from './lintWorker'; -import WorkerURL from './lintWorker?worker&url'; +import type { LinterTask, LintWorker } from '@neo4j-cypher/lint-worker'; +import {WorkerURL} from '@neo4j-cypher/lint-worker' import {returnFive} from '@neo4j-cypher/lint-worker'; const pool = workerpool.pool(WorkerURL, { @@ -35,7 +35,7 @@ export const cypherLinter: (config: CypherConfig) => Extension = (config) => lastSemanticJob = proxyWorker.lintCypherQuery( query, config.schema ?? {}, - config.featureFlags ?? {}, + //config.featureFlags ?? {}, ); const result = await lastSemanticJob; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index fd04ebf56..9bd245b67 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -110,6 +110,22 @@ importers: specifier: ^7.7.0 version: 7.7.0 + packages/lint-worker: + dependencies: + '@neo4j-cypher/language-support': + specifier: 2.0.0-next.4 + version: 2.0.0-next.4 + '@neo4j-cypher/language-support-new': + specifier: npm:@neo4j-cypher/language-support@2.0.0-next.19 + version: '@neo4j-cypher/language-support@2.0.0-next.19' + workerpool: + specifier: ^9.0.4 + version: 9.0.4 + devDependencies: + '@types/lodash.debounce': + specifier: ^4.0.9 + version: 4.0.9 + packages/query-tools: dependencies: '@neo4j-cypher/language-support': @@ -158,6 +174,9 @@ importers: '@neo4j-cypher/language-support': specifier: workspace:* version: link:../language-support + '@neo4j-cypher/lint-worker': + specifier: workspace:* + version: link:../lint-worker '@types/prismjs': specifier: ^1.26.3 version: 1.26.4 @@ -1353,6 +1372,14 @@ packages: resolution: {integrity: sha512-XdlGB5p1vI+f+Mh8NlALayoHWSjBms3aXGFYEaNqF7e75cOWu3q804x+MQk1U+zp0+UqvF82gryqwwgU5s6LUg==} engines: {node: '>=14.0.0'} + '@neo4j-cypher/language-support@2.0.0-next.19': + resolution: {integrity: sha512-+I+zxL3IWEa+Ai01JPwfZ2fuBUIGiNS8ZegN6WZaYMCgR0Ss9us6m0izUgiRHjy69JfeEIhMS/v6icZeP20hHQ==} + engines: {node: '>=18.18.2'} + + '@neo4j-cypher/language-support@2.0.0-next.4': + resolution: {integrity: sha512-Ae7d2BScuLSrz/vdEy7gQH1ix1NN2iyvqaIikSBgYE2ktKO5b8N3YLSXV+fMy6vUiFeSJIFaBwesGrJjvaEgSg==} + engines: {node: '>=18.18.2'} + '@neo4j-cypher/react-codemirror@1.0.4': resolution: {integrity: sha512-3hLsnd+BS3uYDvcsfQb+dZ2Y/uKJ4x07gA3XGd+2DGjJ59S6dilIfO10Ww6W0nBbq/Y5wSgaSURBjB4sQw8Csg==} engines: {node: '>=16'} @@ -2621,6 +2648,9 @@ packages: resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==} engines: {node: '>=12'} + antlr4-c3@3.4.4: + resolution: {integrity: sha512-ixp1i17ypbRzZnffdarIfCVEXJwPydtDt61SHMGkc+UCD7rrbfvHESTMTgx8jFhUgKAgcHyt9060kQ8nU3vlxA==} + antlr4@4.10.1: resolution: {integrity: sha512-fmxidcOwmktzHUD+tz8y/zKLI/NfVAB0+MOvnFUBzo8ToFnphK8JY88oOJeRdhnTrAhjtu45bvxddzbb8nMeIA==} engines: {node: '>=14'} @@ -2629,6 +2659,9 @@ packages: resolution: {integrity: sha512-QiVbZhyy4xAZ17UPEuG3YTOt8ZaoeOR1CvEAqrEsDBsOqINslaB147i9xqljZqoyf5S+EUlGStaj+t22LT9MOg==} engines: {node: '>=16'} + antlr4ng@3.0.16: + resolution: {integrity: sha512-DQuJkC7kX3xunfF4K2KsWTSvoxxslv+FQp/WHQZTJSsH2Ec3QfFmrxC3Nky2ok9yglXn6nHM4zUaVDxcN5f6kA==} + any-promise@1.3.0: resolution: {integrity: sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==} @@ -8095,6 +8128,19 @@ snapshots: lodash.find: 4.6.0 lodash.includes: 4.3.0 + '@neo4j-cypher/language-support@2.0.0-next.19': + dependencies: + antlr4: 4.13.2 + fastest-levenshtein: 1.0.16 + vscode-languageserver-types: 3.17.5 + + '@neo4j-cypher/language-support@2.0.0-next.4': + dependencies: + antlr4: 4.13.2 + antlr4-c3: 3.4.4 + fastest-levenshtein: 1.0.16 + vscode-languageserver-types: 3.17.5 + '@neo4j-cypher/react-codemirror@1.0.4(@lezer/common@1.2.1)(react@18.3.1)': dependencies: '@babel/runtime': 7.27.0 @@ -10001,10 +10047,16 @@ snapshots: ansi-styles@6.2.1: {} + antlr4-c3@3.4.4: + dependencies: + antlr4ng: 3.0.16 + antlr4@4.10.1: {} antlr4@4.13.2: {} + antlr4ng@3.0.16: {} + any-promise@1.3.0: {} anymatch@3.1.3: From 8e8bf6bd0f2ecc25f1444bb95fccb11234d24ff1 Mon Sep 17 00:00:00 2001 From: Nacho Cordon Date: Tue, 29 Apr 2025 14:00:31 +0100 Subject: [PATCH 04/10] Renames lint worker --- packages/lint-worker/package.json | 9 ++++----- packages/lint-worker/src/index.ts | 2 -- packages/lint-worker/src/lintWorker.ts | 4 +--- .../react-codemirror/src/lang-cypher/autocomplete.ts | 3 +-- .../react-codemirror/src/lang-cypher/syntaxValidation.ts | 2 -- 5 files changed, 6 insertions(+), 14 deletions(-) delete mode 100644 packages/lint-worker/src/index.ts diff --git a/packages/lint-worker/package.json b/packages/lint-worker/package.json index d861ed371..6ac1d8775 100644 --- a/packages/lint-worker/package.json +++ b/packages/lint-worker/package.json @@ -34,19 +34,18 @@ "workerpool": "^9.0.4" }, "scripts": { - "build": "pnpm build-types && esbuild ./src/index.ts --bundle --platform=node --outfile=dist/index.mjs --format=esm --minify", + "build": "pnpm build-types && esbuild ./src/lintWorker.ts --bundle --platform=node --outfile=dist/lintWorker.mjs --format=esm --minify", "clean": "rm -rf dist", "build-types": "tsc --emitDeclarationOnly --outDir dist/types" }, "devDependencies": { "@types/lodash.debounce": "^4.0.9" }, - "types": "./dist/types/src/index.d.ts", + "types": "./dist/types/src/lintWorker.d.ts", "exports": { ".": { - "require": "./dist/index.mjs", - "import": "./dist/index.mjs", - "default": "./dist/index.mjs" + "import": "./dist/lintWorker.mjs", + "default": "./dist/lintWorker.mjs" } } } diff --git a/packages/lint-worker/src/index.ts b/packages/lint-worker/src/index.ts deleted file mode 100644 index 0e4dd271c..000000000 --- a/packages/lint-worker/src/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from './lintWorker'; -export const WorkerURL = new URL('./index', import.meta.url).href; diff --git a/packages/lint-worker/src/lintWorker.ts b/packages/lint-worker/src/lintWorker.ts index 65889b1b0..c3ba6af95 100644 --- a/packages/lint-worker/src/lintWorker.ts +++ b/packages/lint-worker/src/lintWorker.ts @@ -12,9 +12,7 @@ import { } from '@neo4j-cypher/language-support'; import workerpool from 'workerpool'; -export function returnFive() { - return 5; -} +export const WorkerURL = new URL('./lintWorker', import.meta.url).href; function lintCypherQuery( query: string, diff --git a/packages/react-codemirror/src/lang-cypher/autocomplete.ts b/packages/react-codemirror/src/lang-cypher/autocomplete.ts index b3bbb8066..71ddc2d25 100644 --- a/packages/react-codemirror/src/lang-cypher/autocomplete.ts +++ b/packages/react-codemirror/src/lang-cypher/autocomplete.ts @@ -14,7 +14,7 @@ import { import { CompletionItemIcons } from '../icons'; import type { CypherConfig } from './langCypher'; import { getDocString } from './utils'; -import { returnFive, WorkerURL } from '@neo4j-cypher/lint-worker' +import { WorkerURL } from '@neo4j-cypher/lint-worker' const completionKindToCodemirrorIcon = (c: CompletionItemKind) => { const map: Record = { @@ -61,7 +61,6 @@ export const completionStyles: ( export const cypherAutocomplete: (config: CypherConfig) => CompletionSource = (config) => (context) => { - console.log("calling test method", returnFive()) console.log("getting url", WorkerURL) const documentText = context.state.doc.toString(); const offset = context.pos; diff --git a/packages/react-codemirror/src/lang-cypher/syntaxValidation.ts b/packages/react-codemirror/src/lang-cypher/syntaxValidation.ts index 5072021d7..5d1c8282a 100644 --- a/packages/react-codemirror/src/lang-cypher/syntaxValidation.ts +++ b/packages/react-codemirror/src/lang-cypher/syntaxValidation.ts @@ -5,7 +5,6 @@ import workerpool from 'workerpool'; import type { CypherConfig } from './langCypher'; import type { LinterTask, LintWorker } from '@neo4j-cypher/lint-worker'; import {WorkerURL} from '@neo4j-cypher/lint-worker' -import {returnFive} from '@neo4j-cypher/lint-worker'; const pool = workerpool.pool(WorkerURL, { minWorkers: 2, @@ -17,7 +16,6 @@ let lastSemanticJob: LinterTask | undefined; export const cypherLinter: (config: CypherConfig) => Extension = (config) => linter(async (view) => { - console.log("Calling imported method: ", returnFive()) if (!config.lint) { return []; } From a05ea70debfe1d33653457f368a8fca3744d8f31 Mon Sep 17 00:00:00 2001 From: Nacho Cordon Date: Tue, 29 Apr 2025 14:37:52 +0100 Subject: [PATCH 05/10] Use workspace dep for lint-worker --- packages/lint-worker/package.json | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/lint-worker/package.json b/packages/lint-worker/package.json index 6ac1d8775..97f9b2d07 100644 --- a/packages/lint-worker/package.json +++ b/packages/lint-worker/package.json @@ -29,8 +29,7 @@ "node": ">=18.18.2" }, "dependencies": { - "@neo4j-cypher/language-support": "2.0.0-next.4", - "@neo4j-cypher/language-support-new": "npm:@neo4j-cypher/language-support@2.0.0-next.19", + "@neo4j-cypher/language-support": "workspace:*", "workerpool": "^9.0.4" }, "scripts": { From 9fd928d17d6547490fb1239b069743431b10b461 Mon Sep 17 00:00:00 2001 From: Nacho Cordon Date: Tue, 29 Apr 2025 15:08:03 +0100 Subject: [PATCH 06/10] Uses workspace:* version in the lint-worker --- packages/lint-worker/package.json | 2 +- packages/lint-worker/src/lintWorker.ts | 59 ++++++-------------------- pnpm-lock.yaml | 40 +---------------- 3 files changed, 16 insertions(+), 85 deletions(-) diff --git a/packages/lint-worker/package.json b/packages/lint-worker/package.json index 97f9b2d07..1c6eafe7f 100644 --- a/packages/lint-worker/package.json +++ b/packages/lint-worker/package.json @@ -33,7 +33,7 @@ "workerpool": "^9.0.4" }, "scripts": { - "build": "pnpm build-types && esbuild ./src/lintWorker.ts --bundle --platform=node --outfile=dist/lintWorker.mjs --format=esm --minify", + "build": "pnpm build-types && esbuild ./src/lintWorker.ts --bundle --platform=node --conditions=require --outfile=dist/lintWorker.mjs --format=esm --minify", "clean": "rm -rf dist", "build-types": "tsc --emitDeclarationOnly --outDir dist/types" }, diff --git a/packages/lint-worker/src/lintWorker.ts b/packages/lint-worker/src/lintWorker.ts index c3ba6af95..433c5e8c3 100644 --- a/packages/lint-worker/src/lintWorker.ts +++ b/packages/lint-worker/src/lintWorker.ts @@ -1,59 +1,26 @@ -import { - DbSchema as DbSchemaNew, - Neo4jFunction, -} from '@neo4j-cypher/language-support-new'; import { DbSchema, - // lintCypherQuery as _lintCypherQuery, - // _internalFeatureFlags, - validateSyntax, - validateSemantics, - Neo4jProcedure, + lintCypherQuery as _lintCypherQuery, + _internalFeatureFlags, + SyntaxDiagnostic, } from '@neo4j-cypher/language-support'; import workerpool from 'workerpool'; export const WorkerURL = new URL('./lintWorker', import.meta.url).href; -function lintCypherQuery( +export function lintCypherQuery( query: string, - dbSchema: DbSchemaNew, - //featureFlags: { consoleCommands?: boolean; cypher25?: boolean } = {}, -) { - //console.log("Entering lintCypherQuery in worker with featureflags", featureFlags) + dbSchema: DbSchema, + featureFlags: { consoleCommands?: boolean; cypher25?: boolean } = {}, +): SyntaxDiagnostic[] { // We allow to override the consoleCommands feature flag - // if (featureFlags.consoleCommands !== undefined) { - // _internalFeatureFlags.consoleCommands = featureFlags.consoleCommands; - // } - // if (featureFlags.cypher25 !== undefined) { - // _internalFeatureFlags.cypher25 = featureFlags.cypher25; - // } - if (dbSchema.procedures && dbSchema.functions) { - const oldSchema: DbSchema = { - procedures: dbSchema.procedures['CYPHER 5'] as Record< - string, - Neo4jProcedure - >, - functions: dbSchema.functions['CYPHER 5'] as Record< - string, - Neo4jFunction - >, - labels: dbSchema.labels, - relationshipTypes: dbSchema.relationshipTypes, - databaseNames: dbSchema.databaseNames, - aliasNames: dbSchema.aliasNames, - // userNames: dbSchema.userNames, - // roleNames: dbSchema.roleNames, - parameters: dbSchema.parameters, - propertyKeys: dbSchema.propertyKeys, - }; - const syntaxErrors = validateSyntax(query, oldSchema); - const semanticErrors = - syntaxErrors.length > 0 ? [] : validateSemantics(query, oldSchema); - - return syntaxErrors.concat(semanticErrors); + if (featureFlags.consoleCommands !== undefined) { + _internalFeatureFlags.consoleCommands = featureFlags.consoleCommands; } - - return validateSyntax(query, {}); + if (featureFlags.cypher25 !== undefined) { + _internalFeatureFlags.cypher25 = featureFlags.cypher25; + } + return _lintCypherQuery(query, dbSchema); } workerpool.worker({ lintCypherQuery }); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 9bd245b67..b683de697 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -113,11 +113,8 @@ importers: packages/lint-worker: dependencies: '@neo4j-cypher/language-support': - specifier: 2.0.0-next.4 - version: 2.0.0-next.4 - '@neo4j-cypher/language-support-new': - specifier: npm:@neo4j-cypher/language-support@2.0.0-next.19 - version: '@neo4j-cypher/language-support@2.0.0-next.19' + specifier: workspace:* + version: link:../language-support workerpool: specifier: ^9.0.4 version: 9.0.4 @@ -1372,14 +1369,6 @@ packages: resolution: {integrity: sha512-XdlGB5p1vI+f+Mh8NlALayoHWSjBms3aXGFYEaNqF7e75cOWu3q804x+MQk1U+zp0+UqvF82gryqwwgU5s6LUg==} engines: {node: '>=14.0.0'} - '@neo4j-cypher/language-support@2.0.0-next.19': - resolution: {integrity: sha512-+I+zxL3IWEa+Ai01JPwfZ2fuBUIGiNS8ZegN6WZaYMCgR0Ss9us6m0izUgiRHjy69JfeEIhMS/v6icZeP20hHQ==} - engines: {node: '>=18.18.2'} - - '@neo4j-cypher/language-support@2.0.0-next.4': - resolution: {integrity: sha512-Ae7d2BScuLSrz/vdEy7gQH1ix1NN2iyvqaIikSBgYE2ktKO5b8N3YLSXV+fMy6vUiFeSJIFaBwesGrJjvaEgSg==} - engines: {node: '>=18.18.2'} - '@neo4j-cypher/react-codemirror@1.0.4': resolution: {integrity: sha512-3hLsnd+BS3uYDvcsfQb+dZ2Y/uKJ4x07gA3XGd+2DGjJ59S6dilIfO10Ww6W0nBbq/Y5wSgaSURBjB4sQw8Csg==} engines: {node: '>=16'} @@ -2648,9 +2637,6 @@ packages: resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==} engines: {node: '>=12'} - antlr4-c3@3.4.4: - resolution: {integrity: sha512-ixp1i17ypbRzZnffdarIfCVEXJwPydtDt61SHMGkc+UCD7rrbfvHESTMTgx8jFhUgKAgcHyt9060kQ8nU3vlxA==} - antlr4@4.10.1: resolution: {integrity: sha512-fmxidcOwmktzHUD+tz8y/zKLI/NfVAB0+MOvnFUBzo8ToFnphK8JY88oOJeRdhnTrAhjtu45bvxddzbb8nMeIA==} engines: {node: '>=14'} @@ -2659,9 +2645,6 @@ packages: resolution: {integrity: sha512-QiVbZhyy4xAZ17UPEuG3YTOt8ZaoeOR1CvEAqrEsDBsOqINslaB147i9xqljZqoyf5S+EUlGStaj+t22LT9MOg==} engines: {node: '>=16'} - antlr4ng@3.0.16: - resolution: {integrity: sha512-DQuJkC7kX3xunfF4K2KsWTSvoxxslv+FQp/WHQZTJSsH2Ec3QfFmrxC3Nky2ok9yglXn6nHM4zUaVDxcN5f6kA==} - any-promise@1.3.0: resolution: {integrity: sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==} @@ -8128,19 +8111,6 @@ snapshots: lodash.find: 4.6.0 lodash.includes: 4.3.0 - '@neo4j-cypher/language-support@2.0.0-next.19': - dependencies: - antlr4: 4.13.2 - fastest-levenshtein: 1.0.16 - vscode-languageserver-types: 3.17.5 - - '@neo4j-cypher/language-support@2.0.0-next.4': - dependencies: - antlr4: 4.13.2 - antlr4-c3: 3.4.4 - fastest-levenshtein: 1.0.16 - vscode-languageserver-types: 3.17.5 - '@neo4j-cypher/react-codemirror@1.0.4(@lezer/common@1.2.1)(react@18.3.1)': dependencies: '@babel/runtime': 7.27.0 @@ -10047,16 +10017,10 @@ snapshots: ansi-styles@6.2.1: {} - antlr4-c3@3.4.4: - dependencies: - antlr4ng: 3.0.16 - antlr4@4.10.1: {} antlr4@4.13.2: {} - antlr4ng@3.0.16: {} - any-promise@1.3.0: {} anymatch@3.1.3: From 370180e7d2cbd8db934a7de0969eab260b7ba81f Mon Sep 17 00:00:00 2001 From: Nacho Cordon Date: Tue, 29 Apr 2025 15:43:07 +0100 Subject: [PATCH 07/10] small nits --- package.json | 2 +- packages/lint-worker/package.json | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index bb4ff4b75..e05e455d8 100644 --- a/package.json +++ b/package.json @@ -16,7 +16,7 @@ "dev-codemirror": "pnpm --filter='...@neo4j-cypher/react-codemirror-playground' build && pnpm --filter='@neo4j-cypher/react-codemirror-playground' dev", "release": "pnpm build && pnpm publish -r --tag next --access=public", "snapshot-release": "pnpm changeset pre exit && pnpm changeset version --snapshot canary && pnpm install --frozen-lockfile=false && pnpm build && pnpm publish -r --tag canary --no-git-checks --access=public", - "deep-clean": "pnpm clean && rimraf -g **/{node_modules,dist}", + "deep-clean": "pnpm clean && rimraf -g **/{node_modules,dist,tsconfig.tsbuildinfo}", "clean": "pnpm --recursive --parallel clean", "test": "pnpm --recursive --parallel test", "test:e2e": "pnpm --recursive test:e2e", diff --git a/packages/lint-worker/package.json b/packages/lint-worker/package.json index 1c6eafe7f..ee2dabfa5 100644 --- a/packages/lint-worker/package.json +++ b/packages/lint-worker/package.json @@ -16,7 +16,7 @@ "cypher", "lint worker" ], - "version": "9.26.0", + "version": "2025.4.0", "repository": { "type": "git", "url": "git://github.com/neo4j/cypher-language-support.git" @@ -33,7 +33,7 @@ "workerpool": "^9.0.4" }, "scripts": { - "build": "pnpm build-types && esbuild ./src/lintWorker.ts --bundle --platform=node --conditions=require --outfile=dist/lintWorker.mjs --format=esm --minify", + "build": "pnpm build-types && esbuild ./src/lintWorker.ts --bundle --platform=node --conditions=require --outfile=dist/lintWorker.mjs --format=esm --minify --sourcemap", "clean": "rm -rf dist", "build-types": "tsc --emitDeclarationOnly --outDir dist/types" }, From 65e99e56db384448c3b4aa49d8991db6d8089e4a Mon Sep 17 00:00:00 2001 From: Nacho Cordon Date: Wed, 30 Apr 2025 11:49:29 +0100 Subject: [PATCH 08/10] Fixes playwright yada yada? --- .github/actions/setup-and-build/action.yaml | 2 +- packages/language-support/package.json | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/actions/setup-and-build/action.yaml b/.github/actions/setup-and-build/action.yaml index d4f49fc35..7d59e3e87 100644 --- a/.github/actions/setup-and-build/action.yaml +++ b/.github/actions/setup-and-build/action.yaml @@ -17,7 +17,7 @@ runs: - name: Setup node.js uses: actions/setup-node@v4 with: - node-version: 20 + node-version: 22 cache: 'pnpm' registry-url: 'https://registry.npmjs.org' diff --git a/packages/language-support/package.json b/packages/language-support/package.json index 99e1e6e38..61fb941e0 100644 --- a/packages/language-support/package.json +++ b/packages/language-support/package.json @@ -21,6 +21,7 @@ "linting", "highlighting" ], + "type": "module", "version": "2.0.0-next.20", "main": "./dist/cjs/index.cjs", "module": "./dist/esm/project/language-support/src/index.js", From 16116d766aa16012da04bc9be8873b1b08697a41 Mon Sep 17 00:00:00 2001 From: Nacho Cordon Date: Wed, 30 Apr 2025 14:04:53 +0100 Subject: [PATCH 09/10] Increases heap space --- .github/actions/codemirror-e2e-tests/action.yaml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/actions/codemirror-e2e-tests/action.yaml b/.github/actions/codemirror-e2e-tests/action.yaml index 8220ea1fb..337eb2d27 100644 --- a/.github/actions/codemirror-e2e-tests/action.yaml +++ b/.github/actions/codemirror-e2e-tests/action.yaml @@ -5,6 +5,9 @@ inputs: required: true default: 'chromium' +env: + NODE_OPTIONS: '--max_old_space_size=8192' + runs: using: 'composite' steps: From f8b0a8ab8336014cd5fb77ee5573a1249adcd610 Mon Sep 17 00:00:00 2001 From: Nacho Cordon Date: Wed, 30 Apr 2025 15:55:47 +0100 Subject: [PATCH 10/10] Splits compilation of lint worker to have bundled files and esm files --- packages/lint-worker/package.json | 10 +++-- packages/lint-worker/src/lintWorker.ts | 34 ----------------- packages/lint-worker/tsconfig.json | 4 +- .../react-codemirror-playground/package.json | 1 + .../vite.config.ts | 12 +++++- .../react-codemirror/playwright-ct.config.ts | 4 +- .../src/lang-cypher/autocomplete.ts | 2 - pnpm-lock.yaml | 37 +++++++++++++++++++ 8 files changed, 59 insertions(+), 45 deletions(-) delete mode 100644 packages/lint-worker/src/lintWorker.ts diff --git a/packages/lint-worker/package.json b/packages/lint-worker/package.json index ee2dabfa5..ba99a04a9 100644 --- a/packages/lint-worker/package.json +++ b/packages/lint-worker/package.json @@ -3,6 +3,7 @@ "description": "Cypher Lint Worker", "author": "Neo4j Inc.", "license": "Apache-2.0", + "sideEffects": false, "files": [ "./dist", "./src", @@ -33,18 +34,19 @@ "workerpool": "^9.0.4" }, "scripts": { - "build": "pnpm build-types && esbuild ./src/lintWorker.ts --bundle --platform=node --conditions=require --outfile=dist/lintWorker.mjs --format=esm --minify --sourcemap", + "build": "pnpm build-types && tsc --module esnext --outDir dist && esbuild ./src/index.ts --bundle --platform=node --conditions=require --outfile=dist/lintWorker.mjs --format=esm --minify --sourcemap", "clean": "rm -rf dist", "build-types": "tsc --emitDeclarationOnly --outDir dist/types" }, "devDependencies": { "@types/lodash.debounce": "^4.0.9" }, - "types": "./dist/types/src/lintWorker.d.ts", + "types": "./dist/types/src/index.d.ts", "exports": { ".": { - "import": "./dist/lintWorker.mjs", - "default": "./dist/lintWorker.mjs" + "types": "./dist/types/src/index.d.ts", + "import": "./dist/src/index.js", + "default": "./dist/src/index.js" } } } diff --git a/packages/lint-worker/src/lintWorker.ts b/packages/lint-worker/src/lintWorker.ts deleted file mode 100644 index 433c5e8c3..000000000 --- a/packages/lint-worker/src/lintWorker.ts +++ /dev/null @@ -1,34 +0,0 @@ -import { - DbSchema, - lintCypherQuery as _lintCypherQuery, - _internalFeatureFlags, - SyntaxDiagnostic, -} from '@neo4j-cypher/language-support'; -import workerpool from 'workerpool'; - -export const WorkerURL = new URL('./lintWorker', import.meta.url).href; - -export function lintCypherQuery( - query: string, - dbSchema: DbSchema, - featureFlags: { consoleCommands?: boolean; cypher25?: boolean } = {}, -): SyntaxDiagnostic[] { - // We allow to override the consoleCommands feature flag - if (featureFlags.consoleCommands !== undefined) { - _internalFeatureFlags.consoleCommands = featureFlags.consoleCommands; - } - if (featureFlags.cypher25 !== undefined) { - _internalFeatureFlags.cypher25 = featureFlags.cypher25; - } - return _lintCypherQuery(query, dbSchema); -} - -workerpool.worker({ lintCypherQuery }); - -type LinterArgs = Parameters; - -export type LinterTask = workerpool.Promise>; - -export type LintWorker = { - lintCypherQuery: (...args: LinterArgs) => LinterTask; -}; diff --git a/packages/lint-worker/tsconfig.json b/packages/lint-worker/tsconfig.json index a5eef0c49..c84087acd 100644 --- a/packages/lint-worker/tsconfig.json +++ b/packages/lint-worker/tsconfig.json @@ -1,6 +1,6 @@ { "extends": "../../tsconfig.base.json", - "include": ["src"], + "include": ["src/"], "exclude": [], "compilerOptions": { "outDir": "./dist", @@ -9,4 +9,4 @@ "module": "esnext", "moduleResolution": "node" } -} \ No newline at end of file +} diff --git a/packages/react-codemirror-playground/package.json b/packages/react-codemirror-playground/package.json index 3cfffd8e6..a07aae907 100644 --- a/packages/react-codemirror-playground/package.json +++ b/packages/react-codemirror-playground/package.json @@ -40,6 +40,7 @@ "@vitejs/plugin-react": "^3.1.0", "autoprefixer": "^10.4.14", "postcss": "^8.4.23", + "rollup-plugin-visualizer": "^5.14.0", "tailwindcss": "^3.3.1", "vite": "^4.5.10" } diff --git a/packages/react-codemirror-playground/vite.config.ts b/packages/react-codemirror-playground/vite.config.ts index 62145f527..91632eff1 100644 --- a/packages/react-codemirror-playground/vite.config.ts +++ b/packages/react-codemirror-playground/vite.config.ts @@ -1,7 +1,15 @@ import react from '@vitejs/plugin-react'; -import { defineConfig } from 'vite'; +import { defineConfig, type PluginOption } from 'vite'; + +import { visualizer } from 'rollup-plugin-visualizer'; export default defineConfig({ - plugins: [react()], + plugins: [ + react(), + visualizer({ + include: [{ file: '*/**/*.js' }, { file: '*/**/*.mjs' }], + exclude: { file: '**/node_modules/**/*' }, + }) as PluginOption, + ], base: './', }); diff --git a/packages/react-codemirror/playwright-ct.config.ts b/packages/react-codemirror/playwright-ct.config.ts index 6d967e055..b8d9883cd 100644 --- a/packages/react-codemirror/playwright-ct.config.ts +++ b/packages/react-codemirror/playwright-ct.config.ts @@ -16,7 +16,7 @@ export default defineConfig({ /* Retry on CI only */ retries: process.env.CI ? 2 : 0, /* Opt out of parallel tests on CI. */ - workers: process.env.CI ? 1 : undefined, + workers: 1, /* Reporter to use. See https://playwright.dev/docs/test-reporters */ reporter: 'html', /* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */ @@ -29,9 +29,11 @@ export default defineConfig({ // vite config to get worker working ctViteConfig: { + mode: 'development', build: { rollupOptions: { output: { + manualChunks: undefined, entryFileNames: `assets/[name].js`, chunkFileNames: `assets/[name].js`, assetFileNames: `assets/[name].[ext]`, diff --git a/packages/react-codemirror/src/lang-cypher/autocomplete.ts b/packages/react-codemirror/src/lang-cypher/autocomplete.ts index 71ddc2d25..41d10b72d 100644 --- a/packages/react-codemirror/src/lang-cypher/autocomplete.ts +++ b/packages/react-codemirror/src/lang-cypher/autocomplete.ts @@ -14,7 +14,6 @@ import { import { CompletionItemIcons } from '../icons'; import type { CypherConfig } from './langCypher'; import { getDocString } from './utils'; -import { WorkerURL } from '@neo4j-cypher/lint-worker' const completionKindToCodemirrorIcon = (c: CompletionItemKind) => { const map: Record = { @@ -61,7 +60,6 @@ export const completionStyles: ( export const cypherAutocomplete: (config: CypherConfig) => CompletionSource = (config) => (context) => { - console.log("getting url", WorkerURL) const documentText = context.state.doc.toString(); const offset = context.pos; const triggerCharacters = ['.', ':', '{', '$', ')']; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index b683de697..3bab5b64d 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -293,6 +293,9 @@ importers: postcss: specifier: ^8.4.23 version: 8.4.45 + rollup-plugin-visualizer: + specifier: ^5.14.0 + version: 5.14.0(rollup@4.37.0) tailwindcss: specifier: ^3.3.1 version: 3.4.10(ts-node@10.9.1(@types/node@22.14.0)(typescript@5.8.3)) @@ -5470,6 +5473,10 @@ packages: resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} engines: {node: '>=8.6'} + picomatch@4.0.2: + resolution: {integrity: sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==} + engines: {node: '>=12'} + pidtree@0.6.0: resolution: {integrity: sha512-eG2dWTVw5bzqGRztnHExczNxt5VGsE6OwTeCG3fdUf9KBsZzO3R5OIIIzWR+iZA0NtZ+RDVdaoE2dK1cn6jH4g==} engines: {node: '>=0.10'} @@ -5962,6 +5969,19 @@ packages: ripemd160@2.0.2: resolution: {integrity: sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==} + rollup-plugin-visualizer@5.14.0: + resolution: {integrity: sha512-VlDXneTDaKsHIw8yzJAFWtrzguoJ/LnQ+lMpoVfYJ3jJF4Ihe5oYLAqLklIK/35lgUY+1yEzCkHyZ1j4A5w5fA==} + engines: {node: '>=18'} + hasBin: true + peerDependencies: + rolldown: 1.x + rollup: 2.x || 3.x || 4.x + peerDependenciesMeta: + rolldown: + optional: true + rollup: + optional: true + rollup@3.29.5: resolution: {integrity: sha512-GVsDdsbJzzy4S/v3dqWPJ7EfvZJfCHiDqe80IyrF59LYuP+e6U1LJoUqeuqRbwAWoMNoXivMNeNAOf5E22VA1w==} engines: {node: '>=14.18.0', npm: '>=8.0.0'} @@ -6183,6 +6203,10 @@ packages: resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} engines: {node: '>=0.10.0'} + source-map@0.7.4: + resolution: {integrity: sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==} + engines: {node: '>= 8'} + space-separated-tokens@1.1.5: resolution: {integrity: sha512-q/JSVd1Lptzhf5bkYm4ob4iWPjx0KiRe3sRFBNrVqbJkFaBm5vbbowy1mymoPNLRa52+oadOhJ+K49wsSeSjTA==} @@ -13283,6 +13307,8 @@ snapshots: picomatch@2.3.1: {} + picomatch@4.0.2: {} + pidtree@0.6.0: {} pify@2.3.0: {} @@ -13894,6 +13920,15 @@ snapshots: hash-base: 3.0.5 inherits: 2.0.4 + rollup-plugin-visualizer@5.14.0(rollup@4.37.0): + dependencies: + open: 8.4.2 + picomatch: 4.0.2 + source-map: 0.7.4 + yargs: 17.7.2 + optionalDependencies: + rollup: 4.37.0 + rollup@3.29.5: optionalDependencies: fsevents: 2.3.3 @@ -14130,6 +14165,8 @@ snapshots: source-map@0.6.1: {} + source-map@0.7.4: {} + space-separated-tokens@1.1.5: {} spacetrim@0.11.39: {}