1
0
This commit is contained in:
2025-09-10 10:21:37 +02:00
parent 637991c394
commit 806d735c35
20 changed files with 480 additions and 259 deletions

248
package-lock.json generated
View File

@@ -16,9 +16,9 @@
} }
}, },
"node_modules/@esbuild/aix-ppc64": { "node_modules/@esbuild/aix-ppc64": {
"version": "0.25.4", "version": "0.25.9",
"resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.4.tgz", "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.9.tgz",
"integrity": "sha512-1VCICWypeQKhVbE9oW/sJaAmjLxhVqacdkvPLEjwlttjfwENRSClS8EjBz0KzRyFSCPDIkuXW34Je/vk7zdB7Q==", "integrity": "sha512-OaGtL73Jck6pBKjNIe24BnFE6agGl+6KxDtTfHhy1HmhthfKouEcOhqpSL64K4/0WCtbKFLOdzD/44cJ4k9opA==",
"cpu": [ "cpu": [
"ppc64" "ppc64"
], ],
@@ -33,9 +33,9 @@
} }
}, },
"node_modules/@esbuild/android-arm": { "node_modules/@esbuild/android-arm": {
"version": "0.25.4", "version": "0.25.9",
"resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.4.tgz", "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.9.tgz",
"integrity": "sha512-QNdQEps7DfFwE3hXiU4BZeOV68HHzYwGd0Nthhd3uCkkEKK7/R6MTgM0P7H7FAs5pU/DIWsviMmEGxEoxIZ+ZQ==", "integrity": "sha512-5WNI1DaMtxQ7t7B6xa572XMXpHAaI/9Hnhk8lcxF4zVN4xstUgTlvuGDorBguKEnZO70qwEcLpfifMLoxiPqHQ==",
"cpu": [ "cpu": [
"arm" "arm"
], ],
@@ -50,9 +50,9 @@
} }
}, },
"node_modules/@esbuild/android-arm64": { "node_modules/@esbuild/android-arm64": {
"version": "0.25.4", "version": "0.25.9",
"resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.4.tgz", "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.9.tgz",
"integrity": "sha512-bBy69pgfhMGtCnwpC/x5QhfxAz/cBgQ9enbtwjf6V9lnPI/hMyT9iWpR1arm0l3kttTr4L0KSLpKmLp/ilKS9A==", "integrity": "sha512-IDrddSmpSv51ftWslJMvl3Q2ZT98fUSL2/rlUXuVqRXHCs5EUF1/f+jbjF5+NG9UffUDMCiTyh8iec7u8RlTLg==",
"cpu": [ "cpu": [
"arm64" "arm64"
], ],
@@ -67,9 +67,9 @@
} }
}, },
"node_modules/@esbuild/android-x64": { "node_modules/@esbuild/android-x64": {
"version": "0.25.4", "version": "0.25.9",
"resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.4.tgz", "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.9.tgz",
"integrity": "sha512-TVhdVtQIFuVpIIR282btcGC2oGQoSfZfmBdTip2anCaVYcqWlZXGcdcKIUklfX2wj0JklNYgz39OBqh2cqXvcQ==", "integrity": "sha512-I853iMZ1hWZdNllhVZKm34f4wErd4lMyeV7BLzEExGEIZYsOzqDWDf+y082izYUE8gtJnYHdeDpN/6tUdwvfiw==",
"cpu": [ "cpu": [
"x64" "x64"
], ],
@@ -84,9 +84,9 @@
} }
}, },
"node_modules/@esbuild/darwin-arm64": { "node_modules/@esbuild/darwin-arm64": {
"version": "0.25.4", "version": "0.25.9",
"resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.4.tgz", "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.9.tgz",
"integrity": "sha512-Y1giCfM4nlHDWEfSckMzeWNdQS31BQGs9/rouw6Ub91tkK79aIMTH3q9xHvzH8d0wDru5Ci0kWB8b3up/nl16g==", "integrity": "sha512-XIpIDMAjOELi/9PB30vEbVMs3GV1v2zkkPnuyRRURbhqjyzIINwj+nbQATh4H9GxUgH1kFsEyQMxwiLFKUS6Rg==",
"cpu": [ "cpu": [
"arm64" "arm64"
], ],
@@ -101,9 +101,9 @@
} }
}, },
"node_modules/@esbuild/darwin-x64": { "node_modules/@esbuild/darwin-x64": {
"version": "0.25.4", "version": "0.25.9",
"resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.4.tgz", "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.9.tgz",
"integrity": "sha512-CJsry8ZGM5VFVeyUYB3cdKpd/H69PYez4eJh1W/t38vzutdjEjtP7hB6eLKBoOdxcAlCtEYHzQ/PJ/oU9I4u0A==", "integrity": "sha512-jhHfBzjYTA1IQu8VyrjCX4ApJDnH+ez+IYVEoJHeqJm9VhG9Dh2BYaJritkYK3vMaXrf7Ogr/0MQ8/MeIefsPQ==",
"cpu": [ "cpu": [
"x64" "x64"
], ],
@@ -118,9 +118,9 @@
} }
}, },
"node_modules/@esbuild/freebsd-arm64": { "node_modules/@esbuild/freebsd-arm64": {
"version": "0.25.4", "version": "0.25.9",
"resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.4.tgz", "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.9.tgz",
"integrity": "sha512-yYq+39NlTRzU2XmoPW4l5Ifpl9fqSk0nAJYM/V/WUGPEFfek1epLHJIkTQM6bBs1swApjO5nWgvr843g6TjxuQ==", "integrity": "sha512-z93DmbnY6fX9+KdD4Ue/H6sYs+bhFQJNCPZsi4XWJoYblUqT06MQUdBCpcSfuiN72AbqeBFu5LVQTjfXDE2A6Q==",
"cpu": [ "cpu": [
"arm64" "arm64"
], ],
@@ -135,9 +135,9 @@
} }
}, },
"node_modules/@esbuild/freebsd-x64": { "node_modules/@esbuild/freebsd-x64": {
"version": "0.25.4", "version": "0.25.9",
"resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.4.tgz", "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.9.tgz",
"integrity": "sha512-0FgvOJ6UUMflsHSPLzdfDnnBBVoCDtBTVyn/MrWloUNvq/5SFmh13l3dvgRPkDihRxb77Y17MbqbCAa2strMQQ==", "integrity": "sha512-mrKX6H/vOyo5v71YfXWJxLVxgy1kyt1MQaD8wZJgJfG4gq4DpQGpgTB74e5yBeQdyMTbgxp0YtNj7NuHN0PoZg==",
"cpu": [ "cpu": [
"x64" "x64"
], ],
@@ -152,9 +152,9 @@
} }
}, },
"node_modules/@esbuild/linux-arm": { "node_modules/@esbuild/linux-arm": {
"version": "0.25.4", "version": "0.25.9",
"resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.4.tgz", "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.9.tgz",
"integrity": "sha512-kro4c0P85GMfFYqW4TWOpvmF8rFShbWGnrLqlzp4X1TNWjRY3JMYUfDCtOxPKOIY8B0WC8HN51hGP4I4hz4AaQ==", "integrity": "sha512-HBU2Xv78SMgaydBmdor38lg8YDnFKSARg1Q6AT0/y2ezUAKiZvc211RDFHlEZRFNRVhcMamiToo7bDx3VEOYQw==",
"cpu": [ "cpu": [
"arm" "arm"
], ],
@@ -169,9 +169,9 @@
} }
}, },
"node_modules/@esbuild/linux-arm64": { "node_modules/@esbuild/linux-arm64": {
"version": "0.25.4", "version": "0.25.9",
"resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.4.tgz", "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.9.tgz",
"integrity": "sha512-+89UsQTfXdmjIvZS6nUnOOLoXnkUTB9hR5QAeLrQdzOSWZvNSAXAtcRDHWtqAUtAmv7ZM1WPOOeSxDzzzMogiQ==", "integrity": "sha512-BlB7bIcLT3G26urh5Dmse7fiLmLXnRlopw4s8DalgZ8ef79Jj4aUcYbk90g8iCa2467HX8SAIidbL7gsqXHdRw==",
"cpu": [ "cpu": [
"arm64" "arm64"
], ],
@@ -186,9 +186,9 @@
} }
}, },
"node_modules/@esbuild/linux-ia32": { "node_modules/@esbuild/linux-ia32": {
"version": "0.25.4", "version": "0.25.9",
"resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.4.tgz", "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.9.tgz",
"integrity": "sha512-yTEjoapy8UP3rv8dB0ip3AfMpRbyhSN3+hY8mo/i4QXFeDxmiYbEKp3ZRjBKcOP862Ua4b1PDfwlvbuwY7hIGQ==", "integrity": "sha512-e7S3MOJPZGp2QW6AK6+Ly81rC7oOSerQ+P8L0ta4FhVi+/j/v2yZzx5CqqDaWjtPFfYz21Vi1S0auHrap3Ma3A==",
"cpu": [ "cpu": [
"ia32" "ia32"
], ],
@@ -203,9 +203,9 @@
} }
}, },
"node_modules/@esbuild/linux-loong64": { "node_modules/@esbuild/linux-loong64": {
"version": "0.25.4", "version": "0.25.9",
"resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.4.tgz", "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.9.tgz",
"integrity": "sha512-NeqqYkrcGzFwi6CGRGNMOjWGGSYOpqwCjS9fvaUlX5s3zwOtn1qwg1s2iE2svBe4Q/YOG1q6875lcAoQK/F4VA==", "integrity": "sha512-Sbe10Bnn0oUAB2AalYztvGcK+o6YFFA/9829PhOCUS9vkJElXGdphz0A3DbMdP8gmKkqPmPcMJmJOrI3VYB1JQ==",
"cpu": [ "cpu": [
"loong64" "loong64"
], ],
@@ -220,9 +220,9 @@
} }
}, },
"node_modules/@esbuild/linux-mips64el": { "node_modules/@esbuild/linux-mips64el": {
"version": "0.25.4", "version": "0.25.9",
"resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.4.tgz", "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.9.tgz",
"integrity": "sha512-IcvTlF9dtLrfL/M8WgNI/qJYBENP3ekgsHbYUIzEzq5XJzzVEV/fXY9WFPfEEXmu3ck2qJP8LG/p3Q8f7Zc2Xg==", "integrity": "sha512-YcM5br0mVyZw2jcQeLIkhWtKPeVfAerES5PvOzaDxVtIyZ2NUBZKNLjC5z3/fUlDgT6w89VsxP2qzNipOaaDyA==",
"cpu": [ "cpu": [
"mips64el" "mips64el"
], ],
@@ -237,9 +237,9 @@
} }
}, },
"node_modules/@esbuild/linux-ppc64": { "node_modules/@esbuild/linux-ppc64": {
"version": "0.25.4", "version": "0.25.9",
"resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.4.tgz", "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.9.tgz",
"integrity": "sha512-HOy0aLTJTVtoTeGZh4HSXaO6M95qu4k5lJcH4gxv56iaycfz1S8GO/5Jh6X4Y1YiI0h7cRyLi+HixMR+88swag==", "integrity": "sha512-++0HQvasdo20JytyDpFvQtNrEsAgNG2CY1CLMwGXfFTKGBGQT3bOeLSYE2l1fYdvML5KUuwn9Z8L1EWe2tzs1w==",
"cpu": [ "cpu": [
"ppc64" "ppc64"
], ],
@@ -254,9 +254,9 @@
} }
}, },
"node_modules/@esbuild/linux-riscv64": { "node_modules/@esbuild/linux-riscv64": {
"version": "0.25.4", "version": "0.25.9",
"resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.4.tgz", "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.9.tgz",
"integrity": "sha512-i8JUDAufpz9jOzo4yIShCTcXzS07vEgWzyX3NH2G7LEFVgrLEhjwL3ajFE4fZI3I4ZgiM7JH3GQ7ReObROvSUA==", "integrity": "sha512-uNIBa279Y3fkjV+2cUjx36xkx7eSjb8IvnL01eXUKXez/CBHNRw5ekCGMPM0BcmqBxBcdgUWuUXmVWwm4CH9kg==",
"cpu": [ "cpu": [
"riscv64" "riscv64"
], ],
@@ -271,9 +271,9 @@
} }
}, },
"node_modules/@esbuild/linux-s390x": { "node_modules/@esbuild/linux-s390x": {
"version": "0.25.4", "version": "0.25.9",
"resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.4.tgz", "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.9.tgz",
"integrity": "sha512-jFnu+6UbLlzIjPQpWCNh5QtrcNfMLjgIavnwPQAfoGx4q17ocOU9MsQ2QVvFxwQoWpZT8DvTLooTvmOQXkO51g==", "integrity": "sha512-Mfiphvp3MjC/lctb+7D287Xw1DGzqJPb/J2aHHcHxflUo+8tmN/6d4k6I2yFR7BVo5/g7x2Monq4+Yew0EHRIA==",
"cpu": [ "cpu": [
"s390x" "s390x"
], ],
@@ -288,9 +288,9 @@
} }
}, },
"node_modules/@esbuild/linux-x64": { "node_modules/@esbuild/linux-x64": {
"version": "0.25.4", "version": "0.25.9",
"resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.4.tgz", "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.9.tgz",
"integrity": "sha512-6e0cvXwzOnVWJHq+mskP8DNSrKBr1bULBvnFLpc1KY+d+irZSgZ02TGse5FsafKS5jg2e4pbvK6TPXaF/A6+CA==", "integrity": "sha512-iSwByxzRe48YVkmpbgoxVzn76BXjlYFXC7NvLYq+b+kDjyyk30J0JY47DIn8z1MO3K0oSl9fZoRmZPQI4Hklzg==",
"cpu": [ "cpu": [
"x64" "x64"
], ],
@@ -305,9 +305,9 @@
} }
}, },
"node_modules/@esbuild/netbsd-arm64": { "node_modules/@esbuild/netbsd-arm64": {
"version": "0.25.4", "version": "0.25.9",
"resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.4.tgz", "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.9.tgz",
"integrity": "sha512-vUnkBYxZW4hL/ie91hSqaSNjulOnYXE1VSLusnvHg2u3jewJBz3YzB9+oCw8DABeVqZGg94t9tyZFoHma8gWZQ==", "integrity": "sha512-9jNJl6FqaUG+COdQMjSCGW4QiMHH88xWbvZ+kRVblZsWrkXlABuGdFJ1E9L7HK+T0Yqd4akKNa/lO0+jDxQD4Q==",
"cpu": [ "cpu": [
"arm64" "arm64"
], ],
@@ -322,9 +322,9 @@
} }
}, },
"node_modules/@esbuild/netbsd-x64": { "node_modules/@esbuild/netbsd-x64": {
"version": "0.25.4", "version": "0.25.9",
"resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.4.tgz", "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.9.tgz",
"integrity": "sha512-XAg8pIQn5CzhOB8odIcAm42QsOfa98SBeKUdo4xa8OvX8LbMZqEtgeWE9P/Wxt7MlG2QqvjGths+nq48TrUiKw==", "integrity": "sha512-RLLdkflmqRG8KanPGOU7Rpg829ZHu8nFy5Pqdi9U01VYtG9Y0zOG6Vr2z4/S+/3zIyOxiK6cCeYNWOFR9QP87g==",
"cpu": [ "cpu": [
"x64" "x64"
], ],
@@ -339,9 +339,9 @@
} }
}, },
"node_modules/@esbuild/openbsd-arm64": { "node_modules/@esbuild/openbsd-arm64": {
"version": "0.25.4", "version": "0.25.9",
"resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.4.tgz", "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.9.tgz",
"integrity": "sha512-Ct2WcFEANlFDtp1nVAXSNBPDxyU+j7+tId//iHXU2f/lN5AmO4zLyhDcpR5Cz1r08mVxzt3Jpyt4PmXQ1O6+7A==", "integrity": "sha512-YaFBlPGeDasft5IIM+CQAhJAqS3St3nJzDEgsgFixcfZeyGPCd6eJBWzke5piZuZ7CtL656eOSYKk4Ls2C0FRQ==",
"cpu": [ "cpu": [
"arm64" "arm64"
], ],
@@ -356,9 +356,9 @@
} }
}, },
"node_modules/@esbuild/openbsd-x64": { "node_modules/@esbuild/openbsd-x64": {
"version": "0.25.4", "version": "0.25.9",
"resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.4.tgz", "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.9.tgz",
"integrity": "sha512-xAGGhyOQ9Otm1Xu8NT1ifGLnA6M3sJxZ6ixylb+vIUVzvvd6GOALpwQrYrtlPouMqd/vSbgehz6HaVk4+7Afhw==", "integrity": "sha512-1MkgTCuvMGWuqVtAvkpkXFmtL8XhWy+j4jaSO2wxfJtilVCi0ZE37b8uOdMItIHz4I6z1bWWtEX4CJwcKYLcuA==",
"cpu": [ "cpu": [
"x64" "x64"
], ],
@@ -372,10 +372,27 @@
"node": ">=18" "node": ">=18"
} }
}, },
"node_modules/@esbuild/openharmony-arm64": {
"version": "0.25.9",
"resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.9.tgz",
"integrity": "sha512-4Xd0xNiMVXKh6Fa7HEJQbrpP3m3DDn43jKxMjxLLRjWnRsfxjORYJlXPO4JNcXtOyfajXorRKY9NkOpTHptErg==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"openharmony"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/sunos-x64": { "node_modules/@esbuild/sunos-x64": {
"version": "0.25.4", "version": "0.25.9",
"resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.4.tgz", "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.9.tgz",
"integrity": "sha512-Mw+tzy4pp6wZEK0+Lwr76pWLjrtjmJyUB23tHKqEDP74R3q95luY/bXqXZeYl4NYlvwOqoRKlInQialgCKy67Q==", "integrity": "sha512-WjH4s6hzo00nNezhp3wFIAfmGZ8U7KtrJNlFMRKxiI9mxEK1scOMAaa9i4crUtu+tBr+0IN6JCuAcSBJZfnphw==",
"cpu": [ "cpu": [
"x64" "x64"
], ],
@@ -390,9 +407,9 @@
} }
}, },
"node_modules/@esbuild/win32-arm64": { "node_modules/@esbuild/win32-arm64": {
"version": "0.25.4", "version": "0.25.9",
"resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.4.tgz", "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.9.tgz",
"integrity": "sha512-AVUP428VQTSddguz9dO9ngb+E5aScyg7nOeJDrF1HPYu555gmza3bDGMPhmVXL8svDSoqPCsCPjb265yG/kLKQ==", "integrity": "sha512-mGFrVJHmZiRqmP8xFOc6b84/7xa5y5YvR1x8djzXpJBSv/UsNK6aqec+6JDjConTgvvQefdGhFDAs2DLAds6gQ==",
"cpu": [ "cpu": [
"arm64" "arm64"
], ],
@@ -407,9 +424,9 @@
} }
}, },
"node_modules/@esbuild/win32-ia32": { "node_modules/@esbuild/win32-ia32": {
"version": "0.25.4", "version": "0.25.9",
"resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.4.tgz", "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.9.tgz",
"integrity": "sha512-i1sW+1i+oWvQzSgfRcxxG2k4I9n3O9NRqy8U+uugaT2Dy7kLO9Y7wI72haOahxceMX8hZAzgGou1FhndRldxRg==", "integrity": "sha512-b33gLVU2k11nVx1OhX3C8QQP6UHQK4ZtN56oFWvVXvz2VkDoe6fbG8TOgHFxEvqeqohmRnIHe5A1+HADk4OQww==",
"cpu": [ "cpu": [
"ia32" "ia32"
], ],
@@ -424,9 +441,9 @@
} }
}, },
"node_modules/@esbuild/win32-x64": { "node_modules/@esbuild/win32-x64": {
"version": "0.25.4", "version": "0.25.9",
"resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.4.tgz", "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.9.tgz",
"integrity": "sha512-nOT2vZNw6hJ+z43oP1SPea/G/6AbN6X+bGNhNuq8NtRHy4wsMhw765IKLNmnjek7GvjWBYQ8Q5VBoYTFg9y1UQ==", "integrity": "sha512-PPOl1mi6lpLNQxnGoyAfschAodRFYXJ+9fs6WHXz7CSWKbOqiMZsubC+BQsVKuul+3vKLuwTHsS2c2y9EoKwxQ==",
"cpu": [ "cpu": [
"x64" "x64"
], ],
@@ -441,9 +458,9 @@
} }
}, },
"node_modules/@types/node": { "node_modules/@types/node": {
"version": "22.15.21", "version": "22.18.1",
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.15.21.tgz", "resolved": "https://registry.npmjs.org/@types/node/-/node-22.18.1.tgz",
"integrity": "sha512-EV/37Td6c+MgKAbkcLG6vqZ2zEYHD7bvSrzqqs2RIhbA6w3x+Dqz8MZM3sP6kGTeLrdoOgKZe+Xja7tUB2DNkQ==", "integrity": "sha512-rzSDyhn4cYznVG+PCzGe1lwuMYJrcBS1fc3JqSa2PvtABwWo+dZ1ij5OVok3tqfpEBCBoaR4d7upFJk73HRJDw==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
@@ -451,9 +468,9 @@
} }
}, },
"node_modules/esbuild": { "node_modules/esbuild": {
"version": "0.25.4", "version": "0.25.9",
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.4.tgz", "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.9.tgz",
"integrity": "sha512-8pgjLUcUjcgDg+2Q4NYXnPbo/vncAY4UmyaCm0jZevERqCHZIaWwdJHkf8XQtu4AxSKCdvrUbT0XUr1IdZzI8Q==", "integrity": "sha512-CRbODhYyQx3qp7ZEwzxOk4JBqmD/seJrzPa/cGjY1VtIn5E09Oi9/dB4JwctnfZ8Q8iT7rioVv5k/FNT/uf54g==",
"dev": true, "dev": true,
"hasInstallScript": true, "hasInstallScript": true,
"license": "MIT", "license": "MIT",
@@ -464,31 +481,32 @@
"node": ">=18" "node": ">=18"
}, },
"optionalDependencies": { "optionalDependencies": {
"@esbuild/aix-ppc64": "0.25.4", "@esbuild/aix-ppc64": "0.25.9",
"@esbuild/android-arm": "0.25.4", "@esbuild/android-arm": "0.25.9",
"@esbuild/android-arm64": "0.25.4", "@esbuild/android-arm64": "0.25.9",
"@esbuild/android-x64": "0.25.4", "@esbuild/android-x64": "0.25.9",
"@esbuild/darwin-arm64": "0.25.4", "@esbuild/darwin-arm64": "0.25.9",
"@esbuild/darwin-x64": "0.25.4", "@esbuild/darwin-x64": "0.25.9",
"@esbuild/freebsd-arm64": "0.25.4", "@esbuild/freebsd-arm64": "0.25.9",
"@esbuild/freebsd-x64": "0.25.4", "@esbuild/freebsd-x64": "0.25.9",
"@esbuild/linux-arm": "0.25.4", "@esbuild/linux-arm": "0.25.9",
"@esbuild/linux-arm64": "0.25.4", "@esbuild/linux-arm64": "0.25.9",
"@esbuild/linux-ia32": "0.25.4", "@esbuild/linux-ia32": "0.25.9",
"@esbuild/linux-loong64": "0.25.4", "@esbuild/linux-loong64": "0.25.9",
"@esbuild/linux-mips64el": "0.25.4", "@esbuild/linux-mips64el": "0.25.9",
"@esbuild/linux-ppc64": "0.25.4", "@esbuild/linux-ppc64": "0.25.9",
"@esbuild/linux-riscv64": "0.25.4", "@esbuild/linux-riscv64": "0.25.9",
"@esbuild/linux-s390x": "0.25.4", "@esbuild/linux-s390x": "0.25.9",
"@esbuild/linux-x64": "0.25.4", "@esbuild/linux-x64": "0.25.9",
"@esbuild/netbsd-arm64": "0.25.4", "@esbuild/netbsd-arm64": "0.25.9",
"@esbuild/netbsd-x64": "0.25.4", "@esbuild/netbsd-x64": "0.25.9",
"@esbuild/openbsd-arm64": "0.25.4", "@esbuild/openbsd-arm64": "0.25.9",
"@esbuild/openbsd-x64": "0.25.4", "@esbuild/openbsd-x64": "0.25.9",
"@esbuild/sunos-x64": "0.25.4", "@esbuild/openharmony-arm64": "0.25.9",
"@esbuild/win32-arm64": "0.25.4", "@esbuild/sunos-x64": "0.25.9",
"@esbuild/win32-ia32": "0.25.4", "@esbuild/win32-arm64": "0.25.9",
"@esbuild/win32-x64": "0.25.4" "@esbuild/win32-ia32": "0.25.9",
"@esbuild/win32-x64": "0.25.9"
} }
}, },
"node_modules/fsevents": { "node_modules/fsevents": {
@@ -507,9 +525,9 @@
} }
}, },
"node_modules/get-tsconfig": { "node_modules/get-tsconfig": {
"version": "4.7.6", "version": "4.10.1",
"resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.7.6.tgz", "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.10.1.tgz",
"integrity": "sha512-ZAqrLlu18NbDdRaHq+AKXzAmqIUPswPWKUchfytdAjiRFnCe5ojG2bstg6mRiZabkKfCoL/e98pbBELIV/YCeA==", "integrity": "sha512-auHyJ4AgMz7vgS8Hp3N6HXSmlMdUyhSUrfBF16w153rxtLIEOE+HGqaBppczZvnHLqQJfiHotCYpNhl0lUROFQ==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
@@ -530,9 +548,9 @@
} }
}, },
"node_modules/tsx": { "node_modules/tsx": {
"version": "4.19.4", "version": "4.20.5",
"resolved": "https://registry.npmjs.org/tsx/-/tsx-4.19.4.tgz", "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.20.5.tgz",
"integrity": "sha512-gK5GVzDkJK1SI1zwHf32Mqxf2tSJkNx+eYcNly5+nHvWqXUJYUkWBQtKauoESz3ymezAI++ZwT855x5p5eop+Q==", "integrity": "sha512-+wKjMNU9w/EaQayHXb7WA7ZaHY6hN8WgfvHNQ3t1PnU91/7O8TcTnIhCDYTZwnt8JsO9IBqZ30Ln1r7pPF52Aw==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
@@ -550,9 +568,9 @@
} }
}, },
"node_modules/typescript": { "node_modules/typescript": {
"version": "5.8.3", "version": "5.9.2",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.3.tgz", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.2.tgz",
"integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==", "integrity": "sha512-CWBzXQrc/qOkhidw1OzBTQuYRbfyxDXJMVJ1XNwUHGROVmuaeiEm3OslpZ1RV96d7SKKjZKrSJu3+t/xlw3R9A==",
"dev": true, "dev": true,
"license": "Apache-2.0", "license": "Apache-2.0",
"bin": { "bin": {

View File

@@ -16,5 +16,15 @@
"esbuild": "^0.25.4", "esbuild": "^0.25.4",
"tsx": "^4.19.4", "tsx": "^4.19.4",
"typescript": "^5.8.3" "typescript": "^5.8.3"
},
"exports": {
".": {
"import": "./src/index.ts",
"types": "./src/index.ts"
},
"./*": {
"import": "./src/*.ts",
"types": "./src/*.ts"
}
} }
} }

View File

@@ -1,10 +1,10 @@
import { Collector } from "../collector/types.js"; import { Collector } from "../collector/types.js";
import { asAsyncComparer, combineNullableAsyncComparers, 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 { strictEquals } from "../equality-comparer/index.js"; import { strictEquals } from "../equality-comparer/sync.js";
import { MaybeAsyncEqualityComparison } from "../equality-comparer/types.js"; import { MaybeAsyncEqualityComparison } from "../equality-comparer/types.js";
import { createAsyncEqualityMap } from "../equality-map.js"; import { createAsyncEqualityMap } from "../equality-map/index.js";
import { createAsyncEqualitySet } from "../equality-set.js"; import { createAsyncEqualitySet } from "../equality-set/index.js";
import { createQueue } from "../queue.js"; import { createQueue } from "../queue.js";
import { getRandomElementAsync } from "../random/index.js"; import { getRandomElementAsync } from "../random/index.js";
import { AsyncRandomOptions } from "../random/types.js"; import { AsyncRandomOptions } from "../random/types.js";

View File

@@ -15,11 +15,11 @@ export function asComparison<T>(comparer: ComparisonOrComparer<T>) {
return typeof comparer === "function" ? comparer : comparer.comparison(); return typeof comparer === "function" ? comparer : comparer.comparison();
} }
export function createComparer<T>(comparison: Comparison<T>): Comparer<T> { export function createComparer<T = any>(comparison: Comparison<T>): Comparer<T> {
return new SimpleComparer(comparison); return new SimpleComparer(comparison);
} }
export function createComparerUsing<T, U>(projection: Converter<T, U>, comparison?: ComparisonOrComparer<U>): Comparer<T> { export function createComparerUsing<T = any, U = any>(projection: Converter<T, U>, comparison?: ComparisonOrComparer<U>): Comparer<T> {
return new MappedComparer(projection, comparison); return new MappedComparer(projection, comparison);
} }

View File

@@ -24,12 +24,9 @@ export interface AsyncComparer<T> {
export type Comparison<T> = (first: T, second: T) => number; export type Comparison<T> = (first: T, second: T) => number;
export type ComparisonOrComparer<T> = Comparison<T> | Comparer<T>; export type ComparisonOrComparer<T> = Comparison<T> | Comparer<T>;
export type Equater<T> = (first: T, second: T) => boolean;
export type AsyncComparison<T> = AsyncFunction<Comparison<T>>; export type AsyncComparison<T> = AsyncFunction<Comparison<T>>;
export type MaybeAsyncComparison<T> = MaybeAsyncFunction<Comparison<T>>; export type MaybeAsyncComparison<T> = MaybeAsyncFunction<Comparison<T>>;
export type AsyncComparisonOrComparer<T> = AsyncComparison<T> | AsyncComparer<T>; export type AsyncComparisonOrComparer<T> = AsyncComparison<T> | AsyncComparer<T>;
export type MaybeAsyncComparisonOrComparer<T> = MaybeAsyncComparison<T> | Comparer<T> | AsyncComparer<T>; export type MaybeAsyncComparisonOrComparer<T> = MaybeAsyncComparison<T> | Comparer<T> | AsyncComparer<T>;
export type AsyncEquater<T> = AsyncFunction<Equater<T>>;
export type MaybeAsyncEquater<T> = MaybeAsyncFunction<Equater<T>>;

View File

@@ -1,11 +0,0 @@
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);
}

View File

@@ -0,0 +1,167 @@
import { Converter } from "../types.js";
import { Nullable } from "../utils.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> {
return obj instanceof BaseEqualityComparer;
}
export function asEqualityComparer<T>(equalityComparer: EqualityComparisonOrComparer<T>) {
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> {
return new SimpleEqualityComparer(equalityComparison);
}
export function createEqualityComparerUsing<T = any, U = any>(projection: Converter<T, U>, equalityComparison?: EqualityComparisonOrComparer<U>): EqualityComparer<T> {
return new MappedEqualityComparer(projection, equalityComparison);
}
export function oppositeEqualityComparison<T>(equalityComparison: EqualityComparison<T>): EqualityComparison<T> {
return (a, b) => !equalityComparison(a, b);
}
export function combineNullableEqualityComparers<T>(equalityComparers: Nullable<EqualityComparisonOrComparer<T>>[]) {
let result = defaultEqualityComparer;
for (const equalityComparer of equalityComparers) {
if (!equalityComparer) {
continue;
}
result = result.then(asEqualityComparer(equalityComparer));
}
return result === defaultEqualityComparer ? undefined : result;
}
export abstract class BaseEqualityComparer<T> implements EqualityComparer<T> {
#cachedBoundEqualityComparison: EqualityComparison<T> | undefined;
public abstract equals(a: T, b: T): boolean;
public equalityComparison(): EqualityComparison<T> {
return this.#cachedBoundEqualityComparison ??= this.equals.bind(this);
}
public opposite(): EqualityComparer<T> {
return new OppositeEqualityComparer(this);
}
public then(equalityComparer: EqualityComparer<T>): EqualityComparer<T> {
return new ThenEqualityComparer(this, equalityComparer);
}
public thenEquals(equalityComparison: EqualityComparison<T>): EqualityComparer<T> {
return this.then(createEqualityComparer(equalityComparison));
}
public thenEqualsUsing<U>(projection: Converter<T, U>, equalityComparison?: EqualityComparisonOrComparer<U>): EqualityComparer<T> {
return this.then(createEqualityComparerUsing(projection, equalityComparison));
}
}
class SimpleEqualityComparer<T> extends BaseEqualityComparer<T> {
readonly #equalityComparison: EqualityComparison<T>;
public constructor(equalityComparison: EqualityComparison<T>) {
super();
this.#equalityComparison = equalityComparison;
}
public override equals(a: T, b: T): boolean {
return this.#equalityComparison(a, b);
}
public override equalityComparison() {
return this.#equalityComparison;
}
}
class MappedEqualityComparer<T, U> extends BaseEqualityComparer<T> {
readonly #projection: Converter<T, U>;
readonly #equalityComparison: EqualityComparer<U>;
public constructor(projection: Converter<T, U>, equalityComparison?: EqualityComparisonOrComparer<U>) {
super();
this.#projection = projection;
this.#equalityComparison = equalityComparison ? asEqualityComparer(equalityComparison) : defaultEqualityComparer;
}
public override equals(a: T, b: T): boolean {
return this.#equalityComparison.equals(this.#projection(a), this.#projection(b));
}
}
class OppositeEqualityComparer<T> extends BaseEqualityComparer<T> {
readonly #base: EqualityComparer<T>;
public constructor(base: EqualityComparer<T>) {
super();
this.#base = base;
}
public override equals(a: T, b: T): boolean {
return !this.#base.equals(a, b);
}
public override opposite(): EqualityComparer<T> {
return this.#base;
}
}
class ThenEqualityComparer<T> extends BaseEqualityComparer<T> {
readonly #base: EqualityComparer<T>;
readonly #equalityComparer: EqualityComparer<T>;
public constructor(base: EqualityComparer<T>, equalityComparer: EqualityComparer<T>) {
super();
this.#base = base;
this.#equalityComparer = equalityComparer;
}
public override equals(a: T, b: T) {
return this.#base.equals(a, b) && this.#equalityComparer.equals(a, b);
}
}
export const defaultEqualityComparer: EqualityComparer<any> = new class DefaultEqualityComparer extends BaseEqualityComparer<any> {
public override equals(a: any, b: any): boolean {
return a === b;
}
};
export function getDefaultComparer<T>(): EqualityComparer<T> {
return defaultEqualityComparer;
}
export const dateComparer: EqualityComparer<Date> = new class DateEqualityComparer extends BaseEqualityComparer<Date> {
public override equals(a: Date, b: Date): boolean {
return a.getTime() === b.getTime();
}
};
export const looseEqualsComparer: EqualityComparer<any> = new SimpleEqualityComparer<any>(looseEquals);
export const strictEqualsComparer: EqualityComparer<any> = new SimpleEqualityComparer<any>(strictEquals);
export const sameValueComparer: EqualityComparer<any> = new SimpleEqualityComparer<any>(sameValue);

View File

@@ -1,6 +1,15 @@
import { AsyncFunction, MaybeAsyncFunction } from "../types.js"; import { Converter, MaybeAsyncFunction } from "../types.js";
export interface EqualityComparer<T> {
equals(a: T, b: T): boolean;
equalityComparison(): EqualityComparison<T>;
opposite(): EqualityComparer<T>;
then(equalityComparer: EqualityComparer<T>): EqualityComparer<T>;
thenEquals(equalityComparison: EqualityComparison<T>): EqualityComparer<T>;
thenEqualsUsing<U>(projection: Converter<T, U>, equalityComparison?: EqualityComparisonOrComparer<U>): EqualityComparer<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 AsyncEqualityComparison<T> = AsyncFunction<EqualityComparison<T>>;
export type MaybeAsyncEqualityComparison<T> = MaybeAsyncFunction<EqualityComparison<T>>; export type MaybeAsyncEqualityComparison<T> = MaybeAsyncFunction<EqualityComparison<T>>;

View File

@@ -1,22 +1,9 @@
import { EqualityComparison, MaybeAsyncEqualityComparison } from "./equality-comparer/types.js"; import { asEqualityComparer } from "../equality-comparer/sync.js";
import { MaybeAsyncIterable } from "./types.js"; import { EqualityComparer, EqualityComparisonOrComparer, MaybeAsyncEqualityComparison } from "../equality-comparer/types.js";
import { MaybeAsyncIterable } from "../types.js";
import { AsyncEqualityMap, EqualityMap, EqualityMapEntry } from "./types.js";
export type Entry<K, V> = [key: K, value: V]; export class NativeEqualityMap<K, V> implements EqualityMap<K, V> {
export interface EqualityMap<K, V> extends Iterable<Entry<K, V>> {
readonly size: number;
get(key: K): V | undefined;
set(key: K, value: V): V | undefined;
setAll(entries: Iterable<Entry<K, V>>): void;
contains(key: K): boolean;
remove(key: K): V | undefined;
clear(): void;
keys(): IterableIterator<K>;
values(): IterableIterator<V>;
entries(): IterableIterator<Entry<K, V>>;
}
class NativeEqualityMap<K, V> implements EqualityMap<K, V> {
readonly #map = new Map<K, V>(); readonly #map = new Map<K, V>();
get size() { get size() {
@@ -33,7 +20,7 @@ class NativeEqualityMap<K, V> implements EqualityMap<K, V> {
return existing; return existing;
} }
setAll(entries: Iterable<Entry<K, V>>) { setAll(entries: Iterable<EqualityMapEntry<K, V>>) {
for (const [key, value] of entries) { for (const [key, value] of entries) {
this.set(key, value); this.set(key, value);
} }
@@ -70,12 +57,12 @@ class NativeEqualityMap<K, V> implements EqualityMap<K, V> {
} }
} }
class CustomEqualityMap<K, V> implements EqualityMap<K, V> { export class CustomEqualityMap<K, V> implements EqualityMap<K, V> {
readonly #list: Entry<K, V>[] = []; readonly #list: EqualityMapEntry<K, V>[] = [];
readonly #keyComparer: EqualityComparison<K>; readonly #keyComparer: EqualityComparer<K>;
constructor(keyComparer: EqualityComparison<K>) { constructor(keyComparer: EqualityComparisonOrComparer<K>) {
this.#keyComparer = keyComparer; this.#keyComparer = asEqualityComparer(keyComparer);
} }
get size() { get size() {
@@ -84,7 +71,7 @@ class CustomEqualityMap<K, V> implements EqualityMap<K, V> {
get(key: K) { get(key: K) {
for (const entry of this.#list) { for (const entry of this.#list) {
if (this.#keyComparer(key, entry[0])) { if (this.#keyComparer.equals(key, entry[0])) {
return entry[1]; return entry[1];
} }
} }
@@ -94,7 +81,7 @@ class CustomEqualityMap<K, V> implements EqualityMap<K, V> {
set(key: K, value: V) { set(key: K, value: V) {
for (const entry of this.#list) { for (const entry of this.#list) {
if (this.#keyComparer(key, entry[0])) { if (this.#keyComparer.equals(key, entry[0])) {
const previous = entry[1]; const previous = entry[1];
entry[1] = value; entry[1] = value;
return previous; return previous;
@@ -106,7 +93,7 @@ class CustomEqualityMap<K, V> implements EqualityMap<K, V> {
return undefined; return undefined;
} }
setAll(entries: Iterable<Entry<K, V>>) { setAll(entries: Iterable<EqualityMapEntry<K, V>>) {
for (const [key, value] of entries) { for (const [key, value] of entries) {
this.set(key, value); this.set(key, value);
} }
@@ -114,7 +101,7 @@ class CustomEqualityMap<K, V> implements EqualityMap<K, V> {
contains(key: K) { contains(key: K) {
for (const entry of this.#list) { for (const entry of this.#list) {
if (this.#keyComparer(key, entry[0])) { if (this.#keyComparer.equals(key, entry[0])) {
return true; return true;
} }
} }
@@ -124,7 +111,7 @@ class CustomEqualityMap<K, V> implements EqualityMap<K, V> {
remove(key: K) { remove(key: K) {
for (let i = 0; i < this.#list.length; i++) { for (let i = 0; i < this.#list.length; i++) {
if (this.#keyComparer(key, this.#list[i][0])) { if (this.#keyComparer.equals(key, this.#list[i][0])) {
const removed = this.#list.splice(i, 1); const removed = this.#list.splice(i, 1);
return removed[0][1]; return removed[0][1];
} }
@@ -155,29 +142,12 @@ class CustomEqualityMap<K, V> implements EqualityMap<K, V> {
*[Symbol.iterator]() { *[Symbol.iterator]() {
for (const entry of this.#list) { for (const entry of this.#list) {
yield entry.slice() as Entry<K, V>; // no entry mutation allowed! yield entry.slice() as EqualityMapEntry<K, V>; // no entry mutation allowed!
} }
} }
} }
export function createEqualityMap<K, V>(keyComparer?: EqualityComparison<K>): EqualityMap<K, V> { export class NativeAsyncEqualityMap<K, V> implements AsyncEqualityMap<K, V> {
return keyComparer ? new CustomEqualityMap<K, V>(keyComparer) : new NativeEqualityMap<K, V>();
}
export interface AsyncEqualityMap<K, V> extends Iterable<Entry<K, V>> {
readonly size: number;
get(key: K): Promise<V | undefined>;
set(key: K, value: V): Promise<V | undefined>;
setAll(entries: MaybeAsyncIterable<Entry<K, V>>): Promise<void>;
contains(key: K): Promise<boolean>;
remove(key: K): Promise<V | undefined>;
clear(): void;
keys(): IterableIterator<K>;
values(): IterableIterator<V>;
entries(): IterableIterator<Entry<K, V>>;
}
class NativeAsyncEqualityMap<K, V> implements AsyncEqualityMap<K, V> {
readonly #map = new Map<K, V>(); readonly #map = new Map<K, V>();
get size() { get size() {
@@ -194,7 +164,7 @@ class NativeAsyncEqualityMap<K, V> implements AsyncEqualityMap<K, V> {
return existing; return existing;
} }
async setAll(entries: MaybeAsyncIterable<Entry<K, V>>) { async setAll(entries: MaybeAsyncIterable<EqualityMapEntry<K, V>>) {
for await (const [key, value] of entries) { for await (const [key, value] of entries) {
await this.set(key, value); await this.set(key, value);
} }
@@ -231,8 +201,8 @@ class NativeAsyncEqualityMap<K, V> implements AsyncEqualityMap<K, V> {
} }
} }
class CustomAsyncEqualityMap<K, V> implements AsyncEqualityMap<K, V> { export class CustomAsyncEqualityMap<K, V> implements AsyncEqualityMap<K, V> {
readonly #list: Entry<K, V>[] = []; readonly #list: EqualityMapEntry<K, V>[] = [];
readonly #keyComparer: MaybeAsyncEqualityComparison<K>; readonly #keyComparer: MaybeAsyncEqualityComparison<K>;
constructor(keyComparer: MaybeAsyncEqualityComparison<K>) { constructor(keyComparer: MaybeAsyncEqualityComparison<K>) {
@@ -267,7 +237,7 @@ class CustomAsyncEqualityMap<K, V> implements AsyncEqualityMap<K, V> {
return undefined; return undefined;
} }
async setAll(entries: MaybeAsyncIterable<Entry<K, V>>) { async setAll(entries: MaybeAsyncIterable<EqualityMapEntry<K, V>>) {
for await (const [key, value] of entries) { for await (const [key, value] of entries) {
await this.set(key, value); await this.set(key, value);
} }
@@ -316,11 +286,7 @@ class CustomAsyncEqualityMap<K, V> implements AsyncEqualityMap<K, V> {
*[Symbol.iterator]() { *[Symbol.iterator]() {
for (const entry of this.#list) { for (const entry of this.#list) {
yield entry.slice() as Entry<K, V>; // no entry mutation allowed! yield entry.slice() as EqualityMapEntry<K, V>; // no entry mutation allowed!
} }
} }
} }
export function createAsyncEqualityMap<K, V>(keyComparer?: MaybeAsyncEqualityComparison<K>): AsyncEqualityMap<K, V> {
return keyComparer ? new CustomAsyncEqualityMap<K, V>(keyComparer) : new NativeAsyncEqualityMap<K, V>();
}

11
src/equality-map/index.ts Normal file
View File

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

29
src/equality-map/types.ts Normal file
View File

@@ -0,0 +1,29 @@
import { MaybeAsyncIterable } from "../types.js";
export type EqualityMapEntry<K, V> = [key: K, value: V];
export interface EqualityMap<K, V> extends Iterable<EqualityMapEntry<K, V>> {
readonly size: number;
get(key: K): V | undefined;
set(key: K, value: V): V | undefined;
setAll(entries: Iterable<EqualityMapEntry<K, V>>): void;
contains(key: K): boolean;
remove(key: K): V | undefined;
clear(): void;
keys(): IterableIterator<K>;
values(): IterableIterator<V>;
entries(): IterableIterator<EqualityMapEntry<K, V>>;
}
export interface AsyncEqualityMap<K, V> extends Iterable<EqualityMapEntry<K, V>> {
readonly size: number;
get(key: K): Promise<V | undefined>;
set(key: K, value: V): Promise<V | undefined>;
setAll(entries: MaybeAsyncIterable<EqualityMapEntry<K, V>>): Promise<void>;
contains(key: K): Promise<boolean>;
remove(key: K): Promise<V | undefined>;
clear(): void;
keys(): IterableIterator<K>;
values(): IterableIterator<V>;
entries(): IterableIterator<EqualityMapEntry<K, V>>;
}

View File

@@ -1,17 +1,9 @@
import { EqualityComparison, MaybeAsyncEqualityComparison } from "./equality-comparer/types.js"; import { asEqualityComparer } from "../equality-comparer/sync.js";
import { MaybeAsyncIterable } from "./types.js"; import { EqualityComparer, EqualityComparisonOrComparer, MaybeAsyncEqualityComparison } from "../equality-comparer/types.js";
import { MaybeAsyncIterable } from "../types.js";
import { AsyncEqualitySet, EqualitySet } from "./types.js";
export interface EqualitySet<T> extends Iterable<T> { export class NativeEqualitySet<T> implements EqualitySet<T> {
readonly size: number;
add(value: T): boolean;
addAll(values: Iterable<T>): number;
contains(value: T): boolean;
remove(value: T): boolean;
clear(): void;
values(): IterableIterator<T>;
}
class NativeEqualitySet<T> implements EqualitySet<T> {
readonly #set = new Set<T>(); readonly #set = new Set<T>();
get size() { get size() {
@@ -57,12 +49,12 @@ class NativeEqualitySet<T> implements EqualitySet<T> {
} }
} }
class CustomEqualitySet<T> implements EqualitySet<T> { export class CustomEqualitySet<T> implements EqualitySet<T> {
readonly #list: T[] = []; readonly #list: T[] = [];
readonly #equater: EqualityComparison<T>; readonly #equater: EqualityComparer<T>;
constructor(equater: EqualityComparison<T>) { constructor(equater: EqualityComparisonOrComparer<T>) {
this.#equater = equater; this.#equater = asEqualityComparer(equater);
} }
get size() { get size() {
@@ -93,7 +85,7 @@ class CustomEqualitySet<T> implements EqualitySet<T> {
contains(value: T) { contains(value: T) {
for (const val of this.#list) { for (const val of this.#list) {
if (this.#equater(value, val)) { if (this.#equater.equals(value, val)) {
return true; return true;
} }
} }
@@ -105,7 +97,7 @@ class CustomEqualitySet<T> implements EqualitySet<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 (this.#equater(value, this.#list[i])) { if (this.#equater.equals(value, this.#list[i])) {
this.#list.splice(i, 1); this.#list.splice(i, 1);
return true; return true;
} }
@@ -127,21 +119,7 @@ class CustomEqualitySet<T> implements EqualitySet<T> {
} }
} }
export function createEqualitySet<T>(equater?: EqualityComparison<T>): EqualitySet<T> { export class NativeAsyncEqualitySet<T> implements AsyncEqualitySet<T> {
return equater ? new CustomEqualitySet(equater) : new NativeEqualitySet<T>();
}
export interface AsyncEqualitySet<T> extends Iterable<T> {
readonly size: number;
add(value: T): Promise<boolean>;
addAll(values: MaybeAsyncIterable<T>): Promise<number>;
contains(value: T): Promise<boolean>;
remove(value: T): Promise<boolean>;
clear(): void;
values(): IterableIterator<T>;
}
class NativeAsyncEqualitySet<T> implements AsyncEqualitySet<T> {
readonly #set = new Set<T>(); readonly #set = new Set<T>();
get size() { get size() {
@@ -187,7 +165,7 @@ class NativeAsyncEqualitySet<T> implements AsyncEqualitySet<T> {
} }
} }
class CustomAsyncEqualitySet<T> implements AsyncEqualitySet<T> { export class CustomAsyncEqualitySet<T> implements AsyncEqualitySet<T> {
readonly #list: T[] = []; readonly #list: T[] = [];
readonly #equater: MaybeAsyncEqualityComparison<T>; readonly #equater: MaybeAsyncEqualityComparison<T>;
@@ -256,7 +234,3 @@ class CustomAsyncEqualitySet<T> implements AsyncEqualitySet<T> {
return this.#list[Symbol.iterator](); return this.#list[Symbol.iterator]();
} }
} }
export function createAsyncEqualitySet<T>(equater?: MaybeAsyncEqualityComparison<T>): AsyncEqualitySet<T> {
return equater ? new CustomAsyncEqualitySet(equater) : new NativeAsyncEqualitySet<T>();
}

11
src/equality-set/index.ts Normal file
View File

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

21
src/equality-set/types.ts Normal file
View File

@@ -0,0 +1,21 @@
import { MaybeAsyncIterable } from "../types.js";
export interface EqualitySet<T> extends Iterable<T> {
readonly size: number;
add(value: T): boolean;
addAll(values: Iterable<T>): number;
contains(value: T): boolean;
remove(value: T): boolean;
clear(): void;
values(): IterableIterator<T>;
}
export interface AsyncEqualitySet<T> extends Iterable<T> {
readonly size: number;
add(value: T): Promise<boolean>;
addAll(values: MaybeAsyncIterable<T>): Promise<number>;
contains(value: T): Promise<boolean>;
remove(value: T): Promise<boolean>;
clear(): void;
values(): IterableIterator<T>;
}

View File

@@ -15,5 +15,9 @@ 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 * as EqualityComparers from "./equality-comparer/index.js"; export * as EqualityComparers from "./equality-comparer/sync.js";
export * from "./equality-comparer/types.js"; export * from "./equality-comparer/types.js";
export * as EqualityMaps from "./equality-map/index.js";
export * from "./equality-map/types.js";
export * as EqualitySets from "./equality-set/index.js";
export * from "./equality-set/types.js";

View File

@@ -1,6 +1,6 @@
import { BitArray } from "../bitarray/index.js"; import { BitArray } from "../bitarray/index.js";
import { asArray } from "../utils.js"; import { asArray } from "../utils.js";
import { AsyncRandomOptions, ElementPredicate, ElementWeight, RandomGenerator, RandomOptions } from "./types.js"; import { AsyncRandomOptions, ElementPredicate, ElementWeight, RandomElement, RandomGenerator, RandomOptions } from "./types.js";
export const alwaysTrue: ElementPredicate = () => true; export const alwaysTrue: ElementPredicate = () => true;
export const weightOfOne: ElementWeight = () => 1.0; export const weightOfOne: ElementWeight = () => 1.0;
@@ -45,9 +45,10 @@ function withDefaultOptions<T>(options: RandomOptions<T> | AsyncRandomOptions<T>
}; };
} }
function _getRandomElement<T>(sequence: Iterable<T>, options: Required<RandomOptions<T>>) { function _getRandomElement<T>(sequence: Iterable<T>, options: Required<RandomOptions<T>>): RandomElement<T> {
const { predicate, weight, random } = options; const { predicate, weight, random } = options;
let found = false;
let result: T | undefined = undefined; let result: T | undefined = undefined;
let resultIndex = -1; let resultIndex = -1;
let index = 0; let index = 0;
@@ -66,22 +67,24 @@ function _getRandomElement<T>(sequence: Iterable<T>, options: Required<RandomOpt
weightAcc += w; weightAcc += w;
if (random() * weightAcc < w) { if (random() * weightAcc < w) {
found = true;
result = element; result = element;
resultIndex = currentIndex; resultIndex = currentIndex;
} }
} }
} }
return { element: result, index: resultIndex }; return { found, element: result, index: resultIndex } as RandomElement<T>;
} }
export function getRandomElement<T>(sequence: Iterable<T>, options?: RandomOptions<T>) { export function getRandomElement<T>(sequence: Iterable<T>, options?: RandomOptions<T>) {
return _getRandomElement(sequence, withDefaultOptions(options)); return _getRandomElement(sequence, withDefaultOptions(options));
} }
async function _getRandomElementAsync<T>(sequence: AsyncIterable<T>, options: Required<AsyncRandomOptions<T>>) { async function _getRandomElementAsync<T>(sequence: AsyncIterable<T>, options: Required<AsyncRandomOptions<T>>): Promise<RandomElement<T>> {
const { predicate, weight, random } = options; const { predicate, weight, random } = options;
let found = false;
let result: T | undefined = undefined; let result: T | undefined = undefined;
let resultIndex = -1; let resultIndex = -1;
let index = 0; let index = 0;
@@ -100,13 +103,14 @@ async function _getRandomElementAsync<T>(sequence: AsyncIterable<T>, options: Re
weightAcc += w; weightAcc += w;
if (random() * weightAcc < w) { if (random() * weightAcc < w) {
found = true;
result = element; result = element;
resultIndex = currentIndex; resultIndex = currentIndex;
} }
} }
} }
return { element: result, index: resultIndex }; return { found, element: result, index: resultIndex } as RandomElement<T>;
} }
export async function getRandomElementAsync<T>(sequence: AsyncIterable<T>, options?: AsyncRandomOptions<T>) { export async function getRandomElementAsync<T>(sequence: AsyncIterable<T>, options?: AsyncRandomOptions<T>) {

View File

@@ -4,7 +4,7 @@ export type ElementPredicate<T = any> = (index: number, obj: T) => boolean;
export type ElementWeight<T = any> = (index: number, obj: T) => number; export type ElementWeight<T = any> = (index: number, obj: T) => number;
export type RandomGenerator = () => number; export type RandomGenerator = () => number;
export interface RandomOptions<T = any> { export type RandomOptions<T = any> = {
predicate?: ElementPredicate<T>; predicate?: ElementPredicate<T>;
weight?: ElementWeight<T>; weight?: ElementWeight<T>;
random?: RandomGenerator; random?: RandomGenerator;
@@ -13,8 +13,20 @@ export interface RandomOptions<T = any> {
export type MaybeAsyncElementPredicate<T = any> = MaybeAsyncFunction<ElementPredicate<T>>; export type MaybeAsyncElementPredicate<T = any> = MaybeAsyncFunction<ElementPredicate<T>>;
export type MaybeAsyncElementWeight<T = any> = MaybeAsyncFunction<ElementWeight<T>>; export type MaybeAsyncElementWeight<T = any> = MaybeAsyncFunction<ElementWeight<T>>;
export interface AsyncRandomOptions<T = any> { export type AsyncRandomOptions<T = any> = {
predicate?: MaybeAsyncElementPredicate<T>; predicate?: MaybeAsyncElementPredicate<T>;
weight?: MaybeAsyncElementWeight<T>; weight?: MaybeAsyncElementWeight<T>;
random?: RandomGenerator; random?: RandomGenerator;
}; };
type RandomElementFound<T> = {
found: true;
element: T;
index: number;
};
type RandomElementNotFound = {
found: false;
element: undefined;
index: -1;
};
export type RandomElement<T> = RandomElementFound<T> | RandomElementNotFound;

View File

@@ -3,10 +3,10 @@ import { AsyncSequence } from "../async/types.js";
import { Collector } from "../collector/types.js"; import { Collector } from "../collector/types.js";
import { asComparer, combineNullableComparers, 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 { strictEquals } from "../equality-comparer/index.js"; import { strictEquals } from "../equality-comparer/sync.js";
import { EqualityComparison } from "../equality-comparer/types.js"; import { EqualityComparison } from "../equality-comparer/types.js";
import { createEqualityMap } from "../equality-map.js"; import { createEqualityMap } from "../equality-map/index.js";
import { createEqualitySet } from "../equality-set.js"; import { createEqualitySet } from "../equality-set/index.js";
import { createQueue } from "../queue.js"; import { createQueue } from "../queue.js";
import { getRandomElement } from "../random/index.js"; import { getRandomElement } from "../random/index.js";
import { RandomOptions } from "../random/types.js"; import { RandomOptions } from "../random/types.js";

View File

@@ -9,7 +9,7 @@ export function wrap<T = any>(iterable: Iterable<T>): Sequence<T> {
} }
if (Array.isArray(iterable)) { if (Array.isArray(iterable)) {
return array(iterable); return array<T>(iterable);
} }
if (iterable instanceof Set) { if (iterable instanceof Set) {
@@ -20,7 +20,7 @@ export function wrap<T = any>(iterable: Iterable<T>): Sequence<T> {
return map(iterable) as unknown as Sequence<T>; return map(iterable) as unknown as Sequence<T>;
} }
return sequence(iterable); return sequence<T>(iterable);
} }
export function sequence<T = any>(iterable: Iterable<T>): Sequence<T> { export function sequence<T = any>(iterable: Iterable<T>): Sequence<T> {
@@ -86,9 +86,9 @@ export function generator<T>(generator: () => Iterable<T>): Sequence<T> {
return new GeneratorSequence(generator); return new GeneratorSequence(generator);
} }
export function range(max: number): Sequence<number> export function range(max: number): Sequence<number>;
export function range(min: number, max: number): Sequence<number> export function range(min: number, max: number): Sequence<number>;
export function range(min: number, max: number, step: number): Sequence<number> export function range(min: number, max: number, step: number): Sequence<number>;
export function range(a: number, b?: number, c?: number): Sequence<number> { export function range(a: number, b?: number, c?: number): Sequence<number> {
if (b === undefined) { if (b === undefined) {
b = a; b = a;
@@ -102,9 +102,9 @@ export function range(a: number, b?: number, c?: number): Sequence<number> {
return new RangeSequence(a, b, c); return new RangeSequence(a, b, c);
} }
export function bigintRange(max: bigint): Sequence<bigint> export function bigintRange(max: bigint): Sequence<bigint>;
export function bigintRange(min: bigint, max: bigint): Sequence<bigint> export function bigintRange(min: bigint, max: bigint): Sequence<bigint>;
export function bigintRange(min: bigint, max: bigint, step: bigint): Sequence<bigint> export function bigintRange(min: bigint, max: bigint, step: bigint): Sequence<bigint>;
export function bigintRange(a: bigint, b?: bigint, c?: bigint): Sequence<bigint> { export function bigintRange(a: bigint, b?: bigint, c?: bigint): Sequence<bigint> {
if (b === undefined) { if (b === undefined) {
b = a; b = a;

View File

@@ -1,11 +1,11 @@
{ {
"compilerOptions": { "compilerOptions": {
"module": "NodeNext", "module": "nodenext",
"target": "ESNext", "target": "esnext",
"moduleResolution": "nodenext", "moduleResolution": "nodenext",
"rootDir": "src", "lib": [
"outDir": "build", "ESNext"
"outFile": "build/index.ts", ],
"esModuleInterop": true, "esModuleInterop": true,
"alwaysStrict": true, "alwaysStrict": true,
"strict": true, "strict": true,
@@ -13,10 +13,9 @@
"allowUnreachableCode": true, "allowUnreachableCode": true,
"declaration": true, "declaration": true,
"declarationMap": true, "declarationMap": true,
"emitDeclarationOnly": true, "rootDir": "./src"
"composite": true
}, },
"include": [ "include": [
"src" "./src"
] ]
} }