From 71c620a28d2b4df0004bb0cd655895ed3d303bc1 Mon Sep 17 00:00:00 2001 From: Herve BECHER Date: Wed, 10 Sep 2025 10:21:37 +0200 Subject: [PATCH] sync --- package-lock.json | 248 ++++++++++-------- package.json | 6 + src/async/impl.ts | 6 +- src/comparer/sync.ts | 4 +- src/comparer/types.ts | 3 - src/equality-comparer/index.ts | 11 - src/equality-comparer/sync.ts | 167 ++++++++++++ src/equality-comparer/types.ts | 13 +- src/{equality-map.ts => equality-map/impl.ts} | 80 ++---- src/equality-map/index.ts | 11 + src/equality-map/types.ts | 29 ++ src/{equality-set.ts => equality-set/impl.ts} | 52 +--- src/equality-set/index.ts | 11 + src/equality-set/types.ts | 21 ++ src/index.ts | 6 +- src/random/index.ts | 14 +- src/random/types.ts | 16 +- src/sync/impl.ts | 6 +- src/sync/index.ts | 16 +- tsconfig.json | 15 +- 20 files changed, 476 insertions(+), 259 deletions(-) delete mode 100644 src/equality-comparer/index.ts create mode 100644 src/equality-comparer/sync.ts rename src/{equality-map.ts => equality-map/impl.ts} (62%) create mode 100644 src/equality-map/index.ts create mode 100644 src/equality-map/types.ts rename src/{equality-set.ts => equality-set/impl.ts} (68%) create mode 100644 src/equality-set/index.ts create mode 100644 src/equality-set/types.ts diff --git a/package-lock.json b/package-lock.json index 00c9db9..89cb2dc 100644 --- a/package-lock.json +++ b/package-lock.json @@ -16,9 +16,9 @@ } }, "node_modules/@esbuild/aix-ppc64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.4.tgz", - "integrity": "sha512-1VCICWypeQKhVbE9oW/sJaAmjLxhVqacdkvPLEjwlttjfwENRSClS8EjBz0KzRyFSCPDIkuXW34Je/vk7zdB7Q==", + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.9.tgz", + "integrity": "sha512-OaGtL73Jck6pBKjNIe24BnFE6agGl+6KxDtTfHhy1HmhthfKouEcOhqpSL64K4/0WCtbKFLOdzD/44cJ4k9opA==", "cpu": [ "ppc64" ], @@ -33,9 +33,9 @@ } }, "node_modules/@esbuild/android-arm": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.4.tgz", - "integrity": "sha512-QNdQEps7DfFwE3hXiU4BZeOV68HHzYwGd0Nthhd3uCkkEKK7/R6MTgM0P7H7FAs5pU/DIWsviMmEGxEoxIZ+ZQ==", + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.9.tgz", + "integrity": "sha512-5WNI1DaMtxQ7t7B6xa572XMXpHAaI/9Hnhk8lcxF4zVN4xstUgTlvuGDorBguKEnZO70qwEcLpfifMLoxiPqHQ==", "cpu": [ "arm" ], @@ -50,9 +50,9 @@ } }, "node_modules/@esbuild/android-arm64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.4.tgz", - "integrity": "sha512-bBy69pgfhMGtCnwpC/x5QhfxAz/cBgQ9enbtwjf6V9lnPI/hMyT9iWpR1arm0l3kttTr4L0KSLpKmLp/ilKS9A==", + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.9.tgz", + "integrity": "sha512-IDrddSmpSv51ftWslJMvl3Q2ZT98fUSL2/rlUXuVqRXHCs5EUF1/f+jbjF5+NG9UffUDMCiTyh8iec7u8RlTLg==", "cpu": [ "arm64" ], @@ -67,9 +67,9 @@ } }, "node_modules/@esbuild/android-x64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.4.tgz", - "integrity": "sha512-TVhdVtQIFuVpIIR282btcGC2oGQoSfZfmBdTip2anCaVYcqWlZXGcdcKIUklfX2wj0JklNYgz39OBqh2cqXvcQ==", + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.9.tgz", + "integrity": "sha512-I853iMZ1hWZdNllhVZKm34f4wErd4lMyeV7BLzEExGEIZYsOzqDWDf+y082izYUE8gtJnYHdeDpN/6tUdwvfiw==", "cpu": [ "x64" ], @@ -84,9 +84,9 @@ } }, "node_modules/@esbuild/darwin-arm64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.4.tgz", - "integrity": "sha512-Y1giCfM4nlHDWEfSckMzeWNdQS31BQGs9/rouw6Ub91tkK79aIMTH3q9xHvzH8d0wDru5Ci0kWB8b3up/nl16g==", + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.9.tgz", + "integrity": "sha512-XIpIDMAjOELi/9PB30vEbVMs3GV1v2zkkPnuyRRURbhqjyzIINwj+nbQATh4H9GxUgH1kFsEyQMxwiLFKUS6Rg==", "cpu": [ "arm64" ], @@ -101,9 +101,9 @@ } }, "node_modules/@esbuild/darwin-x64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.4.tgz", - "integrity": "sha512-CJsry8ZGM5VFVeyUYB3cdKpd/H69PYez4eJh1W/t38vzutdjEjtP7hB6eLKBoOdxcAlCtEYHzQ/PJ/oU9I4u0A==", + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.9.tgz", + "integrity": "sha512-jhHfBzjYTA1IQu8VyrjCX4ApJDnH+ez+IYVEoJHeqJm9VhG9Dh2BYaJritkYK3vMaXrf7Ogr/0MQ8/MeIefsPQ==", "cpu": [ "x64" ], @@ -118,9 +118,9 @@ } }, "node_modules/@esbuild/freebsd-arm64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.4.tgz", - "integrity": "sha512-yYq+39NlTRzU2XmoPW4l5Ifpl9fqSk0nAJYM/V/WUGPEFfek1epLHJIkTQM6bBs1swApjO5nWgvr843g6TjxuQ==", + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.9.tgz", + "integrity": "sha512-z93DmbnY6fX9+KdD4Ue/H6sYs+bhFQJNCPZsi4XWJoYblUqT06MQUdBCpcSfuiN72AbqeBFu5LVQTjfXDE2A6Q==", "cpu": [ "arm64" ], @@ -135,9 +135,9 @@ } }, "node_modules/@esbuild/freebsd-x64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.4.tgz", - "integrity": "sha512-0FgvOJ6UUMflsHSPLzdfDnnBBVoCDtBTVyn/MrWloUNvq/5SFmh13l3dvgRPkDihRxb77Y17MbqbCAa2strMQQ==", + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.9.tgz", + "integrity": "sha512-mrKX6H/vOyo5v71YfXWJxLVxgy1kyt1MQaD8wZJgJfG4gq4DpQGpgTB74e5yBeQdyMTbgxp0YtNj7NuHN0PoZg==", "cpu": [ "x64" ], @@ -152,9 +152,9 @@ } }, "node_modules/@esbuild/linux-arm": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.4.tgz", - "integrity": "sha512-kro4c0P85GMfFYqW4TWOpvmF8rFShbWGnrLqlzp4X1TNWjRY3JMYUfDCtOxPKOIY8B0WC8HN51hGP4I4hz4AaQ==", + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.9.tgz", + "integrity": "sha512-HBU2Xv78SMgaydBmdor38lg8YDnFKSARg1Q6AT0/y2ezUAKiZvc211RDFHlEZRFNRVhcMamiToo7bDx3VEOYQw==", "cpu": [ "arm" ], @@ -169,9 +169,9 @@ } }, "node_modules/@esbuild/linux-arm64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.4.tgz", - "integrity": "sha512-+89UsQTfXdmjIvZS6nUnOOLoXnkUTB9hR5QAeLrQdzOSWZvNSAXAtcRDHWtqAUtAmv7ZM1WPOOeSxDzzzMogiQ==", + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.9.tgz", + "integrity": "sha512-BlB7bIcLT3G26urh5Dmse7fiLmLXnRlopw4s8DalgZ8ef79Jj4aUcYbk90g8iCa2467HX8SAIidbL7gsqXHdRw==", "cpu": [ "arm64" ], @@ -186,9 +186,9 @@ } }, "node_modules/@esbuild/linux-ia32": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.4.tgz", - "integrity": "sha512-yTEjoapy8UP3rv8dB0ip3AfMpRbyhSN3+hY8mo/i4QXFeDxmiYbEKp3ZRjBKcOP862Ua4b1PDfwlvbuwY7hIGQ==", + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.9.tgz", + "integrity": "sha512-e7S3MOJPZGp2QW6AK6+Ly81rC7oOSerQ+P8L0ta4FhVi+/j/v2yZzx5CqqDaWjtPFfYz21Vi1S0auHrap3Ma3A==", "cpu": [ "ia32" ], @@ -203,9 +203,9 @@ } }, "node_modules/@esbuild/linux-loong64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.4.tgz", - "integrity": "sha512-NeqqYkrcGzFwi6CGRGNMOjWGGSYOpqwCjS9fvaUlX5s3zwOtn1qwg1s2iE2svBe4Q/YOG1q6875lcAoQK/F4VA==", + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.9.tgz", + "integrity": "sha512-Sbe10Bnn0oUAB2AalYztvGcK+o6YFFA/9829PhOCUS9vkJElXGdphz0A3DbMdP8gmKkqPmPcMJmJOrI3VYB1JQ==", "cpu": [ "loong64" ], @@ -220,9 +220,9 @@ } }, "node_modules/@esbuild/linux-mips64el": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.4.tgz", - "integrity": "sha512-IcvTlF9dtLrfL/M8WgNI/qJYBENP3ekgsHbYUIzEzq5XJzzVEV/fXY9WFPfEEXmu3ck2qJP8LG/p3Q8f7Zc2Xg==", + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.9.tgz", + "integrity": "sha512-YcM5br0mVyZw2jcQeLIkhWtKPeVfAerES5PvOzaDxVtIyZ2NUBZKNLjC5z3/fUlDgT6w89VsxP2qzNipOaaDyA==", "cpu": [ "mips64el" ], @@ -237,9 +237,9 @@ } }, "node_modules/@esbuild/linux-ppc64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.4.tgz", - "integrity": "sha512-HOy0aLTJTVtoTeGZh4HSXaO6M95qu4k5lJcH4gxv56iaycfz1S8GO/5Jh6X4Y1YiI0h7cRyLi+HixMR+88swag==", + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.9.tgz", + "integrity": "sha512-++0HQvasdo20JytyDpFvQtNrEsAgNG2CY1CLMwGXfFTKGBGQT3bOeLSYE2l1fYdvML5KUuwn9Z8L1EWe2tzs1w==", "cpu": [ "ppc64" ], @@ -254,9 +254,9 @@ } }, "node_modules/@esbuild/linux-riscv64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.4.tgz", - "integrity": "sha512-i8JUDAufpz9jOzo4yIShCTcXzS07vEgWzyX3NH2G7LEFVgrLEhjwL3ajFE4fZI3I4ZgiM7JH3GQ7ReObROvSUA==", + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.9.tgz", + "integrity": "sha512-uNIBa279Y3fkjV+2cUjx36xkx7eSjb8IvnL01eXUKXez/CBHNRw5ekCGMPM0BcmqBxBcdgUWuUXmVWwm4CH9kg==", "cpu": [ "riscv64" ], @@ -271,9 +271,9 @@ } }, "node_modules/@esbuild/linux-s390x": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.4.tgz", - "integrity": "sha512-jFnu+6UbLlzIjPQpWCNh5QtrcNfMLjgIavnwPQAfoGx4q17ocOU9MsQ2QVvFxwQoWpZT8DvTLooTvmOQXkO51g==", + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.9.tgz", + "integrity": "sha512-Mfiphvp3MjC/lctb+7D287Xw1DGzqJPb/J2aHHcHxflUo+8tmN/6d4k6I2yFR7BVo5/g7x2Monq4+Yew0EHRIA==", "cpu": [ "s390x" ], @@ -288,9 +288,9 @@ } }, "node_modules/@esbuild/linux-x64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.4.tgz", - "integrity": "sha512-6e0cvXwzOnVWJHq+mskP8DNSrKBr1bULBvnFLpc1KY+d+irZSgZ02TGse5FsafKS5jg2e4pbvK6TPXaF/A6+CA==", + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.9.tgz", + "integrity": "sha512-iSwByxzRe48YVkmpbgoxVzn76BXjlYFXC7NvLYq+b+kDjyyk30J0JY47DIn8z1MO3K0oSl9fZoRmZPQI4Hklzg==", "cpu": [ "x64" ], @@ -305,9 +305,9 @@ } }, "node_modules/@esbuild/netbsd-arm64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.4.tgz", - "integrity": "sha512-vUnkBYxZW4hL/ie91hSqaSNjulOnYXE1VSLusnvHg2u3jewJBz3YzB9+oCw8DABeVqZGg94t9tyZFoHma8gWZQ==", + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.9.tgz", + "integrity": "sha512-9jNJl6FqaUG+COdQMjSCGW4QiMHH88xWbvZ+kRVblZsWrkXlABuGdFJ1E9L7HK+T0Yqd4akKNa/lO0+jDxQD4Q==", "cpu": [ "arm64" ], @@ -322,9 +322,9 @@ } }, "node_modules/@esbuild/netbsd-x64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.4.tgz", - "integrity": "sha512-XAg8pIQn5CzhOB8odIcAm42QsOfa98SBeKUdo4xa8OvX8LbMZqEtgeWE9P/Wxt7MlG2QqvjGths+nq48TrUiKw==", + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.9.tgz", + "integrity": "sha512-RLLdkflmqRG8KanPGOU7Rpg829ZHu8nFy5Pqdi9U01VYtG9Y0zOG6Vr2z4/S+/3zIyOxiK6cCeYNWOFR9QP87g==", "cpu": [ "x64" ], @@ -339,9 +339,9 @@ } }, "node_modules/@esbuild/openbsd-arm64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.4.tgz", - "integrity": "sha512-Ct2WcFEANlFDtp1nVAXSNBPDxyU+j7+tId//iHXU2f/lN5AmO4zLyhDcpR5Cz1r08mVxzt3Jpyt4PmXQ1O6+7A==", + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.9.tgz", + "integrity": "sha512-YaFBlPGeDasft5IIM+CQAhJAqS3St3nJzDEgsgFixcfZeyGPCd6eJBWzke5piZuZ7CtL656eOSYKk4Ls2C0FRQ==", "cpu": [ "arm64" ], @@ -356,9 +356,9 @@ } }, "node_modules/@esbuild/openbsd-x64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.4.tgz", - "integrity": "sha512-xAGGhyOQ9Otm1Xu8NT1ifGLnA6M3sJxZ6ixylb+vIUVzvvd6GOALpwQrYrtlPouMqd/vSbgehz6HaVk4+7Afhw==", + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.9.tgz", + "integrity": "sha512-1MkgTCuvMGWuqVtAvkpkXFmtL8XhWy+j4jaSO2wxfJtilVCi0ZE37b8uOdMItIHz4I6z1bWWtEX4CJwcKYLcuA==", "cpu": [ "x64" ], @@ -372,10 +372,27 @@ "node": ">=18" } }, + "node_modules/@esbuild/openharmony-arm64": { + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.9.tgz", + "integrity": "sha512-4Xd0xNiMVXKh6Fa7HEJQbrpP3m3DDn43jKxMjxLLRjWnRsfxjORYJlXPO4JNcXtOyfajXorRKY9NkOpTHptErg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": ">=18" + } + }, "node_modules/@esbuild/sunos-x64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.4.tgz", - "integrity": "sha512-Mw+tzy4pp6wZEK0+Lwr76pWLjrtjmJyUB23tHKqEDP74R3q95luY/bXqXZeYl4NYlvwOqoRKlInQialgCKy67Q==", + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.9.tgz", + "integrity": "sha512-WjH4s6hzo00nNezhp3wFIAfmGZ8U7KtrJNlFMRKxiI9mxEK1scOMAaa9i4crUtu+tBr+0IN6JCuAcSBJZfnphw==", "cpu": [ "x64" ], @@ -390,9 +407,9 @@ } }, "node_modules/@esbuild/win32-arm64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.4.tgz", - "integrity": "sha512-AVUP428VQTSddguz9dO9ngb+E5aScyg7nOeJDrF1HPYu555gmza3bDGMPhmVXL8svDSoqPCsCPjb265yG/kLKQ==", + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.9.tgz", + "integrity": "sha512-mGFrVJHmZiRqmP8xFOc6b84/7xa5y5YvR1x8djzXpJBSv/UsNK6aqec+6JDjConTgvvQefdGhFDAs2DLAds6gQ==", "cpu": [ "arm64" ], @@ -407,9 +424,9 @@ } }, "node_modules/@esbuild/win32-ia32": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.4.tgz", - "integrity": "sha512-i1sW+1i+oWvQzSgfRcxxG2k4I9n3O9NRqy8U+uugaT2Dy7kLO9Y7wI72haOahxceMX8hZAzgGou1FhndRldxRg==", + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.9.tgz", + "integrity": "sha512-b33gLVU2k11nVx1OhX3C8QQP6UHQK4ZtN56oFWvVXvz2VkDoe6fbG8TOgHFxEvqeqohmRnIHe5A1+HADk4OQww==", "cpu": [ "ia32" ], @@ -424,9 +441,9 @@ } }, "node_modules/@esbuild/win32-x64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.4.tgz", - "integrity": "sha512-nOT2vZNw6hJ+z43oP1SPea/G/6AbN6X+bGNhNuq8NtRHy4wsMhw765IKLNmnjek7GvjWBYQ8Q5VBoYTFg9y1UQ==", + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.9.tgz", + "integrity": "sha512-PPOl1mi6lpLNQxnGoyAfschAodRFYXJ+9fs6WHXz7CSWKbOqiMZsubC+BQsVKuul+3vKLuwTHsS2c2y9EoKwxQ==", "cpu": [ "x64" ], @@ -441,9 +458,9 @@ } }, "node_modules/@types/node": { - "version": "22.15.21", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.15.21.tgz", - "integrity": "sha512-EV/37Td6c+MgKAbkcLG6vqZ2zEYHD7bvSrzqqs2RIhbA6w3x+Dqz8MZM3sP6kGTeLrdoOgKZe+Xja7tUB2DNkQ==", + "version": "22.18.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.18.1.tgz", + "integrity": "sha512-rzSDyhn4cYznVG+PCzGe1lwuMYJrcBS1fc3JqSa2PvtABwWo+dZ1ij5OVok3tqfpEBCBoaR4d7upFJk73HRJDw==", "dev": true, "license": "MIT", "dependencies": { @@ -451,9 +468,9 @@ } }, "node_modules/esbuild": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.4.tgz", - "integrity": "sha512-8pgjLUcUjcgDg+2Q4NYXnPbo/vncAY4UmyaCm0jZevERqCHZIaWwdJHkf8XQtu4AxSKCdvrUbT0XUr1IdZzI8Q==", + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.9.tgz", + "integrity": "sha512-CRbODhYyQx3qp7ZEwzxOk4JBqmD/seJrzPa/cGjY1VtIn5E09Oi9/dB4JwctnfZ8Q8iT7rioVv5k/FNT/uf54g==", "dev": true, "hasInstallScript": true, "license": "MIT", @@ -464,31 +481,32 @@ "node": ">=18" }, "optionalDependencies": { - "@esbuild/aix-ppc64": "0.25.4", - "@esbuild/android-arm": "0.25.4", - "@esbuild/android-arm64": "0.25.4", - "@esbuild/android-x64": "0.25.4", - "@esbuild/darwin-arm64": "0.25.4", - "@esbuild/darwin-x64": "0.25.4", - "@esbuild/freebsd-arm64": "0.25.4", - "@esbuild/freebsd-x64": "0.25.4", - "@esbuild/linux-arm": "0.25.4", - "@esbuild/linux-arm64": "0.25.4", - "@esbuild/linux-ia32": "0.25.4", - "@esbuild/linux-loong64": "0.25.4", - "@esbuild/linux-mips64el": "0.25.4", - "@esbuild/linux-ppc64": "0.25.4", - "@esbuild/linux-riscv64": "0.25.4", - "@esbuild/linux-s390x": "0.25.4", - "@esbuild/linux-x64": "0.25.4", - "@esbuild/netbsd-arm64": "0.25.4", - "@esbuild/netbsd-x64": "0.25.4", - "@esbuild/openbsd-arm64": "0.25.4", - "@esbuild/openbsd-x64": "0.25.4", - "@esbuild/sunos-x64": "0.25.4", - "@esbuild/win32-arm64": "0.25.4", - "@esbuild/win32-ia32": "0.25.4", - "@esbuild/win32-x64": "0.25.4" + "@esbuild/aix-ppc64": "0.25.9", + "@esbuild/android-arm": "0.25.9", + "@esbuild/android-arm64": "0.25.9", + "@esbuild/android-x64": "0.25.9", + "@esbuild/darwin-arm64": "0.25.9", + "@esbuild/darwin-x64": "0.25.9", + "@esbuild/freebsd-arm64": "0.25.9", + "@esbuild/freebsd-x64": "0.25.9", + "@esbuild/linux-arm": "0.25.9", + "@esbuild/linux-arm64": "0.25.9", + "@esbuild/linux-ia32": "0.25.9", + "@esbuild/linux-loong64": "0.25.9", + "@esbuild/linux-mips64el": "0.25.9", + "@esbuild/linux-ppc64": "0.25.9", + "@esbuild/linux-riscv64": "0.25.9", + "@esbuild/linux-s390x": "0.25.9", + "@esbuild/linux-x64": "0.25.9", + "@esbuild/netbsd-arm64": "0.25.9", + "@esbuild/netbsd-x64": "0.25.9", + "@esbuild/openbsd-arm64": "0.25.9", + "@esbuild/openbsd-x64": "0.25.9", + "@esbuild/openharmony-arm64": "0.25.9", + "@esbuild/sunos-x64": "0.25.9", + "@esbuild/win32-arm64": "0.25.9", + "@esbuild/win32-ia32": "0.25.9", + "@esbuild/win32-x64": "0.25.9" } }, "node_modules/fsevents": { @@ -507,9 +525,9 @@ } }, "node_modules/get-tsconfig": { - "version": "4.7.6", - "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.7.6.tgz", - "integrity": "sha512-ZAqrLlu18NbDdRaHq+AKXzAmqIUPswPWKUchfytdAjiRFnCe5ojG2bstg6mRiZabkKfCoL/e98pbBELIV/YCeA==", + "version": "4.10.1", + "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.10.1.tgz", + "integrity": "sha512-auHyJ4AgMz7vgS8Hp3N6HXSmlMdUyhSUrfBF16w153rxtLIEOE+HGqaBppczZvnHLqQJfiHotCYpNhl0lUROFQ==", "dev": true, "license": "MIT", "dependencies": { @@ -530,9 +548,9 @@ } }, "node_modules/tsx": { - "version": "4.19.4", - "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.19.4.tgz", - "integrity": "sha512-gK5GVzDkJK1SI1zwHf32Mqxf2tSJkNx+eYcNly5+nHvWqXUJYUkWBQtKauoESz3ymezAI++ZwT855x5p5eop+Q==", + "version": "4.20.5", + "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.20.5.tgz", + "integrity": "sha512-+wKjMNU9w/EaQayHXb7WA7ZaHY6hN8WgfvHNQ3t1PnU91/7O8TcTnIhCDYTZwnt8JsO9IBqZ30Ln1r7pPF52Aw==", "dev": true, "license": "MIT", "dependencies": { @@ -550,9 +568,9 @@ } }, "node_modules/typescript": { - "version": "5.8.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.3.tgz", - "integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==", + "version": "5.9.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.2.tgz", + "integrity": "sha512-CWBzXQrc/qOkhidw1OzBTQuYRbfyxDXJMVJ1XNwUHGROVmuaeiEm3OslpZ1RV96d7SKKjZKrSJu3+t/xlw3R9A==", "dev": true, "license": "Apache-2.0", "bin": { diff --git a/package.json b/package.json index f9153aa..ea73832 100644 --- a/package.json +++ b/package.json @@ -16,5 +16,11 @@ "esbuild": "^0.25.4", "tsx": "^4.19.4", "typescript": "^5.8.3" + }, + "exports": { + ".": { + "import": "./src/index.ts", + "types": "./src/index.ts" + } } } diff --git a/src/async/impl.ts b/src/async/impl.ts index 76b3d62..86a1416 100644 --- a/src/async/impl.ts +++ b/src/async/impl.ts @@ -1,10 +1,10 @@ import { Collector } from "../collector/types.js"; import { asAsyncComparer, combineNullableAsyncComparers, createAsyncComparerUsing, defaultAsyncComparer } from "../comparer/async.js"; import { MaybeAsyncComparisonOrComparer, AsyncComparer } from "../comparer/types.js"; -import { strictEquals } from "../equality-comparer/index.js"; +import { strictEquals } from "../equality-comparer/sync.js"; import { MaybeAsyncEqualityComparison } from "../equality-comparer/types.js"; -import { createAsyncEqualityMap } from "../equality-map.js"; -import { createAsyncEqualitySet } from "../equality-set.js"; +import { createAsyncEqualityMap } from "../equality-map/index.js"; +import { createAsyncEqualitySet } from "../equality-set/index.js"; import { createQueue } from "../queue.js"; import { getRandomElementAsync } from "../random/index.js"; import { AsyncRandomOptions } from "../random/types.js"; diff --git a/src/comparer/sync.ts b/src/comparer/sync.ts index dded405..f8227e4 100644 --- a/src/comparer/sync.ts +++ b/src/comparer/sync.ts @@ -15,11 +15,11 @@ export function asComparison(comparer: ComparisonOrComparer) { return typeof comparer === "function" ? comparer : comparer.comparison(); } -export function createComparer(comparison: Comparison): Comparer { +export function createComparer(comparison: Comparison): Comparer { return new SimpleComparer(comparison); } -export function createComparerUsing(projection: Converter, comparison?: ComparisonOrComparer): Comparer { +export function createComparerUsing(projection: Converter, comparison?: ComparisonOrComparer): Comparer { return new MappedComparer(projection, comparison); } diff --git a/src/comparer/types.ts b/src/comparer/types.ts index 84ba7ec..9f7dab5 100644 --- a/src/comparer/types.ts +++ b/src/comparer/types.ts @@ -24,12 +24,9 @@ export interface AsyncComparer { export type Comparison = (first: T, second: T) => number; export type ComparisonOrComparer = Comparison | Comparer; -export type Equater = (first: T, second: T) => boolean; export type AsyncComparison = AsyncFunction>; export type MaybeAsyncComparison = MaybeAsyncFunction>; export type AsyncComparisonOrComparer = AsyncComparison | AsyncComparer; export type MaybeAsyncComparisonOrComparer = MaybeAsyncComparison | Comparer | AsyncComparer; -export type AsyncEquater = AsyncFunction>; -export type MaybeAsyncEquater = MaybeAsyncFunction>; diff --git a/src/equality-comparer/index.ts b/src/equality-comparer/index.ts deleted file mode 100644 index dd073ed..0000000 --- a/src/equality-comparer/index.ts +++ /dev/null @@ -1,11 +0,0 @@ -export function looseEquals(a: T, b: T) { - return a == b; -} - -export function strictEquals(a: T, b: T) { - return a === b; -} - -export function sameValue(a: T, b: T) { - return Object.is(a, b); -} diff --git a/src/equality-comparer/sync.ts b/src/equality-comparer/sync.ts new file mode 100644 index 0000000..0a62a2c --- /dev/null +++ b/src/equality-comparer/sync.ts @@ -0,0 +1,167 @@ +import { Converter } from "../types.js"; +import { Nullable } from "../utils.js"; +import { EqualityComparer, EqualityComparison, EqualityComparisonOrComparer } from "./types.js"; + +export function looseEquals(a: T, b: T) { + return a == b; +} + +export function strictEquals(a: T, b: T) { + return a === b; +} + +export function sameValue(a: T, b: T) { + return Object.is(a, b); +} + +export function isEqualityComparer(obj: any): obj is EqualityComparer { + return obj instanceof BaseEqualityComparer; +} + +export function asEqualityComparer(equalityComparer: EqualityComparisonOrComparer) { + return typeof equalityComparer === "function" ? createEqualityComparer(equalityComparer) : equalityComparer; +} + +export function asEqualityComparison(equalityComparer: EqualityComparisonOrComparer) { + return typeof equalityComparer === "function" ? equalityComparer : equalityComparer.equalityComparison(); +} + +export function createEqualityComparer(equalityComparison: EqualityComparison): EqualityComparer { + return new SimpleEqualityComparer(equalityComparison); +} + +export function createEqualityComparerUsing(projection: Converter, equalityComparison?: EqualityComparisonOrComparer): EqualityComparer { + return new MappedEqualityComparer(projection, equalityComparison); +} + +export function oppositeEqualityComparison(equalityComparison: EqualityComparison): EqualityComparison { + return (a, b) => !equalityComparison(a, b); +} + +export function combineNullableEqualityComparers(equalityComparers: Nullable>[]) { + let result = defaultEqualityComparer; + + for (const equalityComparer of equalityComparers) { + if (!equalityComparer) { + continue; + } + + result = result.then(asEqualityComparer(equalityComparer)); + } + + return result === defaultEqualityComparer ? undefined : result; +} + +export abstract class BaseEqualityComparer implements EqualityComparer { + #cachedBoundEqualityComparison: EqualityComparison | undefined; + + public abstract equals(a: T, b: T): boolean; + + public equalityComparison(): EqualityComparison { + return this.#cachedBoundEqualityComparison ??= this.equals.bind(this); + } + + public opposite(): EqualityComparer { + return new OppositeEqualityComparer(this); + } + + public then(equalityComparer: EqualityComparer): EqualityComparer { + return new ThenEqualityComparer(this, equalityComparer); + } + + public thenEquals(equalityComparison: EqualityComparison): EqualityComparer { + return this.then(createEqualityComparer(equalityComparison)); + } + + public thenEqualsUsing(projection: Converter, equalityComparison?: EqualityComparisonOrComparer): EqualityComparer { + return this.then(createEqualityComparerUsing(projection, equalityComparison)); + } +} + +class SimpleEqualityComparer extends BaseEqualityComparer { + readonly #equalityComparison: EqualityComparison; + + public constructor(equalityComparison: EqualityComparison) { + super(); + + this.#equalityComparison = equalityComparison; + } + + public override equals(a: T, b: T): boolean { + return this.#equalityComparison(a, b); + } + + public override equalityComparison() { + return this.#equalityComparison; + } +} + +class MappedEqualityComparer extends BaseEqualityComparer { + readonly #projection: Converter; + readonly #equalityComparison: EqualityComparer; + + public constructor(projection: Converter, equalityComparison?: EqualityComparisonOrComparer) { + super(); + + this.#projection = projection; + this.#equalityComparison = equalityComparison ? asEqualityComparer(equalityComparison) : defaultEqualityComparer; + } + + public override equals(a: T, b: T): boolean { + return this.#equalityComparison.equals(this.#projection(a), this.#projection(b)); + } +} + +class OppositeEqualityComparer extends BaseEqualityComparer { + readonly #base: EqualityComparer; + + public constructor(base: EqualityComparer) { + super(); + + this.#base = base; + } + + public override equals(a: T, b: T): boolean { + return !this.#base.equals(a, b); + } + + public override opposite(): EqualityComparer { + return this.#base; + } +} + +class ThenEqualityComparer extends BaseEqualityComparer { + readonly #base: EqualityComparer; + readonly #equalityComparer: EqualityComparer; + + public constructor(base: EqualityComparer, equalityComparer: EqualityComparer) { + super(); + + this.#base = base; + this.#equalityComparer = equalityComparer; + } + + public override equals(a: T, b: T) { + return this.#base.equals(a, b) && this.#equalityComparer.equals(a, b); + } +} + +export const defaultEqualityComparer: EqualityComparer = new class DefaultEqualityComparer extends BaseEqualityComparer { + public override equals(a: any, b: any): boolean { + return a === b; + } +}; + +export function getDefaultComparer(): EqualityComparer { + return defaultEqualityComparer; +} + +export const dateComparer: EqualityComparer = new class DateEqualityComparer extends BaseEqualityComparer { + public override equals(a: Date, b: Date): boolean { + return a.getTime() === b.getTime(); + } +}; + +export const looseEqualsComparer: EqualityComparer = new SimpleEqualityComparer(looseEquals); +export const strictEqualsComparer: EqualityComparer = new SimpleEqualityComparer(strictEquals); +export const sameValueComparer: EqualityComparer = new SimpleEqualityComparer(sameValue); diff --git a/src/equality-comparer/types.ts b/src/equality-comparer/types.ts index 9a11762..3c63b70 100644 --- a/src/equality-comparer/types.ts +++ b/src/equality-comparer/types.ts @@ -1,6 +1,15 @@ -import { AsyncFunction, MaybeAsyncFunction } from "../types.js"; +import { Converter, MaybeAsyncFunction } from "../types.js"; + +export interface EqualityComparer { + equals(a: T, b: T): boolean; + equalityComparison(): EqualityComparison; + opposite(): EqualityComparer; + then(equalityComparer: EqualityComparer): EqualityComparer; + thenEquals(equalityComparison: EqualityComparison): EqualityComparer; + thenEqualsUsing(projection: Converter, equalityComparison?: EqualityComparisonOrComparer): EqualityComparer; +} export type EqualityComparison = (first: T, second: T) => boolean; +export type EqualityComparisonOrComparer = EqualityComparison | EqualityComparer; -export type AsyncEqualityComparison = AsyncFunction>; export type MaybeAsyncEqualityComparison = MaybeAsyncFunction>; diff --git a/src/equality-map.ts b/src/equality-map/impl.ts similarity index 62% rename from src/equality-map.ts rename to src/equality-map/impl.ts index f1d0cec..5dacf8d 100644 --- a/src/equality-map.ts +++ b/src/equality-map/impl.ts @@ -1,22 +1,9 @@ -import { EqualityComparison, MaybeAsyncEqualityComparison } from "./equality-comparer/types.js"; -import { MaybeAsyncIterable } from "./types.js"; +import { asEqualityComparer } from "../equality-comparer/sync.js"; +import { EqualityComparer, EqualityComparisonOrComparer, MaybeAsyncEqualityComparison } from "../equality-comparer/types.js"; +import { MaybeAsyncIterable } from "../types.js"; +import { AsyncEqualityMap, EqualityMap, EqualityMapEntry } from "./types.js"; -export type Entry = [key: K, value: V]; - -export interface EqualityMap extends Iterable> { - readonly size: number; - get(key: K): V | undefined; - set(key: K, value: V): V | undefined; - setAll(entries: Iterable>): void; - contains(key: K): boolean; - remove(key: K): V | undefined; - clear(): void; - keys(): IterableIterator; - values(): IterableIterator; - entries(): IterableIterator>; -} - -class NativeEqualityMap implements EqualityMap { +export class NativeEqualityMap implements EqualityMap { readonly #map = new Map(); get size() { @@ -33,7 +20,7 @@ class NativeEqualityMap implements EqualityMap { return existing; } - setAll(entries: Iterable>) { + setAll(entries: Iterable>) { for (const [key, value] of entries) { this.set(key, value); } @@ -70,12 +57,12 @@ class NativeEqualityMap implements EqualityMap { } } -class CustomEqualityMap implements EqualityMap { - readonly #list: Entry[] = []; - readonly #keyComparer: EqualityComparison; +export class CustomEqualityMap implements EqualityMap { + readonly #list: EqualityMapEntry[] = []; + readonly #keyComparer: EqualityComparer; - constructor(keyComparer: EqualityComparison) { - this.#keyComparer = keyComparer; + constructor(keyComparer: EqualityComparisonOrComparer) { + this.#keyComparer = asEqualityComparer(keyComparer); } get size() { @@ -84,7 +71,7 @@ class CustomEqualityMap implements EqualityMap { get(key: K) { for (const entry of this.#list) { - if (this.#keyComparer(key, entry[0])) { + if (this.#keyComparer.equals(key, entry[0])) { return entry[1]; } } @@ -94,7 +81,7 @@ class CustomEqualityMap implements EqualityMap { set(key: K, value: V) { for (const entry of this.#list) { - if (this.#keyComparer(key, entry[0])) { + if (this.#keyComparer.equals(key, entry[0])) { const previous = entry[1]; entry[1] = value; return previous; @@ -106,7 +93,7 @@ class CustomEqualityMap implements EqualityMap { return undefined; } - setAll(entries: Iterable>) { + setAll(entries: Iterable>) { for (const [key, value] of entries) { this.set(key, value); } @@ -114,7 +101,7 @@ class CustomEqualityMap implements EqualityMap { contains(key: K) { for (const entry of this.#list) { - if (this.#keyComparer(key, entry[0])) { + if (this.#keyComparer.equals(key, entry[0])) { return true; } } @@ -124,7 +111,7 @@ class CustomEqualityMap implements EqualityMap { remove(key: K) { for (let i = 0; i < this.#list.length; i++) { - if (this.#keyComparer(key, this.#list[i][0])) { + if (this.#keyComparer.equals(key, this.#list[i][0])) { const removed = this.#list.splice(i, 1); return removed[0][1]; } @@ -155,29 +142,12 @@ class CustomEqualityMap implements EqualityMap { *[Symbol.iterator]() { for (const entry of this.#list) { - yield entry.slice() as Entry; // no entry mutation allowed! + yield entry.slice() as EqualityMapEntry; // no entry mutation allowed! } } } -export function createEqualityMap(keyComparer?: EqualityComparison): EqualityMap { - return keyComparer ? new CustomEqualityMap(keyComparer) : new NativeEqualityMap(); -} - -export interface AsyncEqualityMap extends Iterable> { - readonly size: number; - get(key: K): Promise; - set(key: K, value: V): Promise; - setAll(entries: MaybeAsyncIterable>): Promise; - contains(key: K): Promise; - remove(key: K): Promise; - clear(): void; - keys(): IterableIterator; - values(): IterableIterator; - entries(): IterableIterator>; -} - -class NativeAsyncEqualityMap implements AsyncEqualityMap { +export class NativeAsyncEqualityMap implements AsyncEqualityMap { readonly #map = new Map(); get size() { @@ -194,7 +164,7 @@ class NativeAsyncEqualityMap implements AsyncEqualityMap { return existing; } - async setAll(entries: MaybeAsyncIterable>) { + async setAll(entries: MaybeAsyncIterable>) { for await (const [key, value] of entries) { await this.set(key, value); } @@ -231,8 +201,8 @@ class NativeAsyncEqualityMap implements AsyncEqualityMap { } } -class CustomAsyncEqualityMap implements AsyncEqualityMap { - readonly #list: Entry[] = []; +export class CustomAsyncEqualityMap implements AsyncEqualityMap { + readonly #list: EqualityMapEntry[] = []; readonly #keyComparer: MaybeAsyncEqualityComparison; constructor(keyComparer: MaybeAsyncEqualityComparison) { @@ -267,7 +237,7 @@ class CustomAsyncEqualityMap implements AsyncEqualityMap { return undefined; } - async setAll(entries: MaybeAsyncIterable>) { + async setAll(entries: MaybeAsyncIterable>) { for await (const [key, value] of entries) { await this.set(key, value); } @@ -316,11 +286,7 @@ class CustomAsyncEqualityMap implements AsyncEqualityMap { *[Symbol.iterator]() { for (const entry of this.#list) { - yield entry.slice() as Entry; // no entry mutation allowed! + yield entry.slice() as EqualityMapEntry; // no entry mutation allowed! } } } - -export function createAsyncEqualityMap(keyComparer?: MaybeAsyncEqualityComparison): AsyncEqualityMap { - return keyComparer ? new CustomAsyncEqualityMap(keyComparer) : new NativeAsyncEqualityMap(); -} diff --git a/src/equality-map/index.ts b/src/equality-map/index.ts new file mode 100644 index 0000000..1ef22f3 --- /dev/null +++ b/src/equality-map/index.ts @@ -0,0 +1,11 @@ +import { EqualityComparisonOrComparer, MaybeAsyncEqualityComparison } from "../equality-comparer/types.js"; +import { CustomAsyncEqualityMap, CustomEqualityMap, NativeAsyncEqualityMap, NativeEqualityMap } from "./impl.js"; +import { AsyncEqualityMap, EqualityMap } from "./types.js"; + +export function createEqualityMap(keyComparer?: EqualityComparisonOrComparer): EqualityMap { + return keyComparer ? new CustomEqualityMap(keyComparer) : new NativeEqualityMap(); +} + +export function createAsyncEqualityMap(keyComparer?: MaybeAsyncEqualityComparison): AsyncEqualityMap { + return keyComparer ? new CustomAsyncEqualityMap(keyComparer) : new NativeAsyncEqualityMap(); +} diff --git a/src/equality-map/types.ts b/src/equality-map/types.ts new file mode 100644 index 0000000..79a9dde --- /dev/null +++ b/src/equality-map/types.ts @@ -0,0 +1,29 @@ +import { MaybeAsyncIterable } from "../types.js"; + +export type EqualityMapEntry = [key: K, value: V]; + +export interface EqualityMap extends Iterable> { + readonly size: number; + get(key: K): V | undefined; + set(key: K, value: V): V | undefined; + setAll(entries: Iterable>): void; + contains(key: K): boolean; + remove(key: K): V | undefined; + clear(): void; + keys(): IterableIterator; + values(): IterableIterator; + entries(): IterableIterator>; +} + +export interface AsyncEqualityMap extends Iterable> { + readonly size: number; + get(key: K): Promise; + set(key: K, value: V): Promise; + setAll(entries: MaybeAsyncIterable>): Promise; + contains(key: K): Promise; + remove(key: K): Promise; + clear(): void; + keys(): IterableIterator; + values(): IterableIterator; + entries(): IterableIterator>; +} diff --git a/src/equality-set.ts b/src/equality-set/impl.ts similarity index 68% rename from src/equality-set.ts rename to src/equality-set/impl.ts index 6c08cdd..8eeae30 100644 --- a/src/equality-set.ts +++ b/src/equality-set/impl.ts @@ -1,17 +1,9 @@ -import { EqualityComparison, MaybeAsyncEqualityComparison } from "./equality-comparer/types.js"; -import { MaybeAsyncIterable } from "./types.js"; +import { asEqualityComparer } from "../equality-comparer/sync.js"; +import { EqualityComparer, EqualityComparisonOrComparer, MaybeAsyncEqualityComparison } from "../equality-comparer/types.js"; +import { MaybeAsyncIterable } from "../types.js"; +import { AsyncEqualitySet, EqualitySet } from "./types.js"; -export interface EqualitySet extends Iterable { - readonly size: number; - add(value: T): boolean; - addAll(values: Iterable): number; - contains(value: T): boolean; - remove(value: T): boolean; - clear(): void; - values(): IterableIterator; -} - -class NativeEqualitySet implements EqualitySet { +export class NativeEqualitySet implements EqualitySet { readonly #set = new Set(); get size() { @@ -57,12 +49,12 @@ class NativeEqualitySet implements EqualitySet { } } -class CustomEqualitySet implements EqualitySet { +export class CustomEqualitySet implements EqualitySet { readonly #list: T[] = []; - readonly #equater: EqualityComparison; + readonly #equater: EqualityComparer; - constructor(equater: EqualityComparison) { - this.#equater = equater; + constructor(equater: EqualityComparisonOrComparer) { + this.#equater = asEqualityComparer(equater); } get size() { @@ -93,7 +85,7 @@ class CustomEqualitySet implements EqualitySet { contains(value: T) { for (const val of this.#list) { - if (this.#equater(value, val)) { + if (this.#equater.equals(value, val)) { return true; } } @@ -105,7 +97,7 @@ class CustomEqualitySet implements EqualitySet { const length = this.#list.length; for (let i = 0; i < length; i++) { - if (this.#equater(value, this.#list[i])) { + if (this.#equater.equals(value, this.#list[i])) { this.#list.splice(i, 1); return true; } @@ -127,21 +119,7 @@ class CustomEqualitySet implements EqualitySet { } } -export function createEqualitySet(equater?: EqualityComparison): EqualitySet { - return equater ? new CustomEqualitySet(equater) : new NativeEqualitySet(); -} - -export interface AsyncEqualitySet extends Iterable { - readonly size: number; - add(value: T): Promise; - addAll(values: MaybeAsyncIterable): Promise; - contains(value: T): Promise; - remove(value: T): Promise; - clear(): void; - values(): IterableIterator; -} - -class NativeAsyncEqualitySet implements AsyncEqualitySet { +export class NativeAsyncEqualitySet implements AsyncEqualitySet { readonly #set = new Set(); get size() { @@ -187,7 +165,7 @@ class NativeAsyncEqualitySet implements AsyncEqualitySet { } } -class CustomAsyncEqualitySet implements AsyncEqualitySet { +export class CustomAsyncEqualitySet implements AsyncEqualitySet { readonly #list: T[] = []; readonly #equater: MaybeAsyncEqualityComparison; @@ -256,7 +234,3 @@ class CustomAsyncEqualitySet implements AsyncEqualitySet { return this.#list[Symbol.iterator](); } } - -export function createAsyncEqualitySet(equater?: MaybeAsyncEqualityComparison): AsyncEqualitySet { - return equater ? new CustomAsyncEqualitySet(equater) : new NativeAsyncEqualitySet(); -} diff --git a/src/equality-set/index.ts b/src/equality-set/index.ts new file mode 100644 index 0000000..f814368 --- /dev/null +++ b/src/equality-set/index.ts @@ -0,0 +1,11 @@ +import { EqualityComparisonOrComparer, MaybeAsyncEqualityComparison } from "../equality-comparer/types.js"; +import { CustomAsyncEqualitySet, CustomEqualitySet, NativeAsyncEqualitySet, NativeEqualitySet } from "./impl.js"; +import { AsyncEqualitySet, EqualitySet } from "./types.js"; + +export function createEqualitySet(equater?: EqualityComparisonOrComparer): EqualitySet { + return equater ? new CustomEqualitySet(equater) : new NativeEqualitySet(); +} + +export function createAsyncEqualitySet(equater?: MaybeAsyncEqualityComparison): AsyncEqualitySet { + return equater ? new CustomAsyncEqualitySet(equater) : new NativeAsyncEqualitySet(); +} diff --git a/src/equality-set/types.ts b/src/equality-set/types.ts new file mode 100644 index 0000000..50ab39b --- /dev/null +++ b/src/equality-set/types.ts @@ -0,0 +1,21 @@ +import { MaybeAsyncIterable } from "../types.js"; + +export interface EqualitySet extends Iterable { + readonly size: number; + add(value: T): boolean; + addAll(values: Iterable): number; + contains(value: T): boolean; + remove(value: T): boolean; + clear(): void; + values(): IterableIterator; +} + +export interface AsyncEqualitySet extends Iterable { + readonly size: number; + add(value: T): Promise; + addAll(values: MaybeAsyncIterable): Promise; + contains(value: T): Promise; + remove(value: T): Promise; + clear(): void; + values(): IterableIterator; +} diff --git a/src/index.ts b/src/index.ts index d0842cf..eed01c2 100644 --- a/src/index.ts +++ b/src/index.ts @@ -15,5 +15,9 @@ export * as Comparers from "./comparer/sync.js"; export { BaseAsyncComparer } from "./comparer/async.js"; export * as AsyncComparers from "./comparer/async.js"; export * from "./comparer/types.js"; -export * as EqualityComparers from "./equality-comparer/index.js"; +export * as EqualityComparers from "./equality-comparer/sync.js"; export * from "./equality-comparer/types.js"; +export * as EqualityMaps from "./equality-map/index.js"; +export * from "./equality-map/types.js"; +export * as EqualitySets from "./equality-set/index.js"; +export * from "./equality-set/types.js"; diff --git a/src/random/index.ts b/src/random/index.ts index 4ae507b..d6c01a3 100644 --- a/src/random/index.ts +++ b/src/random/index.ts @@ -1,6 +1,6 @@ import { BitArray } from "../bitarray/index.js"; import { asArray } from "../utils.js"; -import { AsyncRandomOptions, ElementPredicate, ElementWeight, RandomGenerator, RandomOptions } from "./types.js"; +import { AsyncRandomOptions, ElementPredicate, ElementWeight, RandomElement, RandomGenerator, RandomOptions } from "./types.js"; export const alwaysTrue: ElementPredicate = () => true; export const weightOfOne: ElementWeight = () => 1.0; @@ -45,9 +45,10 @@ function withDefaultOptions(options: RandomOptions | AsyncRandomOptions }; } -function _getRandomElement(sequence: Iterable, options: Required>) { +function _getRandomElement(sequence: Iterable, options: Required>): RandomElement { const { predicate, weight, random } = options; + let found = false; let result: T | undefined = undefined; let resultIndex = -1; let index = 0; @@ -66,22 +67,24 @@ function _getRandomElement(sequence: Iterable, options: Required; } export function getRandomElement(sequence: Iterable, options?: RandomOptions) { return _getRandomElement(sequence, withDefaultOptions(options)); } -async function _getRandomElementAsync(sequence: AsyncIterable, options: Required>) { +async function _getRandomElementAsync(sequence: AsyncIterable, options: Required>): Promise> { const { predicate, weight, random } = options; + let found = false; let result: T | undefined = undefined; let resultIndex = -1; let index = 0; @@ -100,13 +103,14 @@ async function _getRandomElementAsync(sequence: AsyncIterable, options: Re weightAcc += w; if (random() * weightAcc < w) { + found = true; result = element; resultIndex = currentIndex; } } } - return { element: result, index: resultIndex }; + return { found, element: result, index: resultIndex } as RandomElement; } export async function getRandomElementAsync(sequence: AsyncIterable, options?: AsyncRandomOptions) { diff --git a/src/random/types.ts b/src/random/types.ts index 76f9d9b..49bbd4f 100644 --- a/src/random/types.ts +++ b/src/random/types.ts @@ -4,7 +4,7 @@ export type ElementPredicate = (index: number, obj: T) => boolean; export type ElementWeight = (index: number, obj: T) => number; export type RandomGenerator = () => number; -export interface RandomOptions { +export type RandomOptions = { predicate?: ElementPredicate; weight?: ElementWeight; random?: RandomGenerator; @@ -13,8 +13,20 @@ export interface RandomOptions { export type MaybeAsyncElementPredicate = MaybeAsyncFunction>; export type MaybeAsyncElementWeight = MaybeAsyncFunction>; -export interface AsyncRandomOptions { +export type AsyncRandomOptions = { predicate?: MaybeAsyncElementPredicate; weight?: MaybeAsyncElementWeight; random?: RandomGenerator; }; + +type RandomElementFound = { + found: true; + element: T; + index: number; +}; +type RandomElementNotFound = { + found: false; + element: undefined; + index: -1; +}; +export type RandomElement = RandomElementFound | RandomElementNotFound; diff --git a/src/sync/impl.ts b/src/sync/impl.ts index da300a0..a18ec51 100644 --- a/src/sync/impl.ts +++ b/src/sync/impl.ts @@ -3,10 +3,10 @@ import { AsyncSequence } from "../async/types.js"; import { Collector } from "../collector/types.js"; import { asComparer, combineNullableComparers, createComparerUsing, defaultComparer } from "../comparer/sync.js"; import { ComparisonOrComparer, Comparer } from "../comparer/types.js"; -import { strictEquals } from "../equality-comparer/index.js"; +import { strictEquals } from "../equality-comparer/sync.js"; import { EqualityComparison } from "../equality-comparer/types.js"; -import { createEqualityMap } from "../equality-map.js"; -import { createEqualitySet } from "../equality-set.js"; +import { createEqualityMap } from "../equality-map/index.js"; +import { createEqualitySet } from "../equality-set/index.js"; import { createQueue } from "../queue.js"; import { getRandomElement } from "../random/index.js"; import { RandomOptions } from "../random/types.js"; diff --git a/src/sync/index.ts b/src/sync/index.ts index 07c6d58..6f9c4bc 100644 --- a/src/sync/index.ts +++ b/src/sync/index.ts @@ -9,7 +9,7 @@ export function wrap(iterable: Iterable): Sequence { } if (Array.isArray(iterable)) { - return array(iterable); + return array(iterable); } if (iterable instanceof Set) { @@ -20,7 +20,7 @@ export function wrap(iterable: Iterable): Sequence { return map(iterable) as unknown as Sequence; } - return sequence(iterable); + return sequence(iterable); } export function sequence(iterable: Iterable): Sequence { @@ -86,9 +86,9 @@ export function generator(generator: () => Iterable): Sequence { return new GeneratorSequence(generator); } -export function range(max: number): Sequence -export function range(min: number, max: number): Sequence -export function range(min: number, max: number, step: number): Sequence +export function range(max: number): Sequence; +export function range(min: number, max: number): Sequence; +export function range(min: number, max: number, step: number): Sequence; export function range(a: number, b?: number, c?: number): Sequence { if (b === undefined) { b = a; @@ -102,9 +102,9 @@ export function range(a: number, b?: number, c?: number): Sequence { return new RangeSequence(a, b, c); } -export function bigintRange(max: bigint): Sequence -export function bigintRange(min: bigint, max: bigint): Sequence -export function bigintRange(min: bigint, max: bigint, step: bigint): Sequence +export function bigintRange(max: bigint): Sequence; +export function bigintRange(min: bigint, max: bigint): Sequence; +export function bigintRange(min: bigint, max: bigint, step: bigint): Sequence; export function bigintRange(a: bigint, b?: bigint, c?: bigint): Sequence { if (b === undefined) { b = a; diff --git a/tsconfig.json b/tsconfig.json index 2b511f3..08ee3f4 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,11 +1,11 @@ { "compilerOptions": { - "module": "NodeNext", - "target": "ESNext", + "module": "nodenext", + "target": "esnext", "moduleResolution": "nodenext", - "rootDir": "src", - "outDir": "build", - "outFile": "build/index.ts", + "lib": [ + "ESNext" + ], "esModuleInterop": true, "alwaysStrict": true, "strict": true, @@ -13,10 +13,9 @@ "allowUnreachableCode": true, "declaration": true, "declarationMap": true, - "emitDeclarationOnly": true, - "composite": true + "rootDir": "./src" }, "include": [ - "src" + "./src" ] }