From 60e5824524166333d1e789199574053667c14a50 Mon Sep 17 00:00:00 2001 From: Revone Date: Thu, 31 Aug 2023 00:18:13 +0800 Subject: [PATCH] The APIs of Heap and Priority Queue got optimized --- jest.config.js | 2 +- package-lock.json | 468 +++++++++--------- package.json | 5 +- src/data-structures/graph/abstract-graph.ts | 53 +- src/data-structures/heap/heap.ts | 60 +-- .../priority-queue/priority-queue.ts | 4 +- tests/integration/bst.test.ts | 2 +- tests/integration/heap.test.js | 19 + tests/unit/data-structures/heap/heap.test.ts | 53 +- .../data-structures/heap/max-heap.test.ts | 20 +- .../data-structures/heap/min-heap.test.ts | 26 +- .../priority-queue/min-priority-queue.test.ts | 40 +- .../priority-queue/priority-queue.test.ts | 12 +- tests/utils/index.ts | 1 + tests/utils/number.ts | 3 + 15 files changed, 454 insertions(+), 314 deletions(-) create mode 100644 tests/integration/heap.test.js create mode 100644 tests/utils/index.ts create mode 100644 tests/utils/number.ts diff --git a/jest.config.js b/jest.config.js index 51f93b3..6a6f586 100644 --- a/jest.config.js +++ b/jest.config.js @@ -1,5 +1,5 @@ module.exports = { preset: 'ts-jest', testEnvironment: 'node', - testMatch: ['/tests/**/*.test.ts'], + testMatch: ['/tests/**/*.test.ts', '/tests/**/*.test.js'], }; \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index c15fc26..7e7f4db 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,16 +1,17 @@ { "name": "data-structure-typed", - "version": "1.19.4", + "version": "1.19.5", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "data-structure-typed", - "version": "1.19.4", + "version": "1.19.5", "license": "MIT", "dependencies": { - "avl-tree-typed": "^1.19.44", - "bst-typed": "^1.19.45", + "avl-tree-typed": "^1.19.5", + "bst-typed": "^1.19.5", + "heap-typed": "^1.19.5", "zod": "^3.22.2" }, "devDependencies": { @@ -37,12 +38,12 @@ } }, "node_modules/@babel/code-frame": { - "version": "7.22.10", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.10.tgz", - "integrity": "sha512-/KKIMG4UEL35WmI9OlvMhurwtytjvXoFcGNrOvyG9zIzA8YmPjVtIZUf7b05+TPO7G7/GEmLHDaoCgACHl9hhA==", + "version": "7.22.13", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.13.tgz", + "integrity": "sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w==", "dev": true, "dependencies": { - "@babel/highlight": "^7.22.10", + "@babel/highlight": "^7.22.13", "chalk": "^2.4.2" }, "engines": { @@ -115,9 +116,9 @@ } }, "node_modules/@babel/core": { - "version": "7.22.10", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.22.10.tgz", - "integrity": "sha512-fTmqbbUBAwCcre6zPzNngvsI0aNrPZe77AeqvDxWM9Nm+04RrJ3CAmGHA9f7lJQY6ZMhRztNemy4uslDxTX4Qw==", + "version": "7.22.11", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.22.11.tgz", + "integrity": "sha512-lh7RJrtPdhibbxndr6/xx0w8+CVlY5FJZiaSz908Fpy+G0xkBFTvwLcKJFF4PJxVfGhVWNebikpWGnOoC71juQ==", "dev": true, "dependencies": { "@ampproject/remapping": "^2.2.0", @@ -125,15 +126,15 @@ "@babel/generator": "^7.22.10", "@babel/helper-compilation-targets": "^7.22.10", "@babel/helper-module-transforms": "^7.22.9", - "@babel/helpers": "^7.22.10", - "@babel/parser": "^7.22.10", + "@babel/helpers": "^7.22.11", + "@babel/parser": "^7.22.11", "@babel/template": "^7.22.5", - "@babel/traverse": "^7.22.10", - "@babel/types": "^7.22.10", + "@babel/traverse": "^7.22.11", + "@babel/types": "^7.22.11", "convert-source-map": "^1.7.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", - "json5": "^2.2.2", + "json5": "^2.2.3", "semver": "^6.3.1" }, "engines": { @@ -325,23 +326,23 @@ } }, "node_modules/@babel/helpers": { - "version": "7.22.10", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.22.10.tgz", - "integrity": "sha512-a41J4NW8HyZa1I1vAndrraTlPZ/eZoga2ZgS7fEr0tZJGVU4xqdE80CEm0CcNjha5EZ8fTBYLKHF0kqDUuAwQw==", + "version": "7.22.11", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.22.11.tgz", + "integrity": "sha512-vyOXC8PBWaGc5h7GMsNx68OH33cypkEDJCHvYVVgVbbxJDROYVtexSk0gK5iCF1xNjRIN2s8ai7hwkWDq5szWg==", "dev": true, "dependencies": { "@babel/template": "^7.22.5", - "@babel/traverse": "^7.22.10", - "@babel/types": "^7.22.10" + "@babel/traverse": "^7.22.11", + "@babel/types": "^7.22.11" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/highlight": { - "version": "7.22.10", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.10.tgz", - "integrity": "sha512-78aUtVcT7MUscr0K5mIEnkwxPE0MaxkR5RxRwuHaQ+JuU5AmTPhY+do2mdzVTnIJJpyBglql2pehuBIWHug+WQ==", + "version": "7.22.13", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.13.tgz", + "integrity": "sha512-C/BaXcnnvBCmHTpz/VGZ8jgtE2aYlW4hxDhseJAWZb7gqGM/qtCK6iZUb0TyKFf7BOUsBH7Q7fkRsDRhg1XklQ==", "dev": true, "dependencies": { "@babel/helper-validator-identifier": "^7.22.5", @@ -409,9 +410,9 @@ } }, "node_modules/@babel/parser": { - "version": "7.22.10", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.22.10.tgz", - "integrity": "sha512-lNbdGsQb9ekfsnjFGhEiF4hfFqGgfOP3H3d27re3n+CGhNuTSUEQdfWk556sTLNTloczcdM5TYF2LhzmDQKyvQ==", + "version": "7.22.13", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.22.13.tgz", + "integrity": "sha512-3l6+4YOvc9wx7VlCSw4yQfcBo01ECA8TicQfbnCPuCEpRQrf+gTUyGdxNw+pyTUyywp6JRD1w0YQs9TpBXYlkw==", "dev": true, "bin": { "parser": "bin/babel-parser.js" @@ -612,9 +613,9 @@ } }, "node_modules/@babel/traverse": { - "version": "7.22.10", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.22.10.tgz", - "integrity": "sha512-Q/urqV4pRByiNNpb/f5OSv28ZlGJiFiiTh+GAHktbIrkPhPbl90+uW6SmpoLyZqutrg9AEaEf3Q/ZBRHBXgxig==", + "version": "7.22.11", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.22.11.tgz", + "integrity": "sha512-mzAenteTfomcB7mfPtyi+4oe5BZ6MXxWcn4CX+h4IRJ+OOGXBrWU6jDQavkQI9Vuc5P+donFabBfFCcmWka9lQ==", "dev": true, "dependencies": { "@babel/code-frame": "^7.22.10", @@ -623,8 +624,8 @@ "@babel/helper-function-name": "^7.22.5", "@babel/helper-hoist-variables": "^7.22.5", "@babel/helper-split-export-declaration": "^7.22.6", - "@babel/parser": "^7.22.10", - "@babel/types": "^7.22.10", + "@babel/parser": "^7.22.11", + "@babel/types": "^7.22.11", "debug": "^4.1.0", "globals": "^11.1.0" }, @@ -633,9 +634,9 @@ } }, "node_modules/@babel/types": { - "version": "7.22.10", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.22.10.tgz", - "integrity": "sha512-obaoigiLrlDZ7TUQln/8m4mSqIW2QFeOrCQc9r+xsaHGNoplVNYlRVpsfE8Vj35GEm2ZH4ZhrNYogs/3fj85kg==", + "version": "7.22.11", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.22.11.tgz", + "integrity": "sha512-siazHiGuZRz9aB9NpHy9GOs9xiQPKnMzgdr493iI1M67vRXpnEq8ZOOKzezC5q7zwuQ6sDhdSp4SD9ixKSqKZg==", "dev": true, "dependencies": { "@babel/helper-string-parser": "^7.22.5", @@ -695,9 +696,9 @@ } }, "node_modules/@jest/console": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-29.6.3.tgz", - "integrity": "sha512-ukZbHAdDH4ktZIOKvWs1juAXhiVAdvCyM8zv4S/7Ii3vJSDvMW5k+wOVGMQmHLHUFw3Ko63ZQNy7NI6PSlsD5w==", + "version": "29.6.4", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-29.6.4.tgz", + "integrity": "sha512-wNK6gC0Ha9QeEPSkeJedQuTQqxZYnDPuDcDhVuVatRvMkL4D0VTvFVZj+Yuh6caG2aOfzkUZ36KtCmLNtR02hw==", "dev": true, "dependencies": { "@jest/types": "^29.6.3", @@ -761,15 +762,15 @@ "dev": true }, "node_modules/@jest/core": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/@jest/core/-/core-29.6.3.tgz", - "integrity": "sha512-skV1XrfNxfagmjRUrk2FyN5/2YwIzdWVVBa/orUfbLvQUANXxERq2pTvY0I+FinWHjDKB2HRmpveUiph4X0TJw==", + "version": "29.6.4", + "resolved": "https://registry.npmjs.org/@jest/core/-/core-29.6.4.tgz", + "integrity": "sha512-U/vq5ccNTSVgYH7mHnodHmCffGWHJnz/E1BEWlLuK5pM4FZmGfBn/nrJGLjUsSmyx3otCeqc1T31F4y08AMDLg==", "dev": true, "dependencies": { - "@jest/console": "^29.6.3", - "@jest/reporters": "^29.6.3", - "@jest/test-result": "^29.6.3", - "@jest/transform": "^29.6.3", + "@jest/console": "^29.6.4", + "@jest/reporters": "^29.6.4", + "@jest/test-result": "^29.6.4", + "@jest/transform": "^29.6.4", "@jest/types": "^29.6.3", "@types/node": "*", "ansi-escapes": "^4.2.1", @@ -778,18 +779,18 @@ "exit": "^0.1.2", "graceful-fs": "^4.2.9", "jest-changed-files": "^29.6.3", - "jest-config": "^29.6.3", - "jest-haste-map": "^29.6.3", + "jest-config": "^29.6.4", + "jest-haste-map": "^29.6.4", "jest-message-util": "^29.6.3", "jest-regex-util": "^29.6.3", - "jest-resolve": "^29.6.3", - "jest-resolve-dependencies": "^29.6.3", - "jest-runner": "^29.6.3", - "jest-runtime": "^29.6.3", - "jest-snapshot": "^29.6.3", + "jest-resolve": "^29.6.4", + "jest-resolve-dependencies": "^29.6.4", + "jest-runner": "^29.6.4", + "jest-runtime": "^29.6.4", + "jest-snapshot": "^29.6.4", "jest-util": "^29.6.3", "jest-validate": "^29.6.3", - "jest-watcher": "^29.6.3", + "jest-watcher": "^29.6.4", "micromatch": "^4.0.4", "pretty-format": "^29.6.3", "slash": "^3.0.0", @@ -878,12 +879,12 @@ } }, "node_modules/@jest/environment": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-29.6.3.tgz", - "integrity": "sha512-u/u3cCztYCfgBiGHsamqP5x+XvucftOGPbf5RJQxfpeC1y4AL8pCjKvPDA3oCmdhZYPgk5AE0VOD/flweR69WA==", + "version": "29.6.4", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-29.6.4.tgz", + "integrity": "sha512-sQ0SULEjA1XUTHmkBRl7A1dyITM9yb1yb3ZNKPX3KlTd6IG7mWUe3e2yfExtC2Zz1Q+mMckOLHmL/qLiuQJrBQ==", "dev": true, "dependencies": { - "@jest/fake-timers": "^29.6.3", + "@jest/fake-timers": "^29.6.4", "@jest/types": "^29.6.3", "@types/node": "*", "jest-mock": "^29.6.3" @@ -893,22 +894,22 @@ } }, "node_modules/@jest/expect": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-29.6.3.tgz", - "integrity": "sha512-Ic08XbI2jlg6rECy+CGwk/8NDa6VE7UmIG6++9OTPAMnQmNGY28hu69Nf629CWv6T7YMODLbONxDFKdmQeI9FA==", + "version": "29.6.4", + "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-29.6.4.tgz", + "integrity": "sha512-Warhsa7d23+3X5bLbrbYvaehcgX5TLYhI03JKoedTiI8uJU4IhqYBWF7OSSgUyz4IgLpUYPkK0AehA5/fRclAA==", "dev": true, "dependencies": { - "expect": "^29.6.3", - "jest-snapshot": "^29.6.3" + "expect": "^29.6.4", + "jest-snapshot": "^29.6.4" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/@jest/expect-utils": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-29.6.3.tgz", - "integrity": "sha512-nvOEW4YoqRKD9HBJ9OJ6przvIvP9qilp5nAn1462P5ZlL/MM9SgPEZFyjTGPfs7QkocdUsJa6KjHhyRn4ueItA==", + "version": "29.6.4", + "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-29.6.4.tgz", + "integrity": "sha512-FEhkJhqtvBwgSpiTrocquJCdXPsyvNKcl/n7A3u7X4pVoF4bswm11c9d4AV+kfq2Gpv/mM8x7E7DsRvH+djkrg==", "dev": true, "dependencies": { "jest-get-type": "^29.6.3" @@ -918,9 +919,9 @@ } }, "node_modules/@jest/fake-timers": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-29.6.3.tgz", - "integrity": "sha512-pa1wmqvbj6eX0nMvOM2VDAWvJOI5A/Mk3l8O7n7EsAh71sMZblaKO9iT4GjIj0LwwK3CP/Jp1ypEV0x3m89RvA==", + "version": "29.6.4", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-29.6.4.tgz", + "integrity": "sha512-6UkCwzoBK60edXIIWb0/KWkuj7R7Qq91vVInOe3De6DSpaEiqjKcJw4F7XUet24Wupahj9J6PlR09JqJ5ySDHw==", "dev": true, "dependencies": { "@jest/types": "^29.6.3", @@ -935,13 +936,13 @@ } }, "node_modules/@jest/globals": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-29.6.3.tgz", - "integrity": "sha512-RB+uI+CZMHntzlnOPlll5x/jgRff3LEPl/td/jzMXiIgR0iIhKq9qm1HLU+EC52NuoVy/1swit/sDGjVn4bc6A==", + "version": "29.6.4", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-29.6.4.tgz", + "integrity": "sha512-wVIn5bdtjlChhXAzVXavcY/3PEjf4VqM174BM3eGL5kMxLiZD5CLnbmkEyA1Dwh9q8XjP6E8RwjBsY/iCWrWsA==", "dev": true, "dependencies": { - "@jest/environment": "^29.6.3", - "@jest/expect": "^29.6.3", + "@jest/environment": "^29.6.4", + "@jest/expect": "^29.6.4", "@jest/types": "^29.6.3", "jest-mock": "^29.6.3" }, @@ -950,15 +951,15 @@ } }, "node_modules/@jest/reporters": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-29.6.3.tgz", - "integrity": "sha512-kGz59zMi0GkVjD2CJeYWG9k6cvj7eBqt9aDAqo2rcCLRTYlvQ62Gu/n+tOmJMBHGjzeijjuCENjzTyYBgrtLUw==", + "version": "29.6.4", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-29.6.4.tgz", + "integrity": "sha512-sxUjWxm7QdchdrD3NfWKrL8FBsortZeibSJv4XLjESOOjSUOkjQcb0ZHJwfhEGIvBvTluTzfG2yZWZhkrXJu8g==", "dev": true, "dependencies": { "@bcoe/v8-coverage": "^0.2.3", - "@jest/console": "^29.6.3", - "@jest/test-result": "^29.6.3", - "@jest/transform": "^29.6.3", + "@jest/console": "^29.6.4", + "@jest/test-result": "^29.6.4", + "@jest/transform": "^29.6.4", "@jest/types": "^29.6.3", "@jridgewell/trace-mapping": "^0.3.18", "@types/node": "*", @@ -974,7 +975,7 @@ "istanbul-reports": "^3.1.3", "jest-message-util": "^29.6.3", "jest-util": "^29.6.3", - "jest-worker": "^29.6.3", + "jest-worker": "^29.6.4", "slash": "^3.0.0", "string-length": "^4.0.1", "strip-ansi": "^6.0.0", @@ -1131,12 +1132,12 @@ } }, "node_modules/@jest/test-result": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-29.6.3.tgz", - "integrity": "sha512-k7ZZaNvOSMBHPZYiy0kuiaFoyansR5QnTwDux1EjK3kD5iWpRVyJIJ0RAIV39SThafchuW59vra7F8mdy5Hfgw==", + "version": "29.6.4", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-29.6.4.tgz", + "integrity": "sha512-uQ1C0AUEN90/dsyEirgMLlouROgSY+Wc/JanVVk0OiUKa5UFh7sJpMEM3aoUBAz2BRNvUJ8j3d294WFuRxSyOQ==", "dev": true, "dependencies": { - "@jest/console": "^29.6.3", + "@jest/console": "^29.6.4", "@jest/types": "^29.6.3", "@types/istanbul-lib-coverage": "^2.0.0", "collect-v8-coverage": "^1.0.0" @@ -1146,14 +1147,14 @@ } }, "node_modules/@jest/test-sequencer": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-29.6.3.tgz", - "integrity": "sha512-/SmijaAU2TY9ComFGIYa6Z+fmKqQMnqs2Nmwb0P/Z/tROdZ7M0iruES1EaaU9PBf8o9uED5xzaJ3YPFEIcDgAg==", + "version": "29.6.4", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-29.6.4.tgz", + "integrity": "sha512-E84M6LbpcRq3fT4ckfKs9ryVanwkaIB0Ws9bw3/yP4seRLg/VaCZ/LgW0MCq5wwk4/iP/qnilD41aj2fsw2RMg==", "dev": true, "dependencies": { - "@jest/test-result": "^29.6.3", + "@jest/test-result": "^29.6.4", "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.6.3", + "jest-haste-map": "^29.6.4", "slash": "^3.0.0" }, "engines": { @@ -1161,9 +1162,9 @@ } }, "node_modules/@jest/transform": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-29.6.3.tgz", - "integrity": "sha512-dPIc3DsvMZ/S8ut4L2ViCj265mKO0owB0wfzBv2oGzL9pQ+iRvJewHqLBmsGb7XFb5UotWIEtvY5A/lnylaIoQ==", + "version": "29.6.4", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-29.6.4.tgz", + "integrity": "sha512-8thgRSiXUqtr/pPGY/OsyHuMjGyhVnWrFAwoxmIemlBuiMyU1WFs0tXoNxzcr4A4uErs/ABre76SGmrr5ab/AA==", "dev": true, "dependencies": { "@babel/core": "^7.11.6", @@ -1174,7 +1175,7 @@ "convert-source-map": "^2.0.0", "fast-json-stable-stringify": "^2.1.0", "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.6.3", + "jest-haste-map": "^29.6.4", "jest-regex-util": "^29.6.3", "jest-util": "^29.6.3", "micromatch": "^4.0.4", @@ -1468,9 +1469,9 @@ } }, "node_modules/@types/node": { - "version": "20.5.3", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.5.3.tgz", - "integrity": "sha512-ITI7rbWczR8a/S6qjAW7DMqxqFMjjTo61qZVWJ1ubPvbIQsL5D/TvwjYEalM8Kthpe3hTzOGrF2TGbAu2uyqeA==", + "version": "20.5.7", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.5.7.tgz", + "integrity": "sha512-dP7f3LdZIysZnmvP3ANJYTSwg+wLLl8p7RqniVlV7j+oXSXAbt9h0WIBFmJy5inWZoX9wZN6eXx+YXd9Rh3RBA==", "dev": true }, "node_modules/@types/stack-utils": { @@ -1626,21 +1627,21 @@ } }, "node_modules/avl-tree-typed": { - "version": "1.19.44", - "resolved": "https://registry.npmjs.org/avl-tree-typed/-/avl-tree-typed-1.19.44.tgz", - "integrity": "sha512-psn/2Lmz4umFa5CedqvfQOH5kqnB+GU4piOZZGTQQ+kX0hR6N9Sdzv10xFj1TqEdMmBjNR+Ng5q4TL/mrb+a2w==", + "version": "1.19.45", + "resolved": "https://registry.npmjs.org/avl-tree-typed/-/avl-tree-typed-1.19.45.tgz", + "integrity": "sha512-/uluq7j+c5iTmcVzHHvuMKWdoIJ9ZqSfDgRXkPIqBHXxOEr05jxfwt1IRgdxJhsv3gOv4/mRzKJKfwNqjKv1Qg==", "dependencies": { "data-structure-typed": "^1.19.4", "zod": "^3.22.2" } }, "node_modules/babel-jest": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.6.3.tgz", - "integrity": "sha512-1Ne93zZZEy5XmTa4Q+W5+zxBrDpExX8E3iy+xJJ+24ewlfo/T3qHfQJCzi/MMVFmBQDNxtRR/Gfd2dwb/0yrQw==", + "version": "29.6.4", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.6.4.tgz", + "integrity": "sha512-meLj23UlSLddj6PC+YTOFRgDAtjnZom8w/ACsrx0gtPtv5cJZk0A5Unk5bV4wixD7XaPCN1fQvpww8czkZURmw==", "dev": true, "dependencies": { - "@jest/transform": "^29.6.3", + "@jest/transform": "^29.6.4", "@types/babel__core": "^7.1.14", "babel-plugin-istanbul": "^6.1.1", "babel-preset-jest": "^29.6.3", @@ -1880,11 +1881,11 @@ } }, "node_modules/bst-typed": { - "version": "1.19.45", - "resolved": "https://registry.npmjs.org/bst-typed/-/bst-typed-1.19.45.tgz", - "integrity": "sha512-x/vLIaFDdgv4zcTVgpJmTwW6BanpPPM9eE/P8v72VE9eFgBEspDGOSJsd4Fel7fO8DF+MUqwksMreCln0ECy3g==", + "version": "1.19.5", + "resolved": "https://registry.npmjs.org/bst-typed/-/bst-typed-1.19.5.tgz", + "integrity": "sha512-xvW7t2v6G6YA3pyLTAnxTrIeOy+Lpuwi9Sr/lVnif7sJhAh4qutUu9PQZgttTfqdySGfBHux4N7bOCj5/l17KQ==", "dependencies": { - "data-structure-typed": "^1.19.4", + "data-structure-typed": "^1.19.5", "zod": "^3.22.2" } }, @@ -1913,9 +1914,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001522", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001522.tgz", - "integrity": "sha512-TKiyTVZxJGhsTszLuzb+6vUZSjVOAhClszBr2Ta2k9IwtNBT/4dzmL6aywt0HCgEZlmwJzXJd8yNiob6HgwTRg==", + "version": "1.0.30001524", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001524.tgz", + "integrity": "sha512-Jj917pJtYg9HSJBF95HVX3Cdr89JUyLT4IZ8SvM5aDRni95swKgYi3TgYLH5hnGfPE/U1dg6IfZ50UsIlLkwSA==", "dev": true, "funding": [ { @@ -2146,11 +2147,21 @@ } }, "node_modules/data-structure-typed": { - "version": "1.19.4", - "resolved": "https://registry.npmjs.org/data-structure-typed/-/data-structure-typed-1.19.4.tgz", - "integrity": "sha512-qZ05QoqIl78GDFCdDFA1WumRX+MX0v60nB/GrP7ZyqPFamOk6TdaIcZqDQCZ+mrQeHmSID2l6jhROWtfiTjBrw==", + "version": "1.19.5", + "resolved": "https://registry.npmjs.org/data-structure-typed/-/data-structure-typed-1.19.5.tgz", + "integrity": "sha512-Q6rn8ww6AN8es5FD49p1pRuka5TIH3bp/nb3LmsAuL0ChecskVf2V94iNk33aRQXnvQwN8R+4YBsEn2j1/xqQA==", "dependencies": { - "bst-typed": "^1.19.0", + "avl-tree-typed": "^1.19.44", + "bst-typed": "^1.19.45", + "zod": "^3.22.2" + } + }, + "node_modules/data-structure-typed/node_modules/bst-typed": { + "version": "1.19.45", + "resolved": "https://registry.npmjs.org/bst-typed/-/bst-typed-1.19.45.tgz", + "integrity": "sha512-x/vLIaFDdgv4zcTVgpJmTwW6BanpPPM9eE/P8v72VE9eFgBEspDGOSJsd4Fel7fO8DF+MUqwksMreCln0ECy3g==", + "dependencies": { + "data-structure-typed": "^1.19.4", "zod": "^3.22.2" } }, @@ -2195,9 +2206,9 @@ } }, "node_modules/dependency-cruiser": { - "version": "13.1.4", - "resolved": "https://registry.npmjs.org/dependency-cruiser/-/dependency-cruiser-13.1.4.tgz", - "integrity": "sha512-cMrtPuPxp+uqQMt196IJ8lgKQglu+dbTsWgGHV+Y0AkWYJISjByluA1YcmPjglzXB9innj0s+oEcGE/N6Jm4aA==", + "version": "13.1.5", + "resolved": "https://registry.npmjs.org/dependency-cruiser/-/dependency-cruiser-13.1.5.tgz", + "integrity": "sha512-+ADEHbORwoH4HGF/RIg2sCb5hjL6JU5sPsmnzxwY0508wpj+ZdWomzkaYsctsdf+OD+iVCijbxmcR3VMW2v16w==", "dev": true, "dependencies": { "acorn": "8.10.0", @@ -2224,7 +2235,7 @@ "semver-try-require": "6.2.3", "teamcity-service-messages": "0.1.14", "tsconfig-paths-webpack-plugin": "4.1.0", - "watskeburt": "0.12.1", + "watskeburt": "1.0.1", "wrap-ansi": "8.1.0" }, "bin": { @@ -2264,9 +2275,9 @@ "dev": true }, "node_modules/electron-to-chromium": { - "version": "1.4.499", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.499.tgz", - "integrity": "sha512-0NmjlYBLKVHva4GABWAaHuPJolnDuL0AhV3h1hES6rcLCWEIbRL6/8TghfsVwkx6TEroQVdliX7+aLysUpKvjw==", + "version": "1.4.505", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.505.tgz", + "integrity": "sha512-0A50eL5BCCKdxig2SsCXhpuztnB9PfUgRMojj5tMvt8O54lbwz3t6wNgnpiTRosw5QjlJB7ixhVyeg8daLQwSQ==", "dev": true }, "node_modules/emittery": { @@ -2382,14 +2393,14 @@ } }, "node_modules/expect": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/expect/-/expect-29.6.3.tgz", - "integrity": "sha512-x1vY4LlEMWUYVZQrFi4ZANXFwqYbJ/JNQspLVvzhW2BNY28aNcXMQH6imBbt+RBf5sVRTodYHXtSP/TLEU0Dxw==", + "version": "29.6.4", + "resolved": "https://registry.npmjs.org/expect/-/expect-29.6.4.tgz", + "integrity": "sha512-F2W2UyQ8XYyftHT57dtfg8Ue3X5qLgm2sSug0ivvLRH/VKNRL/pDxg/TH7zVzbQB0tu80clNFy6LU7OS/VSEKA==", "dev": true, "dependencies": { - "@jest/expect-utils": "^29.6.3", + "@jest/expect-utils": "^29.6.4", "jest-get-type": "^29.6.3", - "jest-matcher-utils": "^29.6.3", + "jest-matcher-utils": "^29.6.4", "jest-message-util": "^29.6.3", "jest-util": "^29.6.3" }, @@ -2613,6 +2624,15 @@ "node": ">=8" } }, + "node_modules/heap-typed": { + "version": "1.19.5", + "resolved": "https://registry.npmjs.org/heap-typed/-/heap-typed-1.19.5.tgz", + "integrity": "sha512-E7H53VmkgDIa1+sVqao2i/QcUE2k85ZYLAmknM9+2QMb9wjJOCaFNiPjuZJLb0J7q+4nrgGedF7kxGFZFa+gwQ==", + "dependencies": { + "data-structure-typed": "^1.19.5", + "zod": "^3.22.2" + } + }, "node_modules/html-escaper": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", @@ -2878,9 +2898,9 @@ } }, "node_modules/jackspeak": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-2.3.0.tgz", - "integrity": "sha512-uKmsITSsF4rUWQHzqaRUuyAir3fZfW3f202Ee34lz/gZCi970CPZwyQXLGNgWJvvZbvFyzeyGq0+4fcG/mBKZg==", + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-2.3.1.tgz", + "integrity": "sha512-4iSY3Bh1Htv+kLhiiZunUhQ+OYXIn0ze3ulq8JeWrFKmhPAJSySV2+kdtRh2pGcCeF0s6oR8Oc+pYZynJj4t8A==", "dev": true, "dependencies": { "@isaacs/cliui": "^8.0.2" @@ -2896,15 +2916,15 @@ } }, "node_modules/jest": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/jest/-/jest-29.6.3.tgz", - "integrity": "sha512-alueLuoPCDNHFcFGmgETR4KpQ+0ff3qVaiJwxQM4B5sC0CvXcgg4PEi7xrDkxuItDmdz/FVc7SSit4KEu8GRvw==", + "version": "29.6.4", + "resolved": "https://registry.npmjs.org/jest/-/jest-29.6.4.tgz", + "integrity": "sha512-tEFhVQFF/bzoYV1YuGyzLPZ6vlPrdfvDmmAxudA1dLEuiztqg2Rkx20vkKY32xiDROcD2KXlgZ7Cu8RPeEHRKw==", "dev": true, "dependencies": { - "@jest/core": "^29.6.3", + "@jest/core": "^29.6.4", "@jest/types": "^29.6.3", "import-local": "^3.0.2", - "jest-cli": "^29.6.3" + "jest-cli": "^29.6.4" }, "bin": { "jest": "bin/jest.js" @@ -2936,14 +2956,14 @@ } }, "node_modules/jest-circus": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-29.6.3.tgz", - "integrity": "sha512-p0R5YqZEMnOpHqHLWRSjm2z/0p6RNsrNE/GRRT3eli8QGOAozj6Ys/3Tv+Ej+IfltJoSPwcQ6/hOCRkNlxLLCw==", + "version": "29.6.4", + "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-29.6.4.tgz", + "integrity": "sha512-YXNrRyntVUgDfZbjXWBMPslX1mQ8MrSG0oM/Y06j9EYubODIyHWP8hMUbjbZ19M3M+zamqEur7O80HODwACoJw==", "dev": true, "dependencies": { - "@jest/environment": "^29.6.3", - "@jest/expect": "^29.6.3", - "@jest/test-result": "^29.6.3", + "@jest/environment": "^29.6.4", + "@jest/expect": "^29.6.4", + "@jest/test-result": "^29.6.4", "@jest/types": "^29.6.3", "@types/node": "*", "chalk": "^4.0.0", @@ -2951,10 +2971,10 @@ "dedent": "^1.0.0", "is-generator-fn": "^2.0.0", "jest-each": "^29.6.3", - "jest-matcher-utils": "^29.6.3", + "jest-matcher-utils": "^29.6.4", "jest-message-util": "^29.6.3", - "jest-runtime": "^29.6.3", - "jest-snapshot": "^29.6.3", + "jest-runtime": "^29.6.4", + "jest-snapshot": "^29.6.4", "jest-util": "^29.6.3", "p-limit": "^3.1.0", "pretty-format": "^29.6.3", @@ -3016,19 +3036,19 @@ "dev": true }, "node_modules/jest-cli": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-29.6.3.tgz", - "integrity": "sha512-KuPdXUPXQIf0t6DvmG8MV4QyhcjR1a6ruKl3YL7aGn/AQ8JkROwFkWzEpDIpt11Qy188dHbRm8WjwMsV/4nmnQ==", + "version": "29.6.4", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-29.6.4.tgz", + "integrity": "sha512-+uMCQ7oizMmh8ZwRfZzKIEszFY9ksjjEQnTEMTaL7fYiL3Kw4XhqT9bYh+A4DQKUb67hZn2KbtEnDuHvcgK4pQ==", "dev": true, "dependencies": { - "@jest/core": "^29.6.3", - "@jest/test-result": "^29.6.3", + "@jest/core": "^29.6.4", + "@jest/test-result": "^29.6.4", "@jest/types": "^29.6.3", "chalk": "^4.0.0", "exit": "^0.1.2", "graceful-fs": "^4.2.9", "import-local": "^3.0.2", - "jest-config": "^29.6.3", + "jest-config": "^29.6.4", "jest-util": "^29.6.3", "jest-validate": "^29.6.3", "prompts": "^2.0.1", @@ -3099,26 +3119,26 @@ "dev": true }, "node_modules/jest-config": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-29.6.3.tgz", - "integrity": "sha512-nb9bOq2aEqogbyL4F9mLkAeQGAgNt7Uz6U59YtQDIxFPiL7Ejgq0YIrp78oyEHD6H4CIV/k7mFrK7eFDzUJ69w==", + "version": "29.6.4", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-29.6.4.tgz", + "integrity": "sha512-JWohr3i9m2cVpBumQFv2akMEnFEPVOh+9L2xIBJhJ0zOaci2ZXuKJj0tgMKQCBZAKA09H049IR4HVS/43Qb19A==", "dev": true, "dependencies": { "@babel/core": "^7.11.6", - "@jest/test-sequencer": "^29.6.3", + "@jest/test-sequencer": "^29.6.4", "@jest/types": "^29.6.3", - "babel-jest": "^29.6.3", + "babel-jest": "^29.6.4", "chalk": "^4.0.0", "ci-info": "^3.2.0", "deepmerge": "^4.2.2", "glob": "^7.1.3", "graceful-fs": "^4.2.9", - "jest-circus": "^29.6.3", - "jest-environment-node": "^29.6.3", + "jest-circus": "^29.6.4", + "jest-environment-node": "^29.6.4", "jest-get-type": "^29.6.3", "jest-regex-util": "^29.6.3", - "jest-resolve": "^29.6.3", - "jest-runner": "^29.6.3", + "jest-resolve": "^29.6.4", + "jest-runner": "^29.6.4", "jest-util": "^29.6.3", "jest-validate": "^29.6.3", "micromatch": "^4.0.4", @@ -3235,9 +3255,9 @@ } }, "node_modules/jest-diff": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.6.3.tgz", - "integrity": "sha512-3sw+AdWnwH9sSNohMRKA7JiYUJSRr/WS6+sEFfBuhxU5V5GlEVKfvUn8JuMHE0wqKowemR1C2aHy8VtXbaV8dQ==", + "version": "29.6.4", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.6.4.tgz", + "integrity": "sha512-9F48UxR9e4XOEZvoUXEHSWY4qC4zERJaOfrbBg9JpbJOO43R1vN76REt/aMGZoY6GD5g84nnJiBIVlscegefpw==", "dev": true, "dependencies": { "chalk": "^4.0.0", @@ -3376,13 +3396,13 @@ "dev": true }, "node_modules/jest-environment-node": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-29.6.3.tgz", - "integrity": "sha512-PKl7upfPJXMYbWpD+60o4HP86KvFO2c9dZ+Zr6wUzsG5xcPx/65o3ArNgHW5M0RFvLYdW4/aieR4JSooD0a2ew==", + "version": "29.6.4", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-29.6.4.tgz", + "integrity": "sha512-i7SbpH2dEIFGNmxGCpSc2w9cA4qVD+wfvg2ZnfQ7XVrKL0NA5uDVBIiGH8SR4F0dKEv/0qI5r+aDomDf04DpEQ==", "dev": true, "dependencies": { - "@jest/environment": "^29.6.3", - "@jest/fake-timers": "^29.6.3", + "@jest/environment": "^29.6.4", + "@jest/fake-timers": "^29.6.4", "@jest/types": "^29.6.3", "@types/node": "*", "jest-mock": "^29.6.3", @@ -3402,9 +3422,9 @@ } }, "node_modules/jest-haste-map": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.6.3.tgz", - "integrity": "sha512-GecR5YavfjkhOytEFHAeI6aWWG3f/cOKNB1YJvj/B76xAmeVjy4zJUYobGF030cRmKaO1FBw3V8CZZ6KVh9ZSw==", + "version": "29.6.4", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.6.4.tgz", + "integrity": "sha512-12Ad+VNTDHxKf7k+M65sviyynRoZYuL1/GTuhEVb8RYsNSNln71nANRb/faSyWvx0j+gHcivChXHIoMJrGYjog==", "dev": true, "dependencies": { "@jest/types": "^29.6.3", @@ -3415,7 +3435,7 @@ "graceful-fs": "^4.2.9", "jest-regex-util": "^29.6.3", "jest-util": "^29.6.3", - "jest-worker": "^29.6.3", + "jest-worker": "^29.6.4", "micromatch": "^4.0.4", "walker": "^1.0.8" }, @@ -3440,13 +3460,13 @@ } }, "node_modules/jest-matcher-utils": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.6.3.tgz", - "integrity": "sha512-6ZrMYINZdwduSt5Xu18/n49O1IgXdjsfG7NEZaQws9k69eTKWKcVbJBw/MZsjOZe2sSyJFmuzh8042XWwl54Zg==", + "version": "29.6.4", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.6.4.tgz", + "integrity": "sha512-KSzwyzGvK4HcfnserYqJHYi7sZVqdREJ9DMPAKVbS98JsIAvumihaNUbjrWw0St7p9IY7A9UskCW5MYlGmBQFQ==", "dev": true, "dependencies": { "chalk": "^4.0.0", - "jest-diff": "^29.6.3", + "jest-diff": "^29.6.4", "jest-get-type": "^29.6.3", "pretty-format": "^29.6.3" }, @@ -3613,14 +3633,14 @@ } }, "node_modules/jest-resolve": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-29.6.3.tgz", - "integrity": "sha512-WMXwxhvzDeA/J+9jz1i8ZKGmbw/n+s988EiUvRI4egM+eTn31Hb5v10Re3slG3/qxntkBt2/6GkQVDGu6Bwyhw==", + "version": "29.6.4", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-29.6.4.tgz", + "integrity": "sha512-fPRq+0vcxsuGlG0O3gyoqGTAxasagOxEuyoxHeyxaZbc9QNek0AmJWSkhjlMG+mTsj+8knc/mWb3fXlRNVih7Q==", "dev": true, "dependencies": { "chalk": "^4.0.0", "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.6.3", + "jest-haste-map": "^29.6.4", "jest-pnp-resolver": "^1.2.2", "jest-util": "^29.6.3", "jest-validate": "^29.6.3", @@ -3633,13 +3653,13 @@ } }, "node_modules/jest-resolve-dependencies": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-29.6.3.tgz", - "integrity": "sha512-iah5nhSPTwtUV7yzpTc9xGg8gP3Ch2VNsuFMsKoCkNCrQSbFtx5KRPemmPJ32AUhTSDqJXB6djPN6zAaUGV53g==", + "version": "29.6.4", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-29.6.4.tgz", + "integrity": "sha512-7+6eAmr1ZBF3vOAJVsfLj1QdqeXG+WYhidfLHBRZqGN24MFRIiKG20ItpLw2qRAsW/D2ZUUmCNf6irUr/v6KHA==", "dev": true, "dependencies": { "jest-regex-util": "^29.6.3", - "jest-snapshot": "^29.6.3" + "jest-snapshot": "^29.6.4" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" @@ -3695,30 +3715,30 @@ "dev": true }, "node_modules/jest-runner": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-29.6.3.tgz", - "integrity": "sha512-E4zsMhQnjhirFPhDTJgoLMWUrVCDij/KGzWlbslDHGuO8Hl2pVUfOiygMzVZtZq+BzmlqwEr7LYmW+WFLlmX8w==", + "version": "29.6.4", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-29.6.4.tgz", + "integrity": "sha512-SDaLrMmtVlQYDuG0iSPYLycG8P9jLI+fRm8AF/xPKhYDB2g6xDWjXBrR5M8gEWsK6KVFlebpZ4QsrxdyIX1Jaw==", "dev": true, "dependencies": { - "@jest/console": "^29.6.3", - "@jest/environment": "^29.6.3", - "@jest/test-result": "^29.6.3", - "@jest/transform": "^29.6.3", + "@jest/console": "^29.6.4", + "@jest/environment": "^29.6.4", + "@jest/test-result": "^29.6.4", + "@jest/transform": "^29.6.4", "@jest/types": "^29.6.3", "@types/node": "*", "chalk": "^4.0.0", "emittery": "^0.13.1", "graceful-fs": "^4.2.9", "jest-docblock": "^29.6.3", - "jest-environment-node": "^29.6.3", - "jest-haste-map": "^29.6.3", + "jest-environment-node": "^29.6.4", + "jest-haste-map": "^29.6.4", "jest-leak-detector": "^29.6.3", "jest-message-util": "^29.6.3", - "jest-resolve": "^29.6.3", - "jest-runtime": "^29.6.3", + "jest-resolve": "^29.6.4", + "jest-runtime": "^29.6.4", "jest-util": "^29.6.3", - "jest-watcher": "^29.6.3", - "jest-worker": "^29.6.3", + "jest-watcher": "^29.6.4", + "jest-worker": "^29.6.4", "p-limit": "^3.1.0", "source-map-support": "0.5.13" }, @@ -3776,17 +3796,17 @@ "dev": true }, "node_modules/jest-runtime": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-29.6.3.tgz", - "integrity": "sha512-VM0Z3a9xaqizGpEKwCOIhImkrINYzxgwk8oQAvrmAiXX8LNrJrRjyva30RkuRY0ETAotHLlUcd2moviCA1hgsQ==", + "version": "29.6.4", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-29.6.4.tgz", + "integrity": "sha512-s/QxMBLvmwLdchKEjcLfwzP7h+jsHvNEtxGP5P+Fl1FMaJX2jMiIqe4rJw4tFprzCwuSvVUo9bn0uj4gNRXsbA==", "dev": true, "dependencies": { - "@jest/environment": "^29.6.3", - "@jest/fake-timers": "^29.6.3", - "@jest/globals": "^29.6.3", + "@jest/environment": "^29.6.4", + "@jest/fake-timers": "^29.6.4", + "@jest/globals": "^29.6.4", "@jest/source-map": "^29.6.3", - "@jest/test-result": "^29.6.3", - "@jest/transform": "^29.6.3", + "@jest/test-result": "^29.6.4", + "@jest/transform": "^29.6.4", "@jest/types": "^29.6.3", "@types/node": "*", "chalk": "^4.0.0", @@ -3794,12 +3814,12 @@ "collect-v8-coverage": "^1.0.0", "glob": "^7.1.3", "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.6.3", + "jest-haste-map": "^29.6.4", "jest-message-util": "^29.6.3", "jest-mock": "^29.6.3", "jest-regex-util": "^29.6.3", - "jest-resolve": "^29.6.3", - "jest-snapshot": "^29.6.3", + "jest-resolve": "^29.6.4", + "jest-snapshot": "^29.6.4", "jest-util": "^29.6.3", "slash": "^3.0.0", "strip-bom": "^4.0.0" @@ -3900,9 +3920,9 @@ } }, "node_modules/jest-snapshot": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-29.6.3.tgz", - "integrity": "sha512-66Iu7H1ojiveQMGFnKecHIZPPPBjZwfQEnF6wxqpxGf57sV3YSUtAb5/sTKM5TPa3OndyxZp1wxHFbmgVhc53w==", + "version": "29.6.4", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-29.6.4.tgz", + "integrity": "sha512-VC1N8ED7+4uboUKGIDsbvNAZb6LakgIPgAF4RSpF13dN6YaMokfRqO+BaqK4zIh6X3JffgwbzuGqDEjHm/MrvA==", "dev": true, "dependencies": { "@babel/core": "^7.11.6", @@ -3910,16 +3930,16 @@ "@babel/plugin-syntax-jsx": "^7.7.2", "@babel/plugin-syntax-typescript": "^7.7.2", "@babel/types": "^7.3.3", - "@jest/expect-utils": "^29.6.3", - "@jest/transform": "^29.6.3", + "@jest/expect-utils": "^29.6.4", + "@jest/transform": "^29.6.4", "@jest/types": "^29.6.3", "babel-preset-current-node-syntax": "^1.0.0", "chalk": "^4.0.0", - "expect": "^29.6.3", + "expect": "^29.6.4", "graceful-fs": "^4.2.9", - "jest-diff": "^29.6.3", + "jest-diff": "^29.6.4", "jest-get-type": "^29.6.3", - "jest-matcher-utils": "^29.6.3", + "jest-matcher-utils": "^29.6.4", "jest-message-util": "^29.6.3", "jest-util": "^29.6.3", "natural-compare": "^1.4.0", @@ -4124,12 +4144,12 @@ "dev": true }, "node_modules/jest-watcher": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-29.6.3.tgz", - "integrity": "sha512-NgpFjZ2U2MKusjidbi4Oiu7tfs+nrgdIxIEVROvH1cFmOei9Uj25lwkMsakqLnH/s0nEcvxO1ck77FiRlcnpZg==", + "version": "29.6.4", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-29.6.4.tgz", + "integrity": "sha512-oqUWvx6+On04ShsT00Ir9T4/FvBeEh2M9PTubgITPxDa739p4hoQweWPRGyYeaojgT0xTpZKF0Y/rSY1UgMxvQ==", "dev": true, "dependencies": { - "@jest/test-result": "^29.6.3", + "@jest/test-result": "^29.6.4", "@jest/types": "^29.6.3", "@types/node": "*", "ansi-escapes": "^4.2.1", @@ -4192,9 +4212,9 @@ "dev": true }, "node_modules/jest-worker": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.6.3.tgz", - "integrity": "sha512-wacANXecZ/GbQakpf2CClrqrlwsYYDSXFd4fIGdL+dXpM2GWoJ+6bhQ7vR3TKi3+gkSfBkjy1/khH/WrYS4Q6g==", + "version": "29.6.4", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.6.4.tgz", + "integrity": "sha512-6dpvFV4WjcWbDVGgHTWo/aupl8/LbBx2NSKfiwqf79xC/yeJjKHT1+StcKy/2KTmW16hE68ccKVOtXf+WZGz7Q==", "dev": true, "dependencies": { "@types/node": "*", @@ -5534,9 +5554,9 @@ } }, "node_modules/watskeburt": { - "version": "0.12.1", - "resolved": "https://registry.npmjs.org/watskeburt/-/watskeburt-0.12.1.tgz", - "integrity": "sha512-DHfW+OGKYFTei2jtylJg6ZLCO9P9BHMsf9v4Z4QBvocfdJ0gY+Re7K4rPmpkSpfNLdhzsvovPIQ4z836yViTNA==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/watskeburt/-/watskeburt-1.0.1.tgz", + "integrity": "sha512-MOvC8vf3hAVo1HPF/pkba7065mt6A/P9unLlFvYhZ7Yyuht16tmfCYi/LqHABG4hIRMZCbvY8eDWHPy81eSADA==", "dev": true, "bin": { "watskeburt": "dist/cli.js" diff --git a/package.json b/package.json index e5911dc..067586c 100644 --- a/package.json +++ b/package.json @@ -65,8 +65,9 @@ "typescript": "^4.9.5" }, "dependencies": { - "avl-tree-typed": "^1.19.44", - "bst-typed": "^1.19.45", + "avl-tree-typed": "^1.19.5", + "bst-typed": "^1.19.5", + "heap-typed": "^1.19.5", "zod": "^3.22.2" } } diff --git a/src/data-structures/graph/abstract-graph.ts b/src/data-structures/graph/abstract-graph.ts index 313ea51..a2d8962 100644 --- a/src/data-structures/graph/abstract-graph.ts +++ b/src/data-structures/graph/abstract-graph.ts @@ -129,6 +129,7 @@ export abstract class AbstractGraph, E extends Abs abstract createEdge(srcOrV1: VertexId | string, destOrV2: VertexId | string, weight?: number, val?: E): E; abstract removeEdge(edge: E): E | null; + abstract getEdge(srcOrId: V | VertexId, destOrId: V | VertexId): E | null; abstract degreeOf(vertexOrId: V | VertexId): number; @@ -141,8 +142,6 @@ export abstract class AbstractGraph, E extends Abs abstract getEndsOfEdge(edge: E): [V, V] | null; - protected abstract _addEdgeOnly(edge: E): boolean; - /** * The function "getVertex" returns the vertex with the specified ID or null if it doesn't exist. * @param {VertexId} vertexId - The `vertexId` parameter is the identifier of the vertex that you want to retrieve from @@ -165,7 +164,9 @@ export abstract class AbstractGraph, E extends Abs } addVertex(vertex: V): boolean + addVertex(id: VertexId, val?: V['val']): boolean + addVertex(idOrVertex: VertexId | V, val?: V['val']): boolean { if (idOrVertex instanceof AbstractVertex) { return this._addVertexOnly(idOrVertex); @@ -256,7 +257,6 @@ export abstract class AbstractGraph, E extends Abs } } - /** * The function `getAllPathsBetween` finds all paths between two vertices in a graph using depth-first search. * @param {V | VertexId} v1 - The parameter `v1` represents either a vertex object (`V`) or a vertex ID (`VertexId`). @@ -691,29 +691,6 @@ export abstract class AbstractGraph, E extends Abs return {distMap, preMap, seen, paths, minDist, minPath}; } - /** - * Dijkstra algorithm time: O(logVE) space: O(V + E) - * / - - /** - * Dijkstra algorithm time: O(logVE) space: O(V + E) - * Dijkstra's algorithm is used to find the shortest paths from a source node to all other nodes in a graph. Its basic idea is to repeatedly choose the node closest to the source node and update the distances of other nodes using this node as an intermediary. Dijkstra's algorithm requires that the edge weights in the graph are non-negative. - */ - - - /** - * BellmanFord time:O(VE) space:O(V) - * one to rest pairs - * The Bellman-Ford algorithm is also used to find the shortest paths from a source node to all other nodes in a graph. Unlike Dijkstra's algorithm, it can handle edge weights that are negative. Its basic idea involves iterative relaxation of all edges for several rounds to gradually approximate the shortest paths. Due to its ability to handle negative-weight edges, the Bellman-Ford algorithm is more flexible in some scenarios. - * The `bellmanFord` function implements the Bellman-Ford algorithm to find the shortest path from a source vertex to - */ - - /** - * Floyd algorithm time: O(V^3) space: O(V^2), not support graph with negative weight cycle - * all pairs - * The Floyd-Warshall algorithm is used to find the shortest paths between all pairs of nodes in a graph. It employs dynamic programming to compute the shortest paths from any node to any other node. The Floyd-Warshall algorithm's advantage lies in its ability to handle graphs with negative-weight edges, and it can simultaneously compute shortest paths between any two nodes. - */ - /** * BellmanFord time:O(VE) space:O(V) * one to rest pairs @@ -823,6 +800,29 @@ export abstract class AbstractGraph, E extends Abs return {hasNegativeCycle, distMap, preMap, paths, min, minPath}; } + /** + * Dijkstra algorithm time: O(logVE) space: O(V + E) + * / + + /** + * Dijkstra algorithm time: O(logVE) space: O(V + E) + * Dijkstra's algorithm is used to find the shortest paths from a source node to all other nodes in a graph. Its basic idea is to repeatedly choose the node closest to the source node and update the distances of other nodes using this node as an intermediary. Dijkstra's algorithm requires that the edge weights in the graph are non-negative. + */ + + + /** + * BellmanFord time:O(VE) space:O(V) + * one to rest pairs + * The Bellman-Ford algorithm is also used to find the shortest paths from a source node to all other nodes in a graph. Unlike Dijkstra's algorithm, it can handle edge weights that are negative. Its basic idea involves iterative relaxation of all edges for several rounds to gradually approximate the shortest paths. Due to its ability to handle negative-weight edges, the Bellman-Ford algorithm is more flexible in some scenarios. + * The `bellmanFord` function implements the Bellman-Ford algorithm to find the shortest path from a source vertex to + */ + + /** + * Floyd algorithm time: O(V^3) space: O(V^2), not support graph with negative weight cycle + * all pairs + * The Floyd-Warshall algorithm is used to find the shortest paths between all pairs of nodes in a graph. It employs dynamic programming to compute the shortest paths from any node to any other node. The Floyd-Warshall algorithm's advantage lies in its ability to handle graphs with negative-weight edges, and it can simultaneously compute shortest paths between any two nodes. + */ + /** * Floyd algorithm time: O(V^3) space: O(V^2), not support graph with negative weight cycle * all pairs @@ -1007,6 +1007,7 @@ export abstract class AbstractGraph, E extends Abs return {dfnMap, lowMap, bridges, articulationPoints, SCCs, cycles}; } + protected abstract _addEdgeOnly(edge: E): boolean; protected _addVertexOnly(newVertex: V): boolean { if (this.hasVertex(newVertex)) { diff --git a/src/data-structures/heap/heap.ts b/src/data-structures/heap/heap.ts index 49dc797..4e47546 100644 --- a/src/data-structures/heap/heap.ts +++ b/src/data-structures/heap/heap.ts @@ -88,20 +88,30 @@ export abstract class Heap { return this._pq.size < 1; } + peek(isItem?: undefined): T | undefined; + peek(isItem: false): T | undefined; + peek(isItem: true): HeapItem | null; /** * The `peek` function returns the top item in the priority queue without removing it. * @returns The `peek()` method is returning either a `HeapItem` object or `null`.Returns an val with the highest priority in the queue */ - peek(): HeapItem | null { - return this._pq.peek(); + peek(isItem?: boolean): HeapItem | null | T | undefined { + isItem = isItem ?? false; + const peeked = this._pq.peek(); + return isItem ? peeked : peeked?.val; } + peekLast(isItem?: undefined): T | undefined; + peekLast(isItem: false): T | undefined; + peekLast(isItem: true): HeapItem | null; /** * The `peekLast` function returns the last item in the heap. * @returns The method `peekLast()` returns either a `HeapItem` object or `null`.Returns an val with the lowest priority in the queue */ - peekLast(): HeapItem | null { - return this._pq.leaf(); + peekLast(isItem?: boolean): HeapItem | null | T | undefined { + isItem = isItem ?? false; + const leafItem = this._pq.leaf(); + return isItem ? leafItem : leafItem?.val; } /** @@ -114,41 +124,26 @@ export abstract class Heap { * @returns The `add` method returns the instance of the `Heap` class. * @throws {Error} if priority is not a valid number */ - add(val: T, priority?: number): Heap { - if (typeof val === 'number') { - priority = val; - } else { - if (priority === undefined) { - throw new Error('.add expects a numeric priority'); - } - } - - if (priority && Number.isNaN(+priority)) { - throw new Error('.add expects a numeric priority'); - } - - if (Number.isNaN(+priority) && Number.isNaN(this._priorityExtractor(val))) { - throw new Error( - '.add expects a numeric priority ' - + 'or a constructor callback that returns a number' - ); - } - - const _priority = !Number.isNaN(+priority) ? priority : this._priorityExtractor(val); - this._pq.add(new HeapItem(_priority, val)); + add(priority: number, val?: T,): Heap { + val = (val === undefined) ? priority as T : val; + this._pq.add(new HeapItem(priority, val)); return this; } + poll(isItem?: undefined): T | undefined; + poll(isItem: false): T | undefined; + poll(isItem: true): HeapItem | null; /** * The `poll` function returns the top item from a priority queue or null if the queue is empty.Removes and returns an val with the highest priority in the queue * @returns either a HeapItem object or null. */ - poll(): HeapItem | null { + poll(isItem?: boolean): HeapItem | null | T | undefined { + isItem = isItem ?? false; const top = this._pq.poll(); if (!top) { return null; } - return top; + return isItem ? top : top.val; } /** @@ -166,12 +161,17 @@ export abstract class Heap { } } + toArray(isItem?: undefined): (T | undefined)[]; + toArray(isItem: false): (T | undefined)[]; + toArray(isItem: true): (HeapItem | null)[]; /** * The `toArray` function returns an array of `HeapItem` objects. * @returns An array of HeapItem objects.Returns a sorted list of vals */ - toArray(): HeapItem[] { - return this._pq.toArray(); + toArray(isItem?: boolean): (HeapItem | null | T | undefined)[] { + isItem = isItem ?? false; + const itemArray = this._pq.toArray(); + return isItem ? itemArray : itemArray.map(item => item.val); } /** diff --git a/src/data-structures/priority-queue/priority-queue.ts b/src/data-structures/priority-queue/priority-queue.ts index c846708..9470ea5 100644 --- a/src/data-structures/priority-queue/priority-queue.ts +++ b/src/data-structures/priority-queue/priority-queue.ts @@ -174,15 +174,15 @@ export class PriorityQueue { } /** - * Plan to support sorting of duplicate elements. + * O(n log n), In scenarios with smaller data sizes, heap sort is generally expected to be slower than QuickSort or MergeSort. */ + /** * The function sorts the elements in a data structure and returns them in an array. * Plan to support sorting of duplicate elements. * @returns The `sort()` method is returning an array of type `T[]`. */ sort(): T[] { - // TODO Plan to support sorting of duplicate elements. const visitedNode: T[] = []; while (this.size !== 0) { const top = this.poll(); diff --git a/tests/integration/bst.test.ts b/tests/integration/bst.test.ts index c1c69ff..aea43e2 100644 --- a/tests/integration/bst.test.ts +++ b/tests/integration/bst.test.ts @@ -1,6 +1,6 @@ import {BST, BSTNode} from 'bst-typed'; -describe('BST operations test', () => { +describe('Individual package BST operations test', () => { it('should perform various operations on a Binary Search Tree with numeric values', () => { const bst = new BST(); expect(bst).toBeInstanceOf(BST); diff --git a/tests/integration/heap.test.js b/tests/integration/heap.test.js new file mode 100644 index 0000000..13ce797 --- /dev/null +++ b/tests/integration/heap.test.js @@ -0,0 +1,19 @@ +const {MaxHeap, MinHeap} = require('heap-typed'); + +describe('JS Heap Operation Test', () => { + it('should numeric heap work well', function () { + const minNumHeap = new MinHeap(); + // minNumHeap.add(1).add(6).add(2).add(0).add(5).add(9); + // expect(minNumHeap.poll()).toBe(0); + // expect(minNumHeap.poll()).toBe(1); + // expect(minNumHeap.peek()).toBe(2); + // expect(minNumHeap.toArray().length).toBe(4); + // expect(minNumHeap.toArray()[0]).toBe(2); + // expect(minNumHeap.toArray()[1]).toBe(5); + // expect(minNumHeap.toArray()[2]).toBe(9); + // expect(minNumHeap.toArray()[3]).toBe(6); + + + }); +}); + diff --git a/tests/unit/data-structures/heap/heap.test.ts b/tests/unit/data-structures/heap/heap.test.ts index e0a0728..3d79a38 100644 --- a/tests/unit/data-structures/heap/heap.test.ts +++ b/tests/unit/data-structures/heap/heap.test.ts @@ -1,5 +1,52 @@ +import {MaxHeap, MinHeap} from '../../../../src'; + describe('Heap Operation Test', () => { - it('should xxx', function () { - expect(true).toBe(true); + it('should numeric heap work well', function () { + const minNumHeap = new MinHeap(); + minNumHeap.add(1).add(6).add(2).add(0).add(5).add(9); + expect(minNumHeap.poll()).toBe(0); + expect(minNumHeap.poll()).toBe(1); + expect(minNumHeap.peek()).toBe(2); + expect(minNumHeap.toArray().length).toBe(4); + expect(minNumHeap.toArray()[0]).toBe(2); + expect(minNumHeap.toArray()[1]).toBe(5); + expect(minNumHeap.toArray()[2]).toBe(9); + expect(minNumHeap.toArray()[3]).toBe(6); + + }); -}); \ No newline at end of file + + it('should object heap work well', function () { + const minHeap = new MinHeap<{ a: string }>(); + minHeap.add(1, {a: 'a1'}); + minHeap.add(6, {a: 'a6'}); + minHeap.add(2, {a: 'a2'}); + minHeap.add(0, {a: 'a0'}); + + expect(minHeap.peek()).toEqual({a: 'a0'}); + expect(minHeap.toArray()).toEqual(([{'a': 'a0'}, {'a': 'a1'}, {'a': 'a2'}, {'a': 'a6'}])); + let i = 0; + const expectPolled = [{'a': 'a0'}, {'a': 'a1'}, {'a': 'a2'}, {'a': 'a6'}]; + while (minHeap.size > 0) { + expect(minHeap.poll()).toEqual(expectPolled[i]); + i++; + } + + const maxHeap = new MaxHeap<{ a: string }>(); + maxHeap.add(1, {a: 'a1'}); + maxHeap.add(6, {a: 'a6'}); + maxHeap.add(5, {a: 'a5'}); + maxHeap.add(2, {a: 'a2'}); + maxHeap.add(0, {a: 'a0'}); + maxHeap.add(9, {a: 'a9'}); + expect(maxHeap.peek()).toEqual({'a': 'a9'}); + expect(maxHeap.toArray()).toEqual([{'a': 'a9'}, {'a': 'a2'}, {'a': 'a6'}, {'a': 'a1'}, {'a': 'a0'}, {'a': 'a5'}]); + const maxExpectPolled = [{'a': 'a9'}, {'a': 'a6'}, {'a': 'a5'}, {'a': 'a2'}, {'a': 'a1'}, {'a': 'a0'}]; + let maxI = 0; + while (maxHeap.size > 0) { + expect(maxHeap.poll()).toEqual(maxExpectPolled[maxI]); + maxI++; + } + }); +}); + diff --git a/tests/unit/data-structures/heap/max-heap.test.ts b/tests/unit/data-structures/heap/max-heap.test.ts index 409ef40..5fdce92 100644 --- a/tests/unit/data-structures/heap/max-heap.test.ts +++ b/tests/unit/data-structures/heap/max-heap.test.ts @@ -6,32 +6,32 @@ describe('MaxHeap Operation Test', () => { const maxHeap = new MaxHeap<{ keyA: string }>(); const myObj1 = {keyA: 'a1'}, myObj6 = {keyA: 'a6'}, myObj5 = {keyA: 'a5'}, myObj2 = {keyA: 'a2'}, myObj0 = {keyA: 'a0'}, myObj9 = {keyA: 'a9'}; - maxHeap.add(myObj1, 1); + maxHeap.add(1, myObj1); expect(maxHeap.has(myObj1)).toBe(true); expect(maxHeap.has(myObj9)).toBe(false); - maxHeap.add(myObj6, 6); + maxHeap.add(6, myObj6); expect(maxHeap.has(myObj6)).toBe(true); - maxHeap.add(myObj5, 5); + maxHeap.add(5, myObj5); expect(maxHeap.has(myObj5)).toBe(true); - maxHeap.add(myObj2, 2); + maxHeap.add(2, myObj2); expect(maxHeap.has(myObj2)).toBe(true); expect(maxHeap.has(myObj6)).toBe(true); - maxHeap.add(myObj0, 0); + maxHeap.add(0, myObj0); expect(maxHeap.has(myObj0)).toBe(true); expect(maxHeap.has(myObj9)).toBe(false); - maxHeap.add(myObj9, 9); + maxHeap.add(9, myObj9); expect(maxHeap.has(myObj9)).toBe(true); - const peek9 = maxHeap.peek(); + const peek9 = maxHeap.peek(true); peek9 && peek9.val && expect(peek9.val.keyA).toBe('a9'); - const heapToArr = maxHeap.toArray(); - expect(heapToArr.map(item => item.val?.keyA)).toEqual(['a9', 'a2', 'a6', 'a1', 'a0', 'a5']); + const heapToArr = maxHeap.toArray(true); + expect(heapToArr.map(item => item?.val?.keyA)).toEqual(['a9', 'a2', 'a6', 'a1', 'a0', 'a5']); const values = ['a9', 'a6', 'a5', 'a2', 'a1', 'a0']; let i = 0; while (maxHeap.size > 0) { - const polled = maxHeap.poll(); + const polled = maxHeap.poll(true); expect(polled).toBeInstanceOf(HeapItem); polled && expect(polled.val).toHaveProperty('keyA'); polled && polled.val && expect(polled.val.keyA).toBe(values[i]); diff --git a/tests/unit/data-structures/heap/min-heap.test.ts b/tests/unit/data-structures/heap/min-heap.test.ts index 2409208..3376228 100644 --- a/tests/unit/data-structures/heap/min-heap.test.ts +++ b/tests/unit/data-structures/heap/min-heap.test.ts @@ -21,21 +21,21 @@ describe('MinHeap Operation Test', () => { expect(minNumHeap.has(9)).toBe(true); expect(minNumHeap.size).toBe(6); - const poll1 = minNumHeap.poll(); + const poll1 = minNumHeap.poll(true); expect(poll1).toBeInstanceOf(HeapItem) poll1 instanceof HeapItem && expect(poll1.val).toBe(0); - const poll2 = minNumHeap.poll(); + const poll2 = minNumHeap.poll(true); expect(poll2).toBeInstanceOf(HeapItem) poll2 instanceof HeapItem && expect(poll2.val).toBe(1); - const peek1 = minNumHeap.peek(); + const peek1 = minNumHeap.peek(true); expect(peek1).toBeInstanceOf(HeapItem) peek1 instanceof HeapItem && expect(peek1.val).toBe(2); - const heapArray = minNumHeap.toArray(); + const heapArray = minNumHeap.toArray(true); expect(heapArray).toBeInstanceOf(Array); - expect(heapArray.map(item => item.priority)).toEqual([2, 5, 9, 6]); + expect(heapArray.map(item => item?.priority)).toEqual([2, 5, 9, 6]); expect(minNumHeap.size).toBe(4); }); @@ -52,26 +52,26 @@ describe('MinHeap Operation Test', () => { const obj1 = new MyObject('a1'), obj6 = new MyObject('a6'), obj2 = new MyObject('a2'), obj0 = new MyObject('a0'); - minObjHeap.add(obj1, 1); + minObjHeap.add(1, obj1); expect(minObjHeap.has(obj1)).toBe(true); expect(minObjHeap.has(obj6)).toBe(false); - minObjHeap.add(obj6, 6); + minObjHeap.add(6, obj6); expect(minObjHeap.has(obj6)).toBe(true); - minObjHeap.add(obj2, 2); + minObjHeap.add(2, obj2); expect(minObjHeap.has(obj2)).toBe(true); - minObjHeap.add(obj0, 0); + minObjHeap.add(0, obj0); expect(minObjHeap.has(obj0)).toBe(true); - const peek = minObjHeap.peek(); + const peek = minObjHeap.peek(true); peek && peek.val && expect(peek.val.keyA).toBe('a0'); - const heapToArr = minObjHeap.toArray(); - expect(heapToArr.map(item => item.val?.keyA)).toEqual(['a0', 'a1', 'a2', 'a6']); + const heapToArr = minObjHeap.toArray(true); + expect(heapToArr.map(item => item?.val?.keyA)).toEqual(['a0', 'a1', 'a2', 'a6']); const values = ['a0', 'a1', 'a2', 'a6']; let i = 0; while (minObjHeap.size > 0) { - const polled = minObjHeap.poll(); + const polled = minObjHeap.poll(true); expect(polled).toBeInstanceOf(HeapItem); polled && expect(polled.val).toBeInstanceOf(MyObject); polled && polled.val && expect(polled.val.keyA).toBe(values[i]); diff --git a/tests/unit/data-structures/priority-queue/min-priority-queue.test.ts b/tests/unit/data-structures/priority-queue/min-priority-queue.test.ts index 0a85244..7fa825b 100644 --- a/tests/unit/data-structures/priority-queue/min-priority-queue.test.ts +++ b/tests/unit/data-structures/priority-queue/min-priority-queue.test.ts @@ -1,4 +1,4 @@ -import {MinPriorityQueue} from '../../../../src'; +import {MinPriorityQueue, PriorityQueue} from '../../../../src'; describe('MinPriorityQueue Operation Test', () => { @@ -64,4 +64,42 @@ describe('MinPriorityQueue Operation Test', () => { expect(sortedArray).toEqual([1, 3, 5, 7]); }); + it('should PriorityQueue poll, pee, heapify, toArray work well', function () { + const minPQ = new PriorityQueue({nodes: [5, 2, 3, 4, 6, 1], comparator: (a, b) => a - b}); + expect(minPQ.toArray()).toEqual([1, 2, 3, 4, 6, 5]); + minPQ.poll(); + minPQ.poll(); + minPQ.poll(); + expect(minPQ.toArray()).toEqual([4, 5, 6]); + expect(minPQ.peek()).toBe(4); + expect(PriorityQueue.heapify({ + nodes: [3, 2, 1, 5, 6, 7, 8, 9, 10], + comparator: (a, b) => a - b + }).toArray()).toEqual([1, 2, 3, 5, 6, 7, 8, 9, 10]); + }); + + it('should Max PriorityQueue poll, peek, heapify, toArray work well', function () { + const maxPriorityQueue = new PriorityQueue({nodes: [5, 2, 3, 4, 6, 1], comparator: (a, b) => b - a}); + expect(maxPriorityQueue.toArray()).toEqual([6, 5, 3, 4, 2, 1]); + maxPriorityQueue.poll(); + maxPriorityQueue.poll(); + maxPriorityQueue.poll(); + expect(maxPriorityQueue.toArray()).toEqual([3, 2, 1]); + expect(maxPriorityQueue.peek()).toBe(3); + expect(PriorityQueue.heapify({ + nodes: [3, 2, 1, 5, 6, 7, 8, 9, 10], + comparator: (a, b) => a - b + }).toArray()).toEqual([1, 2, 3, 5, 6, 7, 8, 9, 10]); + }); + + it('should PriorityQueue clone, sort, getNodes, DFS work well', function () { + const minPQ1 = new PriorityQueue({nodes: [2, 5, 8, 3, 1, 6, 7, 4], comparator: (a, b) => a - b}); + const clonedPriorityQueue = minPQ1.clone(); + expect(clonedPriorityQueue.getNodes()).toEqual(minPQ1.getNodes()); + expect(clonedPriorityQueue.sort()).toEqual([1, 2, 3, 4, 5, 6, 7, 8]) + expect(minPQ1.DFS('in')).toEqual([4, 3, 2, 5, 1, 8, 6, 7]); + expect(minPQ1.DFS('post')).toEqual([4, 3, 5, 2, 8, 7, 6, 1]); + expect(minPQ1.DFS('pre')).toEqual([1, 2, 3, 4, 5, 6, 8, 7]); + }); + }); \ No newline at end of file diff --git a/tests/unit/data-structures/priority-queue/priority-queue.test.ts b/tests/unit/data-structures/priority-queue/priority-queue.test.ts index dd75a4f..b5f2a33 100644 --- a/tests/unit/data-structures/priority-queue/priority-queue.test.ts +++ b/tests/unit/data-structures/priority-queue/priority-queue.test.ts @@ -1,4 +1,5 @@ import {PriorityQueue} from '../../../../src'; +import {getRandomInt} from '../../../utils'; describe('PriorityQueue Operation Test', () => { @@ -14,4 +15,13 @@ describe('PriorityQueue Operation Test', () => { })).toBe(false); }); -}); \ No newline at end of file +}); + +describe('Priority Queue Performance Test', () => { + it('should numeric heap work well', function () { + const values = Array.from(new Array(10000), () => getRandomInt(1, 10000000)); + const minPriorityQueue = new PriorityQueue({nodes: values, comparator: (a, b) => a - b}); + const sorted = minPriorityQueue.sort() + expect(sorted).toEqual(values.sort((a, b) => a - b)); + }); +}) \ No newline at end of file diff --git a/tests/utils/index.ts b/tests/utils/index.ts new file mode 100644 index 0000000..678239e --- /dev/null +++ b/tests/utils/index.ts @@ -0,0 +1 @@ +export * from './number'; \ No newline at end of file diff --git a/tests/utils/number.ts b/tests/utils/number.ts new file mode 100644 index 0000000..36f9964 --- /dev/null +++ b/tests/utils/number.ts @@ -0,0 +1,3 @@ +export function getRandomInt(min: number, max: number) { + return Math.floor(Math.random() * (max - min + 1)) + min; +} \ No newline at end of file