From db590d1309666e87ac644c8e7d54b675e005313a Mon Sep 17 00:00:00 2001 From: Antonio Barcelos Date: Thu, 26 Oct 2023 14:08:05 +0200 Subject: [PATCH 01/11] Introduce explicity resource management to Driver and Session objects This is a TC39 [proposal](https://github.com/tc39/proposal-explicit-resource-management) which is already implemented in Typescript 5.2, core-js, babel and other pollifyl tools. This feature enables the user create the driver or a session with the `await using` keywords and then do not have to close the resource afterwards, since this resources will be closed after leaving the block which were created at. For example: ```typescript await using driver = neo4j.driver(uri, authToken) await using session = driver.session() await session.executeRead(tx => "RETURN 1") ``` Since Deno is more strict with typescript, small fixes had to be done in the driver. * Add a value to Result[Symbol.toStringTag]. * Fix Integer.shiftRight function to add propert integer convertion it. A package.json file was added to the `neo4j-driver-deno` folder for making easier to integrate the test runners to the environments. --- package.json | 4 +- packages/core/src/driver.ts | 5 +++ packages/core/src/integer.ts | 3 +- packages/core/src/result.ts | 2 +- packages/core/src/session.ts | 6 +++ packages/neo4j-driver-deno/lib/core/driver.ts | 5 +++ .../neo4j-driver-deno/lib/core/integer.ts | 3 +- packages/neo4j-driver-deno/lib/core/result.ts | 2 +- .../neo4j-driver-deno/lib/core/session.ts | 6 +++ packages/neo4j-driver-deno/test/neo4j.test.ts | 44 +++++++++++++++++++ packages/neo4j-driver/src/session-rx.js | 5 +++ 11 files changed, 79 insertions(+), 6 deletions(-) create mode 100644 packages/neo4j-driver-deno/test/neo4j.test.ts diff --git a/package.json b/package.json index 76daeced5..9db08d61a 100644 --- a/package.json +++ b/package.json @@ -40,8 +40,8 @@ "scripts": { "clean": "lerna clean -y && lerna run clean", "build": "lerna bootstrap --ci", - "set_version::deno": "cd ./packages/neo4j-driver-deno && deno run --allow-read --allow-write ./versioning.ts --output=. --filename=current.version.ts", - "build::deno": "cd ./packages/neo4j-driver-deno && deno run --allow-read --allow-write --allow-net ./generate.ts", + "set_version::deno": "lerna run set_version --scope neo4j-driver-deno --stream", + "build::deno": "lerna run build --scope neo4j-driver-deno --stream", "build::notci": "lerna bootstrap", "docs": "lerna run docs --stream --concurrency 1", "test::unit": "lerna run test::unit --stream", diff --git a/packages/core/src/driver.ts b/packages/core/src/driver.ts index 9f2a7a61e..7b25c9d63 100644 --- a/packages/core/src/driver.ts +++ b/packages/core/src/driver.ts @@ -776,6 +776,11 @@ class Driver { return Promise.resolve() } + // @ts-expect-error + [Symbol.asyncDispose] (): Promise { + return this.close() + } + /** * @protected * @returns {void} diff --git a/packages/core/src/integer.ts b/packages/core/src/integer.ts index bbb8d4d03..e9fd323bb 100644 --- a/packages/core/src/integer.ts +++ b/packages/core/src/integer.ts @@ -695,10 +695,11 @@ class Integer { */ shiftRight (numBits: number | Integer): Integer { let bitsCount: number = Integer.toNumber(numBits) + const numBitNum: number = Integer.toNumber(numBits) if ((bitsCount &= 63) === 0) { return Integer.ZERO - } else if (numBits < 32) { + } else if (numBitNum < 32) { return Integer.fromBits( (this.low >>> bitsCount) | (this.high << (32 - bitsCount)), this.high >> bitsCount diff --git a/packages/core/src/result.ts b/packages/core/src/result.ts index 1ef7771d2..938f04ff1 100644 --- a/packages/core/src/result.ts +++ b/packages/core/src/result.ts @@ -375,7 +375,7 @@ class Result implements Promise void) | null): Promise> { return this._getOrCreatePromise().finally(onfinally) } diff --git a/packages/core/src/session.ts b/packages/core/src/session.ts index 2fad4f2d7..f59f6a679 100644 --- a/packages/core/src/session.ts +++ b/packages/core/src/session.ts @@ -561,6 +561,12 @@ class Session { } } + // @ts-expect-error + [Symbol.asyncDispose] (): Promise { + console.log('calling async dispose') + return this.close() + } + _connectionHolderWithMode (mode: SessionMode): ConnectionHolder { if (mode === ACCESS_MODE_READ) { return this._readConnectionHolder diff --git a/packages/neo4j-driver-deno/lib/core/driver.ts b/packages/neo4j-driver-deno/lib/core/driver.ts index 61a02a5b5..69c102bad 100644 --- a/packages/neo4j-driver-deno/lib/core/driver.ts +++ b/packages/neo4j-driver-deno/lib/core/driver.ts @@ -776,6 +776,11 @@ class Driver { return Promise.resolve() } + // @ts-ignore + [Symbol.asyncDispose](): Promise { + return this.close() + } + /** * @protected * @returns {void} diff --git a/packages/neo4j-driver-deno/lib/core/integer.ts b/packages/neo4j-driver-deno/lib/core/integer.ts index 0b4afd57c..d7a64e154 100644 --- a/packages/neo4j-driver-deno/lib/core/integer.ts +++ b/packages/neo4j-driver-deno/lib/core/integer.ts @@ -695,10 +695,11 @@ class Integer { */ shiftRight (numBits: number | Integer): Integer { let bitsCount: number = Integer.toNumber(numBits) + let numBitNum: number = Integer.toNumber(numBits) if ((bitsCount &= 63) === 0) { return Integer.ZERO - } else if (numBits < 32) { + } else if (numBitNum < 32) { return Integer.fromBits( (this.low >>> bitsCount) | (this.high << (32 - bitsCount)), this.high >> bitsCount diff --git a/packages/neo4j-driver-deno/lib/core/result.ts b/packages/neo4j-driver-deno/lib/core/result.ts index f000b6ac1..43ba35dfe 100644 --- a/packages/neo4j-driver-deno/lib/core/result.ts +++ b/packages/neo4j-driver-deno/lib/core/result.ts @@ -375,7 +375,7 @@ class Result implements Promise void) | null): Promise> { return this._getOrCreatePromise().finally(onfinally) } diff --git a/packages/neo4j-driver-deno/lib/core/session.ts b/packages/neo4j-driver-deno/lib/core/session.ts index 3e0626a1e..c5b5752dc 100644 --- a/packages/neo4j-driver-deno/lib/core/session.ts +++ b/packages/neo4j-driver-deno/lib/core/session.ts @@ -561,6 +561,12 @@ class Session { } } + // @ts-ignore + [Symbol.asyncDispose](): Promise { + console.log("calling async dispose") + return this.close() + } + _connectionHolderWithMode (mode: SessionMode): ConnectionHolder { if (mode === ACCESS_MODE_READ) { return this._readConnectionHolder diff --git a/packages/neo4j-driver-deno/test/neo4j.test.ts b/packages/neo4j-driver-deno/test/neo4j.test.ts new file mode 100644 index 000000000..2bc4f4fff --- /dev/null +++ b/packages/neo4j-driver-deno/test/neo4j.test.ts @@ -0,0 +1,44 @@ +/** + * Copyright (c) "Neo4j" + * Neo4j Sweden AB [http://neo4j.com] + * + * This file is part of Neo4j. + * + * 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 + * + * http://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. + */ +import neo4j from '../lib/mod.ts' + +const env = Deno.env.toObject() + +const username = env.TEST_NEO4J_USER || 'neo4j' +const password = env.TEST_NEO4J_PASS || 'password' +const hostname = env.TEST_NEO4J_HOST || 'localhost' +const scheme = env.TEST_NEO4J_SCHEME || 'bolt' +const boltPort = env.TEST_NEO4J_BOLT_PORT || 7687 +const uri = `${scheme}://${hostname}:${boltPort}` +const authToken = neo4j.auth.basic(username, password) + +// Deno will fail with resource leaks +Deno.test('neo4j.driver should be able to use explicity resource management', async () => { + await using driver = neo4j.driver(uri, authToken) + + await driver.executeQuery('RETURN 1') +}) + +// Deno will fail with resource leaks +Deno.test('driver.session should be able to use explicity resource management', async () => { + await using driver = neo4j.driver(uri, authToken) + await using session = driver.session() + + await session.executeRead(tx => "RETURN 1") +}) diff --git a/packages/neo4j-driver/src/session-rx.js b/packages/neo4j-driver/src/session-rx.js index 1cdef102a..8fa09f695 100644 --- a/packages/neo4j-driver/src/session-rx.js +++ b/packages/neo4j-driver/src/session-rx.js @@ -163,6 +163,11 @@ export default class RxSession { }) } + // @ts-expect-error + [Symbol.asyncDispose] () { + return this.close() + } + /** * Returns the bookmarks received following the last successfully completed query, which is executed * either in an {@link RxTransaction} obtained from this session instance or directly through one of From 9ed9ea5c746ca0b0f79634bc0d1442a04c3155e6 Mon Sep 17 00:00:00 2001 From: Antonio Barcelos Date: Thu, 26 Oct 2023 14:28:02 +0200 Subject: [PATCH 02/11] Fix some details --- packages/core/src/driver.ts | 3 ++- packages/core/src/session.ts | 3 ++- packages/neo4j-driver-deno/lib/core/driver.ts | 3 ++- packages/neo4j-driver-deno/lib/core/integer.ts | 2 +- packages/neo4j-driver-deno/lib/core/session.ts | 5 +++-- packages/neo4j-driver/src/session-rx.js | 1 - 6 files changed, 10 insertions(+), 7 deletions(-) diff --git a/packages/core/src/driver.ts b/packages/core/src/driver.ts index 7b25c9d63..09f3353bc 100644 --- a/packages/core/src/driver.ts +++ b/packages/core/src/driver.ts @@ -776,7 +776,8 @@ class Driver { return Promise.resolve() } - // @ts-expect-error + // eslint-disable-next-line + // @ts-ignore [Symbol.asyncDispose] (): Promise { return this.close() } diff --git a/packages/core/src/session.ts b/packages/core/src/session.ts index f59f6a679..554177a59 100644 --- a/packages/core/src/session.ts +++ b/packages/core/src/session.ts @@ -561,7 +561,8 @@ class Session { } } - // @ts-expect-error + // eslint-disable-next-line + // @ts-ignore [Symbol.asyncDispose] (): Promise { console.log('calling async dispose') return this.close() diff --git a/packages/neo4j-driver-deno/lib/core/driver.ts b/packages/neo4j-driver-deno/lib/core/driver.ts index 69c102bad..e151bde47 100644 --- a/packages/neo4j-driver-deno/lib/core/driver.ts +++ b/packages/neo4j-driver-deno/lib/core/driver.ts @@ -776,8 +776,9 @@ class Driver { return Promise.resolve() } + // eslint-disable-next-line // @ts-ignore - [Symbol.asyncDispose](): Promise { + [Symbol.asyncDispose] (): Promise { return this.close() } diff --git a/packages/neo4j-driver-deno/lib/core/integer.ts b/packages/neo4j-driver-deno/lib/core/integer.ts index d7a64e154..540fe4db1 100644 --- a/packages/neo4j-driver-deno/lib/core/integer.ts +++ b/packages/neo4j-driver-deno/lib/core/integer.ts @@ -695,7 +695,7 @@ class Integer { */ shiftRight (numBits: number | Integer): Integer { let bitsCount: number = Integer.toNumber(numBits) - let numBitNum: number = Integer.toNumber(numBits) + const numBitNum: number = Integer.toNumber(numBits) if ((bitsCount &= 63) === 0) { return Integer.ZERO diff --git a/packages/neo4j-driver-deno/lib/core/session.ts b/packages/neo4j-driver-deno/lib/core/session.ts index c5b5752dc..6feed37fb 100644 --- a/packages/neo4j-driver-deno/lib/core/session.ts +++ b/packages/neo4j-driver-deno/lib/core/session.ts @@ -561,9 +561,10 @@ class Session { } } + // eslint-disable-next-line // @ts-ignore - [Symbol.asyncDispose](): Promise { - console.log("calling async dispose") + [Symbol.asyncDispose] (): Promise { + console.log('calling async dispose') return this.close() } diff --git a/packages/neo4j-driver/src/session-rx.js b/packages/neo4j-driver/src/session-rx.js index 8fa09f695..d5739e8f4 100644 --- a/packages/neo4j-driver/src/session-rx.js +++ b/packages/neo4j-driver/src/session-rx.js @@ -163,7 +163,6 @@ export default class RxSession { }) } - // @ts-expect-error [Symbol.asyncDispose] () { return this.close() } From ad2aaebf283262cd09c83edfd91f53620d815fdb Mon Sep 17 00:00:00 2001 From: Antonio Barcelos Date: Thu, 26 Oct 2023 14:55:50 +0200 Subject: [PATCH 03/11] Send params two layers down --- testkit/build.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testkit/build.py b/testkit/build.py index 7fdbd7000..2776b9259 100644 --- a/testkit/build.py +++ b/testkit/build.py @@ -19,7 +19,7 @@ def init_monorepo(): def clean_and_build(): run_in_driver_repo(["npm", "run", "clean"], env=os.environ) run_in_driver_repo(["npm", "run", "build"], env=os.environ) - run_in_driver_repo(["npm", "run", "build::deno", "--", + run_in_driver_repo(["npm", "run", "build::deno", "--", "--", "--output=lib2/"], env=os.environ) if is_deno() and is_team_city(): From 1ff5c33a48e282b1ff5d2794a419e4176700332f Mon Sep 17 00:00:00 2001 From: Antonio Barcelos Date: Thu, 26 Oct 2023 15:12:38 +0200 Subject: [PATCH 04/11] Add param forward in scripts --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 9db08d61a..63293b227 100644 --- a/package.json +++ b/package.json @@ -40,8 +40,8 @@ "scripts": { "clean": "lerna clean -y && lerna run clean", "build": "lerna bootstrap --ci", - "set_version::deno": "lerna run set_version --scope neo4j-driver-deno --stream", - "build::deno": "lerna run build --scope neo4j-driver-deno --stream", + "set_version::deno": "lerna run set_version --scope neo4j-driver-deno --stream -- ", + "build::deno": "lerna run build --scope neo4j-driver-deno --stream -- ", "build::notci": "lerna bootstrap", "docs": "lerna run docs --stream --concurrency 1", "test::unit": "lerna run test::unit --stream", From f35a5eb6a91eb740331c1f5c6f7c7a34c58cb324 Mon Sep 17 00:00:00 2001 From: Antonio Barcelos Date: Thu, 26 Oct 2023 15:18:20 +0200 Subject: [PATCH 05/11] join -- --- testkit/build.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testkit/build.py b/testkit/build.py index 2776b9259..65effc62c 100644 --- a/testkit/build.py +++ b/testkit/build.py @@ -19,7 +19,7 @@ def init_monorepo(): def clean_and_build(): run_in_driver_repo(["npm", "run", "clean"], env=os.environ) run_in_driver_repo(["npm", "run", "build"], env=os.environ) - run_in_driver_repo(["npm", "run", "build::deno", "--", "--", + run_in_driver_repo(["npm", "run", "build::deno", "-- --", "--output=lib2/"], env=os.environ) if is_deno() and is_team_city(): From 8ef2b3f8fc3efc43c4ba32de01207947638dad44 Mon Sep 17 00:00:00 2001 From: Antonio Barcelos Date: Thu, 26 Oct 2023 15:26:57 +0200 Subject: [PATCH 06/11] Add missing package.json --- packages/neo4j-driver-deno/package.json | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 packages/neo4j-driver-deno/package.json diff --git a/packages/neo4j-driver-deno/package.json b/packages/neo4j-driver-deno/package.json new file mode 100644 index 000000000..69ed1462f --- /dev/null +++ b/packages/neo4j-driver-deno/package.json @@ -0,0 +1,19 @@ +{ + "name": "neo4j-driver-deno", + "version": "5.0.0-dev", + "description": "Package just used for running scripts", + "private": true, + "main": "index.js", + "directories": { + "lib": "lib", + "test": "test" + }, + "scripts": { + "test": "npm run test::integration", + "test::integration": "deno test --allow-all ./test", + "set_version": "deno run --allow-read --allow-write ./versioning.ts --output=. --filename=current.version.ts", + "build": "deno run --allow-read --allow-write --allow-net ./generate.ts" + }, + "author": "Neo4j", + "license": "Apache-2.0" +} From 9990ad77d338b6f0d776aa55b23f092280a145a4 Mon Sep 17 00:00:00 2001 From: Antonio Barcelos Date: Thu, 26 Oct 2023 15:34:25 +0200 Subject: [PATCH 07/11] separate -- --- testkit/build.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testkit/build.py b/testkit/build.py index 65effc62c..2776b9259 100644 --- a/testkit/build.py +++ b/testkit/build.py @@ -19,7 +19,7 @@ def init_monorepo(): def clean_and_build(): run_in_driver_repo(["npm", "run", "clean"], env=os.environ) run_in_driver_repo(["npm", "run", "build"], env=os.environ) - run_in_driver_repo(["npm", "run", "build::deno", "-- --", + run_in_driver_repo(["npm", "run", "build::deno", "--", "--", "--output=lib2/"], env=os.environ) if is_deno() and is_team_city(): From 1fbbf4ec8d02fe4a1870246df577ed63bc3af6e4 Mon Sep 17 00:00:00 2001 From: Antonio Barcelos Date: Thu, 26 Oct 2023 15:49:20 +0200 Subject: [PATCH 08/11] Bump deno version --- testkit/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testkit/Dockerfile b/testkit/Dockerfile index 15e30041a..4fdbdbd96 100644 --- a/testkit/Dockerfile +++ b/testkit/Dockerfile @@ -1,7 +1,7 @@ FROM ubuntu:20.04 ARG NODE_VERSION=10 -ARG DENO_VERSION=1.19.3 +ARG DENO_VERSION=1.37.2 ENV DEBIAN_FRONTEND noninteractive ENV NODE_OPTIONS --max_old_space_size=4096 --use-openssl-ca From f174c70bbb476b7c44183d0f411f249dccc9a585 Mon Sep 17 00:00:00 2001 From: Antonio Barcelos Date: Thu, 26 Oct 2023 16:02:49 +0200 Subject: [PATCH 09/11] Fix deno run parans --- packages/testkit-backend/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/testkit-backend/package.json b/packages/testkit-backend/package.json index 09b0fe41e..383249588 100644 --- a/packages/testkit-backend/package.json +++ b/packages/testkit-backend/package.json @@ -12,7 +12,7 @@ "scripts": { "build": "rollup src/index.js --config rollup.config.js", "start": "node --version | grep -q v10. && node -r esm src/index.js || node --experimental-specifier-resolution=node src/index.js", - "start::deno": "deno run --allow-read --allow-write --allow-net --allow-env --allow-run deno/index.ts", + "start::deno": "deno run --allow-read --allow-write --allow-net --allow-sys --allow-run deno/index.ts", "clean": "rm -fr node_modules public/index.js", "prepare": "npm run build", "node": "node" From f03e17642f1f132f06b7f4d2cd918c01bc7aad39 Mon Sep 17 00:00:00 2001 From: Antonio Barcelos Date: Thu, 26 Oct 2023 16:16:59 +0200 Subject: [PATCH 10/11] Add --allow-env for testkit params --- packages/testkit-backend/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/testkit-backend/package.json b/packages/testkit-backend/package.json index 383249588..45ae6e92b 100644 --- a/packages/testkit-backend/package.json +++ b/packages/testkit-backend/package.json @@ -12,7 +12,7 @@ "scripts": { "build": "rollup src/index.js --config rollup.config.js", "start": "node --version | grep -q v10. && node -r esm src/index.js || node --experimental-specifier-resolution=node src/index.js", - "start::deno": "deno run --allow-read --allow-write --allow-net --allow-sys --allow-run deno/index.ts", + "start::deno": "deno run --allow-read --allow-write --allow-net --allow-env --allow-sys --allow-run deno/index.ts", "clean": "rm -fr node_modules public/index.js", "prepare": "npm run build", "node": "node" From 3cea3f9547ca8ab2e22c8049cdb1cab9c438b601 Mon Sep 17 00:00:00 2001 From: Antonio Barcelos Date: Thu, 26 Oct 2023 16:40:05 +0200 Subject: [PATCH 11/11] Remove console.log --- packages/core/src/session.ts | 1 - packages/neo4j-driver-deno/lib/core/session.ts | 1 - 2 files changed, 2 deletions(-) diff --git a/packages/core/src/session.ts b/packages/core/src/session.ts index 554177a59..bc10af73f 100644 --- a/packages/core/src/session.ts +++ b/packages/core/src/session.ts @@ -564,7 +564,6 @@ class Session { // eslint-disable-next-line // @ts-ignore [Symbol.asyncDispose] (): Promise { - console.log('calling async dispose') return this.close() } diff --git a/packages/neo4j-driver-deno/lib/core/session.ts b/packages/neo4j-driver-deno/lib/core/session.ts index 6feed37fb..5c65570c9 100644 --- a/packages/neo4j-driver-deno/lib/core/session.ts +++ b/packages/neo4j-driver-deno/lib/core/session.ts @@ -564,7 +564,6 @@ class Session { // eslint-disable-next-line // @ts-ignore [Symbol.asyncDispose] (): Promise { - console.log('calling async dispose') return this.close() }