diff --git a/.github/workflows/docker.yaml b/.github/workflows/docker.yaml
index fccaf634..f0a79f53 100644
--- a/.github/workflows/docker.yaml
+++ b/.github/workflows/docker.yaml
@@ -152,6 +152,26 @@ jobs:
BASE_IMAGE=ghcr.io/${{ github.repository_owner }}/base:latest
labels: ${{ steps.meta-january.outputs.labels }}
+ # revoltchat/gifbox
+ - name: Docker meta
+ id: meta-gifbox
+ uses: docker/metadata-action@v4
+ with:
+ images: |
+ docker.io/revoltchat/gifbox
+ ghcr.io/revoltchat/gifbox
+ - name: Publish
+ uses: docker/build-push-action@v4
+ with:
+ context: .
+ push: true
+ platforms: linux/amd64,linux/arm64
+ file: crates/services/gifbox/Dockerfile
+ tags: ${{ steps.meta-gifbox.outputs.tags }}
+ build-args: |
+ BASE_IMAGE=ghcr.io/${{ github.repository_owner }}/base:latest
+ labels: ${{ steps.meta-gifbox.outputs.labels }}
+
# revoltchat/crond
- name: Docker meta
id: meta-crond
diff --git a/Cargo.lock b/Cargo.lock
index 794391c0..8843305f 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -125,12 +125,6 @@ dependencies = [
"tokio 1.47.1",
]
-[[package]]
-name = "android-tzdata"
-version = "0.1.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0"
-
[[package]]
name = "android_system_properties"
version = "0.1.5"
@@ -142,9 +136,9 @@ dependencies = [
[[package]]
name = "anyhow"
-version = "1.0.99"
+version = "1.0.100"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b0674a1ddeecb70197781e945de4b3b8ffb61fa939a5597bcf48503737663100"
+checksum = "a23eb6b1614318a8071c9b2521f36b424b2c83db5eb3a0fead4a6c0809af6e61"
dependencies = [
"backtrace",
]
@@ -250,20 +244,20 @@ dependencies = [
[[package]]
name = "async-io"
-version = "2.5.0"
+version = "2.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "19634d6336019ef220f09fd31168ce5c184b295cbf80345437cc36094ef223ca"
+checksum = "456b8a8feb6f42d237746d4b3e9a178494627745c3c56c6ea55d92ba50d026fc"
dependencies = [
- "async-lock 3.4.1",
+ "autocfg 1.5.0",
"cfg-if",
"concurrent-queue",
"futures-io",
"futures-lite 2.6.1",
"parking",
- "polling 3.10.0",
- "rustix 1.0.8",
+ "polling 3.11.0",
+ "rustix",
"slab",
- "windows-sys 0.60.2",
+ "windows-sys 0.61.0",
]
[[package]]
@@ -288,9 +282,9 @@ dependencies = [
[[package]]
name = "async-process"
-version = "2.4.0"
+version = "2.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "65daa13722ad51e6ab1a1b9c01299142bc75135b337923cfa10e79bbbd669f00"
+checksum = "fc50921ec0055cdd8a16de48773bfeec5c972598674347252c0399676be7da75"
dependencies = [
"async-channel 2.5.0",
"async-io",
@@ -301,7 +295,7 @@ dependencies = [
"cfg-if",
"event-listener 5.4.1",
"futures-lite 2.6.1",
- "rustix 1.0.8",
+ "rustix",
]
[[package]]
@@ -317,9 +311,9 @@ dependencies = [
[[package]]
name = "async-signal"
-version = "0.2.12"
+version = "0.2.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f567af260ef69e1d52c2b560ce0ea230763e6fbb9214a85d768760a920e3e3c1"
+checksum = "43c070bbf59cd3570b6b2dd54cd772527c7c3620fce8be898406dd3ed6adc64c"
dependencies = [
"async-io",
"async-lock 3.4.1",
@@ -327,10 +321,10 @@ dependencies = [
"cfg-if",
"futures-core",
"futures-io",
- "rustix 1.0.8",
+ "rustix",
"signal-hook-registry",
"slab",
- "windows-sys 0.60.2",
+ "windows-sys 0.61.0",
]
[[package]]
@@ -569,9 +563,9 @@ dependencies = [
[[package]]
name = "aws-lc-rs"
-version = "1.13.3"
+version = "1.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5c953fe1ba023e6b7730c0d4b031d06f267f23a46167dcbd40316644b10a17ba"
+checksum = "94b8ff6c09cd57b16da53641caa860168b88c172a5ee163b0288d3d6eea12786"
dependencies = [
"aws-lc-sys",
"zeroize",
@@ -579,9 +573,9 @@ dependencies = [
[[package]]
name = "aws-lc-sys"
-version = "0.30.0"
+version = "0.31.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dbfd150b5dbdb988bcc8fb1fe787eb6b7ee6180ca24da683b61ea5405f3d43ff"
+checksum = "0e44d16778acaf6a9ec9899b92cebd65580b83f685446bf2e1f5d3d732f99dcd"
dependencies = [
"bindgen",
"cc",
@@ -617,9 +611,9 @@ dependencies = [
[[package]]
name = "aws-sdk-s3"
-version = "1.104.0"
+version = "1.106.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "38c488cd6abb0ec9811c401894191932e941c5f91dc226043edacd0afa1634bc"
+checksum = "2c230530df49ed3f2b7b4d9c8613b72a04cdac6452eede16d587fc62addfabac"
dependencies = [
"aws-credential-types",
"aws-runtime",
@@ -651,9 +645,9 @@ dependencies = [
[[package]]
name = "aws-sdk-sso"
-version = "1.83.0"
+version = "1.84.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "643cd43af212d2a1c4dedff6f044d7e1961e5d9e7cfe773d70f31d9842413886"
+checksum = "357a841807f6b52cb26123878b3326921e2a25faca412fabdd32bd35b7edd5d3"
dependencies = [
"aws-credential-types",
"aws-runtime",
@@ -673,9 +667,9 @@ dependencies = [
[[package]]
name = "aws-sdk-ssooidc"
-version = "1.84.0"
+version = "1.85.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "20ec4a95bd48e0db7a424356a161f8d87bd6a4f0af37204775f0da03d9e39fc3"
+checksum = "67e05f33b6c9026fecfe9b3b6740f34d41bc6ff641a6a32dabaab60209245b75"
dependencies = [
"aws-credential-types",
"aws-runtime",
@@ -695,9 +689,9 @@ dependencies = [
[[package]]
name = "aws-sdk-sts"
-version = "1.85.0"
+version = "1.86.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "410309ad0df4606bc721aff0d89c3407682845453247213a0ccc5ff8801ee107"
+checksum = "e7d835f123f307cafffca7b9027c14979f1d403b417d8541d67cf252e8a21e35"
dependencies = [
"aws-credential-types",
"aws-runtime",
@@ -828,11 +822,11 @@ dependencies = [
"hyper-util",
"pin-project-lite 0.2.16",
"rustls 0.21.12",
- "rustls 0.23.31",
+ "rustls 0.23.32",
"rustls-native-certs 0.8.1",
"rustls-pki-types",
"tokio 1.47.1",
- "tokio-rustls 0.26.2",
+ "tokio-rustls 0.26.3",
"tower",
"tracing",
]
@@ -867,9 +861,9 @@ dependencies = [
[[package]]
name = "aws-smithy-runtime"
-version = "1.9.1"
+version = "1.9.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d3946acbe1ead1301ba6862e712c7903ca9bb230bdf1fbd1b5ac54158ef2ab1f"
+checksum = "4fa63ad37685ceb7762fa4d73d06f1d5493feb88e3f27259b9ed277f4c01b185"
dependencies = [
"aws-smithy-async",
"aws-smithy-http",
@@ -963,6 +957,7 @@ checksum = "edca88bc138befd0323b20752846e6587272d3b03b0343c8ea28a6f819e6e71f"
dependencies = [
"async-trait",
"axum-core",
+ "axum-macros",
"bytes 1.10.1",
"futures-util",
"http 1.3.1",
@@ -1169,16 +1164,14 @@ dependencies = [
[[package]]
name = "bindgen"
-version = "0.69.5"
+version = "0.72.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "271383c67ccabffb7381723dea0672a673f292304fcb45c01cc648c7a8d58088"
+checksum = "993776b509cfb49c750f11b8f07a46fa23e0a1386ffc01fb1e7d343efc387895"
dependencies = [
"bitflags 2.9.4",
"cexpr",
"clang-sys",
- "itertools 0.12.1",
- "lazy_static",
- "lazycell",
+ "itertools 0.13.0",
"log",
"prettyplease",
"proc-macro2",
@@ -1187,7 +1180,6 @@ dependencies = [
"rustc-hash",
"shlex",
"syn 2.0.106",
- "which",
]
[[package]]
@@ -1283,7 +1275,7 @@ dependencies = [
"getrandom 0.2.16",
"getrandom 0.3.3",
"hex",
- "indexmap 2.11.0",
+ "indexmap 2.11.4",
"js-sys",
"once_cell",
"rand 0.9.2",
@@ -1390,9 +1382,9 @@ checksum = "a2698f953def977c68f935bb0dfa959375ad4638570e969e2f1e9f433cbf1af6"
[[package]]
name = "cc"
-version = "1.2.36"
+version = "1.2.38"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5252b3d2648e5eedbc1a6f501e3c795e07025c1e93bbf8bbdd6eef7f447a6d54"
+checksum = "80f41ae168f955c12fb8960b057d70d0ca153fb83182b57d86380443527be7e9"
dependencies = [
"find-msvc-tools",
"jobserver",
@@ -1438,17 +1430,16 @@ checksum = "2fd1289c04a9ea8cb22300a459a72a385d7c73d3259e2ed7dcb2af674838cfa9"
[[package]]
name = "chrono"
-version = "0.4.41"
+version = "0.4.42"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c469d952047f47f91b68d1cba3f10d63c11d73e4636f24f08daf0278abf01c4d"
+checksum = "145052bdd345b87320e369255277e3fb5152762ad123a901ef5c262dd38fe8d2"
dependencies = [
- "android-tzdata",
"iana-time-zone",
"js-sys",
"num-traits",
"serde",
"wasm-bindgen",
- "windows-link",
+ "windows-link 0.2.0",
]
[[package]]
@@ -1883,6 +1874,16 @@ dependencies = [
"darling_macro 0.20.11",
]
+[[package]]
+name = "darling"
+version = "0.21.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9cdf337090841a411e2a7f3deb9187445851f91b309c0c0a29e05f74a00a48c0"
+dependencies = [
+ "darling_core 0.21.3",
+ "darling_macro 0.21.3",
+]
+
[[package]]
name = "darling_core"
version = "0.13.4"
@@ -1925,6 +1926,20 @@ dependencies = [
"syn 2.0.106",
]
+[[package]]
+name = "darling_core"
+version = "0.21.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1247195ecd7e3c85f83c8d2a366e4210d588e802133e1e355180a9870b517ea4"
+dependencies = [
+ "fnv",
+ "ident_case",
+ "proc-macro2",
+ "quote 1.0.40",
+ "strsim 0.11.1",
+ "syn 2.0.106",
+]
+
[[package]]
name = "darling_macro"
version = "0.13.4"
@@ -1958,6 +1973,17 @@ dependencies = [
"syn 2.0.106",
]
+[[package]]
+name = "darling_macro"
+version = "0.21.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d38308df82d1080de0afee5d069fa14b0326a88c14f15c5ccda35b4a6c414c81"
+dependencies = [
+ "darling_core 0.21.3",
+ "quote 1.0.40",
+ "syn 2.0.106",
+]
+
[[package]]
name = "dashmap"
version = "5.5.3"
@@ -2342,9 +2368,9 @@ dependencies = [
[[package]]
name = "enum-iterator-derive"
-version = "1.4.0"
+version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a1ab991c1362ac86c61ab6f556cff143daa22e5a15e4e189df818b2fd19fe65b"
+checksum = "685adfa4d6f3d765a26bc5dbc936577de9abf756c1feeb3089b01dd395034842"
dependencies = [
"proc-macro2",
"quote 1.0.40",
@@ -2401,12 +2427,12 @@ dependencies = [
[[package]]
name = "errno"
-version = "0.3.13"
+version = "0.3.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "778e2ac28f6c47af28e4907f13ffd1e1ddbd400980a9abd7c8df189bf578a5ad"
+checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb"
dependencies = [
"libc",
- "windows-sys 0.60.2",
+ "windows-sys 0.61.0",
]
[[package]]
@@ -2563,9 +2589,9 @@ dependencies = [
[[package]]
name = "find-msvc-tools"
-version = "0.1.1"
+version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7fd99930f64d146689264c637b5af2f0233a933bef0d8570e2526bf9e083192d"
+checksum = "1ced73b1dacfc750a6db6c0a0c3a3853c8b41997e2e2c563dc90804ae6867959"
[[package]]
name = "findshlibs"
@@ -2939,7 +2965,7 @@ dependencies = [
"js-sys",
"libc",
"r-efi",
- "wasi 0.14.4+wasi-0.2.4",
+ "wasi 0.14.7+wasi-0.2.4",
"wasm-bindgen",
]
@@ -3046,7 +3072,7 @@ dependencies = [
"futures-sink",
"futures-util",
"http 0.2.12",
- "indexmap 2.11.0",
+ "indexmap 2.11.4",
"slab",
"tokio 1.47.1",
"tokio-util",
@@ -3065,7 +3091,7 @@ dependencies = [
"futures-core",
"futures-sink",
"http 1.3.1",
- "indexmap 2.11.0",
+ "indexmap 2.11.4",
"slab",
"tokio 1.47.1",
"tokio-util",
@@ -3132,6 +3158,12 @@ dependencies = [
"foldhash",
]
+[[package]]
+name = "hashbrown"
+version = "0.16.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5419bdc4f6a9207fbeba6d11b604d481addf78ecd10c11ad51e76c2f6482748d"
+
[[package]]
name = "headers"
version = "0.4.1"
@@ -3276,15 +3308,6 @@ dependencies = [
"digest",
]
-[[package]]
-name = "home"
-version = "0.5.11"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "589533453244b0995c858700322199b2becb13b627df2851f64a2775d024abcf"
-dependencies = [
- "windows-sys 0.59.0",
-]
-
[[package]]
name = "hostname"
version = "0.3.1"
@@ -3477,11 +3500,11 @@ dependencies = [
"http 1.3.1",
"hyper 1.7.0",
"hyper-util",
- "rustls 0.23.31",
+ "rustls 0.23.32",
"rustls-native-certs 0.8.1",
"rustls-pki-types",
"tokio 1.47.1",
- "tokio-rustls 0.26.2",
+ "tokio-rustls 0.26.3",
"tower-service",
]
@@ -3516,9 +3539,9 @@ dependencies = [
[[package]]
name = "hyper-util"
-version = "0.1.16"
+version = "0.1.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8d9b05277c7e8da2c93a568989bb6207bef0112e8d17df7a6eda4a3cf143bc5e"
+checksum = "3c6995591a8f1380fcb4ba966a252a4b29188d51d2b89e3a252f5305be65aea8"
dependencies = [
"base64 0.22.1",
"bytes 1.10.1",
@@ -3542,9 +3565,9 @@ dependencies = [
[[package]]
name = "iana-time-zone"
-version = "0.1.63"
+version = "0.1.64"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b0c919e5debc312ad217002b8048a17b7d83f80703865bbfcfebb0458b0b27d8"
+checksum = "33e57f83510bb73707521ebaffa789ec8caf86f9657cad665b092b581d40e9fb"
dependencies = [
"android_system_properties",
"core-foundation-sys",
@@ -3552,7 +3575,7 @@ dependencies = [
"js-sys",
"log",
"wasm-bindgen",
- "windows-core",
+ "windows-core 0.62.0",
]
[[package]]
@@ -3789,13 +3812,14 @@ dependencies = [
[[package]]
name = "indexmap"
-version = "2.11.0"
+version = "2.11.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f2481980430f9f78649238835720ddccc57e52df14ffce1c6f37391d61b563e9"
+checksum = "4b0f83760fb341a774ed326568e19f5a863af4a952def8c39f9ab92fd95b88e5"
dependencies = [
"equivalent",
- "hashbrown 0.15.5",
+ "hashbrown 0.16.0",
"serde",
+ "serde_core",
]
[[package]]
@@ -3951,6 +3975,15 @@ dependencies = [
"either",
]
+[[package]]
+name = "itertools"
+version = "0.13.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186"
+dependencies = [
+ "either",
+]
+
[[package]]
name = "itoa"
version = "1.0.15"
@@ -3969,9 +4002,9 @@ dependencies = [
[[package]]
name = "js-sys"
-version = "0.3.78"
+version = "0.3.80"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0c0b063578492ceec17683ef2f8c5e89121fbd0b172cbc280635ab7567db2738"
+checksum = "852f13bec5eba4ba9afbeb93fd7c13fe56147f055939ae21c43a29a0ecb2702e"
dependencies = [
"once_cell",
"wasm-bindgen",
@@ -4220,12 +4253,6 @@ dependencies = [
"spin",
]
-[[package]]
-name = "lazycell"
-version = "1.3.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55"
-
[[package]]
name = "lebe"
version = "0.5.3"
@@ -4357,15 +4384,9 @@ dependencies = [
[[package]]
name = "linux-raw-sys"
-version = "0.4.15"
+version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab"
-
-[[package]]
-name = "linux-raw-sys"
-version = "0.9.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cd945864f07fe9f5371a27ad7b52a172b4b499999f1d97574c9fa68373937e12"
+checksum = "df1d3c3b53da64cf5760482273a98e575c651a67eec7f77df96b5b642de8f039"
[[package]]
name = "litemap"
@@ -4552,6 +4573,15 @@ dependencies = [
"hashbrown 0.15.5",
]
+[[package]]
+name = "lru"
+version = "0.16.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bfe949189f46fabb938b3a9a0be30fdd93fd8a09260da863399a8cf3db756ec8"
+dependencies = [
+ "hashbrown 0.15.5",
+]
+
[[package]]
name = "lru-cache"
version = "0.1.2"
@@ -4840,7 +4870,7 @@ dependencies = [
"percent-encoding",
"rand 0.8.5",
"rustc_version_runtime",
- "rustls 0.23.31",
+ "rustls 0.23.32",
"rustversion",
"serde",
"serde_bytes",
@@ -4853,7 +4883,7 @@ dependencies = [
"take_mut",
"thiserror 1.0.69",
"tokio 1.47.1",
- "tokio-rustls 0.26.2",
+ "tokio-rustls 0.26.3",
"tokio-util",
"typed-builder",
"uuid",
@@ -5410,9 +5440,9 @@ checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220"
[[package]]
name = "pest"
-version = "2.8.1"
+version = "2.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1db05f56d34358a8b1066f67cbb203ee3e7ed2ba674a6263a1d5ec6db2204323"
+checksum = "21e0a3a33733faeaf8651dfee72dd0f388f0c8e5ad496a3478fa5a922f49cfa8"
dependencies = [
"memchr",
"thiserror 2.0.16",
@@ -5421,9 +5451,9 @@ dependencies = [
[[package]]
name = "pest_derive"
-version = "2.8.1"
+version = "2.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bb056d9e8ea77922845ec74a1c4e8fb17e7c218cc4fc11a15c5d25e189aa40bc"
+checksum = "bc58706f770acb1dbd0973e6530a3cff4746fb721207feb3a8a6064cd0b6c663"
dependencies = [
"pest",
"pest_generator",
@@ -5431,9 +5461,9 @@ dependencies = [
[[package]]
name = "pest_generator"
-version = "2.8.1"
+version = "2.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "87e404e638f781eb3202dc82db6760c8ae8a1eeef7fb3fa8264b2ef280504966"
+checksum = "6d4f36811dfe07f7b8573462465d5cb8965fffc2e71ae377a33aecf14c2c9a2f"
dependencies = [
"pest",
"pest_meta",
@@ -5444,9 +5474,9 @@ dependencies = [
[[package]]
name = "pest_meta"
-version = "2.8.1"
+version = "2.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "edd1101f170f5903fde0914f899bb503d9ff5271d7ba76bbb70bea63690cc0d5"
+checksum = "42919b05089acbd0a5dcd5405fb304d17d1053847b81163d09c4ad18ce8e8420"
dependencies = [
"pest",
"sha2",
@@ -5459,7 +5489,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b4c5cc86750666a3ed20bdaf5ca2a0344f9c67674cae0515bec2da16fbaa47db"
dependencies = [
"fixedbitset",
- "indexmap 2.11.0",
+ "indexmap 2.11.4",
]
[[package]]
@@ -5647,12 +5677,12 @@ checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c"
[[package]]
name = "plist"
-version = "1.7.4"
+version = "1.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3af6b589e163c5a788fab00ce0c0366f6efbb9959c2f9874b224936af7fce7e1"
+checksum = "740ebea15c5d1428f910cd1a5f52cebf8d25006245ed8ade92702f4943d91e07"
dependencies = [
"base64 0.22.1",
- "indexmap 2.11.0",
+ "indexmap 2.11.4",
"quick-xml",
"serde",
"time",
@@ -5702,16 +5732,16 @@ dependencies = [
[[package]]
name = "polling"
-version = "3.10.0"
+version = "3.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b5bd19146350fe804f7cb2669c851c03d69da628803dab0d98018142aaa5d829"
+checksum = "5d0e4f59085d47d8241c88ead0f274e8a0cb551f3625263c05eb8dd897c34218"
dependencies = [
"cfg-if",
"concurrent-queue",
"hermit-abi 0.5.2",
"pin-project-lite 0.2.16",
- "rustix 1.0.8",
- "windows-sys 0.60.2",
+ "rustix",
+ "windows-sys 0.61.0",
]
[[package]]
@@ -5957,9 +5987,9 @@ dependencies = [
[[package]]
name = "pxfm"
-version = "0.1.23"
+version = "0.1.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f55f4fedc84ed39cb7a489322318976425e42a147e2be79d8f878e2884f94e84"
+checksum = "83f9b339b02259ada5c0f4a389b7fb472f933aa17ce176fd2ad98f28bb401fde"
dependencies = [
"num-traits",
]
@@ -6475,9 +6505,9 @@ dependencies = [
[[package]]
name = "resolv-conf"
-version = "0.7.4"
+version = "0.7.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "95325155c684b1c89f7765e30bc1c42e4a6da51ca513615660cb8a62ef9a88e3"
+checksum = "6b3789b30bd25ba102de4beabd95d21ac45b69b1be7d14522bab988c526d6799"
[[package]]
name = "resvg"
@@ -6515,6 +6545,7 @@ dependencies = [
"revolt-config",
"revolt-database",
"revolt-files",
+ "revolt-ratelimits",
"revolt-result",
"revolt_clamav-client",
"serde",
@@ -6550,6 +6581,7 @@ dependencies = [
"once_cell",
"querystring",
"redis-kiss",
+ "regex",
"revolt-config",
"revolt-database",
"revolt-models",
@@ -6563,6 +6595,15 @@ dependencies = [
"ulid 0.5.0",
]
+[[package]]
+name = "revolt-coalesced"
+version = "0.8.8"
+dependencies = [
+ "indexmap 2.11.4",
+ "lru 0.16.1",
+ "tokio 1.47.1",
+]
+
[[package]]
name = "revolt-config"
version = "0.8.8"
@@ -6675,6 +6716,7 @@ dependencies = [
"revolt-models",
"revolt-permissions",
"revolt-presence",
+ "revolt-ratelimits",
"revolt-result",
"revolt_rocket_okapi",
"rocket",
@@ -6714,6 +6756,28 @@ dependencies = [
"webp",
]
+[[package]]
+name = "revolt-gifbox"
+version = "0.8.8"
+dependencies = [
+ "axum",
+ "axum-extra",
+ "lru_time_cache",
+ "reqwest 0.12.23",
+ "revolt-coalesced",
+ "revolt-config",
+ "revolt-database",
+ "revolt-models",
+ "revolt-ratelimits",
+ "revolt-result",
+ "serde",
+ "serde_json",
+ "tokio 1.47.1",
+ "tracing",
+ "utoipa",
+ "utoipa-scalar",
+]
+
[[package]]
name = "revolt-january"
version = "0.8.8"
@@ -6823,6 +6887,23 @@ dependencies = [
"web-push",
]
+[[package]]
+name = "revolt-ratelimits"
+version = "0.8.8"
+dependencies = [
+ "async-trait",
+ "authifier",
+ "axum",
+ "dashmap",
+ "log",
+ "revolt-config",
+ "revolt-database",
+ "revolt-result",
+ "revolt_rocket_okapi",
+ "rocket",
+ "serde",
+]
+
[[package]]
name = "revolt-result"
version = "0.8.8"
@@ -7027,7 +7108,7 @@ dependencies = [
"either",
"figment",
"futures",
- "indexmap 2.11.0",
+ "indexmap 2.11.4",
"log",
"memchr",
"multer",
@@ -7075,7 +7156,7 @@ checksum = "575d32d7ec1a9770108c879fc7c47815a80073f96ca07ff9525a94fcede1dd46"
dependencies = [
"devise",
"glob",
- "indexmap 2.11.0",
+ "indexmap 2.11.4",
"proc-macro2",
"quote 1.0.40",
"rocket_http",
@@ -7122,7 +7203,7 @@ dependencies = [
"futures",
"http 0.2.12",
"hyper 0.14.32",
- "indexmap 2.11.0",
+ "indexmap 2.11.4",
"log",
"memchr",
"pear",
@@ -7216,9 +7297,9 @@ checksum = "56f7d92ca342cea22a06f2121d944b4fd82af56988c270852495420f961d4ace"
[[package]]
name = "rustc-hash"
-version = "1.1.0"
+version = "2.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
+checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d"
[[package]]
name = "rustc_version"
@@ -7241,28 +7322,15 @@ dependencies = [
[[package]]
name = "rustix"
-version = "0.38.44"
+version = "1.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154"
+checksum = "cd15f8a2c5551a84d56efdc1cd049089e409ac19a3072d5037a17fd70719ff3e"
dependencies = [
"bitflags 2.9.4",
"errno",
"libc",
- "linux-raw-sys 0.4.15",
- "windows-sys 0.59.0",
-]
-
-[[package]]
-name = "rustix"
-version = "1.0.8"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "11181fbabf243db407ef8df94a6ce0b2f9a733bd8be4ad02b4eda9602296cac8"
-dependencies = [
- "bitflags 2.9.4",
- "errno",
- "libc",
- "linux-raw-sys 0.9.4",
- "windows-sys 0.60.2",
+ "linux-raw-sys",
+ "windows-sys 0.61.0",
]
[[package]]
@@ -7293,16 +7361,16 @@ dependencies = [
[[package]]
name = "rustls"
-version = "0.23.31"
+version = "0.23.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c0ebcbd2f03de0fc1122ad9bb24b127a5a6cd51d72604a3f3c50ac459762b6cc"
+checksum = "cd3c25631629d034ce7cd9940adc9d45762d46de2b0f57193c4443b92c6d4d40"
dependencies = [
"aws-lc-rs",
"log",
"once_cell",
"ring",
"rustls-pki-types",
- "rustls-webpki 0.103.4",
+ "rustls-webpki 0.103.6",
"subtle",
"zeroize",
]
@@ -7328,7 +7396,7 @@ dependencies = [
"openssl-probe",
"rustls-pki-types",
"schannel",
- "security-framework 3.3.0",
+ "security-framework 3.4.0",
]
[[package]]
@@ -7381,9 +7449,9 @@ dependencies = [
[[package]]
name = "rustls-webpki"
-version = "0.103.4"
+version = "0.103.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0a17884ae0c1b773f1ccd2bd4a8c72f16da897310a98b0e84bf349ad5ead92fc"
+checksum = "8572f3c2cb9934231157b45499fc41e1f58c589fdfb81a844ba873265e80f8eb"
dependencies = [
"aws-lc-rs",
"ring",
@@ -7423,11 +7491,11 @@ checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f"
[[package]]
name = "schannel"
-version = "0.1.27"
+version = "0.1.28"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1f29ebaa345f945cec9fbbc532eb307f0fdad8161f281b6369539c8d84876b3d"
+checksum = "891d81b926048e76efe18581bf793546b4c0eaf8448d72be8de2bbee5fd166e1"
dependencies = [
- "windows-sys 0.59.0",
+ "windows-sys 0.61.0",
]
[[package]]
@@ -7577,9 +7645,9 @@ dependencies = [
[[package]]
name = "security-framework"
-version = "3.3.0"
+version = "3.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "80fb1d92c5028aa318b4b8bd7302a5bfcf48be96a37fc6fc790f806b0004ee0c"
+checksum = "60b369d18893388b345804dc0007963c99b7d665ae71d275812d828c6f089640"
dependencies = [
"bitflags 2.9.4",
"core-foundation 0.10.1",
@@ -7590,9 +7658,9 @@ dependencies = [
[[package]]
name = "security-framework-sys"
-version = "2.14.0"
+version = "2.15.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "49db231d56a190491cb4aeda9527f1ad45345af50b0851622a7adb8c03b01c32"
+checksum = "cc1f0cbffaac4852523ce30d8bd3c5cdc873501d96ff467ca09b6767bb8cd5c0"
dependencies = [
"core-foundation-sys",
"libc",
@@ -7619,9 +7687,9 @@ dependencies = [
[[package]]
name = "semver"
-version = "1.0.26"
+version = "1.0.27"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "56e6fa9c48d24d85fb3de5ad847117517440f6beceb7798af16b4a87d616b8d0"
+checksum = "d767eb0aabc880b29956c35734170f26ed551a859dbd361d140cdbeca61ab1e2"
[[package]]
name = "sentry"
@@ -7783,20 +7851,22 @@ dependencies = [
[[package]]
name = "serde"
-version = "1.0.219"
+version = "1.0.225"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6"
+checksum = "fd6c24dee235d0da097043389623fb913daddf92c76e9f5a1db88607a0bcbd1d"
dependencies = [
+ "serde_core",
"serde_derive",
]
[[package]]
name = "serde_bytes"
-version = "0.11.17"
+version = "0.11.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8437fd221bde2d4ca316d61b90e337e9e702b3820b87d63caa9ba6c02bd06d96"
+checksum = "a5d440709e79d88e51ac01c4b72fc6cb7314017bb7da9eeff678aa94c10e3ea8"
dependencies = [
"serde",
+ "serde_core",
]
[[package]]
@@ -7809,10 +7879,19 @@ dependencies = [
]
[[package]]
-name = "serde_derive"
-version = "1.0.219"
+name = "serde_core"
+version = "1.0.225"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00"
+checksum = "659356f9a0cb1e529b24c01e43ad2bdf520ec4ceaf83047b83ddcc2251f96383"
+dependencies = [
+ "serde_derive",
+]
+
+[[package]]
+name = "serde_derive"
+version = "1.0.225"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0ea936adf78b1f766949a4977b91d2f5595825bd6ec079aa9543ad2685fc4516"
dependencies = [
"proc-macro2",
"quote 1.0.40",
@@ -7832,25 +7911,27 @@ dependencies = [
[[package]]
name = "serde_json"
-version = "1.0.143"
+version = "1.0.145"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d401abef1d108fbd9cbaebc3e46611f4b1021f714a0597a71f41ee463f5f4a5a"
+checksum = "402a6f66d8c709116cf22f558eab210f5a50187f702eb4d7e5ef38d9a7f1c79c"
dependencies = [
- "indexmap 2.11.0",
+ "indexmap 2.11.4",
"itoa",
"memchr",
"ryu",
"serde",
+ "serde_core",
]
[[package]]
name = "serde_path_to_error"
-version = "0.1.17"
+version = "0.1.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "59fab13f937fa393d08645bf3a84bdfe86e296747b506ada67bb15f10f218b2a"
+checksum = "10a9ff822e371bb5403e391ecd83e182e0e77ba7f6fe0160b795797109d1b457"
dependencies = [
"itoa",
"serde",
+ "serde_core",
]
[[package]]
@@ -7876,15 +7957,15 @@ dependencies = [
[[package]]
name = "serde_with"
-version = "3.14.0"
+version = "3.14.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f2c45cd61fefa9db6f254525d46e392b852e0e61d9a1fd36e5bd183450a556d5"
+checksum = "c522100790450cf78eeac1507263d0a350d4d5b30df0c8e1fe051a10c22b376e"
dependencies = [
"base64 0.22.1",
"chrono",
"hex",
"indexmap 1.9.3",
- "indexmap 2.11.0",
+ "indexmap 2.11.4",
"schemars 0.9.0",
"schemars 1.0.4",
"serde",
@@ -7896,11 +7977,11 @@ dependencies = [
[[package]]
name = "serde_with_macros"
-version = "3.14.0"
+version = "3.14.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "de90945e6565ce0d9a25098082ed4ee4002e047cb59892c318d66821e14bb30f"
+checksum = "327ada00f7d64abaac1e55a6911e90cf665aa051b9a561c7006c157f4633135e"
dependencies = [
- "darling 0.20.11",
+ "darling 0.21.3",
"proc-macro2",
"quote 1.0.40",
"syn 2.0.106",
@@ -8413,15 +8494,15 @@ checksum = "61c41af27dd6d1e27b1b16b489db798443478cef1f06a660c96db617ba5de3b1"
[[package]]
name = "tempfile"
-version = "3.21.0"
+version = "3.22.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "15b61f8f20e3a6f7e0649d825294eaf317edce30f82cf6026e7e4cb9222a7d1e"
+checksum = "84fa4d11fadde498443cca10fd3ac23c951f0dc59e080e9f4b93d4df4e4eea53"
dependencies = [
"fastrand 2.3.0",
"getrandom 0.3.3",
"once_cell",
- "rustix 1.0.8",
- "windows-sys 0.60.2",
+ "rustix",
+ "windows-sys 0.61.0",
]
[[package]]
@@ -8509,11 +8590,12 @@ dependencies = [
[[package]]
name = "time"
-version = "0.3.43"
+version = "0.3.44"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "83bde6f1ec10e72d583d91623c939f623002284ef622b87de38cfd546cbf2031"
+checksum = "91e7d9e3bb61134e77bde20dd4825b97c010155709965fedf0f49bb138e52a9d"
dependencies = [
"deranged",
+ "itoa",
"libc",
"num-conv",
"num_threads",
@@ -8674,11 +8756,11 @@ dependencies = [
[[package]]
name = "tokio-rustls"
-version = "0.26.2"
+version = "0.26.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8e727b36a1a0e8b74c376ac2211e40c2c8af09fb4013c60d910495810f008e9b"
+checksum = "05f63835928ca123f1bef57abbcd23bb2ba0ac9ae1235f1e65bda0d06e7786bd"
dependencies = [
- "rustls 0.23.31",
+ "rustls 0.23.32",
"tokio 1.47.1",
]
@@ -8743,7 +8825,7 @@ version = "0.19.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421"
dependencies = [
- "indexmap 2.11.0",
+ "indexmap 2.11.4",
"toml_datetime",
"winnow 0.5.40",
]
@@ -8754,7 +8836,7 @@ version = "0.22.27"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "41fe8c660ae4257887cf66394862d21dbca4a6ddd26f04a3560410406a2f819a"
dependencies = [
- "indexmap 2.11.0",
+ "indexmap 2.11.4",
"serde",
"serde_spanned",
"toml_datetime",
@@ -9076,9 +9158,9 @@ checksum = "260bc6647b3893a9a90668360803a15f96b85a5257b1c3a0c3daf6ae2496de42"
[[package]]
name = "unicode-ident"
-version = "1.0.18"
+version = "1.0.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512"
+checksum = "f63a545481291138910575129486daeaf8ac54aee4387fe7906919f7830c7d9d"
[[package]]
name = "unicode-normalization"
@@ -9232,7 +9314,7 @@ version = "4.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c5afb1a60e207dca502682537fefcfd9921e71d0b83e9576060f09abc6efab23"
dependencies = [
- "indexmap 2.11.0",
+ "indexmap 2.11.4",
"serde",
"serde_json",
"utoipa-gen",
@@ -9421,9 +9503,18 @@ checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b"
[[package]]
name = "wasi"
-version = "0.14.4+wasi-0.2.4"
+version = "0.14.7+wasi-0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "88a5f4a424faf49c3c2c344f166f0662341d470ea185e939657aaff130f0ec4a"
+checksum = "883478de20367e224c0090af9cf5f9fa85bed63a95c1abf3afc5c083ebc06e8c"
+dependencies = [
+ "wasip2",
+]
+
+[[package]]
+name = "wasip2"
+version = "1.0.1+wasi-0.2.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0562428422c63773dad2c345a1882263bbf4d65cf3f42e90921f787ef5ad58e7"
dependencies = [
"wit-bindgen",
]
@@ -9439,9 +9530,9 @@ dependencies = [
[[package]]
name = "wasm-bindgen"
-version = "0.2.101"
+version = "0.2.103"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7e14915cadd45b529bb8d1f343c4ed0ac1de926144b746e2710f9cd05df6603b"
+checksum = "ab10a69fbd0a177f5f649ad4d8d3305499c42bab9aef2f7ff592d0ec8f833819"
dependencies = [
"cfg-if",
"once_cell",
@@ -9452,9 +9543,9 @@ dependencies = [
[[package]]
name = "wasm-bindgen-backend"
-version = "0.2.101"
+version = "0.2.103"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e28d1ba982ca7923fd01448d5c30c6864d0a14109560296a162f80f305fb93bb"
+checksum = "0bb702423545a6007bbc368fde243ba47ca275e549c8a28617f56f6ba53b1d1c"
dependencies = [
"bumpalo",
"log",
@@ -9466,9 +9557,9 @@ dependencies = [
[[package]]
name = "wasm-bindgen-futures"
-version = "0.4.51"
+version = "0.4.53"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0ca85039a9b469b38336411d6d6ced91f3fc87109a2a27b0c197663f5144dffe"
+checksum = "a0b221ff421256839509adbb55998214a70d829d3a28c69b4a6672e9d2a42f67"
dependencies = [
"cfg-if",
"js-sys",
@@ -9479,9 +9570,9 @@ dependencies = [
[[package]]
name = "wasm-bindgen-macro"
-version = "0.2.101"
+version = "0.2.103"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7c3d463ae3eff775b0c45df9da45d68837702ac35af998361e2c84e7c5ec1b0d"
+checksum = "fc65f4f411d91494355917b605e1480033152658d71f722a90647f56a70c88a0"
dependencies = [
"quote 1.0.40",
"wasm-bindgen-macro-support",
@@ -9489,9 +9580,9 @@ dependencies = [
[[package]]
name = "wasm-bindgen-macro-support"
-version = "0.2.101"
+version = "0.2.103"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7bb4ce89b08211f923caf51d527662b75bdc9c9c7aab40f86dcb9fb85ac552aa"
+checksum = "ffc003a991398a8ee604a401e194b6b3a39677b3173d6e74495eb51b82e99a32"
dependencies = [
"proc-macro2",
"quote 1.0.40",
@@ -9502,9 +9593,9 @@ dependencies = [
[[package]]
name = "wasm-bindgen-shared"
-version = "0.2.101"
+version = "0.2.103"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f143854a3b13752c6950862c906306adb27c7e839f7414cec8fea35beab624c1"
+checksum = "293c37f4efa430ca14db3721dfbe48d8c33308096bd44d80ebaa775ab71ba1cf"
dependencies = [
"unicode-ident",
]
@@ -9533,9 +9624,9 @@ dependencies = [
[[package]]
name = "web-sys"
-version = "0.3.78"
+version = "0.3.80"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "77e4b637749ff0d92b8fad63aa1f7cff3cbe125fd49c175cd6345e7272638b12"
+checksum = "fbe734895e869dc429d78c4b433f8d17d95f8d05317440b4fad5ab2d33e596dc"
dependencies = [
"js-sys",
"wasm-bindgen",
@@ -9585,18 +9676,6 @@ version = "0.1.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a751b3277700db47d3e574514de2eced5e54dc8a5436a3bf7a0b248b2cee16f3"
-[[package]]
-name = "which"
-version = "4.4.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "87ba24419a2078cd2b0f2ede2691b6c66d8e47836da3b6db8265ebad47afbfc7"
-dependencies = [
- "either",
- "home",
- "once_cell",
- "rustix 0.38.44",
-]
-
[[package]]
name = "widestring"
version = "1.2.0"
@@ -9621,11 +9700,11 @@ checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
[[package]]
name = "winapi-util"
-version = "0.1.10"
+version = "0.1.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0978bf7171b3d90bac376700cb56d606feb40f251a475a5d6634613564460b22"
+checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22"
dependencies = [
- "windows-sys 0.60.2",
+ "windows-sys 0.61.0",
]
[[package]]
@@ -9650,9 +9729,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9babd3a767a4c1aef6900409f85f5d53ce2544ccdfaa86dad48c91782c6d6893"
dependencies = [
"windows-collections",
- "windows-core",
+ "windows-core 0.61.2",
"windows-future",
- "windows-link",
+ "windows-link 0.1.3",
"windows-numerics",
]
@@ -9662,7 +9741,7 @@ version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3beeceb5e5cfd9eb1d76b381630e82c4241ccd0d27f1a39ed41b2760b255c5e8"
dependencies = [
- "windows-core",
+ "windows-core 0.61.2",
]
[[package]]
@@ -9673,9 +9752,22 @@ checksum = "c0fdd3ddb90610c7638aa2b3a3ab2904fb9e5cdbecc643ddb3647212781c4ae3"
dependencies = [
"windows-implement",
"windows-interface",
- "windows-link",
- "windows-result",
- "windows-strings",
+ "windows-link 0.1.3",
+ "windows-result 0.3.4",
+ "windows-strings 0.4.2",
+]
+
+[[package]]
+name = "windows-core"
+version = "0.62.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "57fe7168f7de578d2d8a05b07fd61870d2e73b4020e9f49aa00da8471723497c"
+dependencies = [
+ "windows-implement",
+ "windows-interface",
+ "windows-link 0.2.0",
+ "windows-result 0.4.0",
+ "windows-strings 0.5.0",
]
[[package]]
@@ -9684,8 +9776,8 @@ version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fc6a41e98427b19fe4b73c550f060b59fa592d7d686537eebf9385621bfbad8e"
dependencies = [
- "windows-core",
- "windows-link",
+ "windows-core 0.61.2",
+ "windows-link 0.1.3",
"windows-threading",
]
@@ -9717,14 +9809,20 @@ version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a"
+[[package]]
+name = "windows-link"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "45e46c0661abb7180e7b9c281db115305d49ca1709ab8242adf09666d2173c65"
+
[[package]]
name = "windows-numerics"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9150af68066c4c5c07ddc0ce30421554771e528bde427614c61038bc2c92c2b1"
dependencies = [
- "windows-core",
- "windows-link",
+ "windows-core 0.61.2",
+ "windows-link 0.1.3",
]
[[package]]
@@ -9733,9 +9831,9 @@ version = "0.5.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5b8a9ed28765efc97bbc954883f4e6796c33a06546ebafacbabee9696967499e"
dependencies = [
- "windows-link",
- "windows-result",
- "windows-strings",
+ "windows-link 0.1.3",
+ "windows-result 0.3.4",
+ "windows-strings 0.4.2",
]
[[package]]
@@ -9744,7 +9842,16 @@ version = "0.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "56f42bd332cc6c8eac5af113fc0c1fd6a8fd2aa08a0119358686e5160d0586c6"
dependencies = [
- "windows-link",
+ "windows-link 0.1.3",
+]
+
+[[package]]
+name = "windows-result"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7084dcc306f89883455a206237404d3eaf961e5bd7e0f312f7c91f57eb44167f"
+dependencies = [
+ "windows-link 0.2.0",
]
[[package]]
@@ -9753,7 +9860,16 @@ version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "56e6c93f3a0c3b36176cb1327a4958a0353d5d166c2a35cb268ace15e91d3b57"
dependencies = [
- "windows-link",
+ "windows-link 0.1.3",
+]
+
+[[package]]
+name = "windows-strings"
+version = "0.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7218c655a553b0bed4426cf54b20d7ba363ef543b52d515b3e48d7fd55318dda"
+dependencies = [
+ "windows-link 0.2.0",
]
[[package]]
@@ -9785,11 +9901,11 @@ dependencies = [
[[package]]
name = "windows-sys"
-version = "0.60.2"
+version = "0.61.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb"
+checksum = "e201184e40b2ede64bc2ea34968b28e33622acdbbf37104f0e4a33f7abe657aa"
dependencies = [
- "windows-targets 0.53.3",
+ "windows-link 0.2.0",
]
[[package]]
@@ -9829,7 +9945,7 @@ version = "0.53.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d5fe6031c4041849d7c496a8ded650796e7b6ecc19df1a431c1a363342e5dc91"
dependencies = [
- "windows-link",
+ "windows-link 0.1.3",
"windows_aarch64_gnullvm 0.53.0",
"windows_aarch64_msvc 0.53.0",
"windows_i686_gnu 0.53.0",
@@ -9846,7 +9962,7 @@ version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b66463ad2e0ea3bbf808b7f1d371311c80e115c0b71d60efc142cafbcfb057a6"
dependencies = [
- "windows-link",
+ "windows-link 0.1.3",
]
[[package]]
@@ -10017,9 +10133,9 @@ dependencies = [
[[package]]
name = "wit-bindgen"
-version = "0.45.1"
+version = "0.46.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5c573471f125075647d03df72e026074b7203790d41351cd6edc96f46bcccd36"
+checksum = "f17a85883d4e6d00e8a97c586de764dabcc06133f7f1d55dce5cdc070ad7fe59"
[[package]]
name = "writeable"
diff --git a/README.md b/README.md
index 3dd25cf5..1f1ccbb0 100644
--- a/README.md
+++ b/README.md
@@ -21,9 +21,11 @@ The services and libraries that power the Revolt service.
| `core/permissions` | [crates/core/permissions](crates/core/permissions) | Core: Permission Logic |     |
| `core/presence` | [crates/core/presence](crates/core/presence) | Core: User Presence |     |
| `core/result` | [crates/core/result](crates/core/result) | Core: Result and Error types |     |
+| `core/coalesced` | [crates/core/coalesced](crates/core/coalesced) | Core: Coalescion service |     |
| `delta` | [crates/delta](crates/delta) | REST API server |  |
| `bonfire` | [crates/bonfire](crates/bonfire) | WebSocket events server |  |
| `services/january` | [crates/services/january](crates/services/january) | Proxy server |  |
+| `services/gifbox` | [crates/services/gifbox](crates/services/gifbox) | Tenor proxy server |  |
| `services/autumn` | [crates/services/autumn](crates/services/autumn) | File server |  |
| `daemons/crond` | [crates/daemons/crond](crates/daemons/crond) | Timed data clean up daemon server |  |
| `daemons/pushd` | [crates/daemons/pushd](crates/daemons/pushd) | Push notification daemon server |  |
@@ -66,6 +68,7 @@ As a heads-up, the development environment uses the following ports:
| `crates/bonfire` | 14703 |
| `crates/services/autumn` | 14704 |
| `crates/services/january` | 14705 |
+| `crates/services/gifbox` | 14706 |
Now you can clone and build the project:
@@ -141,6 +144,8 @@ cargo run --bin revolt-bonfire
cargo run --bin revolt-autumn
# run the proxy server
cargo run --bin revolt-january
+# run the tenor proxy
+cargo run --bin revolt-gifbox
# run the push daemon (not usually needed in regular development)
cargo run --bin revolt-pushd
diff --git a/crates/bonfire/Cargo.toml b/crates/bonfire/Cargo.toml
index e447825d..c0160270 100644
--- a/crates/bonfire/Cargo.toml
+++ b/crates/bonfire/Cargo.toml
@@ -19,6 +19,7 @@ async-channel = "2.3.1"
# parsing
querystring = "1.1.0"
+regex = "1.11.1"
# serde
bincode = "1.3.3"
diff --git a/crates/bonfire/src/config.rs b/crates/bonfire/src/config.rs
index 04cfd5ca..d70a6320 100644
--- a/crates/bonfire/src/config.rs
+++ b/crates/bonfire/src/config.rs
@@ -1,9 +1,15 @@
use async_tungstenite::tungstenite::{handshake, Message};
use futures::channel::oneshot::Sender;
+use once_cell::sync::Lazy;
+use regex::Regex;
use revolt_database::events::client::ReadyPayloadFields;
use revolt_result::{create_error, Result};
use serde::{Deserialize, Serialize};
+/// matches either a single word ie "users" or a key and value ie "settings[notifications]"
+static READY_PAYLOAD_FIELD_REGEX: Lazy =
+ Lazy::new(|| Regex::new(r#"^(\w+)(?:\[(\S+)\])?$"#).unwrap());
+
/// Enumeration of supported protocol formats
#[derive(Debug)]
pub enum ProtocolFormat {
@@ -17,6 +23,7 @@ pub struct ProtocolConfiguration {
protocol_version: i32,
format: ProtocolFormat,
session_token: Option,
+ ready_payload_fields: ReadyPayloadFields,
}
impl ProtocolConfiguration {
@@ -25,11 +32,13 @@ impl ProtocolConfiguration {
protocol_version: i32,
format: ProtocolFormat,
session_token: Option,
+ ready_payload_fields: ReadyPayloadFields,
) -> Self {
Self {
protocol_version,
format,
session_token,
+ ready_payload_fields,
}
}
@@ -86,15 +95,8 @@ impl ProtocolConfiguration {
}
/// Get ready payload fields
- pub fn get_ready_payload_fields(&self) -> Vec {
- vec![
- ReadyPayloadFields::Users,
- ReadyPayloadFields::Servers,
- ReadyPayloadFields::Channels,
- ReadyPayloadFields::Members,
- ReadyPayloadFields::Emoji,
- ReadyPayloadFields::VoiceStates,
- ]
+ pub fn get_ready_payload_fields(&self) -> &ReadyPayloadFields {
+ &self.ready_payload_fields
}
}
@@ -125,6 +127,23 @@ impl handshake::server::Callback for WebsocketHandshakeCallback {
let mut protocol_version = 1;
let mut format = ProtocolFormat::Json;
let mut session_token = None;
+ let mut ready_payload_fields = if params.iter().any(|(k, _)| *k == "ready") {
+ // If they pass the ready field, set all fields to false
+
+ ReadyPayloadFields {
+ users: false,
+ servers: false,
+ channels: false,
+ members: false,
+ emojis: false,
+ voice_states: false,
+ user_settings: Vec::new(),
+ channel_unreads: false,
+ policy_changes: false,
+ }
+ } else {
+ ReadyPayloadFields::default()
+ };
// Parse and map parameters from key-value to known variables.
for (key, value) in params {
@@ -140,6 +159,31 @@ impl handshake::server::Callback for WebsocketHandshakeCallback {
_ => {}
},
"token" => session_token = Some(value.into()),
+ "ready" => {
+ // Re-enable all the fields the client specifies
+ if let Some(captures) = READY_PAYLOAD_FIELD_REGEX.captures(value) {
+ if let Some(field) = captures.get(0) {
+ match field.as_str() {
+ "users" => ready_payload_fields.users = true,
+ "servers" => ready_payload_fields.servers = true,
+ "channels" => ready_payload_fields.channels = true,
+ "members" => ready_payload_fields.members = true,
+ "emojis" => ready_payload_fields.emojis = true,
+ "voice_states" => ready_payload_fields.voice_states = true,
+ "channel_unreads" => ready_payload_fields.channel_unreads = true,
+ "user_settings" => {
+ if let Some(subkey) = captures.get(1) {
+ ready_payload_fields
+ .user_settings
+ .push(subkey.as_str().to_string());
+ }
+ }
+ "policy_changes" => ready_payload_fields.policy_changes = true,
+ _ => {}
+ }
+ }
+ }
+ }
_ => {}
}
}
@@ -152,6 +196,7 @@ impl handshake::server::Callback for WebsocketHandshakeCallback {
protocol_version,
format,
session_token,
+ ready_payload_fields,
})
.is_ok()
{
diff --git a/crates/bonfire/src/events/impl.rs b/crates/bonfire/src/events/impl.rs
index 4f6bf905..6d51a823 100644
--- a/crates/bonfire/src/events/impl.rs
+++ b/crates/bonfire/src/events/impl.rs
@@ -98,21 +98,23 @@ impl State {
pub async fn generate_ready_payload(
&mut self,
db: &Database,
- fields: Vec,
+ fields: &ReadyPayloadFields,
) -> Result {
let user = self.clone_user();
self.cache.is_bot = user.bot.is_some();
// Fetch pending policy changes.
- let policy_changes = if user.bot.is_some() {
- vec![]
+ let policy_changes = if user.bot.is_some() || !fields.policy_changes {
+ None
} else {
- db.fetch_policy_changes()
- .await?
- .into_iter()
- .filter(|policy| policy.created_time > user.last_acknowledged_policy_change)
- .map(Into::into)
- .collect()
+ Some(
+ db.fetch_policy_changes()
+ .await?
+ .into_iter()
+ .filter(|policy| policy.created_time > user.last_acknowledged_policy_change)
+ .map(Into::into)
+ .collect(),
+ )
};
// Find all relationships to the user.
@@ -171,7 +173,7 @@ impl State {
.await?;
// Fetch customisations.
- let emojis = if fields.contains(&ReadyPayloadFields::Emoji) {
+ let emojis = if fields.emojis {
Some(
db.fetch_emoji_by_parent_ids(
&servers
@@ -179,25 +181,49 @@ impl State {
.map(|x| x.id.to_string())
.collect::>(),
)
- .await?,
+ .await?
+ .into_iter()
+ .map(|emoji| emoji.into())
+ .collect(),
)
} else {
None
};
// Fetch user settings
- let user_settings = if let Some(ReadyPayloadFields::UserSettings(keys)) = fields
- .iter()
- .find(|e| matches!(e, ReadyPayloadFields::UserSettings(_)))
- {
- Some(db.fetch_user_settings(&user.id, keys).await?)
+ let user_settings = if !fields.user_settings.is_empty() {
+ Some(
+ db.fetch_user_settings(&user.id, &fields.user_settings)
+ .await?,
+ )
} else {
None
};
// Fetch channel unreads
- let channel_unreads = if fields.contains(&ReadyPayloadFields::ChannelUnreads) {
- Some(db.fetch_unreads(&user.id).await?)
+ let channel_unreads = if fields.channel_unreads {
+ Some(
+ db.fetch_unreads(&user.id)
+ .await?
+ .into_iter()
+ .map(|unread| unread.into())
+ .collect(),
+ )
+ } else {
+ None
+ };
+
+ let voice_states = if fields.voice_states {
+ // fetch voice states for all the channels we can see
+ let mut voice_states = Vec::new();
+
+ for channel in &channels {
+ if let Ok(Some(voice_state)) = get_channel_voice_state(channel).await {
+ voice_states.push(voice_state)
+ }
+ }
+
+ Some(voice_states)
} else {
None
};
@@ -243,47 +269,28 @@ impl State {
self.insert_subscription(channel.id().to_string()).await;
}
- let voice_states = if fields.contains(&ReadyPayloadFields::VoiceStates) {
- // fetch voice states for all the channels we can see
- let mut voice_states = Vec::new();
-
- for channel in &channels {
- if let Ok(Some(voice_state)) = get_channel_voice_state(channel).await {
- voice_states.push(voice_state)
- }
- }
-
- Some(voice_states)
- } else {
- None
- };
-
Ok(EventV1::Ready {
- users: if fields.contains(&ReadyPayloadFields::Users) {
- Some(users)
- } else {
- None
- },
- servers: if fields.contains(&ReadyPayloadFields::Servers) {
+ users: if fields.users { Some(users) } else { None },
+ servers: if fields.servers {
Some(servers.into_iter().map(Into::into).collect())
} else {
None
},
- channels: if fields.contains(&ReadyPayloadFields::Channels) {
+ channels: if fields.channels {
Some(channels.into_iter().map(Into::into).collect())
} else {
None
},
- members: if fields.contains(&ReadyPayloadFields::Members) {
+ members: if fields.members {
Some(members.into_iter().map(Into::into).collect())
} else {
None
},
- emojis: emojis.map(|vec| vec.into_iter().map(Into::into).collect()),
voice_states,
+ emojis,
user_settings,
- channel_unreads: channel_unreads.map(|vec| vec.into_iter().map(Into::into).collect()),
+ channel_unreads,
policy_changes,
})
diff --git a/crates/core/coalesced/Cargo.toml b/crates/core/coalesced/Cargo.toml
new file mode 100644
index 00000000..cb23a8ad
--- /dev/null
+++ b/crates/core/coalesced/Cargo.toml
@@ -0,0 +1,22 @@
+[package]
+name = "revolt-coalesced"
+version = "0.8.8"
+edition = "2021"
+license = "MIT"
+authors = ["Paul Makles ", "Zomatree "]
+description = "Revolt Backend: Coalescion service"
+
+[features]
+tokio = ["dep:tokio"]
+queue = ["dep:indexmap"]
+cache = ["dep:lru"]
+
+default = ["tokio"]
+
+[dependencies]
+tokio = { version = "1.47.0", features = ["sync"], optional = true }
+indexmap = { version = "*", optional = true }
+lru = { version = "*", optional = true }
+
+[dev-dependencies]
+tokio = { version = "1.47.0", features = ["rt", "rt-multi-thread", "macros", "time"] }
diff --git a/crates/core/coalesced/LICENSE b/crates/core/coalesced/LICENSE
new file mode 100644
index 00000000..7c2815b9
--- /dev/null
+++ b/crates/core/coalesced/LICENSE
@@ -0,0 +1,9 @@
+MIT License
+
+Copyright (c) 2024 Pawel Makles
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/crates/core/coalesced/src/config.rs b/crates/core/coalesced/src/config.rs
new file mode 100644
index 00000000..23da1698
--- /dev/null
+++ b/crates/core/coalesced/src/config.rs
@@ -0,0 +1,24 @@
+#[derive(Clone, PartialEq, Eq, Debug)]
+/// Config values for [`CoalescionService`].
+pub struct CoalescionServiceConfig {
+ /// How many tasks are running at once
+ pub max_concurrent: Option,
+ /// Whether to queue tasks once `max_concurrent` is reached
+ #[cfg(feature = "queue")]
+ pub queue_requests: bool,
+ /// Max amount of tasks in the buffer queue
+ #[cfg(feature = "queue")]
+ pub max_queue: Option,
+}
+
+impl Default for CoalescionServiceConfig {
+ fn default() -> Self {
+ Self {
+ max_concurrent: Some(100),
+ #[cfg(feature = "queue")]
+ queue_requests: true,
+ #[cfg(feature = "queue")]
+ max_queue: Some(100)
+ }
+ }
+}
diff --git a/crates/core/coalesced/src/error.rs b/crates/core/coalesced/src/error.rs
new file mode 100644
index 00000000..6be89785
--- /dev/null
+++ b/crates/core/coalesced/src/error.rs
@@ -0,0 +1,27 @@
+use std::fmt;
+
+#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)]
+/// Coalescion service error.
+pub enum Error {
+ /// Failed to receive the actions return from the channel for unknown reason
+ RecvError,
+ /// Reached the `max_concurrent` amount of actions running at once and could not queue the action
+ MaxConcurrent,
+ /// Reached the `max_queue` amount of actions in the queue
+ MaxQueue,
+ /// Failed to downcast the type to the current type being returned, this will be most likely an ID collision
+ DowncastError,
+}
+
+impl fmt::Display for Error {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ match self {
+ Error::RecvError => write!(f, "Unable to receive data from the channel"),
+ Error::MaxConcurrent => write!(f, "Max number of tasks running at once"),
+ Error::MaxQueue => write!(f, "Max number of tasks in queue"),
+ Error::DowncastError => write!(f, "Failed to downcast type, possible key collision with different types")
+ }
+ }
+}
+
+impl std::error::Error for Error {}
diff --git a/crates/core/coalesced/src/lib.rs b/crates/core/coalesced/src/lib.rs
new file mode 100644
index 00000000..89839e23
--- /dev/null
+++ b/crates/core/coalesced/src/lib.rs
@@ -0,0 +1,39 @@
+//! # Coalesced
+//!
+//! Coalescion service to group, caching and queue duplicate actions.
+//! useful for deduplicating web requests, database lookups and other similar resource
+//! intensive or rate-limited actions.
+//!
+//! ## Features
+//! - `tokio`: Uses tokio for the async backend, this is currently the only backend.
+//! - `queue`: Whether to support queueing requests to only allow X amount of actions running at once.
+//! - `cache`: Whether to cache the actions results for future actions with the same id, uses an LRU cache internally.
+//!
+//! [`CoalescionService`] uses both [`Arc`] and [`RwLock`] internally and can be cheaply cloned to
+//! use in your codebase.
+//!
+//! It is common practice to wrap the service and in your own which delegates the executions to ensure all ids are tracked in one location across your codebase.
+//!
+//! All values are stored using [`Any`] and must be [`'static`] + [`Send`] + [`Sync`], if there is an id mismatch
+//! and a type is wrong the library will return an error, values returned from the service are also
+//! wrapped in an [`Arc`] as they are shared to each duplicate action.
+//!
+//! ## Example:
+//! ```rs
+//! use revolt_coalesced::CoalescionService;
+//!
+//! let service = CoalescionService::new();
+//!
+//! let user_id = "my_user_id";
+//! let user = service.execute(user_id, || async move {
+//! database.fetch_user(user_id).await.unwrap()
+//! }).await;
+//! ```
+
+mod config;
+mod error;
+mod service;
+
+pub use config::CoalescionServiceConfig;
+pub use error::Error;
+pub use service::CoalescionService;
diff --git a/crates/core/coalesced/src/service.rs b/crates/core/coalesced/src/service.rs
new file mode 100644
index 00000000..aadadc8a
--- /dev/null
+++ b/crates/core/coalesced/src/service.rs
@@ -0,0 +1,208 @@
+use std::{any::Any, collections::HashMap, fmt::Debug, future::Future, hash::Hash, sync::Arc};
+
+use tokio::sync::{
+ watch::{channel as watch_channel, Receiver},
+ RwLock,
+};
+
+#[cfg(feature = "cache")]
+use lru::LruCache;
+
+#[cfg(feature = "queue")]
+use indexmap::IndexMap;
+
+use crate::{CoalescionServiceConfig, Error};
+
+#[derive(Debug, Clone)]
+#[allow(clippy::type_complexity)]
+/// # Coalescion service
+///
+/// See module description for example usage.
+pub struct CoalescionService {
+ config: Arc,
+ watchers: Arc, Error>>>>>>,
+ #[cfg(feature = "queue")]
+ queue: Arc, Error>>>>>>,
+ #[cfg(feature = "cache")]
+ cache: Option>>>>,
+}
+
+impl CoalescionService {
+ pub fn new() -> Self {
+ Default::default()
+ }
+
+ pub fn from_config(config: CoalescionServiceConfig) -> Self {
+ Self {
+ config: Arc::new(config),
+ watchers: Arc::new(RwLock::new(HashMap::new())),
+ #[cfg(feature = "queue")]
+ queue: Arc::new(RwLock::new(IndexMap::new())),
+ #[cfg(feature = "cache")]
+ cache: None,
+ }
+ }
+
+ #[cfg(feature = "cache")]
+ pub fn from_cache(
+ config: CoalescionServiceConfig,
+ cache: LruCache>,
+ ) -> Self {
+ Self {
+ cache: Some(Arc::new(Mutex::new(cache))),
+ ..Self::from_config(config)
+ }
+ }
+
+ async fn wait_for(
+ &self,
+ mut receiver: Receiver