1
0

Compare commits

..

7 Commits

Author SHA1 Message Date
Herve BECHER
5c847e4972 use consistent wording 2025-09-26 10:20:37 +02:00
Herve BECHER
b6a29cdec2 sync 2025-09-10 10:29:31 +02:00
6a23adb75d move identity function to utils 2025-06-07 09:31:17 +02:00
4445eeb000 improve typing of element finding utils 2025-05-27 10:11:45 +02:00
1f7c246faf move BitArray in its namerspace 2025-05-24 13:21:23 +02:00
Herve BECHER
0fd0e3bada sync 2025-05-24 12:11:44 +02:00
Herve BECHER
e5e6bffe1e sync 2024-10-14 07:38:23 +02:00
19 changed files with 437 additions and 850 deletions

253
package-lock.json generated
View File

@@ -9,15 +9,16 @@
"version": "1.0.0", "version": "1.0.0",
"license": "ISC", "license": "ISC",
"devDependencies": { "devDependencies": {
"@types/node": "^25.5.0", "@types/node": "^22.15.21",
"esbuild": "^0.25.4",
"tsx": "^4.19.4", "tsx": "^4.19.4",
"typescript": "^6.0.2" "typescript": "^5.8.3"
} }
}, },
"node_modules/@esbuild/aix-ppc64": { "node_modules/@esbuild/aix-ppc64": {
"version": "0.27.7", "version": "0.25.9",
"resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.7.tgz", "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.9.tgz",
"integrity": "sha512-EKX3Qwmhz1eMdEJokhALr0YiD0lhQNwDqkPYyPhiSwKrh7/4KRjQc04sZ8db+5DVVnZ1LmbNDI1uAMPEUBnQPg==", "integrity": "sha512-OaGtL73Jck6pBKjNIe24BnFE6agGl+6KxDtTfHhy1HmhthfKouEcOhqpSL64K4/0WCtbKFLOdzD/44cJ4k9opA==",
"cpu": [ "cpu": [
"ppc64" "ppc64"
], ],
@@ -32,9 +33,9 @@
} }
}, },
"node_modules/@esbuild/android-arm": { "node_modules/@esbuild/android-arm": {
"version": "0.27.7", "version": "0.25.9",
"resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.27.7.tgz", "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.9.tgz",
"integrity": "sha512-jbPXvB4Yj2yBV7HUfE2KHe4GJX51QplCN1pGbYjvsyCZbQmies29EoJbkEc+vYuU5o45AfQn37vZlyXy4YJ8RQ==", "integrity": "sha512-5WNI1DaMtxQ7t7B6xa572XMXpHAaI/9Hnhk8lcxF4zVN4xstUgTlvuGDorBguKEnZO70qwEcLpfifMLoxiPqHQ==",
"cpu": [ "cpu": [
"arm" "arm"
], ],
@@ -49,9 +50,9 @@
} }
}, },
"node_modules/@esbuild/android-arm64": { "node_modules/@esbuild/android-arm64": {
"version": "0.27.7", "version": "0.25.9",
"resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.27.7.tgz", "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.9.tgz",
"integrity": "sha512-62dPZHpIXzvChfvfLJow3q5dDtiNMkwiRzPylSCfriLvZeq0a1bWChrGx/BbUbPwOrsWKMn8idSllklzBy+dgQ==", "integrity": "sha512-IDrddSmpSv51ftWslJMvl3Q2ZT98fUSL2/rlUXuVqRXHCs5EUF1/f+jbjF5+NG9UffUDMCiTyh8iec7u8RlTLg==",
"cpu": [ "cpu": [
"arm64" "arm64"
], ],
@@ -66,9 +67,9 @@
} }
}, },
"node_modules/@esbuild/android-x64": { "node_modules/@esbuild/android-x64": {
"version": "0.27.7", "version": "0.25.9",
"resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.27.7.tgz", "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.9.tgz",
"integrity": "sha512-x5VpMODneVDb70PYV2VQOmIUUiBtY3D3mPBG8NxVk5CogneYhkR7MmM3yR/uMdITLrC1ml/NV1rj4bMJuy9MCg==", "integrity": "sha512-I853iMZ1hWZdNllhVZKm34f4wErd4lMyeV7BLzEExGEIZYsOzqDWDf+y082izYUE8gtJnYHdeDpN/6tUdwvfiw==",
"cpu": [ "cpu": [
"x64" "x64"
], ],
@@ -83,9 +84,9 @@
} }
}, },
"node_modules/@esbuild/darwin-arm64": { "node_modules/@esbuild/darwin-arm64": {
"version": "0.27.7", "version": "0.25.9",
"resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.27.7.tgz", "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.9.tgz",
"integrity": "sha512-5lckdqeuBPlKUwvoCXIgI2D9/ABmPq3Rdp7IfL70393YgaASt7tbju3Ac+ePVi3KDH6N2RqePfHnXkaDtY9fkw==", "integrity": "sha512-XIpIDMAjOELi/9PB30vEbVMs3GV1v2zkkPnuyRRURbhqjyzIINwj+nbQATh4H9GxUgH1kFsEyQMxwiLFKUS6Rg==",
"cpu": [ "cpu": [
"arm64" "arm64"
], ],
@@ -100,9 +101,9 @@
} }
}, },
"node_modules/@esbuild/darwin-x64": { "node_modules/@esbuild/darwin-x64": {
"version": "0.27.7", "version": "0.25.9",
"resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.27.7.tgz", "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.9.tgz",
"integrity": "sha512-rYnXrKcXuT7Z+WL5K980jVFdvVKhCHhUwid+dDYQpH+qu+TefcomiMAJpIiC2EM3Rjtq0sO3StMV/+3w3MyyqQ==", "integrity": "sha512-jhHfBzjYTA1IQu8VyrjCX4ApJDnH+ez+IYVEoJHeqJm9VhG9Dh2BYaJritkYK3vMaXrf7Ogr/0MQ8/MeIefsPQ==",
"cpu": [ "cpu": [
"x64" "x64"
], ],
@@ -117,9 +118,9 @@
} }
}, },
"node_modules/@esbuild/freebsd-arm64": { "node_modules/@esbuild/freebsd-arm64": {
"version": "0.27.7", "version": "0.25.9",
"resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.27.7.tgz", "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.9.tgz",
"integrity": "sha512-B48PqeCsEgOtzME2GbNM2roU29AMTuOIN91dsMO30t+Ydis3z/3Ngoj5hhnsOSSwNzS+6JppqWsuhTp6E82l2w==", "integrity": "sha512-z93DmbnY6fX9+KdD4Ue/H6sYs+bhFQJNCPZsi4XWJoYblUqT06MQUdBCpcSfuiN72AbqeBFu5LVQTjfXDE2A6Q==",
"cpu": [ "cpu": [
"arm64" "arm64"
], ],
@@ -134,9 +135,9 @@
} }
}, },
"node_modules/@esbuild/freebsd-x64": { "node_modules/@esbuild/freebsd-x64": {
"version": "0.27.7", "version": "0.25.9",
"resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.27.7.tgz", "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.9.tgz",
"integrity": "sha512-jOBDK5XEjA4m5IJK3bpAQF9/Lelu/Z9ZcdhTRLf4cajlB+8VEhFFRjWgfy3M1O4rO2GQ/b2dLwCUGpiF/eATNQ==", "integrity": "sha512-mrKX6H/vOyo5v71YfXWJxLVxgy1kyt1MQaD8wZJgJfG4gq4DpQGpgTB74e5yBeQdyMTbgxp0YtNj7NuHN0PoZg==",
"cpu": [ "cpu": [
"x64" "x64"
], ],
@@ -151,9 +152,9 @@
} }
}, },
"node_modules/@esbuild/linux-arm": { "node_modules/@esbuild/linux-arm": {
"version": "0.27.7", "version": "0.25.9",
"resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.27.7.tgz", "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.9.tgz",
"integrity": "sha512-RkT/YXYBTSULo3+af8Ib0ykH8u2MBh57o7q/DAs3lTJlyVQkgQvlrPTnjIzzRPQyavxtPtfg0EopvDyIt0j1rA==", "integrity": "sha512-HBU2Xv78SMgaydBmdor38lg8YDnFKSARg1Q6AT0/y2ezUAKiZvc211RDFHlEZRFNRVhcMamiToo7bDx3VEOYQw==",
"cpu": [ "cpu": [
"arm" "arm"
], ],
@@ -168,9 +169,9 @@
} }
}, },
"node_modules/@esbuild/linux-arm64": { "node_modules/@esbuild/linux-arm64": {
"version": "0.27.7", "version": "0.25.9",
"resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.27.7.tgz", "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.9.tgz",
"integrity": "sha512-RZPHBoxXuNnPQO9rvjh5jdkRmVizktkT7TCDkDmQ0W2SwHInKCAV95GRuvdSvA7w4VMwfCjUiPwDi0ZO6Nfe9A==", "integrity": "sha512-BlB7bIcLT3G26urh5Dmse7fiLmLXnRlopw4s8DalgZ8ef79Jj4aUcYbk90g8iCa2467HX8SAIidbL7gsqXHdRw==",
"cpu": [ "cpu": [
"arm64" "arm64"
], ],
@@ -185,9 +186,9 @@
} }
}, },
"node_modules/@esbuild/linux-ia32": { "node_modules/@esbuild/linux-ia32": {
"version": "0.27.7", "version": "0.25.9",
"resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.27.7.tgz", "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.9.tgz",
"integrity": "sha512-GA48aKNkyQDbd3KtkplYWT102C5sn/EZTY4XROkxONgruHPU72l+gW+FfF8tf2cFjeHaRbWpOYa/uRBz/Xq1Pg==", "integrity": "sha512-e7S3MOJPZGp2QW6AK6+Ly81rC7oOSerQ+P8L0ta4FhVi+/j/v2yZzx5CqqDaWjtPFfYz21Vi1S0auHrap3Ma3A==",
"cpu": [ "cpu": [
"ia32" "ia32"
], ],
@@ -202,9 +203,9 @@
} }
}, },
"node_modules/@esbuild/linux-loong64": { "node_modules/@esbuild/linux-loong64": {
"version": "0.27.7", "version": "0.25.9",
"resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.27.7.tgz", "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.9.tgz",
"integrity": "sha512-a4POruNM2oWsD4WKvBSEKGIiWQF8fZOAsycHOt6JBpZ+JN2n2JH9WAv56SOyu9X5IqAjqSIPTaJkqN8F7XOQ5Q==", "integrity": "sha512-Sbe10Bnn0oUAB2AalYztvGcK+o6YFFA/9829PhOCUS9vkJElXGdphz0A3DbMdP8gmKkqPmPcMJmJOrI3VYB1JQ==",
"cpu": [ "cpu": [
"loong64" "loong64"
], ],
@@ -219,9 +220,9 @@
} }
}, },
"node_modules/@esbuild/linux-mips64el": { "node_modules/@esbuild/linux-mips64el": {
"version": "0.27.7", "version": "0.25.9",
"resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.27.7.tgz", "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.9.tgz",
"integrity": "sha512-KabT5I6StirGfIz0FMgl1I+R1H73Gp0ofL9A3nG3i/cYFJzKHhouBV5VWK1CSgKvVaG4q1RNpCTR2LuTVB3fIw==", "integrity": "sha512-YcM5br0mVyZw2jcQeLIkhWtKPeVfAerES5PvOzaDxVtIyZ2NUBZKNLjC5z3/fUlDgT6w89VsxP2qzNipOaaDyA==",
"cpu": [ "cpu": [
"mips64el" "mips64el"
], ],
@@ -236,9 +237,9 @@
} }
}, },
"node_modules/@esbuild/linux-ppc64": { "node_modules/@esbuild/linux-ppc64": {
"version": "0.27.7", "version": "0.25.9",
"resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.27.7.tgz", "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.9.tgz",
"integrity": "sha512-gRsL4x6wsGHGRqhtI+ifpN/vpOFTQtnbsupUF5R5YTAg+y/lKelYR1hXbnBdzDjGbMYjVJLJTd2OFmMewAgwlQ==", "integrity": "sha512-++0HQvasdo20JytyDpFvQtNrEsAgNG2CY1CLMwGXfFTKGBGQT3bOeLSYE2l1fYdvML5KUuwn9Z8L1EWe2tzs1w==",
"cpu": [ "cpu": [
"ppc64" "ppc64"
], ],
@@ -253,9 +254,9 @@
} }
}, },
"node_modules/@esbuild/linux-riscv64": { "node_modules/@esbuild/linux-riscv64": {
"version": "0.27.7", "version": "0.25.9",
"resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.27.7.tgz", "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.9.tgz",
"integrity": "sha512-hL25LbxO1QOngGzu2U5xeXtxXcW+/GvMN3ejANqXkxZ/opySAZMrc+9LY/WyjAan41unrR3YrmtTsUpwT66InQ==", "integrity": "sha512-uNIBa279Y3fkjV+2cUjx36xkx7eSjb8IvnL01eXUKXez/CBHNRw5ekCGMPM0BcmqBxBcdgUWuUXmVWwm4CH9kg==",
"cpu": [ "cpu": [
"riscv64" "riscv64"
], ],
@@ -270,9 +271,9 @@
} }
}, },
"node_modules/@esbuild/linux-s390x": { "node_modules/@esbuild/linux-s390x": {
"version": "0.27.7", "version": "0.25.9",
"resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.27.7.tgz", "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.9.tgz",
"integrity": "sha512-2k8go8Ycu1Kb46vEelhu1vqEP+UeRVj2zY1pSuPdgvbd5ykAw82Lrro28vXUrRmzEsUV0NzCf54yARIK8r0fdw==", "integrity": "sha512-Mfiphvp3MjC/lctb+7D287Xw1DGzqJPb/J2aHHcHxflUo+8tmN/6d4k6I2yFR7BVo5/g7x2Monq4+Yew0EHRIA==",
"cpu": [ "cpu": [
"s390x" "s390x"
], ],
@@ -287,9 +288,9 @@
} }
}, },
"node_modules/@esbuild/linux-x64": { "node_modules/@esbuild/linux-x64": {
"version": "0.27.7", "version": "0.25.9",
"resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.27.7.tgz", "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.9.tgz",
"integrity": "sha512-hzznmADPt+OmsYzw1EE33ccA+HPdIqiCRq7cQeL1Jlq2gb1+OyWBkMCrYGBJ+sxVzve2ZJEVeePbLM2iEIZSxA==", "integrity": "sha512-iSwByxzRe48YVkmpbgoxVzn76BXjlYFXC7NvLYq+b+kDjyyk30J0JY47DIn8z1MO3K0oSl9fZoRmZPQI4Hklzg==",
"cpu": [ "cpu": [
"x64" "x64"
], ],
@@ -304,9 +305,9 @@
} }
}, },
"node_modules/@esbuild/netbsd-arm64": { "node_modules/@esbuild/netbsd-arm64": {
"version": "0.27.7", "version": "0.25.9",
"resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.27.7.tgz", "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.9.tgz",
"integrity": "sha512-b6pqtrQdigZBwZxAn1UpazEisvwaIDvdbMbmrly7cDTMFnw/+3lVxxCTGOrkPVnsYIosJJXAsILG9XcQS+Yu6w==", "integrity": "sha512-9jNJl6FqaUG+COdQMjSCGW4QiMHH88xWbvZ+kRVblZsWrkXlABuGdFJ1E9L7HK+T0Yqd4akKNa/lO0+jDxQD4Q==",
"cpu": [ "cpu": [
"arm64" "arm64"
], ],
@@ -321,9 +322,9 @@
} }
}, },
"node_modules/@esbuild/netbsd-x64": { "node_modules/@esbuild/netbsd-x64": {
"version": "0.27.7", "version": "0.25.9",
"resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.27.7.tgz", "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.9.tgz",
"integrity": "sha512-OfatkLojr6U+WN5EDYuoQhtM+1xco+/6FSzJJnuWiUw5eVcicbyK3dq5EeV/QHT1uy6GoDhGbFpprUiHUYggrw==", "integrity": "sha512-RLLdkflmqRG8KanPGOU7Rpg829ZHu8nFy5Pqdi9U01VYtG9Y0zOG6Vr2z4/S+/3zIyOxiK6cCeYNWOFR9QP87g==",
"cpu": [ "cpu": [
"x64" "x64"
], ],
@@ -338,9 +339,9 @@
} }
}, },
"node_modules/@esbuild/openbsd-arm64": { "node_modules/@esbuild/openbsd-arm64": {
"version": "0.27.7", "version": "0.25.9",
"resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.27.7.tgz", "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.9.tgz",
"integrity": "sha512-AFuojMQTxAz75Fo8idVcqoQWEHIXFRbOc1TrVcFSgCZtQfSdc1RXgB3tjOn/krRHENUB4j00bfGjyl2mJrU37A==", "integrity": "sha512-YaFBlPGeDasft5IIM+CQAhJAqS3St3nJzDEgsgFixcfZeyGPCd6eJBWzke5piZuZ7CtL656eOSYKk4Ls2C0FRQ==",
"cpu": [ "cpu": [
"arm64" "arm64"
], ],
@@ -355,9 +356,9 @@
} }
}, },
"node_modules/@esbuild/openbsd-x64": { "node_modules/@esbuild/openbsd-x64": {
"version": "0.27.7", "version": "0.25.9",
"resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.27.7.tgz", "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.9.tgz",
"integrity": "sha512-+A1NJmfM8WNDv5CLVQYJ5PshuRm/4cI6WMZRg1by1GwPIQPCTs1GLEUHwiiQGT5zDdyLiRM/l1G0Pv54gvtKIg==", "integrity": "sha512-1MkgTCuvMGWuqVtAvkpkXFmtL8XhWy+j4jaSO2wxfJtilVCi0ZE37b8uOdMItIHz4I6z1bWWtEX4CJwcKYLcuA==",
"cpu": [ "cpu": [
"x64" "x64"
], ],
@@ -372,9 +373,9 @@
} }
}, },
"node_modules/@esbuild/openharmony-arm64": { "node_modules/@esbuild/openharmony-arm64": {
"version": "0.27.7", "version": "0.25.9",
"resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.27.7.tgz", "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.9.tgz",
"integrity": "sha512-+KrvYb/C8zA9CU/g0sR6w2RBw7IGc5J2BPnc3dYc5VJxHCSF1yNMxTV5LQ7GuKteQXZtspjFbiuW5/dOj7H4Yw==", "integrity": "sha512-4Xd0xNiMVXKh6Fa7HEJQbrpP3m3DDn43jKxMjxLLRjWnRsfxjORYJlXPO4JNcXtOyfajXorRKY9NkOpTHptErg==",
"cpu": [ "cpu": [
"arm64" "arm64"
], ],
@@ -389,9 +390,9 @@
} }
}, },
"node_modules/@esbuild/sunos-x64": { "node_modules/@esbuild/sunos-x64": {
"version": "0.27.7", "version": "0.25.9",
"resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.27.7.tgz", "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.9.tgz",
"integrity": "sha512-ikktIhFBzQNt/QDyOL580ti9+5mL/YZeUPKU2ivGtGjdTYoqz6jObj6nOMfhASpS4GU4Q/Clh1QtxWAvcYKamA==", "integrity": "sha512-WjH4s6hzo00nNezhp3wFIAfmGZ8U7KtrJNlFMRKxiI9mxEK1scOMAaa9i4crUtu+tBr+0IN6JCuAcSBJZfnphw==",
"cpu": [ "cpu": [
"x64" "x64"
], ],
@@ -406,9 +407,9 @@
} }
}, },
"node_modules/@esbuild/win32-arm64": { "node_modules/@esbuild/win32-arm64": {
"version": "0.27.7", "version": "0.25.9",
"resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.27.7.tgz", "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.9.tgz",
"integrity": "sha512-7yRhbHvPqSpRUV7Q20VuDwbjW5kIMwTHpptuUzV+AA46kiPze5Z7qgt6CLCK3pWFrHeNfDd1VKgyP4O+ng17CA==", "integrity": "sha512-mGFrVJHmZiRqmP8xFOc6b84/7xa5y5YvR1x8djzXpJBSv/UsNK6aqec+6JDjConTgvvQefdGhFDAs2DLAds6gQ==",
"cpu": [ "cpu": [
"arm64" "arm64"
], ],
@@ -423,9 +424,9 @@
} }
}, },
"node_modules/@esbuild/win32-ia32": { "node_modules/@esbuild/win32-ia32": {
"version": "0.27.7", "version": "0.25.9",
"resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.27.7.tgz", "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.9.tgz",
"integrity": "sha512-SmwKXe6VHIyZYbBLJrhOoCJRB/Z1tckzmgTLfFYOfpMAx63BJEaL9ExI8x7v0oAO3Zh6D/Oi1gVxEYr5oUCFhw==", "integrity": "sha512-b33gLVU2k11nVx1OhX3C8QQP6UHQK4ZtN56oFWvVXvz2VkDoe6fbG8TOgHFxEvqeqohmRnIHe5A1+HADk4OQww==",
"cpu": [ "cpu": [
"ia32" "ia32"
], ],
@@ -440,9 +441,9 @@
} }
}, },
"node_modules/@esbuild/win32-x64": { "node_modules/@esbuild/win32-x64": {
"version": "0.27.7", "version": "0.25.9",
"resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.27.7.tgz", "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.9.tgz",
"integrity": "sha512-56hiAJPhwQ1R4i+21FVF7V8kSD5zZTdHcVuRFMW0hn753vVfQN8xlx4uOPT4xoGH0Z/oVATuR82AiqSTDIpaHg==", "integrity": "sha512-PPOl1mi6lpLNQxnGoyAfschAodRFYXJ+9fs6WHXz7CSWKbOqiMZsubC+BQsVKuul+3vKLuwTHsS2c2y9EoKwxQ==",
"cpu": [ "cpu": [
"x64" "x64"
], ],
@@ -457,19 +458,19 @@
} }
}, },
"node_modules/@types/node": { "node_modules/@types/node": {
"version": "25.5.2", "version": "22.18.1",
"resolved": "https://registry.npmjs.org/@types/node/-/node-25.5.2.tgz", "resolved": "https://registry.npmjs.org/@types/node/-/node-22.18.1.tgz",
"integrity": "sha512-tO4ZIRKNC+MDWV4qKVZe3Ql/woTnmHDr5JD8UI5hn2pwBrHEwOEMZK7WlNb5RKB6EoJ02gwmQS9OrjuFnZYdpg==", "integrity": "sha512-rzSDyhn4cYznVG+PCzGe1lwuMYJrcBS1fc3JqSa2PvtABwWo+dZ1ij5OVok3tqfpEBCBoaR4d7upFJk73HRJDw==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"undici-types": "~7.18.0" "undici-types": "~6.21.0"
} }
}, },
"node_modules/esbuild": { "node_modules/esbuild": {
"version": "0.27.7", "version": "0.25.9",
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.27.7.tgz", "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.9.tgz",
"integrity": "sha512-IxpibTjyVnmrIQo5aqNpCgoACA/dTKLTlhMHihVHhdkxKyPO1uBBthumT0rdHmcsk9uMonIWS0m4FljWzILh3w==", "integrity": "sha512-CRbODhYyQx3qp7ZEwzxOk4JBqmD/seJrzPa/cGjY1VtIn5E09Oi9/dB4JwctnfZ8Q8iT7rioVv5k/FNT/uf54g==",
"dev": true, "dev": true,
"hasInstallScript": true, "hasInstallScript": true,
"license": "MIT", "license": "MIT",
@@ -480,32 +481,32 @@
"node": ">=18" "node": ">=18"
}, },
"optionalDependencies": { "optionalDependencies": {
"@esbuild/aix-ppc64": "0.27.7", "@esbuild/aix-ppc64": "0.25.9",
"@esbuild/android-arm": "0.27.7", "@esbuild/android-arm": "0.25.9",
"@esbuild/android-arm64": "0.27.7", "@esbuild/android-arm64": "0.25.9",
"@esbuild/android-x64": "0.27.7", "@esbuild/android-x64": "0.25.9",
"@esbuild/darwin-arm64": "0.27.7", "@esbuild/darwin-arm64": "0.25.9",
"@esbuild/darwin-x64": "0.27.7", "@esbuild/darwin-x64": "0.25.9",
"@esbuild/freebsd-arm64": "0.27.7", "@esbuild/freebsd-arm64": "0.25.9",
"@esbuild/freebsd-x64": "0.27.7", "@esbuild/freebsd-x64": "0.25.9",
"@esbuild/linux-arm": "0.27.7", "@esbuild/linux-arm": "0.25.9",
"@esbuild/linux-arm64": "0.27.7", "@esbuild/linux-arm64": "0.25.9",
"@esbuild/linux-ia32": "0.27.7", "@esbuild/linux-ia32": "0.25.9",
"@esbuild/linux-loong64": "0.27.7", "@esbuild/linux-loong64": "0.25.9",
"@esbuild/linux-mips64el": "0.27.7", "@esbuild/linux-mips64el": "0.25.9",
"@esbuild/linux-ppc64": "0.27.7", "@esbuild/linux-ppc64": "0.25.9",
"@esbuild/linux-riscv64": "0.27.7", "@esbuild/linux-riscv64": "0.25.9",
"@esbuild/linux-s390x": "0.27.7", "@esbuild/linux-s390x": "0.25.9",
"@esbuild/linux-x64": "0.27.7", "@esbuild/linux-x64": "0.25.9",
"@esbuild/netbsd-arm64": "0.27.7", "@esbuild/netbsd-arm64": "0.25.9",
"@esbuild/netbsd-x64": "0.27.7", "@esbuild/netbsd-x64": "0.25.9",
"@esbuild/openbsd-arm64": "0.27.7", "@esbuild/openbsd-arm64": "0.25.9",
"@esbuild/openbsd-x64": "0.27.7", "@esbuild/openbsd-x64": "0.25.9",
"@esbuild/openharmony-arm64": "0.27.7", "@esbuild/openharmony-arm64": "0.25.9",
"@esbuild/sunos-x64": "0.27.7", "@esbuild/sunos-x64": "0.25.9",
"@esbuild/win32-arm64": "0.27.7", "@esbuild/win32-arm64": "0.25.9",
"@esbuild/win32-ia32": "0.27.7", "@esbuild/win32-ia32": "0.25.9",
"@esbuild/win32-x64": "0.27.7" "@esbuild/win32-x64": "0.25.9"
} }
}, },
"node_modules/fsevents": { "node_modules/fsevents": {
@@ -524,9 +525,9 @@
} }
}, },
"node_modules/get-tsconfig": { "node_modules/get-tsconfig": {
"version": "4.13.7", "version": "4.10.1",
"resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.13.7.tgz", "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.10.1.tgz",
"integrity": "sha512-7tN6rFgBlMgpBML5j8typ92BKFi2sFQvIdpAqLA2beia5avZDrMs0FLZiM5etShWq5irVyGcGMEA1jcDaK7A/Q==", "integrity": "sha512-auHyJ4AgMz7vgS8Hp3N6HXSmlMdUyhSUrfBF16w153rxtLIEOE+HGqaBppczZvnHLqQJfiHotCYpNhl0lUROFQ==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
@@ -547,13 +548,13 @@
} }
}, },
"node_modules/tsx": { "node_modules/tsx": {
"version": "4.21.0", "version": "4.20.5",
"resolved": "https://registry.npmjs.org/tsx/-/tsx-4.21.0.tgz", "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.20.5.tgz",
"integrity": "sha512-5C1sg4USs1lfG0GFb2RLXsdpXqBSEhAaA/0kPL01wxzpMqLILNxIxIOKiILz+cdg/pLnOUxFYOR5yhHU666wbw==", "integrity": "sha512-+wKjMNU9w/EaQayHXb7WA7ZaHY6hN8WgfvHNQ3t1PnU91/7O8TcTnIhCDYTZwnt8JsO9IBqZ30Ln1r7pPF52Aw==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"esbuild": "~0.27.0", "esbuild": "~0.25.0",
"get-tsconfig": "^4.7.5" "get-tsconfig": "^4.7.5"
}, },
"bin": { "bin": {
@@ -567,9 +568,9 @@
} }
}, },
"node_modules/typescript": { "node_modules/typescript": {
"version": "6.0.2", "version": "5.9.2",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-6.0.2.tgz", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.2.tgz",
"integrity": "sha512-bGdAIrZ0wiGDo5l8c++HWtbaNCWTS4UTv7RaTH/ThVIgjkveJt83m74bBHMJkuCbslY8ixgLBVZJIOiQlQTjfQ==", "integrity": "sha512-CWBzXQrc/qOkhidw1OzBTQuYRbfyxDXJMVJ1XNwUHGROVmuaeiEm3OslpZ1RV96d7SKKjZKrSJu3+t/xlw3R9A==",
"dev": true, "dev": true,
"license": "Apache-2.0", "license": "Apache-2.0",
"bin": { "bin": {
@@ -581,9 +582,9 @@
} }
}, },
"node_modules/undici-types": { "node_modules/undici-types": {
"version": "7.18.2", "version": "6.21.0",
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.18.2.tgz", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz",
"integrity": "sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w==", "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==",
"dev": true, "dev": true,
"license": "MIT" "license": "MIT"
} }

View File

@@ -6,14 +6,16 @@
"type": "module", "type": "module",
"scripts": { "scripts": {
"start": "tsx src/index.ts", "start": "tsx src/index.ts",
"test": "tsx src/test.ts" "test": "tsx src/test.ts",
"build": "tsc && esbuild --bundle --minify --sourcemap --platform=node --target=node20 --outdir=build src/index.ts"
}, },
"author": "Hervé BECHER", "author": "Hervé BECHER",
"license": "ISC", "license": "ISC",
"devDependencies": { "devDependencies": {
"@types/node": "^25.5.0", "@types/node": "^22.15.21",
"esbuild": "^0.25.4",
"tsx": "^4.19.4", "tsx": "^4.19.4",
"typescript": "^6.0.2" "typescript": "^5.8.3"
}, },
"exports": { "exports": {
".": { ".": {

View File

@@ -1,8 +1,8 @@
import { Collector } from "../collector/types.js"; import { Collector } from "../collector/types.js";
import { asAsyncComparer, combineAsyncComparers, createAsyncComparerUsing, defaultAsyncComparer } from "../comparer/async.js"; import { asAsyncComparer, combineNullableAsyncComparers, createAsyncComparerUsing, defaultAsyncComparer } from "../comparer/async.js";
import { MaybeAsyncComparisonOrComparer, AsyncComparer } from "../comparer/types.js"; import { MaybeAsyncComparisonOrComparer, AsyncComparer } from "../comparer/types.js";
import { asAsyncEqualityComparer, defaultAsyncEqualityComparer } from "../equality-comparer/async.js"; import { strictEquals } from "../equality-comparer/sync.js";
import { AsyncEqualityComparer, MaybeAsyncEqualityComparisonOrComparer } from "../equality-comparer/types.js"; import { MaybeAsyncEqualityComparison } from "../equality-comparer/types.js";
import { createAsyncEqualityMap } from "../equality-map/index.js"; import { createAsyncEqualityMap } from "../equality-map/index.js";
import { createAsyncEqualitySet } from "../equality-set/index.js"; import { createAsyncEqualitySet } from "../equality-set/index.js";
import { createQueue } from "../queue.js"; import { createQueue } from "../queue.js";
@@ -42,29 +42,31 @@ export abstract class BaseAsyncSequence<TElement> extends AsyncSequenceMarker im
return new WhereAsyncSequence<TElement, any>(this, predicate); return new WhereAsyncSequence<TElement, any>(this, predicate);
} }
groupBy<TKey>(keySelector: MaybeAsyncConverter<TElement, TKey>, elementSelector?: undefined, keyComparer?: MaybeAsyncEqualityComparisonOrComparer<TKey> | undefined): AsyncSequence<GroupedAsyncSequence<TKey, TElement>>; groupBy<TKey>(keySelector: MaybeAsyncConverter<TElement, TKey>, elementSelector?: undefined, keyComparer?: MaybeAsyncEqualityComparison<TKey> | undefined): AsyncSequence<GroupedAsyncSequence<TKey, TElement>>;
groupBy<TKey, TResult>(keySelector: MaybeAsyncConverter<TElement, TKey>, elementSelector: MaybeAsyncConverter<TElement, TResult>, keyComparer?: MaybeAsyncEqualityComparisonOrComparer<TKey> | undefined): AsyncSequence<GroupedAsyncSequence<TKey, TResult>>; groupBy<TKey, TResult>(keySelector: MaybeAsyncConverter<TElement, TKey>, elementSelector: MaybeAsyncConverter<TElement, TResult>, keyComparer?: MaybeAsyncEqualityComparison<TKey> | undefined): AsyncSequence<GroupedAsyncSequence<TKey, TResult>>;
groupBy(keySelector: any, elementSelector?: any, keyComparer?: any) { groupBy(keySelector: any, elementSelector?: any, keyComparer?: any) {
return new GroupByAsyncSequence<any, any, any>(this, keySelector, elementSelector, keyComparer); return new GroupByAsyncSequence<any, any, any>(this, keySelector, elementSelector, keyComparer);
} }
join<TOther, TKey>(sequence: MaybeAsyncIterable<TOther>, firstKeySelector: MaybeAsyncConverter<TElement, TKey>, secondKeySelector: MaybeAsyncConverter<TOther, TKey>, resultSelector?: undefined, keyComparer?: MaybeAsyncEqualityComparisonOrComparer<TKey> | undefined): AsyncSequence<[TElement, TOther]>; join<TOther, TKey>(sequence: MaybeAsyncIterable<TOther>, firstKeySelector: MaybeAsyncConverter<TElement, TKey>, secondKeySelector: MaybeAsyncConverter<TOther, TKey>, resultSelector?: undefined, keyComparer?: MaybeAsyncEqualityComparison<TKey> | undefined): AsyncSequence<[TElement, TOther]>;
join<TOther, TKey, TResult>(sequence: MaybeAsyncIterable<TOther>, firstKeySelector: MaybeAsyncConverter<TElement, TKey>, secondKeySelector: MaybeAsyncConverter<TOther, TKey>, resultSelector: MaybeAsyncBiConverter<TElement, TOther, TResult>, keyComparer?: MaybeAsyncEqualityComparisonOrComparer<TKey> | undefined): AsyncSequence<TResult>; join<TOther, TKey, TResult>(sequence: MaybeAsyncIterable<TOther>, firstKeySelector: MaybeAsyncConverter<TElement, TKey>, secondKeySelector: MaybeAsyncConverter<TOther, TKey>, resultSelector: MaybeAsyncBiConverter<TElement, TOther, TResult>, keyComparer?: MaybeAsyncEqualityComparison<TKey> | undefined): AsyncSequence<TResult>;
join(sequence: any, firstKeySelector: any, secondKeySelector: any, resultSelector?: any, keyComparer?: any) { join(sequence: any, firstKeySelector: any, secondKeySelector: any, resultSelector?: any, keyComparer?: any) {
return new JoinAsyncSequence<any, any, any, any>(this, wrap(sequence), firstKeySelector, secondKeySelector, resultSelector, keyComparer); return new JoinAsyncSequence<any, any, any, any>(this, wrap(sequence), firstKeySelector, secondKeySelector, resultSelector, keyComparer);
} }
groupJoin<TOther, TKey>(sequence: MaybeAsyncIterable<TOther>, firstKeySelector: MaybeAsyncConverter<TElement, TKey>, secondKeySelector: MaybeAsyncConverter<TOther, TKey>, resultSelector?: undefined, keyComparer?: MaybeAsyncEqualityComparisonOrComparer<TKey> | undefined): AsyncSequence<GroupedAsyncSequence<TElement, TOther>>; groupJoin<TOther, TKey>(sequence: MaybeAsyncIterable<TOther>, firstKeySelector: MaybeAsyncConverter<TElement, TKey>, secondKeySelector: MaybeAsyncConverter<TOther, TKey>, resultSelector?: undefined, keyComparer?: MaybeAsyncEqualityComparison<TKey> | undefined): AsyncSequence<GroupedAsyncSequence<TElement, TOther>>;
groupJoin<TOther, TKey, TResult>(sequence: MaybeAsyncIterable<TOther>, firstKeySelector: MaybeAsyncConverter<TElement, TKey>, secondKeySelector: MaybeAsyncConverter<TOther, TKey>, resultSelector: MaybeAsyncBiConverter<TElement, MaybeAsyncIterable<TOther>, TResult>, keyComparer?: MaybeAsyncEqualityComparisonOrComparer<TKey> | undefined): AsyncSequence<TResult>; groupJoin<TOther, TKey, TResult>(sequence: MaybeAsyncIterable<TOther>, firstKeySelector: MaybeAsyncConverter<TElement, TKey>, secondKeySelector: MaybeAsyncConverter<TOther, TKey>, resultSelector: MaybeAsyncBiConverter<TElement, MaybeAsyncIterable<TOther>, TResult>, keyComparer?: MaybeAsyncEqualityComparison<TKey> | undefined): AsyncSequence<TResult>;
groupJoin(sequence: any, firstKeySelector: any, secondKeySelector: any, resultSelector?: any, keyComparer?: any) { groupJoin(sequence: any, firstKeySelector: any, secondKeySelector: any, resultSelector?: any, keyComparer?: any) {
return new GroupJoinAsyncSequence<any, any, any, any>(this, wrap(sequence), firstKeySelector, secondKeySelector, resultSelector, keyComparer); return new GroupJoinAsyncSequence<any, any, any, any>(this, wrap(sequence), firstKeySelector, secondKeySelector, resultSelector, keyComparer);
} }
async contains(obj: TElement, equater?: MaybeAsyncEqualityComparisonOrComparer<TElement>) { async contains(obj: TElement, equater?: MaybeAsyncEqualityComparison<TElement>) {
equater = equater ? asAsyncEqualityComparer(equater) : defaultAsyncEqualityComparer; if (!equater) {
equater = strictEquals;
}
for await (const element of this) { for await (const element of this) {
if (await equater.equals(element, obj)) { if (await equater(element, obj)) {
return true; return true;
} }
} }
@@ -72,7 +74,7 @@ export abstract class BaseAsyncSequence<TElement> extends AsyncSequenceMarker im
return false; return false;
} }
async sequenceEquals(sequence: MaybeAsyncIterable<TElement>, equater?: MaybeAsyncEqualityComparisonOrComparer<TElement>) { async sequenceEquals(sequence: MaybeAsyncIterable<TElement>, equater?: MaybeAsyncEqualityComparison<TElement>) {
if (this === sequence) { if (this === sequence) {
return true; return true;
} }
@@ -86,7 +88,9 @@ export abstract class BaseAsyncSequence<TElement> extends AsyncSequenceMarker im
return false; return false;
} }
equater = equater ? asAsyncEqualityComparer(equater) : defaultAsyncEqualityComparer; if (!equater) {
equater = strictEquals;
}
const thisIterator = this.iterator(); const thisIterator = this.iterator();
const thatIterator = that.iterator(); const thatIterator = that.iterator();
@@ -103,7 +107,7 @@ export abstract class BaseAsyncSequence<TElement> extends AsyncSequenceMarker im
return false; return false;
} }
if (!await equater.equals(thisNext.value, thatNext.value)) { if (!await equater(thisNext.value, thatNext.value)) {
return false; return false;
} }
} }
@@ -117,7 +121,7 @@ export abstract class BaseAsyncSequence<TElement> extends AsyncSequenceMarker im
return new PrependAsyncSequence<TElement>(this, obj); return new PrependAsyncSequence<TElement>(this, obj);
} }
remove(obj: TElement, all?: boolean, equater?: MaybeAsyncEqualityComparisonOrComparer<TElement>): AsyncSequence<TElement> { remove(obj: TElement, all?: boolean, equater?: MaybeAsyncEqualityComparison<TElement>): AsyncSequence<TElement> {
return new RemoveAsyncSequence<TElement>(this, obj, all, equater); return new RemoveAsyncSequence<TElement>(this, obj, all, equater);
} }
@@ -212,29 +216,27 @@ export abstract class BaseAsyncSequence<TElement> extends AsyncSequenceMarker im
} }
async #tryGetLast(predicate?: MaybeAsyncAnyPredicate<TElement>): Promise<FindElementResult<TElement>> { async #tryGetLast(predicate?: MaybeAsyncAnyPredicate<TElement>): Promise<FindElementResult<TElement>> {
let result: FindElementResult<TElement> = { let found = false;
found: false let result: TElement | undefined = undefined;
};
if (predicate) { if (predicate) {
for await (const element of this) { for await (const element of this) {
if (await predicate(element)) { if (await predicate(element)) {
result = { found = true;
found: true, result = element;
element
};
} }
} }
} else { } else {
for await (const element of this) { for await (const element of this) {
result = { found = true;
found: true, result = element;
element
};
} }
} }
return result; return {
found,
element: result
} as FindElementResult<TElement>;
} }
async last(predicate?: MaybeAsyncAnyPredicate<TElement>) { async last(predicate?: MaybeAsyncAnyPredicate<TElement>) {
@@ -514,27 +516,27 @@ export abstract class BaseAsyncSequence<TElement> extends AsyncSequenceMarker im
return new OrderByAsyncSequence<TElement, TBy>(this, true, selector, comparer); return new OrderByAsyncSequence<TElement, TBy>(this, true, selector, comparer);
} }
partition(equater?: MaybeAsyncEqualityComparisonOrComparer<TElement>): AsyncSequence<AsyncSequence<TElement>> { partition(equater?: MaybeAsyncEqualityComparison<TElement>): AsyncSequence<AsyncSequence<TElement>> {
return new PartitionAsyncSequence<TElement>(this, equater); return new PartitionAsyncSequence<TElement>(this, equater);
} }
partitionBy<TBy>(selector: MaybeAsyncConverter<TElement, TBy>, equater?: MaybeAsyncEqualityComparisonOrComparer<TBy>): AsyncSequence<AsyncSequence<TElement>> { partitionBy<TBy>(selector: MaybeAsyncConverter<TElement, TBy>, equater?: MaybeAsyncEqualityComparison<TBy>): AsyncSequence<AsyncSequence<TElement>> {
return new PartitionByAsyncSequence<TElement, TBy>(this, selector, equater); return new PartitionByAsyncSequence<TElement, TBy>(this, selector, equater);
} }
distinct(equater?: MaybeAsyncEqualityComparisonOrComparer<TElement>): AsyncSequence<TElement> { distinct(equater?: MaybeAsyncEqualityComparison<TElement>): AsyncSequence<TElement> {
return new DistinctAsyncSequence<TElement>(this, equater); return new DistinctAsyncSequence<TElement>(this, equater);
} }
distinctBy<TBy>(selector: MaybeAsyncConverter<TElement, TBy>, equater?: MaybeAsyncEqualityComparisonOrComparer<TBy>): AsyncSequence<TElement> { distinctBy<TBy>(selector: MaybeAsyncConverter<TElement, TBy>, equater?: MaybeAsyncEqualityComparison<TBy>): AsyncSequence<TElement> {
return new DistinctByAsyncSequence<TElement, TBy>(this, selector, equater); return new DistinctByAsyncSequence<TElement, TBy>(this, selector, equater);
} }
union(sequence: MaybeAsyncIterable<TElement>, equater?: MaybeAsyncEqualityComparisonOrComparer<TElement>): AsyncSequence<TElement> { union(sequence: MaybeAsyncIterable<TElement>, equater?: MaybeAsyncEqualityComparison<TElement>): AsyncSequence<TElement> {
return new UnionAsyncSequence<TElement>(this, wrap(sequence), equater); return new UnionAsyncSequence<TElement>(this, wrap(sequence), equater);
} }
unionBy<TBy>(sequence: MaybeAsyncIterable<TElement>, selector: MaybeAsyncConverter<TElement, TBy>, equater?: MaybeAsyncEqualityComparisonOrComparer<TBy>): AsyncSequence<TElement> { unionBy<TBy>(sequence: MaybeAsyncIterable<TElement>, selector: MaybeAsyncConverter<TElement, TBy>, equater?: MaybeAsyncEqualityComparison<TBy>): AsyncSequence<TElement> {
return new UnionByAsyncSequence<TElement, TBy>(this, wrap(sequence), selector, equater); return new UnionByAsyncSequence<TElement, TBy>(this, wrap(sequence), selector, equater);
} }
@@ -664,10 +666,6 @@ export abstract class BaseAsyncSequence<TElement> extends AsyncSequenceMarker im
return new ZippedAsyncSequence<TElement, TOther>(this, wrap(sequence)); return new ZippedAsyncSequence<TElement, TOther>(this, wrap(sequence));
} }
cartesianProduct<TOther>(sequence: MaybeAsyncIterable<TOther>): AsyncSequence<[TElement, TOther]> {
return new CartesianProductAsyncSequence<TElement, TOther>(this, wrap(sequence));
}
indexed(): AsyncSequence<[number, TElement]> { indexed(): AsyncSequence<[number, TElement]> {
return new IndexedAsyncSequence<TElement>(this); return new IndexedAsyncSequence<TElement>(this);
} }
@@ -813,29 +811,29 @@ export class DelegatedAsyncSequence<TElement> extends AsyncSequenceMarker implem
return this.#sequence.where(predicate); return this.#sequence.where(predicate);
} }
groupBy<TKey>(keySelector: MaybeAsyncConverter<TElement, TKey>, elementSelector?: undefined, keyComparer?: MaybeAsyncEqualityComparisonOrComparer<TKey> | undefined): AsyncSequence<GroupedAsyncSequence<TKey, TElement>>; groupBy<TKey>(keySelector: MaybeAsyncConverter<TElement, TKey>, elementSelector?: undefined, keyComparer?: MaybeAsyncEqualityComparison<TKey> | undefined): AsyncSequence<GroupedAsyncSequence<TKey, TElement>>;
groupBy<TKey, TResult>(keySelector: MaybeAsyncConverter<TElement, TKey>, elementSelector: MaybeAsyncConverter<TElement, TResult>, keyComparer?: MaybeAsyncEqualityComparisonOrComparer<TKey> | undefined): AsyncSequence<GroupedAsyncSequence<TKey, TResult>>; groupBy<TKey, TResult>(keySelector: MaybeAsyncConverter<TElement, TKey>, elementSelector: MaybeAsyncConverter<TElement, TResult>, keyComparer?: MaybeAsyncEqualityComparison<TKey> | undefined): AsyncSequence<GroupedAsyncSequence<TKey, TResult>>;
groupBy(keySelector: any, elementSelector?: any, keyComparer?: any) { groupBy(keySelector: any, elementSelector?: any, keyComparer?: any) {
return this.#sequence.groupBy(keySelector, elementSelector, keyComparer); return this.#sequence.groupBy(keySelector, elementSelector, keyComparer);
} }
join<TOther, TKey>(sequence: MaybeAsyncIterable<TOther>, firstKeySelector: MaybeAsyncConverter<TElement, TKey>, secondKeySelector: MaybeAsyncConverter<TOther, TKey>, resultSelector?: undefined, keyComparer?: MaybeAsyncEqualityComparisonOrComparer<TKey> | undefined): AsyncSequence<[TElement, TOther]>; join<TOther, TKey>(sequence: MaybeAsyncIterable<TOther>, firstKeySelector: MaybeAsyncConverter<TElement, TKey>, secondKeySelector: MaybeAsyncConverter<TOther, TKey>, resultSelector?: undefined, keyComparer?: MaybeAsyncEqualityComparison<TKey> | undefined): AsyncSequence<[TElement, TOther]>;
join<TOther, TKey, TResult>(sequence: MaybeAsyncIterable<TOther>, firstKeySelector: MaybeAsyncConverter<TElement, TKey>, secondKeySelector: MaybeAsyncConverter<TOther, TKey>, resultSelector: MaybeAsyncBiConverter<TElement, TOther, TResult>, keyComparer?: MaybeAsyncEqualityComparisonOrComparer<TKey> | undefined): AsyncSequence<TResult>; join<TOther, TKey, TResult>(sequence: MaybeAsyncIterable<TOther>, firstKeySelector: MaybeAsyncConverter<TElement, TKey>, secondKeySelector: MaybeAsyncConverter<TOther, TKey>, resultSelector: MaybeAsyncBiConverter<TElement, TOther, TResult>, keyComparer?: MaybeAsyncEqualityComparison<TKey> | undefined): AsyncSequence<TResult>;
join(sequence: any, firstKeySelector: any, secondKeySelector: any, resultSelector?: any, keyComparer?: any) { join(sequence: any, firstKeySelector: any, secondKeySelector: any, resultSelector?: any, keyComparer?: any) {
return this.#sequence.join(sequence, firstKeySelector, secondKeySelector, resultSelector, keyComparer); return this.#sequence.join(sequence, firstKeySelector, secondKeySelector, resultSelector, keyComparer);
} }
groupJoin<TOther, TKey>(sequence: MaybeAsyncIterable<TOther>, firstKeySelector: MaybeAsyncConverter<TElement, TKey>, secondKeySelector: MaybeAsyncConverter<TOther, TKey>, resultSelector?: undefined, keyComparer?: MaybeAsyncEqualityComparisonOrComparer<TKey> | undefined): AsyncSequence<GroupedAsyncSequence<TElement, TOther>>; groupJoin<TOther, TKey>(sequence: MaybeAsyncIterable<TOther>, firstKeySelector: MaybeAsyncConverter<TElement, TKey>, secondKeySelector: MaybeAsyncConverter<TOther, TKey>, resultSelector?: undefined, keyComparer?: MaybeAsyncEqualityComparison<TKey> | undefined): AsyncSequence<GroupedAsyncSequence<TElement, TOther>>;
groupJoin<TOther, TKey, TResult>(sequence: MaybeAsyncIterable<TOther>, firstKeySelector: MaybeAsyncConverter<TElement, TKey>, secondKeySelector: MaybeAsyncConverter<TOther, TKey>, resultSelector: MaybeAsyncBiConverter<TElement, MaybeAsyncIterable<TOther>, TResult>, keyComparer?: MaybeAsyncEqualityComparisonOrComparer<TKey> | undefined): AsyncSequence<TResult>; groupJoin<TOther, TKey, TResult>(sequence: MaybeAsyncIterable<TOther>, firstKeySelector: MaybeAsyncConverter<TElement, TKey>, secondKeySelector: MaybeAsyncConverter<TOther, TKey>, resultSelector: MaybeAsyncBiConverter<TElement, MaybeAsyncIterable<TOther>, TResult>, keyComparer?: MaybeAsyncEqualityComparison<TKey> | undefined): AsyncSequence<TResult>;
groupJoin(sequence: any, firstKeySelector: any, secondKeySelector: any, resultSelector?: any, keyComparer?: any) { groupJoin(sequence: any, firstKeySelector: any, secondKeySelector: any, resultSelector?: any, keyComparer?: any) {
return this.#sequence.groupJoin(sequence, firstKeySelector, secondKeySelector, resultSelector, keyComparer); return this.#sequence.groupJoin(sequence, firstKeySelector, secondKeySelector, resultSelector, keyComparer);
} }
contains(obj: TElement, equater?: MaybeAsyncEqualityComparisonOrComparer<TElement> | undefined): Promise<boolean> { contains(obj: TElement, equater?: MaybeAsyncEqualityComparison<TElement> | undefined): Promise<boolean> {
return this.#sequence.contains(obj, equater); return this.#sequence.contains(obj, equater);
} }
sequenceEquals(sequence: MaybeAsyncIterable<TElement>, equater?: MaybeAsyncEqualityComparisonOrComparer<TElement> | undefined): Promise<boolean> { sequenceEquals(sequence: MaybeAsyncIterable<TElement>, equater?: MaybeAsyncEqualityComparison<TElement> | undefined): Promise<boolean> {
return this.#sequence.sequenceEquals(sequence, equater); return this.#sequence.sequenceEquals(sequence, equater);
} }
@@ -847,7 +845,7 @@ export class DelegatedAsyncSequence<TElement> extends AsyncSequenceMarker implem
return this.#sequence.prepend(obj); return this.#sequence.prepend(obj);
} }
remove(obj: TElement, all?: boolean | undefined, equater?: MaybeAsyncEqualityComparisonOrComparer<TElement> | undefined): AsyncSequence<TElement> { remove(obj: TElement, all?: boolean | undefined, equater?: MaybeAsyncEqualityComparison<TElement> | undefined): AsyncSequence<TElement> {
return this.#sequence.remove(obj, all, equater); return this.#sequence.remove(obj, all, equater);
} }
@@ -918,59 +916,59 @@ export class DelegatedAsyncSequence<TElement> extends AsyncSequenceMarker implem
return this.#sequence.boundsBy(selector, comparer); return this.#sequence.boundsBy(selector, comparer);
} }
order(comparer?: MaybeAsyncComparisonOrComparer<TElement> | undefined): OrderedAsyncSequence<TElement> { order(comparer?: MaybeAsyncComparisonOrComparer<TElement> | undefined): AsyncSequence<TElement> {
return this.#sequence.order(comparer); return this.#sequence.order(comparer);
} }
orderBy<TBy>(selector: MaybeAsyncConverter<TElement, TBy>, comparer?: MaybeAsyncComparisonOrComparer<TBy> | undefined): OrderedAsyncSequence<TElement> { orderBy<TBy>(selector: MaybeAsyncConverter<TElement, TBy>, comparer?: MaybeAsyncComparisonOrComparer<TBy> | undefined): AsyncSequence<TElement> {
return this.#sequence.orderBy(selector, comparer); return this.#sequence.orderBy(selector, comparer);
} }
orderDescending(comparer?: MaybeAsyncComparisonOrComparer<TElement> | undefined): OrderedAsyncSequence<TElement> { orderDescending(comparer?: MaybeAsyncComparisonOrComparer<TElement> | undefined): AsyncSequence<TElement> {
return this.#sequence.orderDescending(comparer); return this.#sequence.orderDescending(comparer);
} }
orderByDescending<TBy>(selector: MaybeAsyncConverter<TElement, TBy>, comparer?: MaybeAsyncComparisonOrComparer<TBy> | undefined): OrderedAsyncSequence<TElement> { orderByDescending<TBy>(selector: MaybeAsyncConverter<TElement, TBy>, comparer?: MaybeAsyncComparisonOrComparer<TBy> | undefined): AsyncSequence<TElement> {
return this.#sequence.orderByDescending(selector, comparer); return this.#sequence.orderByDescending(selector, comparer);
} }
partition(equater?: MaybeAsyncEqualityComparisonOrComparer<TElement> | undefined): AsyncSequence<AsyncSequence<TElement>> { partition(equater?: MaybeAsyncEqualityComparison<TElement> | undefined): AsyncSequence<AsyncSequence<TElement>> {
return this.#sequence.partition(equater); return this.#sequence.partition(equater);
} }
partitionBy<TBy>(selector: MaybeAsyncConverter<TElement, TBy>, equater?: MaybeAsyncEqualityComparisonOrComparer<TBy> | undefined): AsyncSequence<AsyncSequence<TElement>> { partitionBy<TBy>(selector: MaybeAsyncConverter<TElement, TBy>, equater?: MaybeAsyncEqualityComparison<TBy> | undefined): AsyncSequence<AsyncSequence<TElement>> {
return this.#sequence.partitionBy(selector, equater); return this.#sequence.partitionBy(selector, equater);
} }
distinct(equater?: MaybeAsyncEqualityComparisonOrComparer<TElement> | undefined): AsyncSequence<TElement> { distinct(equater?: MaybeAsyncEqualityComparison<TElement> | undefined): AsyncSequence<TElement> {
return this.#sequence.distinct(equater); return this.#sequence.distinct(equater);
} }
distinctBy<TBy>(selector: MaybeAsyncConverter<TElement, TBy>, equater?: MaybeAsyncEqualityComparisonOrComparer<TBy> | undefined): AsyncSequence<TElement> { distinctBy<TBy>(selector: MaybeAsyncConverter<TElement, TBy>, equater?: MaybeAsyncEqualityComparison<TBy> | undefined): AsyncSequence<TElement> {
return this.#sequence.distinctBy(selector, equater); return this.#sequence.distinctBy(selector, equater);
} }
union(sequence: MaybeAsyncIterable<TElement>, equater?: MaybeAsyncEqualityComparisonOrComparer<TElement> | undefined): AsyncSequence<TElement> { union(sequence: MaybeAsyncIterable<TElement>, equater?: MaybeAsyncEqualityComparison<TElement> | undefined): AsyncSequence<TElement> {
return this.#sequence.union(wrap(sequence), equater); return this.#sequence.union(wrap(sequence), equater);
} }
unionBy<TBy>(sequence: MaybeAsyncIterable<TElement>, selector: MaybeAsyncConverter<TElement, TBy>, equater?: MaybeAsyncEqualityComparisonOrComparer<TBy> | undefined): AsyncSequence<TElement> { unionBy<TBy>(sequence: MaybeAsyncIterable<TElement>, selector: MaybeAsyncConverter<TElement, TBy>, equater?: MaybeAsyncEqualityComparison<TBy> | undefined): AsyncSequence<TElement> {
return this.#sequence.unionBy(wrap(sequence), selector, equater); return this.#sequence.unionBy(wrap(sequence), selector, equater);
} }
except(sequence: MaybeAsyncIterable<TElement>, equater?: MaybeAsyncEqualityComparisonOrComparer<TElement> | undefined): AsyncSequence<TElement> { except(sequence: MaybeAsyncIterable<TElement>, equater?: MaybeAsyncEqualityComparison<TElement> | undefined): AsyncSequence<TElement> {
return this.#sequence.except(wrap(sequence), equater); return this.#sequence.except(wrap(sequence), equater);
} }
exceptBy<TBy>(sequence: MaybeAsyncIterable<TElement>, selector: MaybeAsyncConverter<TElement, TBy>, equater?: MaybeAsyncEqualityComparisonOrComparer<TBy> | undefined): AsyncSequence<TElement> { exceptBy<TBy>(sequence: MaybeAsyncIterable<TElement>, selector: MaybeAsyncConverter<TElement, TBy>, equater?: MaybeAsyncEqualityComparison<TBy> | undefined): AsyncSequence<TElement> {
return this.#sequence.exceptBy(wrap(sequence), selector, equater); return this.#sequence.exceptBy(wrap(sequence), selector, equater);
} }
intersect(sequence: MaybeAsyncIterable<TElement>, equater?: MaybeAsyncEqualityComparisonOrComparer<TElement> | undefined): AsyncSequence<TElement> { intersect(sequence: MaybeAsyncIterable<TElement>, equater?: MaybeAsyncEqualityComparison<TElement> | undefined): AsyncSequence<TElement> {
return this.#sequence.intersect(wrap(sequence), equater); return this.#sequence.intersect(wrap(sequence), equater);
} }
intersectBy<TBy>(sequence: MaybeAsyncIterable<TElement>, selector: MaybeAsyncConverter<TElement, TBy>, equater?: MaybeAsyncEqualityComparisonOrComparer<TBy> | undefined): AsyncSequence<TElement> { intersectBy<TBy>(sequence: MaybeAsyncIterable<TElement>, selector: MaybeAsyncConverter<TElement, TBy>, equater?: MaybeAsyncEqualityComparison<TBy> | undefined): AsyncSequence<TElement> {
return this.#sequence.intersectBy(wrap(sequence), selector, equater); return this.#sequence.intersectBy(wrap(sequence), selector, equater);
} }
@@ -1026,10 +1024,6 @@ export class DelegatedAsyncSequence<TElement> extends AsyncSequenceMarker implem
return this.#sequence.zip(wrap(sequence)); return this.#sequence.zip(wrap(sequence));
} }
cartesianProduct<TOther>(sequence: MaybeAsyncIterable<TOther>): AsyncSequence<[TElement, TOther]> {
return this.#sequence.cartesianProduct(wrap(sequence));
}
indexed(): AsyncSequence<[number, TElement]> { indexed(): AsyncSequence<[number, TElement]> {
return this.#sequence.indexed(); return this.#sequence.indexed();
} }
@@ -1241,20 +1235,6 @@ export class WrappedObjectAsync<T> extends BaseAsyncSequence<T> {
} }
} }
export class WrappedPromise<T> extends BaseAsyncSequence<T> {
readonly #promise: Promise<MaybeAsyncIterable<T>>;
constructor(promise: Promise<MaybeAsyncIterable<T>>) {
super();
this.#promise = promise;
}
override async *iterator() {
yield* await this.#promise;
}
}
export class WrappedArrayAsync<T> extends BaseAsyncSequence<T> { export class WrappedArrayAsync<T> extends BaseAsyncSequence<T> {
readonly #array: ReadonlyArray<MaybePromiseLike<T>>; readonly #array: ReadonlyArray<MaybePromiseLike<T>>;
@@ -1401,9 +1381,9 @@ export class ConcatAsyncSequence<T> extends BaseAsyncSequence<T> {
class DistinctAsyncSequence<T> extends BaseAsyncSequence<T> { class DistinctAsyncSequence<T> extends BaseAsyncSequence<T> {
readonly #sequence: AsyncSequence<T>; readonly #sequence: AsyncSequence<T>;
readonly #equater: MaybeAsyncEqualityComparisonOrComparer<T> | undefined; readonly #equater: MaybeAsyncEqualityComparison<T> | undefined;
constructor(sequence: AsyncSequence<T>, equater?: MaybeAsyncEqualityComparisonOrComparer<T>) { constructor(sequence: AsyncSequence<T>, equater?: MaybeAsyncEqualityComparison<T>) {
super(); super();
this.#sequence = sequence; this.#sequence = sequence;
@@ -1424,9 +1404,9 @@ class DistinctAsyncSequence<T> extends BaseAsyncSequence<T> {
class DistinctByAsyncSequence<T, U> extends BaseAsyncSequence<T> { class DistinctByAsyncSequence<T, U> extends BaseAsyncSequence<T> {
readonly #sequence: AsyncSequence<T>; readonly #sequence: AsyncSequence<T>;
readonly #selector: MaybeAsyncConverter<T, U>; readonly #selector: MaybeAsyncConverter<T, U>;
readonly #equater: MaybeAsyncEqualityComparisonOrComparer<U> | undefined; readonly #equater: MaybeAsyncEqualityComparison<U> | undefined;
constructor(sequence: AsyncSequence<T>, selector: MaybeAsyncConverter<T, U>, equater?: MaybeAsyncEqualityComparisonOrComparer<U>) { constructor(sequence: AsyncSequence<T>, selector: MaybeAsyncConverter<T, U>, equater?: MaybeAsyncEqualityComparison<U>) {
super(); super();
this.#sequence = sequence; this.#sequence = sequence;
@@ -1707,7 +1687,7 @@ class TakeAsyncSequence<T> extends BaseAsyncSequence<T> {
return; return;
} }
yield next.value; yield next.value as T;
i--; i--;
} }
} }
@@ -1727,13 +1707,13 @@ class OrderByAsyncSequence<T, U> extends BaseOrderedAsyncSequence<T> {
class ThenOrderAsyncSequence<T> extends BaseOrderedAsyncSequence<T> { class ThenOrderAsyncSequence<T> extends BaseOrderedAsyncSequence<T> {
constructor(sequence: OrderedAsyncSequence<T>, descending: boolean, sorter?: MaybeAsyncComparisonOrComparer<T>) { constructor(sequence: OrderedAsyncSequence<T>, descending: boolean, sorter?: MaybeAsyncComparisonOrComparer<T>) {
super(sequence, combineAsyncComparers([sequence.comparer, sorter]), descending); super(sequence, combineNullableAsyncComparers([sequence.comparer, sorter]), descending);
} }
} }
class ThenOrderByAsyncSequence<T, U> extends BaseOrderedAsyncSequence<T> { class ThenOrderByAsyncSequence<T, U> extends BaseOrderedAsyncSequence<T> {
constructor(sequence: OrderedAsyncSequence<T>, descending: boolean, selector: MaybeAsyncConverter<T, U>, sorter?: MaybeAsyncComparisonOrComparer<U>) { constructor(sequence: OrderedAsyncSequence<T>, descending: boolean, selector: MaybeAsyncConverter<T, U>, sorter?: MaybeAsyncComparisonOrComparer<U>) {
super(sequence, combineAsyncComparers([sequence.comparer, createAsyncComparerUsing(selector, sorter)]), descending); super(sequence, combineNullableAsyncComparers([sequence.comparer, createAsyncComparerUsing(selector, sorter)]), descending);
} }
} }
@@ -1843,52 +1823,12 @@ class ZippedAsyncSequence<T, U> extends BaseAsyncSequence<[T, U]> {
} }
} }
export class CartesianProductAsyncSequence<T, U> extends BaseAsyncSequence<[T, U]> {
readonly #first: AsyncSequence<T>;
readonly #second: AsyncSequence<U>;
constructor(first: AsyncSequence<T>, second: AsyncSequence<U>) {
super();
this.#first = first;
this.#second = second;
}
override async nonEnumeratedCount() {
const n1 = await this.#first.nonEnumeratedCount();
if (n1 < 0) {
return -1;
}
const n2 = await this.#second.nonEnumeratedCount();
if (n2 < 0) {
return -1;
}
return n1 * n2;
}
override async maxCount() {
return await this.#first.maxCount() * await this.#second.maxCount();
}
override async *iterator() {
for await (const firstObj of this.#first) {
for await (const secondObj of this.#second) {
yield [firstObj, secondObj] as [T, U];
}
}
}
}
class UnionAsyncSequence<T> extends BaseAsyncSequence<T> { class UnionAsyncSequence<T> extends BaseAsyncSequence<T> {
readonly #first: AsyncSequence<T>; readonly #first: AsyncSequence<T>;
readonly #second: AsyncSequence<T>; readonly #second: AsyncSequence<T>;
readonly #equater: MaybeAsyncEqualityComparisonOrComparer<T> | undefined; readonly #equater: MaybeAsyncEqualityComparison<T> | undefined;
constructor(first: AsyncSequence<T>, second: AsyncSequence<T>, equater?: MaybeAsyncEqualityComparisonOrComparer<T>) { constructor(first: AsyncSequence<T>, second: AsyncSequence<T>, equater?: MaybeAsyncEqualityComparison<T>) {
super(); super();
this.#first = first; this.#first = first;
@@ -1919,9 +1859,9 @@ class UnionByAsyncSequence<T, U> extends BaseAsyncSequence<T> {
readonly #first: AsyncSequence<T>; readonly #first: AsyncSequence<T>;
readonly #second: AsyncSequence<T>; readonly #second: AsyncSequence<T>;
readonly #selector: MaybeAsyncConverter<T, U>; readonly #selector: MaybeAsyncConverter<T, U>;
readonly #equater: MaybeAsyncEqualityComparisonOrComparer<U> | undefined; readonly #equater: MaybeAsyncEqualityComparison<U> | undefined;
constructor(first: AsyncSequence<T>, second: AsyncSequence<T>, selector: MaybeAsyncConverter<T, U>, equater?: MaybeAsyncEqualityComparisonOrComparer<U>) { constructor(first: AsyncSequence<T>, second: AsyncSequence<T>, selector: MaybeAsyncConverter<T, U>, equater?: MaybeAsyncEqualityComparison<U>) {
super(); super();
this.#first = first; this.#first = first;
@@ -1952,9 +1892,9 @@ class UnionByAsyncSequence<T, U> extends BaseAsyncSequence<T> {
class ExceptAsyncSequence<T> extends BaseAsyncSequence<T> { class ExceptAsyncSequence<T> extends BaseAsyncSequence<T> {
readonly #first: AsyncSequence<T>; readonly #first: AsyncSequence<T>;
readonly #second: AsyncSequence<T>; readonly #second: AsyncSequence<T>;
readonly #equater: MaybeAsyncEqualityComparisonOrComparer<T> | undefined; readonly #equater: MaybeAsyncEqualityComparison<T> | undefined;
constructor(first: AsyncSequence<T>, second: AsyncSequence<T>, equater?: MaybeAsyncEqualityComparisonOrComparer<T>) { constructor(first: AsyncSequence<T>, second: AsyncSequence<T>, equater?: MaybeAsyncEqualityComparison<T>) {
super(); super();
this.#first = first; this.#first = first;
@@ -1983,9 +1923,9 @@ class ExceptByAsyncSequence<T, U> extends BaseAsyncSequence<T> {
readonly #first: AsyncSequence<T>; readonly #first: AsyncSequence<T>;
readonly #second: AsyncSequence<T>; readonly #second: AsyncSequence<T>;
readonly #selector: MaybeAsyncConverter<T, U>; readonly #selector: MaybeAsyncConverter<T, U>;
readonly #equater: MaybeAsyncEqualityComparisonOrComparer<U> | undefined; readonly #equater: MaybeAsyncEqualityComparison<U> | undefined;
constructor(first: AsyncSequence<T>, second: AsyncSequence<T>, selector: MaybeAsyncConverter<T, U>, equater?: MaybeAsyncEqualityComparisonOrComparer<U>) { constructor(first: AsyncSequence<T>, second: AsyncSequence<T>, selector: MaybeAsyncConverter<T, U>, equater?: MaybeAsyncEqualityComparison<U>) {
super(); super();
this.#first = first; this.#first = first;
@@ -2014,9 +1954,9 @@ class ExceptByAsyncSequence<T, U> extends BaseAsyncSequence<T> {
class IntersectAsyncSequence<T> extends BaseAsyncSequence<T> { class IntersectAsyncSequence<T> extends BaseAsyncSequence<T> {
readonly #first: AsyncSequence<T>; readonly #first: AsyncSequence<T>;
readonly #second: AsyncSequence<T>; readonly #second: AsyncSequence<T>;
readonly #equater: MaybeAsyncEqualityComparisonOrComparer<T> | undefined; readonly #equater: MaybeAsyncEqualityComparison<T> | undefined;
constructor(first: AsyncSequence<T>, second: AsyncSequence<T>, equater?: MaybeAsyncEqualityComparisonOrComparer<T>) { constructor(first: AsyncSequence<T>, second: AsyncSequence<T>, equater?: MaybeAsyncEqualityComparison<T>) {
super(); super();
this.#first = first; this.#first = first;
@@ -2045,9 +1985,9 @@ class IntersectByAsyncSequence<T, U> extends BaseAsyncSequence<T> {
readonly #first: AsyncSequence<T>; readonly #first: AsyncSequence<T>;
readonly #second: AsyncSequence<T>; readonly #second: AsyncSequence<T>;
readonly #selector: MaybeAsyncConverter<T, U>; readonly #selector: MaybeAsyncConverter<T, U>;
readonly #equater: MaybeAsyncEqualityComparisonOrComparer<U> | undefined; readonly #equater: MaybeAsyncEqualityComparison<U> | undefined;
constructor(first: AsyncSequence<T>, second: AsyncSequence<T>, selector: MaybeAsyncConverter<T, U>, equater?: MaybeAsyncEqualityComparisonOrComparer<U>) { constructor(first: AsyncSequence<T>, second: AsyncSequence<T>, selector: MaybeAsyncConverter<T, U>, equater?: MaybeAsyncEqualityComparison<U>) {
super(); super();
this.#first = first; this.#first = first;
@@ -2099,9 +2039,9 @@ class GroupByAsyncSequence<TElement, TKey, TResult> extends BaseAsyncSequence<Gr
readonly #sequence: AsyncSequence<TElement>; readonly #sequence: AsyncSequence<TElement>;
readonly #keySelector: MaybeAsyncConverter<TElement, TKey>; readonly #keySelector: MaybeAsyncConverter<TElement, TKey>;
readonly #elementSelector: MaybeAsyncConverter<TElement, TResult>; readonly #elementSelector: MaybeAsyncConverter<TElement, TResult>;
readonly #keyComparer: MaybeAsyncEqualityComparisonOrComparer<TKey> | undefined; readonly #keyComparer: MaybeAsyncEqualityComparison<TKey> | undefined;
constructor(sequence: AsyncSequence<TElement>, keySelector: MaybeAsyncConverter<TElement, TKey>, elementSelector?: MaybeAsyncConverter<TElement, TResult>, keyComparer?: MaybeAsyncEqualityComparisonOrComparer<TKey>) { constructor(sequence: AsyncSequence<TElement>, keySelector: MaybeAsyncConverter<TElement, TKey>, elementSelector?: MaybeAsyncConverter<TElement, TResult>, keyComparer?: MaybeAsyncEqualityComparison<TKey>) {
super(); super();
this.#sequence = sequence; this.#sequence = sequence;
@@ -2172,9 +2112,9 @@ class JoinAsyncSequence<TOuter, TInner, TKey, TResult> extends BaseAsyncSequence
readonly #firstKeySelector: MaybeAsyncConverter<TOuter, TKey>; readonly #firstKeySelector: MaybeAsyncConverter<TOuter, TKey>;
readonly #secondKeySelector: MaybeAsyncConverter<TInner, TKey>; readonly #secondKeySelector: MaybeAsyncConverter<TInner, TKey>;
readonly #resultSelector: MaybeAsyncBiConverter<TOuter, TInner, TResult>; readonly #resultSelector: MaybeAsyncBiConverter<TOuter, TInner, TResult>;
readonly #keyComparer: AsyncEqualityComparer<TKey>; readonly #keyComparer: MaybeAsyncEqualityComparison<TKey>;
constructor(first: AsyncSequence<TOuter>, second: AsyncSequence<TInner>, firstKeySelector: MaybeAsyncConverter<TOuter, TKey>, secondKeySelector: MaybeAsyncConverter<TInner, TKey>, resultSelector?: MaybeAsyncBiConverter<TOuter, TInner, TResult>, keyComparer?: MaybeAsyncEqualityComparisonOrComparer<TKey>) { constructor(first: AsyncSequence<TOuter>, second: AsyncSequence<TInner>, firstKeySelector: MaybeAsyncConverter<TOuter, TKey>, secondKeySelector: MaybeAsyncConverter<TInner, TKey>, resultSelector?: MaybeAsyncBiConverter<TOuter, TInner, TResult>, keyComparer?: MaybeAsyncEqualityComparison<TKey>) {
super(); super();
this.#first = first; this.#first = first;
@@ -2182,7 +2122,7 @@ class JoinAsyncSequence<TOuter, TInner, TKey, TResult> extends BaseAsyncSequence
this.#firstKeySelector = firstKeySelector; this.#firstKeySelector = firstKeySelector;
this.#secondKeySelector = secondKeySelector; this.#secondKeySelector = secondKeySelector;
this.#resultSelector = resultSelector ?? identity as MaybeAsyncBiConverter<TOuter, TInner, TResult>; this.#resultSelector = resultSelector ?? identity as MaybeAsyncBiConverter<TOuter, TInner, TResult>;
this.#keyComparer = keyComparer ? asAsyncEqualityComparer(keyComparer) : defaultAsyncEqualityComparer; this.#keyComparer = keyComparer ?? strictEquals;
} }
override async *iterator() { override async *iterator() {
@@ -2192,7 +2132,7 @@ class JoinAsyncSequence<TOuter, TInner, TKey, TResult> extends BaseAsyncSequence
for await (const secondObj of this.#second) { for await (const secondObj of this.#second) {
const secondKey = await this.#secondKeySelector(secondObj); const secondKey = await this.#secondKeySelector(secondObj);
if (await this.#keyComparer.equals(firstKey, secondKey)) { if (await this.#keyComparer(firstKey, secondKey)) {
yield await this.#resultSelector(firstObj, secondObj); yield await this.#resultSelector(firstObj, secondObj);
} }
} }
@@ -2206,9 +2146,9 @@ class GroupJoinAsyncSequence<TOuter, TInner, TKey, TResult> extends BaseAsyncSeq
readonly #firstKeySelector: MaybeAsyncConverter<TOuter, TKey>; readonly #firstKeySelector: MaybeAsyncConverter<TOuter, TKey>;
readonly #secondKeySelector: MaybeAsyncConverter<TInner, TKey>; readonly #secondKeySelector: MaybeAsyncConverter<TInner, TKey>;
readonly #resultSelector: MaybeAsyncBiConverter<TOuter, MaybeAsyncIterable<TInner>, TResult>; readonly #resultSelector: MaybeAsyncBiConverter<TOuter, MaybeAsyncIterable<TInner>, TResult>;
readonly #keyComparer: AsyncEqualityComparer<TKey>; readonly #keyComparer: MaybeAsyncEqualityComparison<TKey>;
constructor(first: AsyncSequence<TOuter>, second: AsyncSequence<TInner>, firstKeySelector: MaybeAsyncConverter<TOuter, TKey>, secondKeySelector: MaybeAsyncConverter<TInner, TKey>, resultSelector?: MaybeAsyncBiConverter<TOuter, MaybeAsyncIterable<TInner>, TResult>, keyComparer?: MaybeAsyncEqualityComparisonOrComparer<TKey>) { constructor(first: AsyncSequence<TOuter>, second: AsyncSequence<TInner>, firstKeySelector: MaybeAsyncConverter<TOuter, TKey>, secondKeySelector: MaybeAsyncConverter<TInner, TKey>, resultSelector?: MaybeAsyncBiConverter<TOuter, MaybeAsyncIterable<TInner>, TResult>, keyComparer?: MaybeAsyncEqualityComparison<TKey>) {
super(); super();
this.#first = first; this.#first = first;
@@ -2216,7 +2156,7 @@ class GroupJoinAsyncSequence<TOuter, TInner, TKey, TResult> extends BaseAsyncSeq
this.#firstKeySelector = firstKeySelector; this.#firstKeySelector = firstKeySelector;
this.#secondKeySelector = secondKeySelector; this.#secondKeySelector = secondKeySelector;
this.#resultSelector = resultSelector ?? GroupJoinAsyncSequence.#defaultResultSelector as MaybeAsyncBiConverter<TOuter, MaybeAsyncIterable<TInner>, TResult>; this.#resultSelector = resultSelector ?? GroupJoinAsyncSequence.#defaultResultSelector as MaybeAsyncBiConverter<TOuter, MaybeAsyncIterable<TInner>, TResult>;
this.#keyComparer = keyComparer ? asAsyncEqualityComparer(keyComparer) : defaultAsyncEqualityComparer; this.#keyComparer = keyComparer ?? strictEquals;
} }
static #defaultResultSelector<TOuter, TInner>(first: TOuter, second: AsyncSequence<TInner>) { static #defaultResultSelector<TOuter, TInner>(first: TOuter, second: AsyncSequence<TInner>) {
@@ -2231,7 +2171,7 @@ class GroupJoinAsyncSequence<TOuter, TInner, TKey, TResult> extends BaseAsyncSeq
for await (const secondObj of this.#second) { for await (const secondObj of this.#second) {
const secondKey = await this.#secondKeySelector(secondObj); const secondKey = await this.#secondKeySelector(secondObj);
if (await this.#keyComparer.equals(firstKey, secondKey)) { if (await this.#keyComparer(firstKey, secondKey)) {
secondObjs.push(secondObj); secondObjs.push(secondObj);
} }
} }
@@ -2245,22 +2185,22 @@ class RemoveAsyncSequence<T> extends BaseAsyncSequence<T> {
readonly #sequence: AsyncSequence<T>; readonly #sequence: AsyncSequence<T>;
readonly #obj: T; readonly #obj: T;
readonly #all: boolean; readonly #all: boolean;
readonly #equater: AsyncEqualityComparer<T>; readonly #equater: MaybeAsyncEqualityComparison<T>;
constructor(sequence: AsyncSequence<T>, obj: T, all?: boolean, equater?: MaybeAsyncEqualityComparisonOrComparer<T>) { constructor(sequence: AsyncSequence<T>, obj: T, all?: boolean, equater?: MaybeAsyncEqualityComparison<T>) {
super(); super();
this.#sequence = sequence; this.#sequence = sequence;
this.#obj = obj; this.#obj = obj;
this.#all = all ?? false; this.#all = all ?? false;
this.#equater = equater ? asAsyncEqualityComparer(equater) : defaultAsyncEqualityComparer; this.#equater = equater ?? strictEquals;
} }
override async *iterator() { override async *iterator() {
let gotOne = false; let gotOne = false;
for await (const obj of this.#sequence) { for await (const obj of this.#sequence) {
if (await this.#equater.equals(this.#obj, obj)) { if (await this.#equater(this.#obj, obj)) {
if (this.#all) { if (this.#all) {
continue; continue;
} }
@@ -2304,13 +2244,13 @@ class CacheAsyncSequence<T> extends BaseAsyncSequence<T> {
class PartitionAsyncSequence<T> extends BaseAsyncSequence<AsyncSequence<T>> { class PartitionAsyncSequence<T> extends BaseAsyncSequence<AsyncSequence<T>> {
readonly #sequence: AsyncSequence<T>; readonly #sequence: AsyncSequence<T>;
readonly #equater: MaybeAsyncEqualityComparisonOrComparer<T> | undefined; readonly #equater: MaybeAsyncEqualityComparison<T>;
constructor(sequence: AsyncSequence<T>, equater: MaybeAsyncEqualityComparisonOrComparer<T> | undefined) { constructor(sequence: AsyncSequence<T>, equater: MaybeAsyncEqualityComparison<T> | undefined) {
super(); super();
this.#sequence = sequence; this.#sequence = sequence;
this.#equater = equater; this.#equater = equater ?? strictEquals;
} }
override async *iterator() { override async *iterator() {
@@ -2335,14 +2275,14 @@ class PartitionAsyncSequence<T> extends BaseAsyncSequence<AsyncSequence<T>> {
class PartitionByAsyncSequence<TElement, TBy> extends BaseAsyncSequence<AsyncSequence<TElement>> { class PartitionByAsyncSequence<TElement, TBy> extends BaseAsyncSequence<AsyncSequence<TElement>> {
readonly #sequence: AsyncSequence<TElement>; readonly #sequence: AsyncSequence<TElement>;
readonly #selector: MaybeAsyncConverter<TElement, TBy>; readonly #selector: MaybeAsyncConverter<TElement, TBy>;
readonly #equater: MaybeAsyncEqualityComparisonOrComparer<TBy> | undefined; readonly #equater: MaybeAsyncEqualityComparison<TBy>;
constructor(sequence: AsyncSequence<TElement>, selector: MaybeAsyncConverter<TElement, TBy>, equater: MaybeAsyncEqualityComparisonOrComparer<TBy> | undefined) { constructor(sequence: AsyncSequence<TElement>, selector: MaybeAsyncConverter<TElement, TBy>, equater: MaybeAsyncEqualityComparison<TBy> | undefined) {
super(); super();
this.#sequence = sequence; this.#sequence = sequence;
this.#selector = selector; this.#selector = selector;
this.#equater = equater; this.#equater = equater ?? strictEquals;
} }
override async *iterator() { override async *iterator() {

View File

@@ -2,17 +2,13 @@ import { wrap as wrapSync } from "../sync/index.js";
import { Sequence } from "../sync/types.js"; import { Sequence } from "../sync/types.js";
import { MaybeAsyncGenerator, MaybeAsyncIterable, MaybePromiseLike } from "../types.js"; import { MaybeAsyncGenerator, MaybeAsyncIterable, MaybePromiseLike } from "../types.js";
import { isAsyncIterable } from "../utils.js"; import { isAsyncIterable } from "../utils.js";
import { WrappedSequence, WrappedAsyncIterable, WrappedObjectAsync, WrappedArrayAsync, WrappedArrayLikeAsync, FunctionAsyncSequence, GeneratorAsyncSequence, RangeAsyncSequence, RepeatForeverAsyncSequence, RepeatAsyncSequence, AsyncSequenceMarker, EMPTY, ConcatAsyncSequence, WrappedPromise } from "./impl.js"; import { WrappedSequence, WrappedAsyncIterable, WrappedObjectAsync, WrappedArrayAsync, WrappedArrayLikeAsync, FunctionAsyncSequence, GeneratorAsyncSequence, RangeAsyncSequence, RepeatForeverAsyncSequence, RepeatAsyncSequence, AsyncSequenceMarker, EMPTY, ConcatAsyncSequence } from "./impl.js";
import { AsyncSequence } from "./types.js"; import { AsyncSequence } from "./types.js";
export function asAsync<T>(sequence: Sequence<MaybePromiseLike<T>>): AsyncSequence<T> { export function asAsync<T>(sequence: Sequence<MaybePromiseLike<T>>): AsyncSequence<T> {
return new WrappedSequence(sequence); return new WrappedSequence(sequence);
} }
export function wrapPromise<T>(promise: Promise<MaybeAsyncIterable<T>>): AsyncSequence<T> {
return new WrappedPromise(promise);
}
export function wrap<T>(iterable: MaybeAsyncIterable<MaybePromiseLike<T>>): AsyncSequence<T> { export function wrap<T>(iterable: MaybeAsyncIterable<MaybePromiseLike<T>>): AsyncSequence<T> {
if (isAsyncSequence<T>(iterable)) { if (isAsyncSequence<T>(iterable)) {
return iterable; return iterable;

View File

@@ -1,11 +1,10 @@
import { Collector } from "../collector/types.js"; import { Collector } from "../collector/types.js";
import { MaybeAsyncComparisonOrComparer, AsyncComparer } from "../comparer/types.js"; import { MaybeAsyncComparisonOrComparer, AsyncComparer } from "../comparer/types.js";
import { MaybeAsyncEqualityComparisonOrComparer } from "../equality-comparer/types.js"; import { MaybeAsyncEqualityComparison } from "../equality-comparer/types.js";
import { AsyncRandomOptions } from "../random/types.js"; import { AsyncRandomOptions } from "../random/types.js";
import { MaybeAsyncAnyPredicate, MaybeAsyncConverter, MaybeAsyncBiConverter, MaybeAsyncAccumulator, MaybeAsyncAction, MaybeAsyncFunction, MaybePromise, MaybeAsyncIterable } from "../types.js"; import { MaybeAsyncAnyPredicate, MaybeAsyncConverter, MaybeAsyncBiConverter, MaybeAsyncAccumulator, MaybeAsyncAction, MaybeAsyncFunction, MaybePromise, MaybeAsyncIterable } from "../types.js";
export type AsyncSequencePipeline<TElement, TResult> = MaybeAsyncFunction<(sequence: AsyncSequence<TElement>) => TResult>; export type AsyncSequencePipeline<TElement, TResult> = MaybeAsyncFunction<(sequence: AsyncSequence<TElement>) => TResult>;
export type AsyncSequenceElement<TAsyncSequence extends AsyncSequence<any>> = TAsyncSequence extends AsyncSequence<infer TElement> ? TElement : never;
export interface AsyncSequence<TElement> extends AsyncIterable<TElement> { export interface AsyncSequence<TElement> extends AsyncIterable<TElement> {
iterator(): AsyncIterator<TElement>; iterator(): AsyncIterator<TElement>;
@@ -23,24 +22,24 @@ export interface AsyncSequence<TElement> extends AsyncIterable<TElement> {
where<TFiltered extends TElement>(predicate: MaybeAsyncAnyPredicate<TElement>): AsyncSequence<TFiltered>; where<TFiltered extends TElement>(predicate: MaybeAsyncAnyPredicate<TElement>): AsyncSequence<TFiltered>;
where(predicate: MaybeAsyncAnyPredicate<TElement>): AsyncSequence<TElement>; where(predicate: MaybeAsyncAnyPredicate<TElement>): AsyncSequence<TElement>;
groupBy<TKey>(keySelector: MaybeAsyncConverter<TElement, TKey>, elementSelector?: undefined, keyComparer?: MaybeAsyncEqualityComparisonOrComparer<TKey>): AsyncSequence<GroupedAsyncSequence<TKey, TElement>>; groupBy<TKey>(keySelector: MaybeAsyncConverter<TElement, TKey>, elementSelector?: undefined, keyComparer?: MaybeAsyncEqualityComparison<TKey>): AsyncSequence<GroupedAsyncSequence<TKey, TElement>>;
groupBy<TKey, TResult>(keySelector: MaybeAsyncConverter<TElement, TKey>, elementSelector: MaybeAsyncConverter<TElement, TResult>, keyComparer?: MaybeAsyncEqualityComparisonOrComparer<TKey>): AsyncSequence<GroupedAsyncSequence<TKey, TResult>>; groupBy<TKey, TResult>(keySelector: MaybeAsyncConverter<TElement, TKey>, elementSelector: MaybeAsyncConverter<TElement, TResult>, keyComparer?: MaybeAsyncEqualityComparison<TKey>): AsyncSequence<GroupedAsyncSequence<TKey, TResult>>;
join<TOther, TKey>(sequence: MaybeAsyncIterable<TOther>, firstKeySelector: MaybeAsyncConverter<TElement, TKey>, secondKeySelector: MaybeAsyncConverter<TOther, TKey>, resultSelector?: undefined, keyComparer?: MaybeAsyncEqualityComparisonOrComparer<TKey>): AsyncSequence<[TElement, TOther]>; join<TOther, TKey>(sequence: MaybeAsyncIterable<TOther>, firstKeySelector: MaybeAsyncConverter<TElement, TKey>, secondKeySelector: MaybeAsyncConverter<TOther, TKey>, resultSelector?: undefined, keyComparer?: MaybeAsyncEqualityComparison<TKey>): AsyncSequence<[TElement, TOther]>;
join<TOther, TKey, TResult>(sequence: MaybeAsyncIterable<TOther>, firstKeySelector: MaybeAsyncConverter<TElement, TKey>, secondKeySelector: MaybeAsyncConverter<TOther, TKey>, resultSelector: MaybeAsyncBiConverter<TElement, TOther, TResult>, keyComparer?: MaybeAsyncEqualityComparisonOrComparer<TKey>): AsyncSequence<TResult>; join<TOther, TKey, TResult>(sequence: MaybeAsyncIterable<TOther>, firstKeySelector: MaybeAsyncConverter<TElement, TKey>, secondKeySelector: MaybeAsyncConverter<TOther, TKey>, resultSelector: MaybeAsyncBiConverter<TElement, TOther, TResult>, keyComparer?: MaybeAsyncEqualityComparison<TKey>): AsyncSequence<TResult>;
groupJoin<TOther, TKey>(sequence: MaybeAsyncIterable<TOther>, firstKeySelector: MaybeAsyncConverter<TElement, TKey>, secondKeySelector: MaybeAsyncConverter<TOther, TKey>, resultSelector?: undefined, keyComparer?: MaybeAsyncEqualityComparisonOrComparer<TKey>): AsyncSequence<GroupedAsyncSequence<TElement, TOther>>; groupJoin<TOther, TKey>(sequence: MaybeAsyncIterable<TOther>, firstKeySelector: MaybeAsyncConverter<TElement, TKey>, secondKeySelector: MaybeAsyncConverter<TOther, TKey>, resultSelector?: undefined, keyComparer?: MaybeAsyncEqualityComparison<TKey>): AsyncSequence<GroupedAsyncSequence<TElement, TOther>>;
groupJoin<TOther, TKey, TResult>(sequence: MaybeAsyncIterable<TOther>, firstKeySelector: MaybeAsyncConverter<TElement, TKey>, secondKeySelector: MaybeAsyncConverter<TOther, TKey>, resultSelector: MaybeAsyncBiConverter<TElement, MaybeAsyncIterable<TOther>, TResult>, keyComparer?: MaybeAsyncEqualityComparisonOrComparer<TKey>): AsyncSequence<TResult>; groupJoin<TOther, TKey, TResult>(sequence: MaybeAsyncIterable<TOther>, firstKeySelector: MaybeAsyncConverter<TElement, TKey>, secondKeySelector: MaybeAsyncConverter<TOther, TKey>, resultSelector: MaybeAsyncBiConverter<TElement, MaybeAsyncIterable<TOther>, TResult>, keyComparer?: MaybeAsyncEqualityComparison<TKey>): AsyncSequence<TResult>;
contains(obj: TElement, equater?: MaybeAsyncEqualityComparisonOrComparer<TElement>): Promise<boolean>; contains(obj: TElement, equater?: MaybeAsyncEqualityComparison<TElement>): Promise<boolean>;
sequenceEquals(sequence: MaybeAsyncIterable<TElement>, equater?: MaybeAsyncEqualityComparisonOrComparer<TElement>): Promise<boolean>; sequenceEquals(sequence: MaybeAsyncIterable<TElement>, equater?: MaybeAsyncEqualityComparison<TElement>): Promise<boolean>;
append(obj: TElement): AsyncSequence<TElement>; append(obj: TElement): AsyncSequence<TElement>;
prepend(obj: TElement): AsyncSequence<TElement>; prepend(obj: TElement): AsyncSequence<TElement>;
remove(obj: TElement, all?: boolean, equater?: MaybeAsyncEqualityComparisonOrComparer<TElement>): AsyncSequence<TElement>; remove(obj: TElement, all?: boolean, equater?: MaybeAsyncEqualityComparison<TElement>): AsyncSequence<TElement>;
concat(...sequences: MaybeAsyncIterable<TElement>[]): AsyncSequence<TElement>; concat(...sequences: MaybeAsyncIterable<TElement>[]): AsyncSequence<TElement>;
@@ -69,26 +68,26 @@ export interface AsyncSequence<TElement> extends AsyncIterable<TElement> {
bounds(comparer?: MaybeAsyncComparisonOrComparer<TElement>): Promise<[min: TElement, max: TElement]>; bounds(comparer?: MaybeAsyncComparisonOrComparer<TElement>): Promise<[min: TElement, max: TElement]>;
boundsBy<TBy>(selector: MaybeAsyncConverter<TElement, TBy>, comparer?: MaybeAsyncComparisonOrComparer<TBy>): Promise<[min: TElement, max: TElement]>; boundsBy<TBy>(selector: MaybeAsyncConverter<TElement, TBy>, comparer?: MaybeAsyncComparisonOrComparer<TBy>): Promise<[min: TElement, max: TElement]>;
order(comparer?: MaybeAsyncComparisonOrComparer<TElement>): OrderedAsyncSequence<TElement>; order(comparer?: MaybeAsyncComparisonOrComparer<TElement>): AsyncSequence<TElement>;
orderBy<TBy>(selector: MaybeAsyncConverter<TElement, TBy>, comparer?: MaybeAsyncComparisonOrComparer<TBy>): OrderedAsyncSequence<TElement>; orderBy<TBy>(selector: MaybeAsyncConverter<TElement, TBy>, comparer?: MaybeAsyncComparisonOrComparer<TBy>): AsyncSequence<TElement>;
orderDescending(comparer?: MaybeAsyncComparisonOrComparer<TElement>): OrderedAsyncSequence<TElement>; orderDescending(comparer?: MaybeAsyncComparisonOrComparer<TElement>): AsyncSequence<TElement>;
orderByDescending<TBy>(selector: MaybeAsyncConverter<TElement, TBy>, comparer?: MaybeAsyncComparisonOrComparer<TBy>): OrderedAsyncSequence<TElement>; orderByDescending<TBy>(selector: MaybeAsyncConverter<TElement, TBy>, comparer?: MaybeAsyncComparisonOrComparer<TBy>): AsyncSequence<TElement>;
partition(equater?: MaybeAsyncEqualityComparisonOrComparer<TElement>): AsyncSequence<AsyncSequence<TElement>>; partition(equater?: MaybeAsyncEqualityComparison<TElement>): AsyncSequence<AsyncSequence<TElement>>;
partitionBy<TBy>(selector: MaybeAsyncConverter<TElement, TBy>, equater?: MaybeAsyncEqualityComparisonOrComparer<TBy>): AsyncSequence<AsyncSequence<TElement>>; partitionBy<TBy>(selector: MaybeAsyncConverter<TElement, TBy>, equater?: MaybeAsyncEqualityComparison<TBy>): AsyncSequence<AsyncSequence<TElement>>;
distinct(equater?: MaybeAsyncEqualityComparisonOrComparer<TElement>): AsyncSequence<TElement>; distinct(equater?: MaybeAsyncEqualityComparison<TElement>): AsyncSequence<TElement>;
distinctBy<TBy>(selector: MaybeAsyncConverter<TElement, TBy>, equater?: MaybeAsyncEqualityComparisonOrComparer<TBy>): AsyncSequence<TElement>; distinctBy<TBy>(selector: MaybeAsyncConverter<TElement, TBy>, equater?: MaybeAsyncEqualityComparison<TBy>): AsyncSequence<TElement>;
union(sequence: MaybeAsyncIterable<TElement>, equater?: MaybeAsyncEqualityComparisonOrComparer<TElement>): AsyncSequence<TElement>; union(sequence: MaybeAsyncIterable<TElement>, equater?: MaybeAsyncEqualityComparison<TElement>): AsyncSequence<TElement>;
unionBy<TBy>(sequence: MaybeAsyncIterable<TElement>, selector: MaybeAsyncConverter<TElement, TBy>, equater?: MaybeAsyncEqualityComparisonOrComparer<TBy>): AsyncSequence<TElement>; unionBy<TBy>(sequence: MaybeAsyncIterable<TElement>, selector: MaybeAsyncConverter<TElement, TBy>, equater?: MaybeAsyncEqualityComparison<TBy>): AsyncSequence<TElement>;
except(sequence: MaybeAsyncIterable<TElement>, equater?: MaybeAsyncEqualityComparisonOrComparer<TElement>): AsyncSequence<TElement>; except(sequence: MaybeAsyncIterable<TElement>, equater?: MaybeAsyncEqualityComparison<TElement>): AsyncSequence<TElement>;
exceptBy<TBy>(sequence: MaybeAsyncIterable<TElement>, selector: MaybeAsyncConverter<TElement, TBy>, equater?: MaybeAsyncEqualityComparisonOrComparer<TBy>): AsyncSequence<TElement>; exceptBy<TBy>(sequence: MaybeAsyncIterable<TElement>, selector: MaybeAsyncConverter<TElement, TBy>, equater?: MaybeAsyncEqualityComparison<TBy>): AsyncSequence<TElement>;
intersect(sequence: MaybeAsyncIterable<TElement>, equater?: MaybeAsyncEqualityComparisonOrComparer<TElement>): AsyncSequence<TElement>; intersect(sequence: MaybeAsyncIterable<TElement>, equater?: MaybeAsyncEqualityComparison<TElement>): AsyncSequence<TElement>;
intersectBy<TBy>(sequence: MaybeAsyncIterable<TElement>, selector: MaybeAsyncConverter<TElement, TBy>, equater?: MaybeAsyncEqualityComparisonOrComparer<TBy>): AsyncSequence<TElement>; intersectBy<TBy>(sequence: MaybeAsyncIterable<TElement>, selector: MaybeAsyncConverter<TElement, TBy>, equater?: MaybeAsyncEqualityComparison<TBy>): AsyncSequence<TElement>;
all(predicate: MaybeAsyncAnyPredicate<TElement>): Promise<boolean>; all(predicate: MaybeAsyncAnyPredicate<TElement>): Promise<boolean>;
any(predicate: MaybeAsyncAnyPredicate<TElement>): Promise<boolean>; any(predicate: MaybeAsyncAnyPredicate<TElement>): Promise<boolean>;
@@ -109,7 +108,6 @@ export interface AsyncSequence<TElement> extends AsyncIterable<TElement> {
forEach(action: MaybeAsyncAction<TElement>): Promise<void>; forEach(action: MaybeAsyncAction<TElement>): Promise<void>;
zip<TOther>(sequence: MaybeAsyncIterable<TOther>): AsyncSequence<[TElement, TOther]>; zip<TOther>(sequence: MaybeAsyncIterable<TOther>): AsyncSequence<[TElement, TOther]>;
cartesianProduct<TOther>(sequence: MaybeAsyncIterable<TOther>): AsyncSequence<[TElement, TOther]>;
indexed(): AsyncSequence<[number, TElement]>; indexed(): AsyncSequence<[number, TElement]>;

View File

@@ -1,16 +1,16 @@
import { MaybeAsyncConverter } from "../types.js"; import { MaybeAsyncConverter } from "../types.js";
import { Nullable } from "../utils.js"; import { Nullable } from "../utils.js";
import { AsyncComparer, AsyncComparison, Comparer, MaybeAsyncComparison, MaybeAsyncComparisonOrComparer } from "./types.js"; import { AsyncComparer, MaybeAsyncComparisonOrComparer, Comparer, MaybeAsyncComparison, AsyncComparison } from "./types.js";
export function isAsyncComparer<T>(obj: any): obj is AsyncComparer<T> { export function isAsyncComparer<T>(obj: any): obj is AsyncComparer<T> {
return obj instanceof BaseAsyncComparer; return obj instanceof BaseAsyncComparer;
} }
export function asAsyncComparer<T>(comparer: MaybeAsyncComparisonOrComparer<T>): AsyncComparer<T> { export function asAsyncComparer<T>(comparer: MaybeAsyncComparisonOrComparer<T>): AsyncComparer<T> {
return typeof comparer === "function" ? createAsyncComparer(comparer) : isAsyncComparer<T>(comparer) ? comparer : fromSyncComparer(comparer); return typeof comparer === "function" ? createAsyncComparer(comparer) : isAsyncComparer<T>(comparer) ? comparer : new WrappedAsyncComparer(comparer);
} }
export function fromSyncComparer<T>(comparer: Comparer<T>): AsyncComparer<T> { export function fromSync<T>(comparer: Comparer<T>): AsyncComparer<T> {
return new WrappedAsyncComparer(comparer); return new WrappedAsyncComparer(comparer);
} }
@@ -22,8 +22,8 @@ export function createAsyncComparerUsing<T, U>(projection: MaybeAsyncConverter<T
return new MappedAsyncComparer(projection, comparison); return new MappedAsyncComparer(projection, comparison);
} }
export function combineAsyncComparers<T>(comparers: Iterable<Nullable<MaybeAsyncComparisonOrComparer<T>>>): AsyncComparer<T> | undefined { export function combineNullableAsyncComparers<T>(comparers: Nullable<MaybeAsyncComparisonOrComparer<T>>[]): AsyncComparer<T> | undefined {
let result: AsyncComparer<T> = dummyAsyncComparer; let result = defaultAsyncComparer;
for (const comparer of comparers) { for (const comparer of comparers) {
if (!comparer) { if (!comparer) {
@@ -33,7 +33,7 @@ export function combineAsyncComparers<T>(comparers: Iterable<Nullable<MaybeAsync
result = result.then(asAsyncComparer(comparer)); result = result.then(asAsyncComparer(comparer));
} }
return result === dummyAsyncComparer ? undefined : result; return result === defaultAsyncComparer ? undefined : result;
} }
export abstract class BaseAsyncComparer<T> implements AsyncComparer<T> { export abstract class BaseAsyncComparer<T> implements AsyncComparer<T> {
@@ -144,24 +144,6 @@ class ThenAsyncComparer<T> extends BaseAsyncComparer<T> {
} }
} }
const dummyAsyncComparer = new class DummyAsyncComparer extends BaseAsyncComparer<any> {
public override async compare(_a: any, _b: any): Promise<number> {
return 0;
}
public override then(comparer: AsyncComparer<any>): AsyncComparer<any> {
return comparer;
}
public override thenCompare(comparison: MaybeAsyncComparison<any>): AsyncComparer<any> {
return createAsyncComparer(comparison);
}
public override thenCompareUsing<U>(projection: MaybeAsyncConverter<any, U>, comparison?: MaybeAsyncComparisonOrComparer<U> | undefined): AsyncComparer<any> {
return createAsyncComparerUsing(projection, comparison);
}
}
export const defaultAsyncComparer: AsyncComparer<any> = new class DefaultAsyncComparer extends BaseAsyncComparer<any> { export const defaultAsyncComparer: AsyncComparer<any> = new class DefaultAsyncComparer extends BaseAsyncComparer<any> {
public override async compare(a: any, b: any): Promise<number> { public override async compare(a: any, b: any): Promise<number> {
if (a === undefined) { if (a === undefined) {

View File

@@ -1,6 +1,6 @@
import { Converter } from "../types.js"; import { Converter } from "../types.js";
import { Nullable } from "../utils.js"; import { Nullable } from "../utils.js";
import { fromSyncComparer } from "./async.js"; import { fromSync } from "./async.js";
import { Comparer, ComparisonOrComparer, Comparison, AsyncComparer } from "./types.js"; import { Comparer, ComparisonOrComparer, Comparison, AsyncComparer } from "./types.js";
export function isComparer<T>(obj: any): obj is Comparer<T> { export function isComparer<T>(obj: any): obj is Comparer<T> {
@@ -27,8 +27,8 @@ export function reverseComparison<T>(comparison: Comparison<T>): Comparison<T> {
return (a, b) => comparison(b, a); return (a, b) => comparison(b, a);
} }
export function combineComparers<T>(comparers: Iterable<Nullable<ComparisonOrComparer<T>>>) { export function combineNullableComparers<T>(comparers: Nullable<ComparisonOrComparer<T>>[]) {
let result: Comparer<T> = dummyComparer; let result = defaultComparer;
for (const comparer of comparers) { for (const comparer of comparers) {
if (!comparer) { if (!comparer) {
@@ -38,7 +38,7 @@ export function combineComparers<T>(comparers: Iterable<Nullable<ComparisonOrCom
result = result.then(asComparer(comparer)); result = result.then(asComparer(comparer));
} }
return result === dummyComparer ? undefined : result; return result === defaultComparer ? undefined : result;
} }
export abstract class BaseComparer<T> implements Comparer<T> { export abstract class BaseComparer<T> implements Comparer<T> {
@@ -67,7 +67,7 @@ export abstract class BaseComparer<T> implements Comparer<T> {
} }
public toAsync(): AsyncComparer<T> { public toAsync(): AsyncComparer<T> {
return fromSyncComparer<T>(this); return fromSync<T>(this);
} }
public nullAwareComparer(): Comparer<Nullable<T>> { public nullAwareComparer(): Comparer<Nullable<T>> {
@@ -75,24 +75,6 @@ export abstract class BaseComparer<T> implements Comparer<T> {
} }
} }
const dummyComparer = new class DummyComparer extends BaseComparer<any> {
public override compare(_a: any, _b: any): number {
return 0;
}
public override then(comparer: Comparer<any>): Comparer<any> {
return comparer;
}
public override thenCompare(comparison: Comparison<any>): Comparer<any> {
return createComparer(comparison);
}
public override thenCompareUsing<U>(projection: Converter<any, U>, comparison?: ComparisonOrComparer<U> | undefined): Comparer<any> {
return createComparerUsing(projection, comparison);
}
};
class SimpleComparer<T> extends BaseComparer<T> { class SimpleComparer<T> extends BaseComparer<T> {
readonly #comparison: Comparison<T>; readonly #comparison: Comparison<T>;

View File

@@ -1,217 +0,0 @@
import { MaybeAsyncConverter } from "../types.js";
import { Nullable } from "../utils.js";
import { AsyncEqualityComparer, AsyncEqualityComparison, EqualityComparer, MaybeAsyncEqualityComparison, MaybeAsyncEqualityComparisonOrComparer } from "./types.js";
export function isAsyncEqualityComparer<T>(obj: any): obj is AsyncEqualityComparer<T> {
return obj instanceof BaseAsyncEqualityComparer;
}
export function asAsyncEqualityComparer<T>(equalityComparer: MaybeAsyncEqualityComparisonOrComparer<T>): AsyncEqualityComparer<T> {
return typeof equalityComparer === "function" ? createAsyncEqualityComparer(equalityComparer) : isAsyncEqualityComparer<T>(equalityComparer) ? equalityComparer : fromSyncEqualityComparer(equalityComparer);
}
export function fromSyncEqualityComparer<T>(equalityComparer: EqualityComparer<T>): AsyncEqualityComparer<T> {
return new WrappedAsyncEqualityComparer(equalityComparer);
}
export function createAsyncEqualityComparer<T = any>(equalityComparison: MaybeAsyncEqualityComparison<T>): AsyncEqualityComparer<T> {
return new SimpleAsyncEqualityComparer(equalityComparison);
}
export function createAsyncEqualityComparerUsing<T = any, U = any>(projection: MaybeAsyncConverter<T, U>, equalityComparison?: MaybeAsyncEqualityComparisonOrComparer<U>): AsyncEqualityComparer<T> {
return new MappedAsyncEqualityComparer(projection, equalityComparison);
}
export function combineAsyncEqualityComparers<T>(equalityComparers: Iterable<Nullable<MaybeAsyncEqualityComparisonOrComparer<T>>>) {
let result: AsyncEqualityComparer<T> = alwaysTrueAsyncEqualityComparer;
for (const equalityComparer of equalityComparers) {
if (!equalityComparer) {
continue;
}
result = result.then(asAsyncEqualityComparer(equalityComparer));
}
return result === alwaysTrueAsyncEqualityComparer ? undefined : result;
}
export abstract class BaseAsyncEqualityComparer<T> implements AsyncEqualityComparer<T> {
#cachedBoundEqualityComparison: AsyncEqualityComparison<T> | undefined;
public abstract equals(a: T, b: T): Promise<boolean>;
public equalityComparison(): AsyncEqualityComparison<T> {
return this.#cachedBoundEqualityComparison ??= this.equals.bind(this);
}
public opposite(): AsyncEqualityComparer<T> {
return new OppositeAsyncEqualityComparer(this);
}
public then(equalityComparer: AsyncEqualityComparer<T>): AsyncEqualityComparer<T> {
return new ThenAsyncEqualityComparer(this, equalityComparer);
}
public thenEquals(equalityComparison: MaybeAsyncEqualityComparison<T>): AsyncEqualityComparer<T> {
return this.then(createAsyncEqualityComparer(equalityComparison));
}
public thenEqualsUsing<U>(projection: MaybeAsyncConverter<T, U>, equalityComparison?: MaybeAsyncEqualityComparisonOrComparer<U>): AsyncEqualityComparer<T> {
return this.then(createAsyncEqualityComparerUsing(projection, equalityComparison));
}
}
class WrappedAsyncEqualityComparer<T> extends BaseAsyncEqualityComparer<T> {
readonly #base: EqualityComparer<T>;
constructor(base: EqualityComparer<T>) {
super();
this.#base = base;
}
public override async equals(a: T, b: T) {
return this.#base.equals(a, b);
}
}
class SimpleAsyncEqualityComparer<T> extends BaseAsyncEqualityComparer<T> {
readonly #equalityComparison: MaybeAsyncEqualityComparison<T>;
public constructor(equalityComparison: MaybeAsyncEqualityComparison<T>) {
super();
this.#equalityComparison = equalityComparison;
}
public override async equals(a: T, b: T): Promise<boolean> {
return await this.#equalityComparison(a, b);
}
}
class MappedAsyncEqualityComparer<T, U> extends BaseAsyncEqualityComparer<T> {
readonly #projection: MaybeAsyncConverter<T, U>;
readonly #equalityComparison: AsyncEqualityComparer<U>;
public constructor(projection: MaybeAsyncConverter<T, U>, equalityComparison?: MaybeAsyncEqualityComparisonOrComparer<U>) {
super();
this.#projection = projection;
this.#equalityComparison = equalityComparison ? asAsyncEqualityComparer(equalityComparison) : defaultAsyncEqualityComparer;
}
public override async equals(a: T, b: T): Promise<boolean> {
return await this.#equalityComparison.equals(await this.#projection(a), await this.#projection(b));
}
}
class OppositeAsyncEqualityComparer<T> extends BaseAsyncEqualityComparer<T> {
readonly #base: AsyncEqualityComparer<T>;
public constructor(base: AsyncEqualityComparer<T>) {
super();
this.#base = base;
}
public override async equals(a: T, b: T): Promise<boolean> {
return !(await this.#base.equals(a, b));
}
public override opposite(): AsyncEqualityComparer<T> {
return this.#base;
}
}
class ThenAsyncEqualityComparer<T> extends BaseAsyncEqualityComparer<T> {
readonly #base: AsyncEqualityComparer<T>;
readonly #equalityComparer: AsyncEqualityComparer<T>;
public constructor(base: AsyncEqualityComparer<T>, equalityComparer: AsyncEqualityComparer<T>) {
super();
this.#base = base;
this.#equalityComparer = equalityComparer;
}
public override async equals(a: T, b: T) {
return await this.#base.equals(a, b) && await this.#equalityComparer.equals(a, b);
}
}
export const alwaysAsyncFalseEqualityComparer = new class AlwaysFalseAsyncEqualityComparer extends BaseAsyncEqualityComparer<any> {
public override async equals(_a: any, _b: any): Promise<boolean> {
return false;
}
public override opposite(): AsyncEqualityComparer<any> {
return alwaysTrueAsyncEqualityComparer;
}
public override then(_equalityComparer: AsyncEqualityComparer<any>): AsyncEqualityComparer<any> {
return this;
}
public override thenEquals(_equalityComparison: MaybeAsyncEqualityComparison<any>): AsyncEqualityComparer<any> {
return this;
}
public override thenEqualsUsing<U>(_projection: MaybeAsyncConverter<any, U>, _equalityComparison?: MaybeAsyncEqualityComparisonOrComparer<U> | undefined): AsyncEqualityComparer<any> {
return this;
}
};
export const alwaysTrueAsyncEqualityComparer = new class AlwaysTrueAsyncEqualityComparer extends BaseAsyncEqualityComparer<any> {
public override async equals(_a: any, _b: any): Promise<boolean> {
return true;
}
public override opposite(): AsyncEqualityComparer<any> {
return alwaysAsyncFalseEqualityComparer;
}
public override then(equalityComparer: AsyncEqualityComparer<any>): AsyncEqualityComparer<any> {
return equalityComparer;
}
public override thenEquals(equalityComparison: MaybeAsyncEqualityComparison<any>): AsyncEqualityComparer<any> {
return createAsyncEqualityComparer(equalityComparison);
}
public override thenEqualsUsing<U>(projection: MaybeAsyncConverter<any, U>, equalityComparison?: MaybeAsyncEqualityComparisonOrComparer<U> | undefined): AsyncEqualityComparer<any> {
return createAsyncEqualityComparerUsing(projection, equalityComparison);
}
};
export const looseAsyncEqualityComparer: AsyncEqualityComparer<any> = new class LooseAsyncEqualityComparer extends BaseAsyncEqualityComparer<any> {
public override async equals(a: any, b: any): Promise<boolean> {
return a == b;
}
};
export const strictAsyncEqualityComparer: AsyncEqualityComparer<any> = new class StrictAsyncEqualityComparer extends BaseAsyncEqualityComparer<any> {
public override async equals(a: any, b: any): Promise<boolean> {
return a === b;
}
};
export const sameValueAsyncEqualityComparer: AsyncEqualityComparer<any> = new class SameValueAsyncEqualityComparer extends BaseAsyncEqualityComparer<any> {
public override async equals(a: any, b: any): Promise<boolean> {
return Object.is(a, b);
}
};
export const defaultAsyncEqualityComparer: AsyncEqualityComparer<any> = new class DefaultAsyncEqualityComparer extends BaseAsyncEqualityComparer<any> {
public override async equals(a: any, b: any): Promise<boolean> {
return a === b;
}
};
export function getDefaultAsyncEqualityComparer<T>(): AsyncEqualityComparer<T> {
return defaultAsyncEqualityComparer;
}
export const dateAsyncEqualityComparer: AsyncEqualityComparer<Date> = new class DateAsyncEqualityComparer extends BaseAsyncEqualityComparer<Date> {
public override async equals(a: Date, b: Date): Promise<boolean> {
return a.getTime() === b.getTime();
}
};

View File

@@ -2,14 +2,30 @@ import { Converter } from "../types.js";
import { Nullable } from "../utils.js"; import { Nullable } from "../utils.js";
import { EqualityComparer, EqualityComparison, EqualityComparisonOrComparer } from "./types.js"; import { EqualityComparer, EqualityComparison, EqualityComparisonOrComparer } from "./types.js";
export function looseEquals<T>(a: T, b: T) {
return a == b;
}
export function strictEquals<T>(a: T, b: T) {
return a === b;
}
export function sameValue<T>(a: T, b: T) {
return Object.is(a, b);
}
export function isEqualityComparer<T>(obj: any): obj is EqualityComparer<T> { export function isEqualityComparer<T>(obj: any): obj is EqualityComparer<T> {
return obj instanceof BaseEqualityComparer; return obj instanceof BaseEqualityComparer;
} }
export function asEqualityComparer<T>(equalityComparer: EqualityComparisonOrComparer<T>): EqualityComparer<T> { export function asEqualityComparer<T>(equalityComparer: EqualityComparisonOrComparer<T>) {
return typeof equalityComparer === "function" ? createEqualityComparer(equalityComparer) : equalityComparer; return typeof equalityComparer === "function" ? createEqualityComparer(equalityComparer) : equalityComparer;
} }
export function asEqualityComparison<T>(equalityComparer: EqualityComparisonOrComparer<T>) {
return typeof equalityComparer === "function" ? equalityComparer : equalityComparer.equalityComparison();
}
export function createEqualityComparer<T = any>(equalityComparison: EqualityComparison<T>): EqualityComparer<T> { export function createEqualityComparer<T = any>(equalityComparison: EqualityComparison<T>): EqualityComparer<T> {
return new SimpleEqualityComparer(equalityComparison); return new SimpleEqualityComparer(equalityComparison);
} }
@@ -18,8 +34,12 @@ export function createEqualityComparerUsing<T = any, U = any>(projection: Conver
return new MappedEqualityComparer(projection, equalityComparison); return new MappedEqualityComparer(projection, equalityComparison);
} }
export function combineEqualityComparers<T>(equalityComparers: Iterable<Nullable<EqualityComparisonOrComparer<T>>>) { export function oppositeEqualityComparison<T>(equalityComparison: EqualityComparison<T>): EqualityComparison<T> {
let result: EqualityComparer<T> = alwaysTrueEqualityComparer; return (a, b) => !equalityComparison(a, b);
}
export function combineNullableEqualityComparers<T>(equalityComparers: Nullable<EqualityComparisonOrComparer<T>>[]) {
let result = defaultEqualityComparer;
for (const equalityComparer of equalityComparers) { for (const equalityComparer of equalityComparers) {
if (!equalityComparer) { if (!equalityComparer) {
@@ -29,7 +49,7 @@ export function combineEqualityComparers<T>(equalityComparers: Iterable<Nullable
result = result.then(asEqualityComparer(equalityComparer)); result = result.then(asEqualityComparer(equalityComparer));
} }
return result === alwaysTrueEqualityComparer ? undefined : result; return result === defaultEqualityComparer ? undefined : result;
} }
export abstract class BaseEqualityComparer<T> implements EqualityComparer<T> { export abstract class BaseEqualityComparer<T> implements EqualityComparer<T> {
@@ -126,66 +146,6 @@ class ThenEqualityComparer<T> extends BaseEqualityComparer<T> {
} }
} }
export const alwaysFalseEqualityComparer = new class AlwaysFalseEqualityComparer extends BaseEqualityComparer<any> {
public override equals(_a: any, _b: any): boolean {
return false;
}
public override opposite(): EqualityComparer<any> {
return alwaysTrueEqualityComparer;
}
public override then(_equalityComparer: EqualityComparer<any>): EqualityComparer<any> {
return this;
}
public override thenEquals(_equalityComparison: EqualityComparison<any>): EqualityComparer<any> {
return this;
}
public override thenEqualsUsing<U>(_projection: Converter<any, U>, _equalityComparison?: EqualityComparisonOrComparer<U> | undefined): EqualityComparer<any> {
return this;
}
};
export const alwaysTrueEqualityComparer = new class AlwaysTrueEqualityComparer extends BaseEqualityComparer<any> {
public override equals(_a: any, _b: any): boolean {
return true;
}
public override opposite(): EqualityComparer<any> {
return alwaysFalseEqualityComparer;
}
public override then(equalityComparer: EqualityComparer<any>): EqualityComparer<any> {
return equalityComparer;
}
public override thenEquals(equalityComparison: EqualityComparison<any>): EqualityComparer<any> {
return createEqualityComparer(equalityComparison);
}
public override thenEqualsUsing<U>(projection: Converter<any, U>, equalityComparison?: EqualityComparisonOrComparer<U> | undefined): EqualityComparer<any> {
return createEqualityComparerUsing(projection, equalityComparison);
}
};
export const looseEqualityComparer: EqualityComparer<any> = new class LooseEqualityComparer extends BaseEqualityComparer<any> {
public override equals(a: any, b: any): boolean {
return a == b;
}
};
export const strictEqualityComparer: EqualityComparer<any> = new class StrictEqualityComparer extends BaseEqualityComparer<any> {
public override equals(a: any, b: any): boolean {
return a === b;
}
};
export const sameValueEqualityComparer: EqualityComparer<any> = new class SameValueEqualityComparer extends BaseEqualityComparer<any> {
public override equals(a: any, b: any): boolean {
return Object.is(a, b);
}
};
export const defaultEqualityComparer: EqualityComparer<any> = new class DefaultEqualityComparer extends BaseEqualityComparer<any> { export const defaultEqualityComparer: EqualityComparer<any> = new class DefaultEqualityComparer extends BaseEqualityComparer<any> {
public override equals(a: any, b: any): boolean { public override equals(a: any, b: any): boolean {
return a === b; return a === b;
@@ -201,3 +161,7 @@ export const dateEqualityComparer: EqualityComparer<Date> = new class DateEquali
return a.getTime() === b.getTime(); return a.getTime() === b.getTime();
} }
}; };
export const looseEqualityComparer: EqualityComparer<any> = new SimpleEqualityComparer<any>(looseEquals);
export const strictEqualityComparer: EqualityComparer<any> = new SimpleEqualityComparer<any>(strictEquals);
export const sameValueEqualityComparer: EqualityComparer<any> = new SimpleEqualityComparer<any>(sameValue);

View File

@@ -1,4 +1,4 @@
import { AsyncFunction, Converter, MaybeAsyncConverter, MaybeAsyncFunction } from "../types.js"; import { Converter, MaybeAsyncFunction } from "../types.js";
export interface EqualityComparer<T> { export interface EqualityComparer<T> {
equals(a: T, b: T): boolean; equals(a: T, b: T): boolean;
@@ -9,20 +9,7 @@ export interface EqualityComparer<T> {
thenEqualsUsing<U>(projection: Converter<T, U>, equalityComparison?: EqualityComparisonOrComparer<U>): EqualityComparer<T>; thenEqualsUsing<U>(projection: Converter<T, U>, equalityComparison?: EqualityComparisonOrComparer<U>): EqualityComparer<T>;
} }
export interface AsyncEqualityComparer<T> {
equals(a: T, b: T): Promise<boolean>;
equalityComparison(): AsyncEqualityComparison<T>;
opposite(): AsyncEqualityComparer<T>;
then(equalityComparer: AsyncEqualityComparer<T>): AsyncEqualityComparer<T>;
thenEquals(equalityComparison: AsyncEqualityComparison<T>): AsyncEqualityComparer<T>;
thenEqualsUsing<U>(projection: MaybeAsyncConverter<T, U>, equalityComparison?: AsyncEqualityComparisonOrComparer<U>): AsyncEqualityComparer<T>;
}
export type EqualityComparison<T> = (first: T, second: T) => boolean; export type EqualityComparison<T> = (first: T, second: T) => boolean;
export type EqualityComparisonOrComparer<T> = EqualityComparison<T> | EqualityComparer<T>; export type EqualityComparisonOrComparer<T> = EqualityComparison<T> | EqualityComparer<T>;
export type AsyncEqualityComparison<T> = AsyncFunction<EqualityComparison<T>>;
export type MaybeAsyncEqualityComparison<T> = MaybeAsyncFunction<EqualityComparison<T>>; export type MaybeAsyncEqualityComparison<T> = MaybeAsyncFunction<EqualityComparison<T>>;
export type AsyncEqualityComparisonOrComparer<T> = AsyncEqualityComparison<T> | AsyncEqualityComparer<T>;
export type MaybeAsyncEqualityComparisonOrComparer<T> = MaybeAsyncEqualityComparison<T> | EqualityComparer<T> | AsyncEqualityComparer<T>;

View File

@@ -1,6 +1,5 @@
import { asAsyncEqualityComparer } from "../equality-comparer/async.js";
import { asEqualityComparer } from "../equality-comparer/sync.js"; import { asEqualityComparer } from "../equality-comparer/sync.js";
import { AsyncEqualityComparer, EqualityComparer, EqualityComparisonOrComparer, MaybeAsyncEqualityComparisonOrComparer } from "../equality-comparer/types.js"; import { EqualityComparer, EqualityComparisonOrComparer, MaybeAsyncEqualityComparison } from "../equality-comparer/types.js";
import { MaybeAsyncIterable } from "../types.js"; import { MaybeAsyncIterable } from "../types.js";
import { AsyncEqualityMap, EqualityMap, EqualityMapEntry } from "./types.js"; import { AsyncEqualityMap, EqualityMap, EqualityMapEntry } from "./types.js";
@@ -204,10 +203,10 @@ export class NativeAsyncEqualityMap<K, V> implements AsyncEqualityMap<K, V> {
export class CustomAsyncEqualityMap<K, V> implements AsyncEqualityMap<K, V> { export class CustomAsyncEqualityMap<K, V> implements AsyncEqualityMap<K, V> {
readonly #list: EqualityMapEntry<K, V>[] = []; readonly #list: EqualityMapEntry<K, V>[] = [];
readonly #keyComparer: AsyncEqualityComparer<K>; readonly #keyComparer: MaybeAsyncEqualityComparison<K>;
constructor(keyComparer: MaybeAsyncEqualityComparisonOrComparer<K>) { constructor(keyComparer: MaybeAsyncEqualityComparison<K>) {
this.#keyComparer = asAsyncEqualityComparer(keyComparer); this.#keyComparer = keyComparer;
} }
get size() { get size() {
@@ -216,7 +215,7 @@ export class CustomAsyncEqualityMap<K, V> implements AsyncEqualityMap<K, V> {
async get(key: K) { async get(key: K) {
for (const entry of this.#list) { for (const entry of this.#list) {
if (await this.#keyComparer.equals(key, entry[0])) { if (await this.#keyComparer(key, entry[0])) {
return entry[1]; return entry[1];
} }
} }
@@ -226,7 +225,7 @@ export class CustomAsyncEqualityMap<K, V> implements AsyncEqualityMap<K, V> {
async set(key: K, value: V) { async set(key: K, value: V) {
for (const entry of this.#list) { for (const entry of this.#list) {
if (await this.#keyComparer.equals(key, entry[0])) { if (await this.#keyComparer(key, entry[0])) {
const previous = entry[1]; const previous = entry[1];
entry[1] = value; entry[1] = value;
return previous; return previous;
@@ -246,7 +245,7 @@ export class CustomAsyncEqualityMap<K, V> implements AsyncEqualityMap<K, V> {
async contains(key: K) { async contains(key: K) {
for (const entry of this.#list) { for (const entry of this.#list) {
if (await this.#keyComparer.equals(key, entry[0])) { if (await this.#keyComparer(key, entry[0])) {
return true; return true;
} }
} }
@@ -256,7 +255,7 @@ export class CustomAsyncEqualityMap<K, V> implements AsyncEqualityMap<K, V> {
async remove(key: K) { async remove(key: K) {
for (let i = 0; i < this.#list.length; i++) { for (let i = 0; i < this.#list.length; i++) {
if (await this.#keyComparer.equals(key, this.#list[i][0])) { if (await this.#keyComparer(key, this.#list[i][0])) {
const removed = this.#list.splice(i, 1); const removed = this.#list.splice(i, 1);
return removed[0][1]; return removed[0][1];
} }

View File

@@ -1,4 +1,4 @@
import { EqualityComparisonOrComparer, MaybeAsyncEqualityComparisonOrComparer } from "../equality-comparer/types.js"; import { EqualityComparisonOrComparer, MaybeAsyncEqualityComparison } from "../equality-comparer/types.js";
import { CustomAsyncEqualityMap, CustomEqualityMap, NativeAsyncEqualityMap, NativeEqualityMap } from "./impl.js"; import { CustomAsyncEqualityMap, CustomEqualityMap, NativeAsyncEqualityMap, NativeEqualityMap } from "./impl.js";
import { AsyncEqualityMap, EqualityMap } from "./types.js"; import { AsyncEqualityMap, EqualityMap } from "./types.js";
@@ -6,6 +6,6 @@ export function createEqualityMap<K, V>(keyComparer?: EqualityComparisonOrCompar
return keyComparer ? new CustomEqualityMap<K, V>(keyComparer) : new NativeEqualityMap<K, V>(); return keyComparer ? new CustomEqualityMap<K, V>(keyComparer) : new NativeEqualityMap<K, V>();
} }
export function createAsyncEqualityMap<K, V>(keyComparer?: MaybeAsyncEqualityComparisonOrComparer<K>): AsyncEqualityMap<K, V> { export function createAsyncEqualityMap<K, V>(keyComparer?: MaybeAsyncEqualityComparison<K>): AsyncEqualityMap<K, V> {
return keyComparer ? new CustomAsyncEqualityMap<K, V>(keyComparer) : new NativeAsyncEqualityMap<K, V>(); return keyComparer ? new CustomAsyncEqualityMap<K, V>(keyComparer) : new NativeAsyncEqualityMap<K, V>();
} }

View File

@@ -1,6 +1,5 @@
import { asAsyncEqualityComparer } from "../equality-comparer/async.js";
import { asEqualityComparer } from "../equality-comparer/sync.js"; import { asEqualityComparer } from "../equality-comparer/sync.js";
import { AsyncEqualityComparer, EqualityComparer, EqualityComparisonOrComparer, MaybeAsyncEqualityComparisonOrComparer } from "../equality-comparer/types.js"; import { EqualityComparer, EqualityComparisonOrComparer, MaybeAsyncEqualityComparison } from "../equality-comparer/types.js";
import { MaybeAsyncIterable } from "../types.js"; import { MaybeAsyncIterable } from "../types.js";
import { AsyncEqualitySet, EqualitySet } from "./types.js"; import { AsyncEqualitySet, EqualitySet } from "./types.js";
@@ -168,10 +167,10 @@ export class NativeAsyncEqualitySet<T> implements AsyncEqualitySet<T> {
export class CustomAsyncEqualitySet<T> implements AsyncEqualitySet<T> { export class CustomAsyncEqualitySet<T> implements AsyncEqualitySet<T> {
readonly #list: T[] = []; readonly #list: T[] = [];
readonly #equater: AsyncEqualityComparer<T>; readonly #equater: MaybeAsyncEqualityComparison<T>;
constructor(equater: MaybeAsyncEqualityComparisonOrComparer<T>) { constructor(equater: MaybeAsyncEqualityComparison<T>) {
this.#equater = asAsyncEqualityComparer(equater); this.#equater = equater;
} }
get size() { get size() {
@@ -202,7 +201,7 @@ export class CustomAsyncEqualitySet<T> implements AsyncEqualitySet<T> {
async contains(value: T) { async contains(value: T) {
for (const val of this.#list) { for (const val of this.#list) {
if (await this.#equater.equals(value, val)) { if (await this.#equater(value, val)) {
return true; return true;
} }
} }
@@ -214,7 +213,7 @@ export class CustomAsyncEqualitySet<T> implements AsyncEqualitySet<T> {
const length = this.#list.length; const length = this.#list.length;
for (let i = 0; i < length; i++) { for (let i = 0; i < length; i++) {
if (await this.#equater.equals(value, this.#list[i])) { if (await this.#equater(value, this.#list[i])) {
this.#list.splice(i, 1); this.#list.splice(i, 1);
return true; return true;
} }

View File

@@ -1,4 +1,4 @@
import { EqualityComparisonOrComparer, MaybeAsyncEqualityComparisonOrComparer } from "../equality-comparer/types.js"; import { EqualityComparisonOrComparer, MaybeAsyncEqualityComparison } from "../equality-comparer/types.js";
import { CustomAsyncEqualitySet, CustomEqualitySet, NativeAsyncEqualitySet, NativeEqualitySet } from "./impl.js"; import { CustomAsyncEqualitySet, CustomEqualitySet, NativeAsyncEqualitySet, NativeEqualitySet } from "./impl.js";
import { AsyncEqualitySet, EqualitySet } from "./types.js"; import { AsyncEqualitySet, EqualitySet } from "./types.js";
@@ -6,6 +6,6 @@ export function createEqualitySet<T>(equater?: EqualityComparisonOrComparer<T>):
return equater ? new CustomEqualitySet(equater) : new NativeEqualitySet<T>(); return equater ? new CustomEqualitySet(equater) : new NativeEqualitySet<T>();
} }
export function createAsyncEqualitySet<T>(equater?: MaybeAsyncEqualityComparisonOrComparer<T>): AsyncEqualitySet<T> { export function createAsyncEqualitySet<T>(equater?: MaybeAsyncEqualityComparison<T>): AsyncEqualitySet<T> {
return equater ? new CustomAsyncEqualitySet(equater) : new NativeAsyncEqualitySet<T>(); return equater ? new CustomAsyncEqualitySet(equater) : new NativeAsyncEqualitySet<T>();
} }

View File

@@ -15,10 +15,7 @@ export * as Comparers from "./comparer/sync.js";
export { BaseAsyncComparer } from "./comparer/async.js"; export { BaseAsyncComparer } from "./comparer/async.js";
export * as AsyncComparers from "./comparer/async.js"; export * as AsyncComparers from "./comparer/async.js";
export * from "./comparer/types.js"; export * from "./comparer/types.js";
export { BaseEqualityComparer } from "./equality-comparer/sync.js";
export * as EqualityComparers from "./equality-comparer/sync.js"; export * as EqualityComparers from "./equality-comparer/sync.js";
export { BaseAsyncEqualityComparer } from "./equality-comparer/async.js";
export * as AsyncEqualityComparers from "./equality-comparer/async.js";
export * from "./equality-comparer/types.js"; export * from "./equality-comparer/types.js";
export * as EqualityMaps from "./equality-map/index.js"; export * as EqualityMaps from "./equality-map/index.js";
export * from "./equality-map/types.js"; export * from "./equality-map/types.js";

View File

@@ -1,10 +1,10 @@
import { BaseAsyncSequence } from "../async/impl.js"; import { BaseAsyncSequence } from "../async/impl.js";
import { AsyncSequence } from "../async/types.js"; import { AsyncSequence } from "../async/types.js";
import { Collector } from "../collector/types.js"; import { Collector } from "../collector/types.js";
import { asComparer, combineComparers, createComparerUsing, defaultComparer } from "../comparer/sync.js"; import { asComparer, combineNullableComparers, createComparerUsing, defaultComparer } from "../comparer/sync.js";
import { ComparisonOrComparer, Comparer } from "../comparer/types.js"; import { ComparisonOrComparer, Comparer } from "../comparer/types.js";
import { asEqualityComparer, defaultEqualityComparer } from "../equality-comparer/sync.js"; import { strictEquals } from "../equality-comparer/sync.js";
import { EqualityComparer, EqualityComparisonOrComparer } from "../equality-comparer/types.js"; import { EqualityComparison } from "../equality-comparer/types.js";
import { createEqualityMap } from "../equality-map/index.js"; import { createEqualityMap } from "../equality-map/index.js";
import { createEqualitySet } from "../equality-set/index.js"; import { createEqualitySet } from "../equality-set/index.js";
import { createQueue } from "../queue.js"; import { createQueue } from "../queue.js";
@@ -50,23 +50,25 @@ export abstract class BaseSequence<TElement> extends SequenceMarker implements S
return new WhereSequence<TElement, any>(this, predicate); return new WhereSequence<TElement, any>(this, predicate);
} }
groupBy<TKey, TResult>(keySelector: Converter<TElement, TKey>, elementSelector?: Converter<TElement, TResult>, keyComparer?: EqualityComparisonOrComparer<TKey>): Sequence<GroupedSequence<TKey, TResult>> { groupBy<TKey, TResult>(keySelector: Converter<TElement, TKey>, elementSelector?: Converter<TElement, TResult>, keyComparer?: EqualityComparison<TKey>): Sequence<GroupedSequence<TKey, TResult>> {
return new GroupBySequence<TElement, TKey, TResult>(this, keySelector, elementSelector, keyComparer); return new GroupBySequence<TElement, TKey, TResult>(this, keySelector, elementSelector, keyComparer);
} }
join<TOther, TKey, TResult>(sequence: Iterable<TOther>, firstKeySelector: Converter<TElement, TKey>, secondKeySelector: Converter<TOther, TKey>, resultSelector?: BiConverter<TElement, TOther, TResult>, keyComparer?: EqualityComparisonOrComparer<TKey>): Sequence<TResult> { join<TOther, TKey, TResult>(sequence: Iterable<TOther>, firstKeySelector: Converter<TElement, TKey>, secondKeySelector: Converter<TOther, TKey>, resultSelector?: BiConverter<TElement, TOther, TResult>, keyComparer?: EqualityComparison<TKey>): Sequence<TResult> {
return new JoinSequence<TElement, TOther, TKey, TResult>(this, wrap(sequence), firstKeySelector, secondKeySelector, resultSelector, keyComparer); return new JoinSequence<TElement, TOther, TKey, TResult>(this, wrap(sequence), firstKeySelector, secondKeySelector, resultSelector, keyComparer);
} }
groupJoin<TOther, TKey, TResult>(sequence: Iterable<TOther>, firstKeySelector: Converter<TElement, TKey>, secondKeySelector: Converter<TOther, TKey>, resultSelector?: BiConverter<TElement, Iterable<TOther>, TResult>, keyComparer?: EqualityComparisonOrComparer<TKey>): Sequence<TResult> { groupJoin<TOther, TKey, TResult>(sequence: Iterable<TOther>, firstKeySelector: Converter<TElement, TKey>, secondKeySelector: Converter<TOther, TKey>, resultSelector?: BiConverter<TElement, Iterable<TOther>, TResult>, keyComparer?: EqualityComparison<TKey>): Sequence<TResult> {
return new GroupJoinSequence<TElement, TOther, TKey, TResult>(this, wrap(sequence), firstKeySelector, secondKeySelector, resultSelector, keyComparer); return new GroupJoinSequence<TElement, TOther, TKey, TResult>(this, wrap(sequence), firstKeySelector, secondKeySelector, resultSelector, keyComparer);
} }
contains(obj: TElement, equater?: EqualityComparisonOrComparer<TElement>) { contains(obj: TElement, equater?: EqualityComparison<TElement>) {
equater = equater ? asEqualityComparer(equater) : defaultEqualityComparer; if (!equater) {
equater = strictEquals;
}
for (const element of this) { for (const element of this) {
if (equater.equals(element, obj)) { if (equater(element, obj)) {
return true; return true;
} }
} }
@@ -74,7 +76,7 @@ export abstract class BaseSequence<TElement> extends SequenceMarker implements S
return false; return false;
} }
sequenceEquals(sequence: Iterable<TElement>, equater?: EqualityComparisonOrComparer<TElement>) { sequenceEquals(sequence: Iterable<TElement>, equater?: EqualityComparison<TElement>) {
if (this === sequence) { if (this === sequence) {
return true; return true;
} }
@@ -88,7 +90,9 @@ export abstract class BaseSequence<TElement> extends SequenceMarker implements S
return false; return false;
} }
equater = equater ? asEqualityComparer(equater) : defaultEqualityComparer; if (!equater) {
equater = strictEquals;
}
const thisIterator = this.iterator(); const thisIterator = this.iterator();
const thatIterator = other.iterator(); const thatIterator = other.iterator();
@@ -105,7 +109,7 @@ export abstract class BaseSequence<TElement> extends SequenceMarker implements S
return false; return false;
} }
if (!equater.equals(thisNext.value, thatNext.value)) { if (!equater(thisNext.value, thatNext.value)) {
return false; return false;
} }
} }
@@ -119,7 +123,7 @@ export abstract class BaseSequence<TElement> extends SequenceMarker implements S
return new PrependSequence<TElement>(this, obj); return new PrependSequence<TElement>(this, obj);
} }
remove(obj: TElement, all?: boolean, equater?: EqualityComparisonOrComparer<TElement>): Sequence<TElement> { remove(obj: TElement, all?: boolean, equater?: EqualityComparison<TElement>): Sequence<TElement> {
return new RemoveSequence<TElement>(this, obj, all, equater); return new RemoveSequence<TElement>(this, obj, all, equater);
} }
@@ -221,29 +225,27 @@ export abstract class BaseSequence<TElement> extends SequenceMarker implements S
} }
#tryGetLast(predicate?: AnyPredicate<TElement>): FindElementResult<TElement> { #tryGetLast(predicate?: AnyPredicate<TElement>): FindElementResult<TElement> {
let result: FindElementResult<TElement> = { let found = false;
found: false let result: TElement | undefined = undefined;
};
if (predicate) { if (predicate) {
for (const element of this) { for (const element of this) {
if (predicate(element)) { if (predicate(element)) {
result = { found = true;
found: true, result = element;
element
};
} }
} }
} else { } else {
for (const element of this) { for (const element of this) {
result = { found = true;
found: true, result = element;
element
};
} }
} }
return result; return {
found,
element: result
} as FindElementResult<TElement>;
} }
last(predicate?: AnyPredicate<TElement>) { last(predicate?: AnyPredicate<TElement>) {
@@ -523,27 +525,27 @@ export abstract class BaseSequence<TElement> extends SequenceMarker implements S
return new OrderBySequence<TElement, TBy>(this, true, selector, comparer); return new OrderBySequence<TElement, TBy>(this, true, selector, comparer);
} }
partition(equater?: EqualityComparisonOrComparer<TElement>): Sequence<Sequence<TElement>> { partition(equater?: EqualityComparison<TElement>): Sequence<Sequence<TElement>> {
return new PartitionSequence<TElement>(this, equater); return new PartitionSequence<TElement>(this, equater);
} }
partitionBy<TBy>(selector: Converter<TElement, TBy>, equater?: EqualityComparisonOrComparer<TBy>): Sequence<Sequence<TElement>> { partitionBy<TBy>(selector: Converter<TElement, TBy>, equater?: EqualityComparison<TBy>): Sequence<Sequence<TElement>> {
return new PartitionBySequence<TElement, TBy>(this, selector, equater); return new PartitionBySequence<TElement, TBy>(this, selector, equater);
} }
distinct(equater?: EqualityComparisonOrComparer<TElement>): Sequence<TElement> { distinct(equater?: EqualityComparison<TElement>): Sequence<TElement> {
return new DistinctSequence<TElement>(this, equater); return new DistinctSequence<TElement>(this, equater);
} }
distinctBy<TBy>(selector: Converter<TElement, TBy>, equater?: EqualityComparisonOrComparer<TBy>): Sequence<TElement> { distinctBy<TBy>(selector: Converter<TElement, TBy>, equater?: EqualityComparison<TBy>): Sequence<TElement> {
return new DistinctBySequence<TElement, TBy>(this, selector, equater); return new DistinctBySequence<TElement, TBy>(this, selector, equater);
} }
union(sequence: Iterable<TElement>, equater?: EqualityComparisonOrComparer<TElement>): Sequence<TElement> { union(sequence: Iterable<TElement>, equater?: EqualityComparison<TElement>): Sequence<TElement> {
return new UnionSequence<TElement>(this, wrap(sequence), equater); return new UnionSequence<TElement>(this, wrap(sequence), equater);
} }
unionBy<TBy>(sequence: Iterable<TElement>, selector: Converter<TElement, TBy>, equater?: EqualityComparisonOrComparer<TBy>): Sequence<TElement> { unionBy<TBy>(sequence: Iterable<TElement>, selector: Converter<TElement, TBy>, equater?: EqualityComparison<TBy>): Sequence<TElement> {
return new UnionBySequence<TElement, TBy>(this, wrap(sequence), selector, equater); return new UnionBySequence<TElement, TBy>(this, wrap(sequence), selector, equater);
} }
@@ -673,10 +675,6 @@ export abstract class BaseSequence<TElement> extends SequenceMarker implements S
return new ZippedSequence<TElement, TOther>(this, wrap(sequence)); return new ZippedSequence<TElement, TOther>(this, wrap(sequence));
} }
cartesianProduct<TOther>(sequence: Iterable<TOther>): Sequence<[TElement, TOther]> {
return new CartesianProductSequence<TElement, TOther>(this, wrap(sequence));
}
indexed(): Sequence<[number, TElement]> { indexed(): Sequence<[number, TElement]> {
return new IndexedSequence<TElement>(this); return new IndexedSequence<TElement>(this);
} }
@@ -833,29 +831,29 @@ export class DelegatedSequence<TElement> extends SequenceMarker implements Seque
return this.#sequence.where(predicate); return this.#sequence.where(predicate);
} }
groupBy<TKey>(keySelector: Converter<TElement, TKey>, elementSelector?: undefined, keyComparer?: EqualityComparisonOrComparer<TKey> | undefined): Sequence<GroupedSequence<TKey, TElement>>; groupBy<TKey>(keySelector: Converter<TElement, TKey>, elementSelector?: undefined, keyComparer?: EqualityComparison<TKey> | undefined): Sequence<GroupedSequence<TKey, TElement>>;
groupBy<TKey, TResult>(keySelector: Converter<TElement, TKey>, elementSelector: Converter<TElement, TResult>, keyComparer?: EqualityComparisonOrComparer<TKey> | undefined): Sequence<GroupedSequence<TKey, TResult>>; groupBy<TKey, TResult>(keySelector: Converter<TElement, TKey>, elementSelector: Converter<TElement, TResult>, keyComparer?: EqualityComparison<TKey> | undefined): Sequence<GroupedSequence<TKey, TResult>>;
groupBy(keySelector: any, elementSelector?: any, keyComparer?: any) { groupBy(keySelector: any, elementSelector?: any, keyComparer?: any) {
return this.#sequence.groupBy(keySelector, elementSelector, keyComparer); return this.#sequence.groupBy(keySelector, elementSelector, keyComparer);
} }
join<TOther, TKey>(sequence: Iterable<TOther>, firstKeySelector: Converter<TElement, TKey>, secondKeySelector: Converter<TOther, TKey>, resultSelector?: undefined, keyComparer?: EqualityComparisonOrComparer<TKey> | undefined): Sequence<[TElement, TOther]>; join<TOther, TKey>(sequence: Iterable<TOther>, firstKeySelector: Converter<TElement, TKey>, secondKeySelector: Converter<TOther, TKey>, resultSelector?: undefined, keyComparer?: EqualityComparison<TKey> | undefined): Sequence<[TElement, TOther]>;
join<TOther, TKey, TResult>(sequence: Iterable<TOther>, firstKeySelector: Converter<TElement, TKey>, secondKeySelector: Converter<TOther, TKey>, resultSelector: BiConverter<TElement, TOther, TResult>, keyComparer?: EqualityComparisonOrComparer<TKey> | undefined): Sequence<TResult>; join<TOther, TKey, TResult>(sequence: Iterable<TOther>, firstKeySelector: Converter<TElement, TKey>, secondKeySelector: Converter<TOther, TKey>, resultSelector: BiConverter<TElement, TOther, TResult>, keyComparer?: EqualityComparison<TKey> | undefined): Sequence<TResult>;
join(sequence: any, firstKeySelector: any, secondKeySelector: any, resultSelector?: any, keyComparer?: any) { join(sequence: any, firstKeySelector: any, secondKeySelector: any, resultSelector?: any, keyComparer?: any) {
return this.#sequence.join(sequence, firstKeySelector, secondKeySelector, resultSelector, keyComparer); return this.#sequence.join(sequence, firstKeySelector, secondKeySelector, resultSelector, keyComparer);
} }
groupJoin<TOther, TKey>(sequence: Iterable<TOther>, firstKeySelector: Converter<TElement, TKey>, secondKeySelector: Converter<TOther, TKey>, resultSelector?: undefined, keyComparer?: EqualityComparisonOrComparer<TKey> | undefined): Sequence<GroupedSequence<TElement, TOther>>; groupJoin<TOther, TKey>(sequence: Iterable<TOther>, firstKeySelector: Converter<TElement, TKey>, secondKeySelector: Converter<TOther, TKey>, resultSelector?: undefined, keyComparer?: EqualityComparison<TKey> | undefined): Sequence<GroupedSequence<TElement, TOther>>;
groupJoin<TOther, TKey, TResult>(sequence: Iterable<TOther>, firstKeySelector: Converter<TElement, TKey>, secondKeySelector: Converter<TOther, TKey>, resultSelector: BiConverter<TElement, Iterable<TOther>, TResult>, keyComparer?: EqualityComparisonOrComparer<TKey> | undefined): Sequence<TResult>; groupJoin<TOther, TKey, TResult>(sequence: Iterable<TOther>, firstKeySelector: Converter<TElement, TKey>, secondKeySelector: Converter<TOther, TKey>, resultSelector: BiConverter<TElement, Iterable<TOther>, TResult>, keyComparer?: EqualityComparison<TKey> | undefined): Sequence<TResult>;
groupJoin(sequence: any, firstKeySelector: any, secondKeySelector: any, resultSelector?: any, keyComparer?: any) { groupJoin(sequence: any, firstKeySelector: any, secondKeySelector: any, resultSelector?: any, keyComparer?: any) {
return this.#sequence.groupJoin(sequence, firstKeySelector, secondKeySelector, resultSelector, keyComparer); return this.#sequence.groupJoin(sequence, firstKeySelector, secondKeySelector, resultSelector, keyComparer);
} }
contains(obj: TElement, equater?: EqualityComparisonOrComparer<TElement>) { contains(obj: TElement, equater?: EqualityComparison<TElement>) {
return this.#sequence.contains(obj, equater); return this.#sequence.contains(obj, equater);
} }
sequenceEquals(sequence: Iterable<TElement>, equater?: EqualityComparisonOrComparer<TElement>) { sequenceEquals(sequence: Iterable<TElement>, equater?: EqualityComparison<TElement>) {
return this.#sequence.sequenceEquals(sequence, equater); return this.#sequence.sequenceEquals(sequence, equater);
} }
@@ -867,7 +865,7 @@ export class DelegatedSequence<TElement> extends SequenceMarker implements Seque
return this.#sequence.prepend(obj); return this.#sequence.prepend(obj);
} }
remove(obj: TElement, all?: boolean, equater?: EqualityComparisonOrComparer<TElement>) { remove(obj: TElement, all?: boolean, equater?: EqualityComparison<TElement>) {
return this.#sequence.remove(obj, all, equater); return this.#sequence.remove(obj, all, equater);
} }
@@ -951,43 +949,43 @@ export class DelegatedSequence<TElement> extends SequenceMarker implements Seque
return this.#sequence.orderByDescending(selector, comparer); return this.#sequence.orderByDescending(selector, comparer);
} }
partition(equater?: EqualityComparisonOrComparer<TElement> | undefined): Sequence<Sequence<TElement>> { partition(equater?: EqualityComparison<TElement> | undefined): Sequence<Sequence<TElement>> {
return this.#sequence.partition(equater); return this.#sequence.partition(equater);
} }
partitionBy<TBy>(selector: Converter<TElement, TBy>, equater?: EqualityComparisonOrComparer<TBy> | undefined): Sequence<Sequence<TElement>> { partitionBy<TBy>(selector: Converter<TElement, TBy>, equater?: EqualityComparison<TBy> | undefined): Sequence<Sequence<TElement>> {
return this.#sequence.partitionBy(selector, equater); return this.#sequence.partitionBy(selector, equater);
} }
distinct(equater?: EqualityComparisonOrComparer<TElement>) { distinct(equater?: EqualityComparison<TElement>) {
return this.#sequence.distinct(equater); return this.#sequence.distinct(equater);
} }
distinctBy<TBy>(selector: Converter<TElement, TBy>, equater?: EqualityComparisonOrComparer<TBy>) { distinctBy<TBy>(selector: Converter<TElement, TBy>, equater?: EqualityComparison<TBy>) {
return this.#sequence.distinctBy(selector, equater); return this.#sequence.distinctBy(selector, equater);
} }
union(sequence: Iterable<TElement>, equater?: EqualityComparisonOrComparer<TElement>) { union(sequence: Iterable<TElement>, equater?: EqualityComparison<TElement>) {
return this.#sequence.union(sequence, equater); return this.#sequence.union(sequence, equater);
} }
unionBy<TBy>(sequence: Iterable<TElement>, selector: Converter<TElement, TBy>, equater?: EqualityComparisonOrComparer<TBy>) { unionBy<TBy>(sequence: Iterable<TElement>, selector: Converter<TElement, TBy>, equater?: EqualityComparison<TBy>) {
return this.#sequence.unionBy(sequence, selector, equater); return this.#sequence.unionBy(sequence, selector, equater);
} }
except(sequence: Iterable<TElement>, equater?: EqualityComparisonOrComparer<TElement>) { except(sequence: Iterable<TElement>, equater?: EqualityComparison<TElement>) {
return this.#sequence.except(sequence, equater); return this.#sequence.except(sequence, equater);
} }
exceptBy<TBy>(sequence: Iterable<TElement>, selector: Converter<TElement, TBy>, equater?: EqualityComparisonOrComparer<TBy>) { exceptBy<TBy>(sequence: Iterable<TElement>, selector: Converter<TElement, TBy>, equater?: EqualityComparison<TBy>) {
return this.#sequence.exceptBy(sequence, selector, equater); return this.#sequence.exceptBy(sequence, selector, equater);
} }
intersect(sequence: Iterable<TElement>, equater?: EqualityComparisonOrComparer<TElement>) { intersect(sequence: Iterable<TElement>, equater?: EqualityComparison<TElement>) {
return this.#sequence.intersect(sequence, equater); return this.#sequence.intersect(sequence, equater);
} }
intersectBy<TBy>(sequence: Iterable<TElement>, selector: Converter<TElement, TBy>, equater?: EqualityComparisonOrComparer<TBy>) { intersectBy<TBy>(sequence: Iterable<TElement>, selector: Converter<TElement, TBy>, equater?: EqualityComparison<TBy>) {
return this.#sequence.intersectBy(sequence, selector, equater); return this.#sequence.intersectBy(sequence, selector, equater);
} }
@@ -1043,10 +1041,6 @@ export class DelegatedSequence<TElement> extends SequenceMarker implements Seque
return this.#sequence.zip(sequence); return this.#sequence.zip(sequence);
} }
cartesianProduct<TOther>(sequence: Iterable<TOther>) {
return this.#sequence.cartesianProduct(sequence);
}
indexed() { indexed() {
return this.#sequence.indexed(); return this.#sequence.indexed();
} }
@@ -1374,10 +1368,9 @@ export class WrappedArray<T> extends BaseSequence<T> {
return this.#array.length; return this.#array.length;
} }
override contains(obj: T, equater?: EqualityComparisonOrComparer<T>): boolean { override contains(obj: T, equater?: EqualityComparison<T>): boolean {
if (equater) { if (equater) {
const equalityComparer = asEqualityComparer(equater); return this.#array.some(x => equater(x, obj));
return this.#array.some(x => equalityComparer.equals(x, obj));
} }
return this.#array.includes(obj); return this.#array.includes(obj);
@@ -1471,7 +1464,7 @@ export class WrappedSet<T> extends BaseSequence<T> {
return this.#set.size; return this.#set.size;
} }
override contains(obj: T, equater?: EqualityComparisonOrComparer<T>) { override contains(obj: T, equater?: EqualityComparison<T>) {
if (equater) { if (equater) {
return super.contains(obj, equater); return super.contains(obj, equater);
} }
@@ -1501,7 +1494,7 @@ export class WrappedMap<K, V> extends BaseSequence<[K, V]> {
return this.#map.size; return this.#map.size;
} }
override contains(obj: [K, V], equater?: EqualityComparisonOrComparer<[K, V]>) { override contains(obj: [K, V], equater?: EqualityComparison<[K, V]>) {
if (equater) { if (equater) {
return super.contains(obj, equater); return super.contains(obj, equater);
} }
@@ -1610,9 +1603,9 @@ export class ConcatSequence<T> extends BaseSequence<T> {
class DistinctSequence<T> extends BaseSequence<T> { class DistinctSequence<T> extends BaseSequence<T> {
readonly #sequence: Sequence<T>; readonly #sequence: Sequence<T>;
readonly #equater: EqualityComparisonOrComparer<T> | undefined; readonly #equater: EqualityComparison<T> | undefined;
constructor(sequence: Sequence<T>, equater?: EqualityComparisonOrComparer<T>) { constructor(sequence: Sequence<T>, equater?: EqualityComparison<T>) {
super(); super();
this.#sequence = sequence; this.#sequence = sequence;
@@ -1637,9 +1630,9 @@ class DistinctSequence<T> extends BaseSequence<T> {
class DistinctBySequence<T, U> extends BaseSequence<T> { class DistinctBySequence<T, U> extends BaseSequence<T> {
readonly #sequence: Sequence<T>; readonly #sequence: Sequence<T>;
readonly #converter: Converter<T, U>; readonly #converter: Converter<T, U>;
readonly #equater: EqualityComparisonOrComparer<U> | undefined; readonly #equater: EqualityComparison<U> | undefined;
constructor(sequence: Sequence<T>, converter: Converter<T, U>, equater?: EqualityComparisonOrComparer<U>) { constructor(sequence: Sequence<T>, converter: Converter<T, U>, equater?: EqualityComparison<U>) {
super(); super();
this.#sequence = sequence; this.#sequence = sequence;
@@ -1974,13 +1967,13 @@ class OrderBySequence<T, U> extends BaseOrderedSequence<T> {
class ThenOrderSequence<T> extends BaseOrderedSequence<T> { class ThenOrderSequence<T> extends BaseOrderedSequence<T> {
constructor(sequence: OrderedSequence<T>, descending: boolean, sorter?: ComparisonOrComparer<T>) { constructor(sequence: OrderedSequence<T>, descending: boolean, sorter?: ComparisonOrComparer<T>) {
super(sequence, combineComparers([sequence.comparer, sorter]), descending); super(sequence, combineNullableComparers([sequence.comparer, sorter]), descending);
} }
} }
class ThenOrderBySequence<T, U> extends BaseOrderedSequence<T> { class ThenOrderBySequence<T, U> extends BaseOrderedSequence<T> {
constructor(sequence: OrderedSequence<T>, descending: boolean, selector: Converter<T, U>, sorter?: ComparisonOrComparer<U>) { constructor(sequence: OrderedSequence<T>, descending: boolean, selector: Converter<T, U>, sorter?: ComparisonOrComparer<U>) {
super(sequence, combineComparers([sequence.comparer, createComparerUsing(selector, sorter)]), descending); super(sequence, combineNullableComparers([sequence.comparer, createComparerUsing(selector, sorter)]), descending);
} }
} }
@@ -2102,52 +2095,12 @@ export class ZippedSequence<T, U> extends BaseSequence<[T, U]> {
} }
} }
export class CartesianProductSequence<T, U> extends BaseSequence<[T, U]> {
readonly #first: Sequence<T>;
readonly #second: Sequence<U>;
constructor(first: Sequence<T>, second: Sequence<U>) {
super();
this.#first = first;
this.#second = second;
}
override nonEnumeratedCount() {
const n1 = this.#first.nonEnumeratedCount();
if (n1 < 0) {
return -1;
}
const n2 = this.#second.nonEnumeratedCount();
if (n2 < 0) {
return -1;
}
return n1 * n2;
}
override maxCount() {
return this.#first.maxCount() * this.#second.maxCount();
}
override *iterator() {
for (const firstObj of this.#first) {
for (const secondObj of this.#second) {
yield [firstObj, secondObj] as [T, U];
}
}
}
}
class UnionSequence<T> extends BaseSequence<T> { class UnionSequence<T> extends BaseSequence<T> {
readonly #first: Sequence<T>; readonly #first: Sequence<T>;
readonly #second: Sequence<T>; readonly #second: Sequence<T>;
readonly #equater: EqualityComparisonOrComparer<T> | undefined; readonly #equater: EqualityComparison<T> | undefined;
constructor(first: Sequence<T>, second: Sequence<T>, equater?: EqualityComparisonOrComparer<T>) { constructor(first: Sequence<T>, second: Sequence<T>, equater?: EqualityComparison<T>) {
super(); super();
this.#first = first; this.#first = first;
@@ -2179,9 +2132,9 @@ class UnionBySequence<T, U> extends BaseSequence<T> {
readonly #first: Sequence<T>; readonly #first: Sequence<T>;
readonly #second: Sequence<T>; readonly #second: Sequence<T>;
readonly #selector: Converter<T, U>; readonly #selector: Converter<T, U>;
readonly #equater: EqualityComparisonOrComparer<U> | undefined; readonly #equater: EqualityComparison<U> | undefined;
constructor(first: Sequence<T>, second: Sequence<T>, selector: Converter<T, U>, equater?: EqualityComparisonOrComparer<U>) { constructor(first: Sequence<T>, second: Sequence<T>, selector: Converter<T, U>, equater?: EqualityComparison<U>) {
super(); super();
this.#first = first; this.#first = first;
@@ -2213,9 +2166,9 @@ class UnionBySequence<T, U> extends BaseSequence<T> {
class ExceptSequence<T> extends BaseSequence<T> { class ExceptSequence<T> extends BaseSequence<T> {
readonly #first: Sequence<T>; readonly #first: Sequence<T>;
readonly #second: Sequence<T>; readonly #second: Sequence<T>;
readonly #equater: EqualityComparisonOrComparer<T> | undefined; readonly #equater: EqualityComparison<T> | undefined;
constructor(first: Sequence<T>, second: Sequence<T>, equater?: EqualityComparisonOrComparer<T>) { constructor(first: Sequence<T>, second: Sequence<T>, equater?: EqualityComparison<T>) {
super(); super();
this.#first = first; this.#first = first;
@@ -2246,9 +2199,9 @@ class ExceptBySequence<T, U> extends BaseSequence<T> {
readonly #first: Sequence<T>; readonly #first: Sequence<T>;
readonly #second: Sequence<T>; readonly #second: Sequence<T>;
readonly #selector: Converter<T, U>; readonly #selector: Converter<T, U>;
readonly #equater: EqualityComparisonOrComparer<U> | undefined; readonly #equater: EqualityComparison<U> | undefined;
constructor(first: Sequence<T>, second: Sequence<T>, selector: Converter<T, U>, equater?: EqualityComparisonOrComparer<U>) { constructor(first: Sequence<T>, second: Sequence<T>, selector: Converter<T, U>, equater?: EqualityComparison<U>) {
super(); super();
this.#first = first; this.#first = first;
@@ -2279,9 +2232,9 @@ class ExceptBySequence<T, U> extends BaseSequence<T> {
class IntersectSequence<T> extends BaseSequence<T> { class IntersectSequence<T> extends BaseSequence<T> {
readonly #first: Sequence<T>; readonly #first: Sequence<T>;
readonly #second: Sequence<T>; readonly #second: Sequence<T>;
readonly #equater: EqualityComparisonOrComparer<T> | undefined; readonly #equater: EqualityComparison<T> | undefined;
constructor(first: Sequence<T>, second: Sequence<T>, equater?: EqualityComparisonOrComparer<T>) { constructor(first: Sequence<T>, second: Sequence<T>, equater?: EqualityComparison<T>) {
super(); super();
this.#first = first; this.#first = first;
@@ -2310,9 +2263,9 @@ class IntersectBySequence<T, U> extends BaseSequence<T> {
readonly #first: Sequence<T>; readonly #first: Sequence<T>;
readonly #second: Sequence<T>; readonly #second: Sequence<T>;
readonly #selector: Converter<T, U>; readonly #selector: Converter<T, U>;
readonly #equater: EqualityComparisonOrComparer<U> | undefined; readonly #equater: EqualityComparison<U> | undefined;
constructor(first: Sequence<T>, second: Sequence<T>, selector: Converter<T, U>, equater?: EqualityComparisonOrComparer<U>) { constructor(first: Sequence<T>, second: Sequence<T>, selector: Converter<T, U>, equater?: EqualityComparison<U>) {
super(); super();
this.#first = first; this.#first = first;
@@ -2374,9 +2327,9 @@ class GroupBySequence<TElement, TKey, TResult> extends BaseSequence<GroupedSeque
readonly #sequence: Sequence<TElement>; readonly #sequence: Sequence<TElement>;
readonly #keySelector: Converter<TElement, TKey>; readonly #keySelector: Converter<TElement, TKey>;
readonly #elementSelector: Converter<TElement, TResult>; readonly #elementSelector: Converter<TElement, TResult>;
readonly #keyEquater: EqualityComparisonOrComparer<TKey> | undefined; readonly #keyEquater: EqualityComparison<TKey> | undefined;
constructor(sequence: Sequence<TElement>, keySelector: Converter<TElement, TKey>, elementSelector?: Converter<TElement, TResult>, keyEquater?: EqualityComparisonOrComparer<TKey>) { constructor(sequence: Sequence<TElement>, keySelector: Converter<TElement, TKey>, elementSelector?: Converter<TElement, TResult>, keyEquater?: EqualityComparison<TKey>) {
super(); super();
this.#sequence = sequence; this.#sequence = sequence;
@@ -2493,9 +2446,9 @@ class JoinSequence<TOuter, TInner, TKey, TResult> extends BaseSequence<TResult>
readonly #firstKeySelector: Converter<TOuter, TKey>; readonly #firstKeySelector: Converter<TOuter, TKey>;
readonly #secondKeySelector: Converter<TInner, TKey>; readonly #secondKeySelector: Converter<TInner, TKey>;
readonly #resultSelector: BiConverter<TOuter, TInner, TResult>; readonly #resultSelector: BiConverter<TOuter, TInner, TResult>;
readonly #keyEquater: EqualityComparer<TKey>; readonly #keyEquater: EqualityComparison<TKey>;
constructor(first: Sequence<TOuter>, second: Sequence<TInner>, firstKeySelector: Converter<TOuter, TKey>, secondKeySelector: Converter<TInner, TKey>, resultSelector?: BiConverter<TOuter, TInner, TResult>, keyEquater?: EqualityComparisonOrComparer<TKey>) { constructor(first: Sequence<TOuter>, second: Sequence<TInner>, firstKeySelector: Converter<TOuter, TKey>, secondKeySelector: Converter<TInner, TKey>, resultSelector?: BiConverter<TOuter, TInner, TResult>, keyEquater?: EqualityComparison<TKey>) {
super(); super();
this.#first = first; this.#first = first;
@@ -2503,7 +2456,7 @@ class JoinSequence<TOuter, TInner, TKey, TResult> extends BaseSequence<TResult>
this.#firstKeySelector = firstKeySelector; this.#firstKeySelector = firstKeySelector;
this.#secondKeySelector = secondKeySelector; this.#secondKeySelector = secondKeySelector;
this.#resultSelector = resultSelector ?? JoinSequence.#defaultResultSelector as BiConverter<TOuter, TInner, TResult>; this.#resultSelector = resultSelector ?? JoinSequence.#defaultResultSelector as BiConverter<TOuter, TInner, TResult>;
this.#keyEquater = keyEquater ? asEqualityComparer(keyEquater) : defaultEqualityComparer; this.#keyEquater = keyEquater ?? strictEquals;
} }
static #defaultResultSelector<TOuter, TInner>(first: TOuter, second: TInner): [TOuter, TInner] { static #defaultResultSelector<TOuter, TInner>(first: TOuter, second: TInner): [TOuter, TInner] {
@@ -2521,7 +2474,7 @@ class JoinSequence<TOuter, TInner, TKey, TResult> extends BaseSequence<TResult>
for (const secondObj of this.#second) { for (const secondObj of this.#second) {
const secondKey = this.#secondKeySelector(secondObj); const secondKey = this.#secondKeySelector(secondObj);
if (this.#keyEquater.equals(firstKey, secondKey)) { if (this.#keyEquater(firstKey, secondKey)) {
yield this.#resultSelector(firstObj, secondObj); yield this.#resultSelector(firstObj, secondObj);
} }
} }
@@ -2535,9 +2488,9 @@ class GroupJoinSequence<TOuter, TInner, TKey, TResult> extends BaseSequence<TRes
readonly #firstKeySelector: Converter<TOuter, TKey>; readonly #firstKeySelector: Converter<TOuter, TKey>;
readonly #secondKeySelector: Converter<TInner, TKey>; readonly #secondKeySelector: Converter<TInner, TKey>;
readonly #resultSelector: BiConverter<TOuter, Sequence<TInner>, TResult>; readonly #resultSelector: BiConverter<TOuter, Sequence<TInner>, TResult>;
readonly #keyEquater: EqualityComparer<TKey>; readonly #keyEquater: EqualityComparison<TKey>;
constructor(first: Sequence<TOuter>, second: Sequence<TInner>, firstKeySelector: Converter<TOuter, TKey>, secondKeySelector: Converter<TInner, TKey>, resultSelector?: BiConverter<TOuter, Sequence<TInner>, TResult>, keyEquater?: EqualityComparisonOrComparer<TKey>) { constructor(first: Sequence<TOuter>, second: Sequence<TInner>, firstKeySelector: Converter<TOuter, TKey>, secondKeySelector: Converter<TInner, TKey>, resultSelector?: BiConverter<TOuter, Sequence<TInner>, TResult>, keyEquater?: EqualityComparison<TKey>) {
super(); super();
this.#first = first; this.#first = first;
@@ -2545,7 +2498,7 @@ class GroupJoinSequence<TOuter, TInner, TKey, TResult> extends BaseSequence<TRes
this.#firstKeySelector = firstKeySelector; this.#firstKeySelector = firstKeySelector;
this.#secondKeySelector = secondKeySelector; this.#secondKeySelector = secondKeySelector;
this.#resultSelector = resultSelector ?? GroupJoinSequence.#defaultResultSelector as BiConverter<TOuter, Sequence<TInner>, TResult>; this.#resultSelector = resultSelector ?? GroupJoinSequence.#defaultResultSelector as BiConverter<TOuter, Sequence<TInner>, TResult>;
this.#keyEquater = keyEquater ? asEqualityComparer(keyEquater) : defaultEqualityComparer; this.#keyEquater = keyEquater ?? strictEquals;
} }
static #defaultResultSelector<TOuter, TInner>(first: TOuter, second: Sequence<TInner>) { static #defaultResultSelector<TOuter, TInner>(first: TOuter, second: Sequence<TInner>) {
@@ -2568,7 +2521,7 @@ class GroupJoinSequence<TOuter, TInner, TKey, TResult> extends BaseSequence<TRes
for (const secondObj of this.#second) { for (const secondObj of this.#second) {
const secondKey = this.#secondKeySelector(secondObj); const secondKey = this.#secondKeySelector(secondObj);
if (this.#keyEquater.equals(firstKey, secondKey)) { if (this.#keyEquater(firstKey, secondKey)) {
secondObjs.push(secondObj); secondObjs.push(secondObj);
} }
} }
@@ -2582,15 +2535,15 @@ class RemoveSequence<T> extends BaseSequence<T> {
readonly #sequence: Sequence<T>; readonly #sequence: Sequence<T>;
readonly #obj: T; readonly #obj: T;
readonly #all: boolean; readonly #all: boolean;
readonly #equater: EqualityComparer<T>; readonly #equater: EqualityComparison<T>;
constructor(sequence: Sequence<T>, obj: T, all?: boolean, equater?: EqualityComparisonOrComparer<T>) { constructor(sequence: Sequence<T>, obj: T, all?: boolean, equater?: EqualityComparison<T>) {
super(); super();
this.#sequence = sequence; this.#sequence = sequence;
this.#obj = obj; this.#obj = obj;
this.#all = all ?? false; this.#all = all ?? false;
this.#equater = equater ? asEqualityComparer(equater) : defaultEqualityComparer; this.#equater = equater ?? strictEquals;
} }
override maxCount() { override maxCount() {
@@ -2601,7 +2554,7 @@ class RemoveSequence<T> extends BaseSequence<T> {
let gotOne = false; let gotOne = false;
for (const obj of this.#sequence) { for (const obj of this.#sequence) {
if (this.#equater.equals(this.#obj, obj)) { if (this.#equater(this.#obj, obj)) {
if (this.#all) { if (this.#all) {
continue; continue;
} }
@@ -2645,13 +2598,13 @@ class CacheSequence<T> extends BaseSequence<T> {
class PartitionSequence<T> extends BaseSequence<Sequence<T>> { class PartitionSequence<T> extends BaseSequence<Sequence<T>> {
readonly #sequence: Sequence<T>; readonly #sequence: Sequence<T>;
readonly #equater: EqualityComparisonOrComparer<T> | undefined; readonly #equater: EqualityComparison<T>;
constructor(sequence: Sequence<T>, equater: EqualityComparisonOrComparer<T> | undefined) { constructor(sequence: Sequence<T>, equater: EqualityComparison<T> | undefined) {
super(); super();
this.#sequence = sequence; this.#sequence = sequence;
this.#equater = equater; this.#equater = equater ?? strictEquals;
} }
override *iterator() { override *iterator() {
@@ -2676,14 +2629,14 @@ class PartitionSequence<T> extends BaseSequence<Sequence<T>> {
class PartitionBySequence<TElement, TBy> extends BaseSequence<Sequence<TElement>> { class PartitionBySequence<TElement, TBy> extends BaseSequence<Sequence<TElement>> {
readonly #sequence: Sequence<TElement>; readonly #sequence: Sequence<TElement>;
readonly #selector: Converter<TElement, TBy>; readonly #selector: Converter<TElement, TBy>;
readonly #equater: EqualityComparisonOrComparer<TBy> | undefined; readonly #equater: EqualityComparison<TBy>;
constructor(sequence: Sequence<TElement>, selector: Converter<TElement, TBy>, equater: EqualityComparisonOrComparer<TBy> | undefined) { constructor(sequence: Sequence<TElement>, selector: Converter<TElement, TBy>, equater: EqualityComparison<TBy> | undefined) {
super(); super();
this.#sequence = sequence; this.#sequence = sequence;
this.#selector = selector; this.#selector = selector;
this.#equater = equater; this.#equater = equater ?? strictEquals;
} }
override *iterator() { override *iterator() {

View File

@@ -62,6 +62,10 @@ export function of<T>(...elements: T[]): Sequence<T> {
} }
} }
export function ofPropertyKeys<T extends PropertyKey>(...elements: T[]): Sequence<T> {
return of(...elements);
}
export function entries<T>(o: Record<string, T> | ArrayLike<T>): Sequence<[string, T]> { export function entries<T>(o: Record<string, T> | ArrayLike<T>): Sequence<[string, T]> {
return array(Object.entries(o)); return array(Object.entries(o));
} }
@@ -70,9 +74,7 @@ export function keys(o: object): Sequence<string> {
return array(Object.keys(o)); return array(Object.keys(o));
} }
export function values(o: object): Sequence<any>; export function values(o: object): Sequence<any> {
export function values<T>(o: Record<any, T> | ArrayLike<T>): Sequence<T>;
export function values(o: object) {
return array(Object.values(o)); return array(Object.values(o));
} }

View File

@@ -1,12 +1,11 @@
import { AsyncSequence } from "../async/types.js"; import { AsyncSequence } from "../async/types.js";
import { Collector } from "../collector/types.js"; import { Collector } from "../collector/types.js";
import { ComparisonOrComparer, Comparer } from "../comparer/types.js"; import { ComparisonOrComparer, Comparer } from "../comparer/types.js";
import { EqualityComparisonOrComparer } from "../equality-comparer/types.js"; import { EqualityComparison } from "../equality-comparer/types.js";
import { RandomOptions } from "../random/types.js"; import { RandomOptions } from "../random/types.js";
import { AnyPredicate, Converter, TypePredicate, BiConverter, Accumulator, Action } from "../types.js"; import { AnyPredicate, Converter, TypePredicate, BiConverter, Accumulator, Action } from "../types.js";
export type SequencePipeline<TElement, TResult> = (sequence: Sequence<TElement>) => TResult; export type SequencePipeline<TElement, TResult> = (sequence: Sequence<TElement>) => TResult;
export type SequenceElement<TSequence extends Sequence<any>> = TSequence extends Sequence<infer TElement> ? TElement : never;
export interface Sequence<TElement> extends Iterable<TElement> { export interface Sequence<TElement> extends Iterable<TElement> {
iterator(): Iterator<TElement>; iterator(): Iterator<TElement>;
@@ -26,24 +25,24 @@ export interface Sequence<TElement> extends Iterable<TElement> {
where<TFiltered extends TElement>(predicate: TypePredicate<TElement, TFiltered>): Sequence<TFiltered>; where<TFiltered extends TElement>(predicate: TypePredicate<TElement, TFiltered>): Sequence<TFiltered>;
where(predicate: AnyPredicate<TElement>): Sequence<TElement>; where(predicate: AnyPredicate<TElement>): Sequence<TElement>;
groupBy<TKey>(keySelector: Converter<TElement, TKey>, elementSelector?: undefined, keyComparer?: EqualityComparisonOrComparer<TKey>): Sequence<GroupedSequence<TKey, TElement>>; groupBy<TKey>(keySelector: Converter<TElement, TKey>, elementSelector?: undefined, keyComparer?: EqualityComparison<TKey>): Sequence<GroupedSequence<TKey, TElement>>;
groupBy<TKey, TResult>(keySelector: Converter<TElement, TKey>, elementSelector: Converter<TElement, TResult>, keyComparer?: EqualityComparisonOrComparer<TKey>): Sequence<GroupedSequence<TKey, TResult>>; groupBy<TKey, TResult>(keySelector: Converter<TElement, TKey>, elementSelector: Converter<TElement, TResult>, keyComparer?: EqualityComparison<TKey>): Sequence<GroupedSequence<TKey, TResult>>;
join<TOther, TKey>(sequence: Iterable<TOther>, firstKeySelector: Converter<TElement, TKey>, secondKeySelector: Converter<TOther, TKey>, resultSelector?: undefined, keyComparer?: EqualityComparisonOrComparer<TKey>): Sequence<[TElement, TOther]>; join<TOther, TKey>(sequence: Iterable<TOther>, firstKeySelector: Converter<TElement, TKey>, secondKeySelector: Converter<TOther, TKey>, resultSelector?: undefined, keyComparer?: EqualityComparison<TKey>): Sequence<[TElement, TOther]>;
join<TOther, TKey, TResult>(sequence: Iterable<TOther>, firstKeySelector: Converter<TElement, TKey>, secondKeySelector: Converter<TOther, TKey>, resultSelector: BiConverter<TElement, TOther, TResult>, keyComparer?: EqualityComparisonOrComparer<TKey>): Sequence<TResult>; join<TOther, TKey, TResult>(sequence: Iterable<TOther>, firstKeySelector: Converter<TElement, TKey>, secondKeySelector: Converter<TOther, TKey>, resultSelector: BiConverter<TElement, TOther, TResult>, keyComparer?: EqualityComparison<TKey>): Sequence<TResult>;
groupJoin<TOther, TKey>(sequence: Iterable<TOther>, firstKeySelector: Converter<TElement, TKey>, secondKeySelector: Converter<TOther, TKey>, resultSelector?: undefined, keyComparer?: EqualityComparisonOrComparer<TKey>): Sequence<GroupedSequence<TElement, TOther>>; groupJoin<TOther, TKey>(sequence: Iterable<TOther>, firstKeySelector: Converter<TElement, TKey>, secondKeySelector: Converter<TOther, TKey>, resultSelector?: undefined, keyComparer?: EqualityComparison<TKey>): Sequence<GroupedSequence<TElement, TOther>>;
groupJoin<TOther, TKey, TResult>(sequence: Iterable<TOther>, firstKeySelector: Converter<TElement, TKey>, secondKeySelector: Converter<TOther, TKey>, resultSelector: BiConverter<TElement, Iterable<TOther>, TResult>, keyComparer?: EqualityComparisonOrComparer<TKey>): Sequence<TResult>; groupJoin<TOther, TKey, TResult>(sequence: Iterable<TOther>, firstKeySelector: Converter<TElement, TKey>, secondKeySelector: Converter<TOther, TKey>, resultSelector: BiConverter<TElement, Iterable<TOther>, TResult>, keyComparer?: EqualityComparison<TKey>): Sequence<TResult>;
contains(obj: TElement, equater?: EqualityComparisonOrComparer<TElement>): boolean; contains(obj: TElement, equater?: EqualityComparison<TElement>): boolean;
sequenceEquals(sequence: Iterable<TElement>, equater?: EqualityComparisonOrComparer<TElement>): boolean; sequenceEquals(sequence: Iterable<TElement>, equater?: EqualityComparison<TElement>): boolean;
append(obj: TElement): Sequence<TElement>; append(obj: TElement): Sequence<TElement>;
prepend(obj: TElement): Sequence<TElement>; prepend(obj: TElement): Sequence<TElement>;
remove(obj: TElement, all?: boolean, equater?: EqualityComparisonOrComparer<TElement>): Sequence<TElement>; remove(obj: TElement, all?: boolean, equater?: EqualityComparison<TElement>): Sequence<TElement>;
concat(...sequences: Iterable<TElement>[]): Sequence<TElement>; concat(...sequences: Iterable<TElement>[]): Sequence<TElement>;
@@ -78,20 +77,20 @@ export interface Sequence<TElement> extends Iterable<TElement> {
orderDescending(comparer?: ComparisonOrComparer<TElement>): OrderedSequence<TElement>; orderDescending(comparer?: ComparisonOrComparer<TElement>): OrderedSequence<TElement>;
orderByDescending<TBy>(selector: Converter<TElement, TBy>, comparer?: ComparisonOrComparer<TBy>): OrderedSequence<TElement>; orderByDescending<TBy>(selector: Converter<TElement, TBy>, comparer?: ComparisonOrComparer<TBy>): OrderedSequence<TElement>;
partition(equater?: EqualityComparisonOrComparer<TElement>): Sequence<Sequence<TElement>>; partition(equater?: EqualityComparison<TElement>): Sequence<Sequence<TElement>>;
partitionBy<TBy>(selector: Converter<TElement, TBy>, equater?: EqualityComparisonOrComparer<TBy>): Sequence<Sequence<TElement>>; partitionBy<TBy>(selector: Converter<TElement, TBy>, equater?: EqualityComparison<TBy>): Sequence<Sequence<TElement>>;
distinct(equater?: EqualityComparisonOrComparer<TElement>): Sequence<TElement>; distinct(equater?: EqualityComparison<TElement>): Sequence<TElement>;
distinctBy<TBy>(selector: Converter<TElement, TBy>, equater?: EqualityComparisonOrComparer<TBy>): Sequence<TElement>; distinctBy<TBy>(selector: Converter<TElement, TBy>, equater?: EqualityComparison<TBy>): Sequence<TElement>;
union(sequence: Iterable<TElement>, equater?: EqualityComparisonOrComparer<TElement>): Sequence<TElement>; union(sequence: Iterable<TElement>, equater?: EqualityComparison<TElement>): Sequence<TElement>;
unionBy<TBy>(sequence: Iterable<TElement>, selector: Converter<TElement, TBy>, equater?: EqualityComparisonOrComparer<TBy>): Sequence<TElement>; unionBy<TBy>(sequence: Iterable<TElement>, selector: Converter<TElement, TBy>, equater?: EqualityComparison<TBy>): Sequence<TElement>;
except(sequence: Iterable<TElement>, equater?: EqualityComparisonOrComparer<TElement>): Sequence<TElement>; except(sequence: Iterable<TElement>, equater?: EqualityComparison<TElement>): Sequence<TElement>;
exceptBy<TBy>(sequence: Iterable<TElement>, selector: Converter<TElement, TBy>, equater?: EqualityComparisonOrComparer<TBy>): Sequence<TElement>; exceptBy<TBy>(sequence: Iterable<TElement>, selector: Converter<TElement, TBy>, equater?: EqualityComparison<TBy>): Sequence<TElement>;
intersect(sequence: Iterable<TElement>, equater?: EqualityComparisonOrComparer<TElement>): Sequence<TElement>; intersect(sequence: Iterable<TElement>, equater?: EqualityComparison<TElement>): Sequence<TElement>;
intersectBy<TBy>(sequence: Iterable<TElement>, selector: Converter<TElement, TBy>, equater?: EqualityComparisonOrComparer<TBy>): Sequence<TElement>; intersectBy<TBy>(sequence: Iterable<TElement>, selector: Converter<TElement, TBy>, equater?: EqualityComparison<TBy>): Sequence<TElement>;
all(predicate: AnyPredicate<TElement>): boolean; all(predicate: AnyPredicate<TElement>): boolean;
any(predicate: AnyPredicate<TElement>): boolean; any(predicate: AnyPredicate<TElement>): boolean;
@@ -112,7 +111,6 @@ export interface Sequence<TElement> extends Iterable<TElement> {
forEach(action: Action<TElement>): void; forEach(action: Action<TElement>): void;
zip<TOther>(sequence: Iterable<TOther>): Sequence<[TElement, TOther]>; zip<TOther>(sequence: Iterable<TOther>): Sequence<[TElement, TOther]>;
cartesianProduct<TOther>(sequence: Iterable<TOther>): Sequence<[TElement, TOther]>;
indexed(): Sequence<[number, TElement]>; indexed(): Sequence<[number, TElement]>;

View File

@@ -6,9 +6,13 @@
"lib": [ "lib": [
"ESNext" "ESNext"
], ],
"types": ["node"], "esModuleInterop": true,
"alwaysStrict": true, "alwaysStrict": true,
"strict": true, "strict": true,
"allowSyntheticDefaultImports": true,
"allowUnreachableCode": true,
"declaration": true,
"declarationMap": true,
"rootDir": "./src" "rootDir": "./src"
}, },
"include": [ "include": [