From f4906ee483e8bbcfe575d74116b79139d0c5a614 Mon Sep 17 00:00:00 2001 From: ejjonny Date: Sat, 29 Mar 2025 15:20:26 -0600 Subject: [PATCH 01/53] french feed, metrics, log jetstream errors --- Cargo.lock | 968 ++++++++++++++++++------ Cargo.toml | 8 +- examples/sqlite/Cargo.lock | 1386 +++++++++++++++++++++++++++++------ examples/sqlite/Cargo.toml | 3 + examples/sqlite/src/main.rs | 82 ++- src/bin/my_did.rs | 2 +- src/bin/publish.rs | 2 +- src/bin/unpublish.rs | 2 +- src/feed.rs | 6 +- 9 files changed, 1970 insertions(+), 489 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 488f37b..98b04c7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -17,6 +17,18 @@ version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" +[[package]] +name = "ahash" +version = "0.8.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" +dependencies = [ + "cfg-if", + "once_cell", + "version_check", + "zerocopy 0.7.35", +] + [[package]] name = "aho-corasick" version = "1.1.3" @@ -26,6 +38,12 @@ dependencies = [ "memchr", ] +[[package]] +name = "allocator-api2" +version = "0.2.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" + [[package]] name = "android-tzdata" version = "0.1.1" @@ -93,15 +111,15 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.95" +version = "1.0.97" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34ac096ce696dc2fcabef30516bb13c0a68a11d30131d3df6f04711467681b04" +checksum = "dcfed56ad506cb2c684a14971b8861fdc3baaaae314b9e5f9bb532cbe3ba7a4f" [[package]] name = "async-compression" -version = "0.4.18" +version = "0.4.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df895a515f70646414f4b45c0b79082783b80552b373a68283012928df56f522" +checksum = "c0cf008e5e1a9e9e22a7d3c9a4992e21a350290069e36d8fb72304ed17e8f2d2" dependencies = [ "flate2", "futures-core", @@ -110,11 +128,22 @@ dependencies = [ "tokio", ] +[[package]] +name = "async-lock" +version = "3.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff6e472cdea888a4bd64f342f09b3f50e1886d32afe8df3d663c01140b811b18" +dependencies = [ + "event-listener", + "event-listener-strategy", + "pin-project-lite", +] + [[package]] name = "async-trait" -version = "0.1.86" +version = "0.1.88" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "644dd749086bf3771a2fbc5f256fdb982d53f011c7d5d560304eafeecebce79d" +checksum = "e539d3fca749fcee5236ab05e93a52867dd549cc157c8cb7f99595f3cedffdb5" dependencies = [ "proc-macro2", "quote", @@ -129,13 +158,14 @@ checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" [[package]] name = "atrium-api" -version = "0.24.10" +version = "0.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c5d74937642f6b21814e82d80f54d55ebd985b681bffbe27c8a76e726c3c4db" +checksum = "ea3ea578c768ec91082e424a8d139517b2cb5c75149bf3cec04371a1e74f00f2" dependencies = [ + "atrium-common", "atrium-xrpc", "chrono", - "http 1.2.0", + "http 1.3.1", "ipld-core", "langtag", "regex", @@ -147,13 +177,28 @@ dependencies = [ "trait-variant", ] +[[package]] +name = "atrium-common" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "168e558408847bfed69df1033a32fd051f7a037ebc90ea46e588ccb2bfbd7233" +dependencies = [ + "dashmap", + "lru", + "moka", + "thiserror 1.0.69", + "tokio", + "trait-variant", + "web-time", +] + [[package]] name = "atrium-xrpc" -version = "0.12.0" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f223b98be2acdd7afe5b867744aee8258413ed09993099de0a036b247db0ec4c" +checksum = "6b4956d94147cfbb669c68f654eb4fd6a1d00648c810cec79d04ec5425b8f378" dependencies = [ - "http 1.2.0", + "http 1.3.1", "serde", "serde_html_form", "serde_json", @@ -163,9 +208,9 @@ dependencies = [ [[package]] name = "atrium-xrpc-client" -version = "0.5.10" +version = "0.5.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd9946c18301eee62e8bd0ade5ac2750c9a0778fadf097ac60024b2a79485603" +checksum = "9bab4287ccef501b3892e1325280e61ae79a96eb9ee63dceabc0ed3bea35f2eb" dependencies = [ "atrium-xrpc", "reqwest", @@ -189,7 +234,7 @@ dependencies = [ "miniz_oxide", "object", "rustc-demangle", - "windows-targets", + "windows-targets 0.52.6", ] [[package]] @@ -212,9 +257,9 @@ checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" [[package]] name = "bitflags" -version = "2.8.0" +version = "2.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f68f53c83ab957f72c32642f3868eec03eb974d1fb82e453128456482613d36" +checksum = "5c8214115b7bf84099f1309324e63141d4c5d7cc26862f97a0a857dbefe165bd" [[package]] name = "block-buffer" @@ -239,9 +284,9 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.10.0" +version = "1.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f61dac84819c6588b558454b194026eb1f09c293b9036ae9b159e74e73ab6cf9" +checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a" [[package]] name = "camino" @@ -288,9 +333,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.2.12" +version = "1.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "755717a7de9ec452bf7f3f1a3099085deabd7f2962b861dae91ecd7a365903d2" +checksum = "be714c154be609ec7f5dad223a33bf1482fff90472de28f7362806e6d4832b8c" dependencies = [ "jobserver", "libc", @@ -305,9 +350,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "chrono" -version = "0.4.39" +version = "0.4.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e36cc9d416881d2e24f9a963be5fb1cd90966419ac844274161d10488b3e825" +checksum = "1a7964611d71df112cb1730f2ee67324fcf4d0fc6606acbbe9bfe06df124637c" dependencies = [ "android-tzdata", "iana-time-zone", @@ -315,7 +360,7 @@ dependencies = [ "num-traits", "serde", "wasm-bindgen", - "windows-targets", + "windows-link", ] [[package]] @@ -334,9 +379,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.28" +version = "4.5.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e77c3243bd94243c03672cb5154667347c457ca271254724f9f393aee1c05ff" +checksum = "6088f3ae8c3608d19260cd7445411865a485688711b78b5be70d78cd96136f83" dependencies = [ "clap_builder", "clap_derive", @@ -344,9 +389,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.27" +version = "4.5.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b26884eb4b57140e4d2d93652abfa49498b938b3c9179f9fc487b0acc3edad7" +checksum = "22a7ef7f676155edfb82daa97f99441f3ebf4a58d5e32f295a56259f1b6facc8" dependencies = [ "anstream", "anstyle", @@ -356,9 +401,9 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.5.28" +version = "4.5.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf4ced95c6f4a675af3da73304b9ac4ed991640c36374e4b46795c49e17cf1ed" +checksum = "09176aae279615badda0765c0c0b3f6ed53f4709118af73cf4655d85d1530cd7" dependencies = [ "heck", "proc-macro2", @@ -378,11 +423,20 @@ version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990" +[[package]] +name = "concurrent-queue" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ca0197aee26d1ae37445ee532fefce43251d24cc7c166799f4d46817f1d3973" +dependencies = [ + "crossbeam-utils", +] + [[package]] name = "console" -version = "0.15.10" +version = "0.15.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea3c6ecd8059b57859df5c69830340ed3c41d30e3da0c1cbed90a96ac853041b" +checksum = "054ccb5b10f9f2cbf51eb355ca1d05c2d279ce1804688d0db74b4733a5aeafd8" dependencies = [ "encode_unicode", "libc", @@ -433,6 +487,30 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "crossbeam-channel" +version = "0.5.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06ba6d68e24814cb8de6bb986db8222d3a027d15872cabc0d18817bc3c0e4471" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" + [[package]] name = "crypto-common" version = "0.1.6" @@ -443,17 +521,31 @@ dependencies = [ "typenum", ] +[[package]] +name = "dashmap" +version = "6.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5041cc499144891f3790297212f32a74fb938e5136a14943f338ef9e0ae276cf" +dependencies = [ + "cfg-if", + "crossbeam-utils", + "hashbrown 0.14.5", + "lock_api", + "once_cell", + "parking_lot_core", +] + [[package]] name = "data-encoding" -version = "2.7.0" +version = "2.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e60eed09d8c01d3cee5b7d30acb059b76614c918fa0f992e0dd6eeb10daad6f" +checksum = "575f75dfd25738df5b91b8e43e14d44bda14637a58fae779fd2b064f8bf3e010" [[package]] name = "data-encoding-macro" -version = "0.1.16" +version = "0.1.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b16d9d0d88a5273d830dac8b78ceb217ffc9b1d5404e5597a3542515329405b" +checksum = "9f9724adfcf41f45bf652b3995837669d73c4d49a1b5ac1ff82905ac7d9b5558" dependencies = [ "data-encoding", "data-encoding-macro-internal", @@ -461,9 +553,9 @@ dependencies = [ [[package]] name = "data-encoding-macro-internal" -version = "0.1.14" +version = "0.1.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1145d32e826a7748b69ee8fc62d3e6355ff7f1051df53141e7048162fc90481b" +checksum = "18e4fdb82bd54a12e42fb58a800dcae6b9e13982238ce2296dc3570b92148e1f" dependencies = [ "data-encoding", "syn", @@ -523,22 +615,22 @@ dependencies = [ [[package]] name = "env_logger" -version = "0.11.6" +version = "0.11.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcaee3d8e3cfc3fd92428d477bc97fc29ec8716d180c0d74c643bb26166660e0" +checksum = "c3716d7a920fb4fac5d84e9d4bce8ceb321e9414b4409da61b07b75c1e3d0697" dependencies = [ "anstream", "anstyle", "env_filter", - "humantime", + "jiff", "log", ] [[package]] name = "equivalent" -version = "1.0.1" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" +checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" [[package]] name = "errno" @@ -550,6 +642,27 @@ dependencies = [ "windows-sys 0.59.0", ] +[[package]] +name = "event-listener" +version = "5.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3492acde4c3fc54c845eaab3eed8bd00c7a7d881f78bfc801e43a93dec1331ae" +dependencies = [ + "concurrent-queue", + "parking", + "pin-project-lite", +] + +[[package]] +name = "event-listener-strategy" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c3e4e0dd3673c1139bf041f3008816d9cf2946bbfac2945c09e523b8d7b05b2" +dependencies = [ + "event-listener", + "pin-project-lite", +] + [[package]] name = "fallible-iterator" version = "0.3.0" @@ -570,9 +683,9 @@ checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" [[package]] name = "flate2" -version = "1.0.35" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c936bfdafb507ebbf50b8074c54fa31c5be9a1e7e5f467dd659697041407d07c" +checksum = "11faaf5a5236997af9848be0bef4db95824b1d534ebc64d0f0c6cf3e67bd38dc" dependencies = [ "crc32fast", "miniz_oxide", @@ -598,9 +711,9 @@ checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" [[package]] name = "foldhash" -version = "0.1.4" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0d2fde1f7b3d48b8395d5f2de76c18a528bd6a9cdde438df747bfcba3e05d6f" +checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" [[package]] name = "foreign-types" @@ -680,6 +793,19 @@ dependencies = [ "slab", ] +[[package]] +name = "generator" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc6bd114ceda131d3b1d665eba35788690ad37f5916457286b32ab6fd3c438dd" +dependencies = [ + "cfg-if", + "libc", + "log", + "rustversion", + "windows", +] + [[package]] name = "generic-array" version = "0.14.7" @@ -712,7 +838,7 @@ dependencies = [ "cfg-if", "libc", "wasi 0.13.3+wasi-0.2.2", - "windows-targets", + "windows-targets 0.52.6", ] [[package]] @@ -742,16 +868,16 @@ dependencies = [ [[package]] name = "h2" -version = "0.4.7" +version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ccae279728d634d083c00f6099cb58f01cc99c145b84b8be2f6c74618d79922e" +checksum = "5017294ff4bb30944501348f6f8e42e6ad28f42c8bbef7a74029aff064a4e3c2" dependencies = [ "atomic-waker", "bytes", "fnv", "futures-core", "futures-sink", - "http 1.2.0", + "http 1.3.1", "indexmap", "slab", "tokio", @@ -765,12 +891,24 @@ version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "98f494b2060b2a8f5e63379e1e487258e014cee1b1725a735816c0107a2e9d93" +[[package]] +name = "hashbrown" +version = "0.14.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" +dependencies = [ + "ahash", + "allocator-api2", +] + [[package]] name = "hashbrown" version = "0.15.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" dependencies = [ + "allocator-api2", + "equivalent", "foldhash", ] @@ -780,7 +918,7 @@ version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7382cf6263419f2d8df38c55d7da83da5c18aef87fc7a7fc1fb1e344edfe14c1" dependencies = [ - "hashbrown", + "hashbrown 0.15.2", ] [[package]] @@ -826,9 +964,9 @@ dependencies = [ [[package]] name = "http" -version = "1.2.0" +version = "1.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f16ca2af56261c99fba8bac40a10251ce8188205a4c448fbb745a2e4daa76fea" +checksum = "f4a85d31aea989eead29a3aaf9e1115a180df8282431156e533de47660892565" dependencies = [ "bytes", "fnv", @@ -853,27 +991,27 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" dependencies = [ "bytes", - "http 1.2.0", + "http 1.3.1", ] [[package]] name = "http-body-util" -version = "0.1.2" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "793429d76616a256bcb62c2a2ec2bed781c8307e797e2598c50010f2bee2544f" +checksum = "b021d93e26becf5dc7e1b75b1bed1fd93124b374ceb73f43d4d4eafec896a64a" dependencies = [ "bytes", - "futures-util", - "http 1.2.0", + "futures-core", + "http 1.3.1", "http-body 1.0.1", "pin-project-lite", ] [[package]] name = "httparse" -version = "1.10.0" +version = "1.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2d708df4e7140240a16cd6ab0ab65c972d7433ab77819ea693fde9c43811e2a" +checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87" [[package]] name = "httpdate" @@ -881,12 +1019,6 @@ version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" -[[package]] -name = "humantime" -version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" - [[package]] name = "hyper" version = "0.14.32" @@ -920,8 +1052,8 @@ dependencies = [ "bytes", "futures-channel", "futures-util", - "h2 0.4.7", - "http 1.2.0", + "h2 0.4.8", + "http 1.3.1", "http-body 1.0.1", "httparse", "itoa", @@ -938,7 +1070,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2d191583f3da1305256f22463b9bb0471acad48a4e534a5218b9963e9c1f59b2" dependencies = [ "futures-util", - "http 1.2.0", + "http 1.3.1", "hyper 1.6.0", "hyper-util", "rustls", @@ -973,7 +1105,7 @@ dependencies = [ "bytes", "futures-channel", "futures-util", - "http 1.2.0", + "http 1.3.1", "http-body 1.0.1", "hyper 1.6.0", "pin-project-lite", @@ -994,7 +1126,7 @@ dependencies = [ "iana-time-zone-haiku", "js-sys", "wasm-bindgen", - "windows-core", + "windows-core 0.52.0", ] [[package]] @@ -1147,19 +1279,19 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.7.1" +version = "2.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c9c992b02b5b4c94ea26e32fe5bccb7aa7d9f390ab5c1221ff895bc7ea8b652" +checksum = "3954d50fe15b02142bf25d3b8bdadb634ec3948f103d04ffe3031bc8fe9d7058" dependencies = [ "equivalent", - "hashbrown", + "hashbrown 0.15.2", ] [[package]] name = "insta" -version = "1.42.1" +version = "1.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71c1b125e30d93896b365e156c33dadfffab45ee8400afcbba4752f59de08a86" +checksum = "50259abbaa67d11d2bcafc7ba1d094ed7a0c70e3ce893f0d0997f73558cb3084" dependencies = [ "console", "linked-hash-map", @@ -1170,9 +1302,9 @@ dependencies = [ [[package]] name = "ipld-core" -version = "0.4.1" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4ede82a79e134f179f4b29b5fdb1eb92bd1b38c4dfea394c539051150a21b9b" +checksum = "104718b1cc124d92a6d01ca9c9258a7df311405debb3408c445a36452f9bf8db" dependencies = [ "cid", "serde", @@ -1193,15 +1325,14 @@ checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" [[package]] name = "itoa" -version = "1.0.14" +version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d75a2a4b1b190afb6f5425f10f6a8f959d2ea0b9c2b1d79553551850539e4674" +checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" [[package]] name = "jetstream-oxide" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cbde770c76b32262a837d968850d29232189844f4e11a3f02a3d87473929f7e9" +version = "0.1.2" +source = "git+https://github.com/videah/jetstream-oxide?rev=7f21cfae9d8fe193ceb42fb04e511f45ac23764a#7f21cfae9d8fe193ceb42fb04e511f45ac23764a" dependencies = [ "async-trait", "atrium-api", @@ -1211,7 +1342,7 @@ dependencies = [ "log", "serde", "serde_json", - "thiserror 2.0.11", + "thiserror 2.0.12", "tokio", "tokio-tungstenite 0.24.0", "tokio-util", @@ -1219,6 +1350,30 @@ dependencies = [ "zstd", ] +[[package]] +name = "jiff" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d699bc6dfc879fb1bf9bdff0d4c56f0884fc6f0d0eb0fba397a6d00cd9a6b85e" +dependencies = [ + "jiff-static", + "log", + "portable-atomic", + "portable-atomic-util", + "serde", +] + +[[package]] +name = "jiff-static" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d16e75759ee0aa64c57a56acbf43916987b20c77373cb7e808979e02b93c9f9" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "jobserver" version = "0.1.32" @@ -1247,11 +1402,17 @@ dependencies = [ "serde", ] +[[package]] +name = "lazy_static" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" + [[package]] name = "libc" -version = "0.2.169" +version = "0.2.171" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5aba8db14291edd000dfcc4d620c7ebfb122c613afb886ca8803fa4e128a20a" +checksum = "c19937216e9d3aa9956d9bb8dfc0b0c8beb6058fc4f7a4dc4d850edf86a237d6" [[package]] name = "libsqlite3-sys" @@ -1272,15 +1433,15 @@ checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" [[package]] name = "linux-raw-sys" -version = "0.4.15" +version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab" +checksum = "fe7db12097d22ec582439daf8618b8fdd1a7bef6270e9af3b1ebcd30893cf413" [[package]] name = "litemap" -version = "0.7.4" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ee93343901ab17bd981295f2cf0026d4ad018c7c31ba84549a4ddbb47a45104" +checksum = "23fb14cb19457329c82206317a5663005a4d404783dc74f4252769b0d5f42856" [[package]] name = "lock_api" @@ -1294,9 +1455,40 @@ dependencies = [ [[package]] name = "log" -version = "0.4.25" +version = "0.4.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30bde2b3dc3671ae49d8e2e9f044c7c005836e7a023ee57cffa25ab82764bb9e" + +[[package]] +name = "loom" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "419e0dc8046cb947daa77eb95ae174acfbddb7673b4151f56d1eed8e93fbfaca" +dependencies = [ + "cfg-if", + "generator", + "scoped-tls", + "tracing", + "tracing-subscriber", +] + +[[package]] +name = "lru" +version = "0.12.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "234cf4f4a04dc1f57e24b96cc0cd600cf2af460d4161ac5ecdd0af8e1f3b2a38" +dependencies = [ + "hashbrown 0.15.2", +] + +[[package]] +name = "matchers" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04cbf5b083de1c7e0222a7a51dbfdba1cbe1c6ab0b15e29fff3f6c077fd9cd9f" +checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558" +dependencies = [ + "regex-automata 0.1.10", +] [[package]] name = "memchr" @@ -1322,9 +1514,9 @@ dependencies = [ [[package]] name = "miniz_oxide" -version = "0.8.3" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8402cab7aefae129c6977bb0ff1b8fd9a04eb5b51efc50a70bea51cda0c7924" +checksum = "8e3e04debbb59698c15bacbb6d93584a8c0ca9cc3213cb423d31f760d8843ce5" dependencies = [ "adler2", ] @@ -1340,6 +1532,28 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "moka" +version = "0.12.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9321642ca94a4282428e6ea4af8cc2ca4eac48ac7a6a4ea8f33f76d0ce70926" +dependencies = [ + "async-lock", + "crossbeam-channel", + "crossbeam-epoch", + "crossbeam-utils", + "event-listener", + "futures-util", + "loom", + "parking_lot", + "portable-atomic", + "rustc_version", + "smallvec", + "tagptr", + "thiserror 1.0.69", + "uuid", +] + [[package]] name = "multer" version = "2.1.0" @@ -1391,9 +1605,9 @@ dependencies = [ [[package]] name = "native-tls" -version = "0.2.13" +version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0dab59f8e050d5df8e4dd87d9206fb6f65a483e20ac9fda365ade4fab353196c" +checksum = "87de3442987e9dbec73158d5c715e7ad9072fda936bb03d19d7fa10e00520f0e" dependencies = [ "libc", "log", @@ -1406,6 +1620,16 @@ dependencies = [ "tempfile", ] +[[package]] +name = "nu-ansi-term" +version = "0.46.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84" +dependencies = [ + "overload", + "winapi", +] + [[package]] name = "num-traits" version = "0.2.19" @@ -1426,15 +1650,15 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.20.3" +version = "1.21.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "945462a4b81e43c4e3ba96bd7b49d834c6f61198356aa858733bc4acf3cbe62e" +checksum = "d75b0bedcc4fe52caa0e03d9f1151a323e4aa5e2d78ba3580400cd3c9e2bc4bc" [[package]] name = "openssl" -version = "0.10.70" +version = "0.10.71" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61cfb4e166a8bb8c9b55c500bc2308550148ece889be90f609377e58140f42c6" +checksum = "5e14130c6a98cd258fdcb0fb6d744152343ff729cbfcb28c656a9d12b999fbcd" dependencies = [ "bitflags", "cfg-if", @@ -1464,18 +1688,18 @@ checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e" [[package]] name = "openssl-src" -version = "300.4.1+3.4.0" +version = "300.4.2+3.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "faa4eac4138c62414b5622d1b31c5c304f34b406b013c079c2bbc652fdd6678c" +checksum = "168ce4e058f975fe43e89d9ccf78ca668601887ae736090aacc23ae353c298e2" dependencies = [ "cc", ] [[package]] name = "openssl-sys" -version = "0.9.105" +version = "0.9.106" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b22d5b84be05a8d6947c7cb71f7c849aa0f112acd4bf51c2a7c1c988ac0a9dc" +checksum = "8bb61ea9811cc39e3c2069f40b8b8e2e70d8569b361f879786cc7ed48b777cdd" dependencies = [ "cc", "libc", @@ -1484,6 +1708,18 @@ dependencies = [ "vcpkg", ] +[[package]] +name = "overload" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" + +[[package]] +name = "parking" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba" + [[package]] name = "parking_lot" version = "0.12.3" @@ -1504,7 +1740,7 @@ dependencies = [ "libc", "redox_syscall", "smallvec", - "windows-targets", + "windows-targets 0.52.6", ] [[package]] @@ -1515,18 +1751,18 @@ checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" [[package]] name = "pin-project" -version = "1.1.9" +version = "1.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfe2e71e1471fe07709406bf725f710b02927c9c54b2b5b2ec0e8087d97c327d" +checksum = "677f1add503faace112b9f1373e43e9e054bfdd22ff1a63c1bc485eaec6a6a8a" dependencies = [ "pin-project-internal", ] [[package]] name = "pin-project-internal" -version = "1.1.9" +version = "1.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6e859e6e5bd50440ab63c47e3ebabc90f26251f7c73c3d3e837b74a1cc3fa67" +checksum = "6e918e4ff8c4549eb882f14b3a4bc8c8bc93de829416eacf579f1207a8fbf861" dependencies = [ "proc-macro2", "quote", @@ -1547,24 +1783,39 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] name = "pkg-config" -version = "0.3.31" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "953ec861398dccce10c670dfeaf3ec4911ca479e9c02154b3a215178c5f566f2" +checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" + +[[package]] +name = "portable-atomic" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "350e9b48cbc6b0e028b0473b114454c6316e57336ee184ceab6e53f72c178b3e" + +[[package]] +name = "portable-atomic-util" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8a2f0d8d040d7848a709caf78912debcc3f33ee4b3cac47d73d1e1069e83507" +dependencies = [ + "portable-atomic", +] [[package]] name = "ppv-lite86" -version = "0.2.20" +version = "0.2.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04" +checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9" dependencies = [ - "zerocopy", + "zerocopy 0.8.23", ] [[package]] name = "proc-macro2" -version = "1.0.93" +version = "1.0.94" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60946a68e5f9d28b0dc1c21bb8a97ee7d018a8b322fa57838ba31cc878e22d99" +checksum = "a31971752e70b8b2686d7e46ec17fb38dad4051d94024c88df49b667caea9c84" dependencies = [ "unicode-ident", ] @@ -1579,14 +1830,14 @@ dependencies = [ "rustdoc-types", "serde", "serde_json", - "thiserror 2.0.11", + "thiserror 2.0.12", ] [[package]] name = "quote" -version = "1.0.38" +version = "1.0.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e4dccaaaf89514f546c693ddc140f729f958c247918a13380cccc6078391acc" +checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d" dependencies = [ "proc-macro2", ] @@ -1623,9 +1874,9 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.5.8" +version = "0.5.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03a862b389f93e68874fbf580b9de08dd02facb9a788ebadaf4a3fd33cf58834" +checksum = "0b8c0c260b63a8219631167be35e6a988e9554dbd323f8bd08439c8ed1302bd1" dependencies = [ "bitflags", ] @@ -1638,8 +1889,17 @@ checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" dependencies = [ "aho-corasick", "memchr", - "regex-automata", - "regex-syntax", + "regex-automata 0.4.9", + "regex-syntax 0.8.5", +] + +[[package]] +name = "regex-automata" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" +dependencies = [ + "regex-syntax 0.6.29", ] [[package]] @@ -1650,9 +1910,15 @@ checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908" dependencies = [ "aho-corasick", "memchr", - "regex-syntax", + "regex-syntax 0.8.5", ] +[[package]] +name = "regex-syntax" +version = "0.6.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" + [[package]] name = "regex-syntax" version = "0.8.5" @@ -1661,9 +1927,9 @@ checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" [[package]] name = "reqwest" -version = "0.12.12" +version = "0.12.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43e734407157c3c2034e0258f5e4473ddb361b1e85f95a66690d67264d7cd1da" +checksum = "989e327e510263980e231de548a33e63d34962d29ae61b467389a1a09627a254" dependencies = [ "async-compression", "base64 0.22.1", @@ -1671,8 +1937,8 @@ dependencies = [ "encoding_rs", "futures-core", "futures-util", - "h2 0.4.7", - "http 1.2.0", + "h2 0.4.8", + "http 1.3.1", "http-body 1.0.1", "http-body-util", "hyper 1.6.0", @@ -1707,15 +1973,14 @@ dependencies = [ [[package]] name = "ring" -version = "0.17.8" +version = "0.17.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c17fa4cb658e3583423e915b9f3acc01cceaee1860e33d59ebae66adc3a2dc0d" +checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7" dependencies = [ "cc", "cfg-if", "getrandom 0.2.15", "libc", - "spin", "untrusted", "windows-sys 0.52.0", ] @@ -1740,16 +2005,25 @@ version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" +[[package]] +name = "rustc_version" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" +dependencies = [ + "semver", +] + [[package]] name = "rustdoc-json" -version = "0.9.4" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9cba50605762dcbc2e103a3a8b195c83b6978aca443c7dd6699ed2971c213e5" +checksum = "9e27b4d503f72ab0feb20d2b4968930f21ebf1fc904f8792329f4176f02a65d6" dependencies = [ "cargo-manifest", "cargo_metadata", "serde", - "thiserror 2.0.11", + "thiserror 2.0.12", "toml", "tracing", ] @@ -1765,9 +2039,9 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.44" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154" +checksum = "f7178faa4b75a30e269c71e61c353ce2748cf3d76f0c44c393f4e60abf49b825" dependencies = [ "bitflags", "errno", @@ -1778,9 +2052,9 @@ dependencies = [ [[package]] name = "rustls" -version = "0.23.22" +version = "0.23.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fb9263ab4eb695e42321db096e3b8fbd715a59b154d5c88d82db2175b681ba7" +checksum = "47796c98c480fce5406ef69d1c76378375492c3b0a0de587be0c1d9feb12f395" dependencies = [ "once_cell", "rustls-pki-types", @@ -1817,24 +2091,24 @@ dependencies = [ [[package]] name = "rustup-toolchain" -version = "0.1.9" +version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b1146c7808061ba181ab8e2f0836e91b0cc2fd10a70e64dae5c55381ce6d6cf" +checksum = "2d5715001c3f29532641421aaddb1302cbcbfd7507ed5f3a5dd0ddb5b808a7e0" dependencies = [ - "thiserror 2.0.11", + "thiserror 2.0.12", ] [[package]] name = "rustversion" -version = "1.0.19" +version = "1.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7c45b9784283f1b2e7fb61b42047c2fd678ef0960d4f6f1eba131594cc369d4" +checksum = "eded382c5f5f786b989652c49544c4877d9f015cc22e145a5ea8ea66c2921cd2" [[package]] name = "ryu" -version = "1.0.19" +version = "1.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ea1a2d0a644769cc99faa24c3ad26b379b786fe7c36fd3c546254801650e6dd" +checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" [[package]] name = "schannel" @@ -1882,36 +2156,36 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.25" +version = "1.0.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f79dfe2d285b0488816f30e700a7438c5a73d816b5b7d3ac72fbc48b0d185e03" +checksum = "56e6fa9c48d24d85fb3de5ad847117517440f6beceb7798af16b4a87d616b8d0" dependencies = [ "serde", ] [[package]] name = "serde" -version = "1.0.217" +version = "1.0.219" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02fc4265df13d6fa1d00ecff087228cc0a2b5f3c0e87e258d8b94a156e984c70" +checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6" dependencies = [ "serde_derive", ] [[package]] name = "serde_bytes" -version = "0.11.15" +version = "0.11.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "387cc504cb06bb40a96c8e04e951fe01854cf6bc921053c954e4a606d9675c6a" +checksum = "8437fd221bde2d4ca316d61b90e337e9e702b3820b87d63caa9ba6c02bd06d96" dependencies = [ "serde", ] [[package]] name = "serde_derive" -version = "1.0.217" +version = "1.0.219" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a9bf7cf98d04a2b28aead066b7496853d4779c9cc183c440dbac457641e19a0" +checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00" dependencies = [ "proc-macro2", "quote", @@ -1933,9 +2207,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.138" +version = "1.0.140" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d434192e7da787e94a6ea7e9670b26a036d0ca41e0b7efb2676dd32bae872949" +checksum = "20068b6e96dc6c9bd23e01df8827e6c7e1f2fddd43c21810382803c136b99373" dependencies = [ "itoa", "memchr", @@ -1975,6 +2249,15 @@ dependencies = [ "digest", ] +[[package]] +name = "sharded-slab" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" +dependencies = [ + "lazy_static", +] + [[package]] name = "shlex" version = "1.3.0" @@ -2020,6 +2303,7 @@ dependencies = [ "serde_json", "tokio", "warp", + "whatlang", ] [[package]] @@ -2033,9 +2317,9 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.13.2" +version = "1.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" +checksum = "7fcf8323ef1faaee30a44a340193b1ac6814fd9b7b4e88e9d4519a3e4abe1cfd" [[package]] name = "socket2" @@ -2076,9 +2360,9 @@ checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" [[package]] name = "syn" -version = "2.0.98" +version = "2.0.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36147f1a48ae0ec2b5b3bc5b537d267457555a10dc06f3dbc8cb11ba3006d3b1" +checksum = "b09a44accad81e1ba1cd74a32461ba89dee89095ba17b32f5d03683b1b1fc2a0" dependencies = [ "proc-macro2", "quote", @@ -2126,13 +2410,18 @@ dependencies = [ "libc", ] +[[package]] +name = "tagptr" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b2093cf4c8eb1e67749a6762251bc9cd836b6fc171623bd0a9d324d37af2417" + [[package]] name = "tempfile" -version = "3.16.0" +version = "3.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38c246215d7d24f48ae091a2902398798e05d978b24315d6efbc00ede9a8bb91" +checksum = "488960f40a3fd53d72c2a29a58722561dee8afdd175bd88e3db4677d7b2ba600" dependencies = [ - "cfg-if", "fastrand", "getrandom 0.3.1", "once_cell", @@ -2151,11 +2440,11 @@ dependencies = [ [[package]] name = "thiserror" -version = "2.0.11" +version = "2.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d452f284b73e6d76dd36758a0c8684b1d5be31f92b89d07fd5822175732206fc" +checksum = "567b8a2dae586314f7be2a752ec7474332959c6460e02bde30d702a66d488708" dependencies = [ - "thiserror-impl 2.0.11", + "thiserror-impl 2.0.12", ] [[package]] @@ -2171,15 +2460,25 @@ dependencies = [ [[package]] name = "thiserror-impl" -version = "2.0.11" +version = "2.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26afc1baea8a989337eeb52b6e72a039780ce45c3edfcc9c5b9d112feeb173c2" +checksum = "7f7cf42b4507d8ea322120659672cf1b9dbb93f8f2d4ecfd6e51350ff5b17a1d" dependencies = [ "proc-macro2", "quote", "syn", ] +[[package]] +name = "thread_local" +version = "1.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c" +dependencies = [ + "cfg-if", + "once_cell", +] + [[package]] name = "tinystr" version = "0.7.6" @@ -2192,9 +2491,9 @@ dependencies = [ [[package]] name = "tokio" -version = "1.43.0" +version = "1.44.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d61fa4ffa3de412bfea335c6ecff681de2b609ba3c77ef3e00e521813a9ed9e" +checksum = "f382da615b842244d4b8738c82ed1275e6c5dd90c459a30941cd07080b06c91a" dependencies = [ "backtrace", "bytes", @@ -2231,9 +2530,9 @@ dependencies = [ [[package]] name = "tokio-rustls" -version = "0.26.1" +version = "0.26.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f6d0975eaace0cf0fcadee4e4aaa5da15b5c079146f2cffb67c113be122bf37" +checksum = "8e727b36a1a0e8b74c376ac2211e40c2c8af09fb4013c60d910495810f008e9b" dependencies = [ "rustls", "tokio", @@ -2267,9 +2566,9 @@ dependencies = [ [[package]] name = "tokio-util" -version = "0.7.13" +version = "0.7.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7fcaa8d55a2bdd6b83ace262b016eca0d79ee02818c5c1bcdf0305114081078" +checksum = "6b9590b93e6fcc1739458317cccd391ad3955e2bde8913edf6f95f9e65a8f034" dependencies = [ "bytes", "futures-core", @@ -2302,9 +2601,9 @@ dependencies = [ [[package]] name = "toml_edit" -version = "0.22.23" +version = "0.22.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02a8b472d1a3d7c18e2d61a489aee3453fd9031c33e4f55bd533f4a7adca1bee" +checksum = "17b4795ff5edd201c7cd6dca065ae59972ce77d1b80fa0a84d94950ece7d1474" dependencies = [ "indexmap", "serde", @@ -2370,6 +2669,36 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e672c95779cf947c5311f83787af4fa8fffd12fb27e4993211a84bdfd9610f9c" dependencies = [ "once_cell", + "valuable", +] + +[[package]] +name = "tracing-log" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3" +dependencies = [ + "log", + "once_cell", + "tracing-core", +] + +[[package]] +name = "tracing-subscriber" +version = "0.3.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8189decb5ac0fa7bc8b96b7cb9b2701d60d48805aca84a238004d665fcc4008" +dependencies = [ + "matchers", + "nu-ansi-term", + "once_cell", + "regex", + "sharded-slab", + "smallvec", + "thread_local", + "tracing", + "tracing-core", + "tracing-log", ] [[package]] @@ -2398,7 +2727,7 @@ dependencies = [ "byteorder", "bytes", "data-encoding", - "http 1.2.0", + "http 1.3.1", "httparse", "log", "rand", @@ -2417,7 +2746,7 @@ dependencies = [ "byteorder", "bytes", "data-encoding", - "http 1.2.0", + "http 1.3.1", "httparse", "log", "native-tls", @@ -2430,9 +2759,9 @@ dependencies = [ [[package]] name = "typenum" -version = "1.17.0" +version = "1.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" +checksum = "1dccffe3ce07af9386bfd29e80c0ab1a8205a2fc34e4bcd40364df902cfa8f3f" [[package]] name = "unicase" @@ -2442,9 +2771,9 @@ checksum = "75b844d17643ee918803943289730bec8aac480150456169e647ed0b576ba539" [[package]] name = "unicode-ident" -version = "1.0.16" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a210d160f08b701c8721ba1c726c11662f877ea6b7094007e1ca9a1041945034" +checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" [[package]] name = "unsigned-varint" @@ -2493,6 +2822,21 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" +[[package]] +name = "uuid" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "458f7a779bf54acc9f347480ac654f68407d3aab21269a6e3c9f922acd9e2da9" +dependencies = [ + "getrandom 0.3.1", +] + +[[package]] +name = "valuable" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba73ea9cf16a25df0c8caa16c51acb937d5712a8429db78a3ee29d5dcacd3a65" + [[package]] name = "vcpkg" version = "0.2.15" @@ -2639,24 +2983,117 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "web-time" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a6580f308b1fad9207618087a65c04e7a10bc77e02c8e84e9b00dd4b12fa0bb" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "whatlang" +version = "0.16.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "471d1c1645d361eb782a1650b1786a8fb58dd625e681a04c09f5ff7c8764a7b0" +dependencies = [ + "hashbrown 0.14.5", + "once_cell", +] + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows" +version = "0.58.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd04d41d93c4992d421894c18c8b43496aa748dd4c081bac0dc93eb0489272b6" +dependencies = [ + "windows-core 0.58.0", + "windows-targets 0.52.6", +] + [[package]] name = "windows-core" version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" dependencies = [ - "windows-targets", + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-core" +version = "0.58.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ba6d44ec8c2591c134257ce647b7ea6b20335bf6379a27dac5f1641fcf59f99" +dependencies = [ + "windows-implement", + "windows-interface", + "windows-result 0.2.0", + "windows-strings 0.1.0", + "windows-targets 0.52.6", ] +[[package]] +name = "windows-implement" +version = "0.58.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2bbd5b46c938e506ecbce286b6628a02171d56153ba733b6c741fc627ec9579b" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "windows-interface" +version = "0.58.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "053c4c462dc91d3b1504c6fe5a726dd15e216ba718e84a0e46a88fbe5ded3515" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "windows-link" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6dccfd733ce2b1753b03b6d3c65edf020262ea35e20ccdf3e288043e6dd620e3" + [[package]] name = "windows-registry" -version = "0.2.0" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e400001bb720a623c1c69032f8e3e4cf09984deec740f007dd2b03ec864804b0" +checksum = "4286ad90ddb45071efd1a66dfa43eb02dd0dfbae1545ad6cc3c51cf34d7e8ba3" dependencies = [ - "windows-result", - "windows-strings", - "windows-targets", + "windows-result 0.3.1", + "windows-strings 0.3.1", + "windows-targets 0.53.0", ] [[package]] @@ -2665,7 +3102,16 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1d1043d8214f791817bab27572aaa8af63732e11bf84aa21a45a78d6c317ae0e" dependencies = [ - "windows-targets", + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-result" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06374efe858fab7e4f881500e6e86ec8bc28f9462c47e5a9941a0142ad86b189" +dependencies = [ + "windows-link", ] [[package]] @@ -2674,8 +3120,17 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4cd9b125c486025df0eabcb585e62173c6c9eddcec5d117d3b6e8c30e2ee4d10" dependencies = [ - "windows-result", - "windows-targets", + "windows-result 0.2.0", + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-strings" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87fa48cc5d406560701792be122a10132491cff9d0aeb23583cc2dcafc847319" +dependencies = [ + "windows-link", ] [[package]] @@ -2684,7 +3139,7 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ - "windows-targets", + "windows-targets 0.52.6", ] [[package]] @@ -2693,7 +3148,7 @@ version = "0.59.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" dependencies = [ - "windows-targets", + "windows-targets 0.52.6", ] [[package]] @@ -2702,14 +3157,30 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" dependencies = [ - "windows_aarch64_gnullvm", - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_gnullvm", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_gnullvm", - "windows_x86_64_msvc", + "windows_aarch64_gnullvm 0.52.6", + "windows_aarch64_msvc 0.52.6", + "windows_i686_gnu 0.52.6", + "windows_i686_gnullvm 0.52.6", + "windows_i686_msvc 0.52.6", + "windows_x86_64_gnu 0.52.6", + "windows_x86_64_gnullvm 0.52.6", + "windows_x86_64_msvc 0.52.6", +] + +[[package]] +name = "windows-targets" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1e4c7e8ceaaf9cb7d7507c974735728ab453b67ef8f18febdd7c11fe59dca8b" +dependencies = [ + "windows_aarch64_gnullvm 0.53.0", + "windows_aarch64_msvc 0.53.0", + "windows_i686_gnu 0.53.0", + "windows_i686_gnullvm 0.53.0", + "windows_i686_msvc 0.53.0", + "windows_x86_64_gnu 0.53.0", + "windows_x86_64_gnullvm 0.53.0", + "windows_x86_64_msvc 0.53.0", ] [[package]] @@ -2718,53 +3189,101 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86b8d5f90ddd19cb4a147a5fa63ca848db3df085e25fee3cc10b39b6eebae764" + [[package]] name = "windows_aarch64_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" +[[package]] +name = "windows_aarch64_msvc" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7651a1f62a11b8cbd5e0d42526e55f2c99886c77e007179efff86c2b137e66c" + [[package]] name = "windows_i686_gnu" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" +[[package]] +name = "windows_i686_gnu" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1dc67659d35f387f5f6c479dc4e28f1d4bb90ddd1a5d3da2e5d97b42d6272c3" + [[package]] name = "windows_i686_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" +[[package]] +name = "windows_i686_gnullvm" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ce6ccbdedbf6d6354471319e781c0dfef054c81fbc7cf83f338a4296c0cae11" + [[package]] name = "windows_i686_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" +[[package]] +name = "windows_i686_msvc" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "581fee95406bb13382d2f65cd4a908ca7b1e4c2f1917f143ba16efe98a589b5d" + [[package]] name = "windows_x86_64_gnu" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" +[[package]] +name = "windows_x86_64_gnu" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e55b5ac9ea33f2fc1716d1742db15574fd6fc8dadc51caab1c16a3d3b4190ba" + [[package]] name = "windows_x86_64_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a6e035dd0599267ce1ee132e51c27dd29437f63325753051e71dd9e42406c57" + [[package]] name = "windows_x86_64_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" +[[package]] +name = "windows_x86_64_msvc" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486" + [[package]] name = "winnow" -version = "0.7.1" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86e376c75f4f43f44db463cf729e0d3acbf954d13e22c51e26e4c264b4ab545f" +checksum = "0e97b544156e9bebe1a0ffbc03484fc1ffe3100cbce3ffb17eac35f7cdd7ab36" dependencies = [ "memchr", ] @@ -2820,8 +3339,16 @@ version = "0.7.35" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" dependencies = [ - "byteorder", - "zerocopy-derive", + "zerocopy-derive 0.7.35", +] + +[[package]] +name = "zerocopy" +version = "0.8.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd97444d05a4328b90e75e503a34bad781f14e28a823ad3557f0750df1ebcbc6" +dependencies = [ + "zerocopy-derive 0.8.23", ] [[package]] @@ -2835,20 +3362,31 @@ dependencies = [ "syn", ] +[[package]] +name = "zerocopy-derive" +version = "0.8.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6352c01d0edd5db859a63e2605f4ea3183ddbd15e2c4a9e7d32184df75e4f154" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "zerofrom" -version = "0.1.5" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cff3ee08c995dee1859d998dea82f7374f2826091dd9cd47def953cae446cd2e" +checksum = "50cc42e0333e05660c3587f3bf9d0478688e15d870fab3346451ce7f8c9fbea5" dependencies = [ "zerofrom-derive", ] [[package]] name = "zerofrom-derive" -version = "0.1.5" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "595eed982f7d355beb85837f651fa22e90b3c044842dc7f2c2842c086f295808" +checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502" dependencies = [ "proc-macro2", "quote", @@ -2886,27 +3424,27 @@ dependencies = [ [[package]] name = "zstd" -version = "0.13.2" +version = "0.13.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcf2b778a664581e31e389454a7072dab1647606d44f7feea22cd5abb9c9f3f9" +checksum = "e91ee311a569c327171651566e07972200e76fcfe2242a4fa446149a3881c08a" dependencies = [ "zstd-safe", ] [[package]] name = "zstd-safe" -version = "7.2.1" +version = "7.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54a3ab4db68cea366acc5c897c7b4d4d1b8994a9cd6e6f841f8964566a419059" +checksum = "f3051792fbdc2e1e143244dc28c60f73d8470e93f3f9cbd0ead44da5ed802722" dependencies = [ "zstd-sys", ] [[package]] name = "zstd-sys" -version = "2.0.13+zstd.1.5.6" +version = "2.0.14+zstd.1.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38ff0f21cfee8f97d94cef41359e0c89aa6113028ab0291aa8ca0038995a95aa" +checksum = "8fb060d4926e4ac3a3ad15d864e99ceb5f343c6b34f5bd6d81ae6ed417311be5" dependencies = [ "cc", "pkg-config", diff --git a/Cargo.toml b/Cargo.toml index ac84918..648ece0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,8 +11,9 @@ authors = ["cyypherus"] [lib] [features] +default = ["examples"] test-api = ["insta", "public-api", "rustdoc-json", "rustup-toolchain"] -examples = ["rusqlite", "regex"] +examples = ["rusqlite", "regex", "whatlang"] [[bin]] name = "my_did" @@ -37,10 +38,10 @@ path = "examples/sqlite/src/main.rs" required-features = ["examples"] [dependencies] -atrium-api = "=0.24.10" +atrium-api = "0.25.0" dotenv = "0.15.0" env_logger = "0.11.5" -jetstream-oxide = "0.1.1" +jetstream-oxide = { git = "https://github.com/videah/jetstream-oxide", rev = "7f21cfae9d8fe193ceb42fb04e511f45ac23764a" } log = "0.4.22" serde = "1.0.215" serde_json = "1.0.133" @@ -56,6 +57,7 @@ chrono = "0.4.39" # `examples` feature dependencies rusqlite = { version = "0.33.0", features = ["bundled"], optional = true } regex = { version = "1.11.1", optional = true } +whatlang = { version = "0.16.4", optional = true } # `test-api` feature dependencies insta = { version = "1.42.1", optional = true } diff --git a/examples/sqlite/Cargo.lock b/examples/sqlite/Cargo.lock index 42d743d..0b0edca 100644 --- a/examples/sqlite/Cargo.lock +++ b/examples/sqlite/Cargo.lock @@ -17,6 +17,18 @@ version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" +[[package]] +name = "ahash" +version = "0.8.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" +dependencies = [ + "cfg-if", + "once_cell", + "version_check", + "zerocopy 0.7.35", +] + [[package]] name = "aho-corasick" version = "1.1.3" @@ -26,6 +38,12 @@ dependencies = [ "memchr", ] +[[package]] +name = "allocator-api2" +version = "0.2.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" + [[package]] name = "android-tzdata" version = "0.1.1" @@ -93,15 +111,15 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.95" +version = "1.0.97" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34ac096ce696dc2fcabef30516bb13c0a68a11d30131d3df6f04711467681b04" +checksum = "dcfed56ad506cb2c684a14971b8861fdc3baaaae314b9e5f9bb532cbe3ba7a4f" [[package]] name = "async-compression" -version = "0.4.18" +version = "0.4.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df895a515f70646414f4b45c0b79082783b80552b373a68283012928df56f522" +checksum = "c0cf008e5e1a9e9e22a7d3c9a4992e21a350290069e36d8fb72304ed17e8f2d2" dependencies = [ "flate2", "futures-core", @@ -110,11 +128,22 @@ dependencies = [ "tokio", ] +[[package]] +name = "async-lock" +version = "3.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff6e472cdea888a4bd64f342f09b3f50e1886d32afe8df3d663c01140b811b18" +dependencies = [ + "event-listener", + "event-listener-strategy", + "pin-project-lite", +] + [[package]] name = "async-trait" -version = "0.1.85" +version = "0.1.88" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f934833b4b7233644e5848f235df3f57ed8c80f1528a26c3dfa13d2147fa056" +checksum = "e539d3fca749fcee5236ab05e93a52867dd549cc157c8cb7f99595f3cedffdb5" dependencies = [ "proc-macro2", "quote", @@ -129,13 +158,14 @@ checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" [[package]] name = "atrium-api" -version = "0.24.10" +version = "0.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c5d74937642f6b21814e82d80f54d55ebd985b681bffbe27c8a76e726c3c4db" +checksum = "ea3ea578c768ec91082e424a8d139517b2cb5c75149bf3cec04371a1e74f00f2" dependencies = [ + "atrium-common", "atrium-xrpc", "chrono", - "http 1.2.0", + "http 1.3.1", "ipld-core", "langtag", "regex", @@ -147,13 +177,28 @@ dependencies = [ "trait-variant", ] +[[package]] +name = "atrium-common" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "168e558408847bfed69df1033a32fd051f7a037ebc90ea46e588ccb2bfbd7233" +dependencies = [ + "dashmap", + "lru", + "moka", + "thiserror 1.0.69", + "tokio", + "trait-variant", + "web-time", +] + [[package]] name = "atrium-xrpc" -version = "0.12.0" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f223b98be2acdd7afe5b867744aee8258413ed09993099de0a036b247db0ec4c" +checksum = "6b4956d94147cfbb669c68f654eb4fd6a1d00648c810cec79d04ec5425b8f378" dependencies = [ - "http 1.2.0", + "http 1.3.1", "serde", "serde_html_form", "serde_json", @@ -163,9 +208,9 @@ dependencies = [ [[package]] name = "atrium-xrpc-client" -version = "0.5.10" +version = "0.5.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd9946c18301eee62e8bd0ade5ac2750c9a0778fadf097ac60024b2a79485603" +checksum = "9bab4287ccef501b3892e1325280e61ae79a96eb9ee63dceabc0ed3bea35f2eb" dependencies = [ "atrium-xrpc", "reqwest", @@ -177,6 +222,29 @@ version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" +[[package]] +name = "aws-lc-rs" +version = "1.12.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dabb68eb3a7aa08b46fddfd59a3d55c978243557a90ab804769f7e20e67d2b01" +dependencies = [ + "aws-lc-sys", + "zeroize", +] + +[[package]] +name = "aws-lc-sys" +version = "0.27.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77926887776171ced7d662120a75998e444d3750c951abfe07f90da130514b1f" +dependencies = [ + "bindgen", + "cc", + "cmake", + "dunce", + "fs_extra", +] + [[package]] name = "backtrace" version = "0.3.74" @@ -189,7 +257,7 @@ dependencies = [ "miniz_oxide", "object", "rustc-demangle", - "windows-targets", + "windows-targets 0.52.6", ] [[package]] @@ -216,17 +284,43 @@ version = "0.1.0" dependencies = [ "chrono", "log", + "metrics", + "metrics-exporter-prometheus", "regex", "rusqlite", "skyfeed", "tokio", + "whatlang", +] + +[[package]] +name = "bindgen" +version = "0.69.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "271383c67ccabffb7381723dea0672a673f292304fcb45c01cc648c7a8d58088" +dependencies = [ + "bitflags", + "cexpr", + "clang-sys", + "itertools", + "lazy_static", + "lazycell", + "log", + "prettyplease", + "proc-macro2", + "quote", + "regex", + "rustc-hash", + "shlex", + "syn", + "which", ] [[package]] name = "bitflags" -version = "2.8.0" +version = "2.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f68f53c83ab957f72c32642f3868eec03eb974d1fb82e453128456482613d36" +checksum = "5c8214115b7bf84099f1309324e63141d4c5d7cc26862f97a0a857dbefe165bd" [[package]] name = "block-buffer" @@ -239,9 +333,9 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.16.0" +version = "3.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" +checksum = "1628fb46dfa0b37568d12e5edd512553eccf6a22a78e8bde00bb4aed84d5bdbf" [[package]] name = "byteorder" @@ -251,21 +345,30 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.9.0" +version = "1.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "325918d6fe32f23b19878fe4b34794ae41fc19ddbe53b10571a4874d44ffd39b" +checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a" [[package]] name = "cc" -version = "1.2.10" +version = "1.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13208fcbb66eaeffe09b99fffbe1af420f00a7b35aa99ad683dfc1aa76145229" +checksum = "1fcb57c740ae1daf453ae85f16e37396f672b039e00d9d866e07ddb24e328e3a" dependencies = [ "jobserver", "libc", "shlex", ] +[[package]] +name = "cexpr" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766" +dependencies = [ + "nom", +] + [[package]] name = "cfg-if" version = "1.0.0" @@ -274,9 +377,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "chrono" -version = "0.4.39" +version = "0.4.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e36cc9d416881d2e24f9a963be5fb1cd90966419ac844274161d10488b3e825" +checksum = "1a7964611d71df112cb1730f2ee67324fcf4d0fc6606acbbe9bfe06df124637c" dependencies = [ "android-tzdata", "iana-time-zone", @@ -284,7 +387,7 @@ dependencies = [ "num-traits", "serde", "wasm-bindgen", - "windows-targets", + "windows-link", ] [[package]] @@ -301,11 +404,22 @@ dependencies = [ "unsigned-varint", ] +[[package]] +name = "clang-sys" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b023947811758c97c59bf9d1c188fd619ad4718dcaa767947df1cadb14f39f4" +dependencies = [ + "glob", + "libc", + "libloading", +] + [[package]] name = "clap" -version = "4.5.27" +version = "4.5.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "769b0145982b4b48713e01ec42d61614425f27b7058bda7180a3a41f30104796" +checksum = "6088f3ae8c3608d19260cd7445411865a485688711b78b5be70d78cd96136f83" dependencies = [ "clap_builder", "clap_derive", @@ -313,9 +427,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.27" +version = "4.5.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b26884eb4b57140e4d2d93652abfa49498b938b3c9179f9fc487b0acc3edad7" +checksum = "22a7ef7f676155edfb82daa97f99441f3ebf4a58d5e32f295a56259f1b6facc8" dependencies = [ "anstream", "anstyle", @@ -325,9 +439,9 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.5.24" +version = "4.5.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54b755194d6389280185988721fffba69495eed5ee9feeee9a599b53db80318c" +checksum = "09176aae279615badda0765c0c0b3f6ed53f4709118af73cf4655d85d1530cd7" dependencies = [ "heck", "proc-macro2", @@ -341,12 +455,30 @@ version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f46ad14479a25103f283c0f10005961cf086d8dc42205bb44c46ac563475dca6" +[[package]] +name = "cmake" +version = "0.1.54" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7caa3f9de89ddbe2c607f4101924c5abec803763ae9534e4f4d7d8f84aa81f0" +dependencies = [ + "cc", +] + [[package]] name = "colorchoice" version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990" +[[package]] +name = "concurrent-queue" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ca0197aee26d1ae37445ee532fefce43251d24cc7c166799f4d46817f1d3973" +dependencies = [ + "crossbeam-utils", +] + [[package]] name = "core-foundation" version = "0.9.4" @@ -357,6 +489,16 @@ dependencies = [ "libc", ] +[[package]] +name = "core-foundation" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b55271e5c8c478ad3f38ad24ef34923091e0548492a266d19b3c0b4d82574c63" +dependencies = [ + "core-foundation-sys", + "libc", +] + [[package]] name = "core-foundation-sys" version = "0.8.7" @@ -374,9 +516,9 @@ dependencies = [ [[package]] name = "cpufeatures" -version = "0.2.16" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16b80225097f2e5ae4e7179dd2266824648f3e2f49d9134d584b76389d31c4c3" +checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" dependencies = [ "libc", ] @@ -390,6 +532,30 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "crossbeam-channel" +version = "0.5.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06ba6d68e24814cb8de6bb986db8222d3a027d15872cabc0d18817bc3c0e4471" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" + [[package]] name = "crypto-common" version = "0.1.6" @@ -400,17 +566,31 @@ dependencies = [ "typenum", ] +[[package]] +name = "dashmap" +version = "6.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5041cc499144891f3790297212f32a74fb938e5136a14943f338ef9e0ae276cf" +dependencies = [ + "cfg-if", + "crossbeam-utils", + "hashbrown 0.14.5", + "lock_api", + "once_cell", + "parking_lot_core", +] + [[package]] name = "data-encoding" -version = "2.7.0" +version = "2.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e60eed09d8c01d3cee5b7d30acb059b76614c918fa0f992e0dd6eeb10daad6f" +checksum = "575f75dfd25738df5b91b8e43e14d44bda14637a58fae779fd2b064f8bf3e010" [[package]] name = "data-encoding-macro" -version = "0.1.16" +version = "0.1.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b16d9d0d88a5273d830dac8b78ceb217ffc9b1d5404e5597a3542515329405b" +checksum = "9f9724adfcf41f45bf652b3995837669d73c4d49a1b5ac1ff82905ac7d9b5558" dependencies = [ "data-encoding", "data-encoding-macro-internal", @@ -418,9 +598,9 @@ dependencies = [ [[package]] name = "data-encoding-macro-internal" -version = "0.1.14" +version = "0.1.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1145d32e826a7748b69ee8fc62d3e6355ff7f1051df53141e7048162fc90481b" +checksum = "18e4fdb82bd54a12e42fb58a800dcae6b9e13982238ce2296dc3570b92148e1f" dependencies = [ "data-encoding", "syn", @@ -453,6 +633,18 @@ version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "77c90badedccf4105eca100756a0b1289e191f6fcbdadd3cee1d2f614f97da8f" +[[package]] +name = "dunce" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813" + +[[package]] +name = "either" +version = "1.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" + [[package]] name = "encoding_rs" version = "0.8.35" @@ -474,22 +666,22 @@ dependencies = [ [[package]] name = "env_logger" -version = "0.11.6" +version = "0.11.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcaee3d8e3cfc3fd92428d477bc97fc29ec8716d180c0d74c643bb26166660e0" +checksum = "c3716d7a920fb4fac5d84e9d4bce8ceb321e9414b4409da61b07b75c1e3d0697" dependencies = [ "anstream", "anstyle", "env_filter", - "humantime", + "jiff", "log", ] [[package]] name = "equivalent" -version = "1.0.1" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" +checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" [[package]] name = "errno" @@ -501,6 +693,27 @@ dependencies = [ "windows-sys 0.59.0", ] +[[package]] +name = "event-listener" +version = "5.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3492acde4c3fc54c845eaab3eed8bd00c7a7d881f78bfc801e43a93dec1331ae" +dependencies = [ + "concurrent-queue", + "parking", + "pin-project-lite", +] + +[[package]] +name = "event-listener-strategy" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c3e4e0dd3673c1139bf041f3008816d9cf2946bbfac2945c09e523b8d7b05b2" +dependencies = [ + "event-listener", + "pin-project-lite", +] + [[package]] name = "fallible-iterator" version = "0.3.0" @@ -521,9 +734,9 @@ checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" [[package]] name = "flate2" -version = "1.0.35" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c936bfdafb507ebbf50b8074c54fa31c5be9a1e7e5f467dd659697041407d07c" +checksum = "11faaf5a5236997af9848be0bef4db95824b1d534ebc64d0f0c6cf3e67bd38dc" dependencies = [ "crc32fast", "miniz_oxide", @@ -549,9 +762,9 @@ checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" [[package]] name = "foldhash" -version = "0.1.4" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0d2fde1f7b3d48b8395d5f2de76c18a528bd6a9cdde438df747bfcba3e05d6f" +checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" [[package]] name = "foreign-types" @@ -577,6 +790,12 @@ dependencies = [ "percent-encoding", ] +[[package]] +name = "fs_extra" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42703706b716c37f96a77aea830392ad231f44c9e9a67872fa5548707e11b11c" + [[package]] name = "futures-channel" version = "0.3.31" @@ -631,6 +850,19 @@ dependencies = [ "slab", ] +[[package]] +name = "generator" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc6bd114ceda131d3b1d665eba35788690ad37f5916457286b32ab6fd3c438dd" +dependencies = [ + "cfg-if", + "libc", + "log", + "rustversion", + "windows", +] + [[package]] name = "generic-array" version = "0.14.7" @@ -650,16 +882,34 @@ dependencies = [ "cfg-if", "js-sys", "libc", - "wasi", + "wasi 0.11.0+wasi-snapshot-preview1", "wasm-bindgen", ] +[[package]] +name = "getrandom" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73fea8450eea4bac3940448fb7ae50d91f034f941199fcd9d909a5a07aa455f0" +dependencies = [ + "cfg-if", + "libc", + "r-efi", + "wasi 0.14.2+wasi-0.2.4", +] + [[package]] name = "gimli" version = "0.31.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" +[[package]] +name = "glob" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8d1add55171497b4705a648c6b583acafb01d58050a51727785f0b2c8e0a2b2" + [[package]] name = "h2" version = "0.3.26" @@ -681,16 +931,16 @@ dependencies = [ [[package]] name = "h2" -version = "0.4.7" +version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ccae279728d634d083c00f6099cb58f01cc99c145b84b8be2f6c74618d79922e" +checksum = "5017294ff4bb30944501348f6f8e42e6ad28f42c8bbef7a74029aff064a4e3c2" dependencies = [ "atomic-waker", "bytes", "fnv", "futures-core", "futures-sink", - "http 1.2.0", + "http 1.3.1", "indexmap", "slab", "tokio", @@ -698,12 +948,24 @@ dependencies = [ "tracing", ] +[[package]] +name = "hashbrown" +version = "0.14.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" +dependencies = [ + "ahash", + "allocator-api2", +] + [[package]] name = "hashbrown" version = "0.15.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" dependencies = [ + "allocator-api2", + "equivalent", "foldhash", ] @@ -713,7 +975,7 @@ version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7382cf6263419f2d8df38c55d7da83da5c18aef87fc7a7fc1fb1e344edfe14c1" dependencies = [ - "hashbrown", + "hashbrown 0.15.2", ] [[package]] @@ -746,6 +1008,15 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" +[[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 = "http" version = "0.2.12" @@ -759,9 +1030,9 @@ dependencies = [ [[package]] name = "http" -version = "1.2.0" +version = "1.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f16ca2af56261c99fba8bac40a10251ce8188205a4c448fbb745a2e4daa76fea" +checksum = "f4a85d31aea989eead29a3aaf9e1115a180df8282431156e533de47660892565" dependencies = [ "bytes", "fnv", @@ -786,27 +1057,27 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" dependencies = [ "bytes", - "http 1.2.0", + "http 1.3.1", ] [[package]] name = "http-body-util" -version = "0.1.2" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "793429d76616a256bcb62c2a2ec2bed781c8307e797e2598c50010f2bee2544f" +checksum = "b021d93e26becf5dc7e1b75b1bed1fd93124b374ceb73f43d4d4eafec896a64a" dependencies = [ "bytes", - "futures-util", - "http 1.2.0", + "futures-core", + "http 1.3.1", "http-body 1.0.1", "pin-project-lite", ] [[package]] name = "httparse" -version = "1.9.5" +version = "1.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d71d3574edd2771538b901e6549113b4006ece66150fb69c0fb6d9a2adae946" +checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87" [[package]] name = "httpdate" @@ -814,12 +1085,6 @@ version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" -[[package]] -name = "humantime" -version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" - [[package]] name = "hyper" version = "0.14.32" @@ -846,17 +1111,18 @@ dependencies = [ [[package]] name = "hyper" -version = "1.5.2" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "256fb8d4bd6413123cc9d91832d78325c48ff41677595be797d90f42969beae0" +checksum = "cc2b571658e38e0c01b1fdca3bbbe93c00d3d71693ff2770043f8c29bc7d6f80" dependencies = [ "bytes", "futures-channel", "futures-util", - "h2 0.4.7", - "http 1.2.0", + "h2 0.4.8", + "http 1.3.1", "http-body 1.0.1", "httparse", + "httpdate", "itoa", "pin-project-lite", "smallvec", @@ -871,10 +1137,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2d191583f3da1305256f22463b9bb0471acad48a4e534a5218b9963e9c1f59b2" dependencies = [ "futures-util", - "http 1.2.0", - "hyper 1.5.2", + "http 1.3.1", + "hyper 1.6.0", "hyper-util", "rustls", + "rustls-native-certs", "rustls-pki-types", "tokio", "tokio-rustls", @@ -889,7 +1156,7 @@ checksum = "70206fc6890eaca9fde8a0bf71caa2ddfc9fe045ac9e5c70df101a7dbde866e0" dependencies = [ "bytes", "http-body-util", - "hyper 1.5.2", + "hyper 1.6.0", "hyper-util", "native-tls", "tokio", @@ -906,9 +1173,9 @@ dependencies = [ "bytes", "futures-channel", "futures-util", - "http 1.2.0", + "http 1.3.1", "http-body 1.0.1", - "hyper 1.5.2", + "hyper 1.6.0", "pin-project-lite", "socket2", "tokio", @@ -918,16 +1185,17 @@ dependencies = [ [[package]] name = "iana-time-zone" -version = "0.1.61" +version = "0.1.62" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "235e081f3925a06703c2d0117ea8b91f042756fd6e7a6e5d901e8ca1a996b220" +checksum = "b2fd658b06e56721792c5df4475705b6cda790e9298d19d2f8af083457bcd127" dependencies = [ "android_system_properties", "core-foundation-sys", "iana-time-zone-haiku", "js-sys", + "log", "wasm-bindgen", - "windows-core", + "windows-core 0.52.0", ] [[package]] @@ -1080,19 +1348,19 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.7.1" +version = "2.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c9c992b02b5b4c94ea26e32fe5bccb7aa7d9f390ab5c1221ff895bc7ea8b652" +checksum = "3954d50fe15b02142bf25d3b8bdadb634ec3948f103d04ffe3031bc8fe9d7058" dependencies = [ "equivalent", - "hashbrown", + "hashbrown 0.15.2", ] [[package]] name = "ipld-core" -version = "0.4.1" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4ede82a79e134f179f4b29b5fdb1eb92bd1b38c4dfea394c539051150a21b9b" +checksum = "104718b1cc124d92a6d01ca9c9258a7df311405debb3408c445a36452f9bf8db" dependencies = [ "cid", "serde", @@ -1111,16 +1379,25 @@ version = "1.70.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" +[[package]] +name = "itertools" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" +dependencies = [ + "either", +] + [[package]] name = "itoa" -version = "1.0.14" +version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d75a2a4b1b190afb6f5425f10f6a8f959d2ea0b9c2b1d79553551850539e4674" +checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" [[package]] name = "jetstream-oxide" -version = "0.1.0" -source = "git+https://github.com/cyypherus/jetstream-oxide?rev=0ced7f9eec58e368f4ef2d7991f68f1753b5fa39#0ced7f9eec58e368f4ef2d7991f68f1753b5fa39" +version = "0.1.2" +source = "git+https://github.com/videah/jetstream-oxide?rev=7f21cfae9d8fe193ceb42fb04e511f45ac23764a#7f21cfae9d8fe193ceb42fb04e511f45ac23764a" dependencies = [ "async-trait", "atrium-api", @@ -1130,7 +1407,7 @@ dependencies = [ "log", "serde", "serde_json", - "thiserror 2.0.11", + "thiserror 2.0.12", "tokio", "tokio-tungstenite 0.24.0", "tokio-util", @@ -1138,6 +1415,30 @@ dependencies = [ "zstd", ] +[[package]] +name = "jiff" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c102670231191d07d37a35af3eb77f1f0dbf7a71be51a962dcd57ea607be7260" +dependencies = [ + "jiff-static", + "log", + "portable-atomic", + "portable-atomic-util", + "serde", +] + +[[package]] +name = "jiff-static" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cdde31a9d349f1b1f51a0b3714a5940ac022976f4b49485fc04be052b183b4c" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "jobserver" version = "0.1.32" @@ -1166,11 +1467,33 @@ dependencies = [ "serde", ] +[[package]] +name = "lazy_static" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" + +[[package]] +name = "lazycell" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" + [[package]] name = "libc" -version = "0.2.169" +version = "0.2.171" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c19937216e9d3aa9956d9bb8dfc0b0c8beb6058fc4f7a4dc4d850edf86a237d6" + +[[package]] +name = "libloading" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5aba8db14291edd000dfcc4d620c7ebfb122c613afb886ca8803fa4e128a20a" +checksum = "fc2f4eb4bc735547cfed7c0a4922cbd04a4655978c09b54f1f7b228750664c34" +dependencies = [ + "cfg-if", + "windows-targets 0.52.6", +] [[package]] name = "libsqlite3-sys" @@ -1189,11 +1512,17 @@ version = "0.4.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab" +[[package]] +name = "linux-raw-sys" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe7db12097d22ec582439daf8618b8fdd1a7bef6270e9af3b1ebcd30893cf413" + [[package]] name = "litemap" -version = "0.7.4" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ee93343901ab17bd981295f2cf0026d4ad018c7c31ba84549a4ddbb47a45104" +checksum = "23fb14cb19457329c82206317a5663005a4d404783dc74f4252769b0d5f42856" [[package]] name = "lock_api" @@ -1207,52 +1536,158 @@ dependencies = [ [[package]] name = "log" -version = "0.4.25" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04cbf5b083de1c7e0222a7a51dbfdba1cbe1c6ab0b15e29fff3f6c077fd9cd9f" - -[[package]] -name = "memchr" -version = "2.7.4" +version = "0.4.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" +checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94" [[package]] -name = "mime" -version = "0.3.17" +name = "loom" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" +checksum = "419e0dc8046cb947daa77eb95ae174acfbddb7673b4151f56d1eed8e93fbfaca" +dependencies = [ + "cfg-if", + "generator", + "scoped-tls", + "tracing", + "tracing-subscriber", +] [[package]] -name = "mime_guess" -version = "2.0.5" +name = "lru" +version = "0.12.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7c44f8e672c00fe5308fa235f821cb4198414e1c77935c1ab6948d3fd78550e" +checksum = "234cf4f4a04dc1f57e24b96cc0cd600cf2af460d4161ac5ecdd0af8e1f3b2a38" dependencies = [ - "mime", - "unicase", + "hashbrown 0.15.2", ] [[package]] -name = "miniz_oxide" -version = "0.8.3" +name = "matchers" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8402cab7aefae129c6977bb0ff1b8fd9a04eb5b51efc50a70bea51cda0c7924" +checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558" dependencies = [ - "adler2", + "regex-automata 0.1.10", ] [[package]] -name = "mio" -version = "1.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" +name = "memchr" +version = "2.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" + +[[package]] +name = "metrics" +version = "0.24.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a7deb012b3b2767169ff203fadb4c6b0b82b947512e5eb9e0b78c2e186ad9e3" +dependencies = [ + "ahash", + "portable-atomic", +] + +[[package]] +name = "metrics-exporter-prometheus" +version = "0.16.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd7399781913e5393588a8d8c6a2867bf85fb38eaf2502fdce465aad2dc6f034" +dependencies = [ + "base64 0.22.1", + "http-body-util", + "hyper 1.6.0", + "hyper-rustls", + "hyper-util", + "indexmap", + "ipnet", + "metrics", + "metrics-util", + "quanta", + "thiserror 1.0.69", + "tokio", + "tracing", +] + +[[package]] +name = "metrics-util" +version = "0.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbd4884b1dd24f7d6628274a2f5ae22465c337c5ba065ec9b6edccddf8acc673" +dependencies = [ + "crossbeam-epoch", + "crossbeam-utils", + "hashbrown 0.15.2", + "metrics", + "quanta", + "rand", + "rand_xoshiro", + "sketches-ddsketch", +] + +[[package]] +name = "mime" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" + +[[package]] +name = "mime_guess" +version = "2.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7c44f8e672c00fe5308fa235f821cb4198414e1c77935c1ab6948d3fd78550e" +dependencies = [ + "mime", + "unicase", +] + +[[package]] +name = "minimal-lexical" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" + +[[package]] +name = "miniz_oxide" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e3e04debbb59698c15bacbb6d93584a8c0ca9cc3213cb423d31f760d8843ce5" +dependencies = [ + "adler2", +] + +[[package]] +name = "mio" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2886843bf800fba2e3377cff24abf6379b4c4d5c6681eaf9ea5b0d15090450bd" dependencies = [ "libc", - "wasi", + "wasi 0.11.0+wasi-snapshot-preview1", "windows-sys 0.52.0", ] +[[package]] +name = "moka" +version = "0.12.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9321642ca94a4282428e6ea4af8cc2ca4eac48ac7a6a4ea8f33f76d0ce70926" +dependencies = [ + "async-lock", + "crossbeam-channel", + "crossbeam-epoch", + "crossbeam-utils", + "event-listener", + "futures-util", + "loom", + "parking_lot", + "portable-atomic", + "rustc_version", + "smallvec", + "tagptr", + "thiserror 1.0.69", + "uuid", +] + [[package]] name = "multer" version = "2.1.0" @@ -1299,14 +1734,14 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6a51313c5820b0b02bd422f4b44776fbf47961755c74ce64afc73bfad10226c3" dependencies = [ - "getrandom", + "getrandom 0.2.15", ] [[package]] name = "native-tls" -version = "0.2.12" +version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8614eb2c83d59d1c8cc974dd3f920198647674a0a035e1af1fa58707e317466" +checksum = "87de3442987e9dbec73158d5c715e7ad9072fda936bb03d19d7fa10e00520f0e" dependencies = [ "libc", "log", @@ -1314,11 +1749,31 @@ dependencies = [ "openssl-probe", "openssl-sys", "schannel", - "security-framework", + "security-framework 2.11.1", "security-framework-sys", "tempfile", ] +[[package]] +name = "nom" +version = "7.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" +dependencies = [ + "memchr", + "minimal-lexical", +] + +[[package]] +name = "nu-ansi-term" +version = "0.46.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84" +dependencies = [ + "overload", + "winapi", +] + [[package]] name = "num-traits" version = "0.2.19" @@ -1339,15 +1794,15 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.20.2" +version = "1.21.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" +checksum = "d75b0bedcc4fe52caa0e03d9f1151a323e4aa5e2d78ba3580400cd3c9e2bc4bc" [[package]] name = "openssl" -version = "0.10.68" +version = "0.10.71" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6174bc48f102d208783c2c84bf931bb75927a617866870de8a4ea85597f871f5" +checksum = "5e14130c6a98cd258fdcb0fb6d744152343ff729cbfcb28c656a9d12b999fbcd" dependencies = [ "bitflags", "cfg-if", @@ -1377,18 +1832,18 @@ checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e" [[package]] name = "openssl-src" -version = "300.4.1+3.4.0" +version = "300.4.2+3.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "faa4eac4138c62414b5622d1b31c5c304f34b406b013c079c2bbc652fdd6678c" +checksum = "168ce4e058f975fe43e89d9ccf78ca668601887ae736090aacc23ae353c298e2" dependencies = [ "cc", ] [[package]] name = "openssl-sys" -version = "0.9.104" +version = "0.9.106" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45abf306cbf99debc8195b66b7346498d7b10c210de50418b5ccd7ceba08c741" +checksum = "8bb61ea9811cc39e3c2069f40b8b8e2e70d8569b361f879786cc7ed48b777cdd" dependencies = [ "cc", "libc", @@ -1397,6 +1852,18 @@ dependencies = [ "vcpkg", ] +[[package]] +name = "overload" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" + +[[package]] +name = "parking" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba" + [[package]] name = "parking_lot" version = "0.12.3" @@ -1417,7 +1884,7 @@ dependencies = [ "libc", "redox_syscall", "smallvec", - "windows-targets", + "windows-targets 0.52.6", ] [[package]] @@ -1428,18 +1895,18 @@ checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" [[package]] name = "pin-project" -version = "1.1.8" +version = "1.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e2ec53ad785f4d35dac0adea7f7dc6f1bb277ad84a680c7afefeae05d1f5916" +checksum = "677f1add503faace112b9f1373e43e9e054bfdd22ff1a63c1bc485eaec6a6a8a" dependencies = [ "pin-project-internal", ] [[package]] name = "pin-project-internal" -version = "1.1.8" +version = "1.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d56a66c0c55993aa927429d0f8a0abfd74f084e4d9c192cffed01e418d83eefb" +checksum = "6e918e4ff8c4549eb882f14b3a4bc8c8bc93de829416eacf579f1207a8fbf861" dependencies = [ "proc-macro2", "quote", @@ -1460,37 +1927,83 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] name = "pkg-config" -version = "0.3.31" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" + +[[package]] +name = "portable-atomic" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "953ec861398dccce10c670dfeaf3ec4911ca479e9c02154b3a215178c5f566f2" +checksum = "350e9b48cbc6b0e028b0473b114454c6316e57336ee184ceab6e53f72c178b3e" + +[[package]] +name = "portable-atomic-util" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8a2f0d8d040d7848a709caf78912debcc3f33ee4b3cac47d73d1e1069e83507" +dependencies = [ + "portable-atomic", +] [[package]] name = "ppv-lite86" -version = "0.2.20" +version = "0.2.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04" +checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9" dependencies = [ - "zerocopy", + "zerocopy 0.8.24", +] + +[[package]] +name = "prettyplease" +version = "0.2.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5316f57387668042f561aae71480de936257848f9c43ce528e311d89a07cadeb" +dependencies = [ + "proc-macro2", + "syn", ] [[package]] name = "proc-macro2" -version = "1.0.93" +version = "1.0.94" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60946a68e5f9d28b0dc1c21bb8a97ee7d018a8b322fa57838ba31cc878e22d99" +checksum = "a31971752e70b8b2686d7e46ec17fb38dad4051d94024c88df49b667caea9c84" dependencies = [ "unicode-ident", ] +[[package]] +name = "quanta" +version = "0.12.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3bd1fe6824cea6538803de3ff1bc0cf3949024db3d43c9643024bfb33a807c0e" +dependencies = [ + "crossbeam-utils", + "libc", + "once_cell", + "raw-cpuid", + "wasi 0.11.0+wasi-snapshot-preview1", + "web-sys", + "winapi", +] + [[package]] name = "quote" -version = "1.0.38" +version = "1.0.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e4dccaaaf89514f546c693ddc140f729f958c247918a13380cccc6078391acc" +checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d" dependencies = [ "proc-macro2", ] +[[package]] +name = "r-efi" +version = "5.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74765f6d916ee2faa39bc8e68e4f3ed8949b48cccdac59983d287a7cb71ce9c5" + [[package]] name = "rand" version = "0.8.5" @@ -1518,14 +2031,32 @@ version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" dependencies = [ - "getrandom", + "getrandom 0.2.15", +] + +[[package]] +name = "rand_xoshiro" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f97cdb2a36ed4183de61b2f824cc45c9f1037f28afe0a322e9fff4c108b5aaa" +dependencies = [ + "rand_core", +] + +[[package]] +name = "raw-cpuid" +version = "11.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6df7ab838ed27997ba19a4664507e6f82b41fe6e20be42929332156e5e85146" +dependencies = [ + "bitflags", ] [[package]] name = "redox_syscall" -version = "0.5.8" +version = "0.5.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03a862b389f93e68874fbf580b9de08dd02facb9a788ebadaf4a3fd33cf58834" +checksum = "0b8c0c260b63a8219631167be35e6a988e9554dbd323f8bd08439c8ed1302bd1" dependencies = [ "bitflags", ] @@ -1538,8 +2069,17 @@ checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" dependencies = [ "aho-corasick", "memchr", - "regex-automata", - "regex-syntax", + "regex-automata 0.4.9", + "regex-syntax 0.8.5", +] + +[[package]] +name = "regex-automata" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" +dependencies = [ + "regex-syntax 0.6.29", ] [[package]] @@ -1550,9 +2090,15 @@ checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908" dependencies = [ "aho-corasick", "memchr", - "regex-syntax", + "regex-syntax 0.8.5", ] +[[package]] +name = "regex-syntax" +version = "0.6.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" + [[package]] name = "regex-syntax" version = "0.8.5" @@ -1561,9 +2107,9 @@ checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" [[package]] name = "reqwest" -version = "0.12.12" +version = "0.12.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43e734407157c3c2034e0258f5e4473ddb361b1e85f95a66690d67264d7cd1da" +checksum = "d19c46a6fdd48bc4dab94b6103fccc55d34c67cc0ad04653aad4ea2a07cd7bbb" dependencies = [ "async-compression", "base64 0.22.1", @@ -1571,11 +2117,11 @@ dependencies = [ "encoding_rs", "futures-core", "futures-util", - "h2 0.4.7", - "http 1.2.0", + "h2 0.4.8", + "http 1.3.1", "http-body 1.0.1", "http-body-util", - "hyper 1.5.2", + "hyper 1.6.0", "hyper-rustls", "hyper-tls", "hyper-util", @@ -1607,15 +2153,14 @@ dependencies = [ [[package]] name = "ring" -version = "0.17.8" +version = "0.17.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c17fa4cb658e3583423e915b9f3acc01cceaee1860e33d59ebae66adc3a2dc0d" +checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7" dependencies = [ "cc", "cfg-if", - "getrandom", + "getrandom 0.2.15", "libc", - "spin", "untrusted", "windows-sys 0.52.0", ] @@ -1640,6 +2185,21 @@ version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" +[[package]] +name = "rustc-hash" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" + +[[package]] +name = "rustc_version" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" +dependencies = [ + "semver", +] + [[package]] name = "rustix" version = "0.38.44" @@ -1649,16 +2209,30 @@ dependencies = [ "bitflags", "errno", "libc", - "linux-raw-sys", + "linux-raw-sys 0.4.15", + "windows-sys 0.59.0", +] + +[[package]] +name = "rustix" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e56a18552996ac8d29ecc3b190b4fdbb2d91ca4ec396de7bbffaf43f3d637e96" +dependencies = [ + "bitflags", + "errno", + "libc", + "linux-raw-sys 0.9.3", "windows-sys 0.59.0", ] [[package]] name = "rustls" -version = "0.23.21" +version = "0.23.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f287924602bf649d949c63dc8ac8b235fa5387d394020705b80c4eb597ce5b8" +checksum = "822ee9188ac4ec04a2f0531e55d035fb2de73f18b41a63c70c2712503b6fb13c" dependencies = [ + "aws-lc-rs", "once_cell", "rustls-pki-types", "rustls-webpki", @@ -1666,6 +2240,18 @@ dependencies = [ "zeroize", ] +[[package]] +name = "rustls-native-certs" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fcff2dd52b58a8d98a70243663a0d234c4e2b79235637849d15913394a247d3" +dependencies = [ + "openssl-probe", + "rustls-pki-types", + "schannel", + "security-framework 3.2.0", +] + [[package]] name = "rustls-pemfile" version = "2.2.0" @@ -1677,16 +2263,17 @@ dependencies = [ [[package]] name = "rustls-pki-types" -version = "1.10.1" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2bf47e6ff922db3825eb750c4e2ff784c6ff8fb9e13046ef6a1d1c5401b0b37" +checksum = "917ce264624a4b4db1c364dcc35bfca9ded014d0a958cd47ad3e960e988ea51c" [[package]] name = "rustls-webpki" -version = "0.102.8" +version = "0.103.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64ca1bc8749bd4cf37b5ce386cc146580777b4e8572c7b97baf22c83f444bee9" +checksum = "0aa4eeac2588ffff23e9d7a7e9b3f971c5fb5b7ebc9452745e0c232c64f83b2f" dependencies = [ + "aws-lc-rs", "ring", "rustls-pki-types", "untrusted", @@ -1694,15 +2281,15 @@ dependencies = [ [[package]] name = "rustversion" -version = "1.0.19" +version = "1.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7c45b9784283f1b2e7fb61b42047c2fd678ef0960d4f6f1eba131594cc369d4" +checksum = "eded382c5f5f786b989652c49544c4877d9f015cc22e145a5ea8ea66c2921cd2" [[package]] name = "ryu" -version = "1.0.18" +version = "1.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" +checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" [[package]] name = "schannel" @@ -1732,7 +2319,20 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" dependencies = [ "bitflags", - "core-foundation", + "core-foundation 0.9.4", + "core-foundation-sys", + "libc", + "security-framework-sys", +] + +[[package]] +name = "security-framework" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "271720403f46ca04f7ba6f55d438f8bd878d6b8ca0a1046e8228c4145bcbb316" +dependencies = [ + "bitflags", + "core-foundation 0.10.0", "core-foundation-sys", "libc", "security-framework-sys", @@ -1748,29 +2348,35 @@ dependencies = [ "libc", ] +[[package]] +name = "semver" +version = "1.0.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56e6fa9c48d24d85fb3de5ad847117517440f6beceb7798af16b4a87d616b8d0" + [[package]] name = "serde" -version = "1.0.217" +version = "1.0.219" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02fc4265df13d6fa1d00ecff087228cc0a2b5f3c0e87e258d8b94a156e984c70" +checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6" dependencies = [ "serde_derive", ] [[package]] name = "serde_bytes" -version = "0.11.15" +version = "0.11.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "387cc504cb06bb40a96c8e04e951fe01854cf6bc921053c954e4a606d9675c6a" +checksum = "8437fd221bde2d4ca316d61b90e337e9e702b3820b87d63caa9ba6c02bd06d96" dependencies = [ "serde", ] [[package]] name = "serde_derive" -version = "1.0.217" +version = "1.0.219" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a9bf7cf98d04a2b28aead066b7496853d4779c9cc183c440dbac457641e19a0" +checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00" dependencies = [ "proc-macro2", "quote", @@ -1792,9 +2398,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.137" +version = "1.0.140" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "930cfb6e6abf99298aaad7d29abbef7a9999a9a8806a40088f55f0dcec03146b" +checksum = "20068b6e96dc6c9bd23e01df8827e6c7e1f2fddd43c21810382803c136b99373" dependencies = [ "itoa", "memchr", @@ -1825,6 +2431,15 @@ dependencies = [ "digest", ] +[[package]] +name = "sharded-slab" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" +dependencies = [ + "lazy_static", +] + [[package]] name = "shlex" version = "1.3.0" @@ -1840,9 +2455,15 @@ dependencies = [ "libc", ] +[[package]] +name = "sketches-ddsketch" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1e9a774a6c28142ac54bb25d25562e6bcf957493a184f15ad4eebccb23e410a" + [[package]] name = "skyfeed" -version = "0.4.0" +version = "0.6.0" dependencies = [ "anyhow", "atrium-api", @@ -1853,11 +2474,14 @@ dependencies = [ "env_logger", "jetstream-oxide", "log", + "regex", "reqwest", + "rusqlite", "serde", "serde_json", "tokio", "warp", + "whatlang", ] [[package]] @@ -1871,9 +2495,9 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.13.2" +version = "1.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" +checksum = "7fcf8323ef1faaee30a44a340193b1ac6814fd9b7b4e88e9d4519a3e4abe1cfd" [[package]] name = "socket2" @@ -1914,9 +2538,9 @@ checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" [[package]] name = "syn" -version = "2.0.96" +version = "2.0.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5d0adab1ae378d7f53bdebc67a39f1f151407ef230f0ce2883572f5d8985c80" +checksum = "b09a44accad81e1ba1cd74a32461ba89dee89095ba17b32f5d03683b1b1fc2a0" dependencies = [ "proc-macro2", "quote", @@ -1950,7 +2574,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3c879d448e9d986b661742763247d3693ed13609438cf3d006f51f5368a5ba6b" dependencies = [ "bitflags", - "core-foundation", + "core-foundation 0.9.4", "system-configuration-sys", ] @@ -1964,17 +2588,22 @@ dependencies = [ "libc", ] +[[package]] +name = "tagptr" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b2093cf4c8eb1e67749a6762251bc9cd836b6fc171623bd0a9d324d37af2417" + [[package]] name = "tempfile" -version = "3.15.0" +version = "3.19.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a8a559c81686f576e8cd0290cd2a24a2a9ad80c98b3478856500fcbd7acd704" +checksum = "7437ac7763b9b123ccf33c338a5cc1bac6f69b45a136c19bdd8a65e3916435bf" dependencies = [ - "cfg-if", "fastrand", - "getrandom", + "getrandom 0.3.2", "once_cell", - "rustix", + "rustix 1.0.3", "windows-sys 0.59.0", ] @@ -1989,11 +2618,11 @@ dependencies = [ [[package]] name = "thiserror" -version = "2.0.11" +version = "2.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d452f284b73e6d76dd36758a0c8684b1d5be31f92b89d07fd5822175732206fc" +checksum = "567b8a2dae586314f7be2a752ec7474332959c6460e02bde30d702a66d488708" dependencies = [ - "thiserror-impl 2.0.11", + "thiserror-impl 2.0.12", ] [[package]] @@ -2009,15 +2638,25 @@ dependencies = [ [[package]] name = "thiserror-impl" -version = "2.0.11" +version = "2.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26afc1baea8a989337eeb52b6e72a039780ce45c3edfcc9c5b9d112feeb173c2" +checksum = "7f7cf42b4507d8ea322120659672cf1b9dbb93f8f2d4ecfd6e51350ff5b17a1d" dependencies = [ "proc-macro2", "quote", "syn", ] +[[package]] +name = "thread_local" +version = "1.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c" +dependencies = [ + "cfg-if", + "once_cell", +] + [[package]] name = "tinystr" version = "0.7.6" @@ -2030,9 +2669,9 @@ dependencies = [ [[package]] name = "tokio" -version = "1.43.0" +version = "1.44.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d61fa4ffa3de412bfea335c6ecff681de2b609ba3c77ef3e00e521813a9ed9e" +checksum = "f382da615b842244d4b8738c82ed1275e6c5dd90c459a30941cd07080b06c91a" dependencies = [ "backtrace", "bytes", @@ -2069,9 +2708,9 @@ dependencies = [ [[package]] name = "tokio-rustls" -version = "0.26.1" +version = "0.26.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f6d0975eaace0cf0fcadee4e4aaa5da15b5c079146f2cffb67c113be122bf37" +checksum = "8e727b36a1a0e8b74c376ac2211e40c2c8af09fb4013c60d910495810f008e9b" dependencies = [ "rustls", "tokio", @@ -2105,9 +2744,9 @@ dependencies = [ [[package]] name = "tokio-util" -version = "0.7.13" +version = "0.7.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7fcaa8d55a2bdd6b83ace262b016eca0d79ee02818c5c1bcdf0305114081078" +checksum = "6b9590b93e6fcc1739458317cccd391ad3955e2bde8913edf6f95f9e65a8f034" dependencies = [ "bytes", "futures-core", @@ -2161,6 +2800,36 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e672c95779cf947c5311f83787af4fa8fffd12fb27e4993211a84bdfd9610f9c" dependencies = [ "once_cell", + "valuable", +] + +[[package]] +name = "tracing-log" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3" +dependencies = [ + "log", + "once_cell", + "tracing-core", +] + +[[package]] +name = "tracing-subscriber" +version = "0.3.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8189decb5ac0fa7bc8b96b7cb9b2701d60d48805aca84a238004d665fcc4008" +dependencies = [ + "matchers", + "nu-ansi-term", + "once_cell", + "regex", + "sharded-slab", + "smallvec", + "thread_local", + "tracing", + "tracing-core", + "tracing-log", ] [[package]] @@ -2189,7 +2858,7 @@ dependencies = [ "byteorder", "bytes", "data-encoding", - "http 1.2.0", + "http 1.3.1", "httparse", "log", "rand", @@ -2208,7 +2877,7 @@ dependencies = [ "byteorder", "bytes", "data-encoding", - "http 1.2.0", + "http 1.3.1", "httparse", "log", "native-tls", @@ -2221,9 +2890,9 @@ dependencies = [ [[package]] name = "typenum" -version = "1.17.0" +version = "1.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" +checksum = "1dccffe3ce07af9386bfd29e80c0ab1a8205a2fc34e4bcd40364df902cfa8f3f" [[package]] name = "unicase" @@ -2233,9 +2902,9 @@ checksum = "75b844d17643ee918803943289730bec8aac480150456169e647ed0b576ba539" [[package]] name = "unicode-ident" -version = "1.0.15" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11cd88e12b17c6494200a9c1b683a04fcac9573ed74cd1b62aeb2727c5592243" +checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" [[package]] name = "unsigned-varint" @@ -2284,6 +2953,21 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" +[[package]] +name = "uuid" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "458f7a779bf54acc9f347480ac654f68407d3aab21269a6e3c9f922acd9e2da9" +dependencies = [ + "getrandom 0.3.2", +] + +[[package]] +name = "valuable" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba73ea9cf16a25df0c8caa16c51acb937d5712a8429db78a3ee29d5dcacd3a65" + [[package]] name = "vcpkg" version = "0.2.15" @@ -2340,6 +3024,15 @@ version = "0.11.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" +[[package]] +name = "wasi" +version = "0.14.2+wasi-0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9683f9a5a998d873c0d21fcbe3c083009670149a8fab228644b8bd36b2c48cb3" +dependencies = [ + "wit-bindgen-rt", +] + [[package]] name = "wasm-bindgen" version = "0.2.100" @@ -2421,24 +3114,129 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "web-time" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a6580f308b1fad9207618087a65c04e7a10bc77e02c8e84e9b00dd4b12fa0bb" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "whatlang" +version = "0.16.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "471d1c1645d361eb782a1650b1786a8fb58dd625e681a04c09f5ff7c8764a7b0" +dependencies = [ + "hashbrown 0.14.5", + "once_cell", +] + +[[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 = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows" +version = "0.58.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd04d41d93c4992d421894c18c8b43496aa748dd4c081bac0dc93eb0489272b6" +dependencies = [ + "windows-core 0.58.0", + "windows-targets 0.52.6", +] + [[package]] name = "windows-core" version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" dependencies = [ - "windows-targets", + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-core" +version = "0.58.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ba6d44ec8c2591c134257ce647b7ea6b20335bf6379a27dac5f1641fcf59f99" +dependencies = [ + "windows-implement", + "windows-interface", + "windows-result 0.2.0", + "windows-strings 0.1.0", + "windows-targets 0.52.6", ] +[[package]] +name = "windows-implement" +version = "0.58.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2bbd5b46c938e506ecbce286b6628a02171d56153ba733b6c741fc627ec9579b" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "windows-interface" +version = "0.58.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "053c4c462dc91d3b1504c6fe5a726dd15e216ba718e84a0e46a88fbe5ded3515" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "windows-link" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76840935b766e1b0a05c0066835fb9ec80071d4c09a16f6bd5f7e655e3c14c38" + [[package]] name = "windows-registry" -version = "0.2.0" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e400001bb720a623c1c69032f8e3e4cf09984deec740f007dd2b03ec864804b0" +checksum = "4286ad90ddb45071efd1a66dfa43eb02dd0dfbae1545ad6cc3c51cf34d7e8ba3" dependencies = [ - "windows-result", - "windows-strings", - "windows-targets", + "windows-result 0.3.2", + "windows-strings 0.3.1", + "windows-targets 0.53.0", ] [[package]] @@ -2447,7 +3245,16 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1d1043d8214f791817bab27572aaa8af63732e11bf84aa21a45a78d6c317ae0e" dependencies = [ - "windows-targets", + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-result" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c64fd11a4fd95df68efcfee5f44a294fe71b8bc6a91993e2791938abcc712252" +dependencies = [ + "windows-link", ] [[package]] @@ -2456,8 +3263,17 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4cd9b125c486025df0eabcb585e62173c6c9eddcec5d117d3b6e8c30e2ee4d10" dependencies = [ - "windows-result", - "windows-targets", + "windows-result 0.2.0", + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-strings" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87fa48cc5d406560701792be122a10132491cff9d0aeb23583cc2dcafc847319" +dependencies = [ + "windows-link", ] [[package]] @@ -2466,7 +3282,7 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ - "windows-targets", + "windows-targets 0.52.6", ] [[package]] @@ -2475,7 +3291,7 @@ version = "0.59.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" dependencies = [ - "windows-targets", + "windows-targets 0.52.6", ] [[package]] @@ -2484,14 +3300,30 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" dependencies = [ - "windows_aarch64_gnullvm", - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_gnullvm", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_gnullvm", - "windows_x86_64_msvc", + "windows_aarch64_gnullvm 0.52.6", + "windows_aarch64_msvc 0.52.6", + "windows_i686_gnu 0.52.6", + "windows_i686_gnullvm 0.52.6", + "windows_i686_msvc 0.52.6", + "windows_x86_64_gnu 0.52.6", + "windows_x86_64_gnullvm 0.52.6", + "windows_x86_64_msvc 0.52.6", +] + +[[package]] +name = "windows-targets" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1e4c7e8ceaaf9cb7d7507c974735728ab453b67ef8f18febdd7c11fe59dca8b" +dependencies = [ + "windows_aarch64_gnullvm 0.53.0", + "windows_aarch64_msvc 0.53.0", + "windows_i686_gnu 0.53.0", + "windows_i686_gnullvm 0.53.0", + "windows_i686_msvc 0.53.0", + "windows_x86_64_gnu 0.53.0", + "windows_x86_64_gnullvm 0.53.0", + "windows_x86_64_msvc 0.53.0", ] [[package]] @@ -2500,48 +3332,105 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86b8d5f90ddd19cb4a147a5fa63ca848db3df085e25fee3cc10b39b6eebae764" + [[package]] name = "windows_aarch64_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" +[[package]] +name = "windows_aarch64_msvc" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7651a1f62a11b8cbd5e0d42526e55f2c99886c77e007179efff86c2b137e66c" + [[package]] name = "windows_i686_gnu" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" +[[package]] +name = "windows_i686_gnu" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1dc67659d35f387f5f6c479dc4e28f1d4bb90ddd1a5d3da2e5d97b42d6272c3" + [[package]] name = "windows_i686_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" +[[package]] +name = "windows_i686_gnullvm" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ce6ccbdedbf6d6354471319e781c0dfef054c81fbc7cf83f338a4296c0cae11" + [[package]] name = "windows_i686_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" +[[package]] +name = "windows_i686_msvc" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "581fee95406bb13382d2f65cd4a908ca7b1e4c2f1917f143ba16efe98a589b5d" + [[package]] name = "windows_x86_64_gnu" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" +[[package]] +name = "windows_x86_64_gnu" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e55b5ac9ea33f2fc1716d1742db15574fd6fc8dadc51caab1c16a3d3b4190ba" + [[package]] name = "windows_x86_64_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a6e035dd0599267ce1ee132e51c27dd29437f63325753051e71dd9e42406c57" + [[package]] name = "windows_x86_64_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" +[[package]] +name = "windows_x86_64_msvc" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486" + +[[package]] +name = "wit-bindgen-rt" +version = "0.39.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1" +dependencies = [ + "bitflags", +] + [[package]] name = "write16" version = "1.0.0" @@ -2584,8 +3473,16 @@ version = "0.7.35" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" dependencies = [ - "byteorder", - "zerocopy-derive", + "zerocopy-derive 0.7.35", +] + +[[package]] +name = "zerocopy" +version = "0.8.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2586fea28e186957ef732a5f8b3be2da217d65c5969d4b1e17f973ebbe876879" +dependencies = [ + "zerocopy-derive 0.8.24", ] [[package]] @@ -2599,20 +3496,31 @@ dependencies = [ "syn", ] +[[package]] +name = "zerocopy-derive" +version = "0.8.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a996a8f63c5c4448cd959ac1bab0aaa3306ccfd060472f85943ee0750f0169be" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "zerofrom" -version = "0.1.5" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cff3ee08c995dee1859d998dea82f7374f2826091dd9cd47def953cae446cd2e" +checksum = "50cc42e0333e05660c3587f3bf9d0478688e15d870fab3346451ce7f8c9fbea5" dependencies = [ "zerofrom-derive", ] [[package]] name = "zerofrom-derive" -version = "0.1.5" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "595eed982f7d355beb85837f651fa22e90b3c044842dc7f2c2842c086f295808" +checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502" dependencies = [ "proc-macro2", "quote", @@ -2650,27 +3558,27 @@ dependencies = [ [[package]] name = "zstd" -version = "0.13.2" +version = "0.13.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcf2b778a664581e31e389454a7072dab1647606d44f7feea22cd5abb9c9f3f9" +checksum = "e91ee311a569c327171651566e07972200e76fcfe2242a4fa446149a3881c08a" dependencies = [ "zstd-safe", ] [[package]] name = "zstd-safe" -version = "7.2.1" +version = "7.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54a3ab4db68cea366acc5c897c7b4d4d1b8994a9cd6e6f841f8964566a419059" +checksum = "8f49c4d5f0abb602a93fb8736af2a4f4dd9512e36f7f570d66e65ff867ed3b9d" dependencies = [ "zstd-sys", ] [[package]] name = "zstd-sys" -version = "2.0.13+zstd.1.5.6" +version = "2.0.15+zstd.1.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38ff0f21cfee8f97d94cef41359e0c89aa6113028ab0291aa8ca0038995a95aa" +checksum = "eb81183ddd97d0c74cedf1d50d85c8d08c1b8b68ee863bdee9e706eedba1a237" dependencies = [ "cc", "pkg-config", diff --git a/examples/sqlite/Cargo.toml b/examples/sqlite/Cargo.toml index 5915a87..108f86f 100644 --- a/examples/sqlite/Cargo.toml +++ b/examples/sqlite/Cargo.toml @@ -10,3 +10,6 @@ tokio = { version = "1.43.0", features = ["full", "time"] } rusqlite = { version = "0.33.0", features = ["bundled"] } chrono = "0.4.39" regex = "1.11.1" +whatlang = "0.16.4" +metrics = "0.24.1" +metrics-exporter-prometheus = "0.16.2" diff --git a/examples/sqlite/src/main.rs b/examples/sqlite/src/main.rs index 023dc6b..4cdeaf9 100644 --- a/examples/sqlite/src/main.rs +++ b/examples/sqlite/src/main.rs @@ -1,4 +1,6 @@ -use log::info; +use log::{info, trace}; +use metrics::counter; +use metrics_exporter_prometheus::PrometheusBuilder; use rusqlite::{params, Connection}; use skyfeed::{Feed, FeedHandler, FeedResult, Post, Request, Uri}; use std::{sync::Arc, time::Duration}; @@ -9,6 +11,12 @@ async fn main() { let db = Connection::open("feed.db").expect("Failed to open database"); initialize_db(&db); + let builder = PrometheusBuilder::new(); + + builder + .install() + .expect("failed to install recorder/exporter"); + let db = Arc::new(Mutex::new(db)); let mut feed = MyFeed { @@ -23,7 +31,7 @@ async fn main() { } }); - tokio::join!(feed.start("Cats", ([0, 0, 0, 0], 3030)), cleanup_task) + tokio::join!(feed.start("fr", ([0, 0, 0, 0], 3030)), cleanup_task) .1 .expect("Starting tasks failed"); } @@ -45,22 +53,25 @@ struct MyFeedHandler { impl FeedHandler for MyFeedHandler { async fn insert_post(&mut self, post: Post) { - let cat_regex = - regex::RegexBuilder::new("\\b(cats?|kitty|kitties|kittens?|feline|catsofbluesky)\\b") - .case_insensitive(true) - .build() - .unwrap(); - let unwanted_regex = - regex::RegexBuilder::new("\\b(trump|kamala|harris|biden|democrats?|democratic|republicans?|politics|dems?|aoc|GOP|vance|musk|elon|walz|fascists?|furryart|smut|furries|dnc|RFK)\\b|(right wing|left wing)") + regex::RegexBuilder::new(r"\\b(macron|le[- ]?pen|mélenchon|fillon|sarkozy|LREM|RN|gilets\s+jaunes|politique|trudeau|libéraux?|conservateurs?|bloc(?:\s+québécois)?|n(?:ouveau\s+)?parti(?:\s+démocratique)?|constitution(?:nel(?:le)?)?|scandale|gouvernement)\b|(extrême\s+(?:droite|gauche))") .case_insensitive(true) .build() .unwrap(); - if cat_regex.is_match(post.text.as_str()) + let detected_language = whatlang::detect_lang(&post.text); + + let counter = counter!("posts_received"); + counter.increment(1); + + if post.langs.iter().any(|lang| lang.contains("fr")) + && detected_language == Some(whatlang::Lang::Fra) && !unwanted_regex.is_match(post.text.as_str()) && post.labels.is_empty() { + let counter = counter!("posts_stored"); + counter.increment(1); + info!("Storing {post:?}"); let db = self.db.lock().await; @@ -73,15 +84,19 @@ impl FeedHandler for MyFeedHandler { } async fn delete_post(&mut self, uri: Uri) { + let counter = counter!("posts_deleted"); + counter.increment(1); let db = self.db.lock().await; db.execute("DELETE FROM posts WHERE uri = ?1", params![uri.0]) .expect("Failed to delete post"); } async fn like_post(&mut self, like_uri: Uri, liked_post_uri: Uri) { + let counter = counter!("likes_created"); + counter.increment(1); let db = self.db.lock().await; db.execute( - "INSERT INTO likes (post_uri, like_uri) + "INSERT OR REPLACE INTO likes (post_uri, like_uri) SELECT ?1, ?2 WHERE EXISTS (SELECT 1 FROM posts WHERE uri = ?1)", params![liked_post_uri.0, like_uri.0], @@ -90,6 +105,8 @@ impl FeedHandler for MyFeedHandler { } async fn delete_like(&mut self, like_uri: Uri) { + let counter = counter!("likes_deleted"); + counter.increment(1); let db = self.db.lock().await; db.execute("DELETE FROM likes WHERE like_uri = ?1", params![like_uri.0]) .expect("Failed to delete like"); @@ -98,32 +115,38 @@ impl FeedHandler for MyFeedHandler { async fn serve_feed(&self, request: Request) -> FeedResult { info!("Serving {request:?}"); + let counter = counter!("feed_requests"); + counter.increment(1); + let db = self.db.lock().await; let mut stmt = db .prepare( " WITH ranked_posts AS ( - SELECT - uri, - timestamp, - COUNT(like_uri) AS likes - FROM posts - LEFT JOIN likes ON posts.uri = likes.post_uri - GROUP BY posts.uri - HAVING COUNT(like_uri) > 0 + SELECT + posts.uri, + posts.timestamp, + COUNT(likes.like_uri) AS likes + FROM posts + LEFT JOIN likes ON posts.uri = likes.post_uri + GROUP BY posts.uri + HAVING COUNT(likes.like_uri) > 0 ), sorted_posts AS ( - SELECT - uri, - timestamp, - likes, - PERCENT_RANK() OVER (ORDER BY likes DESC) AS rank - FROM ranked_posts + SELECT + uri, + timestamp, + likes, + PERCENT_RANK() OVER (ORDER BY likes DESC) AS rank + FROM ranked_posts ) SELECT uri, likes FROM sorted_posts - WHERE rank <= 0.05 - ORDER BY timestamp DESC; + ORDER BY + CASE WHEN rank <= 0.05 THEN 0 ELSE 1 END, + likes DESC, + timestamp DESC + LIMIT 20; ", ) .expect("Failed to prepare statement"); @@ -183,7 +206,10 @@ async fn cleanup_posts(db: &Arc>) { ) .expect("Failed to clean up old posts"); - info!("Cleaned up {cleaned_posts} posts"); + let counter = counter!("cleaned_posts"); + counter.increment(cleaned_posts as u64); + + trace!("Cleaned up {cleaned_posts} posts"); } fn initialize_db(db: &Connection) { diff --git a/src/bin/my_did.rs b/src/bin/my_did.rs index df58551..eadf7d9 100644 --- a/src/bin/my_did.rs +++ b/src/bin/my_did.rs @@ -1,6 +1,6 @@ use anyhow::Result; use atrium_api::{ - agent::{store::MemorySessionStore, AtpAgent}, + agent::atp_agent::{store::MemorySessionStore, AtpAgent}, types::string::Handle, }; use clap::Parser; diff --git a/src/bin/publish.rs b/src/bin/publish.rs index ce145e8..9d107d0 100644 --- a/src/bin/publish.rs +++ b/src/bin/publish.rs @@ -1,6 +1,6 @@ use atrium_api::com::atproto::repo::put_record::InputData; use atrium_api::{ - agent::{store::MemorySessionStore, AtpAgent}, + agent::atp_agent::{store::MemorySessionStore, AtpAgent}, app::bsky::feed::generator::RecordData, types::{ string::{Datetime, Did, Handle, Nsid}, diff --git a/src/bin/unpublish.rs b/src/bin/unpublish.rs index 354331d..86d4b20 100644 --- a/src/bin/unpublish.rs +++ b/src/bin/unpublish.rs @@ -1,6 +1,6 @@ use anyhow::Result; use atrium_api::{ - agent::{store::MemorySessionStore, AtpAgent}, + agent::atp_agent::{store::MemorySessionStore, AtpAgent}, types::string::{Handle, Nsid}, }; use clap::Parser; diff --git a/src/feed.rs b/src/feed.rs index b460868..efc9f51 100644 --- a/src/feed.rs +++ b/src/feed.rs @@ -130,7 +130,11 @@ pub trait Feed { }) .unwrap(); let receiver = jetstream.connect().await.unwrap(); - while let Ok(event) = receiver.recv_async().await { + while let Ok(event) = receiver + .recv_async() + .await + .inspect_err(|e| error!("Jetstream error: {}", e)) + { if let Commit(commit) = event { #[allow(clippy::collapsible_match)] match commit { From 779a92920a61efaf9c9e97c510d0d11ea3fb7d99 Mon Sep 17 00:00:00 2001 From: ejjonny Date: Sat, 29 Mar 2025 15:32:38 -0600 Subject: [PATCH 02/53] fix feed req, sort desc & fix pagination --- examples/sqlite/src/main.rs | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/examples/sqlite/src/main.rs b/examples/sqlite/src/main.rs index 4cdeaf9..7cf04bd 100644 --- a/examples/sqlite/src/main.rs +++ b/examples/sqlite/src/main.rs @@ -142,11 +142,8 @@ impl FeedHandler for MyFeedHandler { ) SELECT uri, likes FROM sorted_posts - ORDER BY - CASE WHEN rank <= 0.05 THEN 0 ELSE 1 END, - likes DESC, - timestamp DESC - LIMIT 20; + WHERE rank <= 0.05 + ORDER BY timestamp DESC; ", ) .expect("Failed to prepare statement"); From 19ae7bc26f1f5a7345715fe959247a152ef45768 Mon Sep 17 00:00:00 2001 From: cyypherus Date: Fri, 24 Oct 2025 19:04:23 -0600 Subject: [PATCH 03/53] remove metrics --- examples/sqlite/src/main.rs | 26 -------------------------- 1 file changed, 26 deletions(-) diff --git a/examples/sqlite/src/main.rs b/examples/sqlite/src/main.rs index 7cf04bd..588b502 100644 --- a/examples/sqlite/src/main.rs +++ b/examples/sqlite/src/main.rs @@ -1,6 +1,4 @@ use log::{info, trace}; -use metrics::counter; -use metrics_exporter_prometheus::PrometheusBuilder; use rusqlite::{params, Connection}; use skyfeed::{Feed, FeedHandler, FeedResult, Post, Request, Uri}; use std::{sync::Arc, time::Duration}; @@ -11,12 +9,6 @@ async fn main() { let db = Connection::open("feed.db").expect("Failed to open database"); initialize_db(&db); - let builder = PrometheusBuilder::new(); - - builder - .install() - .expect("failed to install recorder/exporter"); - let db = Arc::new(Mutex::new(db)); let mut feed = MyFeed { @@ -61,17 +53,11 @@ impl FeedHandler for MyFeedHandler { let detected_language = whatlang::detect_lang(&post.text); - let counter = counter!("posts_received"); - counter.increment(1); - if post.langs.iter().any(|lang| lang.contains("fr")) && detected_language == Some(whatlang::Lang::Fra) && !unwanted_regex.is_match(post.text.as_str()) && post.labels.is_empty() { - let counter = counter!("posts_stored"); - counter.increment(1); - info!("Storing {post:?}"); let db = self.db.lock().await; @@ -84,16 +70,12 @@ impl FeedHandler for MyFeedHandler { } async fn delete_post(&mut self, uri: Uri) { - let counter = counter!("posts_deleted"); - counter.increment(1); let db = self.db.lock().await; db.execute("DELETE FROM posts WHERE uri = ?1", params![uri.0]) .expect("Failed to delete post"); } async fn like_post(&mut self, like_uri: Uri, liked_post_uri: Uri) { - let counter = counter!("likes_created"); - counter.increment(1); let db = self.db.lock().await; db.execute( "INSERT OR REPLACE INTO likes (post_uri, like_uri) @@ -105,8 +87,6 @@ impl FeedHandler for MyFeedHandler { } async fn delete_like(&mut self, like_uri: Uri) { - let counter = counter!("likes_deleted"); - counter.increment(1); let db = self.db.lock().await; db.execute("DELETE FROM likes WHERE like_uri = ?1", params![like_uri.0]) .expect("Failed to delete like"); @@ -115,9 +95,6 @@ impl FeedHandler for MyFeedHandler { async fn serve_feed(&self, request: Request) -> FeedResult { info!("Serving {request:?}"); - let counter = counter!("feed_requests"); - counter.increment(1); - let db = self.db.lock().await; let mut stmt = db .prepare( @@ -203,9 +180,6 @@ async fn cleanup_posts(db: &Arc>) { ) .expect("Failed to clean up old posts"); - let counter = counter!("cleaned_posts"); - counter.increment(cleaned_posts as u64); - trace!("Cleaned up {cleaned_posts} posts"); } From 2e09079f040746eb3ddafa0670b8a04c6172e870 Mon Sep 17 00:00:00 2001 From: cyypherus Date: Fri, 24 Oct 2025 20:24:07 -0600 Subject: [PATCH 04/53] how is this breaking? --- Cargo.lock | 12 +- Cargo.toml | 2 +- examples/sqlite/Cargo.lock | 1469 +++++++++++++++++------------------- examples/sqlite/Cargo.toml | 3 +- src/bin/publish.rs | 3 +- src/bin/unpublish.rs | 4 +- src/feed.rs | 1 + 7 files changed, 689 insertions(+), 805 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 98b04c7..b6a5a27 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -158,9 +158,9 @@ checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" [[package]] name = "atrium-api" -version = "0.25.0" +version = "0.25.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea3ea578c768ec91082e424a8d139517b2cb5c75149bf3cec04371a1e74f00f2" +checksum = "ef9d5e9352fd27d99383ae1db2b6a6aa239e683a7e750e8d73a73996d82b1fd2" dependencies = [ "atrium-common", "atrium-xrpc", @@ -179,9 +179,9 @@ dependencies = [ [[package]] name = "atrium-common" -version = "0.1.0" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "168e558408847bfed69df1033a32fd051f7a037ebc90ea46e588ccb2bfbd7233" +checksum = "9ed5610654043faa396a5a15afac0ac646d76aebe45aebd7cef4f8b96b0ab7f4" dependencies = [ "dashmap", "lru", @@ -194,9 +194,9 @@ dependencies = [ [[package]] name = "atrium-xrpc" -version = "0.12.1" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b4956d94147cfbb669c68f654eb4fd6a1d00648c810cec79d04ec5425b8f378" +checksum = "0216ad50ce34e9ff982e171c3659e65dedaa2ed5ac2994524debdc9a9647ffa8" dependencies = [ "http 1.3.1", "serde", diff --git a/Cargo.toml b/Cargo.toml index 648ece0..cfb7fcb 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -38,7 +38,7 @@ path = "examples/sqlite/src/main.rs" required-features = ["examples"] [dependencies] -atrium-api = "0.25.0" +atrium-api = "0.25.6" dotenv = "0.15.0" env_logger = "0.11.5" jetstream-oxide = { git = "https://github.com/videah/jetstream-oxide", rev = "7f21cfae9d8fe193ceb42fb04e511f45ac23764a" } diff --git a/examples/sqlite/Cargo.lock b/examples/sqlite/Cargo.lock index 0b0edca..9da8d15 100644 --- a/examples/sqlite/Cargo.lock +++ b/examples/sqlite/Cargo.lock @@ -2,31 +2,22 @@ # It is not intended for manual editing. version = 4 -[[package]] -name = "addr2line" -version = "0.24.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1" -dependencies = [ - "gimli", -] - [[package]] name = "adler2" -version = "2.0.0" +version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" +checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" [[package]] name = "ahash" -version = "0.8.11" +version = "0.8.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" +checksum = "5a15f179cd60c4584b8a8c596927aadc462e27f2ca70c04e0071964a73ba7a75" dependencies = [ "cfg-if", "once_cell", "version_check", - "zerocopy 0.7.35", + "zerocopy", ] [[package]] @@ -44,12 +35,6 @@ version = "0.2.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" -[[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" @@ -61,9 +46,9 @@ dependencies = [ [[package]] name = "anstream" -version = "0.6.18" +version = "0.6.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8acc5369981196006228e28809f761875c0327210a891e941f4c683b3a99529b" +checksum = "43d5b281e737544384e969a5ccad3f1cdd24b48086a0fc1b2a5262a26b8f4f4a" dependencies = [ "anstyle", "anstyle-parse", @@ -76,63 +61,63 @@ dependencies = [ [[package]] name = "anstyle" -version = "1.0.10" +version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55cc3b69f167a1ef2e161439aa98aed94e6028e5f9a59be9a6ffb47aef1651f9" +checksum = "5192cca8006f1fd4f7237516f40fa183bb07f8fbdfedaa0036de5ea9b0b45e78" [[package]] name = "anstyle-parse" -version = "0.2.6" +version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b2d16507662817a6a20a9ea92df6652ee4f94f914589377d69f3b21bc5798a9" +checksum = "4e7644824f0aa2c7b9384579234ef10eb7efb6a0deb83f9630a49594dd9c15c2" dependencies = [ "utf8parse", ] [[package]] name = "anstyle-query" -version = "1.1.2" +version = "1.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79947af37f4177cfead1110013d678905c37501914fba0efea834c3fe9a8d60c" +checksum = "9e231f6134f61b71076a3eab506c379d4f36122f2af15a9ff04415ea4c3339e2" dependencies = [ - "windows-sys 0.59.0", + "windows-sys 0.60.2", ] [[package]] name = "anstyle-wincon" -version = "3.0.7" +version = "3.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca3534e77181a9cc07539ad51f2141fe32f6c3ffd4df76db8ad92346b003ae4e" +checksum = "3e0633414522a32ffaac8ac6cc8f748e090c5717661fddeea04219e2344f5f2a" dependencies = [ "anstyle", - "once_cell", - "windows-sys 0.59.0", + "once_cell_polyfill", + "windows-sys 0.60.2", ] [[package]] name = "anyhow" -version = "1.0.97" +version = "1.0.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcfed56ad506cb2c684a14971b8861fdc3baaaae314b9e5f9bb532cbe3ba7a4f" +checksum = "a23eb6b1614318a8071c9b2521f36b424b2c83db5eb3a0fead4a6c0809af6e61" [[package]] name = "async-compression" -version = "0.4.21" +version = "0.4.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0cf008e5e1a9e9e22a7d3c9a4992e21a350290069e36d8fb72304ed17e8f2d2" +checksum = "5a89bce6054c720275ac2432fbba080a66a2106a44a1b804553930ca6909f4e0" dependencies = [ - "flate2", + "compression-codecs", + "compression-core", "futures-core", - "memchr", "pin-project-lite", "tokio", ] [[package]] name = "async-lock" -version = "3.4.0" +version = "3.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff6e472cdea888a4bd64f342f09b3f50e1886d32afe8df3d663c01140b811b18" +checksum = "5fd03604047cee9b6ce9de9f70c6cd540a0520c813cbd49bae61f33ab80ed1dc" dependencies = [ "event-listener", "event-listener-strategy", @@ -141,13 +126,13 @@ dependencies = [ [[package]] name = "async-trait" -version = "0.1.88" +version = "0.1.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e539d3fca749fcee5236ab05e93a52867dd549cc157c8cb7f99595f3cedffdb5" +checksum = "9035ad2d096bed7955a320ee7e2230574d28fd3c3a0f186cbea1ff3c7eed5dbb" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.108", ] [[package]] @@ -158,9 +143,9 @@ checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" [[package]] name = "atrium-api" -version = "0.25.0" +version = "0.25.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea3ea578c768ec91082e424a8d139517b2cb5c75149bf3cec04371a1e74f00f2" +checksum = "ef9d5e9352fd27d99383ae1db2b6a6aa239e683a7e750e8d73a73996d82b1fd2" dependencies = [ "atrium-common", "atrium-xrpc", @@ -179,9 +164,9 @@ dependencies = [ [[package]] name = "atrium-common" -version = "0.1.0" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "168e558408847bfed69df1033a32fd051f7a037ebc90ea46e588ccb2bfbd7233" +checksum = "9ed5610654043faa396a5a15afac0ac646d76aebe45aebd7cef4f8b96b0ab7f4" dependencies = [ "dashmap", "lru", @@ -194,9 +179,9 @@ dependencies = [ [[package]] name = "atrium-xrpc" -version = "0.12.1" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b4956d94147cfbb669c68f654eb4fd6a1d00648c810cec79d04ec5425b8f378" +checksum = "0216ad50ce34e9ff982e171c3659e65dedaa2ed5ac2994524debdc9a9647ffa8" dependencies = [ "http 1.3.1", "serde", @@ -208,9 +193,9 @@ dependencies = [ [[package]] name = "atrium-xrpc-client" -version = "0.5.11" +version = "0.5.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9bab4287ccef501b3892e1325280e61ae79a96eb9ee63dceabc0ed3bea35f2eb" +checksum = "e099e5171f79faef52364ef0657a4cab086a71b384a779a29597a91b780de0d5" dependencies = [ "atrium-xrpc", "reqwest", @@ -218,15 +203,15 @@ dependencies = [ [[package]] name = "autocfg" -version = "1.4.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" +checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" [[package]] name = "aws-lc-rs" -version = "1.12.6" +version = "1.14.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dabb68eb3a7aa08b46fddfd59a3d55c978243557a90ab804769f7e20e67d2b01" +checksum = "879b6c89592deb404ba4dc0ae6b58ffd1795c78991cbb5b8bc441c48a070440d" dependencies = [ "aws-lc-sys", "zeroize", @@ -234,9 +219,9 @@ dependencies = [ [[package]] name = "aws-lc-sys" -version = "0.27.1" +version = "0.32.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77926887776171ced7d662120a75998e444d3750c951abfe07f90da130514b1f" +checksum = "107a4e9d9cab9963e04e84bb8dee0e25f2a987f9a8bad5ed054abd439caa8f8c" dependencies = [ "bindgen", "cc", @@ -245,27 +230,22 @@ dependencies = [ "fs_extra", ] -[[package]] -name = "backtrace" -version = "0.3.74" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d82cb332cdfaed17ae235a638438ac4d4839913cc2af585c3c6746e8f8bee1a" -dependencies = [ - "addr2line", - "cfg-if", - "libc", - "miniz_oxide", - "object", - "rustc-demangle", - "windows-targets 0.52.6", -] - [[package]] name = "base-x" version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4cbbc9d0964165b47557570cce6c952866c2678457aca742aafc9fb771d30270" +[[package]] +name = "base256emoji" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5e9430d9a245a77c92176e649af6e275f20839a48389859d1661e9a128d077c" +dependencies = [ + "const-str", + "match-lookup", +] + [[package]] name = "base64" version = "0.21.7" @@ -295,16 +275,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", "cexpr", "clang-sys", "itertools", - "lazy_static", - "lazycell", "log", "prettyplease", "proc-macro2", @@ -312,15 +290,14 @@ dependencies = [ "regex", "rustc-hash", "shlex", - "syn", - "which", + "syn 2.0.108", ] [[package]] name = "bitflags" -version = "2.9.0" +version = "2.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c8214115b7bf84099f1309324e63141d4c5d7cc26862f97a0a857dbefe165bd" +checksum = "812e12b5285cc515a9c72a5c1d3b6d46a19dac5acfef5265968c166106e31dd3" [[package]] name = "block-buffer" @@ -333,9 +310,9 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.17.0" +version = "3.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1628fb46dfa0b37568d12e5edd512553eccf6a22a78e8bde00bb4aed84d5bdbf" +checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43" [[package]] name = "byteorder" @@ -351,10 +328,11 @@ checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a" [[package]] name = "cc" -version = "1.2.17" +version = "1.2.43" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fcb57c740ae1daf453ae85f16e37396f672b039e00d9d866e07ddb24e328e3a" +checksum = "739eb0f94557554b3ca9a86d2d37bebd49c5e6d0c1d2bda35ba5bdac830befc2" dependencies = [ + "find-msvc-tools", "jobserver", "libc", "shlex", @@ -371,23 +349,22 @@ dependencies = [ [[package]] name = "cfg-if" -version = "1.0.0" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" [[package]] name = "chrono" -version = "0.4.40" +version = "0.4.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a7964611d71df112cb1730f2ee67324fcf4d0fc6606acbbe9bfe06df124637c" +checksum = "145052bdd345b87320e369255277e3fb5152762ad123a901ef5c262dd38fe8d2" dependencies = [ - "android-tzdata", "iana-time-zone", "js-sys", "num-traits", "serde", "wasm-bindgen", - "windows-link", + "windows-link 0.2.1", ] [[package]] @@ -417,9 +394,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.32" +version = "4.5.50" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6088f3ae8c3608d19260cd7445411865a485688711b78b5be70d78cd96136f83" +checksum = "0c2cfd7bf8a6017ddaa4e32ffe7403d547790db06bd171c1c53926faab501623" dependencies = [ "clap_builder", "clap_derive", @@ -427,9 +404,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.32" +version = "4.5.50" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22a7ef7f676155edfb82daa97f99441f3ebf4a58d5e32f295a56259f1b6facc8" +checksum = "0a4c05b9e80c5ccd3a7ef080ad7b6ba7d6fc00a985b8b157197075677c82c7a0" dependencies = [ "anstream", "anstyle", @@ -439,21 +416,21 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.5.32" +version = "4.5.49" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09176aae279615badda0765c0c0b3f6ed53f4709118af73cf4655d85d1530cd7" +checksum = "2a0b5487afeab2deb2ff4e03a807ad1a03ac532ff5a2cee5d86884440c7f7671" dependencies = [ "heck", "proc-macro2", "quote", - "syn", + "syn 2.0.108", ] [[package]] name = "clap_lex" -version = "0.7.4" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f46ad14479a25103f283c0f10005961cf086d8dc42205bb44c46ac563475dca6" +checksum = "a1d728cc89cf3aee9ff92b05e62b19ee65a02b5702cff7d5a377e32c6ae29d8d" [[package]] name = "cmake" @@ -466,9 +443,26 @@ dependencies = [ [[package]] name = "colorchoice" -version = "1.0.3" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990" +checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75" + +[[package]] +name = "compression-codecs" +version = "0.4.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef8a506ec4b81c460798f572caead636d57d3d7e940f998160f52bd254bf2d23" +dependencies = [ + "compression-core", + "flate2", + "memchr", +] + +[[package]] +name = "compression-core" +version = "0.4.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e47641d3deaf41fb1538ac1f54735925e275eaf3bf4d55c81b137fba797e5cbb" [[package]] name = "concurrent-queue" @@ -479,6 +473,12 @@ dependencies = [ "crossbeam-utils", ] +[[package]] +name = "const-str" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f421161cb492475f1661ddc9815a745a1c894592070661180fdec3d4872e9c3" + [[package]] name = "core-foundation" version = "0.9.4" @@ -491,9 +491,9 @@ dependencies = [ [[package]] name = "core-foundation" -version = "0.10.0" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b55271e5c8c478ad3f38ad24ef34923091e0548492a266d19b3c0b4d82574c63" +checksum = "b2a6cd9ae233e7f62ba4e9353e81a88df7fc8a5987b8d445b4d90c879bd156f6" dependencies = [ "core-foundation-sys", "libc", @@ -525,18 +525,18 @@ dependencies = [ [[package]] name = "crc32fast" -version = "1.4.2" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3" +checksum = "9481c1c90cbf2ac953f07c8d4a58aa3945c425b7185c9154d67a65e4230da511" dependencies = [ "cfg-if", ] [[package]] name = "crossbeam-channel" -version = "0.5.14" +version = "0.5.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06ba6d68e24814cb8de6bb986db8222d3a027d15872cabc0d18817bc3c0e4471" +checksum = "82b8f8f868b36967f9606790d1903570de9ceaf870a7bf9fbbd3016d636a2cb2" dependencies = [ "crossbeam-utils", ] @@ -582,15 +582,15 @@ dependencies = [ [[package]] name = "data-encoding" -version = "2.8.0" +version = "2.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "575f75dfd25738df5b91b8e43e14d44bda14637a58fae779fd2b064f8bf3e010" +checksum = "2a2330da5de22e8a3cb63252ce2abb30116bf5265e89c0e01bc17015ce30a476" [[package]] name = "data-encoding-macro" -version = "0.1.17" +version = "0.1.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f9724adfcf41f45bf652b3995837669d73c4d49a1b5ac1ff82905ac7d9b5558" +checksum = "47ce6c96ea0102f01122a185683611bd5ac8d99e62bc59dd12e6bda344ee673d" dependencies = [ "data-encoding", "data-encoding-macro-internal", @@ -598,12 +598,12 @@ dependencies = [ [[package]] name = "data-encoding-macro-internal" -version = "0.1.15" +version = "0.1.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18e4fdb82bd54a12e42fb58a800dcae6b9e13982238ce2296dc3570b92148e1f" +checksum = "8d162beedaa69905488a8da94f5ac3edb4dd4788b732fadb7bd120b2625c1976" dependencies = [ "data-encoding", - "syn", + "syn 2.0.108", ] [[package]] @@ -624,7 +624,7 @@ checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.108", ] [[package]] @@ -656,9 +656,9 @@ dependencies = [ [[package]] name = "env_filter" -version = "0.1.3" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "186e05a59d4c50738528153b83b0b0194d3a29507dfec16eccd4b342903397d0" +checksum = "1bf3c259d255ca70051b30e2e95b5446cdb8949ac4cd22c0d7fd634d89f568e2" dependencies = [ "log", "regex", @@ -666,9 +666,9 @@ dependencies = [ [[package]] name = "env_logger" -version = "0.11.7" +version = "0.11.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3716d7a920fb4fac5d84e9d4bce8ceb321e9414b4409da61b07b75c1e3d0697" +checksum = "13c863f0904021b108aa8b2f55046443e6b1ebde8fd4a15c399893aae4fa069f" dependencies = [ "anstream", "anstyle", @@ -685,19 +685,19 @@ checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" [[package]] name = "errno" -version = "0.3.10" +version = "0.3.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33d852cb9b869c2a9b3df2f71a3074817f01e1844f839a144f5fcef059a4eb5d" +checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" dependencies = [ "libc", - "windows-sys 0.59.0", + "windows-sys 0.61.2", ] [[package]] name = "event-listener" -version = "5.4.0" +version = "5.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3492acde4c3fc54c845eaab3eed8bd00c7a7d881f78bfc801e43a93dec1331ae" +checksum = "e13b66accf52311f30a0db42147dadea9850cb48cd070028831ae5f5d4b856ab" dependencies = [ "concurrent-queue", "parking", @@ -706,9 +706,9 @@ dependencies = [ [[package]] name = "event-listener-strategy" -version = "0.5.3" +version = "0.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c3e4e0dd3673c1139bf041f3008816d9cf2946bbfac2945c09e523b8d7b05b2" +checksum = "8be9f3dfaaffdae2972880079a491a1a8bb7cbed0b8dd7a347f668b4150a3b93" dependencies = [ "event-listener", "pin-project-lite", @@ -732,11 +732,17 @@ version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" +[[package]] +name = "find-msvc-tools" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52051878f80a721bb68ebfbc930e07b65ba72f2da88968ea5c06fd6ca3d3a127" + [[package]] name = "flate2" -version = "1.1.0" +version = "1.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11faaf5a5236997af9848be0bef4db95824b1d534ebc64d0f0c6cf3e67bd38dc" +checksum = "bfe33edd8e85a12a67454e37f8c75e730830d83e313556ab9ebf9ee7fbeb3bfb" dependencies = [ "crc32fast", "miniz_oxide", @@ -783,9 +789,9 @@ checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" [[package]] name = "form_urlencoded" -version = "1.2.1" +version = "1.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" +checksum = "cb4cb245038516f5f85277875cdaa4f7d2c9a0fa0468de06ed190163b1581fcf" dependencies = [ "percent-encoding", ] @@ -820,7 +826,7 @@ checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.108", ] [[package]] @@ -850,24 +856,11 @@ dependencies = [ "slab", ] -[[package]] -name = "generator" -version = "0.8.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc6bd114ceda131d3b1d665eba35788690ad37f5916457286b32ab6fd3c438dd" -dependencies = [ - "cfg-if", - "libc", - "log", - "rustversion", - "windows", -] - [[package]] name = "generic-array" -version = "0.14.7" +version = "0.14.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +checksum = "4bb6743198531e02858aeaea5398fcc883e71851fcbcb5a2f773e2fb6cb1edf2" dependencies = [ "typenum", "version_check", @@ -875,46 +868,40 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.15" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" +checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592" dependencies = [ "cfg-if", "js-sys", "libc", - "wasi 0.11.0+wasi-snapshot-preview1", + "wasi", "wasm-bindgen", ] [[package]] name = "getrandom" -version = "0.3.2" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73fea8450eea4bac3940448fb7ae50d91f034f941199fcd9d909a5a07aa455f0" +checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd" dependencies = [ "cfg-if", "libc", "r-efi", - "wasi 0.14.2+wasi-0.2.4", + "wasip2", ] -[[package]] -name = "gimli" -version = "0.31.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" - [[package]] name = "glob" -version = "0.3.2" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8d1add55171497b4705a648c6b583acafb01d58050a51727785f0b2c8e0a2b2" +checksum = "0cc23270f6e1808e30a928bdc84dea0b9b4136a8bc82338574f23baf47bbd280" [[package]] name = "h2" -version = "0.3.26" +version = "0.3.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81fe527a889e1532da5c525686d96d4c2e74cdd345badf8dfef9f6b39dd5f5e8" +checksum = "0beca50380b1fc32983fc1cb4587bfa4bb9e78fc259aad4a0032d2080309222d" dependencies = [ "bytes", "fnv", @@ -931,9 +918,9 @@ dependencies = [ [[package]] name = "h2" -version = "0.4.8" +version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5017294ff4bb30944501348f6f8e42e6ad28f42c8bbef7a74029aff064a4e3c2" +checksum = "f3c0b69cfcb4e1b9f1bf2f53f95f766e4661169728ec61cd3fe5a0166f2d1386" dependencies = [ "atomic-waker", "bytes", @@ -960,22 +947,28 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.15.2" +version = "0.15.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" +checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1" dependencies = [ "allocator-api2", "equivalent", "foldhash", ] +[[package]] +name = "hashbrown" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5419bdc4f6a9207fbeba6d11b604d481addf78ecd10c11ad51e76c2f6482748d" + [[package]] name = "hashlink" version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7382cf6263419f2d8df38c55d7da83da5c18aef87fc7a7fc1fb1e344edfe14c1" dependencies = [ - "hashbrown 0.15.2", + "hashbrown 0.15.5", ] [[package]] @@ -1008,15 +1001,6 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" -[[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 = "http" version = "0.2.12" @@ -1095,14 +1079,14 @@ dependencies = [ "futures-channel", "futures-core", "futures-util", - "h2 0.3.26", + "h2 0.3.27", "http 0.2.12", "http-body 0.4.6", "httparse", "httpdate", "itoa", "pin-project-lite", - "socket2", + "socket2 0.5.10", "tokio", "tower-service", "tracing", @@ -1111,20 +1095,22 @@ dependencies = [ [[package]] name = "hyper" -version = "1.6.0" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc2b571658e38e0c01b1fdca3bbbe93c00d3d71693ff2770043f8c29bc7d6f80" +checksum = "eb3aa54a13a0dfe7fbe3a59e0c76093041720fdc77b110cc0fc260fafb4dc51e" dependencies = [ + "atomic-waker", "bytes", "futures-channel", - "futures-util", - "h2 0.4.8", + "futures-core", + "h2 0.4.12", "http 1.3.1", "http-body 1.0.1", "httparse", "httpdate", "itoa", "pin-project-lite", + "pin-utils", "smallvec", "tokio", "want", @@ -1132,13 +1118,12 @@ dependencies = [ [[package]] name = "hyper-rustls" -version = "0.27.5" +version = "0.27.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d191583f3da1305256f22463b9bb0471acad48a4e534a5218b9963e9c1f59b2" +checksum = "e3c93eb611681b207e1fe55d5a71ecf91572ec8a6705cdb6857f7d8d5242cf58" dependencies = [ - "futures-util", "http 1.3.1", - "hyper 1.6.0", + "hyper 1.7.0", "hyper-util", "rustls", "rustls-native-certs", @@ -1156,7 +1141,7 @@ checksum = "70206fc6890eaca9fde8a0bf71caa2ddfc9fe045ac9e5c70df101a7dbde866e0" dependencies = [ "bytes", "http-body-util", - "hyper 1.6.0", + "hyper 1.7.0", "hyper-util", "native-tls", "tokio", @@ -1166,28 +1151,35 @@ dependencies = [ [[package]] name = "hyper-util" -version = "0.1.10" +version = "0.1.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df2dcfbe0677734ab2f3ffa7fa7bfd4706bfdc1ef393f2ee30184aed67e631b4" +checksum = "3c6995591a8f1380fcb4ba966a252a4b29188d51d2b89e3a252f5305be65aea8" dependencies = [ + "base64 0.22.1", "bytes", "futures-channel", + "futures-core", "futures-util", "http 1.3.1", "http-body 1.0.1", - "hyper 1.6.0", + "hyper 1.7.0", + "ipnet", + "libc", + "percent-encoding", "pin-project-lite", - "socket2", + "socket2 0.6.1", + "system-configuration", "tokio", "tower-service", "tracing", + "windows-registry", ] [[package]] name = "iana-time-zone" -version = "0.1.62" +version = "0.1.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2fd658b06e56721792c5df4475705b6cda790e9298d19d2f8af083457bcd127" +checksum = "33e57f83510bb73707521ebaffa789ec8caf86f9657cad665b092b581d40e9fb" dependencies = [ "android_system_properties", "core-foundation-sys", @@ -1195,7 +1187,7 @@ dependencies = [ "js-sys", "log", "wasm-bindgen", - "windows-core 0.52.0", + "windows-core", ] [[package]] @@ -1209,21 +1201,22 @@ dependencies = [ [[package]] name = "icu_collections" -version = "1.5.0" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db2fa452206ebee18c4b5c2274dbf1de17008e874b4dc4f0aea9d01ca79e4526" +checksum = "200072f5d0e3614556f94a9930d5dc3e0662a652823904c3a75dc3b0af7fee47" dependencies = [ "displaydoc", + "potential_utf", "yoke", "zerofrom", "zerovec", ] [[package]] -name = "icu_locid" -version = "1.5.0" +name = "icu_locale_core" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13acbb8371917fc971be86fc8057c41a64b521c184808a698c02acc242dbf637" +checksum = "0cde2700ccaed3872079a65fb1a78f6c0a36c91570f28755dda67bc8f7d9f00a" dependencies = [ "displaydoc", "litemap", @@ -1232,31 +1225,11 @@ dependencies = [ "zerovec", ] -[[package]] -name = "icu_locid_transform" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01d11ac35de8e40fdeda00d9e1e9d92525f3f9d887cdd7aa81d727596788b54e" -dependencies = [ - "displaydoc", - "icu_locid", - "icu_locid_transform_data", - "icu_provider", - "tinystr", - "zerovec", -] - -[[package]] -name = "icu_locid_transform_data" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fdc8ff3388f852bede6b579ad4e978ab004f139284d7b28715f773507b946f6e" - [[package]] name = "icu_normalizer" -version = "1.5.0" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19ce3e0da2ec68599d193c93d088142efd7f9c5d6fc9b803774855747dc6a84f" +checksum = "436880e8e18df4d7bbc06d58432329d6458cc84531f7ac5f024e93deadb37979" dependencies = [ "displaydoc", "icu_collections", @@ -1264,72 +1237,59 @@ dependencies = [ "icu_properties", "icu_provider", "smallvec", - "utf16_iter", - "utf8_iter", - "write16", "zerovec", ] [[package]] name = "icu_normalizer_data" -version = "1.5.0" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8cafbf7aa791e9b22bec55a167906f9e1215fd475cd22adfcf660e03e989516" +checksum = "00210d6893afc98edb752b664b8890f0ef174c8adbb8d0be9710fa66fbbf72d3" [[package]] name = "icu_properties" -version = "1.5.1" +version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93d6020766cfc6302c15dbbc9c8778c37e62c14427cb7f6e601d849e092aeef5" +checksum = "016c619c1eeb94efb86809b015c58f479963de65bdb6253345c1a1276f22e32b" dependencies = [ "displaydoc", "icu_collections", - "icu_locid_transform", + "icu_locale_core", "icu_properties_data", "icu_provider", - "tinystr", + "potential_utf", + "zerotrie", "zerovec", ] [[package]] name = "icu_properties_data" -version = "1.5.0" +version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67a8effbc3dd3e4ba1afa8ad918d5684b8868b3b26500753effea8d2eed19569" +checksum = "298459143998310acd25ffe6810ed544932242d3f07083eee1084d83a71bd632" [[package]] name = "icu_provider" -version = "1.5.0" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ed421c8a8ef78d3e2dbc98a973be2f3770cb42b606e3ab18d6237c4dfde68d9" +checksum = "03c80da27b5f4187909049ee2d72f276f0d9f99a42c306bd0131ecfe04d8e5af" dependencies = [ "displaydoc", - "icu_locid", - "icu_provider_macros", + "icu_locale_core", "stable_deref_trait", "tinystr", "writeable", "yoke", "zerofrom", + "zerotrie", "zerovec", ] -[[package]] -name = "icu_provider_macros" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - [[package]] name = "idna" -version = "1.0.3" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "686f825264d630750a544639377bae737628043f20d38bbc029e8f29ea968a7e" +checksum = "3b0875f23caa03898994f6ddc501886a45c7d3d62d04d2d90788d47be1b1e4de" dependencies = [ "idna_adapter", "smallvec", @@ -1338,9 +1298,9 @@ dependencies = [ [[package]] name = "idna_adapter" -version = "1.2.0" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "daca1df1c957320b2cf139ac61e7bd64fed304c5040df000a745aa1de3b4ef71" +checksum = "3acae9609540aa318d1bc588455225fb2085b9ed0c4f6bd0d9d5bcd86f1a0344" dependencies = [ "icu_normalizer", "icu_properties", @@ -1348,12 +1308,12 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.8.0" +version = "2.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3954d50fe15b02142bf25d3b8bdadb634ec3948f103d04ffe3031bc8fe9d7058" +checksum = "6717a8d2a5a929a1a2eb43a12812498ed141a0bcfb7e8f7844fbdbe4303bba9f" dependencies = [ "equivalent", - "hashbrown 0.15.2", + "hashbrown 0.16.0", ] [[package]] @@ -1373,17 +1333,27 @@ version = "2.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "469fb0b9cefa57e3ef31275ee7cacb78f2fdca44e4765491884a2b119d4eb130" +[[package]] +name = "iri-string" +version = "0.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbc5ebe9c3a1a7a5127f920a418f7585e9e758e911d0466ed004f393b0e380b2" +dependencies = [ + "memchr", + "serde", +] + [[package]] name = "is_terminal_polyfill" -version = "1.70.1" +version = "1.70.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" +checksum = "a6cb138bb79a146c1bd460005623e142ef0181e3d0219cb493e02f7d08a35695" [[package]] name = "itertools" -version = "0.12.1" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" +checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186" dependencies = [ "either", ] @@ -1407,7 +1377,7 @@ dependencies = [ "log", "serde", "serde_json", - "thiserror 2.0.12", + "thiserror 2.0.17", "tokio", "tokio-tungstenite 0.24.0", "tokio-util", @@ -1417,9 +1387,9 @@ dependencies = [ [[package]] name = "jiff" -version = "0.2.5" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c102670231191d07d37a35af3eb77f1f0dbf7a71be51a962dcd57ea607be7260" +checksum = "be1f93b8b1eb69c77f24bbb0afdf66f54b632ee39af40ca21c4365a1d7347e49" dependencies = [ "jiff-static", "log", @@ -1430,29 +1400,30 @@ dependencies = [ [[package]] name = "jiff-static" -version = "0.2.5" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4cdde31a9d349f1b1f51a0b3714a5940ac022976f4b49485fc04be052b183b4c" +checksum = "03343451ff899767262ec32146f6d559dd759fdadf42ff0e227c7c48f72594b4" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.108", ] [[package]] name = "jobserver" -version = "0.1.32" +version = "0.1.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48d1dbcbbeb6a7fec7e059840aa538bd62aaccf972c7346c4d9d2059312853d0" +checksum = "9afb3de4395d6b3e67a780b6de64b51c978ecf11cb9a462c66be7d4ca9039d33" dependencies = [ + "getrandom 0.3.4", "libc", ] [[package]] name = "js-sys" -version = "0.3.77" +version = "0.3.81" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1cfaf33c695fc6e08064efbc1f72ec937429614f25eef83af942d0e227c3a28f" +checksum = "ec48937a97411dcb524a265206ccd4c90bb711fca92b2792c407f268825b9305" dependencies = [ "once_cell", "wasm-bindgen", @@ -1467,32 +1438,20 @@ dependencies = [ "serde", ] -[[package]] -name = "lazy_static" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" - -[[package]] -name = "lazycell" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" - [[package]] name = "libc" -version = "0.2.171" +version = "0.2.177" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c19937216e9d3aa9956d9bb8dfc0b0c8beb6058fc4f7a4dc4d850edf86a237d6" +checksum = "2874a2af47a2325c2001a6e6fad9b16a53b802102b528163885171cf92b15976" [[package]] name = "libloading" -version = "0.8.6" +version = "0.8.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc2f4eb4bc735547cfed7c0a4922cbd04a4655978c09b54f1f7b228750664c34" +checksum = "d7c4b02199fee7c5d21a5ae7d8cfa79a6ef5bb2fc834d6e9058e89c825efdc55" dependencies = [ "cfg-if", - "windows-targets 0.52.6", + "windows-link 0.2.1", ] [[package]] @@ -1508,50 +1467,30 @@ dependencies = [ [[package]] name = "linux-raw-sys" -version = "0.4.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab" - -[[package]] -name = "linux-raw-sys" -version = "0.9.3" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe7db12097d22ec582439daf8618b8fdd1a7bef6270e9af3b1ebcd30893cf413" +checksum = "df1d3c3b53da64cf5760482273a98e575c651a67eec7f77df96b5b642de8f039" [[package]] name = "litemap" -version = "0.7.5" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23fb14cb19457329c82206317a5663005a4d404783dc74f4252769b0d5f42856" +checksum = "241eaef5fd12c88705a01fc1066c48c4b36e0dd4377dcdc7ec3942cea7a69956" [[package]] name = "lock_api" -version = "0.4.12" +version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" +checksum = "224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965" dependencies = [ - "autocfg", "scopeguard", ] [[package]] name = "log" -version = "0.4.27" +version = "0.4.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94" - -[[package]] -name = "loom" -version = "0.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "419e0dc8046cb947daa77eb95ae174acfbddb7673b4151f56d1eed8e93fbfaca" -dependencies = [ - "cfg-if", - "generator", - "scoped-tls", - "tracing", - "tracing-subscriber", -] +checksum = "34080505efa8e45a4b816c349525ebe327ceaa8559756f0356cba97ef3bf7432" [[package]] name = "lru" @@ -1559,29 +1498,31 @@ version = "0.12.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "234cf4f4a04dc1f57e24b96cc0cd600cf2af460d4161ac5ecdd0af8e1f3b2a38" dependencies = [ - "hashbrown 0.15.2", + "hashbrown 0.15.5", ] [[package]] -name = "matchers" -version = "0.1.0" +name = "match-lookup" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558" +checksum = "1265724d8cb29dbbc2b0f06fffb8bf1a8c0cf73a78eede9ba73a4a66c52a981e" dependencies = [ - "regex-automata 0.1.10", + "proc-macro2", + "quote", + "syn 1.0.109", ] [[package]] name = "memchr" -version = "2.7.4" +version = "2.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" +checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273" [[package]] name = "metrics" -version = "0.24.1" +version = "0.24.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a7deb012b3b2767169ff203fadb4c6b0b82b947512e5eb9e0b78c2e186ad9e3" +checksum = "25dea7ac8057892855ec285c440160265225438c3c45072613c25a4b26e98ef5" dependencies = [ "ahash", "portable-atomic", @@ -1595,7 +1536,7 @@ checksum = "dd7399781913e5393588a8d8c6a2867bf85fb38eaf2502fdce465aad2dc6f034" dependencies = [ "base64 0.22.1", "http-body-util", - "hyper 1.6.0", + "hyper 1.7.0", "hyper-rustls", "hyper-util", "indexmap", @@ -1610,16 +1551,16 @@ dependencies = [ [[package]] name = "metrics-util" -version = "0.19.0" +version = "0.19.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbd4884b1dd24f7d6628274a2f5ae22465c337c5ba065ec9b6edccddf8acc673" +checksum = "b8496cc523d1f94c1385dd8f0f0c2c480b2b8aeccb5b7e4485ad6365523ae376" dependencies = [ "crossbeam-epoch", "crossbeam-utils", - "hashbrown 0.15.2", + "hashbrown 0.15.5", "metrics", "quanta", - "rand", + "rand 0.9.2", "rand_xoshiro", "sketches-ddsketch", ] @@ -1648,43 +1589,43 @@ checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" [[package]] name = "miniz_oxide" -version = "0.8.5" +version = "0.8.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e3e04debbb59698c15bacbb6d93584a8c0ca9cc3213cb423d31f760d8843ce5" +checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316" dependencies = [ "adler2", + "simd-adler32", ] [[package]] name = "mio" -version = "1.0.3" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2886843bf800fba2e3377cff24abf6379b4c4d5c6681eaf9ea5b0d15090450bd" +checksum = "69d83b0086dc8ecf3ce9ae2874b2d1290252e2a30720bea58a5c6639b0092873" dependencies = [ "libc", - "wasi 0.11.0+wasi-snapshot-preview1", - "windows-sys 0.52.0", + "wasi", + "windows-sys 0.61.2", ] [[package]] name = "moka" -version = "0.12.10" +version = "0.12.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9321642ca94a4282428e6ea4af8cc2ca4eac48ac7a6a4ea8f33f76d0ce70926" +checksum = "8261cd88c312e0004c1d51baad2980c66528dfdb2bee62003e643a4d8f86b077" dependencies = [ "async-lock", "crossbeam-channel", "crossbeam-epoch", "crossbeam-utils", + "equivalent", "event-listener", "futures-util", - "loom", "parking_lot", "portable-atomic", "rustc_version", "smallvec", "tagptr", - "thiserror 1.0.69", "uuid", ] @@ -1708,11 +1649,12 @@ dependencies = [ [[package]] name = "multibase" -version = "0.9.1" +version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b3539ec3c1f04ac9748a260728e855f261b4977f5c3406612c884564f329404" +checksum = "8694bb4835f452b0e3bb06dbebb1d6fc5385b6ca1caf2e55fd165c042390ec77" dependencies = [ "base-x", + "base256emoji", "data-encoding", "data-encoding-macro", ] @@ -1734,7 +1676,7 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6a51313c5820b0b02bd422f4b44776fbf47961755c74ce64afc73bfad10226c3" dependencies = [ - "getrandom 0.2.15", + "getrandom 0.2.16", ] [[package]] @@ -1764,16 +1706,6 @@ dependencies = [ "minimal-lexical", ] -[[package]] -name = "nu-ansi-term" -version = "0.46.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84" -dependencies = [ - "overload", - "winapi", -] - [[package]] name = "num-traits" version = "0.2.19" @@ -1784,25 +1716,22 @@ dependencies = [ ] [[package]] -name = "object" -version = "0.36.7" +name = "once_cell" +version = "1.21.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62948e14d923ea95ea2c7c86c71013138b66525b86bdc08d2dcc262bdb497b87" -dependencies = [ - "memchr", -] +checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" [[package]] -name = "once_cell" -version = "1.21.1" +name = "once_cell_polyfill" +version = "1.70.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d75b0bedcc4fe52caa0e03d9f1151a323e4aa5e2d78ba3580400cd3c9e2bc4bc" +checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe" [[package]] name = "openssl" -version = "0.10.71" +version = "0.10.74" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e14130c6a98cd258fdcb0fb6d744152343ff729cbfcb28c656a9d12b999fbcd" +checksum = "24ad14dd45412269e1a30f52ad8f0664f0f4f4a89ee8fe28c3b3527021ebb654" dependencies = [ "bitflags", "cfg-if", @@ -1821,7 +1750,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.108", ] [[package]] @@ -1832,18 +1761,18 @@ checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e" [[package]] name = "openssl-src" -version = "300.4.2+3.4.1" +version = "300.5.4+3.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "168ce4e058f975fe43e89d9ccf78ca668601887ae736090aacc23ae353c298e2" +checksum = "a507b3792995dae9b0df8a1c1e3771e8418b7c2d9f0baeba32e6fe8b06c7cb72" dependencies = [ "cc", ] [[package]] name = "openssl-sys" -version = "0.9.106" +version = "0.9.110" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8bb61ea9811cc39e3c2069f40b8b8e2e70d8569b361f879786cc7ed48b777cdd" +checksum = "0a9f0075ba3c21b09f8e8b2026584b1d18d49388648f2fbbf3c97ea8deced8e2" dependencies = [ "cc", "libc", @@ -1852,12 +1781,6 @@ dependencies = [ "vcpkg", ] -[[package]] -name = "overload" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" - [[package]] name = "parking" version = "2.2.1" @@ -1866,9 +1789,9 @@ checksum = "f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba" [[package]] name = "parking_lot" -version = "0.12.3" +version = "0.12.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" +checksum = "93857453250e3077bd71ff98b6a65ea6621a19bb0f559a85248955ac12c45a1a" dependencies = [ "lock_api", "parking_lot_core", @@ -1876,22 +1799,22 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.9.10" +version = "0.9.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" +checksum = "2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1" dependencies = [ "cfg-if", "libc", "redox_syscall", "smallvec", - "windows-targets 0.52.6", + "windows-link 0.2.1", ] [[package]] name = "percent-encoding" -version = "2.3.1" +version = "2.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" +checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" [[package]] name = "pin-project" @@ -1910,7 +1833,7 @@ checksum = "6e918e4ff8c4549eb882f14b3a4bc8c8bc93de829416eacf579f1207a8fbf861" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.108", ] [[package]] @@ -1933,9 +1856,9 @@ checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" [[package]] name = "portable-atomic" -version = "1.11.0" +version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "350e9b48cbc6b0e028b0473b114454c6316e57336ee184ceab6e53f72c178b3e" +checksum = "f84267b20a16ea918e43c6a88433c2d54fa145c92a811b5b047ccbe153674483" [[package]] name = "portable-atomic-util" @@ -1946,63 +1869,72 @@ dependencies = [ "portable-atomic", ] +[[package]] +name = "potential_utf" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "84df19adbe5b5a0782edcab45899906947ab039ccf4573713735ee7de1e6b08a" +dependencies = [ + "zerovec", +] + [[package]] name = "ppv-lite86" version = "0.2.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9" dependencies = [ - "zerocopy 0.8.24", + "zerocopy", ] [[package]] name = "prettyplease" -version = "0.2.31" +version = "0.2.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5316f57387668042f561aae71480de936257848f9c43ce528e311d89a07cadeb" +checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b" dependencies = [ "proc-macro2", - "syn", + "syn 2.0.108", ] [[package]] name = "proc-macro2" -version = "1.0.94" +version = "1.0.103" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a31971752e70b8b2686d7e46ec17fb38dad4051d94024c88df49b667caea9c84" +checksum = "5ee95bc4ef87b8d5ba32e8b7714ccc834865276eab0aed5c9958d00ec45f49e8" dependencies = [ "unicode-ident", ] [[package]] name = "quanta" -version = "0.12.5" +version = "0.12.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3bd1fe6824cea6538803de3ff1bc0cf3949024db3d43c9643024bfb33a807c0e" +checksum = "f3ab5a9d756f0d97bdc89019bd2e4ea098cf9cde50ee7564dde6b81ccc8f06c7" dependencies = [ "crossbeam-utils", "libc", "once_cell", "raw-cpuid", - "wasi 0.11.0+wasi-snapshot-preview1", + "wasi", "web-sys", "winapi", ] [[package]] name = "quote" -version = "1.0.40" +version = "1.0.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d" +checksum = "ce25767e7b499d1b604768e7cde645d14cc8584231ea6b295e9c9eb22c02e1d1" dependencies = [ "proc-macro2", ] [[package]] name = "r-efi" -version = "5.2.0" +version = "5.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74765f6d916ee2faa39bc8e68e4f3ed8949b48cccdac59983d287a7cb71ce9c5" +checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" [[package]] name = "rand" @@ -2011,8 +1943,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" dependencies = [ "libc", - "rand_chacha", - "rand_core", + "rand_chacha 0.3.1", + "rand_core 0.6.4", +] + +[[package]] +name = "rand" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1" +dependencies = [ + "rand_chacha 0.9.0", + "rand_core 0.9.3", ] [[package]] @@ -2022,7 +1964,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" dependencies = [ "ppv-lite86", - "rand_core", + "rand_core 0.6.4", +] + +[[package]] +name = "rand_chacha" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" +dependencies = [ + "ppv-lite86", + "rand_core 0.9.3", ] [[package]] @@ -2031,85 +1983,79 @@ version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" dependencies = [ - "getrandom 0.2.15", + "getrandom 0.2.16", +] + +[[package]] +name = "rand_core" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38" +dependencies = [ + "getrandom 0.3.4", ] [[package]] name = "rand_xoshiro" -version = "0.6.0" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f97cdb2a36ed4183de61b2f824cc45c9f1037f28afe0a322e9fff4c108b5aaa" +checksum = "f703f4665700daf5512dcca5f43afa6af89f09db47fb56be587f80636bda2d41" dependencies = [ - "rand_core", + "rand_core 0.9.3", ] [[package]] name = "raw-cpuid" -version = "11.5.0" +version = "11.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6df7ab838ed27997ba19a4664507e6f82b41fe6e20be42929332156e5e85146" +checksum = "498cd0dc59d73224351ee52a95fee0f1a617a2eae0e7d9d720cc622c73a54186" dependencies = [ "bitflags", ] [[package]] name = "redox_syscall" -version = "0.5.10" +version = "0.5.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b8c0c260b63a8219631167be35e6a988e9554dbd323f8bd08439c8ed1302bd1" +checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" dependencies = [ "bitflags", ] [[package]] name = "regex" -version = "1.11.1" +version = "1.12.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" +checksum = "843bc0191f75f3e22651ae5f1e72939ab2f72a4bc30fa80a066bd66edefc24d4" dependencies = [ "aho-corasick", "memchr", - "regex-automata 0.4.9", - "regex-syntax 0.8.5", -] - -[[package]] -name = "regex-automata" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" -dependencies = [ - "regex-syntax 0.6.29", + "regex-automata", + "regex-syntax", ] [[package]] name = "regex-automata" -version = "0.4.9" +version = "0.4.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908" +checksum = "5276caf25ac86c8d810222b3dbb938e512c55c6831a10f3e6ed1c93b84041f1c" dependencies = [ "aho-corasick", "memchr", - "regex-syntax 0.8.5", + "regex-syntax", ] [[package]] name = "regex-syntax" -version = "0.6.29" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" - -[[package]] -name = "regex-syntax" -version = "0.8.5" +version = "0.8.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" +checksum = "7a2d987857b319362043e95f5353c0535c1f58eec5336fdfcf626430af7def58" [[package]] name = "reqwest" -version = "0.12.15" +version = "0.12.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d19c46a6fdd48bc4dab94b6103fccc55d34c67cc0ad04653aad4ea2a07cd7bbb" +checksum = "9d0946410b9f7b082a427e4ef5c8ff541a88b357bc6c637c40db3a68ac70a36f" dependencies = [ "async-compression", "base64 0.22.1", @@ -2117,38 +2063,35 @@ dependencies = [ "encoding_rs", "futures-core", "futures-util", - "h2 0.4.8", + "h2 0.4.12", "http 1.3.1", "http-body 1.0.1", "http-body-util", - "hyper 1.6.0", + "hyper 1.7.0", "hyper-rustls", "hyper-tls", "hyper-util", - "ipnet", "js-sys", "log", "mime", "native-tls", - "once_cell", "percent-encoding", "pin-project-lite", - "rustls-pemfile", + "rustls-pki-types", "serde", "serde_json", "serde_urlencoded", "sync_wrapper", - "system-configuration", "tokio", "tokio-native-tls", "tokio-util", "tower", + "tower-http", "tower-service", "url", "wasm-bindgen", "wasm-bindgen-futures", "web-sys", - "windows-registry", ] [[package]] @@ -2159,7 +2102,7 @@ checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7" dependencies = [ "cc", "cfg-if", - "getrandom 0.2.15", + "getrandom 0.2.16", "libc", "untrusted", "windows-sys 0.52.0", @@ -2179,17 +2122,11 @@ dependencies = [ "smallvec", ] -[[package]] -name = "rustc-demangle" -version = "0.1.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" - [[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" @@ -2202,35 +2139,22 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.44" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154" -dependencies = [ - "bitflags", - "errno", - "libc", - "linux-raw-sys 0.4.15", - "windows-sys 0.59.0", -] - -[[package]] -name = "rustix" -version = "1.0.3" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e56a18552996ac8d29ecc3b190b4fdbb2d91ca4ec396de7bbffaf43f3d637e96" +checksum = "cd15f8a2c5551a84d56efdc1cd049089e409ac19a3072d5037a17fd70719ff3e" dependencies = [ "bitflags", "errno", "libc", - "linux-raw-sys 0.9.3", - "windows-sys 0.59.0", + "linux-raw-sys", + "windows-sys 0.61.2", ] [[package]] name = "rustls" -version = "0.23.25" +version = "0.23.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "822ee9188ac4ec04a2f0531e55d035fb2de73f18b41a63c70c2712503b6fb13c" +checksum = "6a9586e9ee2b4f8fab52a0048ca7334d7024eef48e2cb9407e3497bb7cab7fa7" dependencies = [ "aws-lc-rs", "once_cell", @@ -2242,36 +2166,30 @@ dependencies = [ [[package]] name = "rustls-native-certs" -version = "0.8.1" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fcff2dd52b58a8d98a70243663a0d234c4e2b79235637849d15913394a247d3" +checksum = "9980d917ebb0c0536119ba501e90834767bffc3d60641457fd84a1f3fd337923" dependencies = [ "openssl-probe", "rustls-pki-types", "schannel", - "security-framework 3.2.0", + "security-framework 3.5.1", ] [[package]] -name = "rustls-pemfile" -version = "2.2.0" +name = "rustls-pki-types" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dce314e5fee3f39953d46bb63bb8a46d40c2f8fb7cc5a3b6cab2bde9721d6e50" +checksum = "229a4a4c221013e7e1f1a043678c5cc39fe5171437c88fb47151a21e6f5b5c79" dependencies = [ - "rustls-pki-types", + "zeroize", ] -[[package]] -name = "rustls-pki-types" -version = "1.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "917ce264624a4b4db1c364dcc35bfca9ded014d0a958cd47ad3e960e988ea51c" - [[package]] name = "rustls-webpki" -version = "0.103.0" +version = "0.103.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0aa4eeac2588ffff23e9d7a7e9b3f971c5fb5b7ebc9452745e0c232c64f83b2f" +checksum = "e10b3f4191e8a80e6b43eebabfac91e5dcecebb27a71f04e820c47ec41d314bf" dependencies = [ "aws-lc-rs", "ring", @@ -2281,9 +2199,9 @@ dependencies = [ [[package]] name = "rustversion" -version = "1.0.20" +version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eded382c5f5f786b989652c49544c4877d9f015cc22e145a5ea8ea66c2921cd2" +checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" [[package]] name = "ryu" @@ -2293,11 +2211,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.2", ] [[package]] @@ -2327,12 +2245,12 @@ dependencies = [ [[package]] name = "security-framework" -version = "3.2.0" +version = "3.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "271720403f46ca04f7ba6f55d438f8bd878d6b8ca0a1046e8228c4145bcbb316" +checksum = "b3297343eaf830f66ede390ea39da1d462b6b0c1b000f420d0a83f898bbbe6ef" dependencies = [ "bitflags", - "core-foundation 0.10.0", + "core-foundation 0.10.1", "core-foundation-sys", "libc", "security-framework-sys", @@ -2340,9 +2258,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", @@ -2350,62 +2268,74 @@ 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 = "serde" -version = "1.0.219" +version = "1.0.228" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6" +checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" 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]] +name = "serde_core" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" +dependencies = [ + "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.219" +version = "1.0.228" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00" +checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.108", ] [[package]] name = "serde_html_form" -version = "0.2.7" +version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d2de91cf02bbc07cde38891769ccd5d4f073d22a40683aa4bc7a95781aaa2c4" +checksum = "b2f2d7ff8a2140333718bb329f5c40fc5f0865b84c426183ce14c97d2ab8154f" dependencies = [ "form_urlencoded", "indexmap", "itoa", "ryu", - "serde", + "serde_core", ] [[package]] name = "serde_json" -version = "1.0.140" +version = "1.0.145" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "20068b6e96dc6c9bd23e01df8827e6c7e1f2fddd43c21810382803c136b99373" +checksum = "402a6f66d8c709116cf22f558eab210f5a50187f702eb4d7e5ef38d9a7f1c79c" dependencies = [ "itoa", "memchr", "ryu", "serde", + "serde_core", ] [[package]] @@ -2431,15 +2361,6 @@ dependencies = [ "digest", ] -[[package]] -name = "sharded-slab" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" -dependencies = [ - "lazy_static", -] - [[package]] name = "shlex" version = "1.3.0" @@ -2448,13 +2369,19 @@ checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" [[package]] name = "signal-hook-registry" -version = "1.4.2" +version = "1.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9e9e0b4211b72e7b8b6e85c807d36c212bdb33ea8587f7569562a84df5465b1" +checksum = "b2a4719bff48cee6b39d12c020eeb490953ad2443b7055bd0b21fca26bd8c28b" dependencies = [ "libc", ] +[[package]] +name = "simd-adler32" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe" + [[package]] name = "sketches-ddsketch" version = "0.3.0" @@ -2464,6 +2391,7 @@ checksum = "c1e9a774a6c28142ac54bb25d25562e6bcf957493a184f15ad4eebccb23e410a" [[package]] name = "skyfeed" version = "0.6.0" +source = "git+https://github.com/cyypherus/skyfeed.git?branch=french-feed#19ae7bc26f1f5a7345715fe959247a152ef45768" dependencies = [ "anyhow", "atrium-api", @@ -2486,29 +2414,36 @@ dependencies = [ [[package]] name = "slab" -version = "0.4.9" +version = "0.4.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" -dependencies = [ - "autocfg", -] +checksum = "7a2ae44ef20feb57a68b23d846850f861394c2e02dc425a50098ae8c90267589" [[package]] name = "smallvec" -version = "1.14.0" +version = "1.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fcf8323ef1faaee30a44a340193b1ac6814fd9b7b4e88e9d4519a3e4abe1cfd" +checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" [[package]] name = "socket2" -version = "0.5.8" +version = "0.5.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c970269d99b64e60ec3bd6ad27270092a5394c4e309314b18ae3fe575695fbe8" +checksum = "e22376abed350d73dd1cd119b57ffccad95b4e585a7cda43e286245ce23c0678" dependencies = [ "libc", "windows-sys 0.52.0", ] +[[package]] +name = "socket2" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17129e116933cf371d018bb80ae557e889637989d8638274fb25622827b03881" +dependencies = [ + "libc", + "windows-sys 0.60.2", +] + [[package]] name = "spin" version = "0.9.8" @@ -2520,9 +2455,9 @@ dependencies = [ [[package]] name = "stable_deref_trait" -version = "1.2.0" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" +checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596" [[package]] name = "strsim" @@ -2538,9 +2473,20 @@ checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" [[package]] name = "syn" -version = "2.0.100" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "2.0.108" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b09a44accad81e1ba1cd74a32461ba89dee89095ba17b32f5d03683b1b1fc2a0" +checksum = "da58917d35242480a05c2897064da0a80589a2a0476c9a3f2fdc83b53502e917" dependencies = [ "proc-macro2", "quote", @@ -2558,13 +2504,13 @@ dependencies = [ [[package]] name = "synstructure" -version = "0.13.1" +version = "0.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" +checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.108", ] [[package]] @@ -2596,15 +2542,15 @@ checksum = "7b2093cf4c8eb1e67749a6762251bc9cd836b6fc171623bd0a9d324d37af2417" [[package]] name = "tempfile" -version = "3.19.1" +version = "3.23.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7437ac7763b9b123ccf33c338a5cc1bac6f69b45a136c19bdd8a65e3916435bf" +checksum = "2d31c77bdf42a745371d260a26ca7163f1e0924b64afa0b688e61b5a9fa02f16" dependencies = [ "fastrand", - "getrandom 0.3.2", + "getrandom 0.3.4", "once_cell", - "rustix 1.0.3", - "windows-sys 0.59.0", + "rustix", + "windows-sys 0.61.2", ] [[package]] @@ -2618,11 +2564,11 @@ dependencies = [ [[package]] name = "thiserror" -version = "2.0.12" +version = "2.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "567b8a2dae586314f7be2a752ec7474332959c6460e02bde30d702a66d488708" +checksum = "f63587ca0f12b72a0600bcba1d40081f830876000bb46dd2337a3051618f4fc8" dependencies = [ - "thiserror-impl 2.0.12", + "thiserror-impl 2.0.17", ] [[package]] @@ -2633,35 +2579,25 @@ checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.108", ] [[package]] name = "thiserror-impl" -version = "2.0.12" +version = "2.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f7cf42b4507d8ea322120659672cf1b9dbb93f8f2d4ecfd6e51350ff5b17a1d" +checksum = "3ff15c8ecd7de3849db632e14d18d2571fa09dfc5ed93479bc4485c7a517c913" dependencies = [ "proc-macro2", "quote", - "syn", -] - -[[package]] -name = "thread_local" -version = "1.1.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c" -dependencies = [ - "cfg-if", - "once_cell", + "syn 2.0.108", ] [[package]] name = "tinystr" -version = "0.7.6" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9117f5d4db391c1cf6927e7bea3db74b9a1c1add8f7eda9ffd5364f40f57b82f" +checksum = "5d4f6d1145dcb577acf783d4e601bc1d76a13337bb54e6233add580b07344c8b" dependencies = [ "displaydoc", "zerovec", @@ -2669,31 +2605,30 @@ dependencies = [ [[package]] name = "tokio" -version = "1.44.1" +version = "1.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f382da615b842244d4b8738c82ed1275e6c5dd90c459a30941cd07080b06c91a" +checksum = "ff360e02eab121e0bc37a2d3b4d4dc622e6eda3a8e5253d5435ecf5bd4c68408" dependencies = [ - "backtrace", "bytes", "libc", "mio", "parking_lot", "pin-project-lite", "signal-hook-registry", - "socket2", + "socket2 0.6.1", "tokio-macros", - "windows-sys 0.52.0", + "windows-sys 0.61.2", ] [[package]] name = "tokio-macros" -version = "2.5.0" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e06d43f1345a3bcd39f6a56dbb7dcab2ba47e68e8ac134855e7e2bdbaf8cab8" +checksum = "af407857209536a95c8e56f8231ef2c2e2aff839b22e07a1ffcbc617e9db9fa5" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.108", ] [[package]] @@ -2708,9 +2643,9 @@ dependencies = [ [[package]] name = "tokio-rustls" -version = "0.26.2" +version = "0.26.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e727b36a1a0e8b74c376ac2211e40c2c8af09fb4013c60d910495810f008e9b" +checksum = "1729aa945f29d91ba541258c8df89027d5792d85a8841fb65e8bf0f4ede4ef61" dependencies = [ "rustls", "tokio", @@ -2744,9 +2679,9 @@ dependencies = [ [[package]] name = "tokio-util" -version = "0.7.14" +version = "0.7.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b9590b93e6fcc1739458317cccd391ad3955e2bde8913edf6f95f9e65a8f034" +checksum = "14307c986784f72ef81c89db7d9e28d6ac26d16213b109ea501696195e6e3ce5" dependencies = [ "bytes", "futures-core", @@ -2770,6 +2705,24 @@ dependencies = [ "tower-service", ] +[[package]] +name = "tower-http" +version = "0.6.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adc82fd73de2a9722ac5da747f12383d2bfdb93591ee6c58486e0097890f05f2" +dependencies = [ + "bitflags", + "bytes", + "futures-util", + "http 1.3.1", + "http-body 1.0.1", + "iri-string", + "pin-project-lite", + "tower", + "tower-layer", + "tower-service", +] + [[package]] name = "tower-layer" version = "0.3.3" @@ -2795,41 +2748,11 @@ dependencies = [ [[package]] name = "tracing-core" -version = "0.1.33" +version = "0.1.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e672c95779cf947c5311f83787af4fa8fffd12fb27e4993211a84bdfd9610f9c" +checksum = "b9d12581f227e93f094d3af2ae690a574abb8a2b9b7a96e7cfe9647b2b617678" dependencies = [ "once_cell", - "valuable", -] - -[[package]] -name = "tracing-log" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3" -dependencies = [ - "log", - "once_cell", - "tracing-core", -] - -[[package]] -name = "tracing-subscriber" -version = "0.3.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8189decb5ac0fa7bc8b96b7cb9b2701d60d48805aca84a238004d665fcc4008" -dependencies = [ - "matchers", - "nu-ansi-term", - "once_cell", - "regex", - "sharded-slab", - "smallvec", - "thread_local", - "tracing", - "tracing-core", - "tracing-log", ] [[package]] @@ -2840,7 +2763,7 @@ checksum = "70977707304198400eb4835a78f6a9f928bf41bba420deb8fdb175cd965d77a7" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.108", ] [[package]] @@ -2861,7 +2784,7 @@ dependencies = [ "http 1.3.1", "httparse", "log", - "rand", + "rand 0.8.5", "sha1", "thiserror 1.0.69", "url", @@ -2881,7 +2804,7 @@ dependencies = [ "httparse", "log", "native-tls", - "rand", + "rand 0.8.5", "sha1", "thiserror 1.0.69", "url", @@ -2890,9 +2813,9 @@ dependencies = [ [[package]] name = "typenum" -version = "1.18.0" +version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1dccffe3ce07af9386bfd29e80c0ab1a8205a2fc34e4bcd40364df902cfa8f3f" +checksum = "562d481066bde0658276a35467c4af00bdc6ee726305698a55b86e61d7ad82bb" [[package]] name = "unicase" @@ -2902,9 +2825,9 @@ checksum = "75b844d17643ee918803943289730bec8aac480150456169e647ed0b576ba539" [[package]] name = "unicode-ident" -version = "1.0.18" +version = "1.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" +checksum = "462eeb75aeb73aea900253ce739c8e18a67423fadf006037cd3ff27e82748a06" [[package]] name = "unsigned-varint" @@ -2920,13 +2843,14 @@ checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" [[package]] name = "url" -version = "2.5.4" +version = "2.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32f8b686cadd1473f4bd0117a5d28d36b1ade384ea9b5069a1c40aefed7fda60" +checksum = "08bc136a29a3d1758e07a9cca267be308aeebf5cfd5a10f3f67ab2097683ef5b" dependencies = [ "form_urlencoded", "idna", "percent-encoding", + "serde", ] [[package]] @@ -2935,12 +2859,6 @@ version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" -[[package]] -name = "utf16_iter" -version = "1.0.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8232dd3cdaed5356e0f716d285e4b40b932ac434100fe9b7e0e8e935b9e6246" - [[package]] name = "utf8_iter" version = "1.0.4" @@ -2955,19 +2873,15 @@ checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" [[package]] name = "uuid" -version = "1.16.0" +version = "1.18.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "458f7a779bf54acc9f347480ac654f68407d3aab21269a6e3c9f922acd9e2da9" +checksum = "2f87b8aa10b915a06587d0dec516c282ff295b475d94abf425d62b57710070a2" dependencies = [ - "getrandom 0.3.2", + "getrandom 0.3.4", + "js-sys", + "wasm-bindgen", ] -[[package]] -name = "valuable" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba73ea9cf16a25df0c8caa16c51acb937d5712a8429db78a3ee29d5dcacd3a65" - [[package]] name = "vcpkg" version = "0.2.15" @@ -3020,50 +2934,51 @@ dependencies = [ [[package]] name = "wasi" -version = "0.11.0+wasi-snapshot-preview1" +version = "0.11.1+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" +checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" [[package]] -name = "wasi" -version = "0.14.2+wasi-0.2.4" +name = "wasip2" +version = "1.0.1+wasi-0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9683f9a5a998d873c0d21fcbe3c083009670149a8fab228644b8bd36b2c48cb3" +checksum = "0562428422c63773dad2c345a1882263bbf4d65cf3f42e90921f787ef5ad58e7" dependencies = [ - "wit-bindgen-rt", + "wit-bindgen", ] [[package]] name = "wasm-bindgen" -version = "0.2.100" +version = "0.2.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1edc8929d7499fc4e8f0be2262a241556cfc54a0bea223790e71446f2aab1ef5" +checksum = "c1da10c01ae9f1ae40cbfac0bac3b1e724b320abfcf52229f80b547c0d250e2d" dependencies = [ "cfg-if", "once_cell", "rustversion", "wasm-bindgen-macro", + "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-backend" -version = "0.2.100" +version = "0.2.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f0a0651a5c2bc21487bde11ee802ccaf4c51935d0d3d42a6101f98161700bc6" +checksum = "671c9a5a66f49d8a47345ab942e2cb93c7d1d0339065d4f8139c486121b43b19" dependencies = [ "bumpalo", "log", "proc-macro2", "quote", - "syn", + "syn 2.0.108", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-futures" -version = "0.4.50" +version = "0.4.54" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "555d470ec0bc3bb57890405e5d4322cc9ea83cebb085523ced7be4144dac1e61" +checksum = "7e038d41e478cc73bae0ff9b36c60cff1c98b8f38f8d7e8061e79ee63608ac5c" dependencies = [ "cfg-if", "js-sys", @@ -3074,9 +2989,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.100" +version = "0.2.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fe63fc6d09ed3792bd0897b314f53de8e16568c2b3f7982f468c0bf9bd0b407" +checksum = "7ca60477e4c59f5f2986c50191cd972e3a50d8a95603bc9434501cf156a9a119" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -3084,31 +2999,31 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.100" +version = "0.2.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de" +checksum = "9f07d2f20d4da7b26400c9f4a0511e6e0345b040694e8a75bd41d578fa4421d7" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.108", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.100" +version = "0.2.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a05d73b933a847d6cccdda8f838a22ff101ad9bf93e33684f39c1f5f0eece3d" +checksum = "bad67dc8b2a1a6e5448428adec4c3e84c43e561d8c9ee8a9e5aabeb193ec41d1" dependencies = [ "unicode-ident", ] [[package]] name = "web-sys" -version = "0.3.77" +version = "0.3.81" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33b6dd2ef9186f1f2072e409e99cd22a975331a6b3591b12c764e0e55c60d5d2" +checksum = "9367c417a924a74cae129e6a2ae3b47fabb1f8995595ab474029da749a8be120" dependencies = [ "js-sys", "wasm-bindgen", @@ -3134,18 +3049,6 @@ dependencies = [ "once_cell", ] -[[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 = "winapi" version = "0.3.9" @@ -3168,112 +3071,98 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" -[[package]] -name = "windows" -version = "0.58.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd04d41d93c4992d421894c18c8b43496aa748dd4c081bac0dc93eb0489272b6" -dependencies = [ - "windows-core 0.58.0", - "windows-targets 0.52.6", -] - -[[package]] -name = "windows-core" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" -dependencies = [ - "windows-targets 0.52.6", -] - [[package]] name = "windows-core" -version = "0.58.0" +version = "0.62.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ba6d44ec8c2591c134257ce647b7ea6b20335bf6379a27dac5f1641fcf59f99" +checksum = "b8e83a14d34d0623b51dce9581199302a221863196a1dde71a7663a4c2be9deb" dependencies = [ "windows-implement", "windows-interface", - "windows-result 0.2.0", - "windows-strings 0.1.0", - "windows-targets 0.52.6", + "windows-link 0.2.1", + "windows-result 0.4.1", + "windows-strings 0.5.1", ] [[package]] name = "windows-implement" -version = "0.58.0" +version = "0.60.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2bbd5b46c938e506ecbce286b6628a02171d56153ba733b6c741fc627ec9579b" +checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.108", ] [[package]] name = "windows-interface" -version = "0.58.0" +version = "0.59.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "053c4c462dc91d3b1504c6fe5a726dd15e216ba718e84a0e46a88fbe5ded3515" +checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.108", ] [[package]] name = "windows-link" -version = "0.1.1" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a" + +[[package]] +name = "windows-link" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76840935b766e1b0a05c0066835fb9ec80071d4c09a16f6bd5f7e655e3c14c38" +checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" [[package]] name = "windows-registry" -version = "0.4.0" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4286ad90ddb45071efd1a66dfa43eb02dd0dfbae1545ad6cc3c51cf34d7e8ba3" +checksum = "5b8a9ed28765efc97bbc954883f4e6796c33a06546ebafacbabee9696967499e" dependencies = [ - "windows-result 0.3.2", - "windows-strings 0.3.1", - "windows-targets 0.53.0", + "windows-link 0.1.3", + "windows-result 0.3.4", + "windows-strings 0.4.2", ] [[package]] name = "windows-result" -version = "0.2.0" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d1043d8214f791817bab27572aaa8af63732e11bf84aa21a45a78d6c317ae0e" +checksum = "56f42bd332cc6c8eac5af113fc0c1fd6a8fd2aa08a0119358686e5160d0586c6" dependencies = [ - "windows-targets 0.52.6", + "windows-link 0.1.3", ] [[package]] name = "windows-result" -version = "0.3.2" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c64fd11a4fd95df68efcfee5f44a294fe71b8bc6a91993e2791938abcc712252" +checksum = "7781fa89eaf60850ac3d2da7af8e5242a5ea78d1a11c49bf2910bb5a73853eb5" dependencies = [ - "windows-link", + "windows-link 0.2.1", ] [[package]] name = "windows-strings" -version = "0.1.0" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4cd9b125c486025df0eabcb585e62173c6c9eddcec5d117d3b6e8c30e2ee4d10" +checksum = "56e6c93f3a0c3b36176cb1327a4958a0353d5d166c2a35cb268ace15e91d3b57" dependencies = [ - "windows-result 0.2.0", - "windows-targets 0.52.6", + "windows-link 0.1.3", ] [[package]] name = "windows-strings" -version = "0.3.1" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87fa48cc5d406560701792be122a10132491cff9d0aeb23583cc2dcafc847319" +checksum = "7837d08f69c77cf6b07689544538e017c1bfcf57e34b4c0ff58e6c2cd3b37091" dependencies = [ - "windows-link", + "windows-link 0.2.1", ] [[package]] @@ -3287,11 +3176,20 @@ dependencies = [ [[package]] name = "windows-sys" -version = "0.59.0" +version = "0.60.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb" dependencies = [ - "windows-targets 0.52.6", + "windows-targets 0.53.5", +] + +[[package]] +name = "windows-sys" +version = "0.61.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" +dependencies = [ + "windows-link 0.2.1", ] [[package]] @@ -3312,18 +3210,19 @@ dependencies = [ [[package]] name = "windows-targets" -version = "0.53.0" +version = "0.53.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1e4c7e8ceaaf9cb7d7507c974735728ab453b67ef8f18febdd7c11fe59dca8b" +checksum = "4945f9f551b88e0d65f3db0bc25c33b8acea4d9e41163edf90dcd0b19f9069f3" dependencies = [ - "windows_aarch64_gnullvm 0.53.0", - "windows_aarch64_msvc 0.53.0", - "windows_i686_gnu 0.53.0", - "windows_i686_gnullvm 0.53.0", - "windows_i686_msvc 0.53.0", - "windows_x86_64_gnu 0.53.0", - "windows_x86_64_gnullvm 0.53.0", - "windows_x86_64_msvc 0.53.0", + "windows-link 0.2.1", + "windows_aarch64_gnullvm 0.53.1", + "windows_aarch64_msvc 0.53.1", + "windows_i686_gnu 0.53.1", + "windows_i686_gnullvm 0.53.1", + "windows_i686_msvc 0.53.1", + "windows_x86_64_gnu 0.53.1", + "windows_x86_64_gnullvm 0.53.1", + "windows_x86_64_msvc 0.53.1", ] [[package]] @@ -3334,9 +3233,9 @@ checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" [[package]] name = "windows_aarch64_gnullvm" -version = "0.53.0" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86b8d5f90ddd19cb4a147a5fa63ca848db3df085e25fee3cc10b39b6eebae764" +checksum = "a9d8416fa8b42f5c947f8482c43e7d89e73a173cead56d044f6a56104a6d1b53" [[package]] name = "windows_aarch64_msvc" @@ -3346,9 +3245,9 @@ checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" [[package]] name = "windows_aarch64_msvc" -version = "0.53.0" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7651a1f62a11b8cbd5e0d42526e55f2c99886c77e007179efff86c2b137e66c" +checksum = "b9d782e804c2f632e395708e99a94275910eb9100b2114651e04744e9b125006" [[package]] name = "windows_i686_gnu" @@ -3358,9 +3257,9 @@ checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" [[package]] name = "windows_i686_gnu" -version = "0.53.0" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1dc67659d35f387f5f6c479dc4e28f1d4bb90ddd1a5d3da2e5d97b42d6272c3" +checksum = "960e6da069d81e09becb0ca57a65220ddff016ff2d6af6a223cf372a506593a3" [[package]] name = "windows_i686_gnullvm" @@ -3370,9 +3269,9 @@ checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" [[package]] name = "windows_i686_gnullvm" -version = "0.53.0" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ce6ccbdedbf6d6354471319e781c0dfef054c81fbc7cf83f338a4296c0cae11" +checksum = "fa7359d10048f68ab8b09fa71c3daccfb0e9b559aed648a8f95469c27057180c" [[package]] name = "windows_i686_msvc" @@ -3382,9 +3281,9 @@ checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" [[package]] name = "windows_i686_msvc" -version = "0.53.0" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "581fee95406bb13382d2f65cd4a908ca7b1e4c2f1917f143ba16efe98a589b5d" +checksum = "1e7ac75179f18232fe9c285163565a57ef8d3c89254a30685b57d83a38d326c2" [[package]] name = "windows_x86_64_gnu" @@ -3394,9 +3293,9 @@ checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" [[package]] name = "windows_x86_64_gnu" -version = "0.53.0" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e55b5ac9ea33f2fc1716d1742db15574fd6fc8dadc51caab1c16a3d3b4190ba" +checksum = "9c3842cdd74a865a8066ab39c8a7a473c0778a3f29370b5fd6b4b9aa7df4a499" [[package]] name = "windows_x86_64_gnullvm" @@ -3406,9 +3305,9 @@ checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" [[package]] name = "windows_x86_64_gnullvm" -version = "0.53.0" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a6e035dd0599267ce1ee132e51c27dd29437f63325753051e71dd9e42406c57" +checksum = "0ffa179e2d07eee8ad8f57493436566c7cc30ac536a3379fdf008f47f6bb7ae1" [[package]] name = "windows_x86_64_msvc" @@ -3418,36 +3317,27 @@ checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] name = "windows_x86_64_msvc" -version = "0.53.0" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486" +checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650" [[package]] -name = "wit-bindgen-rt" -version = "0.39.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1" -dependencies = [ - "bitflags", -] - -[[package]] -name = "write16" -version = "1.0.0" +name = "wit-bindgen" +version = "0.46.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d1890f4022759daae28ed4fe62859b1236caebfc61ede2f63ed4e695f3f6d936" +checksum = "f17a85883d4e6d00e8a97c586de764dabcc06133f7f1d55dce5cdc070ad7fe59" [[package]] name = "writeable" -version = "0.5.5" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e9df38ee2d2c3c5948ea468a8406ff0db0b29ae1ffde1bcf20ef305bcc95c51" +checksum = "ea2f10b9bb0928dfb1b42b65e1f9e36f7f54dbdf08457afefb38afcdec4fa2bb" [[package]] name = "yoke" -version = "0.7.5" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "120e6aef9aa629e3d4f52dc8cc43a015c7724194c97dfaf45180d2daf2b77f40" +checksum = "5f41bb01b8226ef4bfd589436a297c53d118f65921786300e427be8d487695cc" dependencies = [ "serde", "stable_deref_trait", @@ -3457,54 +3347,34 @@ dependencies = [ [[package]] name = "yoke-derive" -version = "0.7.5" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2380878cad4ac9aac1e2435f3eb4020e8374b5f13c296cb75b4620ff8e229154" +checksum = "38da3c9736e16c5d3c8c597a9aaa5d1fa565d0532ae05e27c24aa62fb32c0ab6" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.108", "synstructure", ] [[package]] name = "zerocopy" -version = "0.7.35" +version = "0.8.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" +checksum = "0894878a5fa3edfd6da3f88c4805f4c8558e2b996227a3d864f47fe11e38282c" dependencies = [ - "zerocopy-derive 0.7.35", -] - -[[package]] -name = "zerocopy" -version = "0.8.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2586fea28e186957ef732a5f8b3be2da217d65c5969d4b1e17f973ebbe876879" -dependencies = [ - "zerocopy-derive 0.8.24", + "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.7.35" +version = "0.8.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" +checksum = "88d2b8d9c68ad2b9e4340d7832716a4d21a22a1154777ad56ea55c51a9cf3831" dependencies = [ "proc-macro2", "quote", - "syn", -] - -[[package]] -name = "zerocopy-derive" -version = "0.8.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a996a8f63c5c4448cd959ac1bab0aaa3306ccfd060472f85943ee0750f0169be" -dependencies = [ - "proc-macro2", - "quote", - "syn", + "syn 2.0.108", ] [[package]] @@ -3524,21 +3394,32 @@ checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.108", "synstructure", ] [[package]] name = "zeroize" -version = "1.8.1" +version = "1.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b97154e67e32c85465826e8bcc1c59429aaaf107c1e4a9e53c8d8ccd5eff88d0" + +[[package]] +name = "zerotrie" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" +checksum = "36f0bbd478583f79edad978b407914f61b2972f5af6fa089686016be8f9af595" +dependencies = [ + "displaydoc", + "yoke", + "zerofrom", +] [[package]] name = "zerovec" -version = "0.10.4" +version = "0.11.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa2b893d79df23bfb12d5461018d408ea19dfafe76c2c7ef6d4eba614f8ff079" +checksum = "e7aa2bd55086f1ab526693ecbe444205da57e25f4489879da80635a46d90e73b" dependencies = [ "yoke", "zerofrom", @@ -3547,13 +3428,13 @@ dependencies = [ [[package]] name = "zerovec-derive" -version = "0.10.3" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6eafa6dfb17584ea3e2bd6e76e0cc15ad7af12b09abdd1ca55961bed9b1063c6" +checksum = "5b96237efa0c878c64bd89c436f661be4e46b2f3eff1ebb976f7ef2321d2f58f" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.108", ] [[package]] @@ -3576,9 +3457,9 @@ dependencies = [ [[package]] name = "zstd-sys" -version = "2.0.15+zstd.1.5.7" +version = "2.0.16+zstd.1.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb81183ddd97d0c74cedf1d50d85c8d08c1b8b68ee863bdee9e706eedba1a237" +checksum = "91e19ebc2adc8f83e43039e79776e3fda8ca919132d68a1fed6a5faca2683748" dependencies = [ "cc", "pkg-config", diff --git a/examples/sqlite/Cargo.toml b/examples/sqlite/Cargo.toml index 108f86f..a539f6e 100644 --- a/examples/sqlite/Cargo.toml +++ b/examples/sqlite/Cargo.toml @@ -5,7 +5,8 @@ edition = "2021" [dependencies] log = "0.4.25" -skyfeed = { path = "../.." } +skyfeed = { git = "https://github.com/cyypherus/skyfeed.git", branch = "french-feed" } +# skyfeed = { path = "../.." } tokio = { version = "1.43.0", features = ["full", "time"] } rusqlite = { version = "0.33.0", features = ["bundled"] } chrono = "0.4.39" diff --git a/src/bin/publish.rs b/src/bin/publish.rs index 9d107d0..e55ed63 100644 --- a/src/bin/publish.rs +++ b/src/bin/publish.rs @@ -1,4 +1,5 @@ use atrium_api::com::atproto::repo::put_record::InputData; +use atrium_api::types::string::RecordKey; use atrium_api::{ agent::atp_agent::{store::MemorySessionStore, AtpAgent}, app::bsky::feed::generator::RecordData, @@ -122,7 +123,7 @@ async fn main() { repo: atrium_api::types::string::AtIdentifier::Did( publisher_did.to_owned().did.clone(), ), - rkey: args.name.to_owned(), + rkey: RecordKey::new(args.name.to_owned()).expect("Invalid RecordKey"), swap_commit: None, swap_record: None, validate: None, diff --git a/src/bin/unpublish.rs b/src/bin/unpublish.rs index 86d4b20..acdb360 100644 --- a/src/bin/unpublish.rs +++ b/src/bin/unpublish.rs @@ -1,7 +1,7 @@ use anyhow::Result; use atrium_api::{ agent::atp_agent::{store::MemorySessionStore, AtpAgent}, - types::string::{Handle, Nsid}, + types::string::{Handle, Nsid, RecordKey}, }; use clap::Parser; @@ -62,7 +62,7 @@ async fn main() -> Result<()> { repo: atrium_api::types::string::AtIdentifier::Did( publisher_did.to_owned().did.clone(), ), - rkey: args.name.to_owned(), + rkey: RecordKey::new(args.name.to_owned()).expect("Invalid RecordKey"), swap_commit: None, swap_record: None, } diff --git a/src/feed.rs b/src/feed.rs index efc9f51..b61663a 100644 --- a/src/feed.rs +++ b/src/feed.rs @@ -303,5 +303,6 @@ async fn get_feed_skeleton( }) }) .collect(), + req_id: None, })) } From 78c598806a91318dfe83161f809adb0ae2bde19d Mon Sep 17 00:00:00 2001 From: cyypherus Date: Fri, 24 Oct 2025 20:46:17 -0600 Subject: [PATCH 05/53] pub config --- examples/sqlite/Cargo.lock | 2 +- examples/sqlite/src/main.rs | 21 ++++++++++++++++++--- src/lib.rs | 1 + 3 files changed, 20 insertions(+), 4 deletions(-) diff --git a/examples/sqlite/Cargo.lock b/examples/sqlite/Cargo.lock index 9da8d15..8e31246 100644 --- a/examples/sqlite/Cargo.lock +++ b/examples/sqlite/Cargo.lock @@ -2391,7 +2391,7 @@ checksum = "c1e9a774a6c28142ac54bb25d25562e6bcf957493a184f15ad4eebccb23e410a" [[package]] name = "skyfeed" version = "0.6.0" -source = "git+https://github.com/cyypherus/skyfeed.git?branch=french-feed#19ae7bc26f1f5a7345715fe959247a152ef45768" +source = "git+https://github.com/cyypherus/skyfeed.git?branch=french-feed#2e09079f040746eb3ddafa0670b8a04c6172e870" dependencies = [ "anyhow", "atrium-api", diff --git a/examples/sqlite/src/main.rs b/examples/sqlite/src/main.rs index 588b502..5f4374d 100644 --- a/examples/sqlite/src/main.rs +++ b/examples/sqlite/src/main.rs @@ -1,6 +1,7 @@ use log::{info, trace}; use rusqlite::{params, Connection}; use skyfeed::{Feed, FeedHandler, FeedResult, Post, Request, Uri}; +use std::env; use std::{sync::Arc, time::Duration}; use tokio::sync::Mutex; @@ -23,9 +24,23 @@ async fn main() { } }); - tokio::join!(feed.start("fr", ([0, 0, 0, 0], 3030)), cleanup_task) - .1 - .expect("Starting tasks failed"); + let publisher_did = env::var("PUBLISHER_DID").expect("PUBLISHER_DID env var not set"); + let feed_generator_hostname = + env::var("FEED_GENERATOR_HOSTNAME").expect("FEED_GENERATOR_HOSTNAME env var not set"); + + tokio::join!( + feed.start_with_config( + "fr", + Config { + publisher_did, + feed_generator_hostname + }, + ([0, 0, 0, 0], 3030) + ), + cleanup_task + ) + .1 + .expect("Starting tasks failed"); } struct MyFeed { diff --git a/src/lib.rs b/src/lib.rs index 04fa279..eae7bf3 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -5,6 +5,7 @@ mod models; mod public_api_test; mod utility_models; +pub use config::Config; pub use feed::Feed; pub use feed_handler::FeedHandler; pub use models::*; From 19b6e3c65b6ca888cb6f8fff0a42a8e822dc6d25 Mon Sep 17 00:00:00 2001 From: cyypherus Date: Mon, 17 Nov 2025 10:18:27 -0700 Subject: [PATCH 06/53] wip --- examples/sqlite/Cargo.lock | 2 +- examples/sqlite/railway.toml | 0 examples/sqlite/src/main.rs | 8 ++++---- 3 files changed, 5 insertions(+), 5 deletions(-) create mode 100644 examples/sqlite/railway.toml diff --git a/examples/sqlite/Cargo.lock b/examples/sqlite/Cargo.lock index 8e31246..b7719d1 100644 --- a/examples/sqlite/Cargo.lock +++ b/examples/sqlite/Cargo.lock @@ -2391,7 +2391,7 @@ checksum = "c1e9a774a6c28142ac54bb25d25562e6bcf957493a184f15ad4eebccb23e410a" [[package]] name = "skyfeed" version = "0.6.0" -source = "git+https://github.com/cyypherus/skyfeed.git?branch=french-feed#2e09079f040746eb3ddafa0670b8a04c6172e870" +source = "git+https://github.com/cyypherus/skyfeed.git?branch=french-feed#78c598806a91318dfe83161f809adb0ae2bde19d" dependencies = [ "anyhow", "atrium-api", diff --git a/examples/sqlite/railway.toml b/examples/sqlite/railway.toml new file mode 100644 index 0000000..e69de29 diff --git a/examples/sqlite/src/main.rs b/examples/sqlite/src/main.rs index 5f4374d..526ab85 100644 --- a/examples/sqlite/src/main.rs +++ b/examples/sqlite/src/main.rs @@ -1,13 +1,13 @@ -use log::{info, trace}; +use log::info; use rusqlite::{params, Connection}; -use skyfeed::{Feed, FeedHandler, FeedResult, Post, Request, Uri}; +use skyfeed::{Config, Feed, FeedHandler, FeedResult, Post, Request, Uri}; use std::env; use std::{sync::Arc, time::Duration}; use tokio::sync::Mutex; #[tokio::main] async fn main() { - let db = Connection::open("feed.db").expect("Failed to open database"); + let db = Connection::open("/space/feed.db").expect("Failed to open database"); initialize_db(&db); let db = Arc::new(Mutex::new(db)); @@ -195,7 +195,7 @@ async fn cleanup_posts(db: &Arc>) { ) .expect("Failed to clean up old posts"); - trace!("Cleaned up {cleaned_posts} posts"); + info!("Cleaned up {cleaned_posts} posts"); } fn initialize_db(db: &Connection) { From f0954d59449420411e8a133a920fabfc9efc3006 Mon Sep 17 00:00:00 2001 From: cyypherus Date: Mon, 17 Nov 2025 10:19:00 -0700 Subject: [PATCH 07/53] cleanup --- examples/sqlite/railway.toml | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 examples/sqlite/railway.toml diff --git a/examples/sqlite/railway.toml b/examples/sqlite/railway.toml deleted file mode 100644 index e69de29..0000000 From fcabc054aec929d20c22c55c8827f627e52a6973 Mon Sep 17 00:00:00 2001 From: cyypherus Date: Mon, 24 Nov 2025 20:07:59 -0800 Subject: [PATCH 08/53] wip --- Cargo.lock | 382 ++++++++++++++++++++++++++++++++++-------------- Cargo.toml | 8 +- src/feed.rs | 159 ++++---------------- src/firehose.rs | 284 +++++++++++++++++++++++++++++++++++ src/lib.rs | 1 + 5 files changed, 586 insertions(+), 248 deletions(-) create mode 100644 src/firehose.rs diff --git a/Cargo.lock b/Cargo.lock index b6a5a27..6805b5d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -139,6 +139,28 @@ dependencies = [ "pin-project-lite", ] +[[package]] +name = "async-stream" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b5a71a6f37880a80d1d7f19efd781e4b5de42c88f0722cc13bcb6cc2cfe8476" +dependencies = [ + "async-stream-impl", + "futures-core", + "pin-project-lite", +] + +[[package]] +name = "async-stream-impl" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7c24de15d275a1ecfd47a380fb4d5ec9bfe0933f309ed5e705b775596a3574d" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "async-trait" version = "0.1.88" @@ -192,6 +214,26 @@ dependencies = [ "web-time", ] +[[package]] +name = "atrium-repo" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "300aff863d16ad3aa1655b8586ae24fc492b338f822a7c2852a2241533832b4d" +dependencies = [ + "async-stream", + "atrium-api", + "futures", + "ipld-core", + "serde", + "serde_bytes", + "serde_ipld_dagcbor", + "sha2", + "thiserror 1.0.69", + "tokio", + "tokio-util", + "unsigned-varint", +] + [[package]] name = "atrium-xrpc" version = "0.12.3" @@ -222,6 +264,28 @@ version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" +[[package]] +name = "aws-lc-rs" +version = "1.15.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b5ce75405893cd713f9ab8e297d8e438f624dde7d706108285f7e17a25a180f" +dependencies = [ + "aws-lc-sys", + "zeroize", +] + +[[package]] +name = "aws-lc-sys" +version = "0.34.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "179c3777a8b5e70e90ea426114ffc565b2c1a9f82f6c4a0c5a34aa6ef5e781b6" +dependencies = [ + "cc", + "cmake", + "dunce", + "fs_extra", +] + [[package]] name = "backtrace" version = "0.3.74" @@ -331,12 +395,22 @@ dependencies = [ "thiserror 1.0.69", ] +[[package]] +name = "cbor4ii" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b544cf8c89359205f4f990d0e6f3828db42df85b5dac95d09157a250eb0749c4" +dependencies = [ + "serde", +] + [[package]] name = "cc" -version = "1.2.16" +version = "1.2.47" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be714c154be609ec7f5dad223a33bf1482fff90472de28f7362806e6d4832b8c" +checksum = "cd405d82c84ff7f35739f175f67d8b9fb7687a0e84ccdc78bd3568839827cf07" dependencies = [ + "find-msvc-tools", "jobserver", "libc", "shlex", @@ -417,6 +491,15 @@ version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f46ad14479a25103f283c0f10005961cf086d8dc42205bb44c46ac563475dca6" +[[package]] +name = "cmake" +version = "0.1.54" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7caa3f9de89ddbe2c607f4101924c5abec803763ae9534e4f4d7d8f84aa81f0" +dependencies = [ + "cc", +] + [[package]] name = "colorchoice" version = "1.0.3" @@ -454,6 +537,16 @@ dependencies = [ "libc", ] +[[package]] +name = "core-foundation" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2a6cd9ae233e7f62ba4e9353e81a88df7fc8a5987b8d445b4d90c879bd156f6" +dependencies = [ + "core-foundation-sys", + "libc", +] + [[package]] name = "core-foundation-sys" version = "0.8.7" @@ -588,6 +681,12 @@ version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "77c90badedccf4105eca100756a0b1289e191f6fcbdadd3cee1d2f614f97da8f" +[[package]] +name = "dunce" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813" + [[package]] name = "encode_unicode" version = "1.0.0" @@ -681,6 +780,12 @@ version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" +[[package]] +name = "find-msvc-tools" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a3076410a55c90011c298b04d0cfa770b00fa04e1e3c97d3f6c9de105a03844" + [[package]] name = "flate2" version = "1.1.0" @@ -691,18 +796,6 @@ dependencies = [ "miniz_oxide", ] -[[package]] -name = "flume" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da0e4dd2a88388a1f4ccc7c9ce104604dab68d9f408dc34cd45823d5a9069095" -dependencies = [ - "futures-core", - "futures-sink", - "nanorand", - "spin", -] - [[package]] name = "fnv" version = "1.0.7" @@ -739,6 +832,27 @@ dependencies = [ "percent-encoding", ] +[[package]] +name = "fs_extra" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42703706b716c37f96a77aea830392ad231f44c9e9a67872fa5548707e11b11c" + +[[package]] +name = "futures" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "65bc07b1a8bc7c85c5f2e110c476c7389b4554ba72af57d8445ea63a576b0876" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + [[package]] name = "futures-channel" version = "0.3.31" @@ -755,6 +869,23 @@ version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" +[[package]] +name = "futures-executor" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e28d1d997f585e54aebc3f97d39e72338912123a67330d723fdbb564d646c9f" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-io" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" + [[package]] name = "futures-macro" version = "0.3.31" @@ -784,10 +915,13 @@ version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" dependencies = [ + "futures-channel", "futures-core", + "futures-io", "futures-macro", "futures-sink", "futures-task", + "memchr", "pin-project-lite", "pin-utils", "slab", @@ -823,10 +957,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" dependencies = [ "cfg-if", - "js-sys", "libc", "wasi 0.11.0+wasi-snapshot-preview1", - "wasm-bindgen", ] [[package]] @@ -1329,27 +1461,6 @@ version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" -[[package]] -name = "jetstream-oxide" -version = "0.1.2" -source = "git+https://github.com/videah/jetstream-oxide?rev=7f21cfae9d8fe193ceb42fb04e511f45ac23764a#7f21cfae9d8fe193ceb42fb04e511f45ac23764a" -dependencies = [ - "async-trait", - "atrium-api", - "chrono", - "flume", - "futures-util", - "log", - "serde", - "serde_json", - "thiserror 2.0.12", - "tokio", - "tokio-tungstenite 0.24.0", - "tokio-util", - "url", - "zstd", -] - [[package]] name = "jiff" version = "0.2.4" @@ -1594,15 +1705,6 @@ dependencies = [ "unsigned-varint", ] -[[package]] -name = "nanorand" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a51313c5820b0b02bd422f4b44776fbf47961755c74ce64afc73bfad10226c3" -dependencies = [ - "getrandom 0.2.15", -] - [[package]] name = "native-tls" version = "0.2.14" @@ -1615,7 +1717,7 @@ dependencies = [ "openssl-probe", "openssl-sys", "schannel", - "security-framework", + "security-framework 2.11.1", "security-framework-sys", "tempfile", ] @@ -1686,15 +1788,6 @@ version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e" -[[package]] -name = "openssl-src" -version = "300.4.2+3.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "168ce4e058f975fe43e89d9ccf78ca668601887ae736090aacc23ae353c298e2" -dependencies = [ - "cc", -] - [[package]] name = "openssl-sys" version = "0.9.106" @@ -1703,7 +1796,6 @@ checksum = "8bb61ea9811cc39e3c2069f40b8b8e2e70d8569b361f879786cc7ed48b777cdd" dependencies = [ "cc", "libc", - "openssl-src", "pkg-config", "vcpkg", ] @@ -1849,8 +1941,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" dependencies = [ "libc", - "rand_chacha", - "rand_core", + "rand_chacha 0.3.1", + "rand_core 0.6.4", +] + +[[package]] +name = "rand" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1" +dependencies = [ + "rand_chacha 0.9.0", + "rand_core 0.9.3", ] [[package]] @@ -1860,7 +1962,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" dependencies = [ "ppv-lite86", - "rand_core", + "rand_core 0.6.4", +] + +[[package]] +name = "rand_chacha" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" +dependencies = [ + "ppv-lite86", + "rand_core 0.9.3", ] [[package]] @@ -1872,6 +1984,15 @@ dependencies = [ "getrandom 0.2.15", ] +[[package]] +name = "rand_core" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38" +dependencies = [ + "getrandom 0.3.1", +] + [[package]] name = "redox_syscall" version = "0.5.10" @@ -2052,10 +2173,12 @@ dependencies = [ [[package]] name = "rustls" -version = "0.23.23" +version = "0.23.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "47796c98c480fce5406ef69d1c76378375492c3b0a0de587be0c1d9feb12f395" +checksum = "533f54bc6a7d4f647e46ad909549eda97bf5afc1585190ef692b4286b198bd8f" dependencies = [ + "aws-lc-rs", + "log", "once_cell", "rustls-pki-types", "rustls-webpki", @@ -2063,6 +2186,18 @@ dependencies = [ "zeroize", ] +[[package]] +name = "rustls-native-certs" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9980d917ebb0c0536119ba501e90834767bffc3d60641457fd84a1f3fd337923" +dependencies = [ + "openssl-probe", + "rustls-pki-types", + "schannel", + "security-framework 3.3.0", +] + [[package]] name = "rustls-pemfile" version = "2.2.0" @@ -2074,16 +2209,20 @@ dependencies = [ [[package]] name = "rustls-pki-types" -version = "1.11.0" +version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "917ce264624a4b4db1c364dcc35bfca9ded014d0a958cd47ad3e960e988ea51c" +checksum = "94182ad936a0c91c324cd46c6511b9510ed16af436d7b5bab34beab0afd55f7a" +dependencies = [ + "zeroize", +] [[package]] name = "rustls-webpki" -version = "0.102.8" +version = "0.103.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64ca1bc8749bd4cf37b5ce386cc146580777b4e8572c7b97baf22c83f444bee9" +checksum = "2ffdfa2f5286e2247234e03f680868ac2815974dc39e00ea15adc445d0aafe52" dependencies = [ + "aws-lc-rs", "ring", "rustls-pki-types", "untrusted", @@ -2138,7 +2277,20 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" dependencies = [ "bitflags", - "core-foundation", + "core-foundation 0.9.4", + "core-foundation-sys", + "libc", + "security-framework-sys", +] + +[[package]] +name = "security-framework" +version = "3.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "80fb1d92c5028aa318b4b8bd7302a5bfcf48be96a37fc6fc790f806b0004ee0c" +dependencies = [ + "bitflags", + "core-foundation 0.10.1", "core-foundation-sys", "libc", "security-framework-sys", @@ -2205,6 +2357,18 @@ dependencies = [ "serde", ] +[[package]] +name = "serde_ipld_dagcbor" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46182f4f08349a02b45c998ba3215d3f9de826246ba02bb9dddfe9a2a2100778" +dependencies = [ + "cbor4ii", + "ipld-core", + "scopeguard", + "serde", +] + [[package]] name = "serde_json" version = "1.0.140" @@ -2249,6 +2413,17 @@ dependencies = [ "digest", ] +[[package]] +name = "sha2" +version = "0.10.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + [[package]] name = "sharded-slab" version = "0.1.7" @@ -2284,24 +2459,30 @@ name = "skyfeed" version = "0.6.0" dependencies = [ "anyhow", + "async-trait", "atrium-api", + "atrium-repo", "atrium-xrpc-client", "chrono", "clap", "dotenv", "env_logger", + "futures", "insta", - "jetstream-oxide", + "ipld-core", "log", "public-api", "regex", "reqwest", "rusqlite", "rustdoc-json", + "rustls", "rustup-toolchain", "serde", + "serde_ipld_dagcbor", "serde_json", "tokio", + "tokio-tungstenite 0.28.0", "warp", "whatlang", ] @@ -2336,9 +2517,6 @@ name = "spin" version = "0.9.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" -dependencies = [ - "lock_api", -] [[package]] name = "stable_deref_trait" @@ -2396,7 +2574,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3c879d448e9d986b661742763247d3693ed13609438cf3d006f51f5368a5ba6b" dependencies = [ "bitflags", - "core-foundation", + "core-foundation 0.9.4", "system-configuration-sys", ] @@ -2552,16 +2730,18 @@ dependencies = [ [[package]] name = "tokio-tungstenite" -version = "0.24.0" +version = "0.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edc5f74e248dc973e0dbb7b74c7e0d6fcc301c694ff50049504004ef4d0cdcd9" +checksum = "d25a406cddcc431a75d3d9afc6a7c0f7428d4891dd973e4d54c56b46127bf857" dependencies = [ "futures-util", "log", - "native-tls", + "rustls", + "rustls-native-certs", + "rustls-pki-types", "tokio", - "tokio-native-tls", - "tungstenite 0.24.0", + "tokio-rustls", + "tungstenite 0.28.0", ] [[package]] @@ -2572,6 +2752,7 @@ checksum = "6b9590b93e6fcc1739458317cccd391ad3955e2bde8913edf6f95f9e65a8f034" dependencies = [ "bytes", "futures-core", + "futures-io", "futures-sink", "pin-project-lite", "tokio", @@ -2730,7 +2911,7 @@ dependencies = [ "http 1.3.1", "httparse", "log", - "rand", + "rand 0.8.5", "sha1", "thiserror 1.0.69", "url", @@ -2739,21 +2920,20 @@ dependencies = [ [[package]] name = "tungstenite" -version = "0.24.0" +version = "0.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18e5b8366ee7a95b16d32197d0b2604b43a0be89dc5fac9f8e96ccafbaedda8a" +checksum = "8628dcc84e5a09eb3d8423d6cb682965dea9133204e8fb3efee74c2a0c259442" dependencies = [ - "byteorder", "bytes", "data-encoding", "http 1.3.1", "httparse", "log", - "native-tls", - "rand", + "rand 0.9.2", + "rustls", + "rustls-pki-types", "sha1", - "thiserror 1.0.69", - "url", + "thiserror 2.0.12", "utf-8", ] @@ -2780,6 +2960,10 @@ name = "unsigned-varint" version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eb066959b24b5196ae73cb057f45598450d2c5f71460e98c49b738086eff9c06" +dependencies = [ + "futures-io", + "futures-util", +] [[package]] name = "untrusted" @@ -3421,31 +3605,3 @@ dependencies = [ "quote", "syn", ] - -[[package]] -name = "zstd" -version = "0.13.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e91ee311a569c327171651566e07972200e76fcfe2242a4fa446149a3881c08a" -dependencies = [ - "zstd-safe", -] - -[[package]] -name = "zstd-safe" -version = "7.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3051792fbdc2e1e143244dc28c60f73d8470e93f3f9cbd0ead44da5ed802722" -dependencies = [ - "zstd-sys", -] - -[[package]] -name = "zstd-sys" -version = "2.0.14+zstd.1.5.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fb060d4926e4ac3a3ad15d864e99ceb5f343c6b34f5bd6d81ae6ed417311be5" -dependencies = [ - "cc", - "pkg-config", -] diff --git a/Cargo.toml b/Cargo.toml index cfb7fcb..632d947 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -39,13 +39,15 @@ required-features = ["examples"] [dependencies] atrium-api = "0.25.6" +atrium-repo = "0.1.6" dotenv = "0.15.0" env_logger = "0.11.5" -jetstream-oxide = { git = "https://github.com/videah/jetstream-oxide", rev = "7f21cfae9d8fe193ceb42fb04e511f45ac23764a" } log = "0.4.22" serde = "1.0.215" serde_json = "1.0.133" tokio = { version = "1.41.1", features = ["full"] } +tokio-tungstenite = { version = "0.28.0", features = ["rustls-tls-native-roots"] } +futures = "0.3.31" warp = "0.3.7" anyhow = "1.0.81" @@ -53,6 +55,8 @@ clap = { version = "4.5.3", features = ["derive"] } reqwest = "0.12.9" atrium-xrpc-client = "0.5.10" chrono = "0.4.39" +async-trait = "0.1.81" +ipld-core = "0.4.1" # `examples` feature dependencies rusqlite = { version = "0.33.0", features = ["bundled"], optional = true } @@ -64,3 +68,5 @@ insta = { version = "1.42.1", optional = true } public-api = { version = "0.43.0", optional = true } rustdoc-json = { version = "0.9.4", optional = true } rustup-toolchain = { version = "0.1.9", optional = true } +rustls = "0.23.35" +serde_ipld_dagcbor = "0.6.0" diff --git a/src/feed.rs b/src/feed.rs index b61663a..b2fbea0 100644 --- a/src/feed.rs +++ b/src/feed.rs @@ -4,27 +4,17 @@ use atrium_api::app::bsky::feed::describe_feed_generator::{ use atrium_api::app::bsky::feed::get_feed_skeleton::OutputData as FeedSkeleton; use atrium_api::app::bsky::feed::get_feed_skeleton::Parameters as FeedSkeletonQuery; use atrium_api::app::bsky::feed::get_feed_skeleton::ParametersData as FeedSkeletonParameters; -use atrium_api::record::KnownRecord; use atrium_api::types::Object; -use chrono::DateTime; use env_logger::Env; -use jetstream_oxide::exports::Nsid; -use jetstream_oxide::{ - events::{ - commit::{CommitData, CommitEvent, CommitInfo, CommitType}, - JetstreamEvent::Commit, - }, - DefaultJetstreamEndpoints, JetstreamCompression, JetstreamConfig, JetstreamConnector, -}; -use log::{error, info}; +use log::info; use std::fmt::Debug; use std::net::SocketAddr; use warp::Filter; -use crate::models::{Did, Embed, Label, Post, Request, Uri}; +use crate::models::Request; use crate::utility_models::{DidDocument, Service}; -use crate::Cid; use crate::{config::Config, feed_handler::FeedHandler}; +use crate::firehose::{FirehoseConnector, FirehoseEvent}; /// A `Feed` stores a `FeedHandler`, handles feed server endpoints & connects to the Firehose using the `start` methods. pub trait Feed { @@ -61,7 +51,7 @@ pub trait Feed { config: Config, address: impl Into + Debug + Clone + Send, ) -> impl std::future::Future + Send { - let mut handler = self.handler(); + let handler = self.handler(); let address = address.clone(); let feed_name = name.as_ref().to_string(); async move { @@ -118,131 +108,32 @@ pub trait Feed { } })); let feed_server = warp::serve(routes); - let firehose_listener = tokio::spawn(async move { - let jetstream = JetstreamConnector::new(JetstreamConfig { - endpoint: DefaultJetstreamEndpoints::USEastOne.into(), - wanted_collections: vec![ - Nsid::new("app.bsky.feed.post".to_string()).unwrap(), - Nsid::new("app.bsky.feed.like".to_string()).unwrap(), - ], - compression: JetstreamCompression::Zstd, - ..Default::default() - }) - .unwrap(); - let receiver = jetstream.connect().await.unwrap(); - while let Ok(event) = receiver - .recv_async() - .await - .inspect_err(|e| error!("Jetstream error: {}", e)) - { - if let Commit(commit) = event { - #[allow(clippy::collapsible_match)] - match commit { - CommitEvent::Create { - info, - commit: - CommitData { - info: - CommitInfo { - operation: CommitType::Create, - collection, - rkey, - .. - }, - cid, - record: KnownRecord::AppBskyFeedPost(record), - }, - } => { - #[allow(clippy::to_string_in_format_args)] - let uri = format!( - "at://{}/{}/{}", - info.did.to_string(), - collection.to_string(), - rkey - ); - - let Some(time) = - DateTime::from_timestamp_micros(info.time_us as i64) - else { - let time_us = info.time_us; - error!("Invalid post timestamp: {time_us}"); - continue; - }; - let post = Post { - author_did: Did(info.did.to_string()), - cid: Cid(serde_json::to_string(&cid).unwrap()), - uri: Uri(uri), - text: record.text.clone(), - labels: record - .labels - .as_ref() - .and_then(Label::from_atrium) - .unwrap_or_default(), - timestamp: time, - embed: record.embed.as_ref().and_then(Embed::from_atrium), - langs: record - .langs - .iter() - .filter_map(|lang| serde_json::to_string(&lang).ok()) - .collect(), - }; - handler.insert_post(post).await; - } - CommitEvent::Create { - info, - commit: - CommitData { - info: - CommitInfo { - operation: CommitType::Create, - collection, - rkey, - .. - }, - record: KnownRecord::AppBskyFeedLike(record), - .. - }, - } => { - #[allow(clippy::to_string_in_format_args)] - let uri = format!( - "at://{}/{}/{}", - info.did.to_string(), - collection.to_string(), - rkey - ); - handler - .like_post(Uri(uri), Uri(record.subject.uri.clone())) - .await; - } - CommitEvent::Delete { - info, - commit: - CommitInfo { - rkey, collection, .. - }, - } => { - #[allow(clippy::to_string_in_format_args)] - let uri = format!( - "at://{}/{}/{}", - info.did.to_string(), - collection.to_string(), - rkey - ); - if collection.to_string() == "app.bsky.feed.post" { - handler.delete_post(Uri(uri)).await; - } else if collection.to_string() == "app.bsky.feed.like" { - handler.delete_like(Uri(uri)).await; - } - } - _ => (), + + let (tx, mut rx) = tokio::sync::mpsc::channel(1000); + + let handler_clone = handler.clone(); + let event_handler = tokio::spawn(async move { + while let Some(event) = rx.recv().await { + let mut h = handler_clone.clone(); + match event { + FirehoseEvent::Post(post) => { + h.insert_post(post).await; + } + FirehoseEvent::DeletePost(uri) => { + h.delete_post(uri).await; } } } }); + + let firehose_listener = tokio::spawn(async move { + if let Err(e) = FirehoseConnector::run(tx).await { + log::error!("Firehose error: {}", e); + } + }); - tokio::join!(feed_server.run(address), firehose_listener) - .1 - .expect("Couldn't await tasks"); + let _ = tokio::join!(feed_server.run(address), firehose_listener, event_handler); + } } } diff --git a/src/firehose.rs b/src/firehose.rs new file mode 100644 index 0000000..b5d1148 --- /dev/null +++ b/src/firehose.rs @@ -0,0 +1,284 @@ +use anyhow::Result; +use atrium_api::types::string::RecordKey; +use atrium_api::types::Collection; +use futures::StreamExt; +use tokio::net::TcpStream; +use tokio::sync::mpsc; +use tokio_tungstenite::tungstenite::Message; +use tokio_tungstenite::{connect_async, MaybeTlsStream, WebSocketStream}; + +use atrium_api::app::bsky::feed; +use atrium_api::com::atproto::sync::subscribe_repos::{Commit, NSID}; +use atrium_repo::{blockstore::CarStore, Repository}; + +use crate::models::{Did, Embed, Label, Post, Uri}; +use crate::Cid; +use chrono::DateTime; + +mod frames { + use ipld_core::ipld::Ipld; + use std::io::Cursor; + + #[derive(Debug, Clone, PartialEq, Eq)] + enum FrameHeader { + Message(Option), + Error, + } + + impl TryFrom for FrameHeader { + type Error = anyhow::Error; + + fn try_from(value: Ipld) -> Result>::Error> { + if let Ipld::Map(map) = value { + if let Some(Ipld::Integer(i)) = map.get("op") { + match i { + 1 => { + let t = if let Some(Ipld::String(s)) = map.get("t") { + Some(s.clone()) + } else { + None + }; + return Ok(FrameHeader::Message(t)); + } + -1 => return Ok(FrameHeader::Error), + _ => {} + } + } + } + Err(anyhow::anyhow!("invalid frame type")) + } + } + + #[derive(Debug, Clone, PartialEq, Eq)] + pub enum Frame { + Message(Option, MessageFrame), + Error(ErrorFrame), + } + + #[derive(Debug, Clone, PartialEq, Eq)] + pub struct MessageFrame { + pub body: Vec, + } + + #[derive(Debug, Clone, PartialEq, Eq)] + pub struct ErrorFrame {} + + impl TryFrom<&[u8]> for Frame { + type Error = anyhow::Error; + + fn try_from(value: &[u8]) -> Result>::Error> { + let mut cursor = Cursor::new(value); + let (left, right) = match serde_ipld_dagcbor::from_reader::(&mut cursor) { + Err(serde_ipld_dagcbor::DecodeError::TrailingData) => { + value.split_at(cursor.position() as usize) + } + _ => { + return Err(anyhow::anyhow!("invalid frame type")); + } + }; + let header = FrameHeader::try_from(serde_ipld_dagcbor::from_slice::(left)?)?; + if let FrameHeader::Message(t) = &header { + Ok(Frame::Message( + t.clone(), + MessageFrame { + body: right.to_vec(), + }, + )) + } else { + Ok(Frame::Error(ErrorFrame {})) + } + } + } + + #[cfg(test)] + mod tests { + use super::*; + + fn serialized_data(s: &str) -> Vec { + assert!(s.len() % 2 == 0); + let b2u = |b: u8| match b { + b'0'..=b'9' => b - b'0', + b'a'..=b'f' => b - b'a' + 10, + _ => unreachable!(), + }; + s.as_bytes() + .chunks(2) + .map(|b| (b2u(b[0]) << 4) + b2u(b[1])) + .collect() + } + + #[test] + fn deserialize_message_frame_header() { + let data = serialized_data("a2626f700161746723636f6d6d6974"); + let ipld = + serde_ipld_dagcbor::from_slice::(&data).expect("failed to deserialize"); + let result = FrameHeader::try_from(ipld); + assert_eq!( + result.expect("failed to deserialize"), + FrameHeader::Message(Some(String::from("#commit"))) + ); + } + + #[test] + fn deserialize_error_frame_header() { + let data = serialized_data("a1626f7020"); + let ipld = + serde_ipld_dagcbor::from_slice::(&data).expect("failed to deserialize"); + let result = FrameHeader::try_from(ipld); + assert_eq!(result.expect("failed to deserialize"), FrameHeader::Error); + } + + #[test] + fn deserialize_invalid_frame_header() { + { + let data = serialized_data("a2626f700261746723636f6d6d6974"); + let ipld = + serde_ipld_dagcbor::from_slice::(&data).expect("failed to deserialize"); + let result = FrameHeader::try_from(ipld); + assert_eq!( + result.expect_err("must be failed").to_string(), + "invalid frame type" + ); + } + { + let data = serialized_data("a1626f7021"); + let ipld = + serde_ipld_dagcbor::from_slice::(&data).expect("failed to deserialize"); + let result = FrameHeader::try_from(ipld); + assert_eq!( + result.expect_err("must be failed").to_string(), + "invalid frame type" + ); + } + } + } +} + +use frames::Frame; + +pub enum FirehoseEvent { + Post(Post), + DeletePost(Uri), +} + +pub struct FirehoseConnector; + +impl FirehoseConnector { + pub async fn run(tx: mpsc::Sender) -> Result<(), Box> { + let _ = rustls::crypto::aws_lc_rs::default_provider().install_default(); + let (stream, _) = connect_async(format!("wss://bsky.network/xrpc/{NSID}")).await?; + let mut subscription = RepoSubscription { stream }; + + loop { + let message = match subscription.next().await { + Some(msg) => msg, + None => continue, + }; + + match message { + Ok(Frame::Message(Some(t), message)) => { + if t.as_str() == "#commit" { + match serde_ipld_dagcbor::from_reader(std::io::Cursor::new(message.body.as_slice())) { + Ok(commit) => { + if let Err(e) = Self::handle_commit(&commit, &tx).await { + log::error!("Failed to handle commit: {}", e); + } + } + Err(e) => { + log::error!("Failed to deserialize commit: {}", e); + } + } + } + } + Ok(Frame::Message(None, _msg)) => (), + Ok(Frame::Error(_e)) => { + println!("received error frame"); + break; + } + Err(e) => { + println!("error {e}"); + } + } + } + Ok(()) + } + + async fn handle_commit(commit: &Commit, tx: &mpsc::Sender) -> Result<()> { + let mut repo = Repository::open( + CarStore::open(std::io::Cursor::new(commit.blocks.as_slice())).await?, + commit.commit.0, + ) + .await?; + + for op in &commit.ops { + let mut s = op.path.split('/'); + let collection = s.next().expect("op.path is empty"); + let rkey = s.next().expect("no record key"); + + let action = op.action.as_str(); + + match (collection, action) { + (feed::Post::NSID, "create") => { + let rkey = RecordKey::new(rkey.to_string()).expect("invalid record key"); + if let Some(record) = repo.get::(rkey.clone()).await? { + let uri = format!( + "at://{}/{}/{}", + commit.repo.as_str(), + collection, + rkey.as_str() + ); + + let timestamp = DateTime::parse_from_rfc3339(record.created_at.as_str()) + .ok() + .map(|dt| dt.with_timezone(&chrono::Utc)) + .unwrap_or_else(|| chrono::Utc::now()); + + let post = Post { + author_did: Did(commit.repo.as_str().to_string()), + cid: Cid(serde_json::to_string(&op.cid).unwrap()), + uri: Uri(uri), + text: record.text.clone(), + labels: record + .labels + .as_ref() + .and_then(Label::from_atrium) + .unwrap_or_default(), + timestamp, + embed: record.embed.as_ref().and_then(Embed::from_atrium), + langs: record + .langs + .iter() + .filter_map(|lang| serde_json::to_string(&lang).ok()) + .collect(), + }; + let _ = tx.send(FirehoseEvent::Post(post)).await; + } + } + (feed::Post::NSID, "delete") => { + let rkey_str = rkey.to_string(); + let uri = format!("at://{}/{}/{}", commit.repo.as_str(), collection, rkey_str); + let _ = tx.send(FirehoseEvent::DeletePost(Uri(uri))).await; + } + _ => {} + } + } + Ok(()) + } +} + +struct RepoSubscription { + stream: WebSocketStream>, +} + +impl RepoSubscription { + async fn next(&mut self) -> Option> { + match self.stream.next().await { + Some(Ok(Message::Binary(data))) => { + let slice: &[u8] = &data; + Some(Frame::try_from(slice)) + } + Some(Ok(_)) | None => None, + Some(Err(e)) => Some(Err(anyhow::Error::new(e))), + } + } +} diff --git a/src/lib.rs b/src/lib.rs index eae7bf3..398e90b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,6 +1,7 @@ mod config; mod feed; mod feed_handler; +mod firehose; mod models; mod public_api_test; mod utility_models; From c4293a2e5b488cf24bc57a676f323f9f4ab33822 Mon Sep 17 00:00:00 2001 From: cyypherus Date: Mon, 24 Nov 2025 20:49:33 -0800 Subject: [PATCH 09/53] wip --- Cargo.lock | 7 --- Cargo.toml | 1 - src/firehose.rs | 140 +++++++++++++++++++++++++++++++++++++++++------- 3 files changed, 120 insertions(+), 28 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6805b5d..86a6282 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -109,12 +109,6 @@ dependencies = [ "windows-sys 0.59.0", ] -[[package]] -name = "anyhow" -version = "1.0.97" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcfed56ad506cb2c684a14971b8861fdc3baaaae314b9e5f9bb532cbe3ba7a4f" - [[package]] name = "async-compression" version = "0.4.21" @@ -2458,7 +2452,6 @@ checksum = "bbbb5d9659141646ae647b42fe094daf6c6192d1620870b449d9557f748b2daa" name = "skyfeed" version = "0.6.0" dependencies = [ - "anyhow", "async-trait", "atrium-api", "atrium-repo", diff --git a/Cargo.toml b/Cargo.toml index 632d947..c5db01e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -50,7 +50,6 @@ tokio-tungstenite = { version = "0.28.0", features = ["rustls-tls-native-roots"] futures = "0.3.31" warp = "0.3.7" -anyhow = "1.0.81" clap = { version = "4.5.3", features = ["derive"] } reqwest = "0.12.9" atrium-xrpc-client = "0.5.10" diff --git a/src/firehose.rs b/src/firehose.rs index b5d1148..6012914 100644 --- a/src/firehose.rs +++ b/src/firehose.rs @@ -1,4 +1,3 @@ -use anyhow::Result; use atrium_api::types::string::RecordKey; use atrium_api::types::Collection; use futures::StreamExt; @@ -7,7 +6,7 @@ use tokio::sync::mpsc; use tokio_tungstenite::tungstenite::Message; use tokio_tungstenite::{connect_async, MaybeTlsStream, WebSocketStream}; -use atrium_api::app::bsky::feed; +use atrium_api::app::bsky::feed::{self, Like}; use atrium_api::com::atproto::sync::subscribe_repos::{Commit, NSID}; use atrium_repo::{blockstore::CarStore, Repository}; @@ -19,6 +18,23 @@ mod frames { use ipld_core::ipld::Ipld; use std::io::Cursor; + #[derive(Debug, Clone, PartialEq, Eq)] + pub enum FrameError { + InvalidFrameType, + DecodeError, + } + + impl std::fmt::Display for FrameError { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + FrameError::InvalidFrameType => write!(f, "invalid frame type"), + FrameError::DecodeError => write!(f, "decode error"), + } + } + } + + impl std::error::Error for FrameError {} + #[derive(Debug, Clone, PartialEq, Eq)] enum FrameHeader { Message(Option), @@ -26,7 +42,7 @@ mod frames { } impl TryFrom for FrameHeader { - type Error = anyhow::Error; + type Error = FrameError; fn try_from(value: Ipld) -> Result>::Error> { if let Ipld::Map(map) = value { @@ -45,7 +61,7 @@ mod frames { } } } - Err(anyhow::anyhow!("invalid frame type")) + Err(FrameError::InvalidFrameType) } } @@ -64,7 +80,7 @@ mod frames { pub struct ErrorFrame {} impl TryFrom<&[u8]> for Frame { - type Error = anyhow::Error; + type Error = FrameError; fn try_from(value: &[u8]) -> Result>::Error> { let mut cursor = Cursor::new(value); @@ -73,10 +89,13 @@ mod frames { value.split_at(cursor.position() as usize) } _ => { - return Err(anyhow::anyhow!("invalid frame type")); + return Err(FrameError::InvalidFrameType); } }; - let header = FrameHeader::try_from(serde_ipld_dagcbor::from_slice::(left)?)?; + let header = FrameHeader::try_from( + serde_ipld_dagcbor::from_slice::(left) + .map_err(|_| FrameError::DecodeError)?, + )?; if let FrameHeader::Message(t) = &header { Ok(Frame::Message( t.clone(), @@ -136,8 +155,8 @@ mod frames { serde_ipld_dagcbor::from_slice::(&data).expect("failed to deserialize"); let result = FrameHeader::try_from(ipld); assert_eq!( - result.expect_err("must be failed").to_string(), - "invalid frame type" + result.expect_err("must be failed"), + FrameError::InvalidFrameType ); } { @@ -146,8 +165,8 @@ mod frames { serde_ipld_dagcbor::from_slice::(&data).expect("failed to deserialize"); let result = FrameHeader::try_from(ipld); assert_eq!( - result.expect_err("must be failed").to_string(), - "invalid frame type" + result.expect_err("must be failed"), + FrameError::InvalidFrameType ); } } @@ -156,15 +175,58 @@ mod frames { use frames::Frame; +#[derive(Debug)] +pub enum FirehoseError { + Frame(frames::FrameError), + WebSocket(tokio_tungstenite::tungstenite::Error), + Io(std::io::Error), + CarStore(String), + Repository(String), +} + +impl std::fmt::Display for FirehoseError { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + FirehoseError::Frame(e) => write!(f, "frame error: {}", e), + FirehoseError::WebSocket(e) => write!(f, "websocket error: {}", e), + FirehoseError::Io(e) => write!(f, "io error: {}", e), + FirehoseError::CarStore(msg) => write!(f, "car store error: {}", msg), + FirehoseError::Repository(msg) => write!(f, "repository error: {}", msg), + } + } +} + +impl std::error::Error for FirehoseError {} + +impl From for FirehoseError { + fn from(e: frames::FrameError) -> Self { + FirehoseError::Frame(e) + } +} + +impl From for FirehoseError { + fn from(e: tokio_tungstenite::tungstenite::Error) -> Self { + FirehoseError::WebSocket(e) + } +} + +impl From for FirehoseError { + fn from(e: std::io::Error) -> Self { + FirehoseError::Io(e) + } +} + pub enum FirehoseEvent { Post(Post), DeletePost(Uri), + Like(Uri, Uri), + DeleteLike(Uri), } pub struct FirehoseConnector; impl FirehoseConnector { - pub async fn run(tx: mpsc::Sender) -> Result<(), Box> { + pub async fn run(tx: mpsc::Sender) -> Result<(), FirehoseError> { let _ = rustls::crypto::aws_lc_rs::default_provider().install_default(); let (stream, _) = connect_async(format!("wss://bsky.network/xrpc/{NSID}")).await?; let mut subscription = RepoSubscription { stream }; @@ -178,7 +240,9 @@ impl FirehoseConnector { match message { Ok(Frame::Message(Some(t), message)) => { if t.as_str() == "#commit" { - match serde_ipld_dagcbor::from_reader(std::io::Cursor::new(message.body.as_slice())) { + match serde_ipld_dagcbor::from_reader(std::io::Cursor::new( + message.body.as_slice(), + )) { Ok(commit) => { if let Err(e) = Self::handle_commit(&commit, &tx).await { log::error!("Failed to handle commit: {}", e); @@ -203,12 +267,18 @@ impl FirehoseConnector { Ok(()) } - async fn handle_commit(commit: &Commit, tx: &mpsc::Sender) -> Result<()> { + async fn handle_commit( + commit: &Commit, + tx: &mpsc::Sender, + ) -> Result<(), FirehoseError> { let mut repo = Repository::open( - CarStore::open(std::io::Cursor::new(commit.blocks.as_slice())).await?, + CarStore::open(std::io::Cursor::new(commit.blocks.as_slice())) + .await + .map_err(|e| FirehoseError::CarStore(e.to_string()))?, commit.commit.0, ) - .await?; + .await + .map_err(|e| FirehoseError::Repository(e.to_string()))?; for op in &commit.ops { let mut s = op.path.split('/'); @@ -220,7 +290,11 @@ impl FirehoseConnector { match (collection, action) { (feed::Post::NSID, "create") => { let rkey = RecordKey::new(rkey.to_string()).expect("invalid record key"); - if let Some(record) = repo.get::(rkey.clone()).await? { + if let Some(record) = repo + .get::(rkey.clone()) + .await + .map_err(|e| FirehoseError::Repository(e.to_string()))? + { let uri = format!( "at://{}/{}/{}", commit.repo.as_str(), @@ -259,6 +333,32 @@ impl FirehoseConnector { let uri = format!("at://{}/{}/{}", commit.repo.as_str(), collection, rkey_str); let _ = tx.send(FirehoseEvent::DeletePost(Uri(uri))).await; } + (Like::NSID, "create") => { + let rkey = RecordKey::new(rkey.to_string()).expect("invalid record key"); + if let Some(record) = repo + .get::(rkey.clone()) + .await + .map_err(|e| FirehoseError::Repository(e.to_string()))? + { + let uri = format!( + "at://{}/{}/{}", + commit.repo.as_str(), + collection, + rkey.as_str() + ); + let _ = tx + .send(FirehoseEvent::Like( + Uri(uri), + Uri(record.subject.uri.clone()), + )) + .await; + } + } + (Like::NSID, "delete") => { + let rkey_str = rkey.to_string(); + let uri = format!("at://{}/{}/{}", commit.repo.as_str(), collection, rkey_str); + let _ = tx.send(FirehoseEvent::DeleteLike(Uri(uri))).await; + } _ => {} } } @@ -271,14 +371,14 @@ struct RepoSubscription { } impl RepoSubscription { - async fn next(&mut self) -> Option> { + async fn next(&mut self) -> Option> { match self.stream.next().await { Some(Ok(Message::Binary(data))) => { let slice: &[u8] = &data; - Some(Frame::try_from(slice)) + Some(Frame::try_from(slice).map_err(FirehoseError::from)) } Some(Ok(_)) | None => None, - Some(Err(e)) => Some(Err(anyhow::Error::new(e))), + Some(Err(e)) => Some(Err(FirehoseError::from(e))), } } } From 330df363ace49ac474e02177443500971aa30fd0 Mon Sep 17 00:00:00 2001 From: cyypherus Date: Mon, 24 Nov 2025 23:52:49 -0800 Subject: [PATCH 10/53] wip --- Cargo.lock | 433 ++++++++++++++++++++++++++++++++++--- Cargo.toml | 2 + examples/basic/Cargo.lock | 7 + examples/basic/src/main.rs | 6 +- src/feed.rs | 6 + src/firehose.rs | 158 +++++++------- 6 files changed, 500 insertions(+), 112 deletions(-) create mode 100644 examples/basic/Cargo.lock diff --git a/Cargo.lock b/Cargo.lock index 86a6282..1b63cb5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -109,6 +109,24 @@ dependencies = [ "windows-sys 0.59.0", ] +[[package]] +name = "anyhow" +version = "1.0.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a23eb6b1614318a8071c9b2521f36b424b2c83db5eb3a0fead4a6c0809af6e61" + +[[package]] +name = "arrayref" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76a2e8124351fda1ef8aaaa3bbd7ebbcb486bbcd4225aca0aa0d84bb2db8fecb" + +[[package]] +name = "arrayvec" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" + [[package]] name = "async-compression" version = "0.4.21" @@ -152,7 +170,7 @@ checksum = "c7c24de15d275a1ecfd47a380fb4d5ec9bfe0933f309ed5e705b775596a3574d" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.100", ] [[package]] @@ -163,7 +181,7 @@ checksum = "e539d3fca749fcee5236ab05e93a52867dd549cc157c8cb7f99595f3cedffdb5" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.100", ] [[package]] @@ -225,7 +243,7 @@ dependencies = [ "thiserror 1.0.69", "tokio", "tokio-util", - "unsigned-varint", + "unsigned-varint 0.8.0", ] [[package]] @@ -319,6 +337,41 @@ version = "2.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5c8214115b7bf84099f1309324e63141d4c5d7cc26862f97a0a857dbefe165bd" +[[package]] +name = "blake2b_simd" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06e903a20b159e944f91ec8499fe1e55651480c541ea0a584f5d967c49ad9d99" +dependencies = [ + "arrayref", + "arrayvec", + "constant_time_eq", +] + +[[package]] +name = "blake2s_simd" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e90f7deecfac93095eb874a40febd69427776e24e1bd7f87f33ac62d6f0174df" +dependencies = [ + "arrayref", + "arrayvec", + "constant_time_eq", +] + +[[package]] +name = "blake3" +version = "1.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3888aaa89e4b2a40fca9848e400f6a658a5a3978de7be858e209cafa8be9a4a0" +dependencies = [ + "arrayref", + "arrayvec", + "cc", + "cfg-if", + "constant_time_eq", +] + [[package]] name = "block-buffer" version = "0.10.4" @@ -363,7 +416,7 @@ checksum = "8b2ce2075c35e4b492b93e3d5dd1dd3670de553f15045595daef8164ed9a3751" dependencies = [ "serde", "thiserror 1.0.69", - "toml", + "toml 0.8.20", ] [[package]] @@ -431,6 +484,19 @@ dependencies = [ "windows-link", ] +[[package]] +name = "cid" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd94671561e36e4e7de75f753f577edafb0e7c05d6e4547229fdf7938fbcd2c3" +dependencies = [ + "core2", + "multibase", + "multihash 0.18.1", + "serde", + "unsigned-varint 0.7.2", +] + [[package]] name = "cid" version = "0.11.1" @@ -439,10 +505,10 @@ checksum = "3147d8272e8fa0ccd29ce51194dd98f79ddfb8191ba9e3409884e751798acf3a" dependencies = [ "core2", "multibase", - "multihash", + "multihash 0.19.3", "serde", "serde_bytes", - "unsigned-varint", + "unsigned-varint 0.8.0", ] [[package]] @@ -476,7 +542,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn", + "syn 2.0.100", ] [[package]] @@ -521,6 +587,12 @@ dependencies = [ "windows-sys 0.59.0", ] +[[package]] +name = "constant_time_eq" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c74b8349d32d297c9134b8c88677813a227df8f779daa29bfc29c183fe3dca6" + [[package]] name = "core-foundation" version = "0.9.4" @@ -645,7 +717,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "18e4fdb82bd54a12e42fb58a800dcae6b9e13982238ce2296dc3570b92148e1f" dependencies = [ "data-encoding", - "syn", + "syn 2.0.100", ] [[package]] @@ -666,7 +738,7 @@ checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.100", ] [[package]] @@ -756,6 +828,28 @@ dependencies = [ "pin-project-lite", ] +[[package]] +name = "failure" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d32e9bd16cc02eae7db7ef620b392808b89f6a5e16bb3497d159c6b92a0f4f86" +dependencies = [ + "backtrace", + "failure_derive", +] + +[[package]] +name = "failure_derive" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa4da3c766cd7a0db8242e326e9e4e081edd567072893ed320008189715366a4" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", + "synstructure 0.12.6", +] + [[package]] name = "fallible-iterator" version = "0.3.0" @@ -888,7 +982,7 @@ checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.100", ] [[package]] @@ -1077,6 +1171,12 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + [[package]] name = "http" version = "0.2.12" @@ -1379,7 +1479,7 @@ checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.100", ] [[package]] @@ -1432,7 +1532,7 @@ version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "104718b1cc124d92a6d01ca9c9258a7df311405debb3408c445a36452f9bf8db" dependencies = [ - "cid", + "cid 0.11.1", "serde", "serde_bytes", ] @@ -1476,7 +1576,7 @@ checksum = "8d16e75759ee0aa64c57a56acbf43916987b20c77373cb7e808979e02b93c9f9" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.100", ] [[package]] @@ -1498,6 +1598,15 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "keccak" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ecc2af9a1119c51f12a14607e783cb977bde58bc069ff0c3da1095e635d70654" +dependencies = [ + "cpufeatures", +] + [[package]] name = "langtag" version = "0.3.4" @@ -1519,6 +1628,95 @@ version = "0.2.171" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c19937216e9d3aa9956d9bb8dfc0b0c8beb6058fc4f7a4dc4d850edf86a237d6" +[[package]] +name = "libipld" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1ccd6b8ffb3afee7081fcaec00e1b099fd1c7ccf35ba5729d88538fcc3b4599" +dependencies = [ + "fnv", + "libipld-cbor", + "libipld-cbor-derive", + "libipld-core", + "libipld-json", + "libipld-macro", + "libipld-pb", + "log", + "multihash 0.18.1", + "thiserror 1.0.69", +] + +[[package]] +name = "libipld-cbor" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77d98c9d1747aa5eef1cf099cd648c3fd2d235249f5fed07522aaebc348e423b" +dependencies = [ + "byteorder", + "libipld-core", + "thiserror 1.0.69", +] + +[[package]] +name = "libipld-cbor-derive" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d5ba3a729b72973e456a1812b0afe2e176a376c1836cc1528e9fc98ae8cb838" +dependencies = [ + "proc-macro-crate", + "proc-macro2", + "quote", + "syn 1.0.109", + "synstructure 0.12.6", +] + +[[package]] +name = "libipld-core" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5acd707e8d8b092e967b2af978ed84709eaded82b75effe6cb6f6cc797ef8158" +dependencies = [ + "anyhow", + "cid 0.10.1", + "core2", + "multibase", + "multihash 0.18.1", + "thiserror 1.0.69", +] + +[[package]] +name = "libipld-json" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25856def940047b07b25c33d4e66d248597049ab0202085215dc4dca0487731c" +dependencies = [ + "libipld-core", + "multihash 0.18.1", + "serde", + "serde_json", +] + +[[package]] +name = "libipld-macro" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "71171c54214f866ae6722f3027f81dff0931e600e5a61e6b1b6a49ca0b5ed4ae" +dependencies = [ + "libipld-core", +] + +[[package]] +name = "libipld-pb" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3f2d0f866c4cd5dc9aa8068c429ba478d2882a3a4b70ab56f7e9a0eddf5d16f" +dependencies = [ + "bytes", + "libipld-core", + "quick-protobuf", + "thiserror 1.0.69", +] + [[package]] name = "libsqlite3-sys" version = "0.31.0" @@ -1688,6 +1886,34 @@ dependencies = [ "data-encoding-macro", ] +[[package]] +name = "multicodec" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f287a558ce2cac6f63944876d2f76ae2254a17fbe174c82967e76e0aab3379ed" +dependencies = [ + "failure", + "serde", + "unsigned-varint 0.2.3", +] + +[[package]] +name = "multihash" +version = "0.18.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfd8a792c1694c6da4f68db0a9d707c72bd260994da179e6030a5dcee00bb815" +dependencies = [ + "blake2b_simd", + "blake2s_simd", + "blake3", + "core2", + "digest", + "multihash-derive", + "sha2", + "sha3", + "unsigned-varint 0.7.2", +] + [[package]] name = "multihash" version = "0.19.3" @@ -1696,7 +1922,21 @@ checksum = "6b430e7953c29dd6a09afc29ff0bb69c6e306329ee6794700aee27b76a1aea8d" dependencies = [ "core2", "serde", - "unsigned-varint", + "unsigned-varint 0.8.0", +] + +[[package]] +name = "multihash-derive" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d6d4752e6230d8ef7adf7bd5d8c4b1f6561c1014c5ba9a37445ccefe18aa1db" +dependencies = [ + "proc-macro-crate", + "proc-macro-error", + "proc-macro2", + "quote", + "syn 1.0.109", + "synstructure 0.12.6", ] [[package]] @@ -1773,7 +2013,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.100", ] [[package]] @@ -1852,7 +2092,7 @@ checksum = "6e918e4ff8c4549eb882f14b3a4bc8c8bc93de829416eacf579f1207a8fbf861" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.100", ] [[package]] @@ -1897,6 +2137,40 @@ dependencies = [ "zerocopy 0.8.23", ] +[[package]] +name = "proc-macro-crate" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e17d47ce914bf4de440332250b0edd23ce48c005f59fab39d3335866b114f11a" +dependencies = [ + "thiserror 1.0.69", + "toml 0.5.11", +] + +[[package]] +name = "proc-macro-error" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" +dependencies = [ + "proc-macro-error-attr", + "proc-macro2", + "quote", + "syn 1.0.109", + "version_check", +] + +[[package]] +name = "proc-macro-error-attr" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" +dependencies = [ + "proc-macro2", + "quote", + "version_check", +] + [[package]] name = "proc-macro2" version = "1.0.94" @@ -1919,6 +2193,15 @@ dependencies = [ "thiserror 2.0.12", ] +[[package]] +name = "quick-protobuf" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d6da84cc204722a989e01ba2f6e1e276e190f22263d0cb6ce8526fcdb0d2e1f" +dependencies = [ + "byteorder", +] + [[package]] name = "quote" version = "1.0.40" @@ -2100,6 +2383,24 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "rs-car" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "732df95a8f40f7623f7d54eac1e11626d86fd970f7542738d64c30d0d7ff0068" +dependencies = [ + "blake2b_simd", + "cid 0.10.1", + "futures", + "hex", + "libipld", + "libipld-cbor", + "multibase", + "multicodec", + "multihash 0.18.1", + "sha2", +] + [[package]] name = "rusqlite" version = "0.33.0" @@ -2139,7 +2440,7 @@ dependencies = [ "cargo_metadata", "serde", "thiserror 2.0.12", - "toml", + "toml 0.8.20", "tracing", ] @@ -2335,7 +2636,7 @@ checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.100", ] [[package]] @@ -2418,6 +2719,16 @@ dependencies = [ "digest", ] +[[package]] +name = "sha3" +version = "0.10.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75872d278a8f37ef87fa0ddbda7802605cb18344497949862c0d4dcb291eba60" +dependencies = [ + "digest", + "keccak", +] + [[package]] name = "sharded-slab" version = "0.1.7" @@ -2452,6 +2763,7 @@ checksum = "bbbb5d9659141646ae647b42fe094daf6c6192d1620870b449d9557f748b2daa" name = "skyfeed" version = "0.6.0" dependencies = [ + "anyhow", "async-trait", "atrium-api", "atrium-repo", @@ -2467,6 +2779,7 @@ dependencies = [ "public-api", "regex", "reqwest", + "rs-car", "rusqlite", "rustdoc-json", "rustls", @@ -2529,6 +2842,17 @@ version = "2.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + [[package]] name = "syn" version = "2.0.100" @@ -2549,6 +2873,18 @@ dependencies = [ "futures-core", ] +[[package]] +name = "synstructure" +version = "0.12.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f36bdaa60a83aca3921b5259d5400cbf5e90fc51931376a9bd4a0eb79aa7210f" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", + "unicode-xid", +] + [[package]] name = "synstructure" version = "0.13.1" @@ -2557,7 +2893,7 @@ checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.100", ] [[package]] @@ -2626,7 +2962,7 @@ checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.100", ] [[package]] @@ -2637,7 +2973,7 @@ checksum = "7f7cf42b4507d8ea322120659672cf1b9dbb93f8f2d4ecfd6e51350ff5b17a1d" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.100", ] [[package]] @@ -2686,7 +3022,7 @@ checksum = "6e06d43f1345a3bcd39f6a56dbb7dcab2ba47e68e8ac134855e7e2bdbaf8cab8" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.100", ] [[package]] @@ -2751,6 +3087,15 @@ dependencies = [ "tokio", ] +[[package]] +name = "toml" +version = "0.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4f7f0dd8d50a853a531c426359045b1998f04219d88799810762cd4ad314234" +dependencies = [ + "serde", +] + [[package]] name = "toml" version = "0.8.20" @@ -2833,7 +3178,7 @@ checksum = "395ae124c09f9e6918a2310af6038fba074bcf474ac352496d5910dd59a2226d" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.100", ] [[package]] @@ -2883,7 +3228,7 @@ checksum = "70977707304198400eb4835a78f6a9f928bf41bba420deb8fdb175cd965d77a7" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.100", ] [[package]] @@ -2948,6 +3293,24 @@ version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" +[[package]] +name = "unicode-xid" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" + +[[package]] +name = "unsigned-varint" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7f0023a96687fe169081e8adce3f65e3874426b7886e9234d490af2dc077959" + +[[package]] +name = "unsigned-varint" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6889a77d49f1f013504cec6bf97a2c730394adedaeb1deb5ea08949a50541105" + [[package]] name = "unsigned-varint" version = "0.8.0" @@ -3101,7 +3464,7 @@ dependencies = [ "log", "proc-macro2", "quote", - "syn", + "syn 2.0.100", "wasm-bindgen-shared", ] @@ -3136,7 +3499,7 @@ checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.100", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -3242,7 +3605,7 @@ checksum = "2bbd5b46c938e506ecbce286b6628a02171d56153ba733b6c741fc627ec9579b" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.100", ] [[package]] @@ -3253,7 +3616,7 @@ checksum = "053c4c462dc91d3b1504c6fe5a726dd15e216ba718e84a0e46a88fbe5ded3515" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.100", ] [[package]] @@ -3506,8 +3869,8 @@ checksum = "2380878cad4ac9aac1e2435f3eb4020e8374b5f13c296cb75b4620ff8e229154" dependencies = [ "proc-macro2", "quote", - "syn", - "synstructure", + "syn 2.0.100", + "synstructure 0.13.1", ] [[package]] @@ -3536,7 +3899,7 @@ checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.100", ] [[package]] @@ -3547,7 +3910,7 @@ checksum = "6352c01d0edd5db859a63e2605f4ea3183ddbd15e2c4a9e7d32184df75e4f154" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.100", ] [[package]] @@ -3567,8 +3930,8 @@ checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502" dependencies = [ "proc-macro2", "quote", - "syn", - "synstructure", + "syn 2.0.100", + "synstructure 0.13.1", ] [[package]] @@ -3596,5 +3959,5 @@ checksum = "6eafa6dfb17584ea3e2bd6e76e0cc15ad7af12b09abdd1ca55961bed9b1063c6" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.100", ] diff --git a/Cargo.toml b/Cargo.toml index c5db01e..631b090 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -51,6 +51,7 @@ futures = "0.3.31" warp = "0.3.7" clap = { version = "4.5.3", features = ["derive"] } +anyhow = "1.0.81" reqwest = "0.12.9" atrium-xrpc-client = "0.5.10" chrono = "0.4.39" @@ -69,3 +70,4 @@ rustdoc-json = { version = "0.9.4", optional = true } rustup-toolchain = { version = "0.1.9", optional = true } rustls = "0.23.35" serde_ipld_dagcbor = "0.6.0" +rs-car = "0.1" diff --git a/examples/basic/Cargo.lock b/examples/basic/Cargo.lock new file mode 100644 index 0000000..ba41654 --- /dev/null +++ b/examples/basic/Cargo.lock @@ -0,0 +1,7 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "basic" +version = "0.1.0" diff --git a/examples/basic/src/main.rs b/examples/basic/src/main.rs index 1689fca..41379a2 100644 --- a/examples/basic/src/main.rs +++ b/examples/basic/src/main.rs @@ -36,8 +36,8 @@ struct MyPost { impl FeedHandler for MyFeedHandler { async fn insert_post(&mut self, post: Post) { + println!("📝 POST: {}", post.text); if post.text.to_lowercase().contains(" cat ") { - info!("Storing {post:?}"); const MAX_POSTS: usize = 100; let mut posts = self.posts.lock().await; @@ -54,6 +54,7 @@ impl FeedHandler for MyFeedHandler { } async fn delete_post(&mut self, uri: Uri) { + println!("🗑️ DELETE POST: {}", uri.0); self.posts .lock() .await @@ -61,6 +62,7 @@ impl FeedHandler for MyFeedHandler { } async fn like_post(&mut self, like_uri: Uri, liked_post_uri: Uri) { + // println!("❤️ LIKE: {} likes {}", like_uri.0, liked_post_uri.0); if let Some(post_with_likes) = self .posts .lock() @@ -69,10 +71,12 @@ impl FeedHandler for MyFeedHandler { .find(|p| p.post.uri == liked_post_uri) { post_with_likes.likes.insert(like_uri); + dbg!(post_with_likes.likes.len()); } } async fn delete_like(&mut self, like_uri: Uri) { + println!("💔 DELETE LIKE: {}", like_uri.0); let mut posts = self.posts.lock().await; for post_with_likes in posts.iter_mut() { post_with_likes.likes.remove(&like_uri); diff --git a/src/feed.rs b/src/feed.rs index b2fbea0..198baf7 100644 --- a/src/feed.rs +++ b/src/feed.rs @@ -122,6 +122,12 @@ pub trait Feed { FirehoseEvent::DeletePost(uri) => { h.delete_post(uri).await; } + FirehoseEvent::Like(like_uri, post_uri) => { + h.like_post(post_uri, like_uri).await; + } + FirehoseEvent::DeleteLike(uri) => { + h.delete_like(uri).await; + } } } }); diff --git a/src/firehose.rs b/src/firehose.rs index 6012914..aa160f3 100644 --- a/src/firehose.rs +++ b/src/firehose.rs @@ -1,4 +1,3 @@ -use atrium_api::types::string::RecordKey; use atrium_api::types::Collection; use futures::StreamExt; use tokio::net::TcpStream; @@ -8,7 +7,7 @@ use tokio_tungstenite::{connect_async, MaybeTlsStream, WebSocketStream}; use atrium_api::app::bsky::feed::{self, Like}; use atrium_api::com::atproto::sync::subscribe_repos::{Commit, NSID}; -use atrium_repo::{blockstore::CarStore, Repository}; +use atrium_api::types::CidLink; use crate::models::{Did, Embed, Label, Post, Uri}; use crate::Cid; @@ -181,7 +180,6 @@ pub enum FirehoseError { WebSocket(tokio_tungstenite::tungstenite::Error), Io(std::io::Error), CarStore(String), - Repository(String), } impl std::fmt::Display for FirehoseError { @@ -191,7 +189,6 @@ impl std::fmt::Display for FirehoseError { FirehoseError::WebSocket(e) => write!(f, "websocket error: {}", e), FirehoseError::Io(e) => write!(f, "io error: {}", e), FirehoseError::CarStore(msg) => write!(f, "car store error: {}", msg), - FirehoseError::Repository(msg) => write!(f, "repository error: {}", msg), } } } @@ -231,12 +228,7 @@ impl FirehoseConnector { let (stream, _) = connect_async(format!("wss://bsky.network/xrpc/{NSID}")).await?; let mut subscription = RepoSubscription { stream }; - loop { - let message = match subscription.next().await { - Some(msg) => msg, - None => continue, - }; - + while let Some(message) = subscription.next().await { match message { Ok(Frame::Message(Some(t), message)) => { if t.as_str() == "#commit" { @@ -271,92 +263,106 @@ impl FirehoseConnector { commit: &Commit, tx: &mpsc::Sender, ) -> Result<(), FirehoseError> { - let mut repo = Repository::open( - CarStore::open(std::io::Cursor::new(commit.blocks.as_slice())) - .await - .map_err(|e| FirehoseError::CarStore(e.to_string()))?, - commit.commit.0, - ) - .await - .map_err(|e| FirehoseError::Repository(e.to_string()))?; + let mut blocks = commit.blocks.as_slice(); + let (items, _) = rs_car::car_read_all(&mut blocks, true) + .await + .map_err(|e| FirehoseError::CarStore(e.to_string()))?; for op in &commit.ops { let mut s = op.path.split('/'); let collection = s.next().expect("op.path is empty"); let rkey = s.next().expect("no record key"); - let action = op.action.as_str(); match (collection, action) { (feed::Post::NSID, "create") => { - let rkey = RecordKey::new(rkey.to_string()).expect("invalid record key"); - if let Some(record) = repo - .get::(rkey.clone()) - .await - .map_err(|e| FirehoseError::Repository(e.to_string()))? - { - let uri = format!( - "at://{}/{}/{}", - commit.repo.as_str(), - collection, - rkey.as_str() + if let Some((_, item_data)) = items.iter().find(|(cid, _)| { + let converted_cid = CidLink( + cid.to_string() + .parse() + .unwrap_or_else(|_| panic!("invalid CID: {}", cid)), ); - - let timestamp = DateTime::parse_from_rfc3339(record.created_at.as_str()) - .ok() - .map(|dt| dt.with_timezone(&chrono::Utc)) - .unwrap_or_else(|| chrono::Utc::now()); - - let post = Post { - author_did: Did(commit.repo.as_str().to_string()), - cid: Cid(serde_json::to_string(&op.cid).unwrap()), - uri: Uri(uri), - text: record.text.clone(), - labels: record - .labels - .as_ref() - .and_then(Label::from_atrium) - .unwrap_or_default(), - timestamp, - embed: record.embed.as_ref().and_then(Embed::from_atrium), - langs: record - .langs - .iter() - .filter_map(|lang| serde_json::to_string(&lang).ok()) - .collect(), - }; - let _ = tx.send(FirehoseEvent::Post(post)).await; + Some(converted_cid) == op.cid + }) { + match serde_ipld_dagcbor::from_reader(&mut item_data.clone().as_slice()) { + Ok(record) => { + let record: feed::post::Record = record; + let uri = format!( + "at://{}/{}/{}", + commit.repo.as_str(), + collection, + rkey + ); + + let timestamp = + DateTime::parse_from_rfc3339(record.created_at.as_str()) + .ok() + .map(|dt| dt.with_timezone(&chrono::Utc)) + .unwrap_or_else(|| chrono::Utc::now()); + + let post = Post { + author_did: Did(commit.repo.as_str().to_string()), + cid: Cid(serde_json::to_string(&op.cid).unwrap()), + uri: Uri(uri), + text: record.text.clone(), + labels: record + .labels + .as_ref() + .and_then(Label::from_atrium) + .unwrap_or_default(), + timestamp, + embed: record.embed.as_ref().and_then(Embed::from_atrium), + langs: record + .langs + .iter() + .filter_map(|lang| serde_json::to_string(&lang).ok()) + .collect(), + }; + let _ = tx.send(FirehoseEvent::Post(post)).await; + } + Err(_) => { + log::error!("Failed to deserialize post record for {}", rkey); + } + } } } (feed::Post::NSID, "delete") => { - let rkey_str = rkey.to_string(); - let uri = format!("at://{}/{}/{}", commit.repo.as_str(), collection, rkey_str); + let uri = format!("at://{}/{}/{}", commit.repo.as_str(), collection, rkey); let _ = tx.send(FirehoseEvent::DeletePost(Uri(uri))).await; } (Like::NSID, "create") => { - let rkey = RecordKey::new(rkey.to_string()).expect("invalid record key"); - if let Some(record) = repo - .get::(rkey.clone()) - .await - .map_err(|e| FirehoseError::Repository(e.to_string()))? - { - let uri = format!( - "at://{}/{}/{}", - commit.repo.as_str(), - collection, - rkey.as_str() + if let Some((_, item_data)) = items.iter().find(|(cid, _)| { + let converted_cid = CidLink( + cid.to_string() + .parse() + .unwrap_or_else(|_| panic!("invalid CID: {}", cid)), ); - let _ = tx - .send(FirehoseEvent::Like( - Uri(uri), - Uri(record.subject.uri.clone()), - )) - .await; + Some(converted_cid) == op.cid + }) { + match serde_ipld_dagcbor::from_reader(&mut item_data.clone().as_slice()) { + Ok(record) => { + let record: feed::like::Record = record; + let uri = format!( + "at://{}/{}/{}", + commit.repo.as_str(), + collection, + rkey + ); + let _ = tx + .send(FirehoseEvent::Like( + Uri(uri), + Uri(record.subject.uri.clone()), + )) + .await; + } + Err(_) => { + log::error!("Failed to deserialize like record for {}", rkey); + } + } } } (Like::NSID, "delete") => { - let rkey_str = rkey.to_string(); - let uri = format!("at://{}/{}/{}", commit.repo.as_str(), collection, rkey_str); + let uri = format!("at://{}/{}/{}", commit.repo.as_str(), collection, rkey); let _ = tx.send(FirehoseEvent::DeleteLike(Uri(uri))).await; } _ => {} From 1a8fe84d750bce841ed896f862e82a444397e230 Mon Sep 17 00:00:00 2001 From: cyypherus Date: Mon, 24 Nov 2025 23:57:50 -0800 Subject: [PATCH 11/53] error cleanup --- src/firehose.rs | 28 +++++----------------------- 1 file changed, 5 insertions(+), 23 deletions(-) diff --git a/src/firehose.rs b/src/firehose.rs index aa160f3..0f1ec79 100644 --- a/src/firehose.rs +++ b/src/firehose.rs @@ -178,7 +178,6 @@ use frames::Frame; pub enum FirehoseError { Frame(frames::FrameError), WebSocket(tokio_tungstenite::tungstenite::Error), - Io(std::io::Error), CarStore(String), } @@ -187,7 +186,6 @@ impl std::fmt::Display for FirehoseError { match self { FirehoseError::Frame(e) => write!(f, "frame error: {}", e), FirehoseError::WebSocket(e) => write!(f, "websocket error: {}", e), - FirehoseError::Io(e) => write!(f, "io error: {}", e), FirehoseError::CarStore(msg) => write!(f, "car store error: {}", msg), } } @@ -195,24 +193,6 @@ impl std::fmt::Display for FirehoseError { impl std::error::Error for FirehoseError {} -impl From for FirehoseError { - fn from(e: frames::FrameError) -> Self { - FirehoseError::Frame(e) - } -} - -impl From for FirehoseError { - fn from(e: tokio_tungstenite::tungstenite::Error) -> Self { - FirehoseError::WebSocket(e) - } -} - -impl From for FirehoseError { - fn from(e: std::io::Error) -> Self { - FirehoseError::Io(e) - } -} - pub enum FirehoseEvent { Post(Post), DeletePost(Uri), @@ -225,7 +205,9 @@ pub struct FirehoseConnector; impl FirehoseConnector { pub async fn run(tx: mpsc::Sender) -> Result<(), FirehoseError> { let _ = rustls::crypto::aws_lc_rs::default_provider().install_default(); - let (stream, _) = connect_async(format!("wss://bsky.network/xrpc/{NSID}")).await?; + let (stream, _) = connect_async(format!("wss://bsky.network/xrpc/{NSID}")) + .await + .map_err(|e| FirehoseError::WebSocket(e))?; let mut subscription = RepoSubscription { stream }; while let Some(message) = subscription.next().await { @@ -381,10 +363,10 @@ impl RepoSubscription { match self.stream.next().await { Some(Ok(Message::Binary(data))) => { let slice: &[u8] = &data; - Some(Frame::try_from(slice).map_err(FirehoseError::from)) + Some(Frame::try_from(slice).map_err(|e| FirehoseError::Frame(e))) } Some(Ok(_)) | None => None, - Some(Err(e)) => Some(Err(FirehoseError::from(e))), + Some(Err(e)) => Some(Err(FirehoseError::WebSocket(e))), } } } From bdfde9c887f6fe16af86eb55d5f96eb95705e137 Mon Sep 17 00:00:00 2001 From: cyypherus Date: Tue, 25 Nov 2025 00:19:18 -0800 Subject: [PATCH 12/53] cleanup --- src/firehose.rs | 73 +++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 58 insertions(+), 15 deletions(-) diff --git a/src/firehose.rs b/src/firehose.rs index 0f1ec79..204ac8c 100644 --- a/src/firehose.rs +++ b/src/firehose.rs @@ -208,9 +208,46 @@ impl FirehoseConnector { let (stream, _) = connect_async(format!("wss://bsky.network/xrpc/{NSID}")) .await .map_err(|e| FirehoseError::WebSocket(e))?; - let mut subscription = RepoSubscription { stream }; + let subscription = RepoSubscription { stream }; + let (frame_tx, frame_rx) = mpsc::channel(10000); + + let receive_task = tokio::spawn(Self::receive_frames(subscription, frame_tx)); + let parse_task = tokio::spawn(Self::parse_frames(frame_rx, tx)); + + tokio::select! { + receive_result = receive_task => { + receive_result.map_err(|_| FirehoseError::WebSocket( + tokio_tungstenite::tungstenite::Error::ConnectionClosed + ))??; + } + parse_result = parse_task => { + parse_result.map_err(|_| FirehoseError::WebSocket( + tokio_tungstenite::tungstenite::Error::ConnectionClosed + ))??; + } + } + + Ok(()) + } + + async fn receive_frames( + mut subscription: RepoSubscription, + frame_tx: mpsc::Sender>, + ) -> Result<(), FirehoseError> { while let Some(message) = subscription.next().await { + if frame_tx.send(message).await.is_err() { + break; + } + } + Ok(()) + } + + async fn parse_frames( + mut frame_rx: mpsc::Receiver>, + tx: mpsc::Sender, + ) -> Result<(), FirehoseError> { + while let Some(message) = frame_rx.recv().await { match message { Ok(Frame::Message(Some(t), message)) => { if t.as_str() == "#commit" { @@ -229,12 +266,13 @@ impl FirehoseConnector { } } Ok(Frame::Message(None, _msg)) => (), - Ok(Frame::Error(_e)) => { - println!("received error frame"); + Ok(Frame::Error(e)) => { + log::error!("Received error frame: {e:?}"); break; } Err(e) => { - println!("error {e}"); + log::error!("Error receiving frames {e}"); + return Err(e); } } } @@ -259,11 +297,10 @@ impl FirehoseConnector { match (collection, action) { (feed::Post::NSID, "create") => { if let Some((_, item_data)) = items.iter().find(|(cid, _)| { - let converted_cid = CidLink( - cid.to_string() - .parse() - .unwrap_or_else(|_| panic!("invalid CID: {}", cid)), - ); + let converted_cid = match cid.to_string().parse() { + Ok(parsed) => CidLink(parsed), + Err(_) => return false, + }; Some(converted_cid) == op.cid }) { match serde_ipld_dagcbor::from_reader(&mut item_data.clone().as_slice()) { @@ -282,9 +319,16 @@ impl FirehoseConnector { .map(|dt| dt.with_timezone(&chrono::Utc)) .unwrap_or_else(|| chrono::Utc::now()); + let cid_str = match serde_json::to_string(&op.cid) { + Ok(s) => s, + Err(e) => { + log::error!("Failed to serialize CID for {}: {}", rkey, e); + continue; + } + }; let post = Post { author_did: Did(commit.repo.as_str().to_string()), - cid: Cid(serde_json::to_string(&op.cid).unwrap()), + cid: Cid(cid_str), uri: Uri(uri), text: record.text.clone(), labels: record @@ -314,11 +358,10 @@ impl FirehoseConnector { } (Like::NSID, "create") => { if let Some((_, item_data)) = items.iter().find(|(cid, _)| { - let converted_cid = CidLink( - cid.to_string() - .parse() - .unwrap_or_else(|_| panic!("invalid CID: {}", cid)), - ); + let converted_cid = match cid.to_string().parse() { + Ok(parsed) => CidLink(parsed), + Err(_) => return false, + }; Some(converted_cid) == op.cid }) { match serde_ipld_dagcbor::from_reader(&mut item_data.clone().as_slice()) { From 288e8a6ae6c32d98642d2df79e25fda0e67709e3 Mon Sep 17 00:00:00 2001 From: cyypherus Date: Tue, 25 Nov 2025 00:36:11 -0800 Subject: [PATCH 13/53] cleanup --- examples/sqlite/Cargo.lock | 630 +++++++++++++++++++++++++++++++------ examples/sqlite/Cargo.toml | 8 +- 2 files changed, 534 insertions(+), 104 deletions(-) diff --git a/examples/sqlite/Cargo.lock b/examples/sqlite/Cargo.lock index b7719d1..7476460 100644 --- a/examples/sqlite/Cargo.lock +++ b/examples/sqlite/Cargo.lock @@ -2,6 +2,15 @@ # It is not intended for manual editing. version = 4 +[[package]] +name = "addr2line" +version = "0.25.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b5d307320b3181d6d7954e663bd7c774a838b8220fe0593c86d9fb09f498b4b" +dependencies = [ + "gimli", +] + [[package]] name = "adler2" version = "2.0.1" @@ -100,6 +109,18 @@ version = "1.0.100" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a23eb6b1614318a8071c9b2521f36b424b2c83db5eb3a0fead4a6c0809af6e61" +[[package]] +name = "arrayref" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76a2e8124351fda1ef8aaaa3bbd7ebbcb486bbcd4225aca0aa0d84bb2db8fecb" + +[[package]] +name = "arrayvec" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" + [[package]] name = "async-compression" version = "0.4.32" @@ -124,6 +145,28 @@ dependencies = [ "pin-project-lite", ] +[[package]] +name = "async-stream" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b5a71a6f37880a80d1d7f19efd781e4b5de42c88f0722cc13bcb6cc2cfe8476" +dependencies = [ + "async-stream-impl", + "futures-core", + "pin-project-lite", +] + +[[package]] +name = "async-stream-impl" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7c24de15d275a1ecfd47a380fb4d5ec9bfe0933f309ed5e705b775596a3574d" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.108", +] + [[package]] name = "async-trait" version = "0.1.89" @@ -177,6 +220,26 @@ dependencies = [ "web-time", ] +[[package]] +name = "atrium-repo" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "300aff863d16ad3aa1655b8586ae24fc492b338f822a7c2852a2241533832b4d" +dependencies = [ + "async-stream", + "atrium-api", + "futures", + "ipld-core", + "serde", + "serde_bytes", + "serde_ipld_dagcbor", + "sha2", + "thiserror 1.0.69", + "tokio", + "tokio-util", + "unsigned-varint 0.8.0", +] + [[package]] name = "atrium-xrpc" version = "0.12.3" @@ -230,6 +293,21 @@ dependencies = [ "fs_extra", ] +[[package]] +name = "backtrace" +version = "0.3.76" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb531853791a215d7c62a30daf0dde835f381ab5de4589cfe7c649d2cbe92bd6" +dependencies = [ + "addr2line", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", + "windows-link 0.2.1", +] + [[package]] name = "base-x" version = "0.2.11" @@ -299,6 +377,41 @@ version = "2.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "812e12b5285cc515a9c72a5c1d3b6d46a19dac5acfef5265968c166106e31dd3" +[[package]] +name = "blake2b_simd" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06e903a20b159e944f91ec8499fe1e55651480c541ea0a584f5d967c49ad9d99" +dependencies = [ + "arrayref", + "arrayvec", + "constant_time_eq", +] + +[[package]] +name = "blake2s_simd" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e90f7deecfac93095eb874a40febd69427776e24e1bd7f87f33ac62d6f0174df" +dependencies = [ + "arrayref", + "arrayvec", + "constant_time_eq", +] + +[[package]] +name = "blake3" +version = "1.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3888aaa89e4b2a40fca9848e400f6a658a5a3978de7be858e209cafa8be9a4a0" +dependencies = [ + "arrayref", + "arrayvec", + "cc", + "cfg-if", + "constant_time_eq", +] + [[package]] name = "block-buffer" version = "0.10.4" @@ -326,6 +439,15 @@ version = "1.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a" +[[package]] +name = "cbor4ii" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b544cf8c89359205f4f990d0e6f3828db42df85b5dac95d09157a250eb0749c4" +dependencies = [ + "serde", +] + [[package]] name = "cc" version = "1.2.43" @@ -367,6 +489,19 @@ dependencies = [ "windows-link 0.2.1", ] +[[package]] +name = "cid" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd94671561e36e4e7de75f753f577edafb0e7c05d6e4547229fdf7938fbcd2c3" +dependencies = [ + "core2", + "multibase", + "multihash 0.18.1", + "serde", + "unsigned-varint 0.7.2", +] + [[package]] name = "cid" version = "0.11.1" @@ -375,10 +510,10 @@ checksum = "3147d8272e8fa0ccd29ce51194dd98f79ddfb8191ba9e3409884e751798acf3a" dependencies = [ "core2", "multibase", - "multihash", + "multihash 0.19.3", "serde", "serde_bytes", - "unsigned-varint", + "unsigned-varint 0.8.0", ] [[package]] @@ -479,6 +614,12 @@ version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2f421161cb492475f1661ddc9815a745a1c894592070661180fdec3d4872e9c3" +[[package]] +name = "constant_time_eq" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c74b8349d32d297c9134b8c88677813a227df8f779daa29bfc29c183fe3dca6" + [[package]] name = "core-foundation" version = "0.9.4" @@ -714,6 +855,28 @@ dependencies = [ "pin-project-lite", ] +[[package]] +name = "failure" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d32e9bd16cc02eae7db7ef620b392808b89f6a5e16bb3497d159c6b92a0f4f86" +dependencies = [ + "backtrace", + "failure_derive", +] + +[[package]] +name = "failure_derive" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa4da3c766cd7a0db8242e326e9e4e081edd567072893ed320008189715366a4" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", + "synstructure 0.12.6", +] + [[package]] name = "fallible-iterator" version = "0.3.0" @@ -748,18 +911,6 @@ dependencies = [ "miniz_oxide", ] -[[package]] -name = "flume" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da0e4dd2a88388a1f4ccc7c9ce104604dab68d9f408dc34cd45823d5a9069095" -dependencies = [ - "futures-core", - "futures-sink", - "nanorand", - "spin", -] - [[package]] name = "fnv" version = "1.0.7" @@ -802,6 +953,21 @@ version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42703706b716c37f96a77aea830392ad231f44c9e9a67872fa5548707e11b11c" +[[package]] +name = "futures" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "65bc07b1a8bc7c85c5f2e110c476c7389b4554ba72af57d8445ea63a576b0876" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + [[package]] name = "futures-channel" version = "0.3.31" @@ -818,6 +984,23 @@ version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" +[[package]] +name = "futures-executor" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e28d1d997f585e54aebc3f97d39e72338912123a67330d723fdbb564d646c9f" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-io" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" + [[package]] name = "futures-macro" version = "0.3.31" @@ -847,10 +1030,13 @@ version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" dependencies = [ + "futures-channel", "futures-core", + "futures-io", "futures-macro", "futures-sink", "futures-task", + "memchr", "pin-project-lite", "pin-utils", "slab", @@ -873,10 +1059,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592" dependencies = [ "cfg-if", - "js-sys", "libc", "wasi", - "wasm-bindgen", ] [[package]] @@ -891,6 +1075,12 @@ dependencies = [ "wasip2", ] +[[package]] +name = "gimli" +version = "0.32.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e629b9b98ef3dd8afe6ca2bd0f89306cec16d43d907889945bc5d6687f2f13c7" + [[package]] name = "glob" version = "0.3.3" @@ -1001,6 +1191,12 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + [[package]] name = "http" version = "0.2.12" @@ -1322,7 +1518,7 @@ version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "104718b1cc124d92a6d01ca9c9258a7df311405debb3408c445a36452f9bf8db" dependencies = [ - "cid", + "cid 0.11.1", "serde", "serde_bytes", ] @@ -1364,27 +1560,6 @@ version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" -[[package]] -name = "jetstream-oxide" -version = "0.1.2" -source = "git+https://github.com/videah/jetstream-oxide?rev=7f21cfae9d8fe193ceb42fb04e511f45ac23764a#7f21cfae9d8fe193ceb42fb04e511f45ac23764a" -dependencies = [ - "async-trait", - "atrium-api", - "chrono", - "flume", - "futures-util", - "log", - "serde", - "serde_json", - "thiserror 2.0.17", - "tokio", - "tokio-tungstenite 0.24.0", - "tokio-util", - "url", - "zstd", -] - [[package]] name = "jiff" version = "0.2.15" @@ -1429,6 +1604,15 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "keccak" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ecc2af9a1119c51f12a14607e783cb977bde58bc069ff0c3da1095e635d70654" +dependencies = [ + "cpufeatures", +] + [[package]] name = "langtag" version = "0.3.4" @@ -1444,6 +1628,95 @@ version = "0.2.177" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2874a2af47a2325c2001a6e6fad9b16a53b802102b528163885171cf92b15976" +[[package]] +name = "libipld" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1ccd6b8ffb3afee7081fcaec00e1b099fd1c7ccf35ba5729d88538fcc3b4599" +dependencies = [ + "fnv", + "libipld-cbor", + "libipld-cbor-derive", + "libipld-core", + "libipld-json", + "libipld-macro", + "libipld-pb", + "log", + "multihash 0.18.1", + "thiserror 1.0.69", +] + +[[package]] +name = "libipld-cbor" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77d98c9d1747aa5eef1cf099cd648c3fd2d235249f5fed07522aaebc348e423b" +dependencies = [ + "byteorder", + "libipld-core", + "thiserror 1.0.69", +] + +[[package]] +name = "libipld-cbor-derive" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d5ba3a729b72973e456a1812b0afe2e176a376c1836cc1528e9fc98ae8cb838" +dependencies = [ + "proc-macro-crate", + "proc-macro2", + "quote", + "syn 1.0.109", + "synstructure 0.12.6", +] + +[[package]] +name = "libipld-core" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5acd707e8d8b092e967b2af978ed84709eaded82b75effe6cb6f6cc797ef8158" +dependencies = [ + "anyhow", + "cid 0.10.1", + "core2", + "multibase", + "multihash 0.18.1", + "thiserror 1.0.69", +] + +[[package]] +name = "libipld-json" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25856def940047b07b25c33d4e66d248597049ab0202085215dc4dca0487731c" +dependencies = [ + "libipld-core", + "multihash 0.18.1", + "serde", + "serde_json", +] + +[[package]] +name = "libipld-macro" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "71171c54214f866ae6722f3027f81dff0931e600e5a61e6b1b6a49ca0b5ed4ae" +dependencies = [ + "libipld-core", +] + +[[package]] +name = "libipld-pb" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3f2d0f866c4cd5dc9aa8068c429ba478d2882a3a4b70ab56f7e9a0eddf5d16f" +dependencies = [ + "bytes", + "libipld-core", + "quick-protobuf", + "thiserror 1.0.69", +] + [[package]] name = "libloading" version = "0.8.9" @@ -1659,6 +1932,34 @@ dependencies = [ "data-encoding-macro", ] +[[package]] +name = "multicodec" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f287a558ce2cac6f63944876d2f76ae2254a17fbe174c82967e76e0aab3379ed" +dependencies = [ + "failure", + "serde", + "unsigned-varint 0.2.3", +] + +[[package]] +name = "multihash" +version = "0.18.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfd8a792c1694c6da4f68db0a9d707c72bd260994da179e6030a5dcee00bb815" +dependencies = [ + "blake2b_simd", + "blake2s_simd", + "blake3", + "core2", + "digest", + "multihash-derive", + "sha2", + "sha3", + "unsigned-varint 0.7.2", +] + [[package]] name = "multihash" version = "0.19.3" @@ -1667,16 +1968,21 @@ checksum = "6b430e7953c29dd6a09afc29ff0bb69c6e306329ee6794700aee27b76a1aea8d" dependencies = [ "core2", "serde", - "unsigned-varint", + "unsigned-varint 0.8.0", ] [[package]] -name = "nanorand" -version = "0.7.0" +name = "multihash-derive" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a51313c5820b0b02bd422f4b44776fbf47961755c74ce64afc73bfad10226c3" +checksum = "1d6d4752e6230d8ef7adf7bd5d8c4b1f6561c1014c5ba9a37445ccefe18aa1db" dependencies = [ - "getrandom 0.2.16", + "proc-macro-crate", + "proc-macro-error", + "proc-macro2", + "quote", + "syn 1.0.109", + "synstructure 0.12.6", ] [[package]] @@ -1715,6 +2021,15 @@ dependencies = [ "autocfg", ] +[[package]] +name = "object" +version = "0.37.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff76201f031d8863c38aa7f905eca4f53abbfa15f609db4277d44cd8938f33fe" +dependencies = [ + "memchr", +] + [[package]] name = "once_cell" version = "1.21.3" @@ -1759,15 +2074,6 @@ version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e" -[[package]] -name = "openssl-src" -version = "300.5.4+3.5.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a507b3792995dae9b0df8a1c1e3771e8418b7c2d9f0baeba32e6fe8b06c7cb72" -dependencies = [ - "cc", -] - [[package]] name = "openssl-sys" version = "0.9.110" @@ -1776,7 +2082,6 @@ checksum = "0a9f0075ba3c21b09f8e8b2026584b1d18d49388648f2fbbf3c97ea8deced8e2" dependencies = [ "cc", "libc", - "openssl-src", "pkg-config", "vcpkg", ] @@ -1897,6 +2202,40 @@ dependencies = [ "syn 2.0.108", ] +[[package]] +name = "proc-macro-crate" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e17d47ce914bf4de440332250b0edd23ce48c005f59fab39d3335866b114f11a" +dependencies = [ + "thiserror 1.0.69", + "toml", +] + +[[package]] +name = "proc-macro-error" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" +dependencies = [ + "proc-macro-error-attr", + "proc-macro2", + "quote", + "syn 1.0.109", + "version_check", +] + +[[package]] +name = "proc-macro-error-attr" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" +dependencies = [ + "proc-macro2", + "quote", + "version_check", +] + [[package]] name = "proc-macro2" version = "1.0.103" @@ -1921,6 +2260,15 @@ dependencies = [ "winapi", ] +[[package]] +name = "quick-protobuf" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d6da84cc204722a989e01ba2f6e1e276e190f22263d0cb6ce8526fcdb0d2e1f" +dependencies = [ + "byteorder", +] + [[package]] name = "quote" version = "1.0.41" @@ -2108,6 +2456,24 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "rs-car" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "732df95a8f40f7623f7d54eac1e11626d86fd970f7542738d64c30d0d7ff0068" +dependencies = [ + "blake2b_simd", + "cid 0.10.1", + "futures", + "hex", + "libipld", + "libipld-cbor", + "multibase", + "multicodec", + "multihash 0.18.1", + "sha2", +] + [[package]] name = "rusqlite" version = "0.33.0" @@ -2122,6 +2488,12 @@ dependencies = [ "smallvec", ] +[[package]] +name = "rustc-demangle" +version = "0.1.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56f7d92ca342cea22a06f2121d944b4fd82af56988c270852495420f961d4ace" + [[package]] name = "rustc-hash" version = "2.1.1" @@ -2152,11 +2524,12 @@ dependencies = [ [[package]] name = "rustls" -version = "0.23.34" +version = "0.23.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a9586e9ee2b4f8fab52a0048ca7334d7024eef48e2cb9407e3497bb7cab7fa7" +checksum = "533f54bc6a7d4f647e46ad909549eda97bf5afc1585190ef692b4286b198bd8f" dependencies = [ "aws-lc-rs", + "log", "once_cell", "rustls-pki-types", "rustls-webpki", @@ -2325,6 +2698,18 @@ dependencies = [ "serde_core", ] +[[package]] +name = "serde_ipld_dagcbor" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46182f4f08349a02b45c998ba3215d3f9de826246ba02bb9dddfe9a2a2100778" +dependencies = [ + "cbor4ii", + "ipld-core", + "scopeguard", + "serde", +] + [[package]] name = "serde_json" version = "1.0.145" @@ -2361,6 +2746,27 @@ dependencies = [ "digest", ] +[[package]] +name = "sha2" +version = "0.10.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + +[[package]] +name = "sha3" +version = "0.10.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75872d278a8f37ef87fa0ddbda7802605cb18344497949862c0d4dcb291eba60" +dependencies = [ + "digest", + "keccak", +] + [[package]] name = "shlex" version = "1.3.0" @@ -2391,23 +2797,29 @@ checksum = "c1e9a774a6c28142ac54bb25d25562e6bcf957493a184f15ad4eebccb23e410a" [[package]] name = "skyfeed" version = "0.6.0" -source = "git+https://github.com/cyypherus/skyfeed.git?branch=french-feed#78c598806a91318dfe83161f809adb0ae2bde19d" dependencies = [ "anyhow", + "async-trait", "atrium-api", + "atrium-repo", "atrium-xrpc-client", "chrono", "clap", "dotenv", "env_logger", - "jetstream-oxide", + "futures", + "ipld-core", "log", "regex", "reqwest", + "rs-car", "rusqlite", + "rustls", "serde", + "serde_ipld_dagcbor", "serde_json", "tokio", + "tokio-tungstenite 0.28.0", "warp", "whatlang", ] @@ -2449,9 +2861,6 @@ name = "spin" version = "0.9.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" -dependencies = [ - "lock_api", -] [[package]] name = "stable_deref_trait" @@ -2502,6 +2911,18 @@ dependencies = [ "futures-core", ] +[[package]] +name = "synstructure" +version = "0.12.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f36bdaa60a83aca3921b5259d5400cbf5e90fc51931376a9bd4a0eb79aa7210f" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", + "unicode-xid", +] + [[package]] name = "synstructure" version = "0.13.2" @@ -2665,16 +3086,18 @@ dependencies = [ [[package]] name = "tokio-tungstenite" -version = "0.24.0" +version = "0.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edc5f74e248dc973e0dbb7b74c7e0d6fcc301c694ff50049504004ef4d0cdcd9" +checksum = "d25a406cddcc431a75d3d9afc6a7c0f7428d4891dd973e4d54c56b46127bf857" dependencies = [ "futures-util", "log", - "native-tls", + "rustls", + "rustls-native-certs", + "rustls-pki-types", "tokio", - "tokio-native-tls", - "tungstenite 0.24.0", + "tokio-rustls", + "tungstenite 0.28.0", ] [[package]] @@ -2685,11 +3108,21 @@ checksum = "14307c986784f72ef81c89db7d9e28d6ac26d16213b109ea501696195e6e3ce5" dependencies = [ "bytes", "futures-core", + "futures-io", "futures-sink", "pin-project-lite", "tokio", ] +[[package]] +name = "toml" +version = "0.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4f7f0dd8d50a853a531c426359045b1998f04219d88799810762cd4ad314234" +dependencies = [ + "serde", +] + [[package]] name = "tower" version = "0.5.2" @@ -2793,21 +3226,20 @@ dependencies = [ [[package]] name = "tungstenite" -version = "0.24.0" +version = "0.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18e5b8366ee7a95b16d32197d0b2604b43a0be89dc5fac9f8e96ccafbaedda8a" +checksum = "8628dcc84e5a09eb3d8423d6cb682965dea9133204e8fb3efee74c2a0c259442" dependencies = [ - "byteorder", "bytes", "data-encoding", "http 1.3.1", "httparse", "log", - "native-tls", - "rand 0.8.5", + "rand 0.9.2", + "rustls", + "rustls-pki-types", "sha1", - "thiserror 1.0.69", - "url", + "thiserror 2.0.17", "utf-8", ] @@ -2829,11 +3261,33 @@ version = "1.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "462eeb75aeb73aea900253ce739c8e18a67423fadf006037cd3ff27e82748a06" +[[package]] +name = "unicode-xid" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" + +[[package]] +name = "unsigned-varint" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7f0023a96687fe169081e8adce3f65e3874426b7886e9234d490af2dc077959" + +[[package]] +name = "unsigned-varint" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6889a77d49f1f013504cec6bf97a2c730394adedaeb1deb5ea08949a50541105" + [[package]] name = "unsigned-varint" version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eb066959b24b5196ae73cb057f45598450d2c5f71460e98c49b738086eff9c06" +dependencies = [ + "futures-io", + "futures-util", +] [[package]] name = "untrusted" @@ -3354,7 +3808,7 @@ dependencies = [ "proc-macro2", "quote", "syn 2.0.108", - "synstructure", + "synstructure 0.13.2", ] [[package]] @@ -3395,7 +3849,7 @@ dependencies = [ "proc-macro2", "quote", "syn 2.0.108", - "synstructure", + "synstructure 0.13.2", ] [[package]] @@ -3436,31 +3890,3 @@ dependencies = [ "quote", "syn 2.0.108", ] - -[[package]] -name = "zstd" -version = "0.13.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e91ee311a569c327171651566e07972200e76fcfe2242a4fa446149a3881c08a" -dependencies = [ - "zstd-safe", -] - -[[package]] -name = "zstd-safe" -version = "7.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f49c4d5f0abb602a93fb8736af2a4f4dd9512e36f7f570d66e65ff867ed3b9d" -dependencies = [ - "zstd-sys", -] - -[[package]] -name = "zstd-sys" -version = "2.0.16+zstd.1.5.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91e19ebc2adc8f83e43039e79776e3fda8ca919132d68a1fed6a5faca2683748" -dependencies = [ - "cc", - "pkg-config", -] diff --git a/examples/sqlite/Cargo.toml b/examples/sqlite/Cargo.toml index a539f6e..e2e7210 100644 --- a/examples/sqlite/Cargo.toml +++ b/examples/sqlite/Cargo.toml @@ -1,11 +1,12 @@ [package] -name = "basic" +name = "sqlite-feed" version = "0.1.0" edition = "2021" +publish = false [dependencies] log = "0.4.25" -skyfeed = { git = "https://github.com/cyypherus/skyfeed.git", branch = "french-feed" } +skyfeed = { git = "https://github.com/cyypherus/skyfeed.git", branch = "atrium-firehose" } # skyfeed = { path = "../.." } tokio = { version = "1.43.0", features = ["full", "time"] } rusqlite = { version = "0.33.0", features = ["bundled"] } @@ -14,3 +15,6 @@ regex = "1.11.1" whatlang = "0.16.4" metrics = "0.24.1" metrics-exporter-prometheus = "0.16.2" + +[profile.release] +lto = true From 321d6972317fe741b2913aeec2ae3d6ce6b535ab Mon Sep 17 00:00:00 2001 From: cyypherus Date: Tue, 25 Nov 2025 09:25:39 -0800 Subject: [PATCH 14/53] fix likes --- src/feed.rs | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/feed.rs b/src/feed.rs index 198baf7..fb62a5e 100644 --- a/src/feed.rs +++ b/src/feed.rs @@ -11,10 +11,10 @@ use std::fmt::Debug; use std::net::SocketAddr; use warp::Filter; +use crate::firehose::{FirehoseConnector, FirehoseEvent}; use crate::models::Request; use crate::utility_models::{DidDocument, Service}; use crate::{config::Config, feed_handler::FeedHandler}; -use crate::firehose::{FirehoseConnector, FirehoseEvent}; /// A `Feed` stores a `FeedHandler`, handles feed server endpoints & connects to the Firehose using the `start` methods. pub trait Feed { @@ -108,9 +108,9 @@ pub trait Feed { } })); let feed_server = warp::serve(routes); - + let (tx, mut rx) = tokio::sync::mpsc::channel(1000); - + let handler_clone = handler.clone(); let event_handler = tokio::spawn(async move { while let Some(event) = rx.recv().await { @@ -123,7 +123,7 @@ pub trait Feed { h.delete_post(uri).await; } FirehoseEvent::Like(like_uri, post_uri) => { - h.like_post(post_uri, like_uri).await; + h.like_post(like_uri, post_uri).await; } FirehoseEvent::DeleteLike(uri) => { h.delete_like(uri).await; @@ -131,7 +131,7 @@ pub trait Feed { } } }); - + let firehose_listener = tokio::spawn(async move { if let Err(e) = FirehoseConnector::run(tx).await { log::error!("Firehose error: {}", e); @@ -139,7 +139,6 @@ pub trait Feed { }); let _ = tokio::join!(feed_server.run(address), firehose_listener, event_handler); - } } } From 07e0452c76a66d22228de9e515dc6cbeda9dfdf3 Mon Sep 17 00:00:00 2001 From: cyypherus Date: Sun, 30 Nov 2025 10:33:29 -0800 Subject: [PATCH 15/53] use flume --- Cargo.lock | 27 +++++++++++++++++++++++++++ Cargo.toml | 1 + examples/basic/src/main.rs | 3 --- examples/sqlite/Cargo.lock | 31 ++++++++++++++++--------------- src/feed.rs | 4 ++-- src/firehose.rs | 25 ++++++++++++------------- 6 files changed, 58 insertions(+), 33 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1b63cb5..6ff2b1d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -884,6 +884,18 @@ dependencies = [ "miniz_oxide", ] +[[package]] +name = "flume" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da0e4dd2a88388a1f4ccc7c9ce104604dab68d9f408dc34cd45823d5a9069095" +dependencies = [ + "futures-core", + "futures-sink", + "nanorand", + "spin", +] + [[package]] name = "fnv" version = "1.0.7" @@ -1045,8 +1057,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" dependencies = [ "cfg-if", + "js-sys", "libc", "wasi 0.11.0+wasi-snapshot-preview1", + "wasm-bindgen", ] [[package]] @@ -1939,6 +1953,15 @@ dependencies = [ "synstructure 0.12.6", ] +[[package]] +name = "nanorand" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a51313c5820b0b02bd422f4b44776fbf47961755c74ce64afc73bfad10226c3" +dependencies = [ + "getrandom 0.2.15", +] + [[package]] name = "native-tls" version = "0.2.14" @@ -2772,6 +2795,7 @@ dependencies = [ "clap", "dotenv", "env_logger", + "flume", "futures", "insta", "ipld-core", @@ -2823,6 +2847,9 @@ name = "spin" version = "0.9.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" +dependencies = [ + "lock_api", +] [[package]] name = "stable_deref_trait" diff --git a/Cargo.toml b/Cargo.toml index 631b090..1ed34b5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -71,3 +71,4 @@ rustup-toolchain = { version = "0.1.9", optional = true } rustls = "0.23.35" serde_ipld_dagcbor = "0.6.0" rs-car = "0.1" +flume = "0.11.1" diff --git a/examples/basic/src/main.rs b/examples/basic/src/main.rs index 41379a2..4bf60d4 100644 --- a/examples/basic/src/main.rs +++ b/examples/basic/src/main.rs @@ -62,7 +62,6 @@ impl FeedHandler for MyFeedHandler { } async fn like_post(&mut self, like_uri: Uri, liked_post_uri: Uri) { - // println!("❤️ LIKE: {} likes {}", like_uri.0, liked_post_uri.0); if let Some(post_with_likes) = self .posts .lock() @@ -71,12 +70,10 @@ impl FeedHandler for MyFeedHandler { .find(|p| p.post.uri == liked_post_uri) { post_with_likes.likes.insert(like_uri); - dbg!(post_with_likes.likes.len()); } } async fn delete_like(&mut self, like_uri: Uri) { - println!("💔 DELETE LIKE: {}", like_uri.0); let mut posts = self.posts.lock().await; for post_with_likes in posts.iter_mut() { post_with_likes.likes.remove(&like_uri); diff --git a/examples/sqlite/Cargo.lock b/examples/sqlite/Cargo.lock index 7476460..f6bb620 100644 --- a/examples/sqlite/Cargo.lock +++ b/examples/sqlite/Cargo.lock @@ -336,21 +336,6 @@ version = "0.22.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" -[[package]] -name = "basic" -version = "0.1.0" -dependencies = [ - "chrono", - "log", - "metrics", - "metrics-exporter-prometheus", - "regex", - "rusqlite", - "skyfeed", - "tokio", - "whatlang", -] - [[package]] name = "bindgen" version = "0.72.1" @@ -2797,6 +2782,7 @@ checksum = "c1e9a774a6c28142ac54bb25d25562e6bcf957493a184f15ad4eebccb23e410a" [[package]] name = "skyfeed" version = "0.6.0" +source = "git+https://github.com/cyypherus/skyfeed.git?branch=atrium-firehose#321d6972317fe741b2913aeec2ae3d6ce6b535ab" dependencies = [ "anyhow", "async-trait", @@ -2862,6 +2848,21 @@ version = "0.9.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" +[[package]] +name = "sqlite-feed" +version = "0.1.0" +dependencies = [ + "chrono", + "log", + "metrics", + "metrics-exporter-prometheus", + "regex", + "rusqlite", + "skyfeed", + "tokio", + "whatlang", +] + [[package]] name = "stable_deref_trait" version = "1.2.1" diff --git a/src/feed.rs b/src/feed.rs index fb62a5e..8c807f2 100644 --- a/src/feed.rs +++ b/src/feed.rs @@ -109,11 +109,11 @@ pub trait Feed { })); let feed_server = warp::serve(routes); - let (tx, mut rx) = tokio::sync::mpsc::channel(1000); + let (tx, rx): (flume::Sender, _) = flume::unbounded(); let handler_clone = handler.clone(); let event_handler = tokio::spawn(async move { - while let Some(event) = rx.recv().await { + while let Ok(event) = rx.recv_async().await { let mut h = handler_clone.clone(); match event { FirehoseEvent::Post(post) => { diff --git a/src/firehose.rs b/src/firehose.rs index 204ac8c..54a87fe 100644 --- a/src/firehose.rs +++ b/src/firehose.rs @@ -1,7 +1,6 @@ use atrium_api::types::Collection; use futures::StreamExt; use tokio::net::TcpStream; -use tokio::sync::mpsc; use tokio_tungstenite::tungstenite::Message; use tokio_tungstenite::{connect_async, MaybeTlsStream, WebSocketStream}; @@ -203,14 +202,14 @@ pub enum FirehoseEvent { pub struct FirehoseConnector; impl FirehoseConnector { - pub async fn run(tx: mpsc::Sender) -> Result<(), FirehoseError> { + pub async fn run(tx: flume::Sender) -> Result<(), FirehoseError> { let _ = rustls::crypto::aws_lc_rs::default_provider().install_default(); let (stream, _) = connect_async(format!("wss://bsky.network/xrpc/{NSID}")) .await .map_err(|e| FirehoseError::WebSocket(e))?; let subscription = RepoSubscription { stream }; - let (frame_tx, frame_rx) = mpsc::channel(10000); + let (frame_tx, frame_rx) = flume::unbounded(); let receive_task = tokio::spawn(Self::receive_frames(subscription, frame_tx)); let parse_task = tokio::spawn(Self::parse_frames(frame_rx, tx)); @@ -233,10 +232,10 @@ impl FirehoseConnector { async fn receive_frames( mut subscription: RepoSubscription, - frame_tx: mpsc::Sender>, + frame_tx: flume::Sender>, ) -> Result<(), FirehoseError> { while let Some(message) = subscription.next().await { - if frame_tx.send(message).await.is_err() { + if frame_tx.send_async(message).await.is_err() { break; } } @@ -244,10 +243,10 @@ impl FirehoseConnector { } async fn parse_frames( - mut frame_rx: mpsc::Receiver>, - tx: mpsc::Sender, + frame_rx: flume::Receiver>, + tx: flume::Sender, ) -> Result<(), FirehoseError> { - while let Some(message) = frame_rx.recv().await { + while let Ok(message) = frame_rx.recv_async().await { match message { Ok(Frame::Message(Some(t), message)) => { if t.as_str() == "#commit" { @@ -281,7 +280,7 @@ impl FirehoseConnector { async fn handle_commit( commit: &Commit, - tx: &mpsc::Sender, + tx: &flume::Sender, ) -> Result<(), FirehoseError> { let mut blocks = commit.blocks.as_slice(); let (items, _) = rs_car::car_read_all(&mut blocks, true) @@ -344,7 +343,7 @@ impl FirehoseConnector { .filter_map(|lang| serde_json::to_string(&lang).ok()) .collect(), }; - let _ = tx.send(FirehoseEvent::Post(post)).await; + let _ = tx.send_async(FirehoseEvent::Post(post)).await; } Err(_) => { log::error!("Failed to deserialize post record for {}", rkey); @@ -354,7 +353,7 @@ impl FirehoseConnector { } (feed::Post::NSID, "delete") => { let uri = format!("at://{}/{}/{}", commit.repo.as_str(), collection, rkey); - let _ = tx.send(FirehoseEvent::DeletePost(Uri(uri))).await; + let _ = tx.send_async(FirehoseEvent::DeletePost(Uri(uri))).await; } (Like::NSID, "create") => { if let Some((_, item_data)) = items.iter().find(|(cid, _)| { @@ -374,7 +373,7 @@ impl FirehoseConnector { rkey ); let _ = tx - .send(FirehoseEvent::Like( + .send_async(FirehoseEvent::Like( Uri(uri), Uri(record.subject.uri.clone()), )) @@ -388,7 +387,7 @@ impl FirehoseConnector { } (Like::NSID, "delete") => { let uri = format!("at://{}/{}/{}", commit.repo.as_str(), collection, rkey); - let _ = tx.send(FirehoseEvent::DeleteLike(Uri(uri))).await; + let _ = tx.send_async(FirehoseEvent::DeleteLike(Uri(uri))).await; } _ => {} } From 11444a2aa02917dcd7897f7c33d9de378ebb2ed4 Mon Sep 17 00:00:00 2001 From: cyypherus Date: Sun, 30 Nov 2025 11:34:41 -0800 Subject: [PATCH 16/53] multi-feed support --- examples/basic/src/main.rs | 2 +- examples/sqlite/src/main.rs | 173 ++++++++++++++++++++++++------------ src/bin/verify.rs | 45 +++++----- src/feed.rs | 37 ++++---- 4 files changed, 162 insertions(+), 95 deletions(-) diff --git a/examples/basic/src/main.rs b/examples/basic/src/main.rs index 4bf60d4..92b95b1 100644 --- a/examples/basic/src/main.rs +++ b/examples/basic/src/main.rs @@ -10,7 +10,7 @@ async fn main() { posts: Arc::new(Mutex::new(Vec::new())), }, }; - feed.start("Cats", ([0, 0, 0, 0], 3030)).await + feed.start(vec!["Cats"], ([0, 0, 0, 0], 3030)).await } struct MyFeed { diff --git a/examples/sqlite/src/main.rs b/examples/sqlite/src/main.rs index 526ab85..dffe880 100644 --- a/examples/sqlite/src/main.rs +++ b/examples/sqlite/src/main.rs @@ -1,26 +1,45 @@ -use log::info; +use log::{error, info}; +use regex::Regex; use rusqlite::{params, Connection}; use skyfeed::{Config, Feed, FeedHandler, FeedResult, Post, Request, Uri}; use std::env; use std::{sync::Arc, time::Duration}; use tokio::sync::Mutex; +const FR_FEED: &'static str = "fr"; +const MY_FEED: &'static str = "cyys-feed"; + #[tokio::main] async fn main() { - let db = Connection::open("/space/feed.db").expect("Failed to open database"); - initialize_db(&db); + let fr_feed_db = Connection::open("feed.db").expect("Failed to open database"); + initialize_db(&fr_feed_db); + let my_feed_db = Connection::open("feed-2.db").expect("Failed to open database"); + initialize_db(&my_feed_db); - let db = Arc::new(Mutex::new(db)); + let fr_feed_db = Arc::new(Mutex::new(fr_feed_db)); + let my_feed_db = Arc::new(Mutex::new(my_feed_db)); let mut feed = MyFeed { - handler: MyFeedHandler { db: db.clone() }, + handler: MyFeedHandler { + fr_regex: regex::RegexBuilder::new(r"\\b(macron|le[- ]?pen|mélenchon|fillon|sarkozy|LREM|RN|gilets\s+jaunes|politique|trudeau|libéraux?|conservateurs?|bloc(?:\s+québécois)?|n(?:ouveau\s+)?parti(?:\s+démocratique)?|constitution(?:nel(?:le)?)?|scandale|gouvernement)\b|(extrême\s+(?:droite|gauche))") + .case_insensitive(true) + .build() + .unwrap(), + fr_feed_db: fr_feed_db.clone(), + my_regex: regex::RegexBuilder::new(r"\b(trump|biden|far left|far right|republican|democrat|immigrant|woke|AI|slop|conservative|liberal|racist|homophobe|slur|xenophobe|israel|palestine|palestinian|immigration|ukraine|russia)s?\b") + .case_insensitive(true) + .build() + .unwrap(), + my_feed_db: my_feed_db.clone(), + }, }; let mut cleanup_interval = tokio::time::interval(Duration::from_secs(10)); let cleanup_task = tokio::spawn(async move { loop { cleanup_interval.tick().await; - cleanup_posts(&db).await; + cleanup_posts(&fr_feed_db).await; + cleanup_posts(&my_feed_db).await; } }); @@ -30,7 +49,7 @@ async fn main() { tokio::join!( feed.start_with_config( - "fr", + vec![FR_FEED, MY_FEED], Config { publisher_did, feed_generator_hostname @@ -55,62 +74,118 @@ impl Feed for MyFeed { #[derive(Clone)] struct MyFeedHandler { - db: Arc>, + fr_regex: Regex, + fr_feed_db: Arc>, + my_regex: Regex, + my_feed_db: Arc>, } impl FeedHandler for MyFeedHandler { async fn insert_post(&mut self, post: Post) { - let unwanted_regex = - regex::RegexBuilder::new(r"\\b(macron|le[- ]?pen|mélenchon|fillon|sarkozy|LREM|RN|gilets\s+jaunes|politique|trudeau|libéraux?|conservateurs?|bloc(?:\s+québécois)?|n(?:ouveau\s+)?parti(?:\s+démocratique)?|constitution(?:nel(?:le)?)?|scandale|gouvernement)\b|(extrême\s+(?:droite|gauche))") - .case_insensitive(true) - .build() - .unwrap(); - + // French feed let detected_language = whatlang::detect_lang(&post.text); + let insert_sql = "INSERT OR REPLACE INTO posts (uri, text, timestamp) VALUES (?1, ?2, ?3)"; if post.langs.iter().any(|lang| lang.contains("fr")) && detected_language == Some(whatlang::Lang::Fra) - && !unwanted_regex.is_match(post.text.as_str()) + && !self.fr_regex.is_match(post.text.as_str()) && post.labels.is_empty() { - info!("Storing {post:?}"); - let db = self.db.lock().await; + info!("Storing french feed post {post:?}"); - db.execute( - "INSERT OR REPLACE INTO posts (uri, text, timestamp) VALUES (?1, ?2, ?3)", - params![post.uri.0, post.text, post.timestamp.timestamp()], - ) - .expect("Failed to insert post"); + self.fr_feed_db + .lock() + .await + .execute( + insert_sql, + params![post.uri.0, post.text, post.timestamp.timestamp()], + ) + .expect("Failed to insert post"); + } + + // My feed + if post.langs.iter().any(|lang| lang.contains("en")) + && detected_language == Some(whatlang::Lang::Eng) + && !self.my_regex.is_match(post.text.as_str()) + { + info!("Storing my feed post {post:?}"); + + self.my_feed_db + .lock() + .await + .execute( + insert_sql, + params![post.uri.0, post.text, post.timestamp.timestamp()], + ) + .expect("Failed to insert post"); } } async fn delete_post(&mut self, uri: Uri) { - let db = self.db.lock().await; - db.execute("DELETE FROM posts WHERE uri = ?1", params![uri.0]) + let unpost_sql = "DELETE FROM posts WHERE uri = ?1"; + self.fr_feed_db + .lock() + .await + .execute(unpost_sql, params![uri.0]) + .expect("Failed to delete post"); + self.my_feed_db + .lock() + .await + .execute(unpost_sql, params![uri.0]) .expect("Failed to delete post"); } async fn like_post(&mut self, like_uri: Uri, liked_post_uri: Uri) { - let db = self.db.lock().await; - db.execute( - "INSERT OR REPLACE INTO likes (post_uri, like_uri) + let like_sql = "INSERT OR REPLACE INTO likes (post_uri, like_uri) SELECT ?1, ?2 - WHERE EXISTS (SELECT 1 FROM posts WHERE uri = ?1)", - params![liked_post_uri.0, like_uri.0], - ) - .expect("Failed to like post"); + WHERE EXISTS (SELECT 1 FROM posts WHERE uri = ?1)"; + self.fr_feed_db + .lock() + .await + .execute(like_sql, params![liked_post_uri.0, like_uri.0]) + .expect("Failed to like post"); + self.my_feed_db + .lock() + .await + .execute(like_sql, params![liked_post_uri.0, like_uri.0]) + .expect("Failed to like post"); } async fn delete_like(&mut self, like_uri: Uri) { - let db = self.db.lock().await; - db.execute("DELETE FROM likes WHERE like_uri = ?1", params![like_uri.0]) + let unlike_sql = "DELETE FROM likes WHERE like_uri = ?1"; + self.fr_feed_db + .lock() + .await + .execute(unlike_sql, params![like_uri.0]) + .expect("Failed to delete like"); + self.my_feed_db + .lock() + .await + .execute(unlike_sql, params![like_uri.0]) .expect("Failed to delete like"); } async fn serve_feed(&self, request: Request) -> FeedResult { info!("Serving {request:?}"); - let db = self.db.lock().await; + let start_index = request + .cursor + .as_deref() + .and_then(|c| c.parse::().ok()) + .unwrap_or(0); + + let posts_per_page = 50; + let db = if request.feed == FR_FEED { + self.fr_feed_db.lock().await + } else if request.feed == MY_FEED { + self.my_feed_db.lock().await + } else { + error!("Requested a nonexistent feed"); + return FeedResult { + cursor: None, + feed: Vec::new(), + }; + }; let mut stmt = db .prepare( " @@ -135,40 +210,28 @@ impl FeedHandler for MyFeedHandler { SELECT uri, likes FROM sorted_posts WHERE rank <= 0.05 - ORDER BY timestamp DESC; - ", + ORDER BY timestamp DESC + LIMIT ? OFFSET ?; + ", ) .expect("Failed to prepare statement"); let post_iter = stmt - .query_map([], |row| row.get::<_, String>(0)) + .query_map([posts_per_page as i64, start_index as i64], |row| { + row.get::<_, String>(0) + }) .expect("Failed to query posts"); - let posts: Vec = post_iter.map(|x| x.unwrap()).map(Uri).collect(); + let posts: Vec = post_iter.filter_map(|x| x.ok()).map(Uri).collect(); - let start_index = request - .cursor - .as_deref() - .and_then(|c| c.parse::().ok()) - .unwrap_or(0); - let posts_per_page = 50; - - let page_posts: Vec<_> = posts - .iter() - .skip(start_index) - .take(posts_per_page) - .cloned() - .collect(); - - let next_cursor = if start_index + posts_per_page < posts.len() { + let next_cursor = if posts.len() == posts_per_page { Some((start_index + posts_per_page).to_string()) } else { None }; - FeedResult { cursor: next_cursor, - feed: page_posts, + feed: posts, } } } diff --git a/src/bin/verify.rs b/src/bin/verify.rs index 0b1bd22..2d7b033 100644 --- a/src/bin/verify.rs +++ b/src/bin/verify.rs @@ -57,29 +57,28 @@ async fn main() { ); // Extract at-uri and fetch the feed skeleton - let at_uri = describe["feeds"][0]["uri"] - .as_str() - .expect("at-uri not found"); + for feed in describe["feeds"].as_array().expect("Unexpected object") { + let at_uri = feed["uri"].as_str().expect("at-uri not found"); + let skeleton_response = client + .get(format!( + "{}/xrpc/app.bsky.feed.getFeedSkeleton", + args.local_url + )) + .query(&[("feed", at_uri), ("limit", "20")]) + .send() + .await + .expect("Feed skeleton failed"); - let skeleton_response = client - .get(format!( - "{}/xrpc/app.bsky.feed.getFeedSkeleton", - args.local_url - )) - .query(&[("feed", at_uri), ("limit", "20")]) - .send() - .await - .expect("Feed skeleton failed"); + let skeleton_body = skeleton_response + .text() + .await + .expect("Failed to read skeleton response text"); + let skeleton: Value = + serde_json::from_str(&skeleton_body).expect("Failed to parse skeleton JSON"); - let skeleton_body = skeleton_response - .text() - .await - .expect("Failed to read skeleton response text"); - let skeleton: Value = - serde_json::from_str(&skeleton_body).expect("Failed to parse skeleton JSON"); - - println!( - "Feed Skeleton Response:\n{}", - serde_json::to_string_pretty(&skeleton).expect("Failed to pretty print skeleton JSON") - ); + println!( + "Feed Skeleton Response:\n{}", + serde_json::to_string_pretty(&skeleton).expect("Failed to pretty print skeleton JSON") + ); + } } diff --git a/src/feed.rs b/src/feed.rs index 8c807f2..3c46757 100644 --- a/src/feed.rs +++ b/src/feed.rs @@ -23,7 +23,7 @@ pub trait Feed { /// /// This method loads the config from a local .env file using `dotenv`. See `Config` /// - /// - name: The identifying name of your feed. This value is used in the feed URL & when identifying which feed to *unpublish*. This is a separate value from the display name. + /// - feed_names: The identifying names of your feeds. This value is used in the feed URL & when identifying which feed to *publish* or *unpublish*. This is a separate value from the display name. /// - address: The address to bind the server to /// /// # Panics @@ -31,14 +31,14 @@ pub trait Feed { /// Panics if unable to bind to the provided address. fn start( &mut self, - name: impl AsRef, + feed_names: Vec<&'static str>, address: impl Into + Debug + Clone + Send, ) -> impl std::future::Future + Send { - self.start_with_config(name, Config::load_env_config(), address) + self.start_with_config(feed_names, Config::load_env_config(), address) } /// Starts the feed generator server & connects to the firehose. /// - /// - name: The identifying name of your feed. This value is used in the feed URL & when identifying which feed to *unpublish*. This is a separate value from the display name. + /// - feed_names: The identifying names of your feeds. This value is used in the feed URL & when identifying which feed to *publish* or *unpublish*. This is a separate value from the display name. /// - config: Configuration values, see `Config` /// - address: The address to bind the server to /// @@ -47,13 +47,13 @@ pub trait Feed { /// Panics if unable to bind to the provided address. fn start_with_config( &mut self, - name: impl AsRef, + feed_names: Vec<&'static str>, config: Config, address: impl Into + Debug + Clone + Send, ) -> impl std::future::Future + Send { let handler = self.handler(); let address = address.clone(); - let feed_name = name.as_ref().to_string(); + let feed_names = feed_names.clone(); async move { env_logger::Builder::from_env(Env::default().default_filter_or("info")).init(); @@ -70,7 +70,7 @@ pub trait Feed { .and(warp::path("app.bsky.feed.describeFeedGenerator")) .and(warp::get()) .and_then(move || { - describe_feed_generator(describe_feed_config.clone(), feed_name.clone()) + describe_feed_generator(describe_feed_config.clone(), feed_names.clone()) }); let get_feed_handler = handler.clone(); @@ -111,10 +111,9 @@ pub trait Feed { let (tx, rx): (flume::Sender, _) = flume::unbounded(); - let handler_clone = handler.clone(); let event_handler = tokio::spawn(async move { + let mut h = handler; while let Ok(event) = rx.recv_async().await { - let mut h = handler_clone.clone(); match event { FirehoseEvent::Post(post) => { h.insert_post(post).await; @@ -157,7 +156,7 @@ async fn did_json(config: Config) -> Result { async fn describe_feed_generator( config: Config, - feed_name: String, + feed_names: Vec>, ) -> Result { Ok(warp::reply::json(&FeedGeneratorDescription { did: atrium_api::types::string::Did::new(format!( @@ -165,12 +164,18 @@ async fn describe_feed_generator( config.feed_generator_hostname )) .unwrap(), - feeds: vec![Object::from(FeedData { - uri: format!( - "at://{}/app.bsky.feed.generator/{}", - config.publisher_did, feed_name - ), - })], + feeds: feed_names + .iter() + .map(|name| { + Object::from(FeedData { + uri: format!( + "at://{}/app.bsky.feed.generator/{}", + config.publisher_did, + name.as_ref().to_string() + ), + }) + }) + .collect(), links: None, })) } From eda67e72785c4eb1186f855b28365f9303e090cc Mon Sep 17 00:00:00 2001 From: cyypherus Date: Sun, 30 Nov 2025 11:59:33 -0800 Subject: [PATCH 17/53] fix feed name in request --- examples/sqlite/Cargo.lock | 29 ++++++++++++++++++++++++++++- examples/sqlite/Cargo.toml | 2 +- examples/sqlite/src/main.rs | 9 +++++---- src/feed.rs | 2 +- 4 files changed, 35 insertions(+), 7 deletions(-) diff --git a/examples/sqlite/Cargo.lock b/examples/sqlite/Cargo.lock index f6bb620..bfda95a 100644 --- a/examples/sqlite/Cargo.lock +++ b/examples/sqlite/Cargo.lock @@ -896,6 +896,18 @@ dependencies = [ "miniz_oxide", ] +[[package]] +name = "flume" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da0e4dd2a88388a1f4ccc7c9ce104604dab68d9f408dc34cd45823d5a9069095" +dependencies = [ + "futures-core", + "futures-sink", + "nanorand", + "spin", +] + [[package]] name = "fnv" version = "1.0.7" @@ -1044,8 +1056,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592" dependencies = [ "cfg-if", + "js-sys", "libc", "wasi", + "wasm-bindgen", ] [[package]] @@ -1970,6 +1984,15 @@ dependencies = [ "synstructure 0.12.6", ] +[[package]] +name = "nanorand" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a51313c5820b0b02bd422f4b44776fbf47961755c74ce64afc73bfad10226c3" +dependencies = [ + "getrandom 0.2.16", +] + [[package]] name = "native-tls" version = "0.2.14" @@ -2782,7 +2805,7 @@ checksum = "c1e9a774a6c28142ac54bb25d25562e6bcf957493a184f15ad4eebccb23e410a" [[package]] name = "skyfeed" version = "0.6.0" -source = "git+https://github.com/cyypherus/skyfeed.git?branch=atrium-firehose#321d6972317fe741b2913aeec2ae3d6ce6b535ab" +source = "git+https://github.com/cyypherus/skyfeed.git?rev=11444a2aa02917dcd7897f7c33d9de378ebb2ed4#11444a2aa02917dcd7897f7c33d9de378ebb2ed4" dependencies = [ "anyhow", "async-trait", @@ -2793,6 +2816,7 @@ dependencies = [ "clap", "dotenv", "env_logger", + "flume", "futures", "ipld-core", "log", @@ -2847,6 +2871,9 @@ name = "spin" version = "0.9.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" +dependencies = [ + "lock_api", +] [[package]] name = "sqlite-feed" diff --git a/examples/sqlite/Cargo.toml b/examples/sqlite/Cargo.toml index e2e7210..301cb67 100644 --- a/examples/sqlite/Cargo.toml +++ b/examples/sqlite/Cargo.toml @@ -6,7 +6,7 @@ publish = false [dependencies] log = "0.4.25" -skyfeed = { git = "https://github.com/cyypherus/skyfeed.git", branch = "atrium-firehose" } +skyfeed = { git = "https://github.com/cyypherus/skyfeed.git", rev = "11444a2aa02917dcd7897f7c33d9de378ebb2ed4" } # skyfeed = { path = "../.." } tokio = { version = "1.43.0", features = ["full", "time"] } rusqlite = { version = "0.33.0", features = ["bundled"] } diff --git a/examples/sqlite/src/main.rs b/examples/sqlite/src/main.rs index dffe880..636431c 100644 --- a/examples/sqlite/src/main.rs +++ b/examples/sqlite/src/main.rs @@ -11,9 +11,9 @@ const MY_FEED: &'static str = "cyys-feed"; #[tokio::main] async fn main() { - let fr_feed_db = Connection::open("feed.db").expect("Failed to open database"); + let fr_feed_db = Connection::open("/space/feed.db").expect("Failed to open database"); initialize_db(&fr_feed_db); - let my_feed_db = Connection::open("feed-2.db").expect("Failed to open database"); + let my_feed_db = Connection::open("/space/feed-2.db").expect("Failed to open database"); initialize_db(&my_feed_db); let fr_feed_db = Arc::new(Mutex::new(fr_feed_db)); @@ -54,6 +54,7 @@ async fn main() { publisher_did, feed_generator_hostname }, + // Config::load_env_config(), ([0, 0, 0, 0], 3030) ), cleanup_task @@ -91,7 +92,7 @@ impl FeedHandler for MyFeedHandler { && !self.fr_regex.is_match(post.text.as_str()) && post.labels.is_empty() { - info!("Storing french feed post {post:?}"); + // info!("Storing french feed post {post:?}"); self.fr_feed_db .lock() @@ -108,7 +109,7 @@ impl FeedHandler for MyFeedHandler { && detected_language == Some(whatlang::Lang::Eng) && !self.my_regex.is_match(post.text.as_str()) { - info!("Storing my feed post {post:?}"); + // info!("Storing my feed post {post:?}"); self.my_feed_db .lock() diff --git a/src/feed.rs b/src/feed.rs index 3c46757..747fe1a 100644 --- a/src/feed.rs +++ b/src/feed.rs @@ -187,7 +187,7 @@ async fn get_feed_skeleton( let skeleton = handler .serve_feed(Request { cursor: query.cursor.clone(), - feed: query.feed.clone(), + feed: query.feed.split("/").last().unwrap_or("").to_string(), limit: query.limit, }) .await; From aa6df26b891a4147133ead6403e33b42ed86cb7f Mon Sep 17 00:00:00 2001 From: cyypherus Date: Mon, 1 Dec 2025 09:16:04 -0800 Subject: [PATCH 18/53] wip --- examples/sqlite/Cargo.lock | 2 +- examples/sqlite/Cargo.toml | 2 +- examples/sqlite/src/main.rs | 45 +++++++++++++++++++------------------ 3 files changed, 25 insertions(+), 24 deletions(-) diff --git a/examples/sqlite/Cargo.lock b/examples/sqlite/Cargo.lock index bfda95a..aad005d 100644 --- a/examples/sqlite/Cargo.lock +++ b/examples/sqlite/Cargo.lock @@ -2805,7 +2805,7 @@ checksum = "c1e9a774a6c28142ac54bb25d25562e6bcf957493a184f15ad4eebccb23e410a" [[package]] name = "skyfeed" version = "0.6.0" -source = "git+https://github.com/cyypherus/skyfeed.git?rev=11444a2aa02917dcd7897f7c33d9de378ebb2ed4#11444a2aa02917dcd7897f7c33d9de378ebb2ed4" +source = "git+https://github.com/cyypherus/skyfeed.git?rev=eda67e72785c4eb1186f855b28365f9303e090cc#eda67e72785c4eb1186f855b28365f9303e090cc" dependencies = [ "anyhow", "async-trait", diff --git a/examples/sqlite/Cargo.toml b/examples/sqlite/Cargo.toml index 301cb67..8be95a7 100644 --- a/examples/sqlite/Cargo.toml +++ b/examples/sqlite/Cargo.toml @@ -6,7 +6,7 @@ publish = false [dependencies] log = "0.4.25" -skyfeed = { git = "https://github.com/cyypherus/skyfeed.git", rev = "11444a2aa02917dcd7897f7c33d9de378ebb2ed4" } +skyfeed = { git = "https://github.com/cyypherus/skyfeed.git", rev = "eda67e72785c4eb1186f855b28365f9303e090cc" } # skyfeed = { path = "../.." } tokio = { version = "1.43.0", features = ["full", "time"] } rusqlite = { version = "0.33.0", features = ["bundled"] } diff --git a/examples/sqlite/src/main.rs b/examples/sqlite/src/main.rs index 636431c..894d3c4 100644 --- a/examples/sqlite/src/main.rs +++ b/examples/sqlite/src/main.rs @@ -1,4 +1,4 @@ -use log::{error, info}; +use log::{error, info, trace}; use regex::Regex; use rusqlite::{params, Connection}; use skyfeed::{Config, Feed, FeedHandler, FeedResult, Post, Request, Uri}; @@ -11,9 +11,11 @@ const MY_FEED: &'static str = "cyys-feed"; #[tokio::main] async fn main() { + // let fr_feed_db = Connection::open("feed.db").expect("Failed to open database"); + // let my_feed_db = Connection::open("feed-2.db").expect("Failed to open database"); let fr_feed_db = Connection::open("/space/feed.db").expect("Failed to open database"); - initialize_db(&fr_feed_db); let my_feed_db = Connection::open("/space/feed-2.db").expect("Failed to open database"); + initialize_db(&fr_feed_db); initialize_db(&my_feed_db); let fr_feed_db = Arc::new(Mutex::new(fr_feed_db)); @@ -26,20 +28,20 @@ async fn main() { .build() .unwrap(), fr_feed_db: fr_feed_db.clone(), - my_regex: regex::RegexBuilder::new(r"\b(trump|biden|far left|far right|republican|democrat|immigrant|woke|AI|slop|conservative|liberal|racist|homophobe|slur|xenophobe|israel|palestine|palestinian|immigration|ukraine|russia)s?\b") - .case_insensitive(true) + my_regex: regex::RegexBuilder::new(r"\b(?i:trump|biden|far (left|right)|republican|democrat|immigration|immigrant|woke|AI|slop|conservative|liberal|racis(t|m)|homophob(e|ic|ia)|xenophob(e|ic|ia)|transphob(e|ic|ia)|slur|israel[i]?|palestin(e|ian)|ukraine|russia|tech bro|kamala|harris|politic(ian|al)|communis(m|t)|socialis(m|t)|antisemit(e|ic|ism)|anti-semite|anti-semitism|semite|fur(ry|sona)|sona|babyfur|diaper|ageregression|(neo)?[-]?nazi|elon|musk|war crime|whataboutism|GOP|(anti)?[-]?(vaccine|vax|vaxx|vaxxed)|vaccination|covid|coronavirus|pandemic|(?-i:ICE)|congress(men|women|ional)?|secretary of defense|potus)s?\b") + // .case_insensitive(true) .build() .unwrap(), my_feed_db: my_feed_db.clone(), }, }; - let mut cleanup_interval = tokio::time::interval(Duration::from_secs(10)); + let mut cleanup_interval = tokio::time::interval(Duration::from_secs(120)); let cleanup_task = tokio::spawn(async move { loop { cleanup_interval.tick().await; - cleanup_posts(&fr_feed_db).await; - cleanup_posts(&my_feed_db).await; + cleanup_posts(&fr_feed_db, 10_000).await; + cleanup_posts(&my_feed_db, 40_000).await; } }); @@ -92,7 +94,7 @@ impl FeedHandler for MyFeedHandler { && !self.fr_regex.is_match(post.text.as_str()) && post.labels.is_empty() { - // info!("Storing french feed post {post:?}"); + trace!("Storing french feed post {post:?}"); self.fr_feed_db .lock() @@ -109,7 +111,7 @@ impl FeedHandler for MyFeedHandler { && detected_language == Some(whatlang::Lang::Eng) && !self.my_regex.is_match(post.text.as_str()) { - // info!("Storing my feed post {post:?}"); + trace!("Storing my feed post {post:?}"); self.my_feed_db .lock() @@ -176,10 +178,10 @@ impl FeedHandler for MyFeedHandler { .unwrap_or(0); let posts_per_page = 50; - let db = if request.feed == FR_FEED { - self.fr_feed_db.lock().await + let (db, threshold) = if request.feed == FR_FEED { + (self.fr_feed_db.lock().await, 0.05) } else if request.feed == MY_FEED { - self.my_feed_db.lock().await + (self.my_feed_db.lock().await, 0.005) } else { error!("Requested a nonexistent feed"); return FeedResult { @@ -210,17 +212,18 @@ impl FeedHandler for MyFeedHandler { ) SELECT uri, likes FROM sorted_posts - WHERE rank <= 0.05 + WHERE rank <= ?1 ORDER BY timestamp DESC - LIMIT ? OFFSET ?; + LIMIT ?2 OFFSET ?3; ", ) .expect("Failed to prepare statement"); let post_iter = stmt - .query_map([posts_per_page as i64, start_index as i64], |row| { - row.get::<_, String>(0) - }) + .query_map( + params![threshold, posts_per_page as i64, start_index as i64], + |row| row.get::<_, String>(0), + ) .expect("Failed to query posts"); let posts: Vec = post_iter.filter_map(|x| x.ok()).map(Uri).collect(); @@ -237,9 +240,7 @@ impl FeedHandler for MyFeedHandler { } } -async fn cleanup_posts(db: &Arc>) { - const MAX_POSTS: usize = 10_000; - +async fn cleanup_posts(db: &Arc>, post_limit: usize) { let cleaned_posts = db .lock() .await @@ -251,7 +252,7 @@ async fn cleanup_posts(db: &Arc>) { SELECT uri FROM posts ORDER BY timestamp DESC - LIMIT {MAX_POSTS} + LIMIT {post_limit} ); " ), @@ -259,7 +260,7 @@ async fn cleanup_posts(db: &Arc>) { ) .expect("Failed to clean up old posts"); - info!("Cleaned up {cleaned_posts} posts"); + trace!("Cleaned up {cleaned_posts} posts"); } fn initialize_db(db: &Connection) { From e6f258601c5f6db83bbde0b392fcbb00dda0d6c7 Mon Sep 17 00:00:00 2001 From: cyypherus Date: Mon, 1 Dec 2025 09:17:49 -0800 Subject: [PATCH 19/53] revert flume changes --- Cargo.lock | 27 --------------------------- Cargo.toml | 1 - examples/basic/src/main.rs | 3 +++ examples/sqlite/Cargo.lock | 31 +++++++++++++++---------------- src/feed.rs | 4 ++-- src/firehose.rs | 25 +++++++++++++------------ 6 files changed, 33 insertions(+), 58 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6ff2b1d..1b63cb5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -884,18 +884,6 @@ dependencies = [ "miniz_oxide", ] -[[package]] -name = "flume" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da0e4dd2a88388a1f4ccc7c9ce104604dab68d9f408dc34cd45823d5a9069095" -dependencies = [ - "futures-core", - "futures-sink", - "nanorand", - "spin", -] - [[package]] name = "fnv" version = "1.0.7" @@ -1057,10 +1045,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" dependencies = [ "cfg-if", - "js-sys", "libc", "wasi 0.11.0+wasi-snapshot-preview1", - "wasm-bindgen", ] [[package]] @@ -1953,15 +1939,6 @@ dependencies = [ "synstructure 0.12.6", ] -[[package]] -name = "nanorand" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a51313c5820b0b02bd422f4b44776fbf47961755c74ce64afc73bfad10226c3" -dependencies = [ - "getrandom 0.2.15", -] - [[package]] name = "native-tls" version = "0.2.14" @@ -2795,7 +2772,6 @@ dependencies = [ "clap", "dotenv", "env_logger", - "flume", "futures", "insta", "ipld-core", @@ -2847,9 +2823,6 @@ name = "spin" version = "0.9.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" -dependencies = [ - "lock_api", -] [[package]] name = "stable_deref_trait" diff --git a/Cargo.toml b/Cargo.toml index 1ed34b5..631b090 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -71,4 +71,3 @@ rustup-toolchain = { version = "0.1.9", optional = true } rustls = "0.23.35" serde_ipld_dagcbor = "0.6.0" rs-car = "0.1" -flume = "0.11.1" diff --git a/examples/basic/src/main.rs b/examples/basic/src/main.rs index 92b95b1..6d9bc30 100644 --- a/examples/basic/src/main.rs +++ b/examples/basic/src/main.rs @@ -62,6 +62,7 @@ impl FeedHandler for MyFeedHandler { } async fn like_post(&mut self, like_uri: Uri, liked_post_uri: Uri) { + // println!("❤️ LIKE: {} likes {}", like_uri.0, liked_post_uri.0); if let Some(post_with_likes) = self .posts .lock() @@ -70,10 +71,12 @@ impl FeedHandler for MyFeedHandler { .find(|p| p.post.uri == liked_post_uri) { post_with_likes.likes.insert(like_uri); + dbg!(post_with_likes.likes.len()); } } async fn delete_like(&mut self, like_uri: Uri) { + println!("💔 DELETE LIKE: {}", like_uri.0); let mut posts = self.posts.lock().await; for post_with_likes in posts.iter_mut() { post_with_likes.likes.remove(&like_uri); diff --git a/examples/sqlite/Cargo.lock b/examples/sqlite/Cargo.lock index aad005d..be3c640 100644 --- a/examples/sqlite/Cargo.lock +++ b/examples/sqlite/Cargo.lock @@ -336,6 +336,21 @@ version = "0.22.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" +[[package]] +name = "basic" +version = "0.1.0" +dependencies = [ + "chrono", + "log", + "metrics", + "metrics-exporter-prometheus", + "regex", + "rusqlite", + "skyfeed", + "tokio", + "whatlang", +] + [[package]] name = "bindgen" version = "0.72.1" @@ -2805,7 +2820,6 @@ checksum = "c1e9a774a6c28142ac54bb25d25562e6bcf957493a184f15ad4eebccb23e410a" [[package]] name = "skyfeed" version = "0.6.0" -source = "git+https://github.com/cyypherus/skyfeed.git?rev=eda67e72785c4eb1186f855b28365f9303e090cc#eda67e72785c4eb1186f855b28365f9303e090cc" dependencies = [ "anyhow", "async-trait", @@ -2875,21 +2889,6 @@ dependencies = [ "lock_api", ] -[[package]] -name = "sqlite-feed" -version = "0.1.0" -dependencies = [ - "chrono", - "log", - "metrics", - "metrics-exporter-prometheus", - "regex", - "rusqlite", - "skyfeed", - "tokio", - "whatlang", -] - [[package]] name = "stable_deref_trait" version = "1.2.1" diff --git a/src/feed.rs b/src/feed.rs index 747fe1a..4090d1c 100644 --- a/src/feed.rs +++ b/src/feed.rs @@ -109,11 +109,11 @@ pub trait Feed { })); let feed_server = warp::serve(routes); - let (tx, rx): (flume::Sender, _) = flume::unbounded(); + let (tx, mut rx) = tokio::sync::mpsc::channel(1000); let event_handler = tokio::spawn(async move { let mut h = handler; - while let Ok(event) = rx.recv_async().await { + while let Some(event) = rx.recv().await { match event { FirehoseEvent::Post(post) => { h.insert_post(post).await; diff --git a/src/firehose.rs b/src/firehose.rs index 54a87fe..204ac8c 100644 --- a/src/firehose.rs +++ b/src/firehose.rs @@ -1,6 +1,7 @@ use atrium_api::types::Collection; use futures::StreamExt; use tokio::net::TcpStream; +use tokio::sync::mpsc; use tokio_tungstenite::tungstenite::Message; use tokio_tungstenite::{connect_async, MaybeTlsStream, WebSocketStream}; @@ -202,14 +203,14 @@ pub enum FirehoseEvent { pub struct FirehoseConnector; impl FirehoseConnector { - pub async fn run(tx: flume::Sender) -> Result<(), FirehoseError> { + pub async fn run(tx: mpsc::Sender) -> Result<(), FirehoseError> { let _ = rustls::crypto::aws_lc_rs::default_provider().install_default(); let (stream, _) = connect_async(format!("wss://bsky.network/xrpc/{NSID}")) .await .map_err(|e| FirehoseError::WebSocket(e))?; let subscription = RepoSubscription { stream }; - let (frame_tx, frame_rx) = flume::unbounded(); + let (frame_tx, frame_rx) = mpsc::channel(10000); let receive_task = tokio::spawn(Self::receive_frames(subscription, frame_tx)); let parse_task = tokio::spawn(Self::parse_frames(frame_rx, tx)); @@ -232,10 +233,10 @@ impl FirehoseConnector { async fn receive_frames( mut subscription: RepoSubscription, - frame_tx: flume::Sender>, + frame_tx: mpsc::Sender>, ) -> Result<(), FirehoseError> { while let Some(message) = subscription.next().await { - if frame_tx.send_async(message).await.is_err() { + if frame_tx.send(message).await.is_err() { break; } } @@ -243,10 +244,10 @@ impl FirehoseConnector { } async fn parse_frames( - frame_rx: flume::Receiver>, - tx: flume::Sender, + mut frame_rx: mpsc::Receiver>, + tx: mpsc::Sender, ) -> Result<(), FirehoseError> { - while let Ok(message) = frame_rx.recv_async().await { + while let Some(message) = frame_rx.recv().await { match message { Ok(Frame::Message(Some(t), message)) => { if t.as_str() == "#commit" { @@ -280,7 +281,7 @@ impl FirehoseConnector { async fn handle_commit( commit: &Commit, - tx: &flume::Sender, + tx: &mpsc::Sender, ) -> Result<(), FirehoseError> { let mut blocks = commit.blocks.as_slice(); let (items, _) = rs_car::car_read_all(&mut blocks, true) @@ -343,7 +344,7 @@ impl FirehoseConnector { .filter_map(|lang| serde_json::to_string(&lang).ok()) .collect(), }; - let _ = tx.send_async(FirehoseEvent::Post(post)).await; + let _ = tx.send(FirehoseEvent::Post(post)).await; } Err(_) => { log::error!("Failed to deserialize post record for {}", rkey); @@ -353,7 +354,7 @@ impl FirehoseConnector { } (feed::Post::NSID, "delete") => { let uri = format!("at://{}/{}/{}", commit.repo.as_str(), collection, rkey); - let _ = tx.send_async(FirehoseEvent::DeletePost(Uri(uri))).await; + let _ = tx.send(FirehoseEvent::DeletePost(Uri(uri))).await; } (Like::NSID, "create") => { if let Some((_, item_data)) = items.iter().find(|(cid, _)| { @@ -373,7 +374,7 @@ impl FirehoseConnector { rkey ); let _ = tx - .send_async(FirehoseEvent::Like( + .send(FirehoseEvent::Like( Uri(uri), Uri(record.subject.uri.clone()), )) @@ -387,7 +388,7 @@ impl FirehoseConnector { } (Like::NSID, "delete") => { let uri = format!("at://{}/{}/{}", commit.repo.as_str(), collection, rkey); - let _ = tx.send_async(FirehoseEvent::DeleteLike(Uri(uri))).await; + let _ = tx.send(FirehoseEvent::DeleteLike(Uri(uri))).await; } _ => {} } From eb7fa6abbbfc9fbbed0841db05b2a7c079d95fef Mon Sep 17 00:00:00 2001 From: cyypherus Date: Mon, 1 Dec 2025 11:29:53 -0800 Subject: [PATCH 20/53] more keywords --- examples/sqlite/src/main.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/sqlite/src/main.rs b/examples/sqlite/src/main.rs index 894d3c4..c131c70 100644 --- a/examples/sqlite/src/main.rs +++ b/examples/sqlite/src/main.rs @@ -28,7 +28,7 @@ async fn main() { .build() .unwrap(), fr_feed_db: fr_feed_db.clone(), - my_regex: regex::RegexBuilder::new(r"\b(?i:trump|biden|far (left|right)|republican|democrat|immigration|immigrant|woke|AI|slop|conservative|liberal|racis(t|m)|homophob(e|ic|ia)|xenophob(e|ic|ia)|transphob(e|ic|ia)|slur|israel[i]?|palestin(e|ian)|ukraine|russia|tech bro|kamala|harris|politic(ian|al)|communis(m|t)|socialis(m|t)|antisemit(e|ic|ism)|anti-semite|anti-semitism|semite|fur(ry|sona)|sona|babyfur|diaper|ageregression|(neo)?[-]?nazi|elon|musk|war crime|whataboutism|GOP|(anti)?[-]?(vaccine|vax|vaxx|vaxxed)|vaccination|covid|coronavirus|pandemic|(?-i:ICE)|congress(men|women|ional)?|secretary of defense|potus)s?\b") + my_regex: regex::RegexBuilder::new(r"\b(?i:trump|biden|far[ ]?(left|right)|(left|right)[ ]?wing|republican|(un)?democrat(ic)?|immigration|immigrant|woke|AI|slop|conservative|liberal|racis(t|m)|homophob(e|ic|ia)|xenophob(e|ic|ia)|transphob(e|ic|ia)|slur|israel[i]?|palestin(e|ian)|ukrain(e|ian)|russia(n)?|tech bro|kamala|harris|politic(ian|al)|communis(m|t)|socialis(m|t)|antisemit(e|ic|ism)|anti-semite|anti-semitism|semite|fur(ry|sona)|sona|babyfur|diaper|ageregression|(neo)?[-]?nazi|elon|musk|war crime|whataboutism|GOP|(anti)?[-]?(vaccine|vax|vaxx|vaxxed)|vaccination|covid|coronavirus|pandemic|immunization|(?-i:ICE)|congress(men|women|ional)?|secretary of defense|potus)s?\b") // .case_insensitive(true) .build() .unwrap(), From 46417357f0591e31ebf04b5c08a77f78d1efb8cf Mon Sep 17 00:00:00 2001 From: cyypherus Date: Mon, 1 Dec 2025 19:40:52 -0700 Subject: [PATCH 21/53] batched sql inserts --- examples/sqlite/Cargo.lock | 54 ++------ examples/sqlite/Cargo.toml | 2 +- examples/sqlite/src/main.rs | 264 +++++++++++++++++++++--------------- 3 files changed, 171 insertions(+), 149 deletions(-) diff --git a/examples/sqlite/Cargo.lock b/examples/sqlite/Cargo.lock index be3c640..490f419 100644 --- a/examples/sqlite/Cargo.lock +++ b/examples/sqlite/Cargo.lock @@ -336,21 +336,6 @@ version = "0.22.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" -[[package]] -name = "basic" -version = "0.1.0" -dependencies = [ - "chrono", - "log", - "metrics", - "metrics-exporter-prometheus", - "regex", - "rusqlite", - "skyfeed", - "tokio", - "whatlang", -] - [[package]] name = "bindgen" version = "0.72.1" @@ -911,18 +896,6 @@ dependencies = [ "miniz_oxide", ] -[[package]] -name = "flume" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da0e4dd2a88388a1f4ccc7c9ce104604dab68d9f408dc34cd45823d5a9069095" -dependencies = [ - "futures-core", - "futures-sink", - "nanorand", - "spin", -] - [[package]] name = "fnv" version = "1.0.7" @@ -1071,10 +1044,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592" dependencies = [ "cfg-if", - "js-sys", "libc", "wasi", - "wasm-bindgen", ] [[package]] @@ -1999,15 +1970,6 @@ dependencies = [ "synstructure 0.12.6", ] -[[package]] -name = "nanorand" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a51313c5820b0b02bd422f4b44776fbf47961755c74ce64afc73bfad10226c3" -dependencies = [ - "getrandom 0.2.16", -] - [[package]] name = "native-tls" version = "0.2.14" @@ -2820,6 +2782,7 @@ checksum = "c1e9a774a6c28142ac54bb25d25562e6bcf957493a184f15ad4eebccb23e410a" [[package]] name = "skyfeed" version = "0.6.0" +source = "git+https://github.com/cyypherus/skyfeed.git?rev=eb7fa6abbbfc9fbbed0841db05b2a7c079d95fef#eb7fa6abbbfc9fbbed0841db05b2a7c079d95fef" dependencies = [ "anyhow", "async-trait", @@ -2830,7 +2793,6 @@ dependencies = [ "clap", "dotenv", "env_logger", - "flume", "futures", "ipld-core", "log", @@ -2885,8 +2847,20 @@ name = "spin" version = "0.9.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" + +[[package]] +name = "sqlite-feed" +version = "0.1.0" dependencies = [ - "lock_api", + "chrono", + "log", + "metrics", + "metrics-exporter-prometheus", + "regex", + "rusqlite", + "skyfeed", + "tokio", + "whatlang", ] [[package]] diff --git a/examples/sqlite/Cargo.toml b/examples/sqlite/Cargo.toml index 8be95a7..935b986 100644 --- a/examples/sqlite/Cargo.toml +++ b/examples/sqlite/Cargo.toml @@ -6,7 +6,7 @@ publish = false [dependencies] log = "0.4.25" -skyfeed = { git = "https://github.com/cyypherus/skyfeed.git", rev = "eda67e72785c4eb1186f855b28365f9303e090cc" } +skyfeed = { git = "https://github.com/cyypherus/skyfeed.git", rev = "eb7fa6abbbfc9fbbed0841db05b2a7c079d95fef" } # skyfeed = { path = "../.." } tokio = { version = "1.43.0", features = ["full", "time"] } rusqlite = { version = "0.33.0", features = ["bundled"] } diff --git a/examples/sqlite/src/main.rs b/examples/sqlite/src/main.rs index c131c70..c617fdc 100644 --- a/examples/sqlite/src/main.rs +++ b/examples/sqlite/src/main.rs @@ -1,8 +1,7 @@ use log::{error, info, trace}; use regex::Regex; -use rusqlite::{params, Connection}; +use rusqlite::{params, params_from_iter, Connection}; use skyfeed::{Config, Feed, FeedHandler, FeedResult, Post, Request, Uri}; -use std::env; use std::{sync::Arc, time::Duration}; use tokio::sync::Mutex; @@ -11,15 +10,11 @@ const MY_FEED: &'static str = "cyys-feed"; #[tokio::main] async fn main() { - // let fr_feed_db = Connection::open("feed.db").expect("Failed to open database"); - // let my_feed_db = Connection::open("feed-2.db").expect("Failed to open database"); - let fr_feed_db = Connection::open("/space/feed.db").expect("Failed to open database"); - let my_feed_db = Connection::open("/space/feed-2.db").expect("Failed to open database"); - initialize_db(&fr_feed_db); - initialize_db(&my_feed_db); + let db = Connection::open("feed.db").expect("Failed to open database"); + // let db = Connection::open("/space/feed.db").expect("Failed to open database"); + initialize_db(&db); - let fr_feed_db = Arc::new(Mutex::new(fr_feed_db)); - let my_feed_db = Arc::new(Mutex::new(my_feed_db)); + let db = Arc::new(Mutex::new(db)); let mut feed = MyFeed { handler: MyFeedHandler { @@ -27,36 +22,38 @@ async fn main() { .case_insensitive(true) .build() .unwrap(), - fr_feed_db: fr_feed_db.clone(), my_regex: regex::RegexBuilder::new(r"\b(?i:trump|biden|far[ ]?(left|right)|(left|right)[ ]?wing|republican|(un)?democrat(ic)?|immigration|immigrant|woke|AI|slop|conservative|liberal|racis(t|m)|homophob(e|ic|ia)|xenophob(e|ic|ia)|transphob(e|ic|ia)|slur|israel[i]?|palestin(e|ian)|ukrain(e|ian)|russia(n)?|tech bro|kamala|harris|politic(ian|al)|communis(m|t)|socialis(m|t)|antisemit(e|ic|ism)|anti-semite|anti-semitism|semite|fur(ry|sona)|sona|babyfur|diaper|ageregression|(neo)?[-]?nazi|elon|musk|war crime|whataboutism|GOP|(anti)?[-]?(vaccine|vax|vaxx|vaxxed)|vaccination|covid|coronavirus|pandemic|immunization|(?-i:ICE)|congress(men|women|ional)?|secretary of defense|potus)s?\b") // .case_insensitive(true) .build() .unwrap(), - my_feed_db: my_feed_db.clone(), + db: db.clone(), + pending_posts: Arc::new(Mutex::new(Vec::new())), + pending_likes: Arc::new(Mutex::new(Vec::new())), + batch_size: 100, }, }; let mut cleanup_interval = tokio::time::interval(Duration::from_secs(120)); + let db_clone = db.clone(); let cleanup_task = tokio::spawn(async move { loop { cleanup_interval.tick().await; - cleanup_posts(&fr_feed_db, 10_000).await; - cleanup_posts(&my_feed_db, 40_000).await; + cleanup_posts(&db_clone, 50_000).await; } }); - let publisher_did = env::var("PUBLISHER_DID").expect("PUBLISHER_DID env var not set"); - let feed_generator_hostname = - env::var("FEED_GENERATOR_HOSTNAME").expect("FEED_GENERATOR_HOSTNAME env var not set"); + // let publisher_did = env::var("PUBLISHER_DID").expect("PUBLISHER_DID env var not set"); + // let feed_generator_hostname = + // env::var("FEED_GENERATOR_HOSTNAME").expect("FEED_GENERATOR_HOSTNAME env var not set"); tokio::join!( feed.start_with_config( vec![FR_FEED, MY_FEED], - Config { - publisher_did, - feed_generator_hostname - }, - // Config::load_env_config(), + // Config { + // publisher_did, + // feed_generator_hostname + // }, + Config::load_env_config(), ([0, 0, 0, 0], 3030) ), cleanup_task @@ -78,60 +75,52 @@ impl Feed for MyFeed { #[derive(Clone)] struct MyFeedHandler { fr_regex: Regex, - fr_feed_db: Arc>, my_regex: Regex, - my_feed_db: Arc>, + db: Arc>, + pending_posts: Arc>>, + pending_likes: Arc>>, + batch_size: usize, } impl FeedHandler for MyFeedHandler { async fn insert_post(&mut self, post: Post) { - // French feed let detected_language = whatlang::detect_lang(&post.text); - let insert_sql = "INSERT OR REPLACE INTO posts (uri, text, timestamp) VALUES (?1, ?2, ?3)"; - - if post.langs.iter().any(|lang| lang.contains("fr")) + let timestamp = post.timestamp.timestamp(); + let feed_type = if post.langs.iter().any(|lang| lang.contains("fr")) && detected_language == Some(whatlang::Lang::Fra) && !self.fr_regex.is_match(post.text.as_str()) && post.labels.is_empty() { - trace!("Storing french feed post {post:?}"); - - self.fr_feed_db - .lock() - .await - .execute( - insert_sql, - params![post.uri.0, post.text, post.timestamp.timestamp()], - ) - .expect("Failed to insert post"); - } - - // My feed - if post.langs.iter().any(|lang| lang.contains("en")) + Some("fr") + } else if post.langs.iter().any(|lang| lang.contains("en")) && detected_language == Some(whatlang::Lang::Eng) && !self.my_regex.is_match(post.text.as_str()) { - trace!("Storing my feed post {post:?}"); - - self.my_feed_db - .lock() - .await - .execute( - insert_sql, - params![post.uri.0, post.text, post.timestamp.timestamp()], - ) - .expect("Failed to insert post"); + Some("en") + } else { + None + }; + + if let Some(feed) = feed_type { + trace!("Queuing {} feed post {post:?}", feed); + let mut pending = self.pending_posts.lock().await; + pending.push(( + post.uri.0.clone(), + post.text.clone(), + timestamp, + feed.to_string(), + )); + + if pending.len() >= self.batch_size { + drop(pending); + self.flush_posts().await; + } } } async fn delete_post(&mut self, uri: Uri) { let unpost_sql = "DELETE FROM posts WHERE uri = ?1"; - self.fr_feed_db - .lock() - .await - .execute(unpost_sql, params![uri.0]) - .expect("Failed to delete post"); - self.my_feed_db + self.db .lock() .await .execute(unpost_sql, params![uri.0]) @@ -139,29 +128,25 @@ impl FeedHandler for MyFeedHandler { } async fn like_post(&mut self, like_uri: Uri, liked_post_uri: Uri) { - let like_sql = "INSERT OR REPLACE INTO likes (post_uri, like_uri) - SELECT ?1, ?2 - WHERE EXISTS (SELECT 1 FROM posts WHERE uri = ?1)"; - self.fr_feed_db - .lock() - .await - .execute(like_sql, params![liked_post_uri.0, like_uri.0]) - .expect("Failed to like post"); - self.my_feed_db - .lock() - .await - .execute(like_sql, params![liked_post_uri.0, like_uri.0]) - .expect("Failed to like post"); + trace!("Queuing like: {} on post {}", like_uri.0, liked_post_uri.0); + let mut pending = self.pending_likes.lock().await; + for feed in &["fr", "en"] { + pending.push(( + liked_post_uri.0.clone(), + like_uri.0.clone(), + feed.to_string(), + )); + } + + if pending.len() >= self.batch_size { + drop(pending); + self.flush_likes().await; + } } async fn delete_like(&mut self, like_uri: Uri) { let unlike_sql = "DELETE FROM likes WHERE like_uri = ?1"; - self.fr_feed_db - .lock() - .await - .execute(unlike_sql, params![like_uri.0]) - .expect("Failed to delete like"); - self.my_feed_db + self.db .lock() .await .execute(unlike_sql, params![like_uri.0]) @@ -178,10 +163,10 @@ impl FeedHandler for MyFeedHandler { .unwrap_or(0); let posts_per_page = 50; - let (db, threshold) = if request.feed == FR_FEED { - (self.fr_feed_db.lock().await, 0.05) + let threshold = if request.feed == FR_FEED { + 0.05 } else if request.feed == MY_FEED { - (self.my_feed_db.lock().await, 0.005) + 0.005 } else { error!("Requested a nonexistent feed"); return FeedResult { @@ -189,39 +174,47 @@ impl FeedHandler for MyFeedHandler { feed: Vec::new(), }; }; + + let db = self.db.lock().await; let mut stmt = db - .prepare( + .prepare(&format!( " - WITH ranked_posts AS ( - SELECT - posts.uri, - posts.timestamp, - COUNT(likes.like_uri) AS likes - FROM posts - LEFT JOIN likes ON posts.uri = likes.post_uri - GROUP BY posts.uri - HAVING COUNT(likes.like_uri) > 0 - ), - sorted_posts AS ( - SELECT - uri, - timestamp, - likes, - PERCENT_RANK() OVER (ORDER BY likes DESC) AS rank - FROM ranked_posts - ) - SELECT uri, likes - FROM sorted_posts - WHERE rank <= ?1 - ORDER BY timestamp DESC - LIMIT ?2 OFFSET ?3; - ", - ) + WITH ranked_posts AS ( + SELECT + posts.uri, + posts.timestamp, + COUNT(likes.like_uri) AS likes + FROM posts + WHERE posts.feed = ?4 + LEFT JOIN likes ON posts.uri = likes.post_uri + GROUP BY posts.uri + HAVING COUNT(likes.like_uri) > 0 + ), + sorted_posts AS ( + SELECT + uri, + timestamp, + likes, + PERCENT_RANK() OVER (ORDER BY likes DESC) AS rank + FROM ranked_posts + ) + SELECT uri, likes + FROM sorted_posts + WHERE rank <= ?1 + ORDER BY timestamp DESC + LIMIT ?2 OFFSET ?3; + " + )) .expect("Failed to prepare statement"); let post_iter = stmt .query_map( - params![threshold, posts_per_page as i64, start_index as i64], + params![ + threshold, + posts_per_page as i64, + start_index as i64, + request.feed + ], |row| row.get::<_, String>(0), ) .expect("Failed to query posts"); @@ -240,6 +233,60 @@ impl FeedHandler for MyFeedHandler { } } +impl MyFeedHandler { + async fn flush_posts(&self) { + let mut pending = self.pending_posts.lock().await; + if pending.is_empty() { + return; + } + + let posts_to_insert: Vec<_> = pending.drain(..).collect(); + drop(pending); + + let mut db = self.db.lock().await; + let tx = db.transaction().expect("Failed to start transaction"); + + { + let mut stmt = tx.prepare( + "INSERT OR REPLACE INTO posts (uri, text, timestamp, feed) VALUES (?1, ?2, ?3, ?4)" + ).expect("Failed to prepare statement"); + + for (uri, text, timestamp, feed) in posts_to_insert { + stmt.execute(params![uri, text, timestamp, feed]) + .expect("Failed to insert post"); + } + } + + tx.commit().expect("Failed to commit transaction"); + } + + async fn flush_likes(&self) { + let mut pending = self.pending_likes.lock().await; + if pending.is_empty() { + return; + } + + let likes_to_insert: Vec<_> = pending.drain(..).collect(); + drop(pending); + + let mut db = self.db.lock().await; + let tx = db.transaction().expect("Failed to start transaction"); + + { + let mut stmt = tx.prepare( + "INSERT OR REPLACE INTO likes (post_uri, like_uri) SELECT ?1, ?2 WHERE EXISTS (SELECT 1 FROM posts WHERE uri = ?1 AND feed = ?3)" + ).expect("Failed to prepare statement"); + + for (post_uri, like_uri, feed) in likes_to_insert { + stmt.execute(params![post_uri, like_uri, feed]) + .expect("Failed to insert like"); + } + } + + tx.commit().expect("Failed to commit transaction"); + } +} + async fn cleanup_posts(db: &Arc>, post_limit: usize) { let cleaned_posts = db .lock() @@ -268,7 +315,8 @@ fn initialize_db(db: &Connection) { "CREATE TABLE IF NOT EXISTS posts ( uri TEXT PRIMARY KEY, text TEXT, - timestamp INTEGER + timestamp INTEGER, + feed TEXT )", [], ) From ed09dac9989c9e42f11c236289af88ec418acfdc Mon Sep 17 00:00:00 2001 From: cyypherus Date: Mon, 1 Dec 2025 19:42:33 -0700 Subject: [PATCH 22/53] re-add flume --- Cargo.lock | 27 +++++++++++++++++++++++++++ Cargo.toml | 1 + examples/basic/src/main.rs | 3 --- examples/sqlite/Cargo.lock | 9 ++++++++- src/feed.rs | 4 ++-- src/firehose.rs | 25 ++++++++++++------------- 6 files changed, 50 insertions(+), 19 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1b63cb5..6ff2b1d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -884,6 +884,18 @@ dependencies = [ "miniz_oxide", ] +[[package]] +name = "flume" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da0e4dd2a88388a1f4ccc7c9ce104604dab68d9f408dc34cd45823d5a9069095" +dependencies = [ + "futures-core", + "futures-sink", + "nanorand", + "spin", +] + [[package]] name = "fnv" version = "1.0.7" @@ -1045,8 +1057,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" dependencies = [ "cfg-if", + "js-sys", "libc", "wasi 0.11.0+wasi-snapshot-preview1", + "wasm-bindgen", ] [[package]] @@ -1939,6 +1953,15 @@ dependencies = [ "synstructure 0.12.6", ] +[[package]] +name = "nanorand" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a51313c5820b0b02bd422f4b44776fbf47961755c74ce64afc73bfad10226c3" +dependencies = [ + "getrandom 0.2.15", +] + [[package]] name = "native-tls" version = "0.2.14" @@ -2772,6 +2795,7 @@ dependencies = [ "clap", "dotenv", "env_logger", + "flume", "futures", "insta", "ipld-core", @@ -2823,6 +2847,9 @@ name = "spin" version = "0.9.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" +dependencies = [ + "lock_api", +] [[package]] name = "stable_deref_trait" diff --git a/Cargo.toml b/Cargo.toml index 631b090..1ed34b5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -71,3 +71,4 @@ rustup-toolchain = { version = "0.1.9", optional = true } rustls = "0.23.35" serde_ipld_dagcbor = "0.6.0" rs-car = "0.1" +flume = "0.11.1" diff --git a/examples/basic/src/main.rs b/examples/basic/src/main.rs index 6d9bc30..92b95b1 100644 --- a/examples/basic/src/main.rs +++ b/examples/basic/src/main.rs @@ -62,7 +62,6 @@ impl FeedHandler for MyFeedHandler { } async fn like_post(&mut self, like_uri: Uri, liked_post_uri: Uri) { - // println!("❤️ LIKE: {} likes {}", like_uri.0, liked_post_uri.0); if let Some(post_with_likes) = self .posts .lock() @@ -71,12 +70,10 @@ impl FeedHandler for MyFeedHandler { .find(|p| p.post.uri == liked_post_uri) { post_with_likes.likes.insert(like_uri); - dbg!(post_with_likes.likes.len()); } } async fn delete_like(&mut self, like_uri: Uri) { - println!("💔 DELETE LIKE: {}", like_uri.0); let mut posts = self.posts.lock().await; for post_with_likes in posts.iter_mut() { post_with_likes.likes.remove(&like_uri); diff --git a/examples/sqlite/Cargo.lock b/examples/sqlite/Cargo.lock index 490f419..0f0505a 100644 --- a/examples/sqlite/Cargo.lock +++ b/examples/sqlite/Cargo.lock @@ -2782,7 +2782,7 @@ checksum = "c1e9a774a6c28142ac54bb25d25562e6bcf957493a184f15ad4eebccb23e410a" [[package]] name = "skyfeed" version = "0.6.0" -source = "git+https://github.com/cyypherus/skyfeed.git?rev=eb7fa6abbbfc9fbbed0841db05b2a7c079d95fef#eb7fa6abbbfc9fbbed0841db05b2a7c079d95fef" +source = "git+https://github.com/cyypherus/skyfeed.git?rev=eda67e72785c4eb1186f855b28365f9303e090cc#eda67e72785c4eb1186f855b28365f9303e090cc" dependencies = [ "anyhow", "async-trait", @@ -2861,6 +2861,13 @@ dependencies = [ "skyfeed", "tokio", "whatlang", + "metrics", + "metrics-exporter-prometheus", + "regex", + "rusqlite", + "skyfeed", + "tokio", + "whatlang", ] [[package]] diff --git a/src/feed.rs b/src/feed.rs index 4090d1c..747fe1a 100644 --- a/src/feed.rs +++ b/src/feed.rs @@ -109,11 +109,11 @@ pub trait Feed { })); let feed_server = warp::serve(routes); - let (tx, mut rx) = tokio::sync::mpsc::channel(1000); + let (tx, rx): (flume::Sender, _) = flume::unbounded(); let event_handler = tokio::spawn(async move { let mut h = handler; - while let Some(event) = rx.recv().await { + while let Ok(event) = rx.recv_async().await { match event { FirehoseEvent::Post(post) => { h.insert_post(post).await; diff --git a/src/firehose.rs b/src/firehose.rs index 204ac8c..54a87fe 100644 --- a/src/firehose.rs +++ b/src/firehose.rs @@ -1,7 +1,6 @@ use atrium_api::types::Collection; use futures::StreamExt; use tokio::net::TcpStream; -use tokio::sync::mpsc; use tokio_tungstenite::tungstenite::Message; use tokio_tungstenite::{connect_async, MaybeTlsStream, WebSocketStream}; @@ -203,14 +202,14 @@ pub enum FirehoseEvent { pub struct FirehoseConnector; impl FirehoseConnector { - pub async fn run(tx: mpsc::Sender) -> Result<(), FirehoseError> { + pub async fn run(tx: flume::Sender) -> Result<(), FirehoseError> { let _ = rustls::crypto::aws_lc_rs::default_provider().install_default(); let (stream, _) = connect_async(format!("wss://bsky.network/xrpc/{NSID}")) .await .map_err(|e| FirehoseError::WebSocket(e))?; let subscription = RepoSubscription { stream }; - let (frame_tx, frame_rx) = mpsc::channel(10000); + let (frame_tx, frame_rx) = flume::unbounded(); let receive_task = tokio::spawn(Self::receive_frames(subscription, frame_tx)); let parse_task = tokio::spawn(Self::parse_frames(frame_rx, tx)); @@ -233,10 +232,10 @@ impl FirehoseConnector { async fn receive_frames( mut subscription: RepoSubscription, - frame_tx: mpsc::Sender>, + frame_tx: flume::Sender>, ) -> Result<(), FirehoseError> { while let Some(message) = subscription.next().await { - if frame_tx.send(message).await.is_err() { + if frame_tx.send_async(message).await.is_err() { break; } } @@ -244,10 +243,10 @@ impl FirehoseConnector { } async fn parse_frames( - mut frame_rx: mpsc::Receiver>, - tx: mpsc::Sender, + frame_rx: flume::Receiver>, + tx: flume::Sender, ) -> Result<(), FirehoseError> { - while let Some(message) = frame_rx.recv().await { + while let Ok(message) = frame_rx.recv_async().await { match message { Ok(Frame::Message(Some(t), message)) => { if t.as_str() == "#commit" { @@ -281,7 +280,7 @@ impl FirehoseConnector { async fn handle_commit( commit: &Commit, - tx: &mpsc::Sender, + tx: &flume::Sender, ) -> Result<(), FirehoseError> { let mut blocks = commit.blocks.as_slice(); let (items, _) = rs_car::car_read_all(&mut blocks, true) @@ -344,7 +343,7 @@ impl FirehoseConnector { .filter_map(|lang| serde_json::to_string(&lang).ok()) .collect(), }; - let _ = tx.send(FirehoseEvent::Post(post)).await; + let _ = tx.send_async(FirehoseEvent::Post(post)).await; } Err(_) => { log::error!("Failed to deserialize post record for {}", rkey); @@ -354,7 +353,7 @@ impl FirehoseConnector { } (feed::Post::NSID, "delete") => { let uri = format!("at://{}/{}/{}", commit.repo.as_str(), collection, rkey); - let _ = tx.send(FirehoseEvent::DeletePost(Uri(uri))).await; + let _ = tx.send_async(FirehoseEvent::DeletePost(Uri(uri))).await; } (Like::NSID, "create") => { if let Some((_, item_data)) = items.iter().find(|(cid, _)| { @@ -374,7 +373,7 @@ impl FirehoseConnector { rkey ); let _ = tx - .send(FirehoseEvent::Like( + .send_async(FirehoseEvent::Like( Uri(uri), Uri(record.subject.uri.clone()), )) @@ -388,7 +387,7 @@ impl FirehoseConnector { } (Like::NSID, "delete") => { let uri = format!("at://{}/{}/{}", commit.repo.as_str(), collection, rkey); - let _ = tx.send(FirehoseEvent::DeleteLike(Uri(uri))).await; + let _ = tx.send_async(FirehoseEvent::DeleteLike(Uri(uri))).await; } _ => {} } From 0c9036e108dadcfdd433d8d262a76093d9c981b8 Mon Sep 17 00:00:00 2001 From: cyypherus Date: Mon, 1 Dec 2025 19:44:07 -0700 Subject: [PATCH 23/53] lock --- Cargo.lock | 1452 +++++++++++++++++++++++++--------------------------- 1 file changed, 695 insertions(+), 757 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6ff2b1d..cb0ab48 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,36 +4,36 @@ version = 4 [[package]] name = "addr2line" -version = "0.24.2" +version = "0.25.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1" +checksum = "1b5d307320b3181d6d7954e663bd7c774a838b8220fe0593c86d9fb09f498b4b" dependencies = [ "gimli", ] [[package]] name = "adler2" -version = "2.0.0" +version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" +checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" [[package]] name = "ahash" -version = "0.8.11" +version = "0.8.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" +checksum = "5a15f179cd60c4584b8a8c596927aadc462e27f2ca70c04e0071964a73ba7a75" dependencies = [ "cfg-if", "once_cell", "version_check", - "zerocopy 0.7.35", + "zerocopy", ] [[package]] name = "aho-corasick" -version = "1.1.3" +version = "1.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" +checksum = "ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301" dependencies = [ "memchr", ] @@ -44,12 +44,6 @@ version = "0.2.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" -[[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" @@ -61,9 +55,9 @@ dependencies = [ [[package]] name = "anstream" -version = "0.6.18" +version = "0.6.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8acc5369981196006228e28809f761875c0327210a891e941f4c683b3a99529b" +checksum = "43d5b281e737544384e969a5ccad3f1cdd24b48086a0fc1b2a5262a26b8f4f4a" dependencies = [ "anstyle", "anstyle-parse", @@ -76,37 +70,37 @@ dependencies = [ [[package]] name = "anstyle" -version = "1.0.10" +version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55cc3b69f167a1ef2e161439aa98aed94e6028e5f9a59be9a6ffb47aef1651f9" +checksum = "5192cca8006f1fd4f7237516f40fa183bb07f8fbdfedaa0036de5ea9b0b45e78" [[package]] name = "anstyle-parse" -version = "0.2.6" +version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b2d16507662817a6a20a9ea92df6652ee4f94f914589377d69f3b21bc5798a9" +checksum = "4e7644824f0aa2c7b9384579234ef10eb7efb6a0deb83f9630a49594dd9c15c2" dependencies = [ "utf8parse", ] [[package]] name = "anstyle-query" -version = "1.1.2" +version = "1.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79947af37f4177cfead1110013d678905c37501914fba0efea834c3fe9a8d60c" +checksum = "40c48f72fd53cd289104fc64099abca73db4166ad86ea0b4341abe65af83dadc" dependencies = [ - "windows-sys 0.59.0", + "windows-sys 0.61.2", ] [[package]] name = "anstyle-wincon" -version = "3.0.7" +version = "3.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca3534e77181a9cc07539ad51f2141fe32f6c3ffd4df76db8ad92346b003ae4e" +checksum = "291e6a250ff86cd4a820112fb8898808a366d8f9f58ce16d1f538353ad55747d" dependencies = [ "anstyle", - "once_cell", - "windows-sys 0.59.0", + "once_cell_polyfill", + "windows-sys 0.61.2", ] [[package]] @@ -129,22 +123,22 @@ checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" [[package]] name = "async-compression" -version = "0.4.21" +version = "0.4.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0cf008e5e1a9e9e22a7d3c9a4992e21a350290069e36d8fb72304ed17e8f2d2" +checksum = "0e86f6d3dc9dc4352edeea6b8e499e13e3f5dc3b964d7ca5fd411415a3498473" dependencies = [ - "flate2", + "compression-codecs", + "compression-core", "futures-core", - "memchr", "pin-project-lite", "tokio", ] [[package]] name = "async-lock" -version = "3.4.0" +version = "3.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff6e472cdea888a4bd64f342f09b3f50e1886d32afe8df3d663c01140b811b18" +checksum = "5fd03604047cee9b6ce9de9f70c6cd540a0520c813cbd49bae61f33ab80ed1dc" dependencies = [ "event-listener", "event-listener-strategy", @@ -170,18 +164,18 @@ checksum = "c7c24de15d275a1ecfd47a380fb4d5ec9bfe0933f309ed5e705b775596a3574d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.111", ] [[package]] name = "async-trait" -version = "0.1.88" +version = "0.1.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e539d3fca749fcee5236ab05e93a52867dd549cc157c8cb7f99595f3cedffdb5" +checksum = "9035ad2d096bed7955a320ee7e2230574d28fd3c3a0f186cbea1ff3c7eed5dbb" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.111", ] [[package]] @@ -199,7 +193,7 @@ dependencies = [ "atrium-common", "atrium-xrpc", "chrono", - "http 1.3.1", + "http 1.4.0", "ipld-core", "langtag", "regex", @@ -252,7 +246,7 @@ version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0216ad50ce34e9ff982e171c3659e65dedaa2ed5ac2994524debdc9a9647ffa8" dependencies = [ - "http 1.3.1", + "http 1.4.0", "serde", "serde_html_form", "serde_json", @@ -262,9 +256,9 @@ dependencies = [ [[package]] name = "atrium-xrpc-client" -version = "0.5.11" +version = "0.5.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9bab4287ccef501b3892e1325280e61ae79a96eb9ee63dceabc0ed3bea35f2eb" +checksum = "e099e5171f79faef52364ef0657a4cab086a71b384a779a29597a91b780de0d5" dependencies = [ "atrium-xrpc", "reqwest", @@ -272,9 +266,9 @@ dependencies = [ [[package]] name = "autocfg" -version = "1.4.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" +checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" [[package]] name = "aws-lc-rs" @@ -300,9 +294,9 @@ dependencies = [ [[package]] name = "backtrace" -version = "0.3.74" +version = "0.3.76" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d82cb332cdfaed17ae235a638438ac4d4839913cc2af585c3c6746e8f8bee1a" +checksum = "bb531853791a215d7c62a30daf0dde835f381ab5de4589cfe7c649d2cbe92bd6" dependencies = [ "addr2line", "cfg-if", @@ -310,7 +304,7 @@ dependencies = [ "miniz_oxide", "object", "rustc-demangle", - "windows-targets 0.52.6", + "windows-link", ] [[package]] @@ -319,6 +313,16 @@ version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4cbbc9d0964165b47557570cce6c952866c2678457aca742aafc9fb771d30270" +[[package]] +name = "base256emoji" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5e9430d9a245a77c92176e649af6e275f20839a48389859d1661e9a128d077c" +dependencies = [ + "const-str", + "match-lookup", +] + [[package]] name = "base64" version = "0.21.7" @@ -333,9 +337,9 @@ checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" [[package]] name = "bitflags" -version = "2.9.0" +version = "2.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c8214115b7bf84099f1309324e63141d4c5d7cc26862f97a0a857dbefe165bd" +checksum = "812e12b5285cc515a9c72a5c1d3b6d46a19dac5acfef5265968c166106e31dd3" [[package]] name = "blake2b_simd" @@ -383,9 +387,9 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.17.0" +version = "3.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1628fb46dfa0b37568d12e5edd512553eccf6a22a78e8bde00bb4aed84d5bdbf" +checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43" [[package]] name = "byteorder" @@ -395,51 +399,68 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.10.1" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a" +checksum = "b35204fbdc0b3f4446b89fc1ac2cf84a8a68971995d0bf2e925ec7cd960f9cb3" [[package]] name = "camino" -version = "1.1.9" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b96ec4966b5813e2c0507c1f86115c8c5abaadc3980879c3424042a02fd1ad3" +checksum = "276a59bf2b2c967788139340c9f0c5b12d7fd6630315c15c217e559de85d2609" dependencies = [ - "serde", + "serde_core", ] [[package]] name = "cargo-manifest" -version = "0.17.0" +version = "0.19.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b2ce2075c35e4b492b93e3d5dd1dd3670de553f15045595daef8164ed9a3751" +checksum = "a1d8af896b707212cd0e99c112a78c9497dd32994192a463ed2f7419d29bd8c6" dependencies = [ "serde", - "thiserror 1.0.69", - "toml 0.8.20", + "thiserror 2.0.17", + "toml 0.8.23", ] [[package]] name = "cargo-platform" -version = "0.1.9" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "84982c6c0ae343635a3a4ee6dedef965513735c8b183caa7289fa6e27399ebd4" +dependencies = [ + "serde", +] + +[[package]] +name = "cargo-util-schemas" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e35af189006b9c0f00a064685c727031e3ed2d8020f7ba284d78cc2671bd36ea" +checksum = "7dc1a6f7b5651af85774ae5a34b4e8be397d9cf4bc063b7e6dbd99a841837830" dependencies = [ + "semver", "serde", + "serde-untagged", + "serde-value", + "thiserror 2.0.17", + "toml 0.8.23", + "unicode-xid", + "url", ] [[package]] name = "cargo_metadata" -version = "0.18.1" +version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d886547e41f740c616ae73108f6eb70afe6d940c7bc697cb30f13daec073037" +checksum = "5cfca2aaa699835ba88faf58a06342a314a950d2b9686165e038286c30316868" dependencies = [ "camino", "cargo-platform", + "cargo-util-schemas", "semver", "serde", "serde_json", - "thiserror 1.0.69", + "thiserror 2.0.17", ] [[package]] @@ -453,9 +474,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.2.47" +version = "1.2.48" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd405d82c84ff7f35739f175f67d8b9fb7687a0e84ccdc78bd3568839827cf07" +checksum = "c481bdbf0ed3b892f6f806287d72acd515b352a4ec27a208489b8c1bc839633a" dependencies = [ "find-msvc-tools", "jobserver", @@ -465,17 +486,16 @@ dependencies = [ [[package]] name = "cfg-if" -version = "1.0.0" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" [[package]] name = "chrono" -version = "0.4.40" +version = "0.4.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a7964611d71df112cb1730f2ee67324fcf4d0fc6606acbbe9bfe06df124637c" +checksum = "145052bdd345b87320e369255277e3fb5152762ad123a901ef5c262dd38fe8d2" dependencies = [ - "android-tzdata", "iana-time-zone", "js-sys", "num-traits", @@ -513,9 +533,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.32" +version = "4.5.53" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6088f3ae8c3608d19260cd7445411865a485688711b78b5be70d78cd96136f83" +checksum = "c9e340e012a1bf4935f5282ed1436d1489548e8f72308207ea5df0e23d2d03f8" dependencies = [ "clap_builder", "clap_derive", @@ -523,9 +543,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.32" +version = "4.5.53" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22a7ef7f676155edfb82daa97f99441f3ebf4a58d5e32f295a56259f1b6facc8" +checksum = "d76b5d13eaa18c901fd2f7fca939fefe3a0727a953561fefdf3b2922b8569d00" dependencies = [ "anstream", "anstyle", @@ -535,21 +555,21 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.5.32" +version = "4.5.49" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09176aae279615badda0765c0c0b3f6ed53f4709118af73cf4655d85d1530cd7" +checksum = "2a0b5487afeab2deb2ff4e03a807ad1a03ac532ff5a2cee5d86884440c7f7671" dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.111", ] [[package]] name = "clap_lex" -version = "0.7.4" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f46ad14479a25103f283c0f10005961cf086d8dc42205bb44c46ac563475dca6" +checksum = "a1d728cc89cf3aee9ff92b05e62b19ee65a02b5702cff7d5a377e32c6ae29d8d" [[package]] name = "cmake" @@ -562,9 +582,26 @@ dependencies = [ [[package]] name = "colorchoice" -version = "1.0.3" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75" + +[[package]] +name = "compression-codecs" +version = "0.4.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "302266479cb963552d11bd042013a58ef1adc56768016c8b82b4199488f2d4ad" +dependencies = [ + "compression-core", + "flate2", + "memchr", +] + +[[package]] +name = "compression-core" +version = "0.4.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990" +checksum = "75984efb6ed102a0d42db99afb6c1948f0380d1d91808d5529916e6c08b49d8d" [[package]] name = "concurrent-queue" @@ -587,6 +624,12 @@ dependencies = [ "windows-sys 0.59.0", ] +[[package]] +name = "const-str" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f421161cb492475f1661ddc9815a745a1c894592070661180fdec3d4872e9c3" + [[package]] name = "constant_time_eq" version = "0.3.1" @@ -639,18 +682,18 @@ dependencies = [ [[package]] name = "crc32fast" -version = "1.4.2" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3" +checksum = "9481c1c90cbf2ac953f07c8d4a58aa3945c425b7185c9154d67a65e4230da511" dependencies = [ "cfg-if", ] [[package]] name = "crossbeam-channel" -version = "0.5.14" +version = "0.5.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06ba6d68e24814cb8de6bb986db8222d3a027d15872cabc0d18817bc3c0e4471" +checksum = "82b8f8f868b36967f9606790d1903570de9ceaf870a7bf9fbbd3016d636a2cb2" dependencies = [ "crossbeam-utils", ] @@ -672,9 +715,9 @@ checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" [[package]] name = "crypto-common" -version = "0.1.6" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +checksum = "78c8292055d1c1df0cce5d180393dc8cce0abec0a7102adb6c7b1eef6016d60a" dependencies = [ "generic-array", "typenum", @@ -696,15 +739,15 @@ dependencies = [ [[package]] name = "data-encoding" -version = "2.8.0" +version = "2.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "575f75dfd25738df5b91b8e43e14d44bda14637a58fae779fd2b064f8bf3e010" +checksum = "2a2330da5de22e8a3cb63252ce2abb30116bf5265e89c0e01bc17015ce30a476" [[package]] name = "data-encoding-macro" -version = "0.1.17" +version = "0.1.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f9724adfcf41f45bf652b3995837669d73c4d49a1b5ac1ff82905ac7d9b5558" +checksum = "47ce6c96ea0102f01122a185683611bd5ac8d99e62bc59dd12e6bda344ee673d" dependencies = [ "data-encoding", "data-encoding-macro-internal", @@ -712,12 +755,12 @@ dependencies = [ [[package]] name = "data-encoding-macro-internal" -version = "0.1.15" +version = "0.1.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18e4fdb82bd54a12e42fb58a800dcae6b9e13982238ce2296dc3570b92148e1f" +checksum = "8d162beedaa69905488a8da94f5ac3edb4dd4788b732fadb7bd120b2625c1976" dependencies = [ "data-encoding", - "syn 2.0.100", + "syn 2.0.111", ] [[package]] @@ -738,7 +781,7 @@ checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.111", ] [[package]] @@ -770,9 +813,9 @@ dependencies = [ [[package]] name = "env_filter" -version = "0.1.3" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "186e05a59d4c50738528153b83b0b0194d3a29507dfec16eccd4b342903397d0" +checksum = "1bf3c259d255ca70051b30e2e95b5446cdb8949ac4cd22c0d7fd634d89f568e2" dependencies = [ "log", "regex", @@ -780,9 +823,9 @@ dependencies = [ [[package]] name = "env_logger" -version = "0.11.7" +version = "0.11.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3716d7a920fb4fac5d84e9d4bce8ceb321e9414b4409da61b07b75c1e3d0697" +checksum = "13c863f0904021b108aa8b2f55046443e6b1ebde8fd4a15c399893aae4fa069f" dependencies = [ "anstream", "anstyle", @@ -797,21 +840,32 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" +[[package]] +name = "erased-serde" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89e8918065695684b2b0702da20382d5ae6065cf3327bc2d6436bd49a71ce9f3" +dependencies = [ + "serde", + "serde_core", + "typeid", +] + [[package]] name = "errno" -version = "0.3.10" +version = "0.3.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33d852cb9b869c2a9b3df2f71a3074817f01e1844f839a144f5fcef059a4eb5d" +checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" dependencies = [ "libc", - "windows-sys 0.59.0", + "windows-sys 0.61.2", ] [[package]] name = "event-listener" -version = "5.4.0" +version = "5.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3492acde4c3fc54c845eaab3eed8bd00c7a7d881f78bfc801e43a93dec1331ae" +checksum = "e13b66accf52311f30a0db42147dadea9850cb48cd070028831ae5f5d4b856ab" dependencies = [ "concurrent-queue", "parking", @@ -820,9 +874,9 @@ dependencies = [ [[package]] name = "event-listener-strategy" -version = "0.5.3" +version = "0.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c3e4e0dd3673c1139bf041f3008816d9cf2946bbfac2945c09e523b8d7b05b2" +checksum = "8be9f3dfaaffdae2972880079a491a1a8bb7cbed0b8dd7a347f668b4150a3b93" dependencies = [ "event-listener", "pin-project-lite", @@ -876,9 +930,9 @@ checksum = "3a3076410a55c90011c298b04d0cfa770b00fa04e1e3c97d3f6c9de105a03844" [[package]] name = "flate2" -version = "1.1.0" +version = "1.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11faaf5a5236997af9848be0bef4db95824b1d534ebc64d0f0c6cf3e67bd38dc" +checksum = "bfe33edd8e85a12a67454e37f8c75e730830d83e313556ab9ebf9ee7fbeb3bfb" dependencies = [ "crc32fast", "miniz_oxide", @@ -925,9 +979,9 @@ checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" [[package]] name = "form_urlencoded" -version = "1.2.1" +version = "1.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" +checksum = "cb4cb245038516f5f85277875cdaa4f7d2c9a0fa0468de06ed190163b1581fcf" dependencies = [ "percent-encoding", ] @@ -994,7 +1048,7 @@ checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.111", ] [[package]] @@ -1027,19 +1081,6 @@ dependencies = [ "slab", ] -[[package]] -name = "generator" -version = "0.8.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc6bd114ceda131d3b1d665eba35788690ad37f5916457286b32ab6fd3c438dd" -dependencies = [ - "cfg-if", - "libc", - "log", - "rustversion", - "windows", -] - [[package]] name = "generic-array" version = "0.14.7" @@ -1052,40 +1093,40 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.15" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" +checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592" dependencies = [ "cfg-if", "js-sys", "libc", - "wasi 0.11.0+wasi-snapshot-preview1", + "wasi", "wasm-bindgen", ] [[package]] name = "getrandom" -version = "0.3.1" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43a49c392881ce6d5c3b8cb70f98717b7c07aabbdff06687b9030dbfbe2725f8" +checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd" dependencies = [ "cfg-if", "libc", - "wasi 0.13.3+wasi-0.2.2", - "windows-targets 0.52.6", + "r-efi", + "wasip2", ] [[package]] name = "gimli" -version = "0.31.1" +version = "0.32.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" +checksum = "e629b9b98ef3dd8afe6ca2bd0f89306cec16d43d907889945bc5d6687f2f13c7" [[package]] name = "h2" -version = "0.3.26" +version = "0.3.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81fe527a889e1532da5c525686d96d4c2e74cdd345badf8dfef9f6b39dd5f5e8" +checksum = "0beca50380b1fc32983fc1cb4587bfa4bb9e78fc259aad4a0032d2080309222d" dependencies = [ "bytes", "fnv", @@ -1102,16 +1143,16 @@ dependencies = [ [[package]] name = "h2" -version = "0.4.8" +version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5017294ff4bb30944501348f6f8e42e6ad28f42c8bbef7a74029aff064a4e3c2" +checksum = "f3c0b69cfcb4e1b9f1bf2f53f95f766e4661169728ec61cd3fe5a0166f2d1386" dependencies = [ "atomic-waker", "bytes", "fnv", "futures-core", "futures-sink", - "http 1.3.1", + "http 1.4.0", "indexmap", "slab", "tokio", @@ -1121,9 +1162,9 @@ dependencies = [ [[package]] name = "hashbag" -version = "0.1.12" +version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "98f494b2060b2a8f5e63379e1e487258e014cee1b1725a735816c0107a2e9d93" +checksum = "7040a10f52cba493ddb09926e15d10a9d8a28043708a405931fe4c6f19fac064" [[package]] name = "hashbrown" @@ -1137,22 +1178,28 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.15.2" +version = "0.15.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" +checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1" dependencies = [ "allocator-api2", "equivalent", "foldhash", ] +[[package]] +name = "hashbrown" +version = "0.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100" + [[package]] name = "hashlink" version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7382cf6263419f2d8df38c55d7da83da5c18aef87fc7a7fc1fb1e344edfe14c1" dependencies = [ - "hashbrown 0.15.2", + "hashbrown 0.15.5", ] [[package]] @@ -1204,12 +1251,11 @@ dependencies = [ [[package]] name = "http" -version = "1.3.1" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4a85d31aea989eead29a3aaf9e1115a180df8282431156e533de47660892565" +checksum = "e3ba2a386d7f85a81f119ad7498ebe444d2e22c2af0b86b069416ace48b3311a" dependencies = [ "bytes", - "fnv", "itoa", ] @@ -1231,7 +1277,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" dependencies = [ "bytes", - "http 1.3.1", + "http 1.4.0", ] [[package]] @@ -1242,7 +1288,7 @@ checksum = "b021d93e26becf5dc7e1b75b1bed1fd93124b374ceb73f43d4d4eafec896a64a" dependencies = [ "bytes", "futures-core", - "http 1.3.1", + "http 1.4.0", "http-body 1.0.1", "pin-project-lite", ] @@ -1269,14 +1315,14 @@ dependencies = [ "futures-channel", "futures-core", "futures-util", - "h2 0.3.26", + "h2 0.3.27", "http 0.2.12", "http-body 0.4.6", "httparse", "httpdate", "itoa", "pin-project-lite", - "socket2", + "socket2 0.5.10", "tokio", "tower-service", "tracing", @@ -1285,19 +1331,21 @@ dependencies = [ [[package]] name = "hyper" -version = "1.6.0" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc2b571658e38e0c01b1fdca3bbbe93c00d3d71693ff2770043f8c29bc7d6f80" +checksum = "2ab2d4f250c3d7b1c9fcdff1cece94ea4e2dfbec68614f7b87cb205f24ca9d11" dependencies = [ + "atomic-waker", "bytes", "futures-channel", - "futures-util", - "h2 0.4.8", - "http 1.3.1", + "futures-core", + "h2 0.4.12", + "http 1.4.0", "http-body 1.0.1", "httparse", "itoa", "pin-project-lite", + "pin-utils", "smallvec", "tokio", "want", @@ -1305,13 +1353,12 @@ dependencies = [ [[package]] name = "hyper-rustls" -version = "0.27.5" +version = "0.27.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d191583f3da1305256f22463b9bb0471acad48a4e534a5218b9963e9c1f59b2" +checksum = "e3c93eb611681b207e1fe55d5a71ecf91572ec8a6705cdb6857f7d8d5242cf58" dependencies = [ - "futures-util", - "http 1.3.1", - "hyper 1.6.0", + "http 1.4.0", + "hyper 1.8.1", "hyper-util", "rustls", "rustls-pki-types", @@ -1328,7 +1375,7 @@ checksum = "70206fc6890eaca9fde8a0bf71caa2ddfc9fe045ac9e5c70df101a7dbde866e0" dependencies = [ "bytes", "http-body-util", - "hyper 1.6.0", + "hyper 1.8.1", "hyper-util", "native-tls", "tokio", @@ -1338,35 +1385,43 @@ dependencies = [ [[package]] name = "hyper-util" -version = "0.1.10" +version = "0.1.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df2dcfbe0677734ab2f3ffa7fa7bfd4706bfdc1ef393f2ee30184aed67e631b4" +checksum = "52e9a2a24dc5c6821e71a7030e1e14b7b632acac55c40e9d2e082c621261bb56" dependencies = [ + "base64 0.22.1", "bytes", "futures-channel", + "futures-core", "futures-util", - "http 1.3.1", + "http 1.4.0", "http-body 1.0.1", - "hyper 1.6.0", + "hyper 1.8.1", + "ipnet", + "libc", + "percent-encoding", "pin-project-lite", - "socket2", + "socket2 0.6.1", + "system-configuration", "tokio", "tower-service", "tracing", + "windows-registry", ] [[package]] name = "iana-time-zone" -version = "0.1.61" +version = "0.1.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "235e081f3925a06703c2d0117ea8b91f042756fd6e7a6e5d901e8ca1a996b220" +checksum = "33e57f83510bb73707521ebaffa789ec8caf86f9657cad665b092b581d40e9fb" dependencies = [ "android_system_properties", "core-foundation-sys", "iana-time-zone-haiku", "js-sys", + "log", "wasm-bindgen", - "windows-core 0.52.0", + "windows-core", ] [[package]] @@ -1380,21 +1435,22 @@ dependencies = [ [[package]] name = "icu_collections" -version = "1.5.0" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db2fa452206ebee18c4b5c2274dbf1de17008e874b4dc4f0aea9d01ca79e4526" +checksum = "4c6b649701667bbe825c3b7e6388cb521c23d88644678e83c0c4d0a621a34b43" dependencies = [ "displaydoc", + "potential_utf", "yoke", "zerofrom", "zerovec", ] [[package]] -name = "icu_locid" -version = "1.5.0" +name = "icu_locale_core" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13acbb8371917fc971be86fc8057c41a64b521c184808a698c02acc242dbf637" +checksum = "edba7861004dd3714265b4db54a3c390e880ab658fec5f7db895fae2046b5bb6" dependencies = [ "displaydoc", "litemap", @@ -1403,104 +1459,66 @@ dependencies = [ "zerovec", ] -[[package]] -name = "icu_locid_transform" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01d11ac35de8e40fdeda00d9e1e9d92525f3f9d887cdd7aa81d727596788b54e" -dependencies = [ - "displaydoc", - "icu_locid", - "icu_locid_transform_data", - "icu_provider", - "tinystr", - "zerovec", -] - -[[package]] -name = "icu_locid_transform_data" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fdc8ff3388f852bede6b579ad4e978ab004f139284d7b28715f773507b946f6e" - [[package]] name = "icu_normalizer" -version = "1.5.0" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19ce3e0da2ec68599d193c93d088142efd7f9c5d6fc9b803774855747dc6a84f" +checksum = "5f6c8828b67bf8908d82127b2054ea1b4427ff0230ee9141c54251934ab1b599" dependencies = [ - "displaydoc", "icu_collections", "icu_normalizer_data", "icu_properties", "icu_provider", "smallvec", - "utf16_iter", - "utf8_iter", - "write16", "zerovec", ] [[package]] name = "icu_normalizer_data" -version = "1.5.0" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8cafbf7aa791e9b22bec55a167906f9e1215fd475cd22adfcf660e03e989516" +checksum = "7aedcccd01fc5fe81e6b489c15b247b8b0690feb23304303a9e560f37efc560a" [[package]] name = "icu_properties" -version = "1.5.1" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93d6020766cfc6302c15dbbc9c8778c37e62c14427cb7f6e601d849e092aeef5" +checksum = "e93fcd3157766c0c8da2f8cff6ce651a31f0810eaa1c51ec363ef790bbb5fb99" dependencies = [ - "displaydoc", "icu_collections", - "icu_locid_transform", + "icu_locale_core", "icu_properties_data", "icu_provider", - "tinystr", + "zerotrie", "zerovec", ] [[package]] name = "icu_properties_data" -version = "1.5.0" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67a8effbc3dd3e4ba1afa8ad918d5684b8868b3b26500753effea8d2eed19569" +checksum = "02845b3647bb045f1100ecd6480ff52f34c35f82d9880e029d329c21d1054899" [[package]] name = "icu_provider" -version = "1.5.0" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ed421c8a8ef78d3e2dbc98a973be2f3770cb42b606e3ab18d6237c4dfde68d9" +checksum = "85962cf0ce02e1e0a629cc34e7ca3e373ce20dda4c4d7294bbd0bf1fdb59e614" dependencies = [ "displaydoc", - "icu_locid", - "icu_provider_macros", - "stable_deref_trait", - "tinystr", + "icu_locale_core", "writeable", "yoke", "zerofrom", + "zerotrie", "zerovec", ] -[[package]] -name = "icu_provider_macros" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.100", -] - [[package]] name = "idna" -version = "1.0.3" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "686f825264d630750a544639377bae737628043f20d38bbc029e8f29ea968a7e" +checksum = "3b0875f23caa03898994f6ddc501886a45c7d3d62d04d2d90788d47be1b1e4de" dependencies = [ "idna_adapter", "smallvec", @@ -1509,9 +1527,9 @@ dependencies = [ [[package]] name = "idna_adapter" -version = "1.2.0" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "daca1df1c957320b2cf139ac61e7bd64fed304c5040df000a745aa1de3b4ef71" +checksum = "3acae9609540aa318d1bc588455225fb2085b9ed0c4f6bd0d9d5bcd86f1a0344" dependencies = [ "icu_normalizer", "icu_properties", @@ -1519,24 +1537,22 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.8.0" +version = "2.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3954d50fe15b02142bf25d3b8bdadb634ec3948f103d04ffe3031bc8fe9d7058" +checksum = "0ad4bb2b565bca0645f4d68c5c9af97fba094e9791da685bf83cb5f3ce74acf2" dependencies = [ "equivalent", - "hashbrown 0.15.2", + "hashbrown 0.16.1", ] [[package]] name = "insta" -version = "1.42.2" +version = "1.44.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50259abbaa67d11d2bcafc7ba1d094ed7a0c70e3ce893f0d0997f73558cb3084" +checksum = "b5c943d4415edd8153251b6f197de5eb1640e56d84e8d9159bea190421c73698" dependencies = [ "console", - "linked-hash-map", "once_cell", - "pin-project", "similar", ] @@ -1557,11 +1573,21 @@ version = "2.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "469fb0b9cefa57e3ef31275ee7cacb78f2fdca44e4765491884a2b119d4eb130" +[[package]] +name = "iri-string" +version = "0.7.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4f867b9d1d896b67beb18518eda36fdb77a32ea590de864f1325b294a6d14397" +dependencies = [ + "memchr", + "serde", +] + [[package]] name = "is_terminal_polyfill" -version = "1.70.1" +version = "1.70.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" +checksum = "a6cb138bb79a146c1bd460005623e142ef0181e3d0219cb493e02f7d08a35695" [[package]] name = "itoa" @@ -1571,42 +1597,43 @@ checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" [[package]] name = "jiff" -version = "0.2.4" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d699bc6dfc879fb1bf9bdff0d4c56f0884fc6f0d0eb0fba397a6d00cd9a6b85e" +checksum = "49cce2b81f2098e7e3efc35bc2e0a6b7abec9d34128283d7a26fa8f32a6dbb35" dependencies = [ "jiff-static", "log", "portable-atomic", "portable-atomic-util", - "serde", + "serde_core", ] [[package]] name = "jiff-static" -version = "0.2.4" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d16e75759ee0aa64c57a56acbf43916987b20c77373cb7e808979e02b93c9f9" +checksum = "980af8b43c3ad5d8d349ace167ec8170839f753a42d233ba19e08afe1850fa69" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.111", ] [[package]] name = "jobserver" -version = "0.1.32" +version = "0.1.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48d1dbcbbeb6a7fec7e059840aa538bd62aaccf972c7346c4d9d2059312853d0" +checksum = "9afb3de4395d6b3e67a780b6de64b51c978ecf11cb9a462c66be7d4ca9039d33" dependencies = [ + "getrandom 0.3.4", "libc", ] [[package]] name = "js-sys" -version = "0.3.77" +version = "0.3.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1cfaf33c695fc6e08064efbc1f72ec937429614f25eef83af942d0e227c3a28f" +checksum = "464a3709c7f55f1f721e5389aa6ea4e3bc6aba669353300af094b29ffbdde1d8" dependencies = [ "once_cell", "wasm-bindgen", @@ -1630,17 +1657,11 @@ dependencies = [ "serde", ] -[[package]] -name = "lazy_static" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" - [[package]] name = "libc" -version = "0.2.171" +version = "0.2.177" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c19937216e9d3aa9956d9bb8dfc0b0c8beb6058fc4f7a4dc4d850edf86a237d6" +checksum = "2874a2af47a2325c2001a6e6fad9b16a53b802102b528163885171cf92b15976" [[package]] name = "libipld" @@ -1742,52 +1763,32 @@ dependencies = [ "vcpkg", ] -[[package]] -name = "linked-hash-map" -version = "0.5.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" - [[package]] name = "linux-raw-sys" -version = "0.9.3" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe7db12097d22ec582439daf8618b8fdd1a7bef6270e9af3b1ebcd30893cf413" +checksum = "df1d3c3b53da64cf5760482273a98e575c651a67eec7f77df96b5b642de8f039" [[package]] name = "litemap" -version = "0.7.5" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23fb14cb19457329c82206317a5663005a4d404783dc74f4252769b0d5f42856" +checksum = "6373607a59f0be73a39b6fe456b8192fcc3585f602af20751600e974dd455e77" [[package]] name = "lock_api" -version = "0.4.12" +version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" +checksum = "224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965" dependencies = [ - "autocfg", "scopeguard", ] [[package]] name = "log" -version = "0.4.26" +version = "0.4.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30bde2b3dc3671ae49d8e2e9f044c7c005836e7a023ee57cffa25ab82764bb9e" - -[[package]] -name = "loom" -version = "0.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "419e0dc8046cb947daa77eb95ae174acfbddb7673b4151f56d1eed8e93fbfaca" -dependencies = [ - "cfg-if", - "generator", - "scoped-tls", - "tracing", - "tracing-subscriber", -] +checksum = "34080505efa8e45a4b816c349525ebe327ceaa8559756f0356cba97ef3bf7432" [[package]] name = "lru" @@ -1795,23 +1796,25 @@ version = "0.12.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "234cf4f4a04dc1f57e24b96cc0cd600cf2af460d4161ac5ecdd0af8e1f3b2a38" dependencies = [ - "hashbrown 0.15.2", + "hashbrown 0.15.5", ] [[package]] -name = "matchers" -version = "0.1.0" +name = "match-lookup" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558" +checksum = "1265724d8cb29dbbc2b0f06fffb8bf1a8c0cf73a78eede9ba73a4a66c52a981e" dependencies = [ - "regex-automata 0.1.10", + "proc-macro2", + "quote", + "syn 1.0.109", ] [[package]] name = "memchr" -version = "2.7.4" +version = "2.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" +checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273" [[package]] name = "mime" @@ -1831,43 +1834,43 @@ dependencies = [ [[package]] name = "miniz_oxide" -version = "0.8.5" +version = "0.8.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e3e04debbb59698c15bacbb6d93584a8c0ca9cc3213cb423d31f760d8843ce5" +checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316" dependencies = [ "adler2", + "simd-adler32", ] [[package]] name = "mio" -version = "1.0.3" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2886843bf800fba2e3377cff24abf6379b4c4d5c6681eaf9ea5b0d15090450bd" +checksum = "69d83b0086dc8ecf3ce9ae2874b2d1290252e2a30720bea58a5c6639b0092873" dependencies = [ "libc", - "wasi 0.11.0+wasi-snapshot-preview1", - "windows-sys 0.52.0", + "wasi", + "windows-sys 0.61.2", ] [[package]] name = "moka" -version = "0.12.10" +version = "0.12.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9321642ca94a4282428e6ea4af8cc2ca4eac48ac7a6a4ea8f33f76d0ce70926" +checksum = "8261cd88c312e0004c1d51baad2980c66528dfdb2bee62003e643a4d8f86b077" dependencies = [ "async-lock", "crossbeam-channel", "crossbeam-epoch", "crossbeam-utils", + "equivalent", "event-listener", "futures-util", - "loom", "parking_lot", "portable-atomic", "rustc_version", "smallvec", "tagptr", - "thiserror 1.0.69", "uuid", ] @@ -1891,11 +1894,12 @@ dependencies = [ [[package]] name = "multibase" -version = "0.9.1" +version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b3539ec3c1f04ac9748a260728e855f261b4977f5c3406612c884564f329404" +checksum = "8694bb4835f452b0e3bb06dbebb1d6fc5385b6ca1caf2e55fd165c042390ec77" dependencies = [ "base-x", + "base256emoji", "data-encoding", "data-encoding-macro", ] @@ -1959,7 +1963,7 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6a51313c5820b0b02bd422f4b44776fbf47961755c74ce64afc73bfad10226c3" dependencies = [ - "getrandom 0.2.15", + "getrandom 0.2.16", ] [[package]] @@ -1979,16 +1983,6 @@ dependencies = [ "tempfile", ] -[[package]] -name = "nu-ansi-term" -version = "0.46.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84" -dependencies = [ - "overload", - "winapi", -] - [[package]] name = "num-traits" version = "0.2.19" @@ -2000,24 +1994,30 @@ dependencies = [ [[package]] name = "object" -version = "0.36.7" +version = "0.37.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62948e14d923ea95ea2c7c86c71013138b66525b86bdc08d2dcc262bdb497b87" +checksum = "ff76201f031d8863c38aa7f905eca4f53abbfa15f609db4277d44cd8938f33fe" dependencies = [ "memchr", ] [[package]] name = "once_cell" -version = "1.21.1" +version = "1.21.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d75b0bedcc4fe52caa0e03d9f1151a323e4aa5e2d78ba3580400cd3c9e2bc4bc" +checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" + +[[package]] +name = "once_cell_polyfill" +version = "1.70.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe" [[package]] name = "openssl" -version = "0.10.71" +version = "0.10.75" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e14130c6a98cd258fdcb0fb6d744152343ff729cbfcb28c656a9d12b999fbcd" +checksum = "08838db121398ad17ab8531ce9de97b244589089e290a384c900cb9ff7434328" dependencies = [ "bitflags", "cfg-if", @@ -2036,7 +2036,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.111", ] [[package]] @@ -2047,9 +2047,9 @@ checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e" [[package]] name = "openssl-sys" -version = "0.9.106" +version = "0.9.111" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8bb61ea9811cc39e3c2069f40b8b8e2e70d8569b361f879786cc7ed48b777cdd" +checksum = "82cab2d520aa75e3c58898289429321eb788c3106963d0dc886ec7a5f4adc321" dependencies = [ "cc", "libc", @@ -2058,10 +2058,13 @@ dependencies = [ ] [[package]] -name = "overload" -version = "0.1.1" +name = "ordered-float" +version = "2.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" +checksum = "68f19d67e5a2795c94e73e0bb1cc1a7edeb2e28efd39e2e1c9b7a40c1108b11c" +dependencies = [ + "num-traits", +] [[package]] name = "parking" @@ -2071,9 +2074,9 @@ checksum = "f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba" [[package]] name = "parking_lot" -version = "0.12.3" +version = "0.12.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" +checksum = "93857453250e3077bd71ff98b6a65ea6621a19bb0f559a85248955ac12c45a1a" dependencies = [ "lock_api", "parking_lot_core", @@ -2081,22 +2084,22 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.9.10" +version = "0.9.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" +checksum = "2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1" dependencies = [ "cfg-if", "libc", "redox_syscall", "smallvec", - "windows-targets 0.52.6", + "windows-link", ] [[package]] name = "percent-encoding" -version = "2.3.1" +version = "2.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" +checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" [[package]] name = "pin-project" @@ -2115,7 +2118,7 @@ checksum = "6e918e4ff8c4549eb882f14b3a4bc8c8bc93de829416eacf579f1207a8fbf861" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.111", ] [[package]] @@ -2138,9 +2141,9 @@ checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" [[package]] name = "portable-atomic" -version = "1.11.0" +version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "350e9b48cbc6b0e028b0473b114454c6316e57336ee184ceab6e53f72c178b3e" +checksum = "f84267b20a16ea918e43c6a88433c2d54fa145c92a811b5b047ccbe153674483" [[package]] name = "portable-atomic-util" @@ -2151,13 +2154,22 @@ dependencies = [ "portable-atomic", ] +[[package]] +name = "potential_utf" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b73949432f5e2a09657003c25bca5e19a0e9c84f8058ca374f49e0ebe605af77" +dependencies = [ + "zerovec", +] + [[package]] name = "ppv-lite86" version = "0.2.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9" dependencies = [ - "zerocopy 0.8.23", + "zerocopy", ] [[package]] @@ -2196,9 +2208,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.94" +version = "1.0.103" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a31971752e70b8b2686d7e46ec17fb38dad4051d94024c88df49b667caea9c84" +checksum = "5ee95bc4ef87b8d5ba32e8b7714ccc834865276eab0aed5c9958d00ec45f49e8" dependencies = [ "unicode-ident", ] @@ -2213,7 +2225,7 @@ dependencies = [ "rustdoc-types", "serde", "serde_json", - "thiserror 2.0.12", + "thiserror 2.0.17", ] [[package]] @@ -2227,13 +2239,19 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.40" +version = "1.0.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d" +checksum = "a338cc41d27e6cc6dce6cefc13a0729dfbb81c262b1f519331575dd80ef3067f" dependencies = [ "proc-macro2", ] +[[package]] +name = "r-efi" +version = "5.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" + [[package]] name = "rand" version = "0.8.5" @@ -2281,7 +2299,7 @@ version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" dependencies = [ - "getrandom 0.2.15", + "getrandom 0.2.16", ] [[package]] @@ -2290,67 +2308,52 @@ version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38" dependencies = [ - "getrandom 0.3.1", + "getrandom 0.3.4", ] [[package]] name = "redox_syscall" -version = "0.5.10" +version = "0.5.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b8c0c260b63a8219631167be35e6a988e9554dbd323f8bd08439c8ed1302bd1" +checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" dependencies = [ "bitflags", ] [[package]] name = "regex" -version = "1.11.1" +version = "1.12.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" +checksum = "843bc0191f75f3e22651ae5f1e72939ab2f72a4bc30fa80a066bd66edefc24d4" dependencies = [ "aho-corasick", "memchr", - "regex-automata 0.4.9", - "regex-syntax 0.8.5", + "regex-automata", + "regex-syntax", ] [[package]] name = "regex-automata" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" -dependencies = [ - "regex-syntax 0.6.29", -] - -[[package]] -name = "regex-automata" -version = "0.4.9" +version = "0.4.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908" +checksum = "5276caf25ac86c8d810222b3dbb938e512c55c6831a10f3e6ed1c93b84041f1c" dependencies = [ "aho-corasick", "memchr", - "regex-syntax 0.8.5", + "regex-syntax", ] [[package]] name = "regex-syntax" -version = "0.6.29" +version = "0.8.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" - -[[package]] -name = "regex-syntax" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" +checksum = "7a2d987857b319362043e95f5353c0535c1f58eec5336fdfcf626430af7def58" [[package]] name = "reqwest" -version = "0.12.14" +version = "0.12.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "989e327e510263980e231de548a33e63d34962d29ae61b467389a1a09627a254" +checksum = "9d0946410b9f7b082a427e4ef5c8ff541a88b357bc6c637c40db3a68ac70a36f" dependencies = [ "async-compression", "base64 0.22.1", @@ -2358,38 +2361,35 @@ dependencies = [ "encoding_rs", "futures-core", "futures-util", - "h2 0.4.8", - "http 1.3.1", + "h2 0.4.12", + "http 1.4.0", "http-body 1.0.1", "http-body-util", - "hyper 1.6.0", + "hyper 1.8.1", "hyper-rustls", "hyper-tls", "hyper-util", - "ipnet", "js-sys", "log", "mime", "native-tls", - "once_cell", "percent-encoding", "pin-project-lite", - "rustls-pemfile", + "rustls-pki-types", "serde", "serde_json", "serde_urlencoded", "sync_wrapper", - "system-configuration", "tokio", "tokio-native-tls", "tokio-util", "tower", + "tower-http", "tower-service", "url", "wasm-bindgen", "wasm-bindgen-futures", "web-sys", - "windows-registry", ] [[package]] @@ -2400,7 +2400,7 @@ checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7" dependencies = [ "cc", "cfg-if", - "getrandom 0.2.15", + "getrandom 0.2.16", "libc", "untrusted", "windows-sys 0.52.0", @@ -2440,9 +2440,9 @@ dependencies = [ [[package]] name = "rustc-demangle" -version = "0.1.24" +version = "0.1.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" +checksum = "56f7d92ca342cea22a06f2121d944b4fd82af56988c270852495420f961d4ace" [[package]] name = "rustc_version" @@ -2455,15 +2455,15 @@ dependencies = [ [[package]] name = "rustdoc-json" -version = "0.9.5" +version = "0.9.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e27b4d503f72ab0feb20d2b4968930f21ebf1fc904f8792329f4176f02a65d6" +checksum = "ab44348a3493c8a852182d0da3e6d92fe340dd099a745652f276ebbb2d34a330" dependencies = [ "cargo-manifest", "cargo_metadata", "serde", - "thiserror 2.0.12", - "toml 0.8.20", + "thiserror 2.0.17", + "toml 0.8.23", "tracing", ] @@ -2478,15 +2478,15 @@ dependencies = [ [[package]] name = "rustix" -version = "1.0.2" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7178faa4b75a30e269c71e61c353ce2748cf3d76f0c44c393f4e60abf49b825" +checksum = "cd15f8a2c5551a84d56efdc1cd049089e409ac19a3072d5037a17fd70719ff3e" dependencies = [ "bitflags", "errno", "libc", "linux-raw-sys", - "windows-sys 0.59.0", + "windows-sys 0.61.2", ] [[package]] @@ -2513,23 +2513,14 @@ dependencies = [ "openssl-probe", "rustls-pki-types", "schannel", - "security-framework 3.3.0", -] - -[[package]] -name = "rustls-pemfile" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dce314e5fee3f39953d46bb63bb8a46d40c2f8fb7cc5a3b6cab2bde9721d6e50" -dependencies = [ - "rustls-pki-types", + "security-framework 3.5.1", ] [[package]] name = "rustls-pki-types" -version = "1.13.0" +version = "1.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94182ad936a0c91c324cd46c6511b9510ed16af436d7b5bab34beab0afd55f7a" +checksum = "708c0f9d5f54ba0272468c1d306a52c495b31fa155e91bc25371e6df7996908c" dependencies = [ "zeroize", ] @@ -2552,14 +2543,14 @@ version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2d5715001c3f29532641421aaddb1302cbcbfd7507ed5f3a5dd0ddb5b808a7e0" dependencies = [ - "thiserror 2.0.12", + "thiserror 2.0.17", ] [[package]] name = "rustversion" -version = "1.0.20" +version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eded382c5f5f786b989652c49544c4877d9f015cc22e145a5ea8ea66c2921cd2" +checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" [[package]] name = "ryu" @@ -2569,11 +2560,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.2", ] [[package]] @@ -2603,9 +2594,9 @@ dependencies = [ [[package]] name = "security-framework" -version = "3.3.0" +version = "3.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80fb1d92c5028aa318b4b8bd7302a5bfcf48be96a37fc6fc790f806b0004ee0c" +checksum = "b3297343eaf830f66ede390ea39da1d462b6b0c1b000f420d0a83f898bbbe6ef" dependencies = [ "bitflags", "core-foundation 0.10.1", @@ -2616,9 +2607,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", @@ -2626,53 +2617,87 @@ 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" dependencies = [ "serde", + "serde_core", ] [[package]] name = "serde" -version = "1.0.219" +version = "1.0.228" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6" +checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" dependencies = [ + "serde_core", "serde_derive", ] +[[package]] +name = "serde-untagged" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9faf48a4a2d2693be24c6289dbe26552776eb7737074e6722891fadbe6c5058" +dependencies = [ + "erased-serde", + "serde", + "serde_core", + "typeid", +] + +[[package]] +name = "serde-value" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3a1a3341211875ef120e117ea7fd5228530ae7e7036a779fdc9117be6b3282c" +dependencies = [ + "ordered-float", + "serde", +] + [[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]] +name = "serde_core" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" +dependencies = [ + "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.219" +version = "1.0.228" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00" +checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.111", ] [[package]] name = "serde_html_form" -version = "0.2.7" +version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d2de91cf02bbc07cde38891769ccd5d4f073d22a40683aa4bc7a95781aaa2c4" +checksum = "b2f2d7ff8a2140333718bb329f5c40fc5f0865b84c426183ce14c97d2ab8154f" dependencies = [ "form_urlencoded", "indexmap", "itoa", "ryu", - "serde", + "serde_core", ] [[package]] @@ -2689,21 +2714,22 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.140" +version = "1.0.145" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "20068b6e96dc6c9bd23e01df8827e6c7e1f2fddd43c21810382803c136b99373" +checksum = "402a6f66d8c709116cf22f558eab210f5a50187f702eb4d7e5ef38d9a7f1c79c" dependencies = [ "itoa", "memchr", "ryu", "serde", + "serde_core", ] [[package]] name = "serde_spanned" -version = "0.6.8" +version = "0.6.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87607cb1398ed59d48732e575a4c28a7a8ebf2454b964fe3f224f2afc07909e1" +checksum = "bf41e0cfaf7226dca15e8197172c295a782857fcb97fad1808a166870dee75a3" dependencies = [ "serde", ] @@ -2752,15 +2778,6 @@ dependencies = [ "keccak", ] -[[package]] -name = "sharded-slab" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" -dependencies = [ - "lazy_static", -] - [[package]] name = "shlex" version = "1.3.0" @@ -2769,13 +2786,19 @@ checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" [[package]] name = "signal-hook-registry" -version = "1.4.2" +version = "1.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9e9e0b4211b72e7b8b6e85c807d36c212bdb33ea8587f7569562a84df5465b1" +checksum = "7664a098b8e616bdfcc2dc0e9ac44eb231eedf41db4e9fe95d8d32ec728dedad" dependencies = [ "libc", ] +[[package]] +name = "simd-adler32" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe" + [[package]] name = "similar" version = "2.7.0" @@ -2819,29 +2842,36 @@ dependencies = [ [[package]] name = "slab" -version = "0.4.9" +version = "0.4.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" -dependencies = [ - "autocfg", -] +checksum = "7a2ae44ef20feb57a68b23d846850f861394c2e02dc425a50098ae8c90267589" [[package]] name = "smallvec" -version = "1.14.0" +version = "1.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fcf8323ef1faaee30a44a340193b1ac6814fd9b7b4e88e9d4519a3e4abe1cfd" +checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" [[package]] name = "socket2" -version = "0.5.8" +version = "0.5.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c970269d99b64e60ec3bd6ad27270092a5394c4e309314b18ae3fe575695fbe8" +checksum = "e22376abed350d73dd1cd119b57ffccad95b4e585a7cda43e286245ce23c0678" dependencies = [ "libc", "windows-sys 0.52.0", ] +[[package]] +name = "socket2" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17129e116933cf371d018bb80ae557e889637989d8638274fb25622827b03881" +dependencies = [ + "libc", + "windows-sys 0.60.2", +] + [[package]] name = "spin" version = "0.9.8" @@ -2853,9 +2883,9 @@ dependencies = [ [[package]] name = "stable_deref_trait" -version = "1.2.0" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" +checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596" [[package]] name = "strsim" @@ -2882,9 +2912,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.100" +version = "2.0.111" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b09a44accad81e1ba1cd74a32461ba89dee89095ba17b32f5d03683b1b1fc2a0" +checksum = "390cc9a294ab71bdb1aa2e99d13be9c753cd2d7bd6560c77118597410c4d2e87" dependencies = [ "proc-macro2", "quote", @@ -2914,13 +2944,13 @@ dependencies = [ [[package]] name = "synstructure" -version = "0.13.1" +version = "0.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" +checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.111", ] [[package]] @@ -2952,15 +2982,15 @@ checksum = "7b2093cf4c8eb1e67749a6762251bc9cd836b6fc171623bd0a9d324d37af2417" [[package]] name = "tempfile" -version = "3.19.0" +version = "3.23.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "488960f40a3fd53d72c2a29a58722561dee8afdd175bd88e3db4677d7b2ba600" +checksum = "2d31c77bdf42a745371d260a26ca7163f1e0924b64afa0b688e61b5a9fa02f16" dependencies = [ "fastrand", - "getrandom 0.3.1", + "getrandom 0.3.4", "once_cell", "rustix", - "windows-sys 0.59.0", + "windows-sys 0.61.2", ] [[package]] @@ -2974,11 +3004,11 @@ dependencies = [ [[package]] name = "thiserror" -version = "2.0.12" +version = "2.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "567b8a2dae586314f7be2a752ec7474332959c6460e02bde30d702a66d488708" +checksum = "f63587ca0f12b72a0600bcba1d40081f830876000bb46dd2337a3051618f4fc8" dependencies = [ - "thiserror-impl 2.0.12", + "thiserror-impl 2.0.17", ] [[package]] @@ -2989,35 +3019,25 @@ checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.111", ] [[package]] name = "thiserror-impl" -version = "2.0.12" +version = "2.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f7cf42b4507d8ea322120659672cf1b9dbb93f8f2d4ecfd6e51350ff5b17a1d" +checksum = "3ff15c8ecd7de3849db632e14d18d2571fa09dfc5ed93479bc4485c7a517c913" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", -] - -[[package]] -name = "thread_local" -version = "1.1.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c" -dependencies = [ - "cfg-if", - "once_cell", + "syn 2.0.111", ] [[package]] name = "tinystr" -version = "0.7.6" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9117f5d4db391c1cf6927e7bea3db74b9a1c1add8f7eda9ffd5364f40f57b82f" +checksum = "42d3e9c45c09de15d06dd8acf5f4e0e399e85927b7f00711024eb7ae10fa4869" dependencies = [ "displaydoc", "zerovec", @@ -3025,31 +3045,30 @@ dependencies = [ [[package]] name = "tokio" -version = "1.44.1" +version = "1.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f382da615b842244d4b8738c82ed1275e6c5dd90c459a30941cd07080b06c91a" +checksum = "ff360e02eab121e0bc37a2d3b4d4dc622e6eda3a8e5253d5435ecf5bd4c68408" dependencies = [ - "backtrace", "bytes", "libc", "mio", "parking_lot", "pin-project-lite", "signal-hook-registry", - "socket2", + "socket2 0.6.1", "tokio-macros", - "windows-sys 0.52.0", + "windows-sys 0.61.2", ] [[package]] name = "tokio-macros" -version = "2.5.0" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e06d43f1345a3bcd39f6a56dbb7dcab2ba47e68e8ac134855e7e2bdbaf8cab8" +checksum = "af407857209536a95c8e56f8231ef2c2e2aff839b22e07a1ffcbc617e9db9fa5" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.111", ] [[package]] @@ -3064,9 +3083,9 @@ dependencies = [ [[package]] name = "tokio-rustls" -version = "0.26.2" +version = "0.26.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e727b36a1a0e8b74c376ac2211e40c2c8af09fb4013c60d910495810f008e9b" +checksum = "1729aa945f29d91ba541258c8df89027d5792d85a8841fb65e8bf0f4ede4ef61" dependencies = [ "rustls", "tokio", @@ -3102,9 +3121,9 @@ dependencies = [ [[package]] name = "tokio-util" -version = "0.7.14" +version = "0.7.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b9590b93e6fcc1739458317cccd391ad3955e2bde8913edf6f95f9e65a8f034" +checksum = "2efa149fe76073d6e8fd97ef4f4eca7b67f599660115591483572e406e165594" dependencies = [ "bytes", "futures-core", @@ -3125,9 +3144,9 @@ dependencies = [ [[package]] name = "toml" -version = "0.8.20" +version = "0.8.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd87a5cdd6ffab733b2f74bc4fd7ee5fff6634124999ac278c35fc78c6120148" +checksum = "dc1beb996b9d83529a9e75c17a1686767d148d70663143c7854d8b4a09ced362" dependencies = [ "indexmap", "serde", @@ -3138,26 +3157,33 @@ dependencies = [ [[package]] name = "toml_datetime" -version = "0.6.8" +version = "0.6.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41" +checksum = "22cddaf88f4fbc13c51aebbf5f8eceb5c7c5a9da2ac40a13519eb5b0a0e8f11c" dependencies = [ "serde", ] [[package]] name = "toml_edit" -version = "0.22.24" +version = "0.22.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17b4795ff5edd201c7cd6dca065ae59972ce77d1b80fa0a84d94950ece7d1474" +checksum = "41fe8c660ae4257887cf66394862d21dbca4a6ddd26f04a3560410406a2f819a" dependencies = [ "indexmap", "serde", "serde_spanned", "toml_datetime", + "toml_write", "winnow", ] +[[package]] +name = "toml_write" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d99f8c9a7727884afe522e9bd5edbfc91a3312b36a77b5fb8926e4c31a41801" + [[package]] name = "tower" version = "0.5.2" @@ -3173,6 +3199,24 @@ dependencies = [ "tower-service", ] +[[package]] +name = "tower-http" +version = "0.6.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9cf146f99d442e8e68e585f5d798ccd3cad9a7835b917e09728880a862706456" +dependencies = [ + "bitflags", + "bytes", + "futures-util", + "http 1.4.0", + "http-body 1.0.1", + "iri-string", + "pin-project-lite", + "tower", + "tower-layer", + "tower-service", +] + [[package]] name = "tower-layer" version = "0.3.3" @@ -3187,9 +3231,9 @@ checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" [[package]] name = "tracing" -version = "0.1.41" +version = "0.1.43" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0" +checksum = "2d15d90a0b5c19378952d479dc858407149d7bb45a14de0142f6c534b16fc647" dependencies = [ "log", "pin-project-lite", @@ -3199,52 +3243,22 @@ dependencies = [ [[package]] name = "tracing-attributes" -version = "0.1.28" +version = "0.1.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "395ae124c09f9e6918a2310af6038fba074bcf474ac352496d5910dd59a2226d" +checksum = "7490cfa5ec963746568740651ac6781f701c9c5ea257c58e057f3ba8cf69e8da" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.111", ] [[package]] name = "tracing-core" -version = "0.1.33" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e672c95779cf947c5311f83787af4fa8fffd12fb27e4993211a84bdfd9610f9c" -dependencies = [ - "once_cell", - "valuable", -] - -[[package]] -name = "tracing-log" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3" -dependencies = [ - "log", - "once_cell", - "tracing-core", -] - -[[package]] -name = "tracing-subscriber" -version = "0.3.19" +version = "0.1.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8189decb5ac0fa7bc8b96b7cb9b2701d60d48805aca84a238004d665fcc4008" +checksum = "7a04e24fab5c89c6a36eb8558c9656f30d81de51dfa4d3b45f26b21d61fa0a6c" dependencies = [ - "matchers", - "nu-ansi-term", "once_cell", - "regex", - "sharded-slab", - "smallvec", - "thread_local", - "tracing", - "tracing-core", - "tracing-log", ] [[package]] @@ -3255,7 +3269,7 @@ checksum = "70977707304198400eb4835a78f6a9f928bf41bba420deb8fdb175cd965d77a7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.111", ] [[package]] @@ -3273,7 +3287,7 @@ dependencies = [ "byteorder", "bytes", "data-encoding", - "http 1.3.1", + "http 1.4.0", "httparse", "log", "rand 0.8.5", @@ -3291,22 +3305,28 @@ checksum = "8628dcc84e5a09eb3d8423d6cb682965dea9133204e8fb3efee74c2a0c259442" dependencies = [ "bytes", "data-encoding", - "http 1.3.1", + "http 1.4.0", "httparse", "log", "rand 0.9.2", "rustls", "rustls-pki-types", "sha1", - "thiserror 2.0.12", + "thiserror 2.0.17", "utf-8", ] +[[package]] +name = "typeid" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc7d623258602320d5c55d1bc22793b57daff0ec7efc270ea7d55ce1d5f5471c" + [[package]] name = "typenum" -version = "1.18.0" +version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1dccffe3ce07af9386bfd29e80c0ab1a8205a2fc34e4bcd40364df902cfa8f3f" +checksum = "562d481066bde0658276a35467c4af00bdc6ee726305698a55b86e61d7ad82bb" [[package]] name = "unicase" @@ -3316,9 +3336,9 @@ checksum = "75b844d17643ee918803943289730bec8aac480150456169e647ed0b576ba539" [[package]] name = "unicode-ident" -version = "1.0.18" +version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" +checksum = "9312f7c4f6ff9069b165498234ce8be658059c6728633667c526e27dc2cf1df5" [[package]] name = "unicode-xid" @@ -3356,13 +3376,14 @@ checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" [[package]] name = "url" -version = "2.5.4" +version = "2.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32f8b686cadd1473f4bd0117a5d28d36b1ade384ea9b5069a1c40aefed7fda60" +checksum = "08bc136a29a3d1758e07a9cca267be308aeebf5cfd5a10f3f67ab2097683ef5b" dependencies = [ "form_urlencoded", "idna", "percent-encoding", + "serde", ] [[package]] @@ -3371,12 +3392,6 @@ version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" -[[package]] -name = "utf16_iter" -version = "1.0.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8232dd3cdaed5356e0f716d285e4b40b932ac434100fe9b7e0e8e935b9e6246" - [[package]] name = "utf8_iter" version = "1.0.4" @@ -3391,19 +3406,15 @@ checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" [[package]] name = "uuid" -version = "1.16.0" +version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "458f7a779bf54acc9f347480ac654f68407d3aab21269a6e3c9f922acd9e2da9" +checksum = "e2e054861b4bd027cd373e18e8d8d8e6548085000e41290d95ce0c373a654b4a" dependencies = [ - "getrandom 0.3.1", + "getrandom 0.3.4", + "js-sys", + "wasm-bindgen", ] -[[package]] -name = "valuable" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba73ea9cf16a25df0c8caa16c51acb937d5712a8429db78a3ee29d5dcacd3a65" - [[package]] name = "vcpkg" version = "0.2.15" @@ -3456,50 +3467,37 @@ dependencies = [ [[package]] name = "wasi" -version = "0.11.0+wasi-snapshot-preview1" +version = "0.11.1+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" +checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" [[package]] -name = "wasi" -version = "0.13.3+wasi-0.2.2" +name = "wasip2" +version = "1.0.1+wasi-0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26816d2e1a4a36a2940b96c5296ce403917633dff8f3440e9b236ed6f6bacad2" +checksum = "0562428422c63773dad2c345a1882263bbf4d65cf3f42e90921f787ef5ad58e7" dependencies = [ - "wit-bindgen-rt", + "wit-bindgen", ] [[package]] name = "wasm-bindgen" -version = "0.2.100" +version = "0.2.106" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1edc8929d7499fc4e8f0be2262a241556cfc54a0bea223790e71446f2aab1ef5" +checksum = "0d759f433fa64a2d763d1340820e46e111a7a5ab75f993d1852d70b03dbb80fd" dependencies = [ "cfg-if", "once_cell", "rustversion", "wasm-bindgen-macro", -] - -[[package]] -name = "wasm-bindgen-backend" -version = "0.2.100" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f0a0651a5c2bc21487bde11ee802ccaf4c51935d0d3d42a6101f98161700bc6" -dependencies = [ - "bumpalo", - "log", - "proc-macro2", - "quote", - "syn 2.0.100", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-futures" -version = "0.4.50" +version = "0.4.56" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "555d470ec0bc3bb57890405e5d4322cc9ea83cebb085523ced7be4144dac1e61" +checksum = "836d9622d604feee9e5de25ac10e3ea5f2d65b41eac0d9ce72eb5deae707ce7c" dependencies = [ "cfg-if", "js-sys", @@ -3510,9 +3508,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.100" +version = "0.2.106" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fe63fc6d09ed3792bd0897b314f53de8e16568c2b3f7982f468c0bf9bd0b407" +checksum = "48cb0d2638f8baedbc542ed444afc0644a29166f1595371af4fecf8ce1e7eeb3" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -3520,31 +3518,31 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.100" +version = "0.2.106" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de" +checksum = "cefb59d5cd5f92d9dcf80e4683949f15ca4b511f4ac0a6e14d4e1ac60c6ecd40" dependencies = [ + "bumpalo", "proc-macro2", "quote", - "syn 2.0.100", - "wasm-bindgen-backend", + "syn 2.0.111", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.100" +version = "0.2.106" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a05d73b933a847d6cccdda8f838a22ff101ad9bf93e33684f39c1f5f0eece3d" +checksum = "cbc538057e648b67f72a982e708d485b2efa771e1ac05fec311f9f63e5800db4" dependencies = [ "unicode-ident", ] [[package]] name = "web-sys" -version = "0.3.77" +version = "0.3.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33b6dd2ef9186f1f2072e409e99cd22a975331a6b3591b12c764e0e55c60d5d2" +checksum = "9b32828d774c412041098d182a8b38b16ea816958e07cf40eec2bc080ae137ac" dependencies = [ "js-sys", "wasm-bindgen", @@ -3570,152 +3568,110 @@ dependencies = [ "once_cell", ] -[[package]] -name = "winapi" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" -dependencies = [ - "winapi-i686-pc-windows-gnu", - "winapi-x86_64-pc-windows-gnu", -] - -[[package]] -name = "winapi-i686-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" - -[[package]] -name = "winapi-x86_64-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" - -[[package]] -name = "windows" -version = "0.58.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd04d41d93c4992d421894c18c8b43496aa748dd4c081bac0dc93eb0489272b6" -dependencies = [ - "windows-core 0.58.0", - "windows-targets 0.52.6", -] - -[[package]] -name = "windows-core" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" -dependencies = [ - "windows-targets 0.52.6", -] - [[package]] name = "windows-core" -version = "0.58.0" +version = "0.62.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ba6d44ec8c2591c134257ce647b7ea6b20335bf6379a27dac5f1641fcf59f99" +checksum = "b8e83a14d34d0623b51dce9581199302a221863196a1dde71a7663a4c2be9deb" dependencies = [ "windows-implement", "windows-interface", - "windows-result 0.2.0", - "windows-strings 0.1.0", - "windows-targets 0.52.6", + "windows-link", + "windows-result", + "windows-strings", ] [[package]] name = "windows-implement" -version = "0.58.0" +version = "0.60.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2bbd5b46c938e506ecbce286b6628a02171d56153ba733b6c741fc627ec9579b" +checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.111", ] [[package]] name = "windows-interface" -version = "0.58.0" +version = "0.59.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "053c4c462dc91d3b1504c6fe5a726dd15e216ba718e84a0e46a88fbe5ded3515" +checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.111", ] [[package]] name = "windows-link" -version = "0.1.0" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6dccfd733ce2b1753b03b6d3c65edf020262ea35e20ccdf3e288043e6dd620e3" +checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" [[package]] name = "windows-registry" -version = "0.4.0" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4286ad90ddb45071efd1a66dfa43eb02dd0dfbae1545ad6cc3c51cf34d7e8ba3" +checksum = "02752bf7fbdcce7f2a27a742f798510f3e5ad88dbe84871e5168e2120c3d5720" dependencies = [ - "windows-result 0.3.1", - "windows-strings 0.3.1", - "windows-targets 0.53.0", + "windows-link", + "windows-result", + "windows-strings", ] [[package]] name = "windows-result" -version = "0.2.0" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d1043d8214f791817bab27572aaa8af63732e11bf84aa21a45a78d6c317ae0e" +checksum = "7781fa89eaf60850ac3d2da7af8e5242a5ea78d1a11c49bf2910bb5a73853eb5" dependencies = [ - "windows-targets 0.52.6", + "windows-link", ] [[package]] -name = "windows-result" -version = "0.3.1" +name = "windows-strings" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06374efe858fab7e4f881500e6e86ec8bc28f9462c47e5a9941a0142ad86b189" +checksum = "7837d08f69c77cf6b07689544538e017c1bfcf57e34b4c0ff58e6c2cd3b37091" dependencies = [ "windows-link", ] [[package]] -name = "windows-strings" -version = "0.1.0" +name = "windows-sys" +version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4cd9b125c486025df0eabcb585e62173c6c9eddcec5d117d3b6e8c30e2ee4d10" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ - "windows-result 0.2.0", "windows-targets 0.52.6", ] [[package]] -name = "windows-strings" -version = "0.3.1" +name = "windows-sys" +version = "0.59.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87fa48cc5d406560701792be122a10132491cff9d0aeb23583cc2dcafc847319" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" dependencies = [ - "windows-link", + "windows-targets 0.52.6", ] [[package]] name = "windows-sys" -version = "0.52.0" +version = "0.60.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb" dependencies = [ - "windows-targets 0.52.6", + "windows-targets 0.53.5", ] [[package]] name = "windows-sys" -version = "0.59.0" +version = "0.61.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" dependencies = [ - "windows-targets 0.52.6", + "windows-link", ] [[package]] @@ -3736,18 +3692,19 @@ dependencies = [ [[package]] name = "windows-targets" -version = "0.53.0" +version = "0.53.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1e4c7e8ceaaf9cb7d7507c974735728ab453b67ef8f18febdd7c11fe59dca8b" +checksum = "4945f9f551b88e0d65f3db0bc25c33b8acea4d9e41163edf90dcd0b19f9069f3" dependencies = [ - "windows_aarch64_gnullvm 0.53.0", - "windows_aarch64_msvc 0.53.0", - "windows_i686_gnu 0.53.0", - "windows_i686_gnullvm 0.53.0", - "windows_i686_msvc 0.53.0", - "windows_x86_64_gnu 0.53.0", - "windows_x86_64_gnullvm 0.53.0", - "windows_x86_64_msvc 0.53.0", + "windows-link", + "windows_aarch64_gnullvm 0.53.1", + "windows_aarch64_msvc 0.53.1", + "windows_i686_gnu 0.53.1", + "windows_i686_gnullvm 0.53.1", + "windows_i686_msvc 0.53.1", + "windows_x86_64_gnu 0.53.1", + "windows_x86_64_gnullvm 0.53.1", + "windows_x86_64_msvc 0.53.1", ] [[package]] @@ -3758,9 +3715,9 @@ checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" [[package]] name = "windows_aarch64_gnullvm" -version = "0.53.0" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86b8d5f90ddd19cb4a147a5fa63ca848db3df085e25fee3cc10b39b6eebae764" +checksum = "a9d8416fa8b42f5c947f8482c43e7d89e73a173cead56d044f6a56104a6d1b53" [[package]] name = "windows_aarch64_msvc" @@ -3770,9 +3727,9 @@ checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" [[package]] name = "windows_aarch64_msvc" -version = "0.53.0" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7651a1f62a11b8cbd5e0d42526e55f2c99886c77e007179efff86c2b137e66c" +checksum = "b9d782e804c2f632e395708e99a94275910eb9100b2114651e04744e9b125006" [[package]] name = "windows_i686_gnu" @@ -3782,9 +3739,9 @@ checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" [[package]] name = "windows_i686_gnu" -version = "0.53.0" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1dc67659d35f387f5f6c479dc4e28f1d4bb90ddd1a5d3da2e5d97b42d6272c3" +checksum = "960e6da069d81e09becb0ca57a65220ddff016ff2d6af6a223cf372a506593a3" [[package]] name = "windows_i686_gnullvm" @@ -3794,9 +3751,9 @@ checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" [[package]] name = "windows_i686_gnullvm" -version = "0.53.0" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ce6ccbdedbf6d6354471319e781c0dfef054c81fbc7cf83f338a4296c0cae11" +checksum = "fa7359d10048f68ab8b09fa71c3daccfb0e9b559aed648a8f95469c27057180c" [[package]] name = "windows_i686_msvc" @@ -3806,9 +3763,9 @@ checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" [[package]] name = "windows_i686_msvc" -version = "0.53.0" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "581fee95406bb13382d2f65cd4a908ca7b1e4c2f1917f143ba16efe98a589b5d" +checksum = "1e7ac75179f18232fe9c285163565a57ef8d3c89254a30685b57d83a38d326c2" [[package]] name = "windows_x86_64_gnu" @@ -3818,9 +3775,9 @@ checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" [[package]] name = "windows_x86_64_gnu" -version = "0.53.0" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e55b5ac9ea33f2fc1716d1742db15574fd6fc8dadc51caab1c16a3d3b4190ba" +checksum = "9c3842cdd74a865a8066ab39c8a7a473c0778a3f29370b5fd6b4b9aa7df4a499" [[package]] name = "windows_x86_64_gnullvm" @@ -3830,9 +3787,9 @@ checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" [[package]] name = "windows_x86_64_gnullvm" -version = "0.53.0" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a6e035dd0599267ce1ee132e51c27dd29437f63325753051e71dd9e42406c57" +checksum = "0ffa179e2d07eee8ad8f57493436566c7cc30ac536a3379fdf008f47f6bb7ae1" [[package]] name = "windows_x86_64_msvc" @@ -3842,47 +3799,37 @@ checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] name = "windows_x86_64_msvc" -version = "0.53.0" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486" +checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650" [[package]] name = "winnow" -version = "0.7.4" +version = "0.7.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e97b544156e9bebe1a0ffbc03484fc1ffe3100cbce3ffb17eac35f7cdd7ab36" +checksum = "5a5364e9d77fcdeeaa6062ced926ee3381faa2ee02d3eb83a5c27a8825540829" dependencies = [ "memchr", ] [[package]] -name = "wit-bindgen-rt" -version = "0.33.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3268f3d866458b787f390cf61f4bbb563b922d091359f9608842999eaee3943c" -dependencies = [ - "bitflags", -] - -[[package]] -name = "write16" -version = "1.0.0" +name = "wit-bindgen" +version = "0.46.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d1890f4022759daae28ed4fe62859b1236caebfc61ede2f63ed4e695f3f6d936" +checksum = "f17a85883d4e6d00e8a97c586de764dabcc06133f7f1d55dce5cdc070ad7fe59" [[package]] name = "writeable" -version = "0.5.5" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e9df38ee2d2c3c5948ea468a8406ff0db0b29ae1ffde1bcf20ef305bcc95c51" +checksum = "9edde0db4769d2dc68579893f2306b26c6ecfbe0ef499b013d731b7b9247e0b9" [[package]] name = "yoke" -version = "0.7.5" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "120e6aef9aa629e3d4f52dc8cc43a015c7724194c97dfaf45180d2daf2b77f40" +checksum = "72d6e5c6afb84d73944e5cedb052c4680d5657337201555f9f2a16b7406d4954" dependencies = [ - "serde", "stable_deref_trait", "yoke-derive", "zerofrom", @@ -3890,54 +3837,34 @@ dependencies = [ [[package]] name = "yoke-derive" -version = "0.7.5" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2380878cad4ac9aac1e2435f3eb4020e8374b5f13c296cb75b4620ff8e229154" +checksum = "b659052874eb698efe5b9e8cf382204678a0086ebf46982b79d6ca3182927e5d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", - "synstructure 0.13.1", -] - -[[package]] -name = "zerocopy" -version = "0.7.35" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" -dependencies = [ - "zerocopy-derive 0.7.35", + "syn 2.0.111", + "synstructure 0.13.2", ] [[package]] name = "zerocopy" -version = "0.8.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd97444d05a4328b90e75e503a34bad781f14e28a823ad3557f0750df1ebcbc6" -dependencies = [ - "zerocopy-derive 0.8.23", -] - -[[package]] -name = "zerocopy-derive" -version = "0.7.35" +version = "0.8.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" +checksum = "fd74ec98b9250adb3ca554bdde269adf631549f51d8a8f8f0a10b50f1cb298c3" dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.100", + "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.8.23" +version = "0.8.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6352c01d0edd5db859a63e2605f4ea3183ddbd15e2c4a9e7d32184df75e4f154" +checksum = "d8a8d209fdf45cf5138cbb5a506f6b52522a25afccc534d1475dad8e31105c6a" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.111", ] [[package]] @@ -3957,21 +3884,32 @@ checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", - "synstructure 0.13.1", + "syn 2.0.111", + "synstructure 0.13.2", ] [[package]] name = "zeroize" -version = "1.8.1" +version = "1.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" +checksum = "b97154e67e32c85465826e8bcc1c59429aaaf107c1e4a9e53c8d8ccd5eff88d0" + +[[package]] +name = "zerotrie" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a59c17a5562d507e4b54960e8569ebee33bee890c70aa3fe7b97e85a9fd7851" +dependencies = [ + "displaydoc", + "yoke", + "zerofrom", +] [[package]] name = "zerovec" -version = "0.10.4" +version = "0.11.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa2b893d79df23bfb12d5461018d408ea19dfafe76c2c7ef6d4eba614f8ff079" +checksum = "6c28719294829477f525be0186d13efa9a3c602f7ec202ca9e353d310fb9a002" dependencies = [ "yoke", "zerofrom", @@ -3980,11 +3918,11 @@ dependencies = [ [[package]] name = "zerovec-derive" -version = "0.10.3" +version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6eafa6dfb17584ea3e2bd6e76e0cc15ad7af12b09abdd1ca55961bed9b1063c6" +checksum = "eadce39539ca5cb3985590102671f2567e659fca9666581ad3411d59207951f3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.111", ] From 05888698112e8b2f6a2c85e11f5fdd196f12a2ab Mon Sep 17 00:00:00 2001 From: cyypherus Date: Mon, 1 Dec 2025 20:03:05 -0700 Subject: [PATCH 24/53] fixing bullshit, log warning for queued updates --- examples/sqlite/src/main.rs | 17 ++++++++++------- src/feed.rs | 9 ++++++++- 2 files changed, 18 insertions(+), 8 deletions(-) diff --git a/examples/sqlite/src/main.rs b/examples/sqlite/src/main.rs index c617fdc..7dadcb2 100644 --- a/examples/sqlite/src/main.rs +++ b/examples/sqlite/src/main.rs @@ -1,6 +1,6 @@ use log::{error, info, trace}; use regex::Regex; -use rusqlite::{params, params_from_iter, Connection}; +use rusqlite::{params, Connection}; use skyfeed::{Config, Feed, FeedHandler, FeedResult, Post, Request, Uri}; use std::{sync::Arc, time::Duration}; use tokio::sync::Mutex; @@ -86,22 +86,22 @@ impl FeedHandler for MyFeedHandler { async fn insert_post(&mut self, post: Post) { let detected_language = whatlang::detect_lang(&post.text); let timestamp = post.timestamp.timestamp(); - let feed_type = if post.langs.iter().any(|lang| lang.contains("fr")) + let feed_to_insert = if post.langs.iter().any(|lang| lang.contains("fr")) && detected_language == Some(whatlang::Lang::Fra) && !self.fr_regex.is_match(post.text.as_str()) && post.labels.is_empty() { - Some("fr") + Some(FR_FEED) } else if post.langs.iter().any(|lang| lang.contains("en")) && detected_language == Some(whatlang::Lang::Eng) && !self.my_regex.is_match(post.text.as_str()) { - Some("en") + Some(MY_FEED) } else { None }; - if let Some(feed) = feed_type { + if let Some(feed) = feed_to_insert { trace!("Queuing {} feed post {post:?}", feed); let mut pending = self.pending_posts.lock().await; pending.push(( @@ -128,9 +128,8 @@ impl FeedHandler for MyFeedHandler { } async fn like_post(&mut self, like_uri: Uri, liked_post_uri: Uri) { - trace!("Queuing like: {} on post {}", like_uri.0, liked_post_uri.0); let mut pending = self.pending_likes.lock().await; - for feed in &["fr", "en"] { + for feed in &[FR_FEED, MY_FEED] { pending.push(( liked_post_uri.0.clone(), like_uri.0.clone(), @@ -241,6 +240,7 @@ impl MyFeedHandler { } let posts_to_insert: Vec<_> = pending.drain(..).collect(); + let count = posts_to_insert.len(); drop(pending); let mut db = self.db.lock().await; @@ -258,6 +258,7 @@ impl MyFeedHandler { } tx.commit().expect("Failed to commit transaction"); + trace!("Successfully flushed {} posts", count); } async fn flush_likes(&self) { @@ -267,6 +268,7 @@ impl MyFeedHandler { } let likes_to_insert: Vec<_> = pending.drain(..).collect(); + let count = likes_to_insert.len(); drop(pending); let mut db = self.db.lock().await; @@ -284,6 +286,7 @@ impl MyFeedHandler { } tx.commit().expect("Failed to commit transaction"); + trace!("Successfully flushed {} likes", count); } } diff --git a/src/feed.rs b/src/feed.rs index 747fe1a..fdad531 100644 --- a/src/feed.rs +++ b/src/feed.rs @@ -6,7 +6,7 @@ use atrium_api::app::bsky::feed::get_feed_skeleton::Parameters as FeedSkeletonQu use atrium_api::app::bsky::feed::get_feed_skeleton::ParametersData as FeedSkeletonParameters; use atrium_api::types::Object; use env_logger::Env; -use log::info; +use log::{info, warn}; use std::fmt::Debug; use std::net::SocketAddr; use warp::Filter; @@ -113,7 +113,14 @@ pub trait Feed { let event_handler = tokio::spawn(async move { let mut h = handler; + let mut warning_log_counter = 0usize; while let Ok(event) = rx.recv_async().await { + warning_log_counter += 1; + let waiting_updates = rx.len(); + if waiting_updates >= 100 && warning_log_counter.is_multiple_of(5) { + warning_log_counter = 0; + warn!("{waiting_updates} updates are awaiting processing, your feed handler implementation may not be processing updates quickly enough. This will result in continuously increasing memory usage if it continues!") + } match event { FirehoseEvent::Post(post) => { h.insert_post(post).await; From 79fe3bdec26e04ef66939c0df241fc7f5b41e4cd Mon Sep 17 00:00:00 2001 From: cyypherus Date: Mon, 1 Dec 2025 20:10:08 -0700 Subject: [PATCH 25/53] toml --- examples/sqlite/Cargo.lock | 36 ++++++++++++++++++++++++++++-------- examples/sqlite/Cargo.toml | 4 ++-- 2 files changed, 30 insertions(+), 10 deletions(-) diff --git a/examples/sqlite/Cargo.lock b/examples/sqlite/Cargo.lock index 0f0505a..c79cd90 100644 --- a/examples/sqlite/Cargo.lock +++ b/examples/sqlite/Cargo.lock @@ -896,6 +896,18 @@ dependencies = [ "miniz_oxide", ] +[[package]] +name = "flume" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da0e4dd2a88388a1f4ccc7c9ce104604dab68d9f408dc34cd45823d5a9069095" +dependencies = [ + "futures-core", + "futures-sink", + "nanorand", + "spin", +] + [[package]] name = "fnv" version = "1.0.7" @@ -1044,8 +1056,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592" dependencies = [ "cfg-if", + "js-sys", "libc", "wasi", + "wasm-bindgen", ] [[package]] @@ -1970,6 +1984,15 @@ dependencies = [ "synstructure 0.12.6", ] +[[package]] +name = "nanorand" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a51313c5820b0b02bd422f4b44776fbf47961755c74ce64afc73bfad10226c3" +dependencies = [ + "getrandom 0.2.16", +] + [[package]] name = "native-tls" version = "0.2.14" @@ -2782,7 +2805,7 @@ checksum = "c1e9a774a6c28142ac54bb25d25562e6bcf957493a184f15ad4eebccb23e410a" [[package]] name = "skyfeed" version = "0.6.0" -source = "git+https://github.com/cyypherus/skyfeed.git?rev=eda67e72785c4eb1186f855b28365f9303e090cc#eda67e72785c4eb1186f855b28365f9303e090cc" +source = "git+https://github.com/cyypherus/skyfeed.git?rev=05888698112e8b2f6a2c85e11f5fdd196f12a2ab#05888698112e8b2f6a2c85e11f5fdd196f12a2ab" dependencies = [ "anyhow", "async-trait", @@ -2793,6 +2816,7 @@ dependencies = [ "clap", "dotenv", "env_logger", + "flume", "futures", "ipld-core", "log", @@ -2847,6 +2871,9 @@ name = "spin" version = "0.9.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" +dependencies = [ + "lock_api", +] [[package]] name = "sqlite-feed" @@ -2861,13 +2888,6 @@ dependencies = [ "skyfeed", "tokio", "whatlang", - "metrics", - "metrics-exporter-prometheus", - "regex", - "rusqlite", - "skyfeed", - "tokio", - "whatlang", ] [[package]] diff --git a/examples/sqlite/Cargo.toml b/examples/sqlite/Cargo.toml index 935b986..14e7744 100644 --- a/examples/sqlite/Cargo.toml +++ b/examples/sqlite/Cargo.toml @@ -1,12 +1,12 @@ [package] name = "sqlite-feed" version = "0.1.0" -edition = "2021" +edition = "2024" publish = false [dependencies] log = "0.4.25" -skyfeed = { git = "https://github.com/cyypherus/skyfeed.git", rev = "eb7fa6abbbfc9fbbed0841db05b2a7c079d95fef" } +skyfeed = { git = "https://github.com/cyypherus/skyfeed.git", rev = "05888698112e8b2f6a2c85e11f5fdd196f12a2ab" } # skyfeed = { path = "../.." } tokio = { version = "1.43.0", features = ["full", "time"] } rusqlite = { version = "0.33.0", features = ["bundled"] } From 2570c1a33e53c473cfc1010172a624f06300ea6a Mon Sep 17 00:00:00 2001 From: cyypherus Date: Mon, 1 Dec 2025 20:10:19 -0700 Subject: [PATCH 26/53] toml --- Cargo.toml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 1ed34b5..5f01168 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "skyfeed" version = "0.6.0" -edition = "2021" +edition = "2024" description = "A library for quickly building BlueSky feed generators." repository = "https://github.com/cyypherus/skyfeed" license = "MIT" @@ -57,6 +57,10 @@ atrium-xrpc-client = "0.5.10" chrono = "0.4.39" async-trait = "0.1.81" ipld-core = "0.4.1" +rustls = "0.23.35" +serde_ipld_dagcbor = "0.6.0" +rs-car = "0.1" +flume = "0.11.1" # `examples` feature dependencies rusqlite = { version = "0.33.0", features = ["bundled"], optional = true } @@ -68,7 +72,3 @@ insta = { version = "1.42.1", optional = true } public-api = { version = "0.43.0", optional = true } rustdoc-json = { version = "0.9.4", optional = true } rustup-toolchain = { version = "0.1.9", optional = true } -rustls = "0.23.35" -serde_ipld_dagcbor = "0.6.0" -rs-car = "0.1" -flume = "0.11.1" From d96c9261bad2b8a817f26dac3c2bc9217c8a6198 Mon Sep 17 00:00:00 2001 From: cyypherus Date: Mon, 1 Dec 2025 20:13:17 -0700 Subject: [PATCH 27/53] counter --- examples/sqlite/Cargo.lock | 2 +- examples/sqlite/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/sqlite/Cargo.lock b/examples/sqlite/Cargo.lock index c79cd90..22a6a17 100644 --- a/examples/sqlite/Cargo.lock +++ b/examples/sqlite/Cargo.lock @@ -2805,7 +2805,7 @@ checksum = "c1e9a774a6c28142ac54bb25d25562e6bcf957493a184f15ad4eebccb23e410a" [[package]] name = "skyfeed" version = "0.6.0" -source = "git+https://github.com/cyypherus/skyfeed.git?rev=05888698112e8b2f6a2c85e11f5fdd196f12a2ab#05888698112e8b2f6a2c85e11f5fdd196f12a2ab" +source = "git+https://github.com/cyypherus/skyfeed.git?rev=2570c1a33e53c473cfc1010172a624f06300ea6a#2570c1a33e53c473cfc1010172a624f06300ea6a" dependencies = [ "anyhow", "async-trait", diff --git a/examples/sqlite/Cargo.toml b/examples/sqlite/Cargo.toml index 14e7744..a00786e 100644 --- a/examples/sqlite/Cargo.toml +++ b/examples/sqlite/Cargo.toml @@ -6,7 +6,7 @@ publish = false [dependencies] log = "0.4.25" -skyfeed = { git = "https://github.com/cyypherus/skyfeed.git", rev = "05888698112e8b2f6a2c85e11f5fdd196f12a2ab" } +skyfeed = { git = "https://github.com/cyypherus/skyfeed.git", rev = "2570c1a33e53c473cfc1010172a624f06300ea6a" } # skyfeed = { path = "../.." } tokio = { version = "1.43.0", features = ["full", "time"] } rusqlite = { version = "0.33.0", features = ["bundled"] } From 8ff6f254d940fc71e7726af900ddf9a4c6d25813 Mon Sep 17 00:00:00 2001 From: cyypherus Date: Mon, 1 Dec 2025 20:13:37 -0700 Subject: [PATCH 28/53] counter --- src/feed.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/feed.rs b/src/feed.rs index fdad531..599f6fd 100644 --- a/src/feed.rs +++ b/src/feed.rs @@ -117,9 +117,11 @@ pub trait Feed { while let Ok(event) = rx.recv_async().await { warning_log_counter += 1; let waiting_updates = rx.len(); - if waiting_updates >= 100 && warning_log_counter.is_multiple_of(5) { + if waiting_updates >= 100 && warning_log_counter >= 5 { warning_log_counter = 0; - warn!("{waiting_updates} updates are awaiting processing, your feed handler implementation may not be processing updates quickly enough. This will result in continuously increasing memory usage if it continues!") + warn!( + "{waiting_updates} updates are awaiting processing, your feed handler implementation may not be processing updates quickly enough. This will result in continuously increasing memory usage if it continues!" + ) } match event { FirehoseEvent::Post(post) => { From 94622c84c49439aa1203bbdc06eb1a3cfa6e9969 Mon Sep 17 00:00:00 2001 From: cyypherus Date: Tue, 2 Dec 2025 07:34:13 -0700 Subject: [PATCH 29/53] likes --- examples/sqlite/Cargo.lock | 2 +- examples/sqlite/Cargo.toml | 2 +- examples/sqlite/src/main.rs | 41 +++++++++++++++---------------------- 3 files changed, 19 insertions(+), 26 deletions(-) diff --git a/examples/sqlite/Cargo.lock b/examples/sqlite/Cargo.lock index 22a6a17..bc9c08e 100644 --- a/examples/sqlite/Cargo.lock +++ b/examples/sqlite/Cargo.lock @@ -2805,7 +2805,7 @@ checksum = "c1e9a774a6c28142ac54bb25d25562e6bcf957493a184f15ad4eebccb23e410a" [[package]] name = "skyfeed" version = "0.6.0" -source = "git+https://github.com/cyypherus/skyfeed.git?rev=2570c1a33e53c473cfc1010172a624f06300ea6a#2570c1a33e53c473cfc1010172a624f06300ea6a" +source = "git+https://github.com/cyypherus/skyfeed.git?rev=8ff6f254d940fc71e7726af900ddf9a4c6d25813#8ff6f254d940fc71e7726af900ddf9a4c6d25813" dependencies = [ "anyhow", "async-trait", diff --git a/examples/sqlite/Cargo.toml b/examples/sqlite/Cargo.toml index a00786e..d53c929 100644 --- a/examples/sqlite/Cargo.toml +++ b/examples/sqlite/Cargo.toml @@ -6,7 +6,7 @@ publish = false [dependencies] log = "0.4.25" -skyfeed = { git = "https://github.com/cyypherus/skyfeed.git", rev = "2570c1a33e53c473cfc1010172a624f06300ea6a" } +skyfeed = { git = "https://github.com/cyypherus/skyfeed.git", rev = "8ff6f254d940fc71e7726af900ddf9a4c6d25813" } # skyfeed = { path = "../.." } tokio = { version = "1.43.0", features = ["full", "time"] } rusqlite = { version = "0.33.0", features = ["bundled"] } diff --git a/examples/sqlite/src/main.rs b/examples/sqlite/src/main.rs index 7dadcb2..4d394bb 100644 --- a/examples/sqlite/src/main.rs +++ b/examples/sqlite/src/main.rs @@ -1,8 +1,8 @@ use log::{error, info, trace}; use regex::Regex; -use rusqlite::{params, Connection}; +use rusqlite::{Connection, params}; use skyfeed::{Config, Feed, FeedHandler, FeedResult, Post, Request, Uri}; -use std::{sync::Arc, time::Duration}; +use std::{env, sync::Arc, time::Duration}; use tokio::sync::Mutex; const FR_FEED: &'static str = "fr"; @@ -10,8 +10,8 @@ const MY_FEED: &'static str = "cyys-feed"; #[tokio::main] async fn main() { - let db = Connection::open("feed.db").expect("Failed to open database"); - // let db = Connection::open("/space/feed.db").expect("Failed to open database"); + // let db = Connection::open("feed.db").expect("Failed to open database"); + let db = Connection::open("/space/feed.db").expect("Failed to open database"); initialize_db(&db); let db = Arc::new(Mutex::new(db)); @@ -23,7 +23,6 @@ async fn main() { .build() .unwrap(), my_regex: regex::RegexBuilder::new(r"\b(?i:trump|biden|far[ ]?(left|right)|(left|right)[ ]?wing|republican|(un)?democrat(ic)?|immigration|immigrant|woke|AI|slop|conservative|liberal|racis(t|m)|homophob(e|ic|ia)|xenophob(e|ic|ia)|transphob(e|ic|ia)|slur|israel[i]?|palestin(e|ian)|ukrain(e|ian)|russia(n)?|tech bro|kamala|harris|politic(ian|al)|communis(m|t)|socialis(m|t)|antisemit(e|ic|ism)|anti-semite|anti-semitism|semite|fur(ry|sona)|sona|babyfur|diaper|ageregression|(neo)?[-]?nazi|elon|musk|war crime|whataboutism|GOP|(anti)?[-]?(vaccine|vax|vaxx|vaxxed)|vaccination|covid|coronavirus|pandemic|immunization|(?-i:ICE)|congress(men|women|ional)?|secretary of defense|potus)s?\b") - // .case_insensitive(true) .build() .unwrap(), db: db.clone(), @@ -42,18 +41,18 @@ async fn main() { } }); - // let publisher_did = env::var("PUBLISHER_DID").expect("PUBLISHER_DID env var not set"); - // let feed_generator_hostname = - // env::var("FEED_GENERATOR_HOSTNAME").expect("FEED_GENERATOR_HOSTNAME env var not set"); + let publisher_did = env::var("PUBLISHER_DID").expect("PUBLISHER_DID env var not set"); + let feed_generator_hostname = + env::var("FEED_GENERATOR_HOSTNAME").expect("FEED_GENERATOR_HOSTNAME env var not set"); tokio::join!( feed.start_with_config( vec![FR_FEED, MY_FEED], - // Config { - // publisher_did, - // feed_generator_hostname - // }, - Config::load_env_config(), + Config { + publisher_did, + feed_generator_hostname + }, + // Config::load_env_config(), ([0, 0, 0, 0], 3030) ), cleanup_task @@ -78,7 +77,7 @@ struct MyFeedHandler { my_regex: Regex, db: Arc>, pending_posts: Arc>>, - pending_likes: Arc>>, + pending_likes: Arc>>, batch_size: usize, } @@ -129,13 +128,7 @@ impl FeedHandler for MyFeedHandler { async fn like_post(&mut self, like_uri: Uri, liked_post_uri: Uri) { let mut pending = self.pending_likes.lock().await; - for feed in &[FR_FEED, MY_FEED] { - pending.push(( - liked_post_uri.0.clone(), - like_uri.0.clone(), - feed.to_string(), - )); - } + pending.push((liked_post_uri.0.clone(), like_uri.0.clone())); if pending.len() >= self.batch_size { drop(pending); @@ -276,11 +269,11 @@ impl MyFeedHandler { { let mut stmt = tx.prepare( - "INSERT OR REPLACE INTO likes (post_uri, like_uri) SELECT ?1, ?2 WHERE EXISTS (SELECT 1 FROM posts WHERE uri = ?1 AND feed = ?3)" + "INSERT OR REPLACE INTO likes (post_uri, like_uri) SELECT ?1, ?2 WHERE EXISTS (SELECT 1 FROM posts WHERE uri = ?1)" ).expect("Failed to prepare statement"); - for (post_uri, like_uri, feed) in likes_to_insert { - stmt.execute(params![post_uri, like_uri, feed]) + for (post_uri, like_uri) in likes_to_insert { + stmt.execute(params![post_uri, like_uri]) .expect("Failed to insert like"); } } From c848dc31aa77f934364e471426dd3725fdb63c00 Mon Sep 17 00:00:00 2001 From: cyypherus Date: Tue, 2 Dec 2025 18:16:09 -0700 Subject: [PATCH 30/53] fix query --- examples/sqlite/src/main.rs | 58 ++++++++++++++++++------------------- 1 file changed, 29 insertions(+), 29 deletions(-) diff --git a/examples/sqlite/src/main.rs b/examples/sqlite/src/main.rs index 4d394bb..a9c86aa 100644 --- a/examples/sqlite/src/main.rs +++ b/examples/sqlite/src/main.rs @@ -5,8 +5,8 @@ use skyfeed::{Config, Feed, FeedHandler, FeedResult, Post, Request, Uri}; use std::{env, sync::Arc, time::Duration}; use tokio::sync::Mutex; -const FR_FEED: &'static str = "fr"; -const MY_FEED: &'static str = "cyys-feed"; +const FR_FEED: &str = "fr"; +const MY_FEED: &str = "cyys-feed"; #[tokio::main] async fn main() { @@ -169,34 +169,34 @@ impl FeedHandler for MyFeedHandler { let db = self.db.lock().await; let mut stmt = db - .prepare(&format!( + .prepare( " - WITH ranked_posts AS ( - SELECT - posts.uri, - posts.timestamp, - COUNT(likes.like_uri) AS likes - FROM posts - WHERE posts.feed = ?4 - LEFT JOIN likes ON posts.uri = likes.post_uri - GROUP BY posts.uri - HAVING COUNT(likes.like_uri) > 0 - ), - sorted_posts AS ( - SELECT - uri, - timestamp, - likes, - PERCENT_RANK() OVER (ORDER BY likes DESC) AS rank - FROM ranked_posts - ) - SELECT uri, likes - FROM sorted_posts - WHERE rank <= ?1 - ORDER BY timestamp DESC - LIMIT ?2 OFFSET ?3; - " - )) + WITH ranked_posts AS ( + SELECT + posts.uri, + posts.timestamp, + COUNT(likes.like_uri) AS likes + FROM posts + LEFT JOIN likes ON posts.uri = likes.post_uri + WHERE posts.feed = ?4 + GROUP BY posts.uri + HAVING COUNT(likes.like_uri) > 0 + ), + sorted_posts AS ( + SELECT + uri, + timestamp, + likes, + PERCENT_RANK() OVER (ORDER BY likes DESC) AS rank + FROM ranked_posts + ) + SELECT uri, likes + FROM sorted_posts + WHERE rank <= ?1 + ORDER BY timestamp DESC; + LIMIT ?2 OFFSET ?3 + ", + ) .expect("Failed to prepare statement"); let post_iter = stmt From 650e266edb7086e8793d5c6afeca9cc92189dadb Mon Sep 17 00:00:00 2001 From: cyypherus Date: Tue, 2 Dec 2025 20:07:42 -0700 Subject: [PATCH 31/53] periodic flush instead of threshold based --- examples/sqlite/src/main.rs | 51 +++++++++++++++++++++---------------- src/feed.rs | 2 +- 2 files changed, 30 insertions(+), 23 deletions(-) diff --git a/examples/sqlite/src/main.rs b/examples/sqlite/src/main.rs index a9c86aa..d51508d 100644 --- a/examples/sqlite/src/main.rs +++ b/examples/sqlite/src/main.rs @@ -16,19 +16,20 @@ async fn main() { let db = Arc::new(Mutex::new(db)); + let pending_posts = Arc::new(Mutex::new(Vec::new())); + let pending_likes = Arc::new(Mutex::new(Vec::new())); let mut feed = MyFeed { handler: MyFeedHandler { fr_regex: regex::RegexBuilder::new(r"\\b(macron|le[- ]?pen|mélenchon|fillon|sarkozy|LREM|RN|gilets\s+jaunes|politique|trudeau|libéraux?|conservateurs?|bloc(?:\s+québécois)?|n(?:ouveau\s+)?parti(?:\s+démocratique)?|constitution(?:nel(?:le)?)?|scandale|gouvernement)\b|(extrême\s+(?:droite|gauche))") .case_insensitive(true) .build() .unwrap(), - my_regex: regex::RegexBuilder::new(r"\b(?i:trump|biden|far[ ]?(left|right)|(left|right)[ ]?wing|republican|(un)?democrat(ic)?|immigration|immigrant|woke|AI|slop|conservative|liberal|racis(t|m)|homophob(e|ic|ia)|xenophob(e|ic|ia)|transphob(e|ic|ia)|slur|israel[i]?|palestin(e|ian)|ukrain(e|ian)|russia(n)?|tech bro|kamala|harris|politic(ian|al)|communis(m|t)|socialis(m|t)|antisemit(e|ic|ism)|anti-semite|anti-semitism|semite|fur(ry|sona)|sona|babyfur|diaper|ageregression|(neo)?[-]?nazi|elon|musk|war crime|whataboutism|GOP|(anti)?[-]?(vaccine|vax|vaxx|vaxxed)|vaccination|covid|coronavirus|pandemic|immunization|(?-i:ICE)|congress(men|women|ional)?|secretary of defense|potus)s?\b") + my_regex: regex::RegexBuilder::new(r"\b(?i:trump|biden|far[ ]?(left|right)|(left|right)[ ]?wing|republican|(un)?democrat(ic)?|immigration|immigrant|woke|AI|slop|conservative|liberal|racis(t|m)|homophob(e|ic|ia)|xenophob(e|ic|ia)|transphob(e|ic|ia)|slur|israel[i]?|palestin(e|ian)|ukrain(e|ian)|russia(n)?|tech bro|kamala|harris|politic(ian|al)|communis(m|t)|socialis(m|t)|antisemit(e|ic|ism)|anti-semite|anti-semitism|semite|fur(ry|sona)|sona|babyfur|diaper|ageregression|(neo)?[-]?nazi|elon|musk|war crime|whataboutism|GOP|(anti)?[-]?(vaccine|vax|vaxx|vaxxed)|vaccination|covid|coronavirus|pandemic|immunization|(?-i:ICE)|congress(men|women|ional)?|secretary of defense|(sco|po)tus|FBI)s?\b") .build() .unwrap(), db: db.clone(), - pending_posts: Arc::new(Mutex::new(Vec::new())), - pending_likes: Arc::new(Mutex::new(Vec::new())), - batch_size: 100, + pending_posts:pending_posts.clone(), + pending_likes:pending_likes.clone(), }, }; @@ -40,6 +41,16 @@ async fn main() { cleanup_posts(&db_clone, 50_000).await; } }); + let posts_for_flushing = pending_posts.clone(); + let likes_for_flushing = pending_likes.clone(); + let mut flush_interval = tokio::time::interval(Duration::from_secs(10)); + let flush_task = tokio::spawn(async move { + loop { + flush_interval.tick().await; + MyFeedHandler::flush_posts(&db.clone(), &posts_for_flushing).await; + MyFeedHandler::flush_likes(&db.clone(), &likes_for_flushing).await; + } + }); let publisher_did = env::var("PUBLISHER_DID").expect("PUBLISHER_DID env var not set"); let feed_generator_hostname = @@ -55,7 +66,8 @@ async fn main() { // Config::load_env_config(), ([0, 0, 0, 0], 3030) ), - cleanup_task + cleanup_task, + flush_task ) .1 .expect("Starting tasks failed"); @@ -78,7 +90,6 @@ struct MyFeedHandler { db: Arc>, pending_posts: Arc>>, pending_likes: Arc>>, - batch_size: usize, } impl FeedHandler for MyFeedHandler { @@ -109,11 +120,6 @@ impl FeedHandler for MyFeedHandler { timestamp, feed.to_string(), )); - - if pending.len() >= self.batch_size { - drop(pending); - self.flush_posts().await; - } } } @@ -129,11 +135,6 @@ impl FeedHandler for MyFeedHandler { async fn like_post(&mut self, like_uri: Uri, liked_post_uri: Uri) { let mut pending = self.pending_likes.lock().await; pending.push((liked_post_uri.0.clone(), like_uri.0.clone())); - - if pending.len() >= self.batch_size { - drop(pending); - self.flush_likes().await; - } } async fn delete_like(&mut self, like_uri: Uri) { @@ -226,8 +227,11 @@ impl FeedHandler for MyFeedHandler { } impl MyFeedHandler { - async fn flush_posts(&self) { - let mut pending = self.pending_posts.lock().await; + async fn flush_posts( + db: &Arc>, + pending_posts: &Arc>>, + ) { + let mut pending = pending_posts.lock().await; if pending.is_empty() { return; } @@ -236,7 +240,7 @@ impl MyFeedHandler { let count = posts_to_insert.len(); drop(pending); - let mut db = self.db.lock().await; + let mut db = db.lock().await; let tx = db.transaction().expect("Failed to start transaction"); { @@ -254,8 +258,11 @@ impl MyFeedHandler { trace!("Successfully flushed {} posts", count); } - async fn flush_likes(&self) { - let mut pending = self.pending_likes.lock().await; + async fn flush_likes( + db: &Arc>, + pending_likes: &Arc>>, + ) { + let mut pending = pending_likes.lock().await; if pending.is_empty() { return; } @@ -264,7 +271,7 @@ impl MyFeedHandler { let count = likes_to_insert.len(); drop(pending); - let mut db = self.db.lock().await; + let mut db = db.lock().await; let tx = db.transaction().expect("Failed to start transaction"); { diff --git a/src/feed.rs b/src/feed.rs index 599f6fd..d9e98d8 100644 --- a/src/feed.rs +++ b/src/feed.rs @@ -117,7 +117,7 @@ pub trait Feed { while let Ok(event) = rx.recv_async().await { warning_log_counter += 1; let waiting_updates = rx.len(); - if waiting_updates >= 100 && warning_log_counter >= 5 { + if waiting_updates >= 200 && warning_log_counter >= 5 { warning_log_counter = 0; warn!( "{waiting_updates} updates are awaiting processing, your feed handler implementation may not be processing updates quickly enough. This will result in continuously increasing memory usage if it continues!" From da232bc447e5b75111a6867cd8c577e326f5a6ec Mon Sep 17 00:00:00 2001 From: cyypherus Date: Wed, 3 Dec 2025 19:59:02 -0700 Subject: [PATCH 32/53] fix cleanup, flush & cleanup at once --- examples/sqlite/Cargo.toml | 5 +- examples/sqlite/src/main.rs | 125 +++++++++++++++++------------------- 2 files changed, 63 insertions(+), 67 deletions(-) diff --git a/examples/sqlite/Cargo.toml b/examples/sqlite/Cargo.toml index d53c929..d7f97c6 100644 --- a/examples/sqlite/Cargo.toml +++ b/examples/sqlite/Cargo.toml @@ -4,9 +4,12 @@ version = "0.1.0" edition = "2024" publish = false +[features] +local = [] + [dependencies] log = "0.4.25" -skyfeed = { git = "https://github.com/cyypherus/skyfeed.git", rev = "8ff6f254d940fc71e7726af900ddf9a4c6d25813" } +skyfeed = { git = "https://github.com/cyypherus/skyfeed.git", rev = "650e266edb7086e8793d5c6afeca9cc92189dadb" } # skyfeed = { path = "../.." } tokio = { version = "1.43.0", features = ["full", "time"] } rusqlite = { version = "0.33.0", features = ["bundled"] } diff --git a/examples/sqlite/src/main.rs b/examples/sqlite/src/main.rs index d51508d..a39cd65 100644 --- a/examples/sqlite/src/main.rs +++ b/examples/sqlite/src/main.rs @@ -33,22 +33,17 @@ async fn main() { }, }; - let mut cleanup_interval = tokio::time::interval(Duration::from_secs(120)); let db_clone = db.clone(); - let cleanup_task = tokio::spawn(async move { - loop { - cleanup_interval.tick().await; - cleanup_posts(&db_clone, 50_000).await; - } - }); let posts_for_flushing = pending_posts.clone(); let likes_for_flushing = pending_likes.clone(); let mut flush_interval = tokio::time::interval(Duration::from_secs(10)); let flush_task = tokio::spawn(async move { loop { flush_interval.tick().await; - MyFeedHandler::flush_posts(&db.clone(), &posts_for_flushing).await; - MyFeedHandler::flush_likes(&db.clone(), &likes_for_flushing).await; + flush_posts(&db.clone(), &posts_for_flushing).await; + flush_likes(&db.clone(), &likes_for_flushing).await; + cleanup_posts(&db_clone, FR_FEED, 10_000).await; + cleanup_posts(&db_clone, MY_FEED, 50_000).await; } }); @@ -66,7 +61,6 @@ async fn main() { // Config::load_env_config(), ([0, 0, 0, 0], 3030) ), - cleanup_task, flush_task ) .1 @@ -112,7 +106,7 @@ impl FeedHandler for MyFeedHandler { }; if let Some(feed) = feed_to_insert { - trace!("Queuing {} feed post {post:?}", feed); + // trace!("Queuing {} feed post {post:?}", feed); let mut pending = self.pending_posts.lock().await; pending.push(( post.uri.0.clone(), @@ -226,91 +220,90 @@ impl FeedHandler for MyFeedHandler { } } -impl MyFeedHandler { - async fn flush_posts( - db: &Arc>, - pending_posts: &Arc>>, - ) { - let mut pending = pending_posts.lock().await; - if pending.is_empty() { - return; - } +async fn flush_posts( + db: &Arc>, + pending_posts: &Arc>>, +) { + let mut pending = pending_posts.lock().await; + if pending.is_empty() { + return; + } - let posts_to_insert: Vec<_> = pending.drain(..).collect(); - let count = posts_to_insert.len(); - drop(pending); + let posts_to_insert: Vec<_> = pending.drain(..).collect(); + let count = posts_to_insert.len(); + drop(pending); - let mut db = db.lock().await; - let tx = db.transaction().expect("Failed to start transaction"); + let mut db = db.lock().await; + let tx = db.transaction().expect("Failed to start transaction"); - { - let mut stmt = tx.prepare( - "INSERT OR REPLACE INTO posts (uri, text, timestamp, feed) VALUES (?1, ?2, ?3, ?4)" - ).expect("Failed to prepare statement"); + { + let mut stmt = tx + .prepare( + "INSERT OR REPLACE INTO posts (uri, text, timestamp, feed) VALUES (?1, ?2, ?3, ?4)", + ) + .expect("Failed to prepare statement"); - for (uri, text, timestamp, feed) in posts_to_insert { - stmt.execute(params![uri, text, timestamp, feed]) - .expect("Failed to insert post"); - } + for (uri, text, timestamp, feed) in posts_to_insert { + stmt.execute(params![uri, text, timestamp, feed]) + .expect("Failed to insert post"); } - - tx.commit().expect("Failed to commit transaction"); - trace!("Successfully flushed {} posts", count); } - async fn flush_likes( - db: &Arc>, - pending_likes: &Arc>>, - ) { - let mut pending = pending_likes.lock().await; - if pending.is_empty() { - return; - } + tx.commit().expect("Failed to commit transaction"); + trace!("Successfully flushed {} posts", count); +} - let likes_to_insert: Vec<_> = pending.drain(..).collect(); - let count = likes_to_insert.len(); - drop(pending); +async fn flush_likes( + db: &Arc>, + pending_likes: &Arc>>, +) { + let mut pending = pending_likes.lock().await; + if pending.is_empty() { + return; + } - let mut db = db.lock().await; - let tx = db.transaction().expect("Failed to start transaction"); + let likes_to_insert: Vec<_> = pending.drain(..).collect(); + let count = likes_to_insert.len(); + drop(pending); - { - let mut stmt = tx.prepare( + let mut db = db.lock().await; + let tx = db.transaction().expect("Failed to start transaction"); + + { + let mut stmt = tx.prepare( "INSERT OR REPLACE INTO likes (post_uri, like_uri) SELECT ?1, ?2 WHERE EXISTS (SELECT 1 FROM posts WHERE uri = ?1)" ).expect("Failed to prepare statement"); - for (post_uri, like_uri) in likes_to_insert { - stmt.execute(params![post_uri, like_uri]) - .expect("Failed to insert like"); - } + for (post_uri, like_uri) in likes_to_insert { + stmt.execute(params![post_uri, like_uri]) + .expect("Failed to insert like"); } - - tx.commit().expect("Failed to commit transaction"); - trace!("Successfully flushed {} likes", count); } + + tx.commit().expect("Failed to commit transaction"); + trace!("Successfully flushed {} likes", count); } -async fn cleanup_posts(db: &Arc>, post_limit: usize) { +async fn cleanup_posts(db: &Arc>, feed: &str, post_limit: usize) { let cleaned_posts = db .lock() .await .execute( - &format!( - " + " DELETE FROM posts WHERE uri NOT IN ( SELECT uri FROM posts + WHERE feed = ?1 ORDER BY timestamp DESC - LIMIT {post_limit} + LIMIT ?2 ); - " - ), - [], + ", + params![feed, post_limit], ) .expect("Failed to clean up old posts"); - trace!("Cleaned up {cleaned_posts} posts"); + trace!("Cleaned up {cleaned_posts} posts on {feed}"); } fn initialize_db(db: &Connection) { From 24a3a2913387c6bca775fb1831bab6a8f6597803 Mon Sep 17 00:00:00 2001 From: cyypherus Date: Thu, 4 Dec 2025 19:50:30 -0700 Subject: [PATCH 33/53] move regex to env, yikes, change warn threshold --- .gitignore | 1 + examples/sqlite/Cargo.lock | 2 +- examples/sqlite/src/main.rs | 61 +++++++++++++++++++++++++------------ src/feed.rs | 2 +- 4 files changed, 45 insertions(+), 21 deletions(-) diff --git a/.gitignore b/.gitignore index 1876539..a271ae9 100644 --- a/.gitignore +++ b/.gitignore @@ -8,3 +8,4 @@ traces/ .env *.sh *.db +*regex.txt diff --git a/examples/sqlite/Cargo.lock b/examples/sqlite/Cargo.lock index bc9c08e..2e27f33 100644 --- a/examples/sqlite/Cargo.lock +++ b/examples/sqlite/Cargo.lock @@ -2805,7 +2805,7 @@ checksum = "c1e9a774a6c28142ac54bb25d25562e6bcf957493a184f15ad4eebccb23e410a" [[package]] name = "skyfeed" version = "0.6.0" -source = "git+https://github.com/cyypherus/skyfeed.git?rev=8ff6f254d940fc71e7726af900ddf9a4c6d25813#8ff6f254d940fc71e7726af900ddf9a4c6d25813" +source = "git+https://github.com/cyypherus/skyfeed.git?rev=650e266edb7086e8793d5c6afeca9cc92189dadb#650e266edb7086e8793d5c6afeca9cc92189dadb" dependencies = [ "anyhow", "async-trait", diff --git a/examples/sqlite/src/main.rs b/examples/sqlite/src/main.rs index a39cd65..c3ef9a1 100644 --- a/examples/sqlite/src/main.rs +++ b/examples/sqlite/src/main.rs @@ -1,3 +1,4 @@ +use dotenv::dotenv; use log::{error, info, trace}; use regex::Regex; use rusqlite::{Connection, params}; @@ -10,26 +11,37 @@ const MY_FEED: &str = "cyys-feed"; #[tokio::main] async fn main() { - // let db = Connection::open("feed.db").expect("Failed to open database"); - let db = Connection::open("/space/feed.db").expect("Failed to open database"); + dotenv().expect("No .env"); + let db = Connection::open("feed.db").expect("Failed to open database"); + // let db = Connection::open("/space/feed.db").expect("Failed to open database"); initialize_db(&db); let db = Arc::new(Mutex::new(db)); + let my_feed_regex = env::var("MY_FEED_REGEX").expect("Missing feed regex"); + let fr_feed_regex = env::var("FR_FEED_REGEX").expect("Missing feed regex"); let pending_posts = Arc::new(Mutex::new(Vec::new())); let pending_likes = Arc::new(Mutex::new(Vec::new())); let mut feed = MyFeed { handler: MyFeedHandler { - fr_regex: regex::RegexBuilder::new(r"\\b(macron|le[- ]?pen|mélenchon|fillon|sarkozy|LREM|RN|gilets\s+jaunes|politique|trudeau|libéraux?|conservateurs?|bloc(?:\s+québécois)?|n(?:ouveau\s+)?parti(?:\s+démocratique)?|constitution(?:nel(?:le)?)?|scandale|gouvernement)\b|(extrême\s+(?:droite|gauche))") + fr_threshold: env::var("FR_FEED_THRESHOLD") + .expect("Missing threshold") + .parse::() + .expect("Invalid threshold"), + my_threshold: env::var("MY_FEED_THRESHOLD") + .expect("Missing threshold") + .parse::() + .expect("Invalid threshold"), + fr_regex: regex::RegexBuilder::new(fr_feed_regex.as_str()) .case_insensitive(true) .build() .unwrap(), - my_regex: regex::RegexBuilder::new(r"\b(?i:trump|biden|far[ ]?(left|right)|(left|right)[ ]?wing|republican|(un)?democrat(ic)?|immigration|immigrant|woke|AI|slop|conservative|liberal|racis(t|m)|homophob(e|ic|ia)|xenophob(e|ic|ia)|transphob(e|ic|ia)|slur|israel[i]?|palestin(e|ian)|ukrain(e|ian)|russia(n)?|tech bro|kamala|harris|politic(ian|al)|communis(m|t)|socialis(m|t)|antisemit(e|ic|ism)|anti-semite|anti-semitism|semite|fur(ry|sona)|sona|babyfur|diaper|ageregression|(neo)?[-]?nazi|elon|musk|war crime|whataboutism|GOP|(anti)?[-]?(vaccine|vax|vaxx|vaxxed)|vaccination|covid|coronavirus|pandemic|immunization|(?-i:ICE)|congress(men|women|ional)?|secretary of defense|(sco|po)tus|FBI)s?\b") + my_regex: regex::RegexBuilder::new(my_feed_regex.as_str()) .build() .unwrap(), db: db.clone(), - pending_posts:pending_posts.clone(), - pending_likes:pending_likes.clone(), + pending_posts: pending_posts.clone(), + pending_likes: pending_likes.clone(), }, }; @@ -79,6 +91,8 @@ impl Feed for MyFeed { #[derive(Clone)] struct MyFeedHandler { + fr_threshold: f32, + my_threshold: f32, fr_regex: Regex, my_regex: Regex, db: Arc>, @@ -151,9 +165,9 @@ impl FeedHandler for MyFeedHandler { let posts_per_page = 50; let threshold = if request.feed == FR_FEED { - 0.05 + self.fr_threshold } else if request.feed == MY_FEED { - 0.005 + self.my_threshold } else { error!("Requested a nonexistent feed"); return FeedResult { @@ -289,21 +303,30 @@ async fn cleanup_posts(db: &Arc>, feed: &str, post_limit: usiz .lock() .await .execute( - " - DELETE FROM posts - WHERE uri NOT IN ( - SELECT uri - FROM posts - WHERE feed = ?1 - ORDER BY timestamp DESC - LIMIT ?2 - ); - ", + "DELETE FROM posts + WHERE feed = ?1 + AND uri NOT IN ( + SELECT uri + FROM posts + WHERE feed = ?1 + ORDER BY timestamp DESC + LIMIT ?2 + );", params![feed, post_limit], ) .expect("Failed to clean up old posts"); - trace!("Cleaned up {cleaned_posts} posts on {feed}"); + let remaining_posts = db + .lock() + .await + .query_row( + "SELECT COUNT(*) FROM posts WHERE feed = ?1", + params![feed], + |row| row.get::<_, usize>(0), + ) + .expect("Failed to count remaining posts"); + + info!("Cleaned up {cleaned_posts} posts on {feed}. {remaining_posts} posts remain."); } fn initialize_db(db: &Connection) { diff --git a/src/feed.rs b/src/feed.rs index d9e98d8..8770e73 100644 --- a/src/feed.rs +++ b/src/feed.rs @@ -117,7 +117,7 @@ pub trait Feed { while let Ok(event) = rx.recv_async().await { warning_log_counter += 1; let waiting_updates = rx.len(); - if waiting_updates >= 200 && warning_log_counter >= 5 { + if waiting_updates >= 2000 && warning_log_counter >= 5 { warning_log_counter = 0; warn!( "{waiting_updates} updates are awaiting processing, your feed handler implementation may not be processing updates quickly enough. This will result in continuously increasing memory usage if it continues!" From 3c6abed9656d2ceb0539ee5095dcc8824e8d7533 Mon Sep 17 00:00:00 2001 From: cyypherus Date: Sat, 6 Dec 2025 14:36:25 -0700 Subject: [PATCH 34/53] clippy & other cleanup --- examples/sqlite/Cargo.lock | 3 +- examples/sqlite/Cargo.toml | 3 +- examples/sqlite/src/main.rs | 137 +++++++++++++++++++++--------------- src/bin/verify.rs | 61 ++++++++++------ src/feed.rs | 8 +-- src/firehose.rs | 42 +++++------ src/lib.rs | 2 + src/models.rs | 4 +- 8 files changed, 152 insertions(+), 108 deletions(-) diff --git a/examples/sqlite/Cargo.lock b/examples/sqlite/Cargo.lock index 2e27f33..66e72a4 100644 --- a/examples/sqlite/Cargo.lock +++ b/examples/sqlite/Cargo.lock @@ -2805,7 +2805,7 @@ checksum = "c1e9a774a6c28142ac54bb25d25562e6bcf957493a184f15ad4eebccb23e410a" [[package]] name = "skyfeed" version = "0.6.0" -source = "git+https://github.com/cyypherus/skyfeed.git?rev=650e266edb7086e8793d5c6afeca9cc92189dadb#650e266edb7086e8793d5c6afeca9cc92189dadb" +source = "git+https://github.com/cyypherus/skyfeed.git?rev=24a3a2913387c6bca775fb1831bab6a8f6597803#24a3a2913387c6bca775fb1831bab6a8f6597803" dependencies = [ "anyhow", "async-trait", @@ -2880,6 +2880,7 @@ name = "sqlite-feed" version = "0.1.0" dependencies = [ "chrono", + "dotenv", "log", "metrics", "metrics-exporter-prometheus", diff --git a/examples/sqlite/Cargo.toml b/examples/sqlite/Cargo.toml index d7f97c6..e3aaeee 100644 --- a/examples/sqlite/Cargo.toml +++ b/examples/sqlite/Cargo.toml @@ -9,7 +9,7 @@ local = [] [dependencies] log = "0.4.25" -skyfeed = { git = "https://github.com/cyypherus/skyfeed.git", rev = "650e266edb7086e8793d5c6afeca9cc92189dadb" } +skyfeed = { git = "https://github.com/cyypherus/skyfeed.git", rev = "24a3a2913387c6bca775fb1831bab6a8f6597803" } # skyfeed = { path = "../.." } tokio = { version = "1.43.0", features = ["full", "time"] } rusqlite = { version = "0.33.0", features = ["bundled"] } @@ -18,6 +18,7 @@ regex = "1.11.1" whatlang = "0.16.4" metrics = "0.24.1" metrics-exporter-prometheus = "0.16.2" +dotenv = "0.15.0" [profile.release] lto = true diff --git a/examples/sqlite/src/main.rs b/examples/sqlite/src/main.rs index c3ef9a1..2d1981f 100644 --- a/examples/sqlite/src/main.rs +++ b/examples/sqlite/src/main.rs @@ -1,4 +1,6 @@ -use dotenv::dotenv; +#![allow(clippy::type_complexity)] + +// use dotenv::dotenv; use log::{error, info, trace}; use regex::Regex; use rusqlite::{Connection, params}; @@ -11,9 +13,9 @@ const MY_FEED: &str = "cyys-feed"; #[tokio::main] async fn main() { - dotenv().expect("No .env"); - let db = Connection::open("feed.db").expect("Failed to open database"); - // let db = Connection::open("/space/feed.db").expect("Failed to open database"); + // dotenv().expect("No .env"); + // let db = Connection::open("feed.db").expect("Failed to open database"); + let db = Connection::open("/space/feed.db").expect("Failed to open database"); initialize_db(&db); let db = Arc::new(Mutex::new(db)); @@ -24,14 +26,6 @@ async fn main() { let pending_likes = Arc::new(Mutex::new(Vec::new())); let mut feed = MyFeed { handler: MyFeedHandler { - fr_threshold: env::var("FR_FEED_THRESHOLD") - .expect("Missing threshold") - .parse::() - .expect("Invalid threshold"), - my_threshold: env::var("MY_FEED_THRESHOLD") - .expect("Missing threshold") - .parse::() - .expect("Invalid threshold"), fr_regex: regex::RegexBuilder::new(fr_feed_regex.as_str()) .case_insensitive(true) .build() @@ -55,7 +49,7 @@ async fn main() { flush_posts(&db.clone(), &posts_for_flushing).await; flush_likes(&db.clone(), &likes_for_flushing).await; cleanup_posts(&db_clone, FR_FEED, 10_000).await; - cleanup_posts(&db_clone, MY_FEED, 50_000).await; + cleanup_posts(&db_clone, MY_FEED, 200_000).await; } }); @@ -91,8 +85,6 @@ impl Feed for MyFeed { #[derive(Clone)] struct MyFeedHandler { - fr_threshold: f32, - my_threshold: f32, fr_regex: Regex, my_regex: Regex, db: Arc>, @@ -157,64 +149,66 @@ impl FeedHandler for MyFeedHandler { async fn serve_feed(&self, request: Request) -> FeedResult { info!("Serving {request:?}"); - let start_index = request + let (hours_back, post_offset) = request .cursor .as_deref() - .and_then(|c| c.parse::().ok()) - .unwrap_or(0); - - let posts_per_page = 50; - let threshold = if request.feed == FR_FEED { - self.fr_threshold - } else if request.feed == MY_FEED { - self.my_threshold - } else { + .and_then(|c| { + let parts: Vec<&str> = c.split(':').collect(); + if parts.len() == 2 { + Some(( + parts.first()?.parse::().ok()?, + parts.get(1)?.parse::().ok()?, + )) + } else { + None + } + }) + .unwrap_or((0, 0)); + + let request_limit: usize = request.limit.unwrap_or(100) as usize; + if request.feed != FR_FEED && request.feed != MY_FEED { error!("Requested a nonexistent feed"); return FeedResult { cursor: None, feed: Vec::new(), }; - }; + } let db = self.db.lock().await; let mut stmt = db .prepare( " - WITH ranked_posts AS ( - SELECT - posts.uri, - posts.timestamp, - COUNT(likes.like_uri) AS likes - FROM posts - LEFT JOIN likes ON posts.uri = likes.post_uri - WHERE posts.feed = ?4 - GROUP BY posts.uri - HAVING COUNT(likes.like_uri) > 0 - ), - sorted_posts AS ( - SELECT - uri, - timestamp, - likes, - PERCENT_RANK() OVER (ORDER BY likes DESC) AS rank - FROM ranked_posts - ) - SELECT uri, likes - FROM sorted_posts - WHERE rank <= ?1 - ORDER BY timestamp DESC; - LIMIT ?2 OFFSET ?3 - ", + WITH top_posts AS ( + SELECT + posts.uri, + posts.timestamp, + ROW_NUMBER() OVER (ORDER BY COUNT(likes.like_uri) DESC, posts.timestamp DESC) as rn, + COUNT(likes.like_uri) AS likes + FROM posts + LEFT JOIN likes ON posts.uri = likes.post_uri + WHERE posts.feed = ?2 + AND posts.timestamp >= (strftime('%s', 'now') - ((?1 + 1) * 3600)) + AND posts.timestamp < (strftime('%s', 'now') - (?1 * 3600)) + AND posts.timestamp < (strftime('%s', 'now') - 300) + GROUP BY posts.uri + LIMIT 100 + ) + SELECT uri + FROM top_posts + WHERE rn > ?3 + ORDER BY timestamp DESC + LIMIT ?4 + ", ) .expect("Failed to prepare statement"); let post_iter = stmt .query_map( params![ - threshold, - posts_per_page as i64, - start_index as i64, - request.feed + hours_back, + request.feed, + post_offset as i64, + request_limit as i64 ], |row| row.get::<_, String>(0), ) @@ -222,11 +216,19 @@ impl FeedHandler for MyFeedHandler { let posts: Vec = post_iter.filter_map(|x| x.ok()).map(Uri).collect(); - let next_cursor = if posts.len() == posts_per_page { - Some((start_index + posts_per_page).to_string()) + info!("Returned {} posts for feed {}", posts.len(), request.feed); + + let next_cursor = if posts.len() == request_limit { + let next_offset = post_offset + posts.len(); + if next_offset < 100 { + Some(format!("{}:{}", hours_back, next_offset)) + } else { + Some(format!("{}:0", hours_back + 1)) + } } else { None }; + FeedResult { cursor: next_cursor, feed: posts, @@ -299,6 +301,22 @@ async fn flush_likes( } async fn cleanup_posts(db: &Arc>, feed: &str, post_limit: usize) { + let oldest_timestamp = db + .lock() + .await + .query_row( + "SELECT MIN(timestamp) FROM posts WHERE feed = ?1", + params![feed], + |row| row.get::<_, Option>(0), + ) + .expect("Failed to get oldest post timestamp"); + + let oldest_date = oldest_timestamp.map(|ts| { + chrono::DateTime::::from_timestamp(ts, 0) + .map(|dt| dt.to_rfc3339()) + .unwrap_or_else(|| "Invalid timestamp".to_string()) + }); + let cleaned_posts = db .lock() .await @@ -326,7 +344,10 @@ async fn cleanup_posts(db: &Arc>, feed: &str, post_limit: usiz ) .expect("Failed to count remaining posts"); - info!("Cleaned up {cleaned_posts} posts on {feed}. {remaining_posts} posts remain."); + info!( + "Cleaned up {cleaned_posts} posts on {feed}. Oldest post available: {}. {remaining_posts} posts remain.", + oldest_date.unwrap_or_else(|| "No posts".to_string()) + ); } fn initialize_db(db: &Connection) { diff --git a/src/bin/verify.rs b/src/bin/verify.rs index 2d7b033..b77bf9e 100644 --- a/src/bin/verify.rs +++ b/src/bin/verify.rs @@ -59,26 +59,45 @@ async fn main() { // Extract at-uri and fetch the feed skeleton for feed in describe["feeds"].as_array().expect("Unexpected object") { let at_uri = feed["uri"].as_str().expect("at-uri not found"); - let skeleton_response = client - .get(format!( - "{}/xrpc/app.bsky.feed.getFeedSkeleton", - args.local_url - )) - .query(&[("feed", at_uri), ("limit", "20")]) - .send() - .await - .expect("Feed skeleton failed"); - - let skeleton_body = skeleton_response - .text() - .await - .expect("Failed to read skeleton response text"); - let skeleton: Value = - serde_json::from_str(&skeleton_body).expect("Failed to parse skeleton JSON"); - - println!( - "Feed Skeleton Response:\n{}", - serde_json::to_string_pretty(&skeleton).expect("Failed to pretty print skeleton JSON") - ); + let mut cursor: Option = None; + + for page in 0..2 { + let mut query = vec![("feed", at_uri.to_string()), ("limit", "20".to_string())]; + if let Some(ref c) = cursor { + query.push(("cursor", c.clone())); + } + + let skeleton_response = client + .get(format!( + "{}/xrpc/app.bsky.feed.getFeedSkeleton", + args.local_url + )) + .query(&query) + .send() + .await + .expect("Feed skeleton failed"); + + let skeleton_body = skeleton_response + .text() + .await + .expect("Failed to read skeleton response text"); + let skeleton: Value = + serde_json::from_str(&skeleton_body).expect("Failed to parse skeleton JSON"); + + println!( + "Feed Skeleton Response (Page {}):\n{}", + page + 1, + serde_json::to_string_pretty(&skeleton).expect("Failed to pretty print skeleton JSON") + ); + + // Extract cursor for next iteration + cursor = skeleton["cursor"] + .as_str() + .map(|s| s.to_string()); + + if cursor.is_none() { + break; + } + } } } diff --git a/src/feed.rs b/src/feed.rs index 8770e73..ada4bb1 100644 --- a/src/feed.rs +++ b/src/feed.rs @@ -84,7 +84,7 @@ pub trait Feed { let api = did_json.or(describe_feed_generator).or(get_feed_skeleton); - info!("Serving feed on {}", format!("{:?}", address)); + info!("Serving feed on {:?}", address); let routes = api.with(warp::log::custom(|info| { let method = info.method(); @@ -125,7 +125,7 @@ pub trait Feed { } match event { FirehoseEvent::Post(post) => { - h.insert_post(post).await; + h.insert_post(*post).await; } FirehoseEvent::DeletePost(uri) => { h.delete_post(uri).await; @@ -180,7 +180,7 @@ async fn describe_feed_generator( uri: format!( "at://{}/app.bsky.feed.generator/{}", config.publisher_did, - name.as_ref().to_string() + name.as_ref() ), }) }) @@ -197,7 +197,7 @@ async fn get_feed_skeleton( .serve_feed(Request { cursor: query.cursor.clone(), feed: query.feed.split("/").last().unwrap_or("").to_string(), - limit: query.limit, + limit: query.limit.map(|l| l.into()), }) .await; Ok::(warp::reply::json(&FeedSkeleton { diff --git a/src/firehose.rs b/src/firehose.rs index 54a87fe..52f4a89 100644 --- a/src/firehose.rs +++ b/src/firehose.rs @@ -2,14 +2,14 @@ use atrium_api::types::Collection; use futures::StreamExt; use tokio::net::TcpStream; use tokio_tungstenite::tungstenite::Message; -use tokio_tungstenite::{connect_async, MaybeTlsStream, WebSocketStream}; +use tokio_tungstenite::{MaybeTlsStream, WebSocketStream, connect_async}; use atrium_api::app::bsky::feed::{self, Like}; use atrium_api::com::atproto::sync::subscribe_repos::{Commit, NSID}; use atrium_api::types::CidLink; -use crate::models::{Did, Embed, Label, Post, Uri}; use crate::Cid; +use crate::models::{Did, Embed, Label, Post, Uri}; use chrono::DateTime; mod frames { @@ -43,20 +43,20 @@ mod frames { type Error = FrameError; fn try_from(value: Ipld) -> Result>::Error> { - if let Ipld::Map(map) = value { - if let Some(Ipld::Integer(i)) = map.get("op") { - match i { - 1 => { - let t = if let Some(Ipld::String(s)) = map.get("t") { - Some(s.clone()) - } else { - None - }; - return Ok(FrameHeader::Message(t)); - } - -1 => return Ok(FrameHeader::Error), - _ => {} + if let Ipld::Map(map) = value + && let Some(Ipld::Integer(i)) = map.get("op") + { + match i { + 1 => { + let t = if let Some(Ipld::String(s)) = map.get("t") { + Some(s.clone()) + } else { + None + }; + return Ok(FrameHeader::Message(t)); } + -1 => return Ok(FrameHeader::Error), + _ => {} } } Err(FrameError::InvalidFrameType) @@ -112,7 +112,7 @@ mod frames { use super::*; fn serialized_data(s: &str) -> Vec { - assert!(s.len() % 2 == 0); + assert!(s.len().is_multiple_of(2)); let b2u = |b: u8| match b { b'0'..=b'9' => b - b'0', b'a'..=b'f' => b - b'a' + 10, @@ -193,7 +193,7 @@ impl std::fmt::Display for FirehoseError { impl std::error::Error for FirehoseError {} pub enum FirehoseEvent { - Post(Post), + Post(Box), DeletePost(Uri), Like(Uri, Uri), DeleteLike(Uri), @@ -206,7 +206,7 @@ impl FirehoseConnector { let _ = rustls::crypto::aws_lc_rs::default_provider().install_default(); let (stream, _) = connect_async(format!("wss://bsky.network/xrpc/{NSID}")) .await - .map_err(|e| FirehoseError::WebSocket(e))?; + .map_err(FirehoseError::WebSocket)?; let subscription = RepoSubscription { stream }; let (frame_tx, frame_rx) = flume::unbounded(); @@ -316,7 +316,7 @@ impl FirehoseConnector { DateTime::parse_from_rfc3339(record.created_at.as_str()) .ok() .map(|dt| dt.with_timezone(&chrono::Utc)) - .unwrap_or_else(|| chrono::Utc::now()); + .unwrap_or_else(chrono::Utc::now); let cid_str = match serde_json::to_string(&op.cid) { Ok(s) => s, @@ -343,7 +343,7 @@ impl FirehoseConnector { .filter_map(|lang| serde_json::to_string(&lang).ok()) .collect(), }; - let _ = tx.send_async(FirehoseEvent::Post(post)).await; + let _ = tx.send_async(FirehoseEvent::Post(Box::new(post))).await; } Err(_) => { log::error!("Failed to deserialize post record for {}", rkey); @@ -405,7 +405,7 @@ impl RepoSubscription { match self.stream.next().await { Some(Ok(Message::Binary(data))) => { let slice: &[u8] = &data; - Some(Frame::try_from(slice).map_err(|e| FirehoseError::Frame(e))) + Some(Frame::try_from(slice).map_err(FirehoseError::Frame)) } Some(Ok(_)) | None => None, Some(Err(e)) => Some(Err(FirehoseError::WebSocket(e))), diff --git a/src/lib.rs b/src/lib.rs index 398e90b..22586fb 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,3 +1,5 @@ +#![allow(clippy::type_complexity)] + mod config; mod feed; mod feed_handler; diff --git a/src/models.rs b/src/models.rs index a424b7c..81ee1be 100644 --- a/src/models.rs +++ b/src/models.rs @@ -3,7 +3,7 @@ use atrium_api::{ embed::record_with_media::MainMediaRefs, feed::post::{RecordEmbedRefs, RecordLabelsRefs}, }, - types::{BlobRef, LimitedNonZeroU8, Object, TypedBlobRef, Union}, + types::{BlobRef, Object, TypedBlobRef, Union}, }; use chrono::{DateTime, Utc}; use log::trace; @@ -12,7 +12,7 @@ use log::trace; pub struct Request { pub cursor: Option, pub feed: String, - pub limit: Option>, + pub limit: Option, } #[derive(Debug, Clone)] From ae44adf7f16aa259c83f6480a491742d9810d260 Mon Sep 17 00:00:00 2001 From: cyypherus Date: Sat, 6 Dec 2025 15:29:39 -0700 Subject: [PATCH 35/53] reworking api --- Cargo.lock | 253 +++++++++------------------------------------ Cargo.toml | 3 +- src/feed.rs | 289 ++++++++++++++++++++++++++++------------------------ 3 files changed, 203 insertions(+), 342 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index cb0ab48..3d850c0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -193,7 +193,7 @@ dependencies = [ "atrium-common", "atrium-xrpc", "chrono", - "http 1.4.0", + "http", "ipld-core", "langtag", "regex", @@ -246,7 +246,7 @@ version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0216ad50ce34e9ff982e171c3659e65dedaa2ed5ac2994524debdc9a9647ffa8" dependencies = [ - "http 1.4.0", + "http", "serde", "serde_html_form", "serde_json", @@ -323,12 +323,6 @@ dependencies = [ "match-lookup", ] -[[package]] -name = "base64" -version = "0.21.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" - [[package]] name = "base64" version = "0.22.1" @@ -1122,25 +1116,6 @@ version = "0.32.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e629b9b98ef3dd8afe6ca2bd0f89306cec16d43d907889945bc5d6687f2f13c7" -[[package]] -name = "h2" -version = "0.3.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0beca50380b1fc32983fc1cb4587bfa4bb9e78fc259aad4a0032d2080309222d" -dependencies = [ - "bytes", - "fnv", - "futures-core", - "futures-sink", - "futures-util", - "http 0.2.12", - "indexmap", - "slab", - "tokio", - "tokio-util", - "tracing", -] - [[package]] name = "h2" version = "0.4.12" @@ -1152,7 +1127,7 @@ dependencies = [ "fnv", "futures-core", "futures-sink", - "http 1.4.0", + "http", "indexmap", "slab", "tokio", @@ -1204,14 +1179,14 @@ dependencies = [ [[package]] name = "headers" -version = "0.3.9" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06683b93020a07e3dbcf5f8c0f6d40080d725bea7936fc01ad345c01b97dc270" +checksum = "b3314d5adb5d94bcdf56771f2e50dbbc80bb4bdf88967526706205ac9eff24eb" dependencies = [ - "base64 0.21.7", + "base64", "bytes", "headers-core", - "http 0.2.12", + "http", "httpdate", "mime", "sha1", @@ -1219,11 +1194,11 @@ dependencies = [ [[package]] name = "headers-core" -version = "0.2.0" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7f66481bfee273957b1f20485a4ff3362987f85b2c236580d81b4eb7a326429" +checksum = "54b4a22553d4242c49fddb9ba998a99962b5cc6f22cb5a3482bec22522403ce4" dependencies = [ - "http 0.2.12", + "http", ] [[package]] @@ -1238,17 +1213,6 @@ version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" -[[package]] -name = "http" -version = "0.2.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1" -dependencies = [ - "bytes", - "fnv", - "itoa", -] - [[package]] name = "http" version = "1.4.0" @@ -1259,17 +1223,6 @@ dependencies = [ "itoa", ] -[[package]] -name = "http-body" -version = "0.4.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" -dependencies = [ - "bytes", - "http 0.2.12", - "pin-project-lite", -] - [[package]] name = "http-body" version = "1.0.1" @@ -1277,7 +1230,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" dependencies = [ "bytes", - "http 1.4.0", + "http", ] [[package]] @@ -1288,8 +1241,8 @@ checksum = "b021d93e26becf5dc7e1b75b1bed1fd93124b374ceb73f43d4d4eafec896a64a" dependencies = [ "bytes", "futures-core", - "http 1.4.0", - "http-body 1.0.1", + "http", + "http-body", "pin-project-lite", ] @@ -1305,30 +1258,6 @@ version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" -[[package]] -name = "hyper" -version = "0.14.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41dfc780fdec9373c01bae43289ea34c972e40ee3c9f6b3c8801a35f35586ce7" -dependencies = [ - "bytes", - "futures-channel", - "futures-core", - "futures-util", - "h2 0.3.27", - "http 0.2.12", - "http-body 0.4.6", - "httparse", - "httpdate", - "itoa", - "pin-project-lite", - "socket2 0.5.10", - "tokio", - "tower-service", - "tracing", - "want", -] - [[package]] name = "hyper" version = "1.8.1" @@ -1339,10 +1268,11 @@ dependencies = [ "bytes", "futures-channel", "futures-core", - "h2 0.4.12", - "http 1.4.0", - "http-body 1.0.1", + "h2", + "http", + "http-body", "httparse", + "httpdate", "itoa", "pin-project-lite", "pin-utils", @@ -1357,8 +1287,8 @@ version = "0.27.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3c93eb611681b207e1fe55d5a71ecf91572ec8a6705cdb6857f7d8d5242cf58" dependencies = [ - "http 1.4.0", - "hyper 1.8.1", + "http", + "hyper", "hyper-util", "rustls", "rustls-pki-types", @@ -1375,7 +1305,7 @@ checksum = "70206fc6890eaca9fde8a0bf71caa2ddfc9fe045ac9e5c70df101a7dbde866e0" dependencies = [ "bytes", "http-body-util", - "hyper 1.8.1", + "hyper", "hyper-util", "native-tls", "tokio", @@ -1389,19 +1319,19 @@ version = "0.1.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "52e9a2a24dc5c6821e71a7030e1e14b7b632acac55c40e9d2e082c621261bb56" dependencies = [ - "base64 0.22.1", + "base64", "bytes", "futures-channel", "futures-core", "futures-util", - "http 1.4.0", - "http-body 1.0.1", - "hyper 1.8.1", + "http", + "http-body", + "hyper", "ipnet", "libc", "percent-encoding", "pin-project-lite", - "socket2 0.6.1", + "socket2", "system-configuration", "tokio", "tower-service", @@ -1874,24 +1804,6 @@ dependencies = [ "uuid", ] -[[package]] -name = "multer" -version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01acbdc23469fd8fe07ab135923371d5f5a422fbf9c522158677c8eb15bc51c2" -dependencies = [ - "bytes", - "encoding_rs", - "futures-util", - "http 0.2.12", - "httparse", - "log", - "memchr", - "mime", - "spin", - "version_check", -] - [[package]] name = "multibase" version = "0.9.2" @@ -2252,35 +2164,14 @@ version = "5.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" -[[package]] -name = "rand" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" -dependencies = [ - "libc", - "rand_chacha 0.3.1", - "rand_core 0.6.4", -] - [[package]] name = "rand" version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1" dependencies = [ - "rand_chacha 0.9.0", - "rand_core 0.9.3", -] - -[[package]] -name = "rand_chacha" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" -dependencies = [ - "ppv-lite86", - "rand_core 0.6.4", + "rand_chacha", + "rand_core", ] [[package]] @@ -2290,16 +2181,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" dependencies = [ "ppv-lite86", - "rand_core 0.9.3", -] - -[[package]] -name = "rand_core" -version = "0.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" -dependencies = [ - "getrandom 0.2.16", + "rand_core", ] [[package]] @@ -2356,16 +2238,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9d0946410b9f7b082a427e4ef5c8ff541a88b357bc6c637c40db3a68ac70a36f" dependencies = [ "async-compression", - "base64 0.22.1", + "base64", "bytes", "encoding_rs", "futures-core", "futures-util", - "h2 0.4.12", - "http 1.4.0", - "http-body 1.0.1", + "h2", + "http", + "http-body", "http-body-util", - "hyper 1.8.1", + "hyper", "hyper-rustls", "hyper-tls", "hyper-util", @@ -2835,7 +2717,7 @@ dependencies = [ "serde_ipld_dagcbor", "serde_json", "tokio", - "tokio-tungstenite 0.28.0", + "tokio-tungstenite", "warp", "whatlang", ] @@ -2852,16 +2734,6 @@ version = "1.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" -[[package]] -name = "socket2" -version = "0.5.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e22376abed350d73dd1cd119b57ffccad95b4e585a7cda43e286245ce23c0678" -dependencies = [ - "libc", - "windows-sys 0.52.0", -] - [[package]] name = "socket2" version = "0.6.1" @@ -3055,7 +2927,7 @@ dependencies = [ "parking_lot", "pin-project-lite", "signal-hook-registry", - "socket2 0.6.1", + "socket2", "tokio-macros", "windows-sys 0.61.2", ] @@ -3091,18 +2963,6 @@ dependencies = [ "tokio", ] -[[package]] -name = "tokio-tungstenite" -version = "0.21.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c83b561d025642014097b66e6c1bb422783339e0909e4429cde4749d1990bc38" -dependencies = [ - "futures-util", - "log", - "tokio", - "tungstenite 0.21.0", -] - [[package]] name = "tokio-tungstenite" version = "0.28.0" @@ -3116,7 +2976,7 @@ dependencies = [ "rustls-pki-types", "tokio", "tokio-rustls", - "tungstenite 0.28.0", + "tungstenite", ] [[package]] @@ -3208,8 +3068,8 @@ dependencies = [ "bitflags", "bytes", "futures-util", - "http 1.4.0", - "http-body 1.0.1", + "http", + "http-body", "iri-string", "pin-project-lite", "tower", @@ -3278,25 +3138,6 @@ version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" -[[package]] -name = "tungstenite" -version = "0.21.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ef1a641ea34f399a848dea702823bbecfb4c486f911735368f1f137cb8257e1" -dependencies = [ - "byteorder", - "bytes", - "data-encoding", - "http 1.4.0", - "httparse", - "log", - "rand 0.8.5", - "sha1", - "thiserror 1.0.69", - "url", - "utf-8", -] - [[package]] name = "tungstenite" version = "0.28.0" @@ -3305,10 +3146,10 @@ checksum = "8628dcc84e5a09eb3d8423d6cb682965dea9133204e8fb3efee74c2a0c259442" dependencies = [ "bytes", "data-encoding", - "http 1.4.0", + "http", "httparse", "log", - "rand 0.9.2", + "rand", "rustls", "rustls-pki-types", "sha1", @@ -3438,20 +3279,21 @@ dependencies = [ [[package]] name = "warp" -version = "0.3.7" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4378d202ff965b011c64817db11d5829506d3404edeadb61f190d111da3f231c" +checksum = "51d06d9202adc1f15d709c4f4a2069be5428aa912cc025d6f268ac441ab066b0" dependencies = [ "bytes", - "futures-channel", "futures-util", "headers", - "http 0.2.12", - "hyper 0.14.32", + "http", + "http-body", + "http-body-util", + "hyper", + "hyper-util", "log", "mime", "mime_guess", - "multer", "percent-encoding", "pin-project", "scoped-tls", @@ -3459,7 +3301,6 @@ dependencies = [ "serde_json", "serde_urlencoded", "tokio", - "tokio-tungstenite 0.21.0", "tokio-util", "tower-service", "tracing", diff --git a/Cargo.toml b/Cargo.toml index 5f01168..61b095c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -48,8 +48,7 @@ serde_json = "1.0.133" tokio = { version = "1.41.1", features = ["full"] } tokio-tungstenite = { version = "0.28.0", features = ["rustls-tls-native-roots"] } futures = "0.3.31" -warp = "0.3.7" - +warp = { version = "0.4.2", features = ["server"] } clap = { version = "4.5.3", features = ["derive"] } anyhow = "1.0.81" reqwest = "0.12.9" diff --git a/src/feed.rs b/src/feed.rs index ada4bb1..6c41ed8 100644 --- a/src/feed.rs +++ b/src/feed.rs @@ -9,145 +9,161 @@ use env_logger::Env; use log::{info, warn}; use std::fmt::Debug; use std::net::SocketAddr; +use std::sync::Arc; +use tokio::sync::Mutex; use warp::Filter; +use crate::config::Config; use crate::firehose::{FirehoseConnector, FirehoseEvent}; use crate::models::Request; use crate::utility_models::{DidDocument, Service}; -use crate::{config::Config, feed_handler::FeedHandler}; +use crate::{FeedResult, Post, Uri}; -/// A `Feed` stores a `FeedHandler`, handles feed server endpoints & connects to the Firehose using the `start` methods. -pub trait Feed { - fn handler(&mut self) -> Handler; - /// Starts the feed generator server & connects to the firehose. - /// - /// This method loads the config from a local .env file using `dotenv`. See `Config` - /// - /// - feed_names: The identifying names of your feeds. This value is used in the feed URL & when identifying which feed to *publish* or *unpublish*. This is a separate value from the display name. - /// - address: The address to bind the server to - /// - /// # Panics - /// - /// Panics if unable to bind to the provided address. - fn start( - &mut self, - feed_names: Vec<&'static str>, - address: impl Into + Debug + Clone + Send, - ) -> impl std::future::Future + Send { - self.start_with_config(feed_names, Config::load_env_config(), address) - } - /// Starts the feed generator server & connects to the firehose. - /// - /// - feed_names: The identifying names of your feeds. This value is used in the feed URL & when identifying which feed to *publish* or *unpublish*. This is a separate value from the display name. - /// - config: Configuration values, see `Config` - /// - address: The address to bind the server to - /// - /// # Panics - /// - /// Panics if unable to bind to the provided address. - fn start_with_config( +pub trait FeedHandler { + fn available_feeds(&mut self) -> impl Future> + Send; + fn insert_post(&mut self, post: Post) -> impl Future + Send; + fn delete_post(&mut self, uri: Uri) -> impl Future + Send; + fn insert_like( &mut self, - feed_names: Vec<&'static str>, - config: Config, - address: impl Into + Debug + Clone + Send, - ) -> impl std::future::Future + Send { - let handler = self.handler(); - let address = address.clone(); - let feed_names = feed_names.clone(); - async move { - env_logger::Builder::from_env(Env::default().default_filter_or("info")).init(); - - let config = config; - - let did_config = config.clone(); - let did_json = warp::path(".well-known") - .and(warp::path("did.json")) - .and(warp::get()) - .and_then(move || did_json(did_config.clone())); - - let describe_feed_config = config.clone(); - let describe_feed_generator = warp::path("xrpc") - .and(warp::path("app.bsky.feed.describeFeedGenerator")) - .and(warp::get()) - .and_then(move || { - describe_feed_generator(describe_feed_config.clone(), feed_names.clone()) - }); - - let get_feed_handler = handler.clone(); - let get_feed_skeleton = warp::path("xrpc") - .and(warp::path("app.bsky.feed.getFeedSkeleton")) - .and(warp::get()) - .and(warp::query::()) - .and_then(move |query: FeedSkeletonParameters| { - get_feed_skeleton::(query.into(), get_feed_handler.clone()) - }); - - let api = did_json.or(describe_feed_generator).or(get_feed_skeleton); - - info!("Serving feed on {:?}", address); - - let routes = api.with(warp::log::custom(|info| { - let method = info.method(); - let path = info.path(); - let status = info.status(); - let elapsed = info.elapsed().as_millis(); - - if status.is_success() { - info!( - "Method: {}, Path: {}, Status: {}, Elapsed Time: {}ms", - method, path, status, elapsed - ); - } else { - log::error!( - "Method: {}, Path: {}, Status: {}, Elapsed Time: {}ms", - method, - path, - status, - elapsed, - ); + like_uri: Uri, + liked_post_uri: Uri, + ) -> impl std::future::Future + Send; + fn delete_like(&mut self, like_uri: Uri) -> impl Future + Send; + fn serve_feed(&self, request: Request) -> impl Future + Send; +} + +/// A `Feed` stores a `FeedHandler`, handles feed server endpoints & connects to the Firehose using the `start` methods. +// pub trait Feed { +// fn handler(&mut self) -> Handler; +/// Starts the feed generator server & connects to the firehose. +/// +/// This method loads the config from a local .env file using `dotenv`. See `Config` +/// +/// - feed_names: The identifying names of your feeds. This value is used in the feed URL & when identifying which feed to *publish* or *unpublish*. This is a separate value from the display name. +/// - address: The address to bind the server to +/// +/// # Panics +/// +/// Panics if unable to bind to the provided address. +fn start( + feed_handler: impl FeedHandler + Send + 'static, + address: impl Into + Debug + Clone + Send, +) -> impl std::future::Future + Send { + start_with_config(feed_handler, Config::load_env_config(), address) +} + +/// Starts the feed generator server & connects to the firehose. +/// +/// - feed_names: The identifying names of your feeds. This value is used in the feed URL & when identifying which feed to *publish* or *unpublish*. This is a separate value from the display name. +/// - config: Configuration values, see `Config` +/// - address: The address to bind the server to +/// +/// # Panics +/// +/// Panics if unable to bind to the provided address. +fn start_with_config( + feed_handler: impl FeedHandler + Send + 'static, + config: Config, + address: impl Into + Debug + Clone + Send, +) -> impl std::future::Future + Send { + env_logger::Builder::from_env(Env::default().default_filter_or("info")).init(); + let address = address.clone(); + let feed_handler = Arc::new(Mutex::new(feed_handler)); + async move { + let config = config; + + let did_config = config.clone(); + let did_json = warp::path(".well-known") + .and(warp::path("did.json")) + .and(warp::get()) + .and_then(move || did_json(did_config.clone())); + + let describe_feed_config = config.clone(); + let describe_feed_generator = warp::path("xrpc") + .and(warp::path("app.bsky.feed.describeFeedGenerator")) + .and(warp::get()) + .and_then({ + let feed_handler = feed_handler.clone(); + move || describe_feed_generator(describe_feed_config.clone(), feed_handler.clone()) + }); + + let get_feed_skeleton = warp::path("xrpc") + .and(warp::path("app.bsky.feed.getFeedSkeleton")) + .and(warp::get()) + .and(warp::query::()) + .and_then({ + let feed_handler = feed_handler.clone(); + move |query: FeedSkeletonParameters| { + get_feed_skeleton(query.into(), feed_handler.clone()) } - })); - let feed_server = warp::serve(routes); - - let (tx, rx): (flume::Sender, _) = flume::unbounded(); - - let event_handler = tokio::spawn(async move { - let mut h = handler; - let mut warning_log_counter = 0usize; - while let Ok(event) = rx.recv_async().await { - warning_log_counter += 1; - let waiting_updates = rx.len(); - if waiting_updates >= 2000 && warning_log_counter >= 5 { - warning_log_counter = 0; - warn!( - "{waiting_updates} updates are awaiting processing, your feed handler implementation may not be processing updates quickly enough. This will result in continuously increasing memory usage if it continues!" - ) + }); + + let api = did_json.or(describe_feed_generator).or(get_feed_skeleton); + + info!("Serving feed on {:?}", address); + + let routes = api.with(warp::log::custom(|info| { + let method = info.method(); + let path = info.path(); + let status = info.status(); + let elapsed = info.elapsed().as_millis(); + + if status.is_success() { + info!( + "Method: {}, Path: {}, Status: {}, Elapsed Time: {}ms", + method, path, status, elapsed + ); + } else { + log::error!( + "Method: {}, Path: {}, Status: {}, Elapsed Time: {}ms", + method, + path, + status, + elapsed, + ); + } + })); + let feed_server = warp::serve(routes); + + let (tx, rx): (flume::Sender, _) = flume::unbounded(); + + let feed_handler = feed_handler.clone(); + let event_handler = tokio::spawn(async move { + let mut warning_log_counter = 0usize; + while let Ok(event) = rx.recv_async().await { + warning_log_counter += 1; + let waiting_updates = rx.len(); + if waiting_updates >= 2000 && warning_log_counter >= 5 { + warning_log_counter = 0; + warn!( + "{waiting_updates} updates are awaiting processing, your feed handler implementation may not be processing updates quickly enough. This will result in continuously increasing memory usage if it continues!" + ) + } + let mut feed_handler = feed_handler.lock().await; + match event { + FirehoseEvent::Post(post) => { + feed_handler.insert_post(*post).await; + } + FirehoseEvent::DeletePost(uri) => { + feed_handler.delete_post(uri).await; + } + FirehoseEvent::Like(like_uri, post_uri) => { + feed_handler.insert_like(like_uri, post_uri).await; } - match event { - FirehoseEvent::Post(post) => { - h.insert_post(*post).await; - } - FirehoseEvent::DeletePost(uri) => { - h.delete_post(uri).await; - } - FirehoseEvent::Like(like_uri, post_uri) => { - h.like_post(like_uri, post_uri).await; - } - FirehoseEvent::DeleteLike(uri) => { - h.delete_like(uri).await; - } + FirehoseEvent::DeleteLike(uri) => { + feed_handler.delete_like(uri).await; } } - }); + } + }); - let firehose_listener = tokio::spawn(async move { - if let Err(e) = FirehoseConnector::run(tx).await { - log::error!("Firehose error: {}", e); - } - }); + let firehose_listener = tokio::spawn(async move { + if let Err(e) = FirehoseConnector::run(tx).await { + log::error!("Firehose error: {}", e); + } + }); - let _ = tokio::join!(feed_server.run(address), firehose_listener, event_handler); - } + let _ = tokio::join!(feed_server.run(address), firehose_listener, event_handler); } } @@ -165,7 +181,7 @@ async fn did_json(config: Config) -> Result { async fn describe_feed_generator( config: Config, - feed_names: Vec>, + feed_handler: Arc>, ) -> Result { Ok(warp::reply::json(&FeedGeneratorDescription { did: atrium_api::types::string::Did::new(format!( @@ -173,14 +189,17 @@ async fn describe_feed_generator( config.feed_generator_hostname )) .unwrap(), - feeds: feed_names + feeds: feed_handler + .lock() + .await + .available_feeds() + .await .iter() .map(|name| { Object::from(FeedData { uri: format!( "at://{}/app.bsky.feed.generator/{}", - config.publisher_did, - name.as_ref() + config.publisher_did, name ), }) }) @@ -189,15 +208,17 @@ async fn describe_feed_generator( })) } -async fn get_feed_skeleton( +async fn get_feed_skeleton( query: FeedSkeletonQuery, - handler: Handler, + feed_handler: Arc>, ) -> Result { - let skeleton = handler + let skeleton = feed_handler + .lock() + .await .serve_feed(Request { cursor: query.cursor.clone(), - feed: query.feed.split("/").last().unwrap_or("").to_string(), limit: query.limit.map(|l| l.into()), + feed: query.feed.split("/").last().unwrap_or("").to_string(), }) .await; Ok::(warp::reply::json(&FeedSkeleton { From b72e51f0d730119473ec0eb3f8e371e190cfb59d Mon Sep 17 00:00:00 2001 From: cyypherus Date: Sat, 6 Dec 2025 15:36:50 -0700 Subject: [PATCH 36/53] fix fix --- src/feed.rs | 209 ++++++++++++++++++++------------------------ src/feed_handler.rs | 16 ---- src/lib.rs | 3 +- 3 files changed, 94 insertions(+), 134 deletions(-) delete mode 100644 src/feed_handler.rs diff --git a/src/feed.rs b/src/feed.rs index 6c41ed8..bbc8457 100644 --- a/src/feed.rs +++ b/src/feed.rs @@ -7,7 +7,6 @@ use atrium_api::app::bsky::feed::get_feed_skeleton::ParametersData as FeedSkelet use atrium_api::types::Object; use env_logger::Env; use log::{info, warn}; -use std::fmt::Debug; use std::net::SocketAddr; use std::sync::Arc; use tokio::sync::Mutex; @@ -32,26 +31,6 @@ pub trait FeedHandler { fn serve_feed(&self, request: Request) -> impl Future + Send; } -/// A `Feed` stores a `FeedHandler`, handles feed server endpoints & connects to the Firehose using the `start` methods. -// pub trait Feed { -// fn handler(&mut self) -> Handler; -/// Starts the feed generator server & connects to the firehose. -/// -/// This method loads the config from a local .env file using `dotenv`. See `Config` -/// -/// - feed_names: The identifying names of your feeds. This value is used in the feed URL & when identifying which feed to *publish* or *unpublish*. This is a separate value from the display name. -/// - address: The address to bind the server to -/// -/// # Panics -/// -/// Panics if unable to bind to the provided address. -fn start( - feed_handler: impl FeedHandler + Send + 'static, - address: impl Into + Debug + Clone + Send, -) -> impl std::future::Future + Send { - start_with_config(feed_handler, Config::load_env_config(), address) -} - /// Starts the feed generator server & connects to the firehose. /// /// - feed_names: The identifying names of your feeds. This value is used in the feed URL & when identifying which feed to *publish* or *unpublish*. This is a separate value from the display name. @@ -61,110 +40,108 @@ fn start( /// # Panics /// /// Panics if unable to bind to the provided address. -fn start_with_config( - feed_handler: impl FeedHandler + Send + 'static, +pub async fn start( config: Config, - address: impl Into + Debug + Clone + Send, -) -> impl std::future::Future + Send { + feed_handler: impl FeedHandler + Send + 'static, + address: impl Into + Send + 'static, +) { env_logger::Builder::from_env(Env::default().default_filter_or("info")).init(); - let address = address.clone(); + let address: SocketAddr = address.into(); let feed_handler = Arc::new(Mutex::new(feed_handler)); - async move { - let config = config; - - let did_config = config.clone(); - let did_json = warp::path(".well-known") - .and(warp::path("did.json")) - .and(warp::get()) - .and_then(move || did_json(did_config.clone())); - - let describe_feed_config = config.clone(); - let describe_feed_generator = warp::path("xrpc") - .and(warp::path("app.bsky.feed.describeFeedGenerator")) - .and(warp::get()) - .and_then({ - let feed_handler = feed_handler.clone(); - move || describe_feed_generator(describe_feed_config.clone(), feed_handler.clone()) - }); - - let get_feed_skeleton = warp::path("xrpc") - .and(warp::path("app.bsky.feed.getFeedSkeleton")) - .and(warp::get()) - .and(warp::query::()) - .and_then({ - let feed_handler = feed_handler.clone(); - move |query: FeedSkeletonParameters| { - get_feed_skeleton(query.into(), feed_handler.clone()) - } - }); - - let api = did_json.or(describe_feed_generator).or(get_feed_skeleton); - - info!("Serving feed on {:?}", address); - - let routes = api.with(warp::log::custom(|info| { - let method = info.method(); - let path = info.path(); - let status = info.status(); - let elapsed = info.elapsed().as_millis(); - - if status.is_success() { - info!( - "Method: {}, Path: {}, Status: {}, Elapsed Time: {}ms", - method, path, status, elapsed - ); - } else { - log::error!( - "Method: {}, Path: {}, Status: {}, Elapsed Time: {}ms", - method, - path, - status, - elapsed, - ); + let config = config; + + let did_config = config.clone(); + let did_json = warp::path(".well-known") + .and(warp::path("did.json")) + .and(warp::get()) + .and_then(move || did_json(did_config.clone())); + + let describe_feed_config = config.clone(); + let describe_feed_generator = warp::path("xrpc") + .and(warp::path("app.bsky.feed.describeFeedGenerator")) + .and(warp::get()) + .and_then({ + let feed_handler = feed_handler.clone(); + move || describe_feed_generator(describe_feed_config.clone(), feed_handler.clone()) + }); + + let get_feed_skeleton = warp::path("xrpc") + .and(warp::path("app.bsky.feed.getFeedSkeleton")) + .and(warp::get()) + .and(warp::query::()) + .and_then({ + let feed_handler = feed_handler.clone(); + move |query: FeedSkeletonParameters| { + get_feed_skeleton(query.into(), feed_handler.clone()) + } + }); + + let api = did_json.or(describe_feed_generator).or(get_feed_skeleton); + + info!("Serving feed on {:?}", address); + + let routes = api.with(warp::log::custom(|info| { + let method = info.method(); + let path = info.path(); + let status = info.status(); + let elapsed = info.elapsed().as_millis(); + + if status.is_success() { + info!( + "Method: {}, Path: {}, Status: {}, Elapsed Time: {}ms", + method, path, status, elapsed + ); + } else { + log::error!( + "Method: {}, Path: {}, Status: {}, Elapsed Time: {}ms", + method, + path, + status, + elapsed, + ); + } + })); + let feed_server = warp::serve(routes); + + let (tx, rx): (flume::Sender, _) = flume::unbounded(); + + let feed_handler = feed_handler.clone(); + let event_handler = tokio::spawn(async move { + let mut warning_log_counter = 0usize; + while let Ok(event) = rx.recv_async().await { + warning_log_counter += 1; + let waiting_updates = rx.len(); + if waiting_updates >= 2000 && warning_log_counter >= 5 { + warning_log_counter = 0; + warn!( + "{waiting_updates} updates are awaiting processing, your feed handler implementation may not be processing updates quickly enough. This will result in continuously increasing memory usage if it continues!" + ) } - })); - let feed_server = warp::serve(routes); - - let (tx, rx): (flume::Sender, _) = flume::unbounded(); - - let feed_handler = feed_handler.clone(); - let event_handler = tokio::spawn(async move { - let mut warning_log_counter = 0usize; - while let Ok(event) = rx.recv_async().await { - warning_log_counter += 1; - let waiting_updates = rx.len(); - if waiting_updates >= 2000 && warning_log_counter >= 5 { - warning_log_counter = 0; - warn!( - "{waiting_updates} updates are awaiting processing, your feed handler implementation may not be processing updates quickly enough. This will result in continuously increasing memory usage if it continues!" - ) + let mut feed_handler = feed_handler.lock().await; + match event { + FirehoseEvent::Post(post) => { + feed_handler.insert_post(*post).await; + } + FirehoseEvent::DeletePost(uri) => { + feed_handler.delete_post(uri).await; + } + FirehoseEvent::Like(like_uri, post_uri) => { + feed_handler.insert_like(like_uri, post_uri).await; } - let mut feed_handler = feed_handler.lock().await; - match event { - FirehoseEvent::Post(post) => { - feed_handler.insert_post(*post).await; - } - FirehoseEvent::DeletePost(uri) => { - feed_handler.delete_post(uri).await; - } - FirehoseEvent::Like(like_uri, post_uri) => { - feed_handler.insert_like(like_uri, post_uri).await; - } - FirehoseEvent::DeleteLike(uri) => { - feed_handler.delete_like(uri).await; - } + FirehoseEvent::DeleteLike(uri) => { + feed_handler.delete_like(uri).await; } } - }); + } + }); - let firehose_listener = tokio::spawn(async move { - if let Err(e) = FirehoseConnector::run(tx).await { - log::error!("Firehose error: {}", e); - } - }); + let firehose_listener = tokio::spawn(async move { + if let Err(e) = FirehoseConnector::run(tx).await { + log::error!("Firehose error: {}", e); + } + }); - let _ = tokio::join!(feed_server.run(address), firehose_listener, event_handler); - } + let _ = tokio::join!(feed_server.run(address), firehose_listener, event_handler); } async fn did_json(config: Config) -> Result { diff --git a/src/feed_handler.rs b/src/feed_handler.rs deleted file mode 100644 index 98cb0c0..0000000 --- a/src/feed_handler.rs +++ /dev/null @@ -1,16 +0,0 @@ -use crate::models::{FeedResult, Post, Request, Uri}; - -/// A feed handler is responsible for -/// - Storing and managing firehose input. -/// - Serving responses to feed requests with `serve_feed` -pub trait FeedHandler { - fn insert_post(&mut self, post: Post) -> impl std::future::Future + Send; - fn delete_post(&mut self, uri: Uri) -> impl std::future::Future + Send; - fn like_post( - &mut self, - like_uri: Uri, - liked_post_uri: Uri, - ) -> impl std::future::Future + Send; - fn delete_like(&mut self, like_uri: Uri) -> impl std::future::Future + Send; - fn serve_feed(&self, request: Request) -> impl std::future::Future + Send; -} diff --git a/src/lib.rs b/src/lib.rs index 22586fb..ede532e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -9,6 +9,5 @@ mod public_api_test; mod utility_models; pub use config::Config; -pub use feed::Feed; -pub use feed_handler::FeedHandler; +pub use feed::FeedHandler; pub use models::*; From c718bc8ea45db9bfc824dd2359d4d8d899968b1c Mon Sep 17 00:00:00 2001 From: cyypherus Date: Sat, 6 Dec 2025 15:43:29 -0700 Subject: [PATCH 37/53] cleanup, docs --- src/feed.rs | 13 +++++++++---- src/models.rs | 2 +- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/src/feed.rs b/src/feed.rs index bbc8457..32e91c7 100644 --- a/src/feed.rs +++ b/src/feed.rs @@ -14,10 +14,15 @@ use warp::Filter; use crate::config::Config; use crate::firehose::{FirehoseConnector, FirehoseEvent}; -use crate::models::Request; +use crate::models::FeedRequest; use crate::utility_models::{DidDocument, Service}; use crate::{FeedResult, Post, Uri}; +/// A feed handler is responsible for +/// - Storing and managing firehose input. +/// - Serving responses to feed requests with `serve_feed` +/// +/// One feed handler can implement any number of feeds. Feed IDs / names are specified by the `available_feeds` function, & are later referred to in the `FeedRequest::feed` field. pub trait FeedHandler { fn available_feeds(&mut self) -> impl Future> + Send; fn insert_post(&mut self, post: Post) -> impl Future + Send; @@ -28,12 +33,12 @@ pub trait FeedHandler { liked_post_uri: Uri, ) -> impl std::future::Future + Send; fn delete_like(&mut self, like_uri: Uri) -> impl Future + Send; - fn serve_feed(&self, request: Request) -> impl Future + Send; + fn serve_feed(&self, request: FeedRequest) -> impl Future + Send; } /// Starts the feed generator server & connects to the firehose. /// -/// - feed_names: The identifying names of your feeds. This value is used in the feed URL & when identifying which feed to *publish* or *unpublish*. This is a separate value from the display name. +/// - feed_handler: An object which handles firehose input & serve feeds. This object can implement multiple feeds. /// - config: Configuration values, see `Config` /// - address: The address to bind the server to /// @@ -192,7 +197,7 @@ async fn get_feed_skeleton( let skeleton = feed_handler .lock() .await - .serve_feed(Request { + .serve_feed(FeedRequest { cursor: query.cursor.clone(), limit: query.limit.map(|l| l.into()), feed: query.feed.split("/").last().unwrap_or("").to_string(), diff --git a/src/models.rs b/src/models.rs index 81ee1be..d7fbf09 100644 --- a/src/models.rs +++ b/src/models.rs @@ -9,7 +9,7 @@ use chrono::{DateTime, Utc}; use log::trace; #[derive(Debug, Clone)] -pub struct Request { +pub struct FeedRequest { pub cursor: Option, pub feed: String, pub limit: Option, From d23838bf643881a253fa4f0b38a99727071be088 Mon Sep 17 00:00:00 2001 From: cyypherus Date: Sat, 6 Dec 2025 15:53:01 -0700 Subject: [PATCH 38/53] update examples --- examples/basic/src/main.rs | 32 +++++++++----------- examples/sqlite/src/main.rs | 59 +++++++++++++++---------------------- src/lib.rs | 3 +- 3 files changed, 39 insertions(+), 55 deletions(-) diff --git a/examples/basic/src/main.rs b/examples/basic/src/main.rs index 92b95b1..ff2778c 100644 --- a/examples/basic/src/main.rs +++ b/examples/basic/src/main.rs @@ -1,26 +1,18 @@ use log::info; -use skyfeed::{Feed, FeedHandler, FeedResult, Post, Request, Uri}; +use skyfeed::{Config, FeedHandler, FeedResult, Post, FeedRequest, Uri, start}; use std::{collections::HashSet, sync::Arc}; use tokio::sync::Mutex; #[tokio::main] async fn main() { - let mut feed = MyFeed { - handler: MyFeedHandler { - posts: Arc::new(Mutex::new(Vec::new())), - }, + let handler = MyFeedHandler { + posts: Arc::new(Mutex::new(Vec::new())), }; - feed.start(vec!["Cats"], ([0, 0, 0, 0], 3030)).await -} - -struct MyFeed { - handler: MyFeedHandler, -} - -impl Feed for MyFeed { - fn handler(&mut self) -> MyFeedHandler { - self.handler.clone() - } + let config = Config { + publisher_did: "did:web:example.com".to_string(), + feed_generator_hostname: "example.com".to_string(), + }; + start(config, handler, ([0, 0, 0, 0], 3030)).await } #[derive(Clone)] @@ -35,6 +27,10 @@ struct MyPost { } impl FeedHandler for MyFeedHandler { + async fn available_feeds(&mut self) -> Vec { + vec!["Cats".to_string()] + } + async fn insert_post(&mut self, post: Post) { println!("📝 POST: {}", post.text); if post.text.to_lowercase().contains(" cat ") { @@ -61,7 +57,7 @@ impl FeedHandler for MyFeedHandler { .retain(|post_with_likes| post_with_likes.post.uri != uri); } - async fn like_post(&mut self, like_uri: Uri, liked_post_uri: Uri) { + async fn insert_like(&mut self, like_uri: Uri, liked_post_uri: Uri) { if let Some(post_with_likes) = self .posts .lock() @@ -80,7 +76,7 @@ impl FeedHandler for MyFeedHandler { } } - async fn serve_feed(&self, request: Request) -> FeedResult { + async fn serve_feed(&self, request: FeedRequest) -> FeedResult { info!("Serving {request:?}"); let posts = self.posts.lock().await; diff --git a/examples/sqlite/src/main.rs b/examples/sqlite/src/main.rs index 2d1981f..937b2f1 100644 --- a/examples/sqlite/src/main.rs +++ b/examples/sqlite/src/main.rs @@ -4,7 +4,7 @@ use log::{error, info, trace}; use regex::Regex; use rusqlite::{Connection, params}; -use skyfeed::{Config, Feed, FeedHandler, FeedResult, Post, Request, Uri}; +use skyfeed::{Config, FeedHandler, FeedRequest, FeedResult, Post, Uri}; use std::{env, sync::Arc, time::Duration}; use tokio::sync::Mutex; @@ -24,19 +24,17 @@ async fn main() { let fr_feed_regex = env::var("FR_FEED_REGEX").expect("Missing feed regex"); let pending_posts = Arc::new(Mutex::new(Vec::new())); let pending_likes = Arc::new(Mutex::new(Vec::new())); - let mut feed = MyFeed { - handler: MyFeedHandler { - fr_regex: regex::RegexBuilder::new(fr_feed_regex.as_str()) - .case_insensitive(true) - .build() - .unwrap(), - my_regex: regex::RegexBuilder::new(my_feed_regex.as_str()) - .build() - .unwrap(), - db: db.clone(), - pending_posts: pending_posts.clone(), - pending_likes: pending_likes.clone(), - }, + let handler = MyFeedHandler { + fr_regex: regex::RegexBuilder::new(fr_feed_regex.as_str()) + .case_insensitive(true) + .build() + .unwrap(), + my_regex: regex::RegexBuilder::new(my_feed_regex.as_str()) + .build() + .unwrap(), + db: db.clone(), + pending_posts: pending_posts.clone(), + pending_likes: pending_likes.clone(), }; let db_clone = db.clone(); @@ -57,32 +55,19 @@ async fn main() { let feed_generator_hostname = env::var("FEED_GENERATOR_HOSTNAME").expect("FEED_GENERATOR_HOSTNAME env var not set"); + let config = Config { + publisher_did, + feed_generator_hostname, + }; + tokio::join!( - feed.start_with_config( - vec![FR_FEED, MY_FEED], - Config { - publisher_did, - feed_generator_hostname - }, - // Config::load_env_config(), - ([0, 0, 0, 0], 3030) - ), + skyfeed::start(config, handler, ([0, 0, 0, 0], 3030)), flush_task ) .1 .expect("Starting tasks failed"); } -struct MyFeed { - handler: MyFeedHandler, -} - -impl Feed for MyFeed { - fn handler(&mut self) -> MyFeedHandler { - self.handler.clone() - } -} - #[derive(Clone)] struct MyFeedHandler { fr_regex: Regex, @@ -93,6 +78,10 @@ struct MyFeedHandler { } impl FeedHandler for MyFeedHandler { + async fn available_feeds(&mut self) -> Vec { + vec![FR_FEED.to_string(), MY_FEED.to_string()] + } + async fn insert_post(&mut self, post: Post) { let detected_language = whatlang::detect_lang(&post.text); let timestamp = post.timestamp.timestamp(); @@ -132,7 +121,7 @@ impl FeedHandler for MyFeedHandler { .expect("Failed to delete post"); } - async fn like_post(&mut self, like_uri: Uri, liked_post_uri: Uri) { + async fn insert_like(&mut self, like_uri: Uri, liked_post_uri: Uri) { let mut pending = self.pending_likes.lock().await; pending.push((liked_post_uri.0.clone(), like_uri.0.clone())); } @@ -146,7 +135,7 @@ impl FeedHandler for MyFeedHandler { .expect("Failed to delete like"); } - async fn serve_feed(&self, request: Request) -> FeedResult { + async fn serve_feed(&self, request: FeedRequest) -> FeedResult { info!("Serving {request:?}"); let (hours_back, post_offset) = request diff --git a/src/lib.rs b/src/lib.rs index ede532e..d494c0f 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -2,12 +2,11 @@ mod config; mod feed; -mod feed_handler; mod firehose; mod models; mod public_api_test; mod utility_models; pub use config::Config; -pub use feed::FeedHandler; +pub use feed::{start, FeedHandler}; pub use models::*; From 93899a464bc4c3a24a54c2e1e98ddd9ca0503662 Mon Sep 17 00:00:00 2001 From: cyypherus Date: Sat, 6 Dec 2025 16:27:33 -0700 Subject: [PATCH 39/53] arc mtx handler --- examples/sqlite/Cargo.lock | 262 +++++++---------------------------- examples/sqlite/Cargo.toml | 3 +- examples/sqlite/src/main.rs | 269 +++++++++++++++++------------------- src/feed.rs | 5 +- 4 files changed, 180 insertions(+), 359 deletions(-) diff --git a/examples/sqlite/Cargo.lock b/examples/sqlite/Cargo.lock index 66e72a4..5ab160c 100644 --- a/examples/sqlite/Cargo.lock +++ b/examples/sqlite/Cargo.lock @@ -193,7 +193,7 @@ dependencies = [ "atrium-common", "atrium-xrpc", "chrono", - "http 1.3.1", + "http", "ipld-core", "langtag", "regex", @@ -246,7 +246,7 @@ version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0216ad50ce34e9ff982e171c3659e65dedaa2ed5ac2994524debdc9a9647ffa8" dependencies = [ - "http 1.3.1", + "http", "serde", "serde_html_form", "serde_json", @@ -324,12 +324,6 @@ dependencies = [ "match-lookup", ] -[[package]] -name = "base64" -version = "0.21.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" - [[package]] name = "base64" version = "0.22.1" @@ -1086,25 +1080,6 @@ version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0cc23270f6e1808e30a928bdc84dea0b9b4136a8bc82338574f23baf47bbd280" -[[package]] -name = "h2" -version = "0.3.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0beca50380b1fc32983fc1cb4587bfa4bb9e78fc259aad4a0032d2080309222d" -dependencies = [ - "bytes", - "fnv", - "futures-core", - "futures-sink", - "futures-util", - "http 0.2.12", - "indexmap", - "slab", - "tokio", - "tokio-util", - "tracing", -] - [[package]] name = "h2" version = "0.4.12" @@ -1116,7 +1091,7 @@ dependencies = [ "fnv", "futures-core", "futures-sink", - "http 1.3.1", + "http", "indexmap", "slab", "tokio", @@ -1162,14 +1137,14 @@ dependencies = [ [[package]] name = "headers" -version = "0.3.9" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06683b93020a07e3dbcf5f8c0f6d40080d725bea7936fc01ad345c01b97dc270" +checksum = "b3314d5adb5d94bcdf56771f2e50dbbc80bb4bdf88967526706205ac9eff24eb" dependencies = [ - "base64 0.21.7", + "base64", "bytes", "headers-core", - "http 0.2.12", + "http", "httpdate", "mime", "sha1", @@ -1177,11 +1152,11 @@ dependencies = [ [[package]] name = "headers-core" -version = "0.2.0" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7f66481bfee273957b1f20485a4ff3362987f85b2c236580d81b4eb7a326429" +checksum = "54b4a22553d4242c49fddb9ba998a99962b5cc6f22cb5a3482bec22522403ce4" dependencies = [ - "http 0.2.12", + "http", ] [[package]] @@ -1196,17 +1171,6 @@ version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" -[[package]] -name = "http" -version = "0.2.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1" -dependencies = [ - "bytes", - "fnv", - "itoa", -] - [[package]] name = "http" version = "1.3.1" @@ -1218,17 +1182,6 @@ dependencies = [ "itoa", ] -[[package]] -name = "http-body" -version = "0.4.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" -dependencies = [ - "bytes", - "http 0.2.12", - "pin-project-lite", -] - [[package]] name = "http-body" version = "1.0.1" @@ -1236,7 +1189,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" dependencies = [ "bytes", - "http 1.3.1", + "http", ] [[package]] @@ -1247,8 +1200,8 @@ checksum = "b021d93e26becf5dc7e1b75b1bed1fd93124b374ceb73f43d4d4eafec896a64a" dependencies = [ "bytes", "futures-core", - "http 1.3.1", - "http-body 1.0.1", + "http", + "http-body", "pin-project-lite", ] @@ -1264,30 +1217,6 @@ version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" -[[package]] -name = "hyper" -version = "0.14.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41dfc780fdec9373c01bae43289ea34c972e40ee3c9f6b3c8801a35f35586ce7" -dependencies = [ - "bytes", - "futures-channel", - "futures-core", - "futures-util", - "h2 0.3.27", - "http 0.2.12", - "http-body 0.4.6", - "httparse", - "httpdate", - "itoa", - "pin-project-lite", - "socket2 0.5.10", - "tokio", - "tower-service", - "tracing", - "want", -] - [[package]] name = "hyper" version = "1.7.0" @@ -1298,9 +1227,9 @@ dependencies = [ "bytes", "futures-channel", "futures-core", - "h2 0.4.12", - "http 1.3.1", - "http-body 1.0.1", + "h2", + "http", + "http-body", "httparse", "httpdate", "itoa", @@ -1317,8 +1246,8 @@ version = "0.27.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3c93eb611681b207e1fe55d5a71ecf91572ec8a6705cdb6857f7d8d5242cf58" dependencies = [ - "http 1.3.1", - "hyper 1.7.0", + "http", + "hyper", "hyper-util", "rustls", "rustls-native-certs", @@ -1336,7 +1265,7 @@ checksum = "70206fc6890eaca9fde8a0bf71caa2ddfc9fe045ac9e5c70df101a7dbde866e0" dependencies = [ "bytes", "http-body-util", - "hyper 1.7.0", + "hyper", "hyper-util", "native-tls", "tokio", @@ -1350,19 +1279,19 @@ version = "0.1.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3c6995591a8f1380fcb4ba966a252a4b29188d51d2b89e3a252f5305be65aea8" dependencies = [ - "base64 0.22.1", + "base64", "bytes", "futures-channel", "futures-core", "futures-util", - "http 1.3.1", - "http-body 1.0.1", - "hyper 1.7.0", + "http", + "http-body", + "hyper", "ipnet", "libc", "percent-encoding", "pin-project-lite", - "socket2 0.6.1", + "socket2", "system-configuration", "tokio", "tower-service", @@ -1806,9 +1735,9 @@ version = "0.16.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dd7399781913e5393588a8d8c6a2867bf85fb38eaf2502fdce465aad2dc6f034" dependencies = [ - "base64 0.22.1", + "base64", "http-body-util", - "hyper 1.7.0", + "hyper", "hyper-rustls", "hyper-util", "indexmap", @@ -1832,7 +1761,7 @@ dependencies = [ "hashbrown 0.15.5", "metrics", "quanta", - "rand 0.9.2", + "rand", "rand_xoshiro", "sketches-ddsketch", ] @@ -1901,24 +1830,6 @@ dependencies = [ "uuid", ] -[[package]] -name = "multer" -version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01acbdc23469fd8fe07ab135923371d5f5a422fbf9c522158677c8eb15bc51c2" -dependencies = [ - "bytes", - "encoding_rs", - "futures-util", - "http 0.2.12", - "httparse", - "log", - "memchr", - "mime", - "spin", - "version_check", -] - [[package]] name = "multibase" version = "0.9.2" @@ -2292,35 +2203,14 @@ version = "5.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" -[[package]] -name = "rand" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" -dependencies = [ - "libc", - "rand_chacha 0.3.1", - "rand_core 0.6.4", -] - [[package]] name = "rand" version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1" dependencies = [ - "rand_chacha 0.9.0", - "rand_core 0.9.3", -] - -[[package]] -name = "rand_chacha" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" -dependencies = [ - "ppv-lite86", - "rand_core 0.6.4", + "rand_chacha", + "rand_core", ] [[package]] @@ -2330,16 +2220,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" dependencies = [ "ppv-lite86", - "rand_core 0.9.3", -] - -[[package]] -name = "rand_core" -version = "0.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" -dependencies = [ - "getrandom 0.2.16", + "rand_core", ] [[package]] @@ -2357,7 +2238,7 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f703f4665700daf5512dcca5f43afa6af89f09db47fb56be587f80636bda2d41" dependencies = [ - "rand_core 0.9.3", + "rand_core", ] [[package]] @@ -2414,16 +2295,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9d0946410b9f7b082a427e4ef5c8ff541a88b357bc6c637c40db3a68ac70a36f" dependencies = [ "async-compression", - "base64 0.22.1", + "base64", "bytes", "encoding_rs", "futures-core", "futures-util", - "h2 0.4.12", - "http 1.3.1", - "http-body 1.0.1", + "h2", + "http", + "http-body", "http-body-util", - "hyper 1.7.0", + "hyper", "hyper-rustls", "hyper-tls", "hyper-util", @@ -2805,7 +2686,7 @@ checksum = "c1e9a774a6c28142ac54bb25d25562e6bcf957493a184f15ad4eebccb23e410a" [[package]] name = "skyfeed" version = "0.6.0" -source = "git+https://github.com/cyypherus/skyfeed.git?rev=24a3a2913387c6bca775fb1831bab6a8f6597803#24a3a2913387c6bca775fb1831bab6a8f6597803" +source = "git+https://github.com/cyypherus/skyfeed.git?rev=d23838bf643881a253fa4f0b38a99727071be088#d23838bf643881a253fa4f0b38a99727071be088" dependencies = [ "anyhow", "async-trait", @@ -2829,7 +2710,7 @@ dependencies = [ "serde_ipld_dagcbor", "serde_json", "tokio", - "tokio-tungstenite 0.28.0", + "tokio-tungstenite", "warp", "whatlang", ] @@ -2846,16 +2727,6 @@ version = "1.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" -[[package]] -name = "socket2" -version = "0.5.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e22376abed350d73dd1cd119b57ffccad95b4e585a7cda43e286245ce23c0678" -dependencies = [ - "libc", - "windows-sys 0.52.0", -] - [[package]] name = "socket2" version = "0.6.1" @@ -3065,7 +2936,7 @@ dependencies = [ "parking_lot", "pin-project-lite", "signal-hook-registry", - "socket2 0.6.1", + "socket2", "tokio-macros", "windows-sys 0.61.2", ] @@ -3101,18 +2972,6 @@ dependencies = [ "tokio", ] -[[package]] -name = "tokio-tungstenite" -version = "0.21.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c83b561d025642014097b66e6c1bb422783339e0909e4429cde4749d1990bc38" -dependencies = [ - "futures-util", - "log", - "tokio", - "tungstenite 0.21.0", -] - [[package]] name = "tokio-tungstenite" version = "0.28.0" @@ -3126,7 +2985,7 @@ dependencies = [ "rustls-pki-types", "tokio", "tokio-rustls", - "tungstenite 0.28.0", + "tungstenite", ] [[package]] @@ -3176,8 +3035,8 @@ dependencies = [ "bitflags", "bytes", "futures-util", - "http 1.3.1", - "http-body 1.0.1", + "http", + "http-body", "iri-string", "pin-project-lite", "tower", @@ -3234,25 +3093,6 @@ version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" -[[package]] -name = "tungstenite" -version = "0.21.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ef1a641ea34f399a848dea702823bbecfb4c486f911735368f1f137cb8257e1" -dependencies = [ - "byteorder", - "bytes", - "data-encoding", - "http 1.3.1", - "httparse", - "log", - "rand 0.8.5", - "sha1", - "thiserror 1.0.69", - "url", - "utf-8", -] - [[package]] name = "tungstenite" version = "0.28.0" @@ -3261,10 +3101,10 @@ checksum = "8628dcc84e5a09eb3d8423d6cb682965dea9133204e8fb3efee74c2a0c259442" dependencies = [ "bytes", "data-encoding", - "http 1.3.1", + "http", "httparse", "log", - "rand 0.9.2", + "rand", "rustls", "rustls-pki-types", "sha1", @@ -3388,20 +3228,21 @@ dependencies = [ [[package]] name = "warp" -version = "0.3.7" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4378d202ff965b011c64817db11d5829506d3404edeadb61f190d111da3f231c" +checksum = "51d06d9202adc1f15d709c4f4a2069be5428aa912cc025d6f268ac441ab066b0" dependencies = [ "bytes", - "futures-channel", "futures-util", "headers", - "http 0.2.12", - "hyper 0.14.32", + "http", + "http-body", + "http-body-util", + "hyper", + "hyper-util", "log", "mime", "mime_guess", - "multer", "percent-encoding", "pin-project", "scoped-tls", @@ -3409,7 +3250,6 @@ dependencies = [ "serde_json", "serde_urlencoded", "tokio", - "tokio-tungstenite 0.21.0", "tokio-util", "tower-service", "tracing", diff --git a/examples/sqlite/Cargo.toml b/examples/sqlite/Cargo.toml index e3aaeee..3de40ed 100644 --- a/examples/sqlite/Cargo.toml +++ b/examples/sqlite/Cargo.toml @@ -3,13 +3,14 @@ name = "sqlite-feed" version = "0.1.0" edition = "2024" publish = false +rust-version = "1.90.0" [features] local = [] [dependencies] log = "0.4.25" -skyfeed = { git = "https://github.com/cyypherus/skyfeed.git", rev = "24a3a2913387c6bca775fb1831bab6a8f6597803" } +skyfeed = { git = "https://github.com/cyypherus/skyfeed.git", rev = "d23838bf643881a253fa4f0b38a99727071be088" } # skyfeed = { path = "../.." } tokio = { version = "1.43.0", features = ["full", "time"] } rusqlite = { version = "0.33.0", features = ["bundled"] } diff --git a/examples/sqlite/src/main.rs b/examples/sqlite/src/main.rs index 937b2f1..abc40a5 100644 --- a/examples/sqlite/src/main.rs +++ b/examples/sqlite/src/main.rs @@ -18,13 +18,9 @@ async fn main() { let db = Connection::open("/space/feed.db").expect("Failed to open database"); initialize_db(&db); - let db = Arc::new(Mutex::new(db)); - let my_feed_regex = env::var("MY_FEED_REGEX").expect("Missing feed regex"); let fr_feed_regex = env::var("FR_FEED_REGEX").expect("Missing feed regex"); - let pending_posts = Arc::new(Mutex::new(Vec::new())); - let pending_likes = Arc::new(Mutex::new(Vec::new())); - let handler = MyFeedHandler { + let handler = Arc::new(Mutex::new(MyFeedHandler { fr_regex: regex::RegexBuilder::new(fr_feed_regex.as_str()) .case_insensitive(true) .build() @@ -32,22 +28,21 @@ async fn main() { my_regex: regex::RegexBuilder::new(my_feed_regex.as_str()) .build() .unwrap(), - db: db.clone(), - pending_posts: pending_posts.clone(), - pending_likes: pending_likes.clone(), - }; + db: Mutex::new(db), + pending_posts: Vec::new(), + pending_likes: Vec::new(), + })); - let db_clone = db.clone(); - let posts_for_flushing = pending_posts.clone(); - let likes_for_flushing = pending_likes.clone(); + let handler_clone = handler.clone(); let mut flush_interval = tokio::time::interval(Duration::from_secs(10)); let flush_task = tokio::spawn(async move { loop { flush_interval.tick().await; - flush_posts(&db.clone(), &posts_for_flushing).await; - flush_likes(&db.clone(), &likes_for_flushing).await; - cleanup_posts(&db_clone, FR_FEED, 10_000).await; - cleanup_posts(&db_clone, MY_FEED, 200_000).await; + let mut handler = handler_clone.lock().await; + handler.flush_posts().await; + handler.flush_likes().await; + handler.cleanup_posts(FR_FEED, 10_000).await; + handler.cleanup_posts(MY_FEED, 200_000).await; } }); @@ -68,13 +63,113 @@ async fn main() { .expect("Starting tasks failed"); } -#[derive(Clone)] struct MyFeedHandler { fr_regex: Regex, my_regex: Regex, - db: Arc>, - pending_posts: Arc>>, - pending_likes: Arc>>, + db: Mutex, + pending_posts: Vec<(String, String, i64, String)>, + pending_likes: Vec<(String, String)>, +} + +impl MyFeedHandler { + async fn flush_posts(&mut self) { + if self.pending_posts.is_empty() { + return; + } + + let posts_to_insert: Vec<_> = self.pending_posts.drain(..).collect(); + let count = posts_to_insert.len(); + + let mut db = self.db.lock().await; + let tx = db.transaction().expect("Failed to start transaction"); + + { + let mut stmt = tx + .prepare( + "INSERT OR REPLACE INTO posts (uri, text, timestamp, feed) VALUES (?1, ?2, ?3, ?4)", + ) + .expect("Failed to prepare statement"); + + for (uri, text, timestamp, feed) in posts_to_insert { + stmt.execute(params![uri, text, timestamp, feed]) + .expect("Failed to insert post"); + } + } + + tx.commit().expect("Failed to commit transaction"); + trace!("Successfully flushed {} posts", count); + } + + async fn flush_likes(&mut self) { + if self.pending_likes.is_empty() { + return; + } + + let likes_to_insert: Vec<_> = self.pending_likes.drain(..).collect(); + let count = likes_to_insert.len(); + + let mut db = self.db.lock().await; + let tx = db.transaction().expect("Failed to start transaction"); + + { + let mut stmt = tx.prepare( + "INSERT OR REPLACE INTO likes (post_uri, like_uri) SELECT ?1, ?2 WHERE EXISTS (SELECT 1 FROM posts WHERE uri = ?1)" + ).expect("Failed to prepare statement"); + + for (post_uri, like_uri) in likes_to_insert { + stmt.execute(params![post_uri, like_uri]) + .expect("Failed to insert like"); + } + } + + tx.commit().expect("Failed to commit transaction"); + trace!("Successfully flushed {} likes", count); + } + + async fn cleanup_posts(&mut self, feed: &str, post_limit: usize) { + let db = self.db.lock().await; + let oldest_timestamp = db + .query_row( + "SELECT MIN(timestamp) FROM posts WHERE feed = ?1", + params![feed], + |row| row.get::<_, Option>(0), + ) + .expect("Failed to get oldest post timestamp"); + + let oldest_date = oldest_timestamp.map(|ts| { + chrono::DateTime::::from_timestamp(ts, 0) + .map(|dt| dt.to_rfc3339()) + .unwrap_or_else(|| "Invalid timestamp".to_string()) + }); + + let cleaned_posts = db + .execute( + "DELETE FROM posts + WHERE feed = ?1 + AND uri NOT IN ( + SELECT uri + FROM posts + WHERE feed = ?1 + ORDER BY timestamp DESC + LIMIT ?2 + );", + params![feed, post_limit], + ) + .expect("Failed to clean up old posts"); + + let remaining_posts = db + .query_row( + "SELECT COUNT(*) FROM posts WHERE feed = ?1", + params![feed], + |row| row.get::<_, usize>(0), + ) + .expect("Failed to count remaining posts"); + + info!( + "Cleaned up {cleaned_posts} posts on {feed}. Oldest post available: {}. {remaining_posts} posts remain.", + oldest_date.unwrap_or_else(|| "No posts".to_string()) + ); + } } impl FeedHandler for MyFeedHandler { @@ -101,9 +196,7 @@ impl FeedHandler for MyFeedHandler { }; if let Some(feed) = feed_to_insert { - // trace!("Queuing {} feed post {post:?}", feed); - let mut pending = self.pending_posts.lock().await; - pending.push(( + self.pending_posts.push(( post.uri.0.clone(), post.text.clone(), timestamp, @@ -122,8 +215,8 @@ impl FeedHandler for MyFeedHandler { } async fn insert_like(&mut self, like_uri: Uri, liked_post_uri: Uri) { - let mut pending = self.pending_likes.lock().await; - pending.push((liked_post_uri.0.clone(), like_uri.0.clone())); + self.pending_likes + .push((liked_post_uri.0.clone(), like_uri.0.clone())); } async fn delete_like(&mut self, like_uri: Uri) { @@ -207,10 +300,14 @@ impl FeedHandler for MyFeedHandler { info!("Returned {} posts for feed {}", posts.len(), request.feed); - let next_cursor = if posts.len() == request_limit { - let next_offset = post_offset + posts.len(); - if next_offset < 100 { - Some(format!("{}:{}", hours_back, next_offset)) + let next_cursor = if !posts.is_empty() { + if posts.len() == request_limit { + let next_offset = post_offset + posts.len(); + if next_offset < 100 { + Some(format!("{}:{}", hours_back, next_offset)) + } else { + Some(format!("{}:0", hours_back + 1)) + } } else { Some(format!("{}:0", hours_back + 1)) } @@ -225,120 +322,6 @@ impl FeedHandler for MyFeedHandler { } } -async fn flush_posts( - db: &Arc>, - pending_posts: &Arc>>, -) { - let mut pending = pending_posts.lock().await; - if pending.is_empty() { - return; - } - - let posts_to_insert: Vec<_> = pending.drain(..).collect(); - let count = posts_to_insert.len(); - drop(pending); - - let mut db = db.lock().await; - let tx = db.transaction().expect("Failed to start transaction"); - - { - let mut stmt = tx - .prepare( - "INSERT OR REPLACE INTO posts (uri, text, timestamp, feed) VALUES (?1, ?2, ?3, ?4)", - ) - .expect("Failed to prepare statement"); - - for (uri, text, timestamp, feed) in posts_to_insert { - stmt.execute(params![uri, text, timestamp, feed]) - .expect("Failed to insert post"); - } - } - - tx.commit().expect("Failed to commit transaction"); - trace!("Successfully flushed {} posts", count); -} - -async fn flush_likes( - db: &Arc>, - pending_likes: &Arc>>, -) { - let mut pending = pending_likes.lock().await; - if pending.is_empty() { - return; - } - - let likes_to_insert: Vec<_> = pending.drain(..).collect(); - let count = likes_to_insert.len(); - drop(pending); - - let mut db = db.lock().await; - let tx = db.transaction().expect("Failed to start transaction"); - - { - let mut stmt = tx.prepare( - "INSERT OR REPLACE INTO likes (post_uri, like_uri) SELECT ?1, ?2 WHERE EXISTS (SELECT 1 FROM posts WHERE uri = ?1)" - ).expect("Failed to prepare statement"); - - for (post_uri, like_uri) in likes_to_insert { - stmt.execute(params![post_uri, like_uri]) - .expect("Failed to insert like"); - } - } - - tx.commit().expect("Failed to commit transaction"); - trace!("Successfully flushed {} likes", count); -} - -async fn cleanup_posts(db: &Arc>, feed: &str, post_limit: usize) { - let oldest_timestamp = db - .lock() - .await - .query_row( - "SELECT MIN(timestamp) FROM posts WHERE feed = ?1", - params![feed], - |row| row.get::<_, Option>(0), - ) - .expect("Failed to get oldest post timestamp"); - - let oldest_date = oldest_timestamp.map(|ts| { - chrono::DateTime::::from_timestamp(ts, 0) - .map(|dt| dt.to_rfc3339()) - .unwrap_or_else(|| "Invalid timestamp".to_string()) - }); - - let cleaned_posts = db - .lock() - .await - .execute( - "DELETE FROM posts - WHERE feed = ?1 - AND uri NOT IN ( - SELECT uri - FROM posts - WHERE feed = ?1 - ORDER BY timestamp DESC - LIMIT ?2 - );", - params![feed, post_limit], - ) - .expect("Failed to clean up old posts"); - - let remaining_posts = db - .lock() - .await - .query_row( - "SELECT COUNT(*) FROM posts WHERE feed = ?1", - params![feed], - |row| row.get::<_, usize>(0), - ) - .expect("Failed to count remaining posts"); - - info!( - "Cleaned up {cleaned_posts} posts on {feed}. Oldest post available: {}. {remaining_posts} posts remain.", - oldest_date.unwrap_or_else(|| "No posts".to_string()) - ); -} - fn initialize_db(db: &Connection) { db.execute( "CREATE TABLE IF NOT EXISTS posts ( diff --git a/src/feed.rs b/src/feed.rs index 32e91c7..39fcfc1 100644 --- a/src/feed.rs +++ b/src/feed.rs @@ -47,14 +47,11 @@ pub trait FeedHandler { /// Panics if unable to bind to the provided address. pub async fn start( config: Config, - feed_handler: impl FeedHandler + Send + 'static, + feed_handler: Arc>, address: impl Into + Send + 'static, ) { env_logger::Builder::from_env(Env::default().default_filter_or("info")).init(); let address: SocketAddr = address.into(); - let feed_handler = Arc::new(Mutex::new(feed_handler)); - let config = config; - let did_config = config.clone(); let did_json = warp::path(".well-known") .and(warp::path("did.json")) From 2809faf5af2cf176681fa9fcd55f6b862111c737 Mon Sep 17 00:00:00 2001 From: cyypherus Date: Sat, 6 Dec 2025 16:43:22 -0700 Subject: [PATCH 40/53] timezone, post culling for longer timeline --- Cargo.lock | 35 +++++++++++++++++++++++++++++++++++ Cargo.toml | 1 + examples/sqlite/Cargo.lock | 37 ++++++++++++++++++++++++++++++++++++- examples/sqlite/Cargo.toml | 3 ++- examples/sqlite/src/main.rs | 37 +++++++++++++++++++++++++------------ 5 files changed, 99 insertions(+), 14 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3d850c0..66a1938 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -498,6 +498,16 @@ dependencies = [ "windows-link", ] +[[package]] +name = "chrono-tz" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6139a8597ed92cf816dfb33f5dd6cf0bb93a6adc938f11039f371bc5bcd26c3" +dependencies = [ + "chrono", + "phf", +] + [[package]] name = "cid" version = "0.10.1" @@ -2013,6 +2023,24 @@ version = "2.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" +[[package]] +name = "phf" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "913273894cec178f401a31ec4b656318d95473527be05c0752cc41cdc32be8b7" +dependencies = [ + "phf_shared", +] + +[[package]] +name = "phf_shared" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06005508882fb681fd97892ecff4b7fd0fee13ef1aa569f8695dae7ab9099981" +dependencies = [ + "siphasher", +] + [[package]] name = "pin-project" version = "1.1.10" @@ -2687,6 +2715,12 @@ version = "2.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bbbb5d9659141646ae647b42fe094daf6c6192d1620870b449d9557f748b2daa" +[[package]] +name = "siphasher" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56199f7ddabf13fe5074ce809e7d3f42b42ae711800501b5b16ea82ad029c39d" + [[package]] name = "skyfeed" version = "0.6.0" @@ -2697,6 +2731,7 @@ dependencies = [ "atrium-repo", "atrium-xrpc-client", "chrono", + "chrono-tz", "clap", "dotenv", "env_logger", diff --git a/Cargo.toml b/Cargo.toml index 61b095c..17fd809 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -65,6 +65,7 @@ flume = "0.11.1" rusqlite = { version = "0.33.0", features = ["bundled"], optional = true } regex = { version = "1.11.1", optional = true } whatlang = { version = "0.16.4", optional = true } +chrono-tz = { version = "0.10", optional = true } # `test-api` feature dependencies insta = { version = "1.42.1", optional = true } diff --git a/examples/sqlite/Cargo.lock b/examples/sqlite/Cargo.lock index 5ab160c..9c6c1a8 100644 --- a/examples/sqlite/Cargo.lock +++ b/examples/sqlite/Cargo.lock @@ -468,6 +468,16 @@ dependencies = [ "windows-link 0.2.1", ] +[[package]] +name = "chrono-tz" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6139a8597ed92cf816dfb33f5dd6cf0bb93a6adc938f11039f371bc5bcd26c3" +dependencies = [ + "chrono", + "phf", +] + [[package]] name = "cid" version = "0.10.1" @@ -2040,6 +2050,24 @@ version = "2.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" +[[package]] +name = "phf" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "913273894cec178f401a31ec4b656318d95473527be05c0752cc41cdc32be8b7" +dependencies = [ + "phf_shared", +] + +[[package]] +name = "phf_shared" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06005508882fb681fd97892ecff4b7fd0fee13ef1aa569f8695dae7ab9099981" +dependencies = [ + "siphasher", +] + [[package]] name = "pin-project" version = "1.1.10" @@ -2677,6 +2705,12 @@ version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe" +[[package]] +name = "siphasher" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56199f7ddabf13fe5074ce809e7d3f42b42ae711800501b5b16ea82ad029c39d" + [[package]] name = "sketches-ddsketch" version = "0.3.0" @@ -2686,7 +2720,7 @@ checksum = "c1e9a774a6c28142ac54bb25d25562e6bcf957493a184f15ad4eebccb23e410a" [[package]] name = "skyfeed" version = "0.6.0" -source = "git+https://github.com/cyypherus/skyfeed.git?rev=d23838bf643881a253fa4f0b38a99727071be088#d23838bf643881a253fa4f0b38a99727071be088" +source = "git+https://github.com/cyypherus/skyfeed.git?rev=93899a464bc4c3a24a54c2e1e98ddd9ca0503662#93899a464bc4c3a24a54c2e1e98ddd9ca0503662" dependencies = [ "anyhow", "async-trait", @@ -2751,6 +2785,7 @@ name = "sqlite-feed" version = "0.1.0" dependencies = [ "chrono", + "chrono-tz", "dotenv", "log", "metrics", diff --git a/examples/sqlite/Cargo.toml b/examples/sqlite/Cargo.toml index 3de40ed..cea3a32 100644 --- a/examples/sqlite/Cargo.toml +++ b/examples/sqlite/Cargo.toml @@ -10,11 +10,12 @@ local = [] [dependencies] log = "0.4.25" -skyfeed = { git = "https://github.com/cyypherus/skyfeed.git", rev = "d23838bf643881a253fa4f0b38a99727071be088" } +skyfeed = { git = "https://github.com/cyypherus/skyfeed.git", rev = "93899a464bc4c3a24a54c2e1e98ddd9ca0503662" } # skyfeed = { path = "../.." } tokio = { version = "1.43.0", features = ["full", "time"] } rusqlite = { version = "0.33.0", features = ["bundled"] } chrono = "0.4.39" +chrono-tz = "0.10" regex = "1.11.1" whatlang = "0.16.4" metrics = "0.24.1" diff --git a/examples/sqlite/src/main.rs b/examples/sqlite/src/main.rs index abc40a5..b5f7fe8 100644 --- a/examples/sqlite/src/main.rs +++ b/examples/sqlite/src/main.rs @@ -1,6 +1,7 @@ #![allow(clippy::type_complexity)] // use dotenv::dotenv; +use chrono_tz::America::Denver; use log::{error, info, trace}; use regex::Regex; use rusqlite::{Connection, params}; @@ -136,23 +137,35 @@ impl MyFeedHandler { ) .expect("Failed to get oldest post timestamp"); - let oldest_date = oldest_timestamp.map(|ts| { + let oldest_date = oldest_timestamp.and_then(|ts| { chrono::DateTime::::from_timestamp(ts, 0) - .map(|dt| dt.to_rfc3339()) - .unwrap_or_else(|| "Invalid timestamp".to_string()) + .map(|dt| dt.with_timezone(&Denver).to_rfc3339()) }); + let cutoff_time = chrono::Utc::now().timestamp() - 5400; + let zero_likes_cleaned = db + .execute( + "DELETE FROM posts + WHERE feed = ?1 + AND timestamp < ?2 + AND uri NOT IN ( + SELECT DISTINCT post_uri FROM likes + );", + params![feed, cutoff_time], + ) + .expect("Failed to clean up zero-like posts"); + let cleaned_posts = db .execute( "DELETE FROM posts - WHERE feed = ?1 - AND uri NOT IN ( - SELECT uri - FROM posts - WHERE feed = ?1 - ORDER BY timestamp DESC - LIMIT ?2 - );", + WHERE feed = ?1 + AND uri NOT IN ( + SELECT uri + FROM posts + WHERE feed = ?1 + ORDER BY timestamp DESC + LIMIT ?2 + );", params![feed, post_limit], ) .expect("Failed to clean up old posts"); @@ -166,7 +179,7 @@ impl MyFeedHandler { .expect("Failed to count remaining posts"); info!( - "Cleaned up {cleaned_posts} posts on {feed}. Oldest post available: {}. {remaining_posts} posts remain.", + "Cleaned up {cleaned_posts} posts on {feed} (plus {zero_likes_cleaned} zero-like posts). Oldest post available: {}. {remaining_posts} posts remain.", oldest_date.unwrap_or_else(|| "No posts".to_string()) ); } From 0ffcfebb9290096915d3d2eb9566c9fc28662bcf Mon Sep 17 00:00:00 2001 From: cyypherus Date: Sat, 6 Dec 2025 18:12:26 -0700 Subject: [PATCH 41/53] rayon parallel post filtering, comments, slower warning, cleanup basic example --- Cargo.lock | 37 +++ Cargo.toml | 3 +- examples/basic/src/main.rs | 36 +-- examples/sqlite/Cargo.lock | 522 ++++++++++++++---------------------- examples/sqlite/Cargo.toml | 1 + examples/sqlite/src/main.rs | 136 ++++++---- src/feed.rs | 2 +- 7 files changed, 344 insertions(+), 393 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 66a1938..5a4b572 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -702,6 +702,16 @@ dependencies = [ "crossbeam-utils", ] +[[package]] +name = "crossbeam-deque" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9dd111b7b7f7d55b72c0a6ae361660ee5853c9af73f70c3c2ef6858b950e2e51" +dependencies = [ + "crossbeam-epoch", + "crossbeam-utils", +] + [[package]] name = "crossbeam-epoch" version = "0.9.18" @@ -800,6 +810,12 @@ version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813" +[[package]] +name = "either" +version = "1.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" + [[package]] name = "encode_unicode" version = "1.0.0" @@ -2221,6 +2237,26 @@ dependencies = [ "getrandom 0.3.4", ] +[[package]] +name = "rayon" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "368f01d005bf8fd9b1206fb6fa653e6c4a81ceb1466406b81792d87c5677a58f" +dependencies = [ + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22e18b0f0062d30d4230b2e85ff77fdfe4326feb054b9783a3460d8435c8ab91" +dependencies = [ + "crossbeam-deque", + "crossbeam-utils", +] + [[package]] name = "redox_syscall" version = "0.5.18" @@ -2741,6 +2777,7 @@ dependencies = [ "ipld-core", "log", "public-api", + "rayon", "regex", "reqwest", "rs-car", diff --git a/Cargo.toml b/Cargo.toml index 17fd809..cf59325 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,7 +13,7 @@ authors = ["cyypherus"] [features] default = ["examples"] test-api = ["insta", "public-api", "rustdoc-json", "rustup-toolchain"] -examples = ["rusqlite", "regex", "whatlang"] +examples = ["rusqlite", "regex", "whatlang", "chrono-tz", "rayon"] [[bin]] name = "my_did" @@ -66,6 +66,7 @@ rusqlite = { version = "0.33.0", features = ["bundled"], optional = true } regex = { version = "1.11.1", optional = true } whatlang = { version = "0.16.4", optional = true } chrono-tz = { version = "0.10", optional = true } +rayon = { version = "1.11.0", optional = true } # `test-api` feature dependencies insta = { version = "1.42.1", optional = true } diff --git a/examples/basic/src/main.rs b/examples/basic/src/main.rs index ff2778c..9aec55c 100644 --- a/examples/basic/src/main.rs +++ b/examples/basic/src/main.rs @@ -1,23 +1,21 @@ use log::info; -use skyfeed::{Config, FeedHandler, FeedResult, Post, FeedRequest, Uri, start}; +use skyfeed::{Config, FeedHandler, FeedRequest, FeedResult, Post, Uri, start}; use std::{collections::HashSet, sync::Arc}; use tokio::sync::Mutex; #[tokio::main] async fn main() { - let handler = MyFeedHandler { - posts: Arc::new(Mutex::new(Vec::new())), - }; + let handler = MyFeedHandler { posts: Vec::new() }; let config = Config { publisher_did: "did:web:example.com".to_string(), feed_generator_hostname: "example.com".to_string(), }; - start(config, handler, ([0, 0, 0, 0], 3030)).await + start(config, Arc::new(Mutex::new(handler)), ([0, 0, 0, 0], 3030)).await } #[derive(Clone)] struct MyFeedHandler { - posts: Arc>>, + posts: Vec, } #[derive(Debug, Clone)] @@ -36,15 +34,13 @@ impl FeedHandler for MyFeedHandler { if post.text.to_lowercase().contains(" cat ") { const MAX_POSTS: usize = 100; - let mut posts = self.posts.lock().await; - - posts.push(MyPost { + self.posts.push(MyPost { post, likes: HashSet::new(), }); - if posts.len() > MAX_POSTS { - posts.remove(0); + if self.posts.len() > MAX_POSTS { + self.posts.remove(0); } } } @@ -52,26 +48,18 @@ impl FeedHandler for MyFeedHandler { async fn delete_post(&mut self, uri: Uri) { println!("🗑️ DELETE POST: {}", uri.0); self.posts - .lock() - .await .retain(|post_with_likes| post_with_likes.post.uri != uri); } async fn insert_like(&mut self, like_uri: Uri, liked_post_uri: Uri) { - if let Some(post_with_likes) = self - .posts - .lock() - .await - .iter_mut() - .find(|p| p.post.uri == liked_post_uri) + if let Some(post_with_likes) = self.posts.iter_mut().find(|p| p.post.uri == liked_post_uri) { post_with_likes.likes.insert(like_uri); } } async fn delete_like(&mut self, like_uri: Uri) { - let mut posts = self.posts.lock().await; - for post_with_likes in posts.iter_mut() { + for post_with_likes in self.posts.iter_mut() { post_with_likes.likes.remove(&like_uri); } } @@ -79,8 +67,6 @@ impl FeedHandler for MyFeedHandler { async fn serve_feed(&self, request: FeedRequest) -> FeedResult { info!("Serving {request:?}"); - let posts = self.posts.lock().await; - // Parse the cursor from the request let start_index = if let Some(cursor) = &request.cursor { cursor.parse::().unwrap_or(0) @@ -91,7 +77,7 @@ impl FeedHandler for MyFeedHandler { let posts_per_page = 5; // Sort posts by likes - let mut sorted_posts: Vec<_> = posts.iter().collect(); + let mut sorted_posts: Vec<_> = self.posts.iter().collect(); sorted_posts.sort_by(|a, b| b.likes.len().cmp(&a.likes.len())); // Paginate posts @@ -103,7 +89,7 @@ impl FeedHandler for MyFeedHandler { .collect(); // Calculate the next cursor - let next_cursor = if start_index + posts_per_page < posts.len() { + let next_cursor = if start_index + posts_per_page < self.posts.len() { Some((start_index + posts_per_page).to_string()) } else { None diff --git a/examples/sqlite/Cargo.lock b/examples/sqlite/Cargo.lock index 9c6c1a8..2e4069b 100644 --- a/examples/sqlite/Cargo.lock +++ b/examples/sqlite/Cargo.lock @@ -31,9 +31,9 @@ dependencies = [ [[package]] name = "aho-corasick" -version = "1.1.3" +version = "1.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" +checksum = "ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301" dependencies = [ "memchr", ] @@ -85,22 +85,22 @@ dependencies = [ [[package]] name = "anstyle-query" -version = "1.1.4" +version = "1.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e231f6134f61b71076a3eab506c379d4f36122f2af15a9ff04415ea4c3339e2" +checksum = "40c48f72fd53cd289104fc64099abca73db4166ad86ea0b4341abe65af83dadc" dependencies = [ - "windows-sys 0.60.2", + "windows-sys 0.61.2", ] [[package]] name = "anstyle-wincon" -version = "3.0.10" +version = "3.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e0633414522a32ffaac8ac6cc8f748e090c5717661fddeea04219e2344f5f2a" +checksum = "291e6a250ff86cd4a820112fb8898808a366d8f9f58ce16d1f538353ad55747d" dependencies = [ "anstyle", "once_cell_polyfill", - "windows-sys 0.60.2", + "windows-sys 0.61.2", ] [[package]] @@ -123,9 +123,9 @@ checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" [[package]] name = "async-compression" -version = "0.4.32" +version = "0.4.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a89bce6054c720275ac2432fbba080a66a2106a44a1b804553930ca6909f4e0" +checksum = "0e86f6d3dc9dc4352edeea6b8e499e13e3f5dc3b964d7ca5fd411415a3498473" dependencies = [ "compression-codecs", "compression-core", @@ -164,7 +164,7 @@ checksum = "c7c24de15d275a1ecfd47a380fb4d5ec9bfe0933f309ed5e705b775596a3574d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.111", ] [[package]] @@ -175,7 +175,7 @@ checksum = "9035ad2d096bed7955a320ee7e2230574d28fd3c3a0f186cbea1ff3c7eed5dbb" dependencies = [ "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.111", ] [[package]] @@ -272,9 +272,9 @@ checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" [[package]] name = "aws-lc-rs" -version = "1.14.1" +version = "1.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "879b6c89592deb404ba4dc0ae6b58ffd1795c78991cbb5b8bc441c48a070440d" +checksum = "6b5ce75405893cd713f9ab8e297d8e438f624dde7d706108285f7e17a25a180f" dependencies = [ "aws-lc-sys", "zeroize", @@ -282,11 +282,10 @@ dependencies = [ [[package]] name = "aws-lc-sys" -version = "0.32.3" +version = "0.34.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "107a4e9d9cab9963e04e84bb8dee0e25f2a987f9a8bad5ed054abd439caa8f8c" +checksum = "179c3777a8b5e70e90ea426114ffc565b2c1a9f82f6c4a0c5a34aa6ef5e781b6" dependencies = [ - "bindgen", "cc", "cmake", "dunce", @@ -305,7 +304,7 @@ dependencies = [ "miniz_oxide", "object", "rustc-demangle", - "windows-link 0.2.1", + "windows-link", ] [[package]] @@ -330,26 +329,6 @@ version = "0.22.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" -[[package]] -name = "bindgen" -version = "0.72.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "993776b509cfb49c750f11b8f07a46fa23e0a1386ffc01fb1e7d343efc387895" -dependencies = [ - "bitflags", - "cexpr", - "clang-sys", - "itertools", - "log", - "prettyplease", - "proc-macro2", - "quote", - "regex", - "rustc-hash", - "shlex", - "syn 2.0.108", -] - [[package]] name = "bitflags" version = "2.10.0" @@ -414,9 +393,9 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.10.1" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a" +checksum = "b35204fbdc0b3f4446b89fc1ac2cf84a8a68971995d0bf2e925ec7cd960f9cb3" [[package]] name = "cbor4ii" @@ -429,9 +408,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.2.43" +version = "1.2.49" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "739eb0f94557554b3ca9a86d2d37bebd49c5e6d0c1d2bda35ba5bdac830befc2" +checksum = "90583009037521a116abf44494efecd645ba48b6622457080f080b85544e2215" dependencies = [ "find-msvc-tools", "jobserver", @@ -439,15 +418,6 @@ dependencies = [ "shlex", ] -[[package]] -name = "cexpr" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766" -dependencies = [ - "nom", -] - [[package]] name = "cfg-if" version = "1.0.4" @@ -465,7 +435,7 @@ dependencies = [ "num-traits", "serde", "wasm-bindgen", - "windows-link 0.2.1", + "windows-link", ] [[package]] @@ -505,22 +475,11 @@ dependencies = [ "unsigned-varint 0.8.0", ] -[[package]] -name = "clang-sys" -version = "1.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b023947811758c97c59bf9d1c188fd619ad4718dcaa767947df1cadb14f39f4" -dependencies = [ - "glob", - "libc", - "libloading", -] - [[package]] name = "clap" -version = "4.5.50" +version = "4.5.53" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c2cfd7bf8a6017ddaa4e32ffe7403d547790db06bd171c1c53926faab501623" +checksum = "c9e340e012a1bf4935f5282ed1436d1489548e8f72308207ea5df0e23d2d03f8" dependencies = [ "clap_builder", "clap_derive", @@ -528,9 +487,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.50" +version = "4.5.53" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a4c05b9e80c5ccd3a7ef080ad7b6ba7d6fc00a985b8b157197075677c82c7a0" +checksum = "d76b5d13eaa18c901fd2f7fca939fefe3a0727a953561fefdf3b2922b8569d00" dependencies = [ "anstream", "anstyle", @@ -547,7 +506,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.111", ] [[package]] @@ -573,9 +532,9 @@ checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75" [[package]] name = "compression-codecs" -version = "0.4.31" +version = "0.4.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef8a506ec4b81c460798f572caead636d57d3d7e940f998160f52bd254bf2d23" +checksum = "302266479cb963552d11bd042013a58ef1adc56768016c8b82b4199488f2d4ad" dependencies = [ "compression-core", "flate2", @@ -584,9 +543,9 @@ dependencies = [ [[package]] name = "compression-core" -version = "0.4.29" +version = "0.4.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e47641d3deaf41fb1538ac1f54735925e275eaf3bf4d55c81b137fba797e5cbb" +checksum = "75984efb6ed102a0d42db99afb6c1948f0380d1d91808d5529916e6c08b49d8d" [[package]] name = "concurrent-queue" @@ -671,6 +630,16 @@ dependencies = [ "crossbeam-utils", ] +[[package]] +name = "crossbeam-deque" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9dd111b7b7f7d55b72c0a6ae361660ee5853c9af73f70c3c2ef6858b950e2e51" +dependencies = [ + "crossbeam-epoch", + "crossbeam-utils", +] + [[package]] name = "crossbeam-epoch" version = "0.9.18" @@ -688,9 +657,9 @@ checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" [[package]] name = "crypto-common" -version = "0.1.6" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +checksum = "78c8292055d1c1df0cce5d180393dc8cce0abec0a7102adb6c7b1eef6016d60a" dependencies = [ "generic-array", "typenum", @@ -733,7 +702,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8d162beedaa69905488a8da94f5ac3edb4dd4788b732fadb7bd120b2625c1976" dependencies = [ "data-encoding", - "syn 2.0.108", + "syn 2.0.111", ] [[package]] @@ -754,7 +723,7 @@ checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.111", ] [[package]] @@ -886,15 +855,15 @@ checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" [[package]] name = "find-msvc-tools" -version = "0.1.4" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52051878f80a721bb68ebfbc930e07b65ba72f2da88968ea5c06fd6ca3d3a127" +checksum = "3a3076410a55c90011c298b04d0cfa770b00fa04e1e3c97d3f6c9de105a03844" [[package]] name = "flate2" -version = "1.1.5" +version = "1.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfe33edd8e85a12a67454e37f8c75e730830d83e313556ab9ebf9ee7fbeb3bfb" +checksum = "a2152dbcb980c05735e2a651d96011320a949eb31a0c8b38b72645ce97dec676" dependencies = [ "crc32fast", "miniz_oxide", @@ -1010,7 +979,7 @@ checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" dependencies = [ "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.111", ] [[package]] @@ -1045,9 +1014,9 @@ dependencies = [ [[package]] name = "generic-array" -version = "0.14.9" +version = "0.14.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4bb6743198531e02858aeaea5398fcc883e71851fcbcb5a2f773e2fb6cb1edf2" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" dependencies = [ "typenum", "version_check", @@ -1084,12 +1053,6 @@ version = "0.32.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e629b9b98ef3dd8afe6ca2bd0f89306cec16d43d907889945bc5d6687f2f13c7" -[[package]] -name = "glob" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0cc23270f6e1808e30a928bdc84dea0b9b4136a8bc82338574f23baf47bbd280" - [[package]] name = "h2" version = "0.4.12" @@ -1132,9 +1095,9 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.16.0" +version = "0.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5419bdc4f6a9207fbeba6d11b604d481addf78ecd10c11ad51e76c2f6482748d" +checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100" [[package]] name = "hashlink" @@ -1183,12 +1146,11 @@ checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" [[package]] name = "http" -version = "1.3.1" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4a85d31aea989eead29a3aaf9e1115a180df8282431156e533de47660892565" +checksum = "e3ba2a386d7f85a81f119ad7498ebe444d2e22c2af0b86b069416ace48b3311a" dependencies = [ "bytes", - "fnv", "itoa", ] @@ -1229,9 +1191,9 @@ checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" [[package]] name = "hyper" -version = "1.7.0" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb3aa54a13a0dfe7fbe3a59e0c76093041720fdc77b110cc0fc260fafb4dc51e" +checksum = "2ab2d4f250c3d7b1c9fcdff1cece94ea4e2dfbec68614f7b87cb205f24ca9d11" dependencies = [ "atomic-waker", "bytes", @@ -1285,9 +1247,9 @@ dependencies = [ [[package]] name = "hyper-util" -version = "0.1.17" +version = "0.1.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c6995591a8f1380fcb4ba966a252a4b29188d51d2b89e3a252f5305be65aea8" +checksum = "727805d60e7938b76b826a6ef209eb70eaa1812794f9424d4a4e2d740662df5f" dependencies = [ "base64", "bytes", @@ -1335,9 +1297,9 @@ dependencies = [ [[package]] name = "icu_collections" -version = "2.0.0" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "200072f5d0e3614556f94a9930d5dc3e0662a652823904c3a75dc3b0af7fee47" +checksum = "4c6b649701667bbe825c3b7e6388cb521c23d88644678e83c0c4d0a621a34b43" dependencies = [ "displaydoc", "potential_utf", @@ -1348,9 +1310,9 @@ dependencies = [ [[package]] name = "icu_locale_core" -version = "2.0.0" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0cde2700ccaed3872079a65fb1a78f6c0a36c91570f28755dda67bc8f7d9f00a" +checksum = "edba7861004dd3714265b4db54a3c390e880ab658fec5f7db895fae2046b5bb6" dependencies = [ "displaydoc", "litemap", @@ -1361,11 +1323,10 @@ dependencies = [ [[package]] name = "icu_normalizer" -version = "2.0.0" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "436880e8e18df4d7bbc06d58432329d6458cc84531f7ac5f024e93deadb37979" +checksum = "5f6c8828b67bf8908d82127b2054ea1b4427ff0230ee9141c54251934ab1b599" dependencies = [ - "displaydoc", "icu_collections", "icu_normalizer_data", "icu_properties", @@ -1376,42 +1337,38 @@ dependencies = [ [[package]] name = "icu_normalizer_data" -version = "2.0.0" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00210d6893afc98edb752b664b8890f0ef174c8adbb8d0be9710fa66fbbf72d3" +checksum = "7aedcccd01fc5fe81e6b489c15b247b8b0690feb23304303a9e560f37efc560a" [[package]] name = "icu_properties" -version = "2.0.1" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "016c619c1eeb94efb86809b015c58f479963de65bdb6253345c1a1276f22e32b" +checksum = "e93fcd3157766c0c8da2f8cff6ce651a31f0810eaa1c51ec363ef790bbb5fb99" dependencies = [ - "displaydoc", "icu_collections", "icu_locale_core", "icu_properties_data", "icu_provider", - "potential_utf", "zerotrie", "zerovec", ] [[package]] name = "icu_properties_data" -version = "2.0.1" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "298459143998310acd25ffe6810ed544932242d3f07083eee1084d83a71bd632" +checksum = "02845b3647bb045f1100ecd6480ff52f34c35f82d9880e029d329c21d1054899" [[package]] name = "icu_provider" -version = "2.0.0" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03c80da27b5f4187909049ee2d72f276f0d9f99a42c306bd0131ecfe04d8e5af" +checksum = "85962cf0ce02e1e0a629cc34e7ca3e373ce20dda4c4d7294bbd0bf1fdb59e614" dependencies = [ "displaydoc", "icu_locale_core", - "stable_deref_trait", - "tinystr", "writeable", "yoke", "zerofrom", @@ -1442,12 +1399,12 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.12.0" +version = "2.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6717a8d2a5a929a1a2eb43a12812498ed141a0bcfb7e8f7844fbdbe4303bba9f" +checksum = "0ad4bb2b565bca0645f4d68c5c9af97fba094e9791da685bf83cb5f3ce74acf2" dependencies = [ "equivalent", - "hashbrown 0.16.0", + "hashbrown 0.16.1", ] [[package]] @@ -1469,9 +1426,9 @@ checksum = "469fb0b9cefa57e3ef31275ee7cacb78f2fdca44e4765491884a2b119d4eb130" [[package]] name = "iri-string" -version = "0.7.8" +version = "0.7.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbc5ebe9c3a1a7a5127f920a418f7585e9e758e911d0466ed004f393b0e380b2" +checksum = "4f867b9d1d896b67beb18518eda36fdb77a32ea590de864f1325b294a6d14397" dependencies = [ "memchr", "serde", @@ -1483,15 +1440,6 @@ version = "1.70.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a6cb138bb79a146c1bd460005623e142ef0181e3d0219cb493e02f7d08a35695" -[[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" @@ -1500,26 +1448,26 @@ checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" [[package]] name = "jiff" -version = "0.2.15" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be1f93b8b1eb69c77f24bbb0afdf66f54b632ee39af40ca21c4365a1d7347e49" +checksum = "49cce2b81f2098e7e3efc35bc2e0a6b7abec9d34128283d7a26fa8f32a6dbb35" dependencies = [ "jiff-static", "log", "portable-atomic", "portable-atomic-util", - "serde", + "serde_core", ] [[package]] name = "jiff-static" -version = "0.2.15" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03343451ff899767262ec32146f6d559dd759fdadf42ff0e227c7c48f72594b4" +checksum = "980af8b43c3ad5d8d349ace167ec8170839f753a42d233ba19e08afe1850fa69" dependencies = [ "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.111", ] [[package]] @@ -1534,9 +1482,9 @@ dependencies = [ [[package]] name = "js-sys" -version = "0.3.81" +version = "0.3.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec48937a97411dcb524a265206ccd4c90bb711fca92b2792c407f268825b9305" +checksum = "464a3709c7f55f1f721e5389aa6ea4e3bc6aba669353300af094b29ffbdde1d8" dependencies = [ "once_cell", "wasm-bindgen", @@ -1562,9 +1510,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.177" +version = "0.2.178" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2874a2af47a2325c2001a6e6fad9b16a53b802102b528163885171cf92b15976" +checksum = "37c93d8daa9d8a012fd8ab92f088405fb202ea0b6ab73ee2482ae66af4f42091" [[package]] name = "libipld" @@ -1655,16 +1603,6 @@ dependencies = [ "thiserror 1.0.69", ] -[[package]] -name = "libloading" -version = "0.8.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7c4b02199fee7c5d21a5ae7d8cfa79a6ef5bb2fc834d6e9058e89c825efdc55" -dependencies = [ - "cfg-if", - "windows-link 0.2.1", -] - [[package]] name = "libsqlite3-sys" version = "0.31.0" @@ -1684,9 +1622,9 @@ checksum = "df1d3c3b53da64cf5760482273a98e575c651a67eec7f77df96b5b642de8f039" [[package]] name = "litemap" -version = "0.8.0" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "241eaef5fd12c88705a01fc1066c48c4b36e0dd4377dcdc7ec3942cea7a69956" +checksum = "6373607a59f0be73a39b6fe456b8192fcc3585f602af20751600e974dd455e77" [[package]] name = "lock_api" @@ -1699,9 +1637,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.28" +version = "0.4.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34080505efa8e45a4b816c349525ebe327ceaa8559756f0356cba97ef3bf7432" +checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897" [[package]] name = "lru" @@ -1731,9 +1669,9 @@ checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273" [[package]] name = "metrics" -version = "0.24.2" +version = "0.24.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25dea7ac8057892855ec285c440160265225438c3c45072613c25a4b26e98ef5" +checksum = "5d5312e9ba3771cfa961b585728215e3d972c950a3eed9252aa093d6301277e8" dependencies = [ "ahash", "portable-atomic", @@ -1792,12 +1730,6 @@ dependencies = [ "unicase", ] -[[package]] -name = "minimal-lexical" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" - [[package]] name = "miniz_oxide" version = "0.8.9" @@ -1810,9 +1742,9 @@ dependencies = [ [[package]] name = "mio" -version = "1.1.0" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69d83b0086dc8ecf3ce9ae2874b2d1290252e2a30720bea58a5c6639b0092873" +checksum = "a69bcab0ad47271a0234d9422b131806bf3968021e5dc9328caf2d4cd58557fc" dependencies = [ "libc", "wasi", @@ -1931,16 +1863,6 @@ dependencies = [ "tempfile", ] -[[package]] -name = "nom" -version = "7.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" -dependencies = [ - "memchr", - "minimal-lexical", -] - [[package]] name = "num-traits" version = "0.2.19" @@ -1973,9 +1895,9 @@ checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe" [[package]] name = "openssl" -version = "0.10.74" +version = "0.10.75" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24ad14dd45412269e1a30f52ad8f0664f0f4f4a89ee8fe28c3b3527021ebb654" +checksum = "08838db121398ad17ab8531ce9de97b244589089e290a384c900cb9ff7434328" dependencies = [ "bitflags", "cfg-if", @@ -1994,7 +1916,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.111", ] [[package]] @@ -2005,9 +1927,9 @@ checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e" [[package]] name = "openssl-sys" -version = "0.9.110" +version = "0.9.111" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a9f0075ba3c21b09f8e8b2026584b1d18d49388648f2fbbf3c97ea8deced8e2" +checksum = "82cab2d520aa75e3c58898289429321eb788c3106963d0dc886ec7a5f4adc321" dependencies = [ "cc", "libc", @@ -2041,7 +1963,7 @@ dependencies = [ "libc", "redox_syscall", "smallvec", - "windows-link 0.2.1", + "windows-link", ] [[package]] @@ -2085,7 +2007,7 @@ checksum = "6e918e4ff8c4549eb882f14b3a4bc8c8bc93de829416eacf579f1207a8fbf861" dependencies = [ "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.111", ] [[package]] @@ -2123,9 +2045,9 @@ dependencies = [ [[package]] name = "potential_utf" -version = "0.1.3" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84df19adbe5b5a0782edcab45899906947ab039ccf4573713735ee7de1e6b08a" +checksum = "b73949432f5e2a09657003c25bca5e19a0e9c84f8058ca374f49e0ebe605af77" dependencies = [ "zerovec", ] @@ -2139,16 +2061,6 @@ dependencies = [ "zerocopy", ] -[[package]] -name = "prettyplease" -version = "0.2.37" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b" -dependencies = [ - "proc-macro2", - "syn 2.0.108", -] - [[package]] name = "proc-macro-crate" version = "1.1.3" @@ -2218,9 +2130,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.41" +version = "1.0.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce25767e7b499d1b604768e7cde645d14cc8584231ea6b295e9c9eb22c02e1d1" +checksum = "a338cc41d27e6cc6dce6cefc13a0729dfbb81c262b1f519331575dd80ef3067f" dependencies = [ "proc-macro2", ] @@ -2278,6 +2190,26 @@ dependencies = [ "bitflags", ] +[[package]] +name = "rayon" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "368f01d005bf8fd9b1206fb6fa653e6c4a81ceb1466406b81792d87c5677a58f" +dependencies = [ + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22e18b0f0062d30d4230b2e85ff77fdfe4326feb054b9783a3460d8435c8ab91" +dependencies = [ + "crossbeam-deque", + "crossbeam-utils", +] + [[package]] name = "redox_syscall" version = "0.5.18" @@ -2411,12 +2343,6 @@ version = "0.1.26" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "56f7d92ca342cea22a06f2121d944b4fd82af56988c270852495420f961d4ace" -[[package]] -name = "rustc-hash" -version = "2.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d" - [[package]] name = "rustc_version" version = "0.4.1" @@ -2468,18 +2394,18 @@ dependencies = [ [[package]] name = "rustls-pki-types" -version = "1.12.0" +version = "1.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "229a4a4c221013e7e1f1a043678c5cc39fe5171437c88fb47151a21e6f5b5c79" +checksum = "708c0f9d5f54ba0272468c1d306a52c495b31fa155e91bc25371e6df7996908c" dependencies = [ "zeroize", ] [[package]] name = "rustls-webpki" -version = "0.103.7" +version = "0.103.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e10b3f4191e8a80e6b43eebabfac91e5dcecebb27a71f04e820c47ec41d314bf" +checksum = "2ffdfa2f5286e2247234e03f680868ac2815974dc39e00ea15adc445d0aafe52" dependencies = [ "aws-lc-rs", "ring", @@ -2599,7 +2525,7 @@ checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" dependencies = [ "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.111", ] [[package]] @@ -2692,9 +2618,9 @@ checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" [[package]] name = "signal-hook-registry" -version = "1.4.6" +version = "1.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2a4719bff48cee6b39d12c020eeb490953ad2443b7055bd0b21fca26bd8c28b" +checksum = "7664a098b8e616bdfcc2dc0e9ac44eb231eedf41db4e9fe95d8d32ec728dedad" dependencies = [ "libc", ] @@ -2790,6 +2716,7 @@ dependencies = [ "log", "metrics", "metrics-exporter-prometheus", + "rayon", "regex", "rusqlite", "skyfeed", @@ -2828,9 +2755,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.108" +version = "2.0.111" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da58917d35242480a05c2897064da0a80589a2a0476c9a3f2fdc83b53502e917" +checksum = "390cc9a294ab71bdb1aa2e99d13be9c753cd2d7bd6560c77118597410c4d2e87" dependencies = [ "proc-macro2", "quote", @@ -2866,7 +2793,7 @@ checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" dependencies = [ "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.111", ] [[package]] @@ -2935,7 +2862,7 @@ checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.111", ] [[package]] @@ -2946,14 +2873,14 @@ checksum = "3ff15c8ecd7de3849db632e14d18d2571fa09dfc5ed93479bc4485c7a517c913" dependencies = [ "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.111", ] [[package]] name = "tinystr" -version = "0.8.1" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d4f6d1145dcb577acf783d4e601bc1d76a13337bb54e6233add580b07344c8b" +checksum = "42d3e9c45c09de15d06dd8acf5f4e0e399e85927b7f00711024eb7ae10fa4869" dependencies = [ "displaydoc", "zerovec", @@ -2984,7 +2911,7 @@ checksum = "af407857209536a95c8e56f8231ef2c2e2aff839b22e07a1ffcbc617e9db9fa5" dependencies = [ "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.111", ] [[package]] @@ -3025,9 +2952,9 @@ dependencies = [ [[package]] name = "tokio-util" -version = "0.7.16" +version = "0.7.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14307c986784f72ef81c89db7d9e28d6ac26d16213b109ea501696195e6e3ce5" +checksum = "2efa149fe76073d6e8fd97ef4f4eca7b67f599660115591483572e406e165594" dependencies = [ "bytes", "futures-core", @@ -3063,9 +2990,9 @@ dependencies = [ [[package]] name = "tower-http" -version = "0.6.6" +version = "0.6.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "adc82fd73de2a9722ac5da747f12383d2bfdb93591ee6c58486e0097890f05f2" +checksum = "9cf146f99d442e8e68e585f5d798ccd3cad9a7835b917e09728880a862706456" dependencies = [ "bitflags", "bytes", @@ -3093,9 +3020,9 @@ checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" [[package]] name = "tracing" -version = "0.1.41" +version = "0.1.43" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0" +checksum = "2d15d90a0b5c19378952d479dc858407149d7bb45a14de0142f6c534b16fc647" dependencies = [ "log", "pin-project-lite", @@ -3104,9 +3031,9 @@ dependencies = [ [[package]] name = "tracing-core" -version = "0.1.34" +version = "0.1.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9d12581f227e93f094d3af2ae690a574abb8a2b9b7a96e7cfe9647b2b617678" +checksum = "7a04e24fab5c89c6a36eb8558c9656f30d81de51dfa4d3b45f26b21d61fa0a6c" dependencies = [ "once_cell", ] @@ -3119,7 +3046,7 @@ checksum = "70977707304198400eb4835a78f6a9f928bf41bba420deb8fdb175cd965d77a7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.111", ] [[package]] @@ -3161,9 +3088,9 @@ checksum = "75b844d17643ee918803943289730bec8aac480150456169e647ed0b576ba539" [[package]] name = "unicode-ident" -version = "1.0.20" +version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "462eeb75aeb73aea900253ce739c8e18a67423fadf006037cd3ff27e82748a06" +checksum = "9312f7c4f6ff9069b165498234ce8be658059c6728633667c526e27dc2cf1df5" [[package]] name = "unicode-xid" @@ -3231,9 +3158,9 @@ checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" [[package]] name = "uuid" -version = "1.18.1" +version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f87b8aa10b915a06587d0dec516c282ff295b475d94abf425d62b57710070a2" +checksum = "e2e054861b4bd027cd373e18e8d8d8e6548085000e41290d95ce0c373a654b4a" dependencies = [ "getrandom 0.3.4", "js-sys", @@ -3307,9 +3234,9 @@ dependencies = [ [[package]] name = "wasm-bindgen" -version = "0.2.104" +version = "0.2.106" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1da10c01ae9f1ae40cbfac0bac3b1e724b320abfcf52229f80b547c0d250e2d" +checksum = "0d759f433fa64a2d763d1340820e46e111a7a5ab75f993d1852d70b03dbb80fd" dependencies = [ "cfg-if", "once_cell", @@ -3318,25 +3245,11 @@ dependencies = [ "wasm-bindgen-shared", ] -[[package]] -name = "wasm-bindgen-backend" -version = "0.2.104" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "671c9a5a66f49d8a47345ab942e2cb93c7d1d0339065d4f8139c486121b43b19" -dependencies = [ - "bumpalo", - "log", - "proc-macro2", - "quote", - "syn 2.0.108", - "wasm-bindgen-shared", -] - [[package]] name = "wasm-bindgen-futures" -version = "0.4.54" +version = "0.4.56" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e038d41e478cc73bae0ff9b36c60cff1c98b8f38f8d7e8061e79ee63608ac5c" +checksum = "836d9622d604feee9e5de25ac10e3ea5f2d65b41eac0d9ce72eb5deae707ce7c" dependencies = [ "cfg-if", "js-sys", @@ -3347,9 +3260,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.104" +version = "0.2.106" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ca60477e4c59f5f2986c50191cd972e3a50d8a95603bc9434501cf156a9a119" +checksum = "48cb0d2638f8baedbc542ed444afc0644a29166f1595371af4fecf8ce1e7eeb3" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -3357,31 +3270,31 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.104" +version = "0.2.106" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f07d2f20d4da7b26400c9f4a0511e6e0345b040694e8a75bd41d578fa4421d7" +checksum = "cefb59d5cd5f92d9dcf80e4683949f15ca4b511f4ac0a6e14d4e1ac60c6ecd40" dependencies = [ + "bumpalo", "proc-macro2", "quote", - "syn 2.0.108", - "wasm-bindgen-backend", + "syn 2.0.111", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.104" +version = "0.2.106" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bad67dc8b2a1a6e5448428adec4c3e84c43e561d8c9ee8a9e5aabeb193ec41d1" +checksum = "cbc538057e648b67f72a982e708d485b2efa771e1ac05fec311f9f63e5800db4" dependencies = [ "unicode-ident", ] [[package]] name = "web-sys" -version = "0.3.81" +version = "0.3.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9367c417a924a74cae129e6a2ae3b47fabb1f8995595ab474029da749a8be120" +checksum = "9b32828d774c412041098d182a8b38b16ea816958e07cf40eec2bc080ae137ac" dependencies = [ "js-sys", "wasm-bindgen", @@ -3437,9 +3350,9 @@ checksum = "b8e83a14d34d0623b51dce9581199302a221863196a1dde71a7663a4c2be9deb" dependencies = [ "windows-implement", "windows-interface", - "windows-link 0.2.1", - "windows-result 0.4.1", - "windows-strings 0.5.1", + "windows-link", + "windows-result", + "windows-strings", ] [[package]] @@ -3450,7 +3363,7 @@ checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf" dependencies = [ "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.111", ] [[package]] @@ -3461,15 +3374,9 @@ checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358" dependencies = [ "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.111", ] -[[package]] -name = "windows-link" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a" - [[package]] name = "windows-link" version = "0.2.1" @@ -3478,22 +3385,13 @@ checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" [[package]] name = "windows-registry" -version = "0.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b8a9ed28765efc97bbc954883f4e6796c33a06546ebafacbabee9696967499e" -dependencies = [ - "windows-link 0.1.3", - "windows-result 0.3.4", - "windows-strings 0.4.2", -] - -[[package]] -name = "windows-result" -version = "0.3.4" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56f42bd332cc6c8eac5af113fc0c1fd6a8fd2aa08a0119358686e5160d0586c6" +checksum = "02752bf7fbdcce7f2a27a742f798510f3e5ad88dbe84871e5168e2120c3d5720" dependencies = [ - "windows-link 0.1.3", + "windows-link", + "windows-result", + "windows-strings", ] [[package]] @@ -3502,16 +3400,7 @@ version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7781fa89eaf60850ac3d2da7af8e5242a5ea78d1a11c49bf2910bb5a73853eb5" dependencies = [ - "windows-link 0.2.1", -] - -[[package]] -name = "windows-strings" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56e6c93f3a0c3b36176cb1327a4958a0353d5d166c2a35cb268ace15e91d3b57" -dependencies = [ - "windows-link 0.1.3", + "windows-link", ] [[package]] @@ -3520,7 +3409,7 @@ version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7837d08f69c77cf6b07689544538e017c1bfcf57e34b4c0ff58e6c2cd3b37091" dependencies = [ - "windows-link 0.2.1", + "windows-link", ] [[package]] @@ -3547,7 +3436,7 @@ version = "0.61.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" dependencies = [ - "windows-link 0.2.1", + "windows-link", ] [[package]] @@ -3572,7 +3461,7 @@ version = "0.53.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4945f9f551b88e0d65f3db0bc25c33b8acea4d9e41163edf90dcd0b19f9069f3" dependencies = [ - "windows-link 0.2.1", + "windows-link", "windows_aarch64_gnullvm 0.53.1", "windows_aarch64_msvc 0.53.1", "windows_i686_gnu 0.53.1", @@ -3687,17 +3576,16 @@ checksum = "f17a85883d4e6d00e8a97c586de764dabcc06133f7f1d55dce5cdc070ad7fe59" [[package]] name = "writeable" -version = "0.6.1" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea2f10b9bb0928dfb1b42b65e1f9e36f7f54dbdf08457afefb38afcdec4fa2bb" +checksum = "9edde0db4769d2dc68579893f2306b26c6ecfbe0ef499b013d731b7b9247e0b9" [[package]] name = "yoke" -version = "0.8.0" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f41bb01b8226ef4bfd589436a297c53d118f65921786300e427be8d487695cc" +checksum = "72d6e5c6afb84d73944e5cedb052c4680d5657337201555f9f2a16b7406d4954" dependencies = [ - "serde", "stable_deref_trait", "yoke-derive", "zerofrom", @@ -3705,34 +3593,34 @@ dependencies = [ [[package]] name = "yoke-derive" -version = "0.8.0" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38da3c9736e16c5d3c8c597a9aaa5d1fa565d0532ae05e27c24aa62fb32c0ab6" +checksum = "b659052874eb698efe5b9e8cf382204678a0086ebf46982b79d6ca3182927e5d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.111", "synstructure 0.13.2", ] [[package]] name = "zerocopy" -version = "0.8.27" +version = "0.8.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0894878a5fa3edfd6da3f88c4805f4c8558e2b996227a3d864f47fe11e38282c" +checksum = "fd74ec98b9250adb3ca554bdde269adf631549f51d8a8f8f0a10b50f1cb298c3" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.8.27" +version = "0.8.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88d2b8d9c68ad2b9e4340d7832716a4d21a22a1154777ad56ea55c51a9cf3831" +checksum = "d8a8d209fdf45cf5138cbb5a506f6b52522a25afccc534d1475dad8e31105c6a" dependencies = [ "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.111", ] [[package]] @@ -3752,7 +3640,7 @@ checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502" dependencies = [ "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.111", "synstructure 0.13.2", ] @@ -3764,9 +3652,9 @@ checksum = "b97154e67e32c85465826e8bcc1c59429aaaf107c1e4a9e53c8d8ccd5eff88d0" [[package]] name = "zerotrie" -version = "0.2.2" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36f0bbd478583f79edad978b407914f61b2972f5af6fa089686016be8f9af595" +checksum = "2a59c17a5562d507e4b54960e8569ebee33bee890c70aa3fe7b97e85a9fd7851" dependencies = [ "displaydoc", "yoke", @@ -3775,9 +3663,9 @@ dependencies = [ [[package]] name = "zerovec" -version = "0.11.4" +version = "0.11.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7aa2bd55086f1ab526693ecbe444205da57e25f4489879da80635a46d90e73b" +checksum = "6c28719294829477f525be0186d13efa9a3c602f7ec202ca9e353d310fb9a002" dependencies = [ "yoke", "zerofrom", @@ -3786,11 +3674,11 @@ dependencies = [ [[package]] name = "zerovec-derive" -version = "0.11.1" +version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b96237efa0c878c64bd89c436f661be4e46b2f3eff1ebb976f7ef2321d2f58f" +checksum = "eadce39539ca5cb3985590102671f2567e659fca9666581ad3411d59207951f3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.111", ] diff --git a/examples/sqlite/Cargo.toml b/examples/sqlite/Cargo.toml index cea3a32..d92b17d 100644 --- a/examples/sqlite/Cargo.toml +++ b/examples/sqlite/Cargo.toml @@ -21,6 +21,7 @@ whatlang = "0.16.4" metrics = "0.24.1" metrics-exporter-prometheus = "0.16.2" dotenv = "0.15.0" +rayon = "1.10" [profile.release] lto = true diff --git a/examples/sqlite/src/main.rs b/examples/sqlite/src/main.rs index b5f7fe8..b0448a5 100644 --- a/examples/sqlite/src/main.rs +++ b/examples/sqlite/src/main.rs @@ -1,8 +1,7 @@ -#![allow(clippy::type_complexity)] - // use dotenv::dotenv; use chrono_tz::America::Denver; use log::{error, info, trace}; +use rayon::prelude::*; use regex::Regex; use rusqlite::{Connection, params}; use skyfeed::{Config, FeedHandler, FeedRequest, FeedResult, Post, Uri}; @@ -12,6 +11,21 @@ use tokio::sync::Mutex; const FR_FEED: &str = "fr"; const MY_FEED: &str = "cyys-feed"; +#[derive(Clone)] +struct PendingPost { + uri: String, + text: String, + timestamp: i64, + langs: Vec, + labels: Vec, +} + +#[derive(Clone)] +struct PendingLike { + post_uri: String, + like_uri: String, +} + #[tokio::main] async fn main() { // dotenv().expect("No .env"); @@ -34,16 +48,25 @@ async fn main() { pending_likes: Vec::new(), })); - let handler_clone = handler.clone(); - let mut flush_interval = tokio::time::interval(Duration::from_secs(10)); + let handler_flush = handler.clone(); + let mut flush_interval = tokio::time::interval(Duration::from_secs(1)); let flush_task = tokio::spawn(async move { loop { flush_interval.tick().await; - let mut handler = handler_clone.lock().await; + let mut handler = handler_flush.lock().await; handler.flush_posts().await; handler.flush_likes().await; + } + }); + + let handler_cleanup = handler.clone(); + let mut cleanup_interval = tokio::time::interval(Duration::from_secs(30)); + let cleanup_task = tokio::spawn(async move { + loop { + cleanup_interval.tick().await; + let mut handler = handler_cleanup.lock().await; handler.cleanup_posts(FR_FEED, 10_000).await; - handler.cleanup_posts(MY_FEED, 200_000).await; + handler.cleanup_posts(MY_FEED, 100_000).await; } }); @@ -58,7 +81,8 @@ async fn main() { tokio::join!( skyfeed::start(config, handler, ([0, 0, 0, 0], 3030)), - flush_task + flush_task, + cleanup_task, ) .1 .expect("Starting tasks failed"); @@ -68,8 +92,8 @@ struct MyFeedHandler { fr_regex: Regex, my_regex: Regex, db: Mutex, - pending_posts: Vec<(String, String, i64, String)>, - pending_likes: Vec<(String, String)>, + pending_posts: Vec, + pending_likes: Vec, } impl MyFeedHandler { @@ -78,27 +102,54 @@ impl MyFeedHandler { return; } - let posts_to_insert: Vec<_> = self.pending_posts.drain(..).collect(); - let count = posts_to_insert.len(); + let posts_to_filter: Vec<_> = self.pending_posts.drain(..).collect(); + let total = posts_to_filter.len(); + + let fr_regex = &self.fr_regex; + let my_regex = &self.my_regex; + + // Parallelize filtering with regex, it can be a bottleneck + let filtered: Vec<(String, String, i64, String)> = posts_to_filter + .into_par_iter() + .filter_map(|post| { + let detected_language = whatlang::detect_lang(&post.text); + + if post.langs.iter().any(|lang| lang.contains("fr")) + && detected_language == Some(whatlang::Lang::Fra) + && !fr_regex.is_match(&post.text) + && post.labels.is_empty() + { + Some((post.uri, post.text, post.timestamp, FR_FEED.to_string())) + } else if post.langs.iter().any(|lang| lang.contains("en")) + && detected_language == Some(whatlang::Lang::Eng) + && !my_regex.is_match(&post.text) + { + Some((post.uri, post.text, post.timestamp, MY_FEED.to_string())) + } else { + None + } + }) + .collect(); + let count = filtered.len(); let mut db = self.db.lock().await; let tx = db.transaction().expect("Failed to start transaction"); { let mut stmt = tx - .prepare( - "INSERT OR REPLACE INTO posts (uri, text, timestamp, feed) VALUES (?1, ?2, ?3, ?4)", - ) - .expect("Failed to prepare statement"); + .prepare( + "INSERT OR REPLACE INTO posts (uri, text, timestamp, feed) VALUES (?1, ?2, ?3, ?4)", + ) + .expect("Failed to prepare statement"); - for (uri, text, timestamp, feed) in posts_to_insert { + for (uri, text, timestamp, feed) in filtered { stmt.execute(params![uri, text, timestamp, feed]) .expect("Failed to insert post"); } } tx.commit().expect("Failed to commit transaction"); - trace!("Successfully flushed {} posts", count); + trace!("Filtered {} posts, inserted {} to db", total, count); } async fn flush_likes(&mut self) { @@ -114,11 +165,11 @@ impl MyFeedHandler { { let mut stmt = tx.prepare( - "INSERT OR REPLACE INTO likes (post_uri, like_uri) SELECT ?1, ?2 WHERE EXISTS (SELECT 1 FROM posts WHERE uri = ?1)" - ).expect("Failed to prepare statement"); + "INSERT OR REPLACE INTO likes (post_uri, like_uri) SELECT ?1, ?2 WHERE EXISTS (SELECT 1 FROM posts WHERE uri = ?1)" + ).expect("Failed to prepare statement"); - for (post_uri, like_uri) in likes_to_insert { - stmt.execute(params![post_uri, like_uri]) + for like in likes_to_insert { + stmt.execute(params![like.post_uri, like.like_uri]) .expect("Failed to insert like"); } } @@ -191,31 +242,13 @@ impl FeedHandler for MyFeedHandler { } async fn insert_post(&mut self, post: Post) { - let detected_language = whatlang::detect_lang(&post.text); - let timestamp = post.timestamp.timestamp(); - let feed_to_insert = if post.langs.iter().any(|lang| lang.contains("fr")) - && detected_language == Some(whatlang::Lang::Fra) - && !self.fr_regex.is_match(post.text.as_str()) - && post.labels.is_empty() - { - Some(FR_FEED) - } else if post.langs.iter().any(|lang| lang.contains("en")) - && detected_language == Some(whatlang::Lang::Eng) - && !self.my_regex.is_match(post.text.as_str()) - { - Some(MY_FEED) - } else { - None - }; - - if let Some(feed) = feed_to_insert { - self.pending_posts.push(( - post.uri.0.clone(), - post.text.clone(), - timestamp, - feed.to_string(), - )); - } + self.pending_posts.push(PendingPost { + uri: post.uri.0.clone(), + text: post.text.clone(), + timestamp: post.timestamp.timestamp(), + langs: post.langs.clone(), + labels: post.labels.iter().map(|l| format!("{:?}", l)).collect(), + }); } async fn delete_post(&mut self, uri: Uri) { @@ -228,8 +261,10 @@ impl FeedHandler for MyFeedHandler { } async fn insert_like(&mut self, like_uri: Uri, liked_post_uri: Uri) { - self.pending_likes - .push((liked_post_uri.0.clone(), like_uri.0.clone())); + self.pending_likes.push(PendingLike { + post_uri: liked_post_uri.0.clone(), + like_uri: like_uri.0.clone(), + }); } async fn delete_like(&mut self, like_uri: Uri) { @@ -270,6 +305,9 @@ impl FeedHandler for MyFeedHandler { } let db = self.db.lock().await; + // Paginates through top 100 posts every hour + // Posts that are <5 minutes old are excluded to give time for moderation + // Cursor is in the format "hour:offset" where hour is the number of hours back we will query, and offset is the number of posts from that hour that this client has already seen let mut stmt = db .prepare( " @@ -281,7 +319,7 @@ impl FeedHandler for MyFeedHandler { COUNT(likes.like_uri) AS likes FROM posts LEFT JOIN likes ON posts.uri = likes.post_uri - WHERE posts.feed = ?2 + WHERE posts.feed = ?2 AND posts.timestamp >= (strftime('%s', 'now') - ((?1 + 1) * 3600)) AND posts.timestamp < (strftime('%s', 'now') - (?1 * 3600)) AND posts.timestamp < (strftime('%s', 'now') - 300) diff --git a/src/feed.rs b/src/feed.rs index 39fcfc1..c34e4a7 100644 --- a/src/feed.rs +++ b/src/feed.rs @@ -113,7 +113,7 @@ pub async fn start( while let Ok(event) = rx.recv_async().await { warning_log_counter += 1; let waiting_updates = rx.len(); - if waiting_updates >= 2000 && warning_log_counter >= 5 { + if waiting_updates >= 2000 && warning_log_counter >= 20 { warning_log_counter = 0; warn!( "{waiting_updates} updates are awaiting processing, your feed handler implementation may not be processing updates quickly enough. This will result in continuously increasing memory usage if it continues!" From c44fdd2eeb9e4c6bc501810052521327b197eb98 Mon Sep 17 00:00:00 2001 From: cyypherus Date: Sat, 6 Dec 2025 18:18:28 -0700 Subject: [PATCH 42/53] reduce usage of stuff --- examples/sqlite/Cargo.lock | 4 +++- examples/sqlite/Cargo.toml | 2 +- examples/sqlite/src/main.rs | 8 +++++--- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/examples/sqlite/Cargo.lock b/examples/sqlite/Cargo.lock index 2e4069b..4670e00 100644 --- a/examples/sqlite/Cargo.lock +++ b/examples/sqlite/Cargo.lock @@ -2646,7 +2646,7 @@ checksum = "c1e9a774a6c28142ac54bb25d25562e6bcf957493a184f15ad4eebccb23e410a" [[package]] name = "skyfeed" version = "0.6.0" -source = "git+https://github.com/cyypherus/skyfeed.git?rev=93899a464bc4c3a24a54c2e1e98ddd9ca0503662#93899a464bc4c3a24a54c2e1e98ddd9ca0503662" +source = "git+https://github.com/cyypherus/skyfeed.git?rev=0ffcfebb9290096915d3d2eb9566c9fc28662bcf#0ffcfebb9290096915d3d2eb9566c9fc28662bcf" dependencies = [ "anyhow", "async-trait", @@ -2654,6 +2654,7 @@ dependencies = [ "atrium-repo", "atrium-xrpc-client", "chrono", + "chrono-tz", "clap", "dotenv", "env_logger", @@ -2661,6 +2662,7 @@ dependencies = [ "futures", "ipld-core", "log", + "rayon", "regex", "reqwest", "rs-car", diff --git a/examples/sqlite/Cargo.toml b/examples/sqlite/Cargo.toml index d92b17d..3e9a640 100644 --- a/examples/sqlite/Cargo.toml +++ b/examples/sqlite/Cargo.toml @@ -10,7 +10,7 @@ local = [] [dependencies] log = "0.4.25" -skyfeed = { git = "https://github.com/cyypherus/skyfeed.git", rev = "93899a464bc4c3a24a54c2e1e98ddd9ca0503662" } +skyfeed = { git = "https://github.com/cyypherus/skyfeed.git", rev = "0ffcfebb9290096915d3d2eb9566c9fc28662bcf" } # skyfeed = { path = "../.." } tokio = { version = "1.43.0", features = ["full", "time"] } rusqlite = { version = "0.33.0", features = ["bundled"] } diff --git a/examples/sqlite/src/main.rs b/examples/sqlite/src/main.rs index b0448a5..fc5ac9b 100644 --- a/examples/sqlite/src/main.rs +++ b/examples/sqlite/src/main.rs @@ -65,8 +65,8 @@ async fn main() { loop { cleanup_interval.tick().await; let mut handler = handler_cleanup.lock().await; - handler.cleanup_posts(FR_FEED, 10_000).await; - handler.cleanup_posts(MY_FEED, 100_000).await; + handler.cleanup_posts(FR_FEED, 5_000).await; + handler.cleanup_posts(MY_FEED, 80_000).await; } }); @@ -193,7 +193,9 @@ impl MyFeedHandler { .map(|dt| dt.with_timezone(&Denver).to_rfc3339()) }); - let cutoff_time = chrono::Utc::now().timestamp() - 5400; + // 3600 seconds = 60 minutes. Delete posts older than 60 minutes that have no likes. + // This gives liked posts more time to accumulate engagement before cleanup. + let cutoff_time = chrono::Utc::now().timestamp() - 3600; let zero_likes_cleaned = db .execute( "DELETE FROM posts From 01044c9521a7a1e8eb1aabbaf26d0a03ca9a7dc8 Mon Sep 17 00:00:00 2001 From: cyypherus Date: Sun, 7 Dec 2025 14:18:23 -0700 Subject: [PATCH 43/53] engagement gate --- examples/sqlite/src/main.rs | 37 ++++++++++++++++++++++++++----------- 1 file changed, 26 insertions(+), 11 deletions(-) diff --git a/examples/sqlite/src/main.rs b/examples/sqlite/src/main.rs index fc5ac9b..0051b0c 100644 --- a/examples/sqlite/src/main.rs +++ b/examples/sqlite/src/main.rs @@ -49,7 +49,7 @@ async fn main() { })); let handler_flush = handler.clone(); - let mut flush_interval = tokio::time::interval(Duration::from_secs(1)); + let mut flush_interval = tokio::time::interval(Duration::from_secs(10)); let flush_task = tokio::spawn(async move { loop { flush_interval.tick().await; @@ -189,24 +189,39 @@ impl MyFeedHandler { .expect("Failed to get oldest post timestamp"); let oldest_date = oldest_timestamp.and_then(|ts| { - chrono::DateTime::::from_timestamp(ts, 0) - .map(|dt| dt.with_timezone(&Denver).to_rfc3339()) + chrono::DateTime::::from_timestamp(ts, 0).map(|dt| { + dt.with_timezone(&Denver) + .format("%b %d, %Y %l:%M %p") + .to_string() + }) }); - // 3600 seconds = 60 minutes. Delete posts older than 60 minutes that have no likes. - // This gives liked posts more time to accumulate engagement before cleanup. - let cutoff_time = chrono::Utc::now().timestamp() - 3600; - let zero_likes_cleaned = db + // Gate posts between 1-2 hours old: only keep the top 1000 by likes. + // This ensures older posts have proven engagement before being retained. + let now = chrono::Utc::now().timestamp(); + let one_hour_ago = now - 3600; + let two_hours_ago = now - 7200; + + let engagement_gated = db .execute( "DELETE FROM posts WHERE feed = ?1 + AND timestamp >= ?3 AND timestamp < ?2 AND uri NOT IN ( - SELECT DISTINCT post_uri FROM likes + SELECT posts.uri + FROM posts + LEFT JOIN likes ON posts.uri = likes.post_uri + WHERE posts.feed = ?1 + AND posts.timestamp >= ?3 + AND posts.timestamp < ?2 + GROUP BY posts.uri + ORDER BY COUNT(likes.like_uri) DESC + LIMIT 1000 );", - params![feed, cutoff_time], + params![feed, one_hour_ago, two_hours_ago], ) - .expect("Failed to clean up zero-like posts"); + .expect("Failed to apply engagement gate"); let cleaned_posts = db .execute( @@ -232,7 +247,7 @@ impl MyFeedHandler { .expect("Failed to count remaining posts"); info!( - "Cleaned up {cleaned_posts} posts on {feed} (plus {zero_likes_cleaned} zero-like posts). Oldest post available: {}. {remaining_posts} posts remain.", + "Cleaned up {cleaned_posts} posts on {feed} (engagement gated: {engagement_gated}). Oldest post available: {}. {remaining_posts} posts remain.", oldest_date.unwrap_or_else(|| "No posts".to_string()) ); } From 208d1ad828c4296569b44fd7b8799293c5b16695 Mon Sep 17 00:00:00 2001 From: cyypherus Date: Sun, 7 Dec 2025 17:41:23 -0700 Subject: [PATCH 44/53] modify limits --- examples/sqlite/src/main.rs | 91 +++++++++++++++++++++---------------- src/feed.rs | 2 +- 2 files changed, 53 insertions(+), 40 deletions(-) diff --git a/examples/sqlite/src/main.rs b/examples/sqlite/src/main.rs index 0051b0c..fbace85 100644 --- a/examples/sqlite/src/main.rs +++ b/examples/sqlite/src/main.rs @@ -43,7 +43,7 @@ async fn main() { my_regex: regex::RegexBuilder::new(my_feed_regex.as_str()) .build() .unwrap(), - db: Mutex::new(db), + db: Arc::new(Mutex::new(db)), pending_posts: Vec::new(), pending_likes: Vec::new(), })); @@ -66,7 +66,7 @@ async fn main() { cleanup_interval.tick().await; let mut handler = handler_cleanup.lock().await; handler.cleanup_posts(FR_FEED, 5_000).await; - handler.cleanup_posts(MY_FEED, 80_000).await; + handler.cleanup_posts(MY_FEED, 10_000).await; } }); @@ -91,7 +91,7 @@ async fn main() { struct MyFeedHandler { fr_regex: Regex, my_regex: Regex, - db: Mutex, + db: Arc>, pending_posts: Vec, pending_likes: Vec, } @@ -196,7 +196,7 @@ impl MyFeedHandler { }) }); - // Gate posts between 1-2 hours old: only keep the top 1000 by likes. + // Gate posts between 1-2 hours old: only keep the top 200 by likes. // This ensures older posts have proven engagement before being retained. let now = chrono::Utc::now().timestamp(); let one_hour_ago = now - 3600; @@ -205,20 +205,20 @@ impl MyFeedHandler { let engagement_gated = db .execute( "DELETE FROM posts - WHERE feed = ?1 - AND timestamp >= ?3 - AND timestamp < ?2 - AND uri NOT IN ( - SELECT posts.uri - FROM posts - LEFT JOIN likes ON posts.uri = likes.post_uri - WHERE posts.feed = ?1 - AND posts.timestamp >= ?3 - AND posts.timestamp < ?2 - GROUP BY posts.uri - ORDER BY COUNT(likes.like_uri) DESC - LIMIT 1000 - );", + WHERE feed = ?1 + AND timestamp >= ?3 + AND timestamp < ?2 + AND uri NOT IN ( + SELECT posts.uri + FROM posts + LEFT JOIN likes ON posts.uri = likes.post_uri + WHERE posts.feed = ?1 + AND posts.timestamp >= ?3 + AND posts.timestamp < ?2 + GROUP BY posts.uri + ORDER BY COUNT(likes.like_uri) DESC + LIMIT 200 + );", params![feed, one_hour_ago, two_hours_ago], ) .expect("Failed to apply engagement gate"); @@ -226,18 +226,27 @@ impl MyFeedHandler { let cleaned_posts = db .execute( "DELETE FROM posts - WHERE feed = ?1 - AND uri NOT IN ( - SELECT uri - FROM posts - WHERE feed = ?1 - ORDER BY timestamp DESC - LIMIT ?2 - );", + WHERE feed = ?1 + AND uri NOT IN ( + SELECT uri + FROM posts + WHERE feed = ?1 + ORDER BY timestamp DESC + LIMIT ?2 + );", params![feed, post_limit], ) .expect("Failed to clean up old posts"); + // Delete all posts older than 2 days (2 * 24 * 60 * 60 = 172800 seconds) + let two_days_ago = now - 172800; + let old_posts = db + .execute( + "DELETE FROM posts WHERE feed = ?1 AND timestamp < ?2", + params![feed, two_days_ago], + ) + .expect("Failed to delete old posts"); + let remaining_posts = db .query_row( "SELECT COUNT(*) FROM posts WHERE feed = ?1", @@ -247,7 +256,7 @@ impl MyFeedHandler { .expect("Failed to count remaining posts"); info!( - "Cleaned up {cleaned_posts} posts on {feed} (engagement gated: {engagement_gated}). Oldest post available: {}. {remaining_posts} posts remain.", + "Cleaned up {cleaned_posts} posts on {feed} (engagement gated: {engagement_gated}, old posts: {old_posts}). Oldest post available: {}. {remaining_posts} posts remain.", oldest_date.unwrap_or_else(|| "No posts".to_string()) ); } @@ -269,12 +278,14 @@ impl FeedHandler for MyFeedHandler { } async fn delete_post(&mut self, uri: Uri) { - let unpost_sql = "DELETE FROM posts WHERE uri = ?1"; - self.db - .lock() - .await - .execute(unpost_sql, params![uri.0]) - .expect("Failed to delete post"); + let db = Arc::clone(&self.db); + tokio::spawn(async move { + let unpost_sql = "DELETE FROM posts WHERE uri = ?1"; + db.lock() + .await + .execute(unpost_sql, params![uri.0]) + .expect("Failed to delete post"); + }); } async fn insert_like(&mut self, like_uri: Uri, liked_post_uri: Uri) { @@ -285,12 +296,14 @@ impl FeedHandler for MyFeedHandler { } async fn delete_like(&mut self, like_uri: Uri) { - let unlike_sql = "DELETE FROM likes WHERE like_uri = ?1"; - self.db - .lock() - .await - .execute(unlike_sql, params![like_uri.0]) - .expect("Failed to delete like"); + let db = Arc::clone(&self.db); + tokio::spawn(async move { + let unlike_sql = "DELETE FROM likes WHERE like_uri = ?1"; + db.lock() + .await + .execute(unlike_sql, params![like_uri.0]) + .expect("Failed to delete like"); + }); } async fn serve_feed(&self, request: FeedRequest) -> FeedResult { diff --git a/src/feed.rs b/src/feed.rs index c34e4a7..7748632 100644 --- a/src/feed.rs +++ b/src/feed.rs @@ -113,7 +113,7 @@ pub async fn start( while let Ok(event) = rx.recv_async().await { warning_log_counter += 1; let waiting_updates = rx.len(); - if waiting_updates >= 2000 && warning_log_counter >= 20 { + if waiting_updates >= 5000 && warning_log_counter >= 100 { warning_log_counter = 0; warn!( "{waiting_updates} updates are awaiting processing, your feed handler implementation may not be processing updates quickly enough. This will result in continuously increasing memory usage if it continues!" From 7eec21f9859fdaa16d20900cfa44fea5352930a3 Mon Sep 17 00:00:00 2001 From: cyypherus Date: Sun, 21 Dec 2025 11:39:23 -0800 Subject: [PATCH 45/53] add queue limit arg & update per minute counter --- examples/basic/src/main.rs | 8 +++++++- examples/sqlite/Cargo.lock | 2 +- examples/sqlite/Cargo.toml | 2 +- examples/sqlite/src/main.rs | 12 ++++++------ src/feed.rs | 12 ++++++------ src/firehose.rs | 31 +++++++++++++++++++++++++++++++ 6 files changed, 52 insertions(+), 15 deletions(-) diff --git a/examples/basic/src/main.rs b/examples/basic/src/main.rs index 9aec55c..b5dbde2 100644 --- a/examples/basic/src/main.rs +++ b/examples/basic/src/main.rs @@ -10,7 +10,13 @@ async fn main() { publisher_did: "did:web:example.com".to_string(), feed_generator_hostname: "example.com".to_string(), }; - start(config, Arc::new(Mutex::new(handler)), ([0, 0, 0, 0], 3030)).await + start( + config, + 5_000, + Arc::new(Mutex::new(handler)), + ([0, 0, 0, 0], 3030), + ) + .await } #[derive(Clone)] diff --git a/examples/sqlite/Cargo.lock b/examples/sqlite/Cargo.lock index 4670e00..28771fd 100644 --- a/examples/sqlite/Cargo.lock +++ b/examples/sqlite/Cargo.lock @@ -2646,7 +2646,7 @@ checksum = "c1e9a774a6c28142ac54bb25d25562e6bcf957493a184f15ad4eebccb23e410a" [[package]] name = "skyfeed" version = "0.6.0" -source = "git+https://github.com/cyypherus/skyfeed.git?rev=0ffcfebb9290096915d3d2eb9566c9fc28662bcf#0ffcfebb9290096915d3d2eb9566c9fc28662bcf" +source = "git+https://github.com/cyypherus/skyfeed.git?rev=208d1ad828c4296569b44fd7b8799293c5b16695#208d1ad828c4296569b44fd7b8799293c5b16695" dependencies = [ "anyhow", "async-trait", diff --git a/examples/sqlite/Cargo.toml b/examples/sqlite/Cargo.toml index 3e9a640..0c937bc 100644 --- a/examples/sqlite/Cargo.toml +++ b/examples/sqlite/Cargo.toml @@ -10,7 +10,7 @@ local = [] [dependencies] log = "0.4.25" -skyfeed = { git = "https://github.com/cyypherus/skyfeed.git", rev = "0ffcfebb9290096915d3d2eb9566c9fc28662bcf" } +skyfeed = { git = "https://github.com/cyypherus/skyfeed.git", rev = "208d1ad828c4296569b44fd7b8799293c5b16695" } # skyfeed = { path = "../.." } tokio = { version = "1.43.0", features = ["full", "time"] } rusqlite = { version = "0.33.0", features = ["bundled"] } diff --git a/examples/sqlite/src/main.rs b/examples/sqlite/src/main.rs index fbace85..acad93c 100644 --- a/examples/sqlite/src/main.rs +++ b/examples/sqlite/src/main.rs @@ -66,7 +66,7 @@ async fn main() { cleanup_interval.tick().await; let mut handler = handler_cleanup.lock().await; handler.cleanup_posts(FR_FEED, 5_000).await; - handler.cleanup_posts(MY_FEED, 10_000).await; + handler.cleanup_posts(MY_FEED, 60_000).await; } }); @@ -80,7 +80,7 @@ async fn main() { }; tokio::join!( - skyfeed::start(config, handler, ([0, 0, 0, 0], 3030)), + skyfeed::start(config, 5_000, handler, ([0, 0, 0, 0], 3030)), flush_task, cleanup_task, ) @@ -196,11 +196,11 @@ impl MyFeedHandler { }) }); - // Gate posts between 1-2 hours old: only keep the top 200 by likes. + // Gate posts between 0.5-1 hours old: only keep the top 100 by likes in that range. // This ensures older posts have proven engagement before being retained. let now = chrono::Utc::now().timestamp(); + let half_hour_ago = now - 1800; let one_hour_ago = now - 3600; - let two_hours_ago = now - 7200; let engagement_gated = db .execute( @@ -217,9 +217,9 @@ impl MyFeedHandler { AND posts.timestamp < ?2 GROUP BY posts.uri ORDER BY COUNT(likes.like_uri) DESC - LIMIT 200 + LIMIT 100 );", - params![feed, one_hour_ago, two_hours_ago], + params![feed, half_hour_ago, one_hour_ago], ) .expect("Failed to apply engagement gate"); diff --git a/src/feed.rs b/src/feed.rs index 7748632..ac28011 100644 --- a/src/feed.rs +++ b/src/feed.rs @@ -39,6 +39,7 @@ pub trait FeedHandler { /// Starts the feed generator server & connects to the firehose. /// /// - feed_handler: An object which handles firehose input & serve feeds. This object can implement multiple feeds. +/// - queue_limit: The maximum number of firehose updates to keep in memory at a time. If your handler does not process updates as quickly or more quickly than they are recieved updates will be stored in memory up to this limit, and then dropped if the queue is already at this limit. Updates can come it /// - config: Configuration values, see `Config` /// - address: The address to bind the server to /// @@ -47,6 +48,7 @@ pub trait FeedHandler { /// Panics if unable to bind to the provided address. pub async fn start( config: Config, + queue_limit: usize, feed_handler: Arc>, address: impl Into + Send + 'static, ) { @@ -109,15 +111,13 @@ pub async fn start( let feed_handler = feed_handler.clone(); let event_handler = tokio::spawn(async move { - let mut warning_log_counter = 0usize; while let Ok(event) = rx.recv_async().await { - warning_log_counter += 1; let waiting_updates = rx.len(); - if waiting_updates >= 5000 && warning_log_counter >= 100 { - warning_log_counter = 0; + if waiting_updates > queue_limit { warn!( - "{waiting_updates} updates are awaiting processing, your feed handler implementation may not be processing updates quickly enough. This will result in continuously increasing memory usage if it continues!" - ) + "{waiting_updates} updates are awaiting processing which is above the specified queue_limit. An update will be dropped to stay under the queue limit. Your feed handler may not be processing updates quickly enough." + ); + continue; } let mut feed_handler = feed_handler.lock().await; match event { diff --git a/src/firehose.rs b/src/firehose.rs index 52f4a89..e871a64 100644 --- a/src/firehose.rs +++ b/src/firehose.rs @@ -11,6 +11,9 @@ use atrium_api::types::CidLink; use crate::Cid; use crate::models::{Did, Embed, Label, Post, Uri}; use chrono::DateTime; +use std::sync::atomic::{AtomicU64, Ordering}; +use std::sync::Arc; +use std::time::{Duration, Instant}; mod frames { use ipld_core::ipld::Ipld; @@ -173,6 +176,32 @@ mod frames { use frames::Frame; +struct UpdatesCounter { + count: Arc, + last_log: Arc>, +} + +impl UpdatesCounter { + fn new() -> Self { + UpdatesCounter { + count: Arc::new(AtomicU64::new(0)), + last_log: Arc::new(tokio::sync::Mutex::new(Instant::now())), + } + } + + async fn increment_and_maybe_log(&self) { + self.count.fetch_add(1, Ordering::Relaxed); + let mut last_log = self.last_log.lock().await; + let elapsed = last_log.elapsed(); + if elapsed >= Duration::from_secs(1) { + let count = self.count.swap(0, Ordering::Relaxed); + let ups = count as f64 / elapsed.as_secs_f64(); + log::trace!("updates/sec: {:.2}", ups); + *last_log = Instant::now(); + } + } +} + #[derive(Debug)] pub enum FirehoseError { Frame(frames::FrameError), @@ -246,6 +275,7 @@ impl FirehoseConnector { frame_rx: flume::Receiver>, tx: flume::Sender, ) -> Result<(), FirehoseError> { + let counter = UpdatesCounter::new(); while let Ok(message) = frame_rx.recv_async().await { match message { Ok(Frame::Message(Some(t), message)) => { @@ -257,6 +287,7 @@ impl FirehoseConnector { if let Err(e) = Self::handle_commit(&commit, &tx).await { log::error!("Failed to handle commit: {}", e); } + counter.increment_and_maybe_log().await; } Err(e) => { log::error!("Failed to deserialize commit: {}", e); From 01c363b6bd9d7019bdcc85b934ae14173333522c Mon Sep 17 00:00:00 2001 From: cyypherus Date: Sun, 21 Dec 2025 13:18:15 -0800 Subject: [PATCH 46/53] implement reconnect with replay for connection resets --- examples/sqlite/Cargo.lock | 1 - examples/sqlite/Cargo.toml | 4 +- examples/sqlite/src/main.rs | 8 +- src/feed.rs | 4 +- src/firehose.rs | 183 ++++++++++++++++++++++-------------- src/lib.rs | 3 +- src/update_counter.rs | 33 +++++++ 7 files changed, 156 insertions(+), 80 deletions(-) create mode 100644 src/update_counter.rs diff --git a/examples/sqlite/Cargo.lock b/examples/sqlite/Cargo.lock index 28771fd..bdb9c2f 100644 --- a/examples/sqlite/Cargo.lock +++ b/examples/sqlite/Cargo.lock @@ -2646,7 +2646,6 @@ checksum = "c1e9a774a6c28142ac54bb25d25562e6bcf957493a184f15ad4eebccb23e410a" [[package]] name = "skyfeed" version = "0.6.0" -source = "git+https://github.com/cyypherus/skyfeed.git?rev=208d1ad828c4296569b44fd7b8799293c5b16695#208d1ad828c4296569b44fd7b8799293c5b16695" dependencies = [ "anyhow", "async-trait", diff --git a/examples/sqlite/Cargo.toml b/examples/sqlite/Cargo.toml index 0c937bc..cc86b30 100644 --- a/examples/sqlite/Cargo.toml +++ b/examples/sqlite/Cargo.toml @@ -10,8 +10,8 @@ local = [] [dependencies] log = "0.4.25" -skyfeed = { git = "https://github.com/cyypherus/skyfeed.git", rev = "208d1ad828c4296569b44fd7b8799293c5b16695" } -# skyfeed = { path = "../.." } +# skyfeed = { git = "https://github.com/cyypherus/skyfeed.git", rev = "208d1ad828c4296569b44fd7b8799293c5b16695" } +skyfeed = { path = "../.." } tokio = { version = "1.43.0", features = ["full", "time"] } rusqlite = { version = "0.33.0", features = ["bundled"] } chrono = "0.4.39" diff --git a/examples/sqlite/src/main.rs b/examples/sqlite/src/main.rs index acad93c..9dfa7c9 100644 --- a/examples/sqlite/src/main.rs +++ b/examples/sqlite/src/main.rs @@ -1,5 +1,5 @@ -// use dotenv::dotenv; use chrono_tz::America::Denver; +use dotenv::dotenv; use log::{error, info, trace}; use rayon::prelude::*; use regex::Regex; @@ -28,9 +28,9 @@ struct PendingLike { #[tokio::main] async fn main() { - // dotenv().expect("No .env"); - // let db = Connection::open("feed.db").expect("Failed to open database"); - let db = Connection::open("/space/feed.db").expect("Failed to open database"); + dotenv().expect("No .env"); + let db = Connection::open("feed.db").expect("Failed to open database"); + // let db = Connection::open("/space/feed.db").expect("Failed to open database"); initialize_db(&db); let my_feed_regex = env::var("MY_FEED_REGEX").expect("Missing feed regex"); diff --git a/src/feed.rs b/src/feed.rs index ac28011..368b85a 100644 --- a/src/feed.rs +++ b/src/feed.rs @@ -18,6 +18,8 @@ use crate::models::FeedRequest; use crate::utility_models::{DidDocument, Service}; use crate::{FeedResult, Post, Uri}; +const FIREHOSE_ENDPOINT: &str = "bsky.network"; + /// A feed handler is responsible for /// - Storing and managing firehose input. /// - Serving responses to feed requests with `serve_feed` @@ -138,7 +140,7 @@ pub async fn start( }); let firehose_listener = tokio::spawn(async move { - if let Err(e) = FirehoseConnector::run(tx).await { + if let Err(e) = FirehoseConnector::run(FIREHOSE_ENDPOINT, tx).await { log::error!("Firehose error: {}", e); } }); diff --git a/src/firehose.rs b/src/firehose.rs index e871a64..3eacd01 100644 --- a/src/firehose.rs +++ b/src/firehose.rs @@ -1,19 +1,21 @@ -use atrium_api::types::Collection; -use futures::StreamExt; -use tokio::net::TcpStream; -use tokio_tungstenite::tungstenite::Message; -use tokio_tungstenite::{MaybeTlsStream, WebSocketStream, connect_async}; - +use crate::Cid; +use crate::firehose::frames::Frame; +use crate::models::{Did, Embed, Label, Post, Uri}; +use crate::update_counter::UpdatesCounter; use atrium_api::app::bsky::feed::{self, Like}; use atrium_api::com::atproto::sync::subscribe_repos::{Commit, NSID}; use atrium_api::types::CidLink; - -use crate::Cid; -use crate::models::{Did, Embed, Label, Post, Uri}; +use atrium_api::types::Collection; use chrono::DateTime; -use std::sync::atomic::{AtomicU64, Ordering}; +use flume::RecvError; +use futures::StreamExt; +use std::convert::Infallible; use std::sync::Arc; -use std::time::{Duration, Instant}; +use std::sync::atomic::{AtomicI64, Ordering}; +use std::time::Duration; +use tokio::net::TcpStream; +use tokio_tungstenite::tungstenite::Message; +use tokio_tungstenite::{MaybeTlsStream, WebSocketStream, connect_async}; mod frames { use ipld_core::ipld::Ipld; @@ -174,47 +176,27 @@ mod frames { } } -use frames::Frame; - -struct UpdatesCounter { - count: Arc, - last_log: Arc>, -} - -impl UpdatesCounter { - fn new() -> Self { - UpdatesCounter { - count: Arc::new(AtomicU64::new(0)), - last_log: Arc::new(tokio::sync::Mutex::new(Instant::now())), - } - } - - async fn increment_and_maybe_log(&self) { - self.count.fetch_add(1, Ordering::Relaxed); - let mut last_log = self.last_log.lock().await; - let elapsed = last_log.elapsed(); - if elapsed >= Duration::from_secs(1) { - let count = self.count.swap(0, Ordering::Relaxed); - let ups = count as f64 / elapsed.as_secs_f64(); - log::trace!("updates/sec: {:.2}", ups); - *last_log = Instant::now(); - } - } -} - #[derive(Debug)] pub enum FirehoseError { - Frame(frames::FrameError), + FrameError(frames::FrameError), + ErrorFrame, WebSocket(tokio_tungstenite::tungstenite::Error), CarStore(String), + SendError(String), + RecvError(RecvError), + JoinError(String), } impl std::fmt::Display for FirehoseError { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { - FirehoseError::Frame(e) => write!(f, "frame error: {}", e), + FirehoseError::FrameError(e) => write!(f, "frame error: {}", e), + FirehoseError::ErrorFrame => write!(f, "error frame"), FirehoseError::WebSocket(e) => write!(f, "websocket error: {}", e), FirehoseError::CarStore(msg) => write!(f, "car store error: {}", msg), + FirehoseError::SendError(msg) => write!(f, "send error: {}", msg), + FirehoseError::RecvError(e) => write!(f, "receive error: {}", e), + FirehoseError::JoinError(msg) => write!(f, "join error: {}", msg), } } } @@ -231,59 +213,123 @@ pub enum FirehoseEvent { pub struct FirehoseConnector; impl FirehoseConnector { - pub async fn run(tx: flume::Sender) -> Result<(), FirehoseError> { - let _ = rustls::crypto::aws_lc_rs::default_provider().install_default(); - let (stream, _) = connect_async(format!("wss://bsky.network/xrpc/{NSID}")) - .await - .map_err(FirehoseError::WebSocket)?; + pub async fn run( + endpoint: &str, + tx: flume::Sender, + ) -> Result<(), FirehoseError> { + let cursor = Arc::new(AtomicI64::new(0)); + const MAX_ATTEMPTS: u32 = 10; + const MAX_BACKOFF_SECS: u64 = 30; + + let mut attempt = 0u32; + + loop { + attempt += 1; + + if attempt > 1 { + let backoff_secs = std::cmp::min(2_u64.pow(attempt - 2), MAX_BACKOFF_SECS); + log::info!( + "Reconnecting to firehose (attempt {}), waiting {}s", + attempt, + backoff_secs + ); + tokio::time::sleep(Duration::from_secs(backoff_secs)).await; + } + + let cursor_value = cursor.load(Ordering::Relaxed); + let url = if cursor_value > 0 { + format!("wss://{endpoint}/xrpc/{NSID}?cursor={}", cursor_value) + } else { + format!("wss://{endpoint}/xrpc/{NSID}") + }; + + let _ = rustls::crypto::aws_lc_rs::default_provider().install_default(); + + match Self::connect_and_run(&url, tx.clone(), cursor.clone()).await { + Ok(()) => { + attempt = 0; + } + Err(e) => { + log::warn!("Firehose connection failed: {}, retrying...", e); + if attempt >= MAX_ATTEMPTS { + log::error!( + "Max reconnection attempts ({}) reached, giving up", + MAX_ATTEMPTS + ); + return Err(e); + } + } + } + } + } + + async fn connect_and_run( + url: &str, + tx: flume::Sender, + cursor: Arc, + ) -> Result<(), FirehoseError> { + let (stream, _) = connect_async(url).await.map_err(FirehoseError::WebSocket)?; let subscription = RepoSubscription { stream }; let (frame_tx, frame_rx) = flume::unbounded(); let receive_task = tokio::spawn(Self::receive_frames(subscription, frame_tx)); - let parse_task = tokio::spawn(Self::parse_frames(frame_rx, tx)); + let parse_task = tokio::spawn(Self::parse_frames(frame_rx, tx, cursor)); tokio::select! { receive_result = receive_task => { - receive_result.map_err(|_| FirehoseError::WebSocket( - tokio_tungstenite::tungstenite::Error::ConnectionClosed - ))??; + match receive_result + .map_err(|e| FirehoseError::JoinError(e.to_string()))?? { + // Infallible! Cool! + } } parse_result = parse_task => { - parse_result.map_err(|_| FirehoseError::WebSocket( - tokio_tungstenite::tungstenite::Error::ConnectionClosed - ))??; + match parse_result + .map_err(|e| FirehoseError::JoinError(e.to_string()))?? { + // Also infallible! Also cool! + } } } - - Ok(()) } async fn receive_frames( mut subscription: RepoSubscription, frame_tx: flume::Sender>, - ) -> Result<(), FirehoseError> { - while let Some(message) = subscription.next().await { - if frame_tx.send_async(message).await.is_err() { - break; + ) -> Result { + loop { + match subscription.next().await { + Some(Ok(frame)) => frame_tx + .send_async(Ok(frame)) + .await + .map_err(|e| FirehoseError::SendError(e.to_string()))?, + Some(Err(e)) => frame_tx + .send_async(Err(e)) + .await + .map_err(|e| FirehoseError::SendError(e.to_string()))?, + None => (), } } - Ok(()) } async fn parse_frames( frame_rx: flume::Receiver>, tx: flume::Sender, - ) -> Result<(), FirehoseError> { + cursor: Arc, + ) -> Result { let counter = UpdatesCounter::new(); - while let Ok(message) = frame_rx.recv_async().await { - match message { + loop { + match frame_rx + .recv_async() + .await + .map_err(FirehoseError::RecvError)? + { Ok(Frame::Message(Some(t), message)) => { if t.as_str() == "#commit" { - match serde_ipld_dagcbor::from_reader(std::io::Cursor::new( + match serde_ipld_dagcbor::from_reader::(std::io::Cursor::new( message.body.as_slice(), )) { Ok(commit) => { + cursor.store(commit.seq, Ordering::Relaxed); if let Err(e) = Self::handle_commit(&commit, &tx).await { log::error!("Failed to handle commit: {}", e); } @@ -296,17 +342,12 @@ impl FirehoseConnector { } } Ok(Frame::Message(None, _msg)) => (), - Ok(Frame::Error(e)) => { - log::error!("Received error frame: {e:?}"); - break; - } + Ok(Frame::Error(_)) => return Err(FirehoseError::ErrorFrame), Err(e) => { - log::error!("Error receiving frames {e}"); return Err(e); } } } - Ok(()) } async fn handle_commit( @@ -436,7 +477,7 @@ impl RepoSubscription { match self.stream.next().await { Some(Ok(Message::Binary(data))) => { let slice: &[u8] = &data; - Some(Frame::try_from(slice).map_err(FirehoseError::Frame)) + Some(Frame::try_from(slice).map_err(FirehoseError::FrameError)) } Some(Ok(_)) | None => None, Some(Err(e)) => Some(Err(FirehoseError::WebSocket(e))), diff --git a/src/lib.rs b/src/lib.rs index d494c0f..425c83b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -5,8 +5,9 @@ mod feed; mod firehose; mod models; mod public_api_test; +mod update_counter; mod utility_models; pub use config::Config; -pub use feed::{start, FeedHandler}; +pub use feed::{FeedHandler, start}; pub use models::*; diff --git a/src/update_counter.rs b/src/update_counter.rs new file mode 100644 index 0000000..788dd54 --- /dev/null +++ b/src/update_counter.rs @@ -0,0 +1,33 @@ +use std::{ + sync::{ + Arc, + atomic::{AtomicU64, Ordering}, + }, + time::{Duration, Instant}, +}; + +pub(crate) struct UpdatesCounter { + count: Arc, + last_log: Arc>, +} + +impl UpdatesCounter { + pub(crate) fn new() -> Self { + UpdatesCounter { + count: Arc::new(AtomicU64::new(0)), + last_log: Arc::new(tokio::sync::Mutex::new(Instant::now())), + } + } + + pub(crate) async fn increment_and_maybe_log(&self) { + self.count.fetch_add(1, Ordering::Relaxed); + let mut last_log = self.last_log.lock().await; + let elapsed = last_log.elapsed(); + if elapsed >= Duration::from_secs(1) { + let count = self.count.swap(0, Ordering::Relaxed); + let ups = count as f64 / elapsed.as_secs_f64(); + log::trace!("updates/sec: {:.2}", ups); + *last_log = Instant::now(); + } + } +} From f8b748151c026806431f148e52ae55f5a2eb2960 Mon Sep 17 00:00:00 2001 From: cyypherus Date: Sun, 21 Dec 2025 13:49:28 -0800 Subject: [PATCH 47/53] implement reconnect with replay for connection resets --- src/feed.rs | 2 +- src/firehose.rs | 42 ++++++++++++++++++++++++------------------ 2 files changed, 25 insertions(+), 19 deletions(-) diff --git a/src/feed.rs b/src/feed.rs index 368b85a..480934f 100644 --- a/src/feed.rs +++ b/src/feed.rs @@ -41,7 +41,7 @@ pub trait FeedHandler { /// Starts the feed generator server & connects to the firehose. /// /// - feed_handler: An object which handles firehose input & serve feeds. This object can implement multiple feeds. -/// - queue_limit: The maximum number of firehose updates to keep in memory at a time. If your handler does not process updates as quickly or more quickly than they are recieved updates will be stored in memory up to this limit, and then dropped if the queue is already at this limit. Updates can come it +/// - queue_limit: The maximum number of firehose updates to keep in memory at a time. If your handler does not process updates as quickly or more quickly than they are recieved updates will be stored in memory up to this limit, and then dropped if the queue is already at this limit. Currently, a reasonable limit is around 5000 updates. Around 500 firehose updates are received per second normally, but this can reach up to 3000 updates per second during replay after a reconnect. /// - config: Configuration values, see `Config` /// - address: The address to bind the server to /// diff --git a/src/firehose.rs b/src/firehose.rs index 3eacd01..9f6c4ab 100644 --- a/src/firehose.rs +++ b/src/firehose.rs @@ -12,7 +12,7 @@ use futures::StreamExt; use std::convert::Infallible; use std::sync::Arc; use std::sync::atomic::{AtomicI64, Ordering}; -use std::time::Duration; +use std::time::{Duration, Instant}; use tokio::net::TcpStream; use tokio_tungstenite::tungstenite::Message; use tokio_tungstenite::{MaybeTlsStream, WebSocketStream, connect_async}; @@ -220,22 +220,12 @@ impl FirehoseConnector { let cursor = Arc::new(AtomicI64::new(0)); const MAX_ATTEMPTS: u32 = 10; const MAX_BACKOFF_SECS: u64 = 30; + const RESET_THRESHOLD_SECS: u64 = MAX_BACKOFF_SECS * 10; - let mut attempt = 0u32; + let mut reconnect_attempts = 0u32; + let mut last_reconnect = Instant::now(); loop { - attempt += 1; - - if attempt > 1 { - let backoff_secs = std::cmp::min(2_u64.pow(attempt - 2), MAX_BACKOFF_SECS); - log::info!( - "Reconnecting to firehose (attempt {}), waiting {}s", - attempt, - backoff_secs - ); - tokio::time::sleep(Duration::from_secs(backoff_secs)).await; - } - let cursor_value = cursor.load(Ordering::Relaxed); let url = if cursor_value > 0 { format!("wss://{endpoint}/xrpc/{NSID}?cursor={}", cursor_value) @@ -246,18 +236,34 @@ impl FirehoseConnector { let _ = rustls::crypto::aws_lc_rs::default_provider().install_default(); match Self::connect_and_run(&url, tx.clone(), cursor.clone()).await { - Ok(()) => { - attempt = 0; - } + Ok(()) => {} Err(e) => { + // If the last reconnect happened longer than 10x our max backoff, we can consider it irrelevant to our current reconnect process + if last_reconnect.elapsed() > Duration::from_secs(RESET_THRESHOLD_SECS) { + reconnect_attempts = 0; + } + + reconnect_attempts += 1; + last_reconnect = Instant::now(); log::warn!("Firehose connection failed: {}, retrying...", e); - if attempt >= MAX_ATTEMPTS { + + if reconnect_attempts >= MAX_ATTEMPTS { log::error!( "Max reconnection attempts ({}) reached, giving up", MAX_ATTEMPTS ); return Err(e); } + + // Exponential backoff with cap + let backoff_secs = + std::cmp::min(2_u64.pow(reconnect_attempts - 1), MAX_BACKOFF_SECS); + log::info!( + "Reconnecting to firehose (attempt {}), waiting {}s", + reconnect_attempts, + backoff_secs + ); + tokio::time::sleep(Duration::from_secs(backoff_secs)).await; } } } From 4a8e6850f20b2900f1653253730a3b8c6f472eba Mon Sep 17 00:00:00 2001 From: cyypherus Date: Sun, 21 Dec 2025 13:53:34 -0800 Subject: [PATCH 48/53] pull in crate updates --- examples/sqlite/Cargo.toml | 4 ++-- examples/sqlite/src/main.rs | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/examples/sqlite/Cargo.toml b/examples/sqlite/Cargo.toml index cc86b30..db6f0e4 100644 --- a/examples/sqlite/Cargo.toml +++ b/examples/sqlite/Cargo.toml @@ -10,8 +10,8 @@ local = [] [dependencies] log = "0.4.25" -# skyfeed = { git = "https://github.com/cyypherus/skyfeed.git", rev = "208d1ad828c4296569b44fd7b8799293c5b16695" } -skyfeed = { path = "../.." } +skyfeed = { git = "https://github.com/cyypherus/skyfeed.git", rev = "f8b748151c026806431f148e52ae55f5a2eb2960" } +# skyfeed = { path = "../.." } tokio = { version = "1.43.0", features = ["full", "time"] } rusqlite = { version = "0.33.0", features = ["bundled"] } chrono = "0.4.39" diff --git a/examples/sqlite/src/main.rs b/examples/sqlite/src/main.rs index 9dfa7c9..1c2213d 100644 --- a/examples/sqlite/src/main.rs +++ b/examples/sqlite/src/main.rs @@ -1,5 +1,5 @@ use chrono_tz::America::Denver; -use dotenv::dotenv; +// use dotenv::dotenv; use log::{error, info, trace}; use rayon::prelude::*; use regex::Regex; @@ -28,9 +28,9 @@ struct PendingLike { #[tokio::main] async fn main() { - dotenv().expect("No .env"); - let db = Connection::open("feed.db").expect("Failed to open database"); - // let db = Connection::open("/space/feed.db").expect("Failed to open database"); + // dotenv().expect("No .env"); + // let db = Connection::open("feed.db").expect("Failed to open database"); + let db = Connection::open("/space/feed.db").expect("Failed to open database"); initialize_db(&db); let my_feed_regex = env::var("MY_FEED_REGEX").expect("Missing feed regex"); From 7627cc91f6dc7f30edb8312671e31c4a9a2d2539 Mon Sep 17 00:00:00 2001 From: cyypherus Date: Sun, 21 Dec 2025 14:07:49 -0800 Subject: [PATCH 49/53] merge main --- Cargo.toml | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 0ce252a..cf59325 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -38,22 +38,10 @@ path = "examples/sqlite/src/main.rs" required-features = ["examples"] [dependencies] -<<<<<<< HEAD atrium-api = "0.25.6" atrium-repo = "0.1.6" -||||||| a5bf293 -atrium-api = "=0.24.10" -======= -atrium-api = "=0.25.2" ->>>>>>> 297cdee61fe34ea6d58bbb4ff0f8000aa2e540a7 dotenv = "0.15.0" env_logger = "0.11.5" -<<<<<<< HEAD -||||||| a5bf293 -jetstream-oxide = "0.1.1" -======= -jetstream-oxide = "=0.1.2" ->>>>>>> 297cdee61fe34ea6d58bbb4ff0f8000aa2e540a7 log = "0.4.22" serde = "1.0.215" serde_json = "1.0.133" From d46e05fc2bd5f31edfd3eab797a93813324ecba9 Mon Sep 17 00:00:00 2001 From: cyypherus Date: Sun, 21 Dec 2025 14:11:06 -0800 Subject: [PATCH 50/53] cleanup --- Cargo.lock | 3770 ++++++++++++++++++++++++++++++++++++++++++ src/bin/publish.rs | 6 +- src/bin/unpublish.rs | 4 +- src/lib.rs | 4 +- 4 files changed, 3777 insertions(+), 7 deletions(-) create mode 100644 Cargo.lock diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..ba05f64 --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,3770 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "addr2line" +version = "0.25.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b5d307320b3181d6d7954e663bd7c774a838b8220fe0593c86d9fb09f498b4b" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler2" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" + +[[package]] +name = "ahash" +version = "0.8.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a15f179cd60c4584b8a8c596927aadc462e27f2ca70c04e0071964a73ba7a75" +dependencies = [ + "cfg-if", + "once_cell", + "version_check", + "zerocopy", +] + +[[package]] +name = "aho-corasick" +version = "1.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301" +dependencies = [ + "memchr", +] + +[[package]] +name = "allocator-api2" +version = "0.2.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" + +[[package]] +name = "android_system_properties" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +dependencies = [ + "libc", +] + +[[package]] +name = "anstream" +version = "0.6.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43d5b281e737544384e969a5ccad3f1cdd24b48086a0fc1b2a5262a26b8f4f4a" +dependencies = [ + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "is_terminal_polyfill", + "utf8parse", +] + +[[package]] +name = "anstyle" +version = "1.0.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5192cca8006f1fd4f7237516f40fa183bb07f8fbdfedaa0036de5ea9b0b45e78" + +[[package]] +name = "anstyle-parse" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e7644824f0aa2c7b9384579234ef10eb7efb6a0deb83f9630a49594dd9c15c2" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-query" +version = "1.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "40c48f72fd53cd289104fc64099abca73db4166ad86ea0b4341abe65af83dadc" +dependencies = [ + "windows-sys 0.61.2", +] + +[[package]] +name = "anstyle-wincon" +version = "3.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "291e6a250ff86cd4a820112fb8898808a366d8f9f58ce16d1f538353ad55747d" +dependencies = [ + "anstyle", + "once_cell_polyfill", + "windows-sys 0.61.2", +] + +[[package]] +name = "anyhow" +version = "1.0.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a23eb6b1614318a8071c9b2521f36b424b2c83db5eb3a0fead4a6c0809af6e61" + +[[package]] +name = "arrayref" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76a2e8124351fda1ef8aaaa3bbd7ebbcb486bbcd4225aca0aa0d84bb2db8fecb" + +[[package]] +name = "arrayvec" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" + +[[package]] +name = "async-compression" +version = "0.4.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "98ec5f6c2f8bc326c994cb9e241cc257ddaba9afa8555a43cffbb5dd86efaa37" +dependencies = [ + "compression-codecs", + "compression-core", + "futures-core", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "async-lock" +version = "3.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "290f7f2596bd5b78a9fec8088ccd89180d7f9f55b94b0576823bbbdc72ee8311" +dependencies = [ + "event-listener", + "event-listener-strategy", + "pin-project-lite", +] + +[[package]] +name = "async-stream" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b5a71a6f37880a80d1d7f19efd781e4b5de42c88f0722cc13bcb6cc2cfe8476" +dependencies = [ + "async-stream-impl", + "futures-core", + "pin-project-lite", +] + +[[package]] +name = "async-stream-impl" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7c24de15d275a1ecfd47a380fb4d5ec9bfe0933f309ed5e705b775596a3574d" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.111", +] + +[[package]] +name = "async-trait" +version = "0.1.89" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9035ad2d096bed7955a320ee7e2230574d28fd3c3a0f186cbea1ff3c7eed5dbb" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.111", +] + +[[package]] +name = "atomic-waker" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" + +[[package]] +name = "atrium-api" +version = "0.25.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef9d5e9352fd27d99383ae1db2b6a6aa239e683a7e750e8d73a73996d82b1fd2" +dependencies = [ + "atrium-common", + "atrium-xrpc", + "chrono", + "http", + "ipld-core", + "langtag", + "regex", + "serde", + "serde_bytes", + "serde_json", + "thiserror 1.0.69", + "tokio", + "trait-variant", +] + +[[package]] +name = "atrium-common" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed5610654043faa396a5a15afac0ac646d76aebe45aebd7cef4f8b96b0ab7f4" +dependencies = [ + "dashmap", + "lru", + "moka", + "thiserror 1.0.69", + "tokio", + "trait-variant", + "web-time", +] + +[[package]] +name = "atrium-repo" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "300aff863d16ad3aa1655b8586ae24fc492b338f822a7c2852a2241533832b4d" +dependencies = [ + "async-stream", + "atrium-api", + "futures", + "ipld-core", + "serde", + "serde_bytes", + "serde_ipld_dagcbor", + "sha2", + "thiserror 1.0.69", + "tokio", + "tokio-util", + "unsigned-varint 0.8.0", +] + +[[package]] +name = "atrium-xrpc" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0216ad50ce34e9ff982e171c3659e65dedaa2ed5ac2994524debdc9a9647ffa8" +dependencies = [ + "http", + "serde", + "serde_html_form", + "serde_json", + "thiserror 1.0.69", + "trait-variant", +] + +[[package]] +name = "atrium-xrpc-client" +version = "0.5.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e099e5171f79faef52364ef0657a4cab086a71b384a779a29597a91b780de0d5" +dependencies = [ + "atrium-xrpc", + "reqwest", +] + +[[package]] +name = "autocfg" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" + +[[package]] +name = "aws-lc-rs" +version = "1.15.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a88aab2464f1f25453baa7a07c84c5b7684e274054ba06817f382357f77a288" +dependencies = [ + "aws-lc-sys", + "zeroize", +] + +[[package]] +name = "aws-lc-sys" +version = "0.35.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b45afffdee1e7c9126814751f88dddc747f41d91da16c9551a0f1e8a11e788a1" +dependencies = [ + "cc", + "cmake", + "dunce", + "fs_extra", +] + +[[package]] +name = "backtrace" +version = "0.3.76" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb531853791a215d7c62a30daf0dde835f381ab5de4589cfe7c649d2cbe92bd6" +dependencies = [ + "addr2line", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", + "windows-link", +] + +[[package]] +name = "base-x" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cbbc9d0964165b47557570cce6c952866c2678457aca742aafc9fb771d30270" + +[[package]] +name = "base256emoji" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5e9430d9a245a77c92176e649af6e275f20839a48389859d1661e9a128d077c" +dependencies = [ + "const-str", + "match-lookup", +] + +[[package]] +name = "base64" +version = "0.22.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" + +[[package]] +name = "bitflags" +version = "2.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "812e12b5285cc515a9c72a5c1d3b6d46a19dac5acfef5265968c166106e31dd3" + +[[package]] +name = "blake2b_simd" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06e903a20b159e944f91ec8499fe1e55651480c541ea0a584f5d967c49ad9d99" +dependencies = [ + "arrayref", + "arrayvec", + "constant_time_eq", +] + +[[package]] +name = "blake2s_simd" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e90f7deecfac93095eb874a40febd69427776e24e1bd7f87f33ac62d6f0174df" +dependencies = [ + "arrayref", + "arrayvec", + "constant_time_eq", +] + +[[package]] +name = "blake3" +version = "1.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3888aaa89e4b2a40fca9848e400f6a658a5a3978de7be858e209cafa8be9a4a0" +dependencies = [ + "arrayref", + "arrayvec", + "cc", + "cfg-if", + "constant_time_eq", +] + +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + +[[package]] +name = "bumpalo" +version = "3.19.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5dd9dc738b7a8311c7ade152424974d8115f2cdad61e8dab8dac9f2362298510" + +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + +[[package]] +name = "bytes" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b35204fbdc0b3f4446b89fc1ac2cf84a8a68971995d0bf2e925ec7cd960f9cb3" + +[[package]] +name = "camino" +version = "1.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e629a66d692cb9ff1a1c664e41771b3dcaf961985a9774c0eb0bd1b51cf60a48" +dependencies = [ + "serde_core", +] + +[[package]] +name = "cargo-manifest" +version = "0.19.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1d8af896b707212cd0e99c112a78c9497dd32994192a463ed2f7419d29bd8c6" +dependencies = [ + "serde", + "thiserror 2.0.17", + "toml 0.8.23", +] + +[[package]] +name = "cargo-platform" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87a0c0e6148f11f01f32650a2ea02d532b2ad4e81d8bd41e6e565b5adc5e6082" +dependencies = [ + "serde", + "serde_core", +] + +[[package]] +name = "cargo_metadata" +version = "0.23.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef987d17b0a113becdd19d3d0022d04d7ef41f9efe4f3fb63ac44ba61df3ade9" +dependencies = [ + "camino", + "cargo-platform", + "semver", + "serde", + "serde_json", + "thiserror 2.0.17", +] + +[[package]] +name = "cbor4ii" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b544cf8c89359205f4f990d0e6f3828db42df85b5dac95d09157a250eb0749c4" +dependencies = [ + "serde", +] + +[[package]] +name = "cc" +version = "1.2.50" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f50d563227a1c37cc0a263f64eca3334388c01c5e4c4861a9def205c614383c" +dependencies = [ + "find-msvc-tools", + "jobserver", + "libc", + "shlex", +] + +[[package]] +name = "cfg-if" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" + +[[package]] +name = "chrono" +version = "0.4.42" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "145052bdd345b87320e369255277e3fb5152762ad123a901ef5c262dd38fe8d2" +dependencies = [ + "iana-time-zone", + "js-sys", + "num-traits", + "serde", + "wasm-bindgen", + "windows-link", +] + +[[package]] +name = "chrono-tz" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6139a8597ed92cf816dfb33f5dd6cf0bb93a6adc938f11039f371bc5bcd26c3" +dependencies = [ + "chrono", + "phf", +] + +[[package]] +name = "cid" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd94671561e36e4e7de75f753f577edafb0e7c05d6e4547229fdf7938fbcd2c3" +dependencies = [ + "core2", + "multibase", + "multihash 0.18.1", + "serde", + "unsigned-varint 0.7.2", +] + +[[package]] +name = "cid" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3147d8272e8fa0ccd29ce51194dd98f79ddfb8191ba9e3409884e751798acf3a" +dependencies = [ + "core2", + "multibase", + "multihash 0.19.3", + "serde", + "serde_bytes", + "unsigned-varint 0.8.0", +] + +[[package]] +name = "clap" +version = "4.5.53" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9e340e012a1bf4935f5282ed1436d1489548e8f72308207ea5df0e23d2d03f8" +dependencies = [ + "clap_builder", + "clap_derive", +] + +[[package]] +name = "clap_builder" +version = "4.5.53" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d76b5d13eaa18c901fd2f7fca939fefe3a0727a953561fefdf3b2922b8569d00" +dependencies = [ + "anstream", + "anstyle", + "clap_lex", + "strsim", +] + +[[package]] +name = "clap_derive" +version = "4.5.49" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a0b5487afeab2deb2ff4e03a807ad1a03ac532ff5a2cee5d86884440c7f7671" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn 2.0.111", +] + +[[package]] +name = "clap_lex" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1d728cc89cf3aee9ff92b05e62b19ee65a02b5702cff7d5a377e32c6ae29d8d" + +[[package]] +name = "cmake" +version = "0.1.57" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75443c44cd6b379beb8c5b45d85d0773baf31cce901fe7bb252f4eff3008ef7d" +dependencies = [ + "cc", +] + +[[package]] +name = "colorchoice" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75" + +[[package]] +name = "compression-codecs" +version = "0.4.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0f7ac3e5b97fdce45e8922fb05cae2c37f7bbd63d30dd94821dacfd8f3f2bf2" +dependencies = [ + "compression-core", + "flate2", + "memchr", +] + +[[package]] +name = "compression-core" +version = "0.4.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75984efb6ed102a0d42db99afb6c1948f0380d1d91808d5529916e6c08b49d8d" + +[[package]] +name = "concurrent-queue" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ca0197aee26d1ae37445ee532fefce43251d24cc7c166799f4d46817f1d3973" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "console" +version = "0.15.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "054ccb5b10f9f2cbf51eb355ca1d05c2d279ce1804688d0db74b4733a5aeafd8" +dependencies = [ + "encode_unicode", + "libc", + "once_cell", + "windows-sys 0.59.0", +] + +[[package]] +name = "const-str" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f421161cb492475f1661ddc9815a745a1c894592070661180fdec3d4872e9c3" + +[[package]] +name = "constant_time_eq" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c74b8349d32d297c9134b8c88677813a227df8f779daa29bfc29c183fe3dca6" + +[[package]] +name = "core-foundation" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "core-foundation" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2a6cd9ae233e7f62ba4e9353e81a88df7fc8a5987b8d445b4d90c879bd156f6" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "core-foundation-sys" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" + +[[package]] +name = "core2" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b49ba7ef1ad6107f8824dbe97de947cbaac53c44e7f9756a1fba0d37c1eec505" +dependencies = [ + "memchr", +] + +[[package]] +name = "cpufeatures" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" +dependencies = [ + "libc", +] + +[[package]] +name = "crc32fast" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9481c1c90cbf2ac953f07c8d4a58aa3945c425b7185c9154d67a65e4230da511" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "crossbeam-channel" +version = "0.5.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "82b8f8f868b36967f9606790d1903570de9ceaf870a7bf9fbbd3016d636a2cb2" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-deque" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9dd111b7b7f7d55b72c0a6ae361660ee5853c9af73f70c3c2ef6858b950e2e51" +dependencies = [ + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" + +[[package]] +name = "crypto-common" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78c8292055d1c1df0cce5d180393dc8cce0abec0a7102adb6c7b1eef6016d60a" +dependencies = [ + "generic-array", + "typenum", +] + +[[package]] +name = "dashmap" +version = "6.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5041cc499144891f3790297212f32a74fb938e5136a14943f338ef9e0ae276cf" +dependencies = [ + "cfg-if", + "crossbeam-utils", + "hashbrown 0.14.5", + "lock_api", + "once_cell", + "parking_lot_core", +] + +[[package]] +name = "data-encoding" +version = "2.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a2330da5de22e8a3cb63252ce2abb30116bf5265e89c0e01bc17015ce30a476" + +[[package]] +name = "data-encoding-macro" +version = "0.1.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47ce6c96ea0102f01122a185683611bd5ac8d99e62bc59dd12e6bda344ee673d" +dependencies = [ + "data-encoding", + "data-encoding-macro-internal", +] + +[[package]] +name = "data-encoding-macro-internal" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d162beedaa69905488a8da94f5ac3edb4dd4788b732fadb7bd120b2625c1976" +dependencies = [ + "data-encoding", + "syn 2.0.111", +] + +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer", + "crypto-common", +] + +[[package]] +name = "displaydoc" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.111", +] + +[[package]] +name = "dotenv" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77c90badedccf4105eca100756a0b1289e191f6fcbdadd3cee1d2f614f97da8f" + +[[package]] +name = "dunce" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813" + +[[package]] +name = "either" +version = "1.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" + +[[package]] +name = "encode_unicode" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34aa73646ffb006b8f5147f3dc182bd4bcb190227ce861fc4a4844bf8e3cb2c0" + +[[package]] +name = "encoding_rs" +version = "0.8.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75030f3c4f45dafd7586dd6780965a8c7e8e285a5ecb86713e63a79c5b2766f3" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "env_filter" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bf3c259d255ca70051b30e2e95b5446cdb8949ac4cd22c0d7fd634d89f568e2" +dependencies = [ + "log", + "regex", +] + +[[package]] +name = "env_logger" +version = "0.11.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13c863f0904021b108aa8b2f55046443e6b1ebde8fd4a15c399893aae4fa069f" +dependencies = [ + "anstream", + "anstyle", + "env_filter", + "jiff", + "log", +] + +[[package]] +name = "equivalent" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" + +[[package]] +name = "errno" +version = "0.3.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" +dependencies = [ + "libc", + "windows-sys 0.61.2", +] + +[[package]] +name = "event-listener" +version = "5.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e13b66accf52311f30a0db42147dadea9850cb48cd070028831ae5f5d4b856ab" +dependencies = [ + "concurrent-queue", + "parking", + "pin-project-lite", +] + +[[package]] +name = "event-listener-strategy" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8be9f3dfaaffdae2972880079a491a1a8bb7cbed0b8dd7a347f668b4150a3b93" +dependencies = [ + "event-listener", + "pin-project-lite", +] + +[[package]] +name = "failure" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d32e9bd16cc02eae7db7ef620b392808b89f6a5e16bb3497d159c6b92a0f4f86" +dependencies = [ + "backtrace", + "failure_derive", +] + +[[package]] +name = "failure_derive" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa4da3c766cd7a0db8242e326e9e4e081edd567072893ed320008189715366a4" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", + "synstructure 0.12.6", +] + +[[package]] +name = "fallible-iterator" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2acce4a10f12dc2fb14a218589d4f1f62ef011b2d0cc4b3cb1bba8e94da14649" + +[[package]] +name = "fallible-streaming-iterator" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7360491ce676a36bf9bb3c56c1aa791658183a54d2744120f27285738d90465a" + +[[package]] +name = "fastrand" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" + +[[package]] +name = "find-msvc-tools" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a3076410a55c90011c298b04d0cfa770b00fa04e1e3c97d3f6c9de105a03844" + +[[package]] +name = "flate2" +version = "1.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfe33edd8e85a12a67454e37f8c75e730830d83e313556ab9ebf9ee7fbeb3bfb" +dependencies = [ + "crc32fast", + "miniz_oxide", +] + +[[package]] +name = "flume" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da0e4dd2a88388a1f4ccc7c9ce104604dab68d9f408dc34cd45823d5a9069095" +dependencies = [ + "futures-core", + "futures-sink", + "nanorand", + "spin", +] + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "foldhash" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" + +[[package]] +name = "foreign-types" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" +dependencies = [ + "foreign-types-shared", +] + +[[package]] +name = "foreign-types-shared" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" + +[[package]] +name = "form_urlencoded" +version = "1.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb4cb245038516f5f85277875cdaa4f7d2c9a0fa0468de06ed190163b1581fcf" +dependencies = [ + "percent-encoding", +] + +[[package]] +name = "fs_extra" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42703706b716c37f96a77aea830392ad231f44c9e9a67872fa5548707e11b11c" + +[[package]] +name = "futures" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "65bc07b1a8bc7c85c5f2e110c476c7389b4554ba72af57d8445ea63a576b0876" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-channel" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-core" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" + +[[package]] +name = "futures-executor" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e28d1d997f585e54aebc3f97d39e72338912123a67330d723fdbb564d646c9f" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-io" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" + +[[package]] +name = "futures-macro" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.111", +] + +[[package]] +name = "futures-sink" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" + +[[package]] +name = "futures-task" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" + +[[package]] +name = "futures-util" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-macro", + "futures-sink", + "futures-task", + "memchr", + "pin-project-lite", + "pin-utils", + "slab", +] + +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", +] + +[[package]] +name = "getrandom" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592" +dependencies = [ + "cfg-if", + "js-sys", + "libc", + "wasi", + "wasm-bindgen", +] + +[[package]] +name = "getrandom" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd" +dependencies = [ + "cfg-if", + "libc", + "r-efi", + "wasip2", +] + +[[package]] +name = "gimli" +version = "0.32.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e629b9b98ef3dd8afe6ca2bd0f89306cec16d43d907889945bc5d6687f2f13c7" + +[[package]] +name = "h2" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3c0b69cfcb4e1b9f1bf2f53f95f766e4661169728ec61cd3fe5a0166f2d1386" +dependencies = [ + "atomic-waker", + "bytes", + "fnv", + "futures-core", + "futures-sink", + "http", + "indexmap", + "slab", + "tokio", + "tokio-util", + "tracing", +] + +[[package]] +name = "hashbag" +version = "0.1.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7040a10f52cba493ddb09926e15d10a9d8a28043708a405931fe4c6f19fac064" + +[[package]] +name = "hashbrown" +version = "0.14.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" +dependencies = [ + "ahash", + "allocator-api2", +] + +[[package]] +name = "hashbrown" +version = "0.15.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1" +dependencies = [ + "allocator-api2", + "equivalent", + "foldhash", +] + +[[package]] +name = "hashbrown" +version = "0.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100" + +[[package]] +name = "hashlink" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7382cf6263419f2d8df38c55d7da83da5c18aef87fc7a7fc1fb1e344edfe14c1" +dependencies = [ + "hashbrown 0.15.5", +] + +[[package]] +name = "headers" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3314d5adb5d94bcdf56771f2e50dbbc80bb4bdf88967526706205ac9eff24eb" +dependencies = [ + "base64", + "bytes", + "headers-core", + "http", + "httpdate", + "mime", + "sha1", +] + +[[package]] +name = "headers-core" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "54b4a22553d4242c49fddb9ba998a99962b5cc6f22cb5a3482bec22522403ce4" +dependencies = [ + "http", +] + +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + +[[package]] +name = "http" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3ba2a386d7f85a81f119ad7498ebe444d2e22c2af0b86b069416ace48b3311a" +dependencies = [ + "bytes", + "itoa", +] + +[[package]] +name = "http-body" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" +dependencies = [ + "bytes", + "http", +] + +[[package]] +name = "http-body-util" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b021d93e26becf5dc7e1b75b1bed1fd93124b374ceb73f43d4d4eafec896a64a" +dependencies = [ + "bytes", + "futures-core", + "http", + "http-body", + "pin-project-lite", +] + +[[package]] +name = "httparse" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87" + +[[package]] +name = "httpdate" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" + +[[package]] +name = "hyper" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2ab2d4f250c3d7b1c9fcdff1cece94ea4e2dfbec68614f7b87cb205f24ca9d11" +dependencies = [ + "atomic-waker", + "bytes", + "futures-channel", + "futures-core", + "h2", + "http", + "http-body", + "httparse", + "httpdate", + "itoa", + "pin-project-lite", + "pin-utils", + "smallvec", + "tokio", + "want", +] + +[[package]] +name = "hyper-rustls" +version = "0.27.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3c93eb611681b207e1fe55d5a71ecf91572ec8a6705cdb6857f7d8d5242cf58" +dependencies = [ + "http", + "hyper", + "hyper-util", + "rustls", + "rustls-pki-types", + "tokio", + "tokio-rustls", + "tower-service", +] + +[[package]] +name = "hyper-tls" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70206fc6890eaca9fde8a0bf71caa2ddfc9fe045ac9e5c70df101a7dbde866e0" +dependencies = [ + "bytes", + "http-body-util", + "hyper", + "hyper-util", + "native-tls", + "tokio", + "tokio-native-tls", + "tower-service", +] + +[[package]] +name = "hyper-util" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "727805d60e7938b76b826a6ef209eb70eaa1812794f9424d4a4e2d740662df5f" +dependencies = [ + "base64", + "bytes", + "futures-channel", + "futures-core", + "futures-util", + "http", + "http-body", + "hyper", + "ipnet", + "libc", + "percent-encoding", + "pin-project-lite", + "socket2", + "system-configuration", + "tokio", + "tower-service", + "tracing", + "windows-registry", +] + +[[package]] +name = "iana-time-zone" +version = "0.1.64" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33e57f83510bb73707521ebaffa789ec8caf86f9657cad665b092b581d40e9fb" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "log", + "wasm-bindgen", + "windows-core", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" +dependencies = [ + "cc", +] + +[[package]] +name = "icu_collections" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c6b649701667bbe825c3b7e6388cb521c23d88644678e83c0c4d0a621a34b43" +dependencies = [ + "displaydoc", + "potential_utf", + "yoke", + "zerofrom", + "zerovec", +] + +[[package]] +name = "icu_locale_core" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edba7861004dd3714265b4db54a3c390e880ab658fec5f7db895fae2046b5bb6" +dependencies = [ + "displaydoc", + "litemap", + "tinystr", + "writeable", + "zerovec", +] + +[[package]] +name = "icu_normalizer" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f6c8828b67bf8908d82127b2054ea1b4427ff0230ee9141c54251934ab1b599" +dependencies = [ + "icu_collections", + "icu_normalizer_data", + "icu_properties", + "icu_provider", + "smallvec", + "zerovec", +] + +[[package]] +name = "icu_normalizer_data" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7aedcccd01fc5fe81e6b489c15b247b8b0690feb23304303a9e560f37efc560a" + +[[package]] +name = "icu_properties" +version = "2.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "020bfc02fe870ec3a66d93e677ccca0562506e5872c650f893269e08615d74ec" +dependencies = [ + "icu_collections", + "icu_locale_core", + "icu_properties_data", + "icu_provider", + "zerotrie", + "zerovec", +] + +[[package]] +name = "icu_properties_data" +version = "2.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "616c294cf8d725c6afcd8f55abc17c56464ef6211f9ed59cccffe534129c77af" + +[[package]] +name = "icu_provider" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85962cf0ce02e1e0a629cc34e7ca3e373ce20dda4c4d7294bbd0bf1fdb59e614" +dependencies = [ + "displaydoc", + "icu_locale_core", + "writeable", + "yoke", + "zerofrom", + "zerotrie", + "zerovec", +] + +[[package]] +name = "idna" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b0875f23caa03898994f6ddc501886a45c7d3d62d04d2d90788d47be1b1e4de" +dependencies = [ + "idna_adapter", + "smallvec", + "utf8_iter", +] + +[[package]] +name = "idna_adapter" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3acae9609540aa318d1bc588455225fb2085b9ed0c4f6bd0d9d5bcd86f1a0344" +dependencies = [ + "icu_normalizer", + "icu_properties", +] + +[[package]] +name = "indexmap" +version = "2.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ad4bb2b565bca0645f4d68c5c9af97fba094e9791da685bf83cb5f3ce74acf2" +dependencies = [ + "equivalent", + "hashbrown 0.16.1", +] + +[[package]] +name = "insta" +version = "1.45.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b76866be74d68b1595eb8060cb9191dca9c021db2316558e52ddc5d55d41b66c" +dependencies = [ + "console", + "once_cell", + "similar", + "tempfile", +] + +[[package]] +name = "ipld-core" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "104718b1cc124d92a6d01ca9c9258a7df311405debb3408c445a36452f9bf8db" +dependencies = [ + "cid 0.11.1", + "serde", + "serde_bytes", +] + +[[package]] +name = "ipnet" +version = "2.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "469fb0b9cefa57e3ef31275ee7cacb78f2fdca44e4765491884a2b119d4eb130" + +[[package]] +name = "iri-string" +version = "0.7.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4f867b9d1d896b67beb18518eda36fdb77a32ea590de864f1325b294a6d14397" +dependencies = [ + "memchr", + "serde", +] + +[[package]] +name = "is_terminal_polyfill" +version = "1.70.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6cb138bb79a146c1bd460005623e142ef0181e3d0219cb493e02f7d08a35695" + +[[package]] +name = "itoa" +version = "1.0.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ee5b5339afb4c41626dde77b7a611bd4f2c202b897852b4bcf5d03eddc61010" + +[[package]] +name = "jiff" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49cce2b81f2098e7e3efc35bc2e0a6b7abec9d34128283d7a26fa8f32a6dbb35" +dependencies = [ + "jiff-static", + "log", + "portable-atomic", + "portable-atomic-util", + "serde_core", +] + +[[package]] +name = "jiff-static" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "980af8b43c3ad5d8d349ace167ec8170839f753a42d233ba19e08afe1850fa69" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.111", +] + +[[package]] +name = "jobserver" +version = "0.1.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9afb3de4395d6b3e67a780b6de64b51c978ecf11cb9a462c66be7d4ca9039d33" +dependencies = [ + "getrandom 0.3.4", + "libc", +] + +[[package]] +name = "js-sys" +version = "0.3.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "464a3709c7f55f1f721e5389aa6ea4e3bc6aba669353300af094b29ffbdde1d8" +dependencies = [ + "once_cell", + "wasm-bindgen", +] + +[[package]] +name = "keccak" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ecc2af9a1119c51f12a14607e783cb977bde58bc069ff0c3da1095e635d70654" +dependencies = [ + "cpufeatures", +] + +[[package]] +name = "langtag" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed60c85f254d6ae8450cec15eedd921efbc4d1bdf6fcf6202b9a58b403f6f805" +dependencies = [ + "serde", +] + +[[package]] +name = "libc" +version = "0.2.178" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37c93d8daa9d8a012fd8ab92f088405fb202ea0b6ab73ee2482ae66af4f42091" + +[[package]] +name = "libipld" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1ccd6b8ffb3afee7081fcaec00e1b099fd1c7ccf35ba5729d88538fcc3b4599" +dependencies = [ + "fnv", + "libipld-cbor", + "libipld-cbor-derive", + "libipld-core", + "libipld-json", + "libipld-macro", + "libipld-pb", + "log", + "multihash 0.18.1", + "thiserror 1.0.69", +] + +[[package]] +name = "libipld-cbor" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77d98c9d1747aa5eef1cf099cd648c3fd2d235249f5fed07522aaebc348e423b" +dependencies = [ + "byteorder", + "libipld-core", + "thiserror 1.0.69", +] + +[[package]] +name = "libipld-cbor-derive" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d5ba3a729b72973e456a1812b0afe2e176a376c1836cc1528e9fc98ae8cb838" +dependencies = [ + "proc-macro-crate", + "proc-macro2", + "quote", + "syn 1.0.109", + "synstructure 0.12.6", +] + +[[package]] +name = "libipld-core" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5acd707e8d8b092e967b2af978ed84709eaded82b75effe6cb6f6cc797ef8158" +dependencies = [ + "anyhow", + "cid 0.10.1", + "core2", + "multibase", + "multihash 0.18.1", + "thiserror 1.0.69", +] + +[[package]] +name = "libipld-json" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25856def940047b07b25c33d4e66d248597049ab0202085215dc4dca0487731c" +dependencies = [ + "libipld-core", + "multihash 0.18.1", + "serde", + "serde_json", +] + +[[package]] +name = "libipld-macro" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "71171c54214f866ae6722f3027f81dff0931e600e5a61e6b1b6a49ca0b5ed4ae" +dependencies = [ + "libipld-core", +] + +[[package]] +name = "libipld-pb" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3f2d0f866c4cd5dc9aa8068c429ba478d2882a3a4b70ab56f7e9a0eddf5d16f" +dependencies = [ + "bytes", + "libipld-core", + "quick-protobuf", + "thiserror 1.0.69", +] + +[[package]] +name = "libsqlite3-sys" +version = "0.31.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad8935b44e7c13394a179a438e0cebba0fe08fe01b54f152e29a93b5cf993fd4" +dependencies = [ + "cc", + "pkg-config", + "vcpkg", +] + +[[package]] +name = "linux-raw-sys" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df1d3c3b53da64cf5760482273a98e575c651a67eec7f77df96b5b642de8f039" + +[[package]] +name = "litemap" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6373607a59f0be73a39b6fe456b8192fcc3585f602af20751600e974dd455e77" + +[[package]] +name = "lock_api" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965" +dependencies = [ + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897" + +[[package]] +name = "lru" +version = "0.12.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "234cf4f4a04dc1f57e24b96cc0cd600cf2af460d4161ac5ecdd0af8e1f3b2a38" +dependencies = [ + "hashbrown 0.15.5", +] + +[[package]] +name = "match-lookup" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1265724d8cb29dbbc2b0f06fffb8bf1a8c0cf73a78eede9ba73a4a66c52a981e" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "memchr" +version = "2.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273" + +[[package]] +name = "mime" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" + +[[package]] +name = "mime_guess" +version = "2.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7c44f8e672c00fe5308fa235f821cb4198414e1c77935c1ab6948d3fd78550e" +dependencies = [ + "mime", + "unicase", +] + +[[package]] +name = "miniz_oxide" +version = "0.8.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316" +dependencies = [ + "adler2", + "simd-adler32", +] + +[[package]] +name = "mio" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a69bcab0ad47271a0234d9422b131806bf3968021e5dc9328caf2d4cd58557fc" +dependencies = [ + "libc", + "wasi", + "windows-sys 0.61.2", +] + +[[package]] +name = "moka" +version = "0.12.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3dec6bd31b08944e08b58fd99373893a6c17054d6f3ea5006cc894f4f4eee2a" +dependencies = [ + "async-lock", + "crossbeam-channel", + "crossbeam-epoch", + "crossbeam-utils", + "equivalent", + "event-listener", + "futures-util", + "parking_lot", + "portable-atomic", + "smallvec", + "tagptr", + "uuid", +] + +[[package]] +name = "multibase" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8694bb4835f452b0e3bb06dbebb1d6fc5385b6ca1caf2e55fd165c042390ec77" +dependencies = [ + "base-x", + "base256emoji", + "data-encoding", + "data-encoding-macro", +] + +[[package]] +name = "multicodec" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f287a558ce2cac6f63944876d2f76ae2254a17fbe174c82967e76e0aab3379ed" +dependencies = [ + "failure", + "serde", + "unsigned-varint 0.2.3", +] + +[[package]] +name = "multihash" +version = "0.18.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfd8a792c1694c6da4f68db0a9d707c72bd260994da179e6030a5dcee00bb815" +dependencies = [ + "blake2b_simd", + "blake2s_simd", + "blake3", + "core2", + "digest", + "multihash-derive", + "sha2", + "sha3", + "unsigned-varint 0.7.2", +] + +[[package]] +name = "multihash" +version = "0.19.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b430e7953c29dd6a09afc29ff0bb69c6e306329ee6794700aee27b76a1aea8d" +dependencies = [ + "core2", + "serde", + "unsigned-varint 0.8.0", +] + +[[package]] +name = "multihash-derive" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d6d4752e6230d8ef7adf7bd5d8c4b1f6561c1014c5ba9a37445ccefe18aa1db" +dependencies = [ + "proc-macro-crate", + "proc-macro-error", + "proc-macro2", + "quote", + "syn 1.0.109", + "synstructure 0.12.6", +] + +[[package]] +name = "nanorand" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a51313c5820b0b02bd422f4b44776fbf47961755c74ce64afc73bfad10226c3" +dependencies = [ + "getrandom 0.2.16", +] + +[[package]] +name = "native-tls" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87de3442987e9dbec73158d5c715e7ad9072fda936bb03d19d7fa10e00520f0e" +dependencies = [ + "libc", + "log", + "openssl", + "openssl-probe", + "openssl-sys", + "schannel", + "security-framework 2.11.1", + "security-framework-sys", + "tempfile", +] + +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", +] + +[[package]] +name = "object" +version = "0.37.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff76201f031d8863c38aa7f905eca4f53abbfa15f609db4277d44cd8938f33fe" +dependencies = [ + "memchr", +] + +[[package]] +name = "once_cell" +version = "1.21.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" + +[[package]] +name = "once_cell_polyfill" +version = "1.70.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe" + +[[package]] +name = "openssl" +version = "0.10.75" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08838db121398ad17ab8531ce9de97b244589089e290a384c900cb9ff7434328" +dependencies = [ + "bitflags", + "cfg-if", + "foreign-types", + "libc", + "once_cell", + "openssl-macros", + "openssl-sys", +] + +[[package]] +name = "openssl-macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.111", +] + +[[package]] +name = "openssl-probe" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e" + +[[package]] +name = "openssl-sys" +version = "0.9.111" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "82cab2d520aa75e3c58898289429321eb788c3106963d0dc886ec7a5f4adc321" +dependencies = [ + "cc", + "libc", + "pkg-config", + "vcpkg", +] + +[[package]] +name = "parking" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba" + +[[package]] +name = "parking_lot" +version = "0.12.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93857453250e3077bd71ff98b6a65ea6621a19bb0f559a85248955ac12c45a1a" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-link", +] + +[[package]] +name = "percent-encoding" +version = "2.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" + +[[package]] +name = "phf" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "913273894cec178f401a31ec4b656318d95473527be05c0752cc41cdc32be8b7" +dependencies = [ + "phf_shared", +] + +[[package]] +name = "phf_shared" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06005508882fb681fd97892ecff4b7fd0fee13ef1aa569f8695dae7ab9099981" +dependencies = [ + "siphasher", +] + +[[package]] +name = "pin-project" +version = "1.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677f1add503faace112b9f1373e43e9e054bfdd22ff1a63c1bc485eaec6a6a8a" +dependencies = [ + "pin-project-internal", +] + +[[package]] +name = "pin-project-internal" +version = "1.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e918e4ff8c4549eb882f14b3a4bc8c8bc93de829416eacf579f1207a8fbf861" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.111", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "pkg-config" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" + +[[package]] +name = "portable-atomic" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f59e70c4aef1e55797c2e8fd94a4f2a973fc972cfde0e0b05f683667b0cd39dd" + +[[package]] +name = "portable-atomic-util" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8a2f0d8d040d7848a709caf78912debcc3f33ee4b3cac47d73d1e1069e83507" +dependencies = [ + "portable-atomic", +] + +[[package]] +name = "potential_utf" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b73949432f5e2a09657003c25bca5e19a0e9c84f8058ca374f49e0ebe605af77" +dependencies = [ + "zerovec", +] + +[[package]] +name = "ppv-lite86" +version = "0.2.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9" +dependencies = [ + "zerocopy", +] + +[[package]] +name = "proc-macro-crate" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e17d47ce914bf4de440332250b0edd23ce48c005f59fab39d3335866b114f11a" +dependencies = [ + "thiserror 1.0.69", + "toml 0.5.11", +] + +[[package]] +name = "proc-macro-error" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" +dependencies = [ + "proc-macro-error-attr", + "proc-macro2", + "quote", + "syn 1.0.109", + "version_check", +] + +[[package]] +name = "proc-macro-error-attr" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" +dependencies = [ + "proc-macro2", + "quote", + "version_check", +] + +[[package]] +name = "proc-macro2" +version = "1.0.103" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ee95bc4ef87b8d5ba32e8b7714ccc834865276eab0aed5c9958d00ec45f49e8" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "public-api" +version = "0.43.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "31529be2a00213a5eeca25ed983569db17036d90de2abe40c55aceaa0915795b" +dependencies = [ + "hashbag", + "rustdoc-types", + "serde", + "serde_json", + "thiserror 2.0.17", +] + +[[package]] +name = "quick-protobuf" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d6da84cc204722a989e01ba2f6e1e276e190f22263d0cb6ce8526fcdb0d2e1f" +dependencies = [ + "byteorder", +] + +[[package]] +name = "quote" +version = "1.0.42" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a338cc41d27e6cc6dce6cefc13a0729dfbb81c262b1f519331575dd80ef3067f" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "r-efi" +version = "5.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" + +[[package]] +name = "rand" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1" +dependencies = [ + "rand_chacha", + "rand_core", +] + +[[package]] +name = "rand_chacha" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38" +dependencies = [ + "getrandom 0.3.4", +] + +[[package]] +name = "rayon" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "368f01d005bf8fd9b1206fb6fa653e6c4a81ceb1466406b81792d87c5677a58f" +dependencies = [ + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22e18b0f0062d30d4230b2e85ff77fdfe4326feb054b9783a3460d8435c8ab91" +dependencies = [ + "crossbeam-deque", + "crossbeam-utils", +] + +[[package]] +name = "redox_syscall" +version = "0.5.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" +dependencies = [ + "bitflags", +] + +[[package]] +name = "regex" +version = "1.12.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "843bc0191f75f3e22651ae5f1e72939ab2f72a4bc30fa80a066bd66edefc24d4" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5276caf25ac86c8d810222b3dbb938e512c55c6831a10f3e6ed1c93b84041f1c" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a2d987857b319362043e95f5353c0535c1f58eec5336fdfcf626430af7def58" + +[[package]] +name = "reqwest" +version = "0.12.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b4c14b2d9afca6a60277086b0cc6a6ae0b568f6f7916c943a8cdc79f8be240f" +dependencies = [ + "base64", + "bytes", + "encoding_rs", + "futures-core", + "h2", + "http", + "http-body", + "http-body-util", + "hyper", + "hyper-rustls", + "hyper-tls", + "hyper-util", + "js-sys", + "log", + "mime", + "native-tls", + "percent-encoding", + "pin-project-lite", + "rustls-pki-types", + "serde", + "serde_json", + "serde_urlencoded", + "sync_wrapper", + "tokio", + "tokio-native-tls", + "tower", + "tower-http", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", +] + +[[package]] +name = "ring" +version = "0.17.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7" +dependencies = [ + "cc", + "cfg-if", + "getrandom 0.2.16", + "libc", + "untrusted", + "windows-sys 0.52.0", +] + +[[package]] +name = "rs-car" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "732df95a8f40f7623f7d54eac1e11626d86fd970f7542738d64c30d0d7ff0068" +dependencies = [ + "blake2b_simd", + "cid 0.10.1", + "futures", + "hex", + "libipld", + "libipld-cbor", + "multibase", + "multicodec", + "multihash 0.18.1", + "sha2", +] + +[[package]] +name = "rusqlite" +version = "0.33.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c6d5e5acb6f6129fe3f7ba0a7fc77bca1942cb568535e18e7bc40262baf3110" +dependencies = [ + "bitflags", + "fallible-iterator", + "fallible-streaming-iterator", + "hashlink", + "libsqlite3-sys", + "smallvec", +] + +[[package]] +name = "rustc-demangle" +version = "0.1.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56f7d92ca342cea22a06f2121d944b4fd82af56988c270852495420f961d4ace" + +[[package]] +name = "rustdoc-json" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "248f714c774453783144ae17f6203d727674a7cb69ba2ecf1df841c187403086" +dependencies = [ + "cargo-manifest", + "cargo_metadata", + "serde", + "thiserror 2.0.17", + "toml 0.8.23", + "tracing", +] + +[[package]] +name = "rustdoc-types" +version = "0.35.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf583db9958b3161d7980a56a8ee3c25e1a40708b81259be72584b7e0ea07c95" +dependencies = [ + "serde", +] + +[[package]] +name = "rustix" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd15f8a2c5551a84d56efdc1cd049089e409ac19a3072d5037a17fd70719ff3e" +dependencies = [ + "bitflags", + "errno", + "libc", + "linux-raw-sys", + "windows-sys 0.61.2", +] + +[[package]] +name = "rustls" +version = "0.23.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "533f54bc6a7d4f647e46ad909549eda97bf5afc1585190ef692b4286b198bd8f" +dependencies = [ + "aws-lc-rs", + "log", + "once_cell", + "rustls-pki-types", + "rustls-webpki", + "subtle", + "zeroize", +] + +[[package]] +name = "rustls-native-certs" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9980d917ebb0c0536119ba501e90834767bffc3d60641457fd84a1f3fd337923" +dependencies = [ + "openssl-probe", + "rustls-pki-types", + "schannel", + "security-framework 3.5.1", +] + +[[package]] +name = "rustls-pki-types" +version = "1.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21e6f2ab2928ca4291b86736a8bd920a277a399bba1589409d72154ff87c1282" +dependencies = [ + "zeroize", +] + +[[package]] +name = "rustls-webpki" +version = "0.103.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2ffdfa2f5286e2247234e03f680868ac2815974dc39e00ea15adc445d0aafe52" +dependencies = [ + "aws-lc-rs", + "ring", + "rustls-pki-types", + "untrusted", +] + +[[package]] +name = "rustup-toolchain" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d5715001c3f29532641421aaddb1302cbcbfd7507ed5f3a5dd0ddb5b808a7e0" +dependencies = [ + "thiserror 2.0.17", +] + +[[package]] +name = "rustversion" +version = "1.0.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" + +[[package]] +name = "ryu" +version = "1.0.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62049b2877bf12821e8f9ad256ee38fdc31db7387ec2d3b3f403024de2034aea" + +[[package]] +name = "schannel" +version = "0.1.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "891d81b926048e76efe18581bf793546b4c0eaf8448d72be8de2bbee5fd166e1" +dependencies = [ + "windows-sys 0.61.2", +] + +[[package]] +name = "scoped-tls" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294" + +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + +[[package]] +name = "security-framework" +version = "2.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" +dependencies = [ + "bitflags", + "core-foundation 0.9.4", + "core-foundation-sys", + "libc", + "security-framework-sys", +] + +[[package]] +name = "security-framework" +version = "3.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3297343eaf830f66ede390ea39da1d462b6b0c1b000f420d0a83f898bbbe6ef" +dependencies = [ + "bitflags", + "core-foundation 0.10.1", + "core-foundation-sys", + "libc", + "security-framework-sys", +] + +[[package]] +name = "security-framework-sys" +version = "2.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc1f0cbffaac4852523ce30d8bd3c5cdc873501d96ff467ca09b6767bb8cd5c0" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "semver" +version = "1.0.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d767eb0aabc880b29956c35734170f26ed551a859dbd361d140cdbeca61ab1e2" +dependencies = [ + "serde", + "serde_core", +] + +[[package]] +name = "serde" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" +dependencies = [ + "serde_core", + "serde_derive", +] + +[[package]] +name = "serde_bytes" +version = "0.11.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5d440709e79d88e51ac01c4b72fc6cb7314017bb7da9eeff678aa94c10e3ea8" +dependencies = [ + "serde", + "serde_core", +] + +[[package]] +name = "serde_core" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.111", +] + +[[package]] +name = "serde_html_form" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2f2d7ff8a2140333718bb329f5c40fc5f0865b84c426183ce14c97d2ab8154f" +dependencies = [ + "form_urlencoded", + "indexmap", + "itoa", + "ryu", + "serde_core", +] + +[[package]] +name = "serde_ipld_dagcbor" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46182f4f08349a02b45c998ba3215d3f9de826246ba02bb9dddfe9a2a2100778" +dependencies = [ + "cbor4ii", + "ipld-core", + "scopeguard", + "serde", +] + +[[package]] +name = "serde_json" +version = "1.0.145" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "402a6f66d8c709116cf22f558eab210f5a50187f702eb4d7e5ef38d9a7f1c79c" +dependencies = [ + "itoa", + "memchr", + "ryu", + "serde", + "serde_core", +] + +[[package]] +name = "serde_spanned" +version = "0.6.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf41e0cfaf7226dca15e8197172c295a782857fcb97fad1808a166870dee75a3" +dependencies = [ + "serde", +] + +[[package]] +name = "serde_urlencoded" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" +dependencies = [ + "form_urlencoded", + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "sha1" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + +[[package]] +name = "sha2" +version = "0.10.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + +[[package]] +name = "sha3" +version = "0.10.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75872d278a8f37ef87fa0ddbda7802605cb18344497949862c0d4dcb291eba60" +dependencies = [ + "digest", + "keccak", +] + +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + +[[package]] +name = "signal-hook-registry" +version = "1.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7664a098b8e616bdfcc2dc0e9ac44eb231eedf41db4e9fe95d8d32ec728dedad" +dependencies = [ + "libc", +] + +[[package]] +name = "simd-adler32" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e320a6c5ad31d271ad523dcf3ad13e2767ad8b1cb8f047f75a8aeaf8da139da2" + +[[package]] +name = "similar" +version = "2.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbbb5d9659141646ae647b42fe094daf6c6192d1620870b449d9557f748b2daa" + +[[package]] +name = "siphasher" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56199f7ddabf13fe5074ce809e7d3f42b42ae711800501b5b16ea82ad029c39d" + +[[package]] +name = "skyfeed" +version = "0.6.0" +dependencies = [ + "anyhow", + "async-trait", + "atrium-api", + "atrium-repo", + "atrium-xrpc-client", + "chrono", + "chrono-tz", + "clap", + "dotenv", + "env_logger", + "flume", + "futures", + "insta", + "ipld-core", + "log", + "public-api", + "rayon", + "regex", + "reqwest", + "rs-car", + "rusqlite", + "rustdoc-json", + "rustls", + "rustup-toolchain", + "serde", + "serde_ipld_dagcbor", + "serde_json", + "tokio", + "tokio-tungstenite", + "warp", + "whatlang", +] + +[[package]] +name = "slab" +version = "0.4.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a2ae44ef20feb57a68b23d846850f861394c2e02dc425a50098ae8c90267589" + +[[package]] +name = "smallvec" +version = "1.15.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" + +[[package]] +name = "socket2" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17129e116933cf371d018bb80ae557e889637989d8638274fb25622827b03881" +dependencies = [ + "libc", + "windows-sys 0.60.2", +] + +[[package]] +name = "spin" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" +dependencies = [ + "lock_api", +] + +[[package]] +name = "stable_deref_trait" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596" + +[[package]] +name = "strsim" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" + +[[package]] +name = "subtle" +version = "2.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" + +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "2.0.111" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "390cc9a294ab71bdb1aa2e99d13be9c753cd2d7bd6560c77118597410c4d2e87" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "sync_wrapper" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bf256ce5efdfa370213c1dabab5935a12e49f2c58d15e9eac2870d3b4f27263" +dependencies = [ + "futures-core", +] + +[[package]] +name = "synstructure" +version = "0.12.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f36bdaa60a83aca3921b5259d5400cbf5e90fc51931376a9bd4a0eb79aa7210f" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", + "unicode-xid", +] + +[[package]] +name = "synstructure" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.111", +] + +[[package]] +name = "system-configuration" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c879d448e9d986b661742763247d3693ed13609438cf3d006f51f5368a5ba6b" +dependencies = [ + "bitflags", + "core-foundation 0.9.4", + "system-configuration-sys", +] + +[[package]] +name = "system-configuration-sys" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e1d1b10ced5ca923a1fcb8d03e96b8d3268065d724548c0211415ff6ac6bac4" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "tagptr" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b2093cf4c8eb1e67749a6762251bc9cd836b6fc171623bd0a9d324d37af2417" + +[[package]] +name = "tempfile" +version = "3.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d31c77bdf42a745371d260a26ca7163f1e0924b64afa0b688e61b5a9fa02f16" +dependencies = [ + "fastrand", + "getrandom 0.3.4", + "once_cell", + "rustix", + "windows-sys 0.61.2", +] + +[[package]] +name = "thiserror" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" +dependencies = [ + "thiserror-impl 1.0.69", +] + +[[package]] +name = "thiserror" +version = "2.0.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f63587ca0f12b72a0600bcba1d40081f830876000bb46dd2337a3051618f4fc8" +dependencies = [ + "thiserror-impl 2.0.17", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.111", +] + +[[package]] +name = "thiserror-impl" +version = "2.0.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ff15c8ecd7de3849db632e14d18d2571fa09dfc5ed93479bc4485c7a517c913" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.111", +] + +[[package]] +name = "tinystr" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42d3e9c45c09de15d06dd8acf5f4e0e399e85927b7f00711024eb7ae10fa4869" +dependencies = [ + "displaydoc", + "zerovec", +] + +[[package]] +name = "tokio" +version = "1.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff360e02eab121e0bc37a2d3b4d4dc622e6eda3a8e5253d5435ecf5bd4c68408" +dependencies = [ + "bytes", + "libc", + "mio", + "parking_lot", + "pin-project-lite", + "signal-hook-registry", + "socket2", + "tokio-macros", + "windows-sys 0.61.2", +] + +[[package]] +name = "tokio-macros" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af407857209536a95c8e56f8231ef2c2e2aff839b22e07a1ffcbc617e9db9fa5" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.111", +] + +[[package]] +name = "tokio-native-tls" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2" +dependencies = [ + "native-tls", + "tokio", +] + +[[package]] +name = "tokio-rustls" +version = "0.26.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1729aa945f29d91ba541258c8df89027d5792d85a8841fb65e8bf0f4ede4ef61" +dependencies = [ + "rustls", + "tokio", +] + +[[package]] +name = "tokio-tungstenite" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d25a406cddcc431a75d3d9afc6a7c0f7428d4891dd973e4d54c56b46127bf857" +dependencies = [ + "futures-util", + "log", + "rustls", + "rustls-native-certs", + "rustls-pki-types", + "tokio", + "tokio-rustls", + "tungstenite", +] + +[[package]] +name = "tokio-util" +version = "0.7.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2efa149fe76073d6e8fd97ef4f4eca7b67f599660115591483572e406e165594" +dependencies = [ + "bytes", + "futures-core", + "futures-io", + "futures-sink", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "toml" +version = "0.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4f7f0dd8d50a853a531c426359045b1998f04219d88799810762cd4ad314234" +dependencies = [ + "serde", +] + +[[package]] +name = "toml" +version = "0.8.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc1beb996b9d83529a9e75c17a1686767d148d70663143c7854d8b4a09ced362" +dependencies = [ + "indexmap", + "serde", + "serde_spanned", + "toml_datetime", + "toml_edit", +] + +[[package]] +name = "toml_datetime" +version = "0.6.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22cddaf88f4fbc13c51aebbf5f8eceb5c7c5a9da2ac40a13519eb5b0a0e8f11c" +dependencies = [ + "serde", +] + +[[package]] +name = "toml_edit" +version = "0.22.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41fe8c660ae4257887cf66394862d21dbca4a6ddd26f04a3560410406a2f819a" +dependencies = [ + "indexmap", + "serde", + "serde_spanned", + "toml_datetime", + "toml_write", + "winnow", +] + +[[package]] +name = "toml_write" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d99f8c9a7727884afe522e9bd5edbfc91a3312b36a77b5fb8926e4c31a41801" + +[[package]] +name = "tower" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d039ad9159c98b70ecfd540b2573b97f7f52c3e8d9f8ad57a24b916a536975f9" +dependencies = [ + "futures-core", + "futures-util", + "pin-project-lite", + "sync_wrapper", + "tokio", + "tower-layer", + "tower-service", +] + +[[package]] +name = "tower-http" +version = "0.6.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4e6559d53cc268e5031cd8429d05415bc4cb4aefc4aa5d6cc35fbf5b924a1f8" +dependencies = [ + "async-compression", + "bitflags", + "bytes", + "futures-core", + "futures-util", + "http", + "http-body", + "http-body-util", + "iri-string", + "pin-project-lite", + "tokio", + "tokio-util", + "tower", + "tower-layer", + "tower-service", +] + +[[package]] +name = "tower-layer" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e" + +[[package]] +name = "tower-service" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" + +[[package]] +name = "tracing" +version = "0.1.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "63e71662fa4b2a2c3a26f570f037eb95bb1f85397f3cd8076caed2f026a6d100" +dependencies = [ + "log", + "pin-project-lite", + "tracing-attributes", + "tracing-core", +] + +[[package]] +name = "tracing-attributes" +version = "0.1.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7490cfa5ec963746568740651ac6781f701c9c5ea257c58e057f3ba8cf69e8da" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.111", +] + +[[package]] +name = "tracing-core" +version = "0.1.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db97caf9d906fbde555dd62fa95ddba9eecfd14cb388e4f491a66d74cd5fb79a" +dependencies = [ + "once_cell", +] + +[[package]] +name = "trait-variant" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70977707304198400eb4835a78f6a9f928bf41bba420deb8fdb175cd965d77a7" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.111", +] + +[[package]] +name = "try-lock" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" + +[[package]] +name = "tungstenite" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8628dcc84e5a09eb3d8423d6cb682965dea9133204e8fb3efee74c2a0c259442" +dependencies = [ + "bytes", + "data-encoding", + "http", + "httparse", + "log", + "rand", + "rustls", + "rustls-pki-types", + "sha1", + "thiserror 2.0.17", + "utf-8", +] + +[[package]] +name = "typenum" +version = "1.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "562d481066bde0658276a35467c4af00bdc6ee726305698a55b86e61d7ad82bb" + +[[package]] +name = "unicase" +version = "2.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75b844d17643ee918803943289730bec8aac480150456169e647ed0b576ba539" + +[[package]] +name = "unicode-ident" +version = "1.0.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9312f7c4f6ff9069b165498234ce8be658059c6728633667c526e27dc2cf1df5" + +[[package]] +name = "unicode-xid" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" + +[[package]] +name = "unsigned-varint" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7f0023a96687fe169081e8adce3f65e3874426b7886e9234d490af2dc077959" + +[[package]] +name = "unsigned-varint" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6889a77d49f1f013504cec6bf97a2c730394adedaeb1deb5ea08949a50541105" + +[[package]] +name = "unsigned-varint" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb066959b24b5196ae73cb057f45598450d2c5f71460e98c49b738086eff9c06" +dependencies = [ + "futures-io", + "futures-util", +] + +[[package]] +name = "untrusted" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" + +[[package]] +name = "url" +version = "2.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08bc136a29a3d1758e07a9cca267be308aeebf5cfd5a10f3f67ab2097683ef5b" +dependencies = [ + "form_urlencoded", + "idna", + "percent-encoding", + "serde", +] + +[[package]] +name = "utf-8" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" + +[[package]] +name = "utf8_iter" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" + +[[package]] +name = "utf8parse" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" + +[[package]] +name = "uuid" +version = "1.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2e054861b4bd027cd373e18e8d8d8e6548085000e41290d95ce0c373a654b4a" +dependencies = [ + "getrandom 0.3.4", + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "vcpkg" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" + +[[package]] +name = "version_check" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" + +[[package]] +name = "want" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" +dependencies = [ + "try-lock", +] + +[[package]] +name = "warp" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51d06d9202adc1f15d709c4f4a2069be5428aa912cc025d6f268ac441ab066b0" +dependencies = [ + "bytes", + "futures-util", + "headers", + "http", + "http-body", + "http-body-util", + "hyper", + "hyper-util", + "log", + "mime", + "mime_guess", + "percent-encoding", + "pin-project", + "scoped-tls", + "serde", + "serde_json", + "serde_urlencoded", + "tokio", + "tokio-util", + "tower-service", + "tracing", +] + +[[package]] +name = "wasi" +version = "0.11.1+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" + +[[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", +] + +[[package]] +name = "wasm-bindgen" +version = "0.2.106" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d759f433fa64a2d763d1340820e46e111a7a5ab75f993d1852d70b03dbb80fd" +dependencies = [ + "cfg-if", + "once_cell", + "rustversion", + "wasm-bindgen-macro", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-futures" +version = "0.4.56" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "836d9622d604feee9e5de25ac10e3ea5f2d65b41eac0d9ce72eb5deae707ce7c" +dependencies = [ + "cfg-if", + "js-sys", + "once_cell", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.106" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48cb0d2638f8baedbc542ed444afc0644a29166f1595371af4fecf8ce1e7eeb3" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.106" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cefb59d5cd5f92d9dcf80e4683949f15ca4b511f4ac0a6e14d4e1ac60c6ecd40" +dependencies = [ + "bumpalo", + "proc-macro2", + "quote", + "syn 2.0.111", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.106" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cbc538057e648b67f72a982e708d485b2efa771e1ac05fec311f9f63e5800db4" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "web-sys" +version = "0.3.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b32828d774c412041098d182a8b38b16ea816958e07cf40eec2bc080ae137ac" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "web-time" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a6580f308b1fad9207618087a65c04e7a10bc77e02c8e84e9b00dd4b12fa0bb" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "whatlang" +version = "0.16.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "471d1c1645d361eb782a1650b1786a8fb58dd625e681a04c09f5ff7c8764a7b0" +dependencies = [ + "hashbrown 0.14.5", + "once_cell", +] + +[[package]] +name = "windows-core" +version = "0.62.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8e83a14d34d0623b51dce9581199302a221863196a1dde71a7663a4c2be9deb" +dependencies = [ + "windows-implement", + "windows-interface", + "windows-link", + "windows-result", + "windows-strings", +] + +[[package]] +name = "windows-implement" +version = "0.60.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.111", +] + +[[package]] +name = "windows-interface" +version = "0.59.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.111", +] + +[[package]] +name = "windows-link" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" + +[[package]] +name = "windows-registry" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02752bf7fbdcce7f2a27a742f798510f3e5ad88dbe84871e5168e2120c3d5720" +dependencies = [ + "windows-link", + "windows-result", + "windows-strings", +] + +[[package]] +name = "windows-result" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7781fa89eaf60850ac3d2da7af8e5242a5ea78d1a11c49bf2910bb5a73853eb5" +dependencies = [ + "windows-link", +] + +[[package]] +name = "windows-strings" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7837d08f69c77cf6b07689544538e017c1bfcf57e34b4c0ff58e6c2cd3b37091" +dependencies = [ + "windows-link", +] + +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-sys" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +dependencies = [ + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-sys" +version = "0.60.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb" +dependencies = [ + "windows-targets 0.53.5", +] + +[[package]] +name = "windows-sys" +version = "0.61.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" +dependencies = [ + "windows-link", +] + +[[package]] +name = "windows-targets" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm 0.52.6", + "windows_aarch64_msvc 0.52.6", + "windows_i686_gnu 0.52.6", + "windows_i686_gnullvm 0.52.6", + "windows_i686_msvc 0.52.6", + "windows_x86_64_gnu 0.52.6", + "windows_x86_64_gnullvm 0.52.6", + "windows_x86_64_msvc 0.52.6", +] + +[[package]] +name = "windows-targets" +version = "0.53.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4945f9f551b88e0d65f3db0bc25c33b8acea4d9e41163edf90dcd0b19f9069f3" +dependencies = [ + "windows-link", + "windows_aarch64_gnullvm 0.53.1", + "windows_aarch64_msvc 0.53.1", + "windows_i686_gnu 0.53.1", + "windows_i686_gnullvm 0.53.1", + "windows_i686_msvc 0.53.1", + "windows_x86_64_gnu 0.53.1", + "windows_x86_64_gnullvm 0.53.1", + "windows_x86_64_msvc 0.53.1", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9d8416fa8b42f5c947f8482c43e7d89e73a173cead56d044f6a56104a6d1b53" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9d782e804c2f632e395708e99a94275910eb9100b2114651e04744e9b125006" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnu" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "960e6da069d81e09becb0ca57a65220ddff016ff2d6af6a223cf372a506593a3" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa7359d10048f68ab8b09fa71c3daccfb0e9b559aed648a8f95469c27057180c" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + +[[package]] +name = "windows_i686_msvc" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e7ac75179f18232fe9c285163565a57ef8d3c89254a30685b57d83a38d326c2" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c3842cdd74a865a8066ab39c8a7a473c0778a3f29370b5fd6b4b9aa7df4a499" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ffa179e2d07eee8ad8f57493436566c7cc30ac536a3379fdf008f47f6bb7ae1" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650" + +[[package]] +name = "winnow" +version = "0.7.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a5364e9d77fcdeeaa6062ced926ee3381faa2ee02d3eb83a5c27a8825540829" +dependencies = [ + "memchr", +] + +[[package]] +name = "wit-bindgen" +version = "0.46.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f17a85883d4e6d00e8a97c586de764dabcc06133f7f1d55dce5cdc070ad7fe59" + +[[package]] +name = "writeable" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9edde0db4769d2dc68579893f2306b26c6ecfbe0ef499b013d731b7b9247e0b9" + +[[package]] +name = "yoke" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72d6e5c6afb84d73944e5cedb052c4680d5657337201555f9f2a16b7406d4954" +dependencies = [ + "stable_deref_trait", + "yoke-derive", + "zerofrom", +] + +[[package]] +name = "yoke-derive" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b659052874eb698efe5b9e8cf382204678a0086ebf46982b79d6ca3182927e5d" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.111", + "synstructure 0.13.2", +] + +[[package]] +name = "zerocopy" +version = "0.8.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd74ec98b9250adb3ca554bdde269adf631549f51d8a8f8f0a10b50f1cb298c3" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.8.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8a8d209fdf45cf5138cbb5a506f6b52522a25afccc534d1475dad8e31105c6a" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.111", +] + +[[package]] +name = "zerofrom" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50cc42e0333e05660c3587f3bf9d0478688e15d870fab3346451ce7f8c9fbea5" +dependencies = [ + "zerofrom-derive", +] + +[[package]] +name = "zerofrom-derive" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.111", + "synstructure 0.13.2", +] + +[[package]] +name = "zeroize" +version = "1.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b97154e67e32c85465826e8bcc1c59429aaaf107c1e4a9e53c8d8ccd5eff88d0" + +[[package]] +name = "zerotrie" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a59c17a5562d507e4b54960e8569ebee33bee890c70aa3fe7b97e85a9fd7851" +dependencies = [ + "displaydoc", + "yoke", + "zerofrom", +] + +[[package]] +name = "zerovec" +version = "0.11.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c28719294829477f525be0186d13efa9a3c602f7ec202ca9e353d310fb9a002" +dependencies = [ + "yoke", + "zerofrom", + "zerovec-derive", +] + +[[package]] +name = "zerovec-derive" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eadce39539ca5cb3985590102671f2567e659fca9666581ad3411d59207951f3" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.111", +] diff --git a/src/bin/publish.rs b/src/bin/publish.rs index 5078f4c..a3ed6d4 100644 --- a/src/bin/publish.rs +++ b/src/bin/publish.rs @@ -1,11 +1,11 @@ use atrium_api::com::atproto::repo::put_record::InputData; use atrium_api::types::string::RecordKey; use atrium_api::{ - agent::atp_agent::{store::MemorySessionStore, AtpAgent}, + agent::atp_agent::{AtpAgent, store::MemorySessionStore}, app::bsky::feed::generator::RecordData, types::{ - string::{Datetime, Did, Handle, Nsid}, TryIntoUnknown, + string::{Datetime, Did, Handle, Nsid}, }, }; use clap::Parser; @@ -124,7 +124,7 @@ async fn main() { repo: atrium_api::types::string::AtIdentifier::Did( publisher_did.to_owned().did.clone(), ), - rkey: RecordKey::new(args.name.to_owned()).expect("Invalid RecordKey"), + rkey: record_key, swap_commit: None, swap_record: None, validate: None, diff --git a/src/bin/unpublish.rs b/src/bin/unpublish.rs index 0b9a2d0..15211bd 100644 --- a/src/bin/unpublish.rs +++ b/src/bin/unpublish.rs @@ -1,6 +1,6 @@ use anyhow::Result; use atrium_api::{ - agent::atp_agent::{store::MemorySessionStore, AtpAgent}, + agent::atp_agent::{AtpAgent, store::MemorySessionStore}, types::string::{Handle, Nsid, RecordKey}, }; use clap::Parser; @@ -64,7 +64,7 @@ async fn main() -> Result<()> { repo: atrium_api::types::string::AtIdentifier::Did( publisher_did.to_owned().did.clone(), ), - rkey: RecordKey::new(args.name.to_owned()).expect("Invalid RecordKey"), + rkey: record_key, swap_commit: None, swap_record: None, } diff --git a/src/lib.rs b/src/lib.rs index 93dba51..fffcf82 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -11,6 +11,6 @@ mod utility_models; pub use config::Config; pub use feed::{FeedHandler, start}; pub use models::{ - Cid, Did, Embed, ExternalEmbed, FeedResult, ImageEmbed, Label, MediaEmbed, Post, QuoteEmbed, - Request, Uri, VideoEmbed, + Cid, Did, Embed, ExternalEmbed, FeedRequest, FeedResult, ImageEmbed, Label, MediaEmbed, Post, + QuoteEmbed, Uri, VideoEmbed, }; From cc0a252f7aaf7f4e46f9252ba9b7c213f0191c93 Mon Sep 17 00:00:00 2001 From: cyypherus Date: Sun, 21 Dec 2025 14:28:03 -0800 Subject: [PATCH 51/53] update snapshots & public-api --- Cargo.lock | 43 +-- Cargo.toml | 5 +- README.md | 10 + examples/sqlite/Cargo.lock | 1 + examples/sqlite/src/main.rs | 8 +- src/public_api_test.rs | 11 +- .../skyfeed__public_api_test__public_api.snap | 252 +++++++++++------- 7 files changed, 200 insertions(+), 130 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ba05f64..1101438 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1474,18 +1474,6 @@ dependencies = [ "hashbrown 0.16.1", ] -[[package]] -name = "insta" -version = "1.45.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b76866be74d68b1595eb8060cb9191dca9c021db2316558e52ddc5d55d41b66c" -dependencies = [ - "console", - "once_cell", - "similar", - "tempfile", -] - [[package]] name = "ipld-core" version = "0.4.2" @@ -2137,14 +2125,15 @@ dependencies = [ [[package]] name = "public-api" -version = "0.43.0" +version = "0.50.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31529be2a00213a5eeca25ed983569db17036d90de2abe40c55aceaa0915795b" +checksum = "6abe4c4c758f4c8c2eacaf9a787f8e7daca79600522c992af7df154b0d5bf9f1" dependencies = [ "hashbag", "rustdoc-types", "serde", "serde_json", + "snapshot-testing", "thiserror 2.0.17", ] @@ -2367,11 +2356,12 @@ dependencies = [ [[package]] name = "rustdoc-types" -version = "0.35.0" +version = "0.56.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf583db9958b3161d7980a56a8ee3c25e1a40708b81259be72584b7e0ea07c95" +checksum = "27bf787c529efe523ed9eb6dcdbaa5954d34329f08d5c243fce928441826ca90" dependencies = [ "serde", + "serde_derive", ] [[package]] @@ -2681,6 +2671,16 @@ version = "2.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bbbb5d9659141646ae647b42fe094daf6c6192d1620870b449d9557f748b2daa" +[[package]] +name = "similar-asserts" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5b441962c817e33508847a22bd82f03a30cff43642dc2fae8b050566121eb9a" +dependencies = [ + "console", + "similar", +] + [[package]] name = "siphasher" version = "1.0.1" @@ -2703,7 +2703,6 @@ dependencies = [ "env_logger", "flume", "futures", - "insta", "ipld-core", "log", "public-api", @@ -2736,6 +2735,16 @@ version = "1.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" +[[package]] +name = "snapshot-testing" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bebf2194b9611339d00b28260cf6bd640073c60179ce7dd1e47badef1eb606e7" +dependencies = [ + "console", + "similar-asserts", +] + [[package]] name = "socket2" version = "0.6.1" diff --git a/Cargo.toml b/Cargo.toml index cf59325..7b28846 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,7 +12,7 @@ authors = ["cyypherus"] [features] default = ["examples"] -test-api = ["insta", "public-api", "rustdoc-json", "rustup-toolchain"] +test-api = ["public-api", "rustdoc-json", "rustup-toolchain"] examples = ["rusqlite", "regex", "whatlang", "chrono-tz", "rayon"] [[bin]] @@ -69,7 +69,6 @@ chrono-tz = { version = "0.10", optional = true } rayon = { version = "1.11.0", optional = true } # `test-api` feature dependencies -insta = { version = "1.42.1", optional = true } -public-api = { version = "0.43.0", optional = true } +public-api = { version = "0.50.2", optional = true } rustdoc-json = { version = "0.9.4", optional = true } rustup-toolchain = { version = "0.1.9", optional = true } diff --git a/README.md b/README.md index e2f9eb0..ef5d103 100644 --- a/README.md +++ b/README.md @@ -205,3 +205,13 @@ To run these, clone this repo & run this command inside the crate directory `cargo run --bin publish` If you'd like to verify your feed server's endpoints _locally_ before you publish, you can also use the [verify](./src/bin/verify.rs) utility. + +### Contributing + +This repo uses `cargo-public-api` to snapshot test the public API. + +If your PR changes the public API, one of the checks will fail by default. + +If the changes to the public API were intentional you can update the snapshot by running: + +`UPDATE_SNAPSHOTS=yes cargo test --features test-api` diff --git a/examples/sqlite/Cargo.lock b/examples/sqlite/Cargo.lock index bdb9c2f..d6e0d3f 100644 --- a/examples/sqlite/Cargo.lock +++ b/examples/sqlite/Cargo.lock @@ -2646,6 +2646,7 @@ checksum = "c1e9a774a6c28142ac54bb25d25562e6bcf957493a184f15ad4eebccb23e410a" [[package]] name = "skyfeed" version = "0.6.0" +source = "git+https://github.com/cyypherus/skyfeed.git?rev=f8b748151c026806431f148e52ae55f5a2eb2960#f8b748151c026806431f148e52ae55f5a2eb2960" dependencies = [ "anyhow", "async-trait", diff --git a/examples/sqlite/src/main.rs b/examples/sqlite/src/main.rs index 1c2213d..9dfa7c9 100644 --- a/examples/sqlite/src/main.rs +++ b/examples/sqlite/src/main.rs @@ -1,5 +1,5 @@ use chrono_tz::America::Denver; -// use dotenv::dotenv; +use dotenv::dotenv; use log::{error, info, trace}; use rayon::prelude::*; use regex::Regex; @@ -28,9 +28,9 @@ struct PendingLike { #[tokio::main] async fn main() { - // dotenv().expect("No .env"); - // let db = Connection::open("feed.db").expect("Failed to open database"); - let db = Connection::open("/space/feed.db").expect("Failed to open database"); + dotenv().expect("No .env"); + let db = Connection::open("feed.db").expect("Failed to open database"); + // let db = Connection::open("/space/feed.db").expect("Failed to open database"); initialize_db(&db); let my_feed_regex = env::var("MY_FEED_REGEX").expect("Missing feed regex"); diff --git a/src/public_api_test.rs b/src/public_api_test.rs index 38678d5..2dad7ff 100644 --- a/src/public_api_test.rs +++ b/src/public_api_test.rs @@ -1,20 +1,21 @@ #[cfg(feature = "test-api")] #[test] fn public_api() { - // Install a compatible nightly toolchain if it is missing + // Install a compatible nightly toolchain if it is missing. rustup_toolchain::install(public_api::MINIMUM_NIGHTLY_RUST_VERSION).unwrap(); - // Build rustdoc JSON + // Build rustdoc JSON. let rustdoc_json = rustdoc_json::Builder::default() .toolchain(public_api::MINIMUM_NIGHTLY_RUST_VERSION) .build() .unwrap(); - // Derive the public API from the rustdoc JSON + // Derive the public API from rustdoc JSON. let public_api = public_api::Builder::from_rustdoc_json(rustdoc_json) .build() .unwrap(); - // Assert that the public API looks correct - insta::assert_snapshot!(public_api); + // Assert that the public API matches the latest snapshot. + // Run with env var `UPDATE_SNAPSHOTS=yes` to update the snapshot. + public_api.assert_eq_or_update("./src/snapshots/skyfeed__public_api_test__public_api.snap"); } diff --git a/src/snapshots/skyfeed__public_api_test__public_api.snap b/src/snapshots/skyfeed__public_api_test__public_api.snap index 47c7607..2ebdffe 100644 --- a/src/snapshots/skyfeed__public_api_test__public_api.snap +++ b/src/snapshots/skyfeed__public_api_test__public_api.snap @@ -1,7 +1,3 @@ ---- -source: src/public_api_test.rs -expression: public_api ---- pub mod skyfeed pub enum skyfeed::Embed pub skyfeed::Embed::External(skyfeed::ExternalEmbed) @@ -42,7 +38,7 @@ pub fn skyfeed::Embed::borrow(&self) -> &T impl core::borrow::BorrowMut for skyfeed::Embed where T: ?core::marker::Sized pub fn skyfeed::Embed::borrow_mut(&mut self) -> &mut T impl core::clone::CloneToUninit for skyfeed::Embed where T: core::clone::Clone -pub unsafe fn skyfeed::Embed::clone_to_uninit(&self, dst: *mut u8) +pub unsafe fn skyfeed::Embed::clone_to_uninit(&self, dest: *mut u8) impl core::convert::From for skyfeed::Embed pub fn skyfeed::Embed::from(t: T) -> T impl crossbeam_epoch::atomic::Pointable for skyfeed::Embed @@ -52,12 +48,12 @@ pub unsafe fn skyfeed::Embed::deref<'a>(ptr: usize) -> &'a T pub unsafe fn skyfeed::Embed::deref_mut<'a>(ptr: usize) -> &'a mut T pub unsafe fn skyfeed::Embed::drop(ptr: usize) pub unsafe fn skyfeed::Embed::init(init: ::Init) -> usize -impl icu_provider::any::MaybeSendSync for skyfeed::Embed +impl libipld_core::codec::References for skyfeed::Embed +pub fn skyfeed::Embed::references(_c: libipld_core::raw::RawCodec, _r: &mut R, _set: &mut E) -> core::result::Result<(), anyhow::Error> where R: std::io::Read, E: core::iter::traits::collect::Extend> impl tracing::instrument::Instrument for skyfeed::Embed impl tracing::instrument::WithSubscriber for skyfeed::Embed impl typenum::type_operators::Same for skyfeed::Embed pub type skyfeed::Embed::Output = T -impl yoke::erased::ErasedDestructor for skyfeed::Embed where T: 'static impl ppv_lite86::types::VZip for skyfeed::Embed where V: ppv_lite86::types::MultiLane pub fn skyfeed::Embed::vzip(self) -> V pub enum skyfeed::Label @@ -114,7 +110,7 @@ pub fn skyfeed::Label::borrow(&self) -> &T impl core::borrow::BorrowMut for skyfeed::Label where T: ?core::marker::Sized pub fn skyfeed::Label::borrow_mut(&mut self) -> &mut T impl core::clone::CloneToUninit for skyfeed::Label where T: core::clone::Clone -pub unsafe fn skyfeed::Label::clone_to_uninit(&self, dst: *mut u8) +pub unsafe fn skyfeed::Label::clone_to_uninit(&self, dest: *mut u8) impl core::convert::From for skyfeed::Label pub fn skyfeed::Label::from(t: T) -> T impl crossbeam_epoch::atomic::Pointable for skyfeed::Label @@ -124,12 +120,12 @@ pub unsafe fn skyfeed::Label::deref<'a>(ptr: usize) -> &'a T pub unsafe fn skyfeed::Label::deref_mut<'a>(ptr: usize) -> &'a mut T pub unsafe fn skyfeed::Label::drop(ptr: usize) pub unsafe fn skyfeed::Label::init(init: ::Init) -> usize -impl icu_provider::any::MaybeSendSync for skyfeed::Label +impl libipld_core::codec::References for skyfeed::Label +pub fn skyfeed::Label::references(_c: libipld_core::raw::RawCodec, _r: &mut R, _set: &mut E) -> core::result::Result<(), anyhow::Error> where R: std::io::Read, E: core::iter::traits::collect::Extend> impl tracing::instrument::Instrument for skyfeed::Label impl tracing::instrument::WithSubscriber for skyfeed::Label impl typenum::type_operators::Same for skyfeed::Label pub type skyfeed::Label::Output = T -impl yoke::erased::ErasedDestructor for skyfeed::Label where T: 'static impl ppv_lite86::types::VZip for skyfeed::Label where V: ppv_lite86::types::MultiLane pub fn skyfeed::Label::vzip(self) -> V pub enum skyfeed::MediaEmbed @@ -169,7 +165,7 @@ pub fn skyfeed::MediaEmbed::borrow(&self) -> &T impl core::borrow::BorrowMut for skyfeed::MediaEmbed where T: ?core::marker::Sized pub fn skyfeed::MediaEmbed::borrow_mut(&mut self) -> &mut T impl core::clone::CloneToUninit for skyfeed::MediaEmbed where T: core::clone::Clone -pub unsafe fn skyfeed::MediaEmbed::clone_to_uninit(&self, dst: *mut u8) +pub unsafe fn skyfeed::MediaEmbed::clone_to_uninit(&self, dest: *mut u8) impl core::convert::From for skyfeed::MediaEmbed pub fn skyfeed::MediaEmbed::from(t: T) -> T impl crossbeam_epoch::atomic::Pointable for skyfeed::MediaEmbed @@ -179,12 +175,12 @@ pub unsafe fn skyfeed::MediaEmbed::deref<'a>(ptr: usize) -> &'a T pub unsafe fn skyfeed::MediaEmbed::deref_mut<'a>(ptr: usize) -> &'a mut T pub unsafe fn skyfeed::MediaEmbed::drop(ptr: usize) pub unsafe fn skyfeed::MediaEmbed::init(init: ::Init) -> usize -impl icu_provider::any::MaybeSendSync for skyfeed::MediaEmbed +impl libipld_core::codec::References for skyfeed::MediaEmbed +pub fn skyfeed::MediaEmbed::references(_c: libipld_core::raw::RawCodec, _r: &mut R, _set: &mut E) -> core::result::Result<(), anyhow::Error> where R: std::io::Read, E: core::iter::traits::collect::Extend> impl tracing::instrument::Instrument for skyfeed::MediaEmbed impl tracing::instrument::WithSubscriber for skyfeed::MediaEmbed impl typenum::type_operators::Same for skyfeed::MediaEmbed pub type skyfeed::MediaEmbed::Output = T -impl yoke::erased::ErasedDestructor for skyfeed::MediaEmbed where T: 'static impl ppv_lite86::types::VZip for skyfeed::MediaEmbed where V: ppv_lite86::types::MultiLane pub fn skyfeed::MediaEmbed::vzip(self) -> V pub struct skyfeed::Cid(pub alloc::string::String) @@ -221,7 +217,7 @@ pub fn skyfeed::Cid::borrow(&self) -> &T impl core::borrow::BorrowMut for skyfeed::Cid where T: ?core::marker::Sized pub fn skyfeed::Cid::borrow_mut(&mut self) -> &mut T impl core::clone::CloneToUninit for skyfeed::Cid where T: core::clone::Clone -pub unsafe fn skyfeed::Cid::clone_to_uninit(&self, dst: *mut u8) +pub unsafe fn skyfeed::Cid::clone_to_uninit(&self, dest: *mut u8) impl core::convert::From for skyfeed::Cid pub fn skyfeed::Cid::from(t: T) -> T impl crossbeam_epoch::atomic::Pointable for skyfeed::Cid @@ -231,14 +227,70 @@ pub unsafe fn skyfeed::Cid::deref<'a>(ptr: usize) -> &'a T pub unsafe fn skyfeed::Cid::deref_mut<'a>(ptr: usize) -> &'a mut T pub unsafe fn skyfeed::Cid::drop(ptr: usize) pub unsafe fn skyfeed::Cid::init(init: ::Init) -> usize -impl icu_provider::any::MaybeSendSync for skyfeed::Cid +impl libipld_core::codec::References for skyfeed::Cid +pub fn skyfeed::Cid::references(_c: libipld_core::raw::RawCodec, _r: &mut R, _set: &mut E) -> core::result::Result<(), anyhow::Error> where R: std::io::Read, E: core::iter::traits::collect::Extend> impl tracing::instrument::Instrument for skyfeed::Cid impl tracing::instrument::WithSubscriber for skyfeed::Cid impl typenum::type_operators::Same for skyfeed::Cid pub type skyfeed::Cid::Output = T -impl yoke::erased::ErasedDestructor for skyfeed::Cid where T: 'static impl ppv_lite86::types::VZip for skyfeed::Cid where V: ppv_lite86::types::MultiLane pub fn skyfeed::Cid::vzip(self) -> V +pub struct skyfeed::Config +pub skyfeed::Config::feed_generator_hostname: alloc::string::String +pub skyfeed::Config::publisher_did: alloc::string::String +impl skyfeed::Config +pub fn skyfeed::Config::load_env_config() -> Self +impl core::clone::Clone for skyfeed::Config +pub fn skyfeed::Config::clone(&self) -> skyfeed::Config +impl core::fmt::Debug for skyfeed::Config +pub fn skyfeed::Config::fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result +impl core::marker::Freeze for skyfeed::Config +impl core::marker::Send for skyfeed::Config +impl core::marker::Sync for skyfeed::Config +impl core::marker::Unpin for skyfeed::Config +impl core::panic::unwind_safe::RefUnwindSafe for skyfeed::Config +impl core::panic::unwind_safe::UnwindSafe for skyfeed::Config +impl atrium_common::types::throttled::Throttleable

for skyfeed::Config where P: core::default::Default +pub fn skyfeed::Config::throttled(self) -> atrium_common::types::throttled::Throttled +impl atrium_common::types::cached::Cacheable for skyfeed::Config +pub fn skyfeed::Config::cached(self, cache: C) -> atrium_common::types::cached::Cached +impl core::convert::Into for skyfeed::Config where U: core::convert::From +pub fn skyfeed::Config::into(self) -> U +impl core::convert::TryFrom for skyfeed::Config where U: core::convert::Into +pub type skyfeed::Config::Error = core::convert::Infallible +pub fn skyfeed::Config::try_from(value: U) -> core::result::Result>::Error> +impl core::convert::TryInto for skyfeed::Config where U: core::convert::TryFrom +pub type skyfeed::Config::Error = >::Error +pub fn skyfeed::Config::try_into(self) -> core::result::Result>::Error> +impl alloc::borrow::ToOwned for skyfeed::Config where T: core::clone::Clone +pub type skyfeed::Config::Owned = T +pub fn skyfeed::Config::clone_into(&self, target: &mut T) +pub fn skyfeed::Config::to_owned(&self) -> T +impl core::any::Any for skyfeed::Config where T: 'static + ?core::marker::Sized +pub fn skyfeed::Config::type_id(&self) -> core::any::TypeId +impl core::borrow::Borrow for skyfeed::Config where T: ?core::marker::Sized +pub fn skyfeed::Config::borrow(&self) -> &T +impl core::borrow::BorrowMut for skyfeed::Config where T: ?core::marker::Sized +pub fn skyfeed::Config::borrow_mut(&mut self) -> &mut T +impl core::clone::CloneToUninit for skyfeed::Config where T: core::clone::Clone +pub unsafe fn skyfeed::Config::clone_to_uninit(&self, dest: *mut u8) +impl core::convert::From for skyfeed::Config +pub fn skyfeed::Config::from(t: T) -> T +impl crossbeam_epoch::atomic::Pointable for skyfeed::Config +pub type skyfeed::Config::Init = T +pub const skyfeed::Config::ALIGN: usize +pub unsafe fn skyfeed::Config::deref<'a>(ptr: usize) -> &'a T +pub unsafe fn skyfeed::Config::deref_mut<'a>(ptr: usize) -> &'a mut T +pub unsafe fn skyfeed::Config::drop(ptr: usize) +pub unsafe fn skyfeed::Config::init(init: ::Init) -> usize +impl libipld_core::codec::References for skyfeed::Config +pub fn skyfeed::Config::references(_c: libipld_core::raw::RawCodec, _r: &mut R, _set: &mut E) -> core::result::Result<(), anyhow::Error> where R: std::io::Read, E: core::iter::traits::collect::Extend> +impl tracing::instrument::Instrument for skyfeed::Config +impl tracing::instrument::WithSubscriber for skyfeed::Config +impl typenum::type_operators::Same for skyfeed::Config +pub type skyfeed::Config::Output = T +impl ppv_lite86::types::VZip for skyfeed::Config where V: ppv_lite86::types::MultiLane +pub fn skyfeed::Config::vzip(self) -> V pub struct skyfeed::Did(pub alloc::string::String) impl core::clone::Clone for skyfeed::Did pub fn skyfeed::Did::clone(&self) -> skyfeed::Did @@ -273,7 +325,7 @@ pub fn skyfeed::Did::borrow(&self) -> &T impl core::borrow::BorrowMut for skyfeed::Did where T: ?core::marker::Sized pub fn skyfeed::Did::borrow_mut(&mut self) -> &mut T impl core::clone::CloneToUninit for skyfeed::Did where T: core::clone::Clone -pub unsafe fn skyfeed::Did::clone_to_uninit(&self, dst: *mut u8) +pub unsafe fn skyfeed::Did::clone_to_uninit(&self, dest: *mut u8) impl core::convert::From for skyfeed::Did pub fn skyfeed::Did::from(t: T) -> T impl crossbeam_epoch::atomic::Pointable for skyfeed::Did @@ -283,12 +335,12 @@ pub unsafe fn skyfeed::Did::deref<'a>(ptr: usize) -> &'a T pub unsafe fn skyfeed::Did::deref_mut<'a>(ptr: usize) -> &'a mut T pub unsafe fn skyfeed::Did::drop(ptr: usize) pub unsafe fn skyfeed::Did::init(init: ::Init) -> usize -impl icu_provider::any::MaybeSendSync for skyfeed::Did +impl libipld_core::codec::References for skyfeed::Did +pub fn skyfeed::Did::references(_c: libipld_core::raw::RawCodec, _r: &mut R, _set: &mut E) -> core::result::Result<(), anyhow::Error> where R: std::io::Read, E: core::iter::traits::collect::Extend> impl tracing::instrument::Instrument for skyfeed::Did impl tracing::instrument::WithSubscriber for skyfeed::Did impl typenum::type_operators::Same for skyfeed::Did pub type skyfeed::Did::Output = T -impl yoke::erased::ErasedDestructor for skyfeed::Did where T: 'static impl ppv_lite86::types::VZip for skyfeed::Did where V: ppv_lite86::types::MultiLane pub fn skyfeed::Did::vzip(self) -> V pub struct skyfeed::ExternalEmbed @@ -329,7 +381,7 @@ pub fn skyfeed::ExternalEmbed::borrow(&self) -> &T impl core::borrow::BorrowMut for skyfeed::ExternalEmbed where T: ?core::marker::Sized pub fn skyfeed::ExternalEmbed::borrow_mut(&mut self) -> &mut T impl core::clone::CloneToUninit for skyfeed::ExternalEmbed where T: core::clone::Clone -pub unsafe fn skyfeed::ExternalEmbed::clone_to_uninit(&self, dst: *mut u8) +pub unsafe fn skyfeed::ExternalEmbed::clone_to_uninit(&self, dest: *mut u8) impl core::convert::From for skyfeed::ExternalEmbed pub fn skyfeed::ExternalEmbed::from(t: T) -> T impl crossbeam_epoch::atomic::Pointable for skyfeed::ExternalEmbed @@ -339,14 +391,69 @@ pub unsafe fn skyfeed::ExternalEmbed::deref<'a>(ptr: usize) -> &'a T pub unsafe fn skyfeed::ExternalEmbed::deref_mut<'a>(ptr: usize) -> &'a mut T pub unsafe fn skyfeed::ExternalEmbed::drop(ptr: usize) pub unsafe fn skyfeed::ExternalEmbed::init(init: ::Init) -> usize -impl icu_provider::any::MaybeSendSync for skyfeed::ExternalEmbed +impl libipld_core::codec::References for skyfeed::ExternalEmbed +pub fn skyfeed::ExternalEmbed::references(_c: libipld_core::raw::RawCodec, _r: &mut R, _set: &mut E) -> core::result::Result<(), anyhow::Error> where R: std::io::Read, E: core::iter::traits::collect::Extend> impl tracing::instrument::Instrument for skyfeed::ExternalEmbed impl tracing::instrument::WithSubscriber for skyfeed::ExternalEmbed impl typenum::type_operators::Same for skyfeed::ExternalEmbed pub type skyfeed::ExternalEmbed::Output = T -impl yoke::erased::ErasedDestructor for skyfeed::ExternalEmbed where T: 'static impl ppv_lite86::types::VZip for skyfeed::ExternalEmbed where V: ppv_lite86::types::MultiLane pub fn skyfeed::ExternalEmbed::vzip(self) -> V +pub struct skyfeed::FeedRequest +pub skyfeed::FeedRequest::cursor: core::option::Option +pub skyfeed::FeedRequest::feed: alloc::string::String +pub skyfeed::FeedRequest::limit: core::option::Option +impl core::clone::Clone for skyfeed::FeedRequest +pub fn skyfeed::FeedRequest::clone(&self) -> skyfeed::FeedRequest +impl core::fmt::Debug for skyfeed::FeedRequest +pub fn skyfeed::FeedRequest::fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result +impl core::marker::Freeze for skyfeed::FeedRequest +impl core::marker::Send for skyfeed::FeedRequest +impl core::marker::Sync for skyfeed::FeedRequest +impl core::marker::Unpin for skyfeed::FeedRequest +impl core::panic::unwind_safe::RefUnwindSafe for skyfeed::FeedRequest +impl core::panic::unwind_safe::UnwindSafe for skyfeed::FeedRequest +impl atrium_common::types::throttled::Throttleable

for skyfeed::FeedRequest where P: core::default::Default +pub fn skyfeed::FeedRequest::throttled(self) -> atrium_common::types::throttled::Throttled +impl atrium_common::types::cached::Cacheable for skyfeed::FeedRequest +pub fn skyfeed::FeedRequest::cached(self, cache: C) -> atrium_common::types::cached::Cached +impl core::convert::Into for skyfeed::FeedRequest where U: core::convert::From +pub fn skyfeed::FeedRequest::into(self) -> U +impl core::convert::TryFrom for skyfeed::FeedRequest where U: core::convert::Into +pub type skyfeed::FeedRequest::Error = core::convert::Infallible +pub fn skyfeed::FeedRequest::try_from(value: U) -> core::result::Result>::Error> +impl core::convert::TryInto for skyfeed::FeedRequest where U: core::convert::TryFrom +pub type skyfeed::FeedRequest::Error = >::Error +pub fn skyfeed::FeedRequest::try_into(self) -> core::result::Result>::Error> +impl alloc::borrow::ToOwned for skyfeed::FeedRequest where T: core::clone::Clone +pub type skyfeed::FeedRequest::Owned = T +pub fn skyfeed::FeedRequest::clone_into(&self, target: &mut T) +pub fn skyfeed::FeedRequest::to_owned(&self) -> T +impl core::any::Any for skyfeed::FeedRequest where T: 'static + ?core::marker::Sized +pub fn skyfeed::FeedRequest::type_id(&self) -> core::any::TypeId +impl core::borrow::Borrow for skyfeed::FeedRequest where T: ?core::marker::Sized +pub fn skyfeed::FeedRequest::borrow(&self) -> &T +impl core::borrow::BorrowMut for skyfeed::FeedRequest where T: ?core::marker::Sized +pub fn skyfeed::FeedRequest::borrow_mut(&mut self) -> &mut T +impl core::clone::CloneToUninit for skyfeed::FeedRequest where T: core::clone::Clone +pub unsafe fn skyfeed::FeedRequest::clone_to_uninit(&self, dest: *mut u8) +impl core::convert::From for skyfeed::FeedRequest +pub fn skyfeed::FeedRequest::from(t: T) -> T +impl crossbeam_epoch::atomic::Pointable for skyfeed::FeedRequest +pub type skyfeed::FeedRequest::Init = T +pub const skyfeed::FeedRequest::ALIGN: usize +pub unsafe fn skyfeed::FeedRequest::deref<'a>(ptr: usize) -> &'a T +pub unsafe fn skyfeed::FeedRequest::deref_mut<'a>(ptr: usize) -> &'a mut T +pub unsafe fn skyfeed::FeedRequest::drop(ptr: usize) +pub unsafe fn skyfeed::FeedRequest::init(init: ::Init) -> usize +impl libipld_core::codec::References for skyfeed::FeedRequest +pub fn skyfeed::FeedRequest::references(_c: libipld_core::raw::RawCodec, _r: &mut R, _set: &mut E) -> core::result::Result<(), anyhow::Error> where R: std::io::Read, E: core::iter::traits::collect::Extend> +impl tracing::instrument::Instrument for skyfeed::FeedRequest +impl tracing::instrument::WithSubscriber for skyfeed::FeedRequest +impl typenum::type_operators::Same for skyfeed::FeedRequest +pub type skyfeed::FeedRequest::Output = T +impl ppv_lite86::types::VZip for skyfeed::FeedRequest where V: ppv_lite86::types::MultiLane +pub fn skyfeed::FeedRequest::vzip(self) -> V pub struct skyfeed::FeedResult pub skyfeed::FeedResult::cursor: core::option::Option pub skyfeed::FeedResult::feed: alloc::vec::Vec @@ -383,7 +490,7 @@ pub fn skyfeed::FeedResult::borrow(&self) -> &T impl core::borrow::BorrowMut for skyfeed::FeedResult where T: ?core::marker::Sized pub fn skyfeed::FeedResult::borrow_mut(&mut self) -> &mut T impl core::clone::CloneToUninit for skyfeed::FeedResult where T: core::clone::Clone -pub unsafe fn skyfeed::FeedResult::clone_to_uninit(&self, dst: *mut u8) +pub unsafe fn skyfeed::FeedResult::clone_to_uninit(&self, dest: *mut u8) impl core::convert::From for skyfeed::FeedResult pub fn skyfeed::FeedResult::from(t: T) -> T impl crossbeam_epoch::atomic::Pointable for skyfeed::FeedResult @@ -393,12 +500,12 @@ pub unsafe fn skyfeed::FeedResult::deref<'a>(ptr: usize) -> &'a T pub unsafe fn skyfeed::FeedResult::deref_mut<'a>(ptr: usize) -> &'a mut T pub unsafe fn skyfeed::FeedResult::drop(ptr: usize) pub unsafe fn skyfeed::FeedResult::init(init: ::Init) -> usize -impl icu_provider::any::MaybeSendSync for skyfeed::FeedResult +impl libipld_core::codec::References for skyfeed::FeedResult +pub fn skyfeed::FeedResult::references(_c: libipld_core::raw::RawCodec, _r: &mut R, _set: &mut E) -> core::result::Result<(), anyhow::Error> where R: std::io::Read, E: core::iter::traits::collect::Extend> impl tracing::instrument::Instrument for skyfeed::FeedResult impl tracing::instrument::WithSubscriber for skyfeed::FeedResult impl typenum::type_operators::Same for skyfeed::FeedResult pub type skyfeed::FeedResult::Output = T -impl yoke::erased::ErasedDestructor for skyfeed::FeedResult where T: 'static impl ppv_lite86::types::VZip for skyfeed::FeedResult where V: ppv_lite86::types::MultiLane pub fn skyfeed::FeedResult::vzip(self) -> V pub struct skyfeed::ImageEmbed @@ -438,7 +545,7 @@ pub fn skyfeed::ImageEmbed::borrow(&self) -> &T impl core::borrow::BorrowMut for skyfeed::ImageEmbed where T: ?core::marker::Sized pub fn skyfeed::ImageEmbed::borrow_mut(&mut self) -> &mut T impl core::clone::CloneToUninit for skyfeed::ImageEmbed where T: core::clone::Clone -pub unsafe fn skyfeed::ImageEmbed::clone_to_uninit(&self, dst: *mut u8) +pub unsafe fn skyfeed::ImageEmbed::clone_to_uninit(&self, dest: *mut u8) impl core::convert::From for skyfeed::ImageEmbed pub fn skyfeed::ImageEmbed::from(t: T) -> T impl crossbeam_epoch::atomic::Pointable for skyfeed::ImageEmbed @@ -448,12 +555,12 @@ pub unsafe fn skyfeed::ImageEmbed::deref<'a>(ptr: usize) -> &'a T pub unsafe fn skyfeed::ImageEmbed::deref_mut<'a>(ptr: usize) -> &'a mut T pub unsafe fn skyfeed::ImageEmbed::drop(ptr: usize) pub unsafe fn skyfeed::ImageEmbed::init(init: ::Init) -> usize -impl icu_provider::any::MaybeSendSync for skyfeed::ImageEmbed +impl libipld_core::codec::References for skyfeed::ImageEmbed +pub fn skyfeed::ImageEmbed::references(_c: libipld_core::raw::RawCodec, _r: &mut R, _set: &mut E) -> core::result::Result<(), anyhow::Error> where R: std::io::Read, E: core::iter::traits::collect::Extend> impl tracing::instrument::Instrument for skyfeed::ImageEmbed impl tracing::instrument::WithSubscriber for skyfeed::ImageEmbed impl typenum::type_operators::Same for skyfeed::ImageEmbed pub type skyfeed::ImageEmbed::Output = T -impl yoke::erased::ErasedDestructor for skyfeed::ImageEmbed where T: 'static impl ppv_lite86::types::VZip for skyfeed::ImageEmbed where V: ppv_lite86::types::MultiLane pub fn skyfeed::ImageEmbed::vzip(self) -> V pub struct skyfeed::Post @@ -498,7 +605,7 @@ pub fn skyfeed::Post::borrow(&self) -> &T impl core::borrow::BorrowMut for skyfeed::Post where T: ?core::marker::Sized pub fn skyfeed::Post::borrow_mut(&mut self) -> &mut T impl core::clone::CloneToUninit for skyfeed::Post where T: core::clone::Clone -pub unsafe fn skyfeed::Post::clone_to_uninit(&self, dst: *mut u8) +pub unsafe fn skyfeed::Post::clone_to_uninit(&self, dest: *mut u8) impl core::convert::From for skyfeed::Post pub fn skyfeed::Post::from(t: T) -> T impl crossbeam_epoch::atomic::Pointable for skyfeed::Post @@ -508,12 +615,12 @@ pub unsafe fn skyfeed::Post::deref<'a>(ptr: usize) -> &'a T pub unsafe fn skyfeed::Post::deref_mut<'a>(ptr: usize) -> &'a mut T pub unsafe fn skyfeed::Post::drop(ptr: usize) pub unsafe fn skyfeed::Post::init(init: ::Init) -> usize -impl icu_provider::any::MaybeSendSync for skyfeed::Post +impl libipld_core::codec::References for skyfeed::Post +pub fn skyfeed::Post::references(_c: libipld_core::raw::RawCodec, _r: &mut R, _set: &mut E) -> core::result::Result<(), anyhow::Error> where R: std::io::Read, E: core::iter::traits::collect::Extend> impl tracing::instrument::Instrument for skyfeed::Post impl tracing::instrument::WithSubscriber for skyfeed::Post impl typenum::type_operators::Same for skyfeed::Post pub type skyfeed::Post::Output = T -impl yoke::erased::ErasedDestructor for skyfeed::Post where T: 'static impl ppv_lite86::types::VZip for skyfeed::Post where V: ppv_lite86::types::MultiLane pub fn skyfeed::Post::vzip(self) -> V pub struct skyfeed::QuoteEmbed @@ -552,7 +659,7 @@ pub fn skyfeed::QuoteEmbed::borrow(&self) -> &T impl core::borrow::BorrowMut for skyfeed::QuoteEmbed where T: ?core::marker::Sized pub fn skyfeed::QuoteEmbed::borrow_mut(&mut self) -> &mut T impl core::clone::CloneToUninit for skyfeed::QuoteEmbed where T: core::clone::Clone -pub unsafe fn skyfeed::QuoteEmbed::clone_to_uninit(&self, dst: *mut u8) +pub unsafe fn skyfeed::QuoteEmbed::clone_to_uninit(&self, dest: *mut u8) impl core::convert::From for skyfeed::QuoteEmbed pub fn skyfeed::QuoteEmbed::from(t: T) -> T impl crossbeam_epoch::atomic::Pointable for skyfeed::QuoteEmbed @@ -562,69 +669,14 @@ pub unsafe fn skyfeed::QuoteEmbed::deref<'a>(ptr: usize) -> &'a T pub unsafe fn skyfeed::QuoteEmbed::deref_mut<'a>(ptr: usize) -> &'a mut T pub unsafe fn skyfeed::QuoteEmbed::drop(ptr: usize) pub unsafe fn skyfeed::QuoteEmbed::init(init: ::Init) -> usize -impl icu_provider::any::MaybeSendSync for skyfeed::QuoteEmbed +impl libipld_core::codec::References for skyfeed::QuoteEmbed +pub fn skyfeed::QuoteEmbed::references(_c: libipld_core::raw::RawCodec, _r: &mut R, _set: &mut E) -> core::result::Result<(), anyhow::Error> where R: std::io::Read, E: core::iter::traits::collect::Extend> impl tracing::instrument::Instrument for skyfeed::QuoteEmbed impl tracing::instrument::WithSubscriber for skyfeed::QuoteEmbed impl typenum::type_operators::Same for skyfeed::QuoteEmbed pub type skyfeed::QuoteEmbed::Output = T -impl yoke::erased::ErasedDestructor for skyfeed::QuoteEmbed where T: 'static impl ppv_lite86::types::VZip for skyfeed::QuoteEmbed where V: ppv_lite86::types::MultiLane pub fn skyfeed::QuoteEmbed::vzip(self) -> V -pub struct skyfeed::Request -pub skyfeed::Request::cursor: core::option::Option -pub skyfeed::Request::feed: alloc::string::String -pub skyfeed::Request::limit: core::option::Option -impl core::clone::Clone for skyfeed::Request -pub fn skyfeed::Request::clone(&self) -> skyfeed::Request -impl core::fmt::Debug for skyfeed::Request -pub fn skyfeed::Request::fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result -impl core::marker::Freeze for skyfeed::Request -impl core::marker::Send for skyfeed::Request -impl core::marker::Sync for skyfeed::Request -impl core::marker::Unpin for skyfeed::Request -impl core::panic::unwind_safe::RefUnwindSafe for skyfeed::Request -impl core::panic::unwind_safe::UnwindSafe for skyfeed::Request -impl atrium_common::types::throttled::Throttleable

for skyfeed::Request where P: core::default::Default -pub fn skyfeed::Request::throttled(self) -> atrium_common::types::throttled::Throttled -impl atrium_common::types::cached::Cacheable for skyfeed::Request -pub fn skyfeed::Request::cached(self, cache: C) -> atrium_common::types::cached::Cached -impl core::convert::Into for skyfeed::Request where U: core::convert::From -pub fn skyfeed::Request::into(self) -> U -impl core::convert::TryFrom for skyfeed::Request where U: core::convert::Into -pub type skyfeed::Request::Error = core::convert::Infallible -pub fn skyfeed::Request::try_from(value: U) -> core::result::Result>::Error> -impl core::convert::TryInto for skyfeed::Request where U: core::convert::TryFrom -pub type skyfeed::Request::Error = >::Error -pub fn skyfeed::Request::try_into(self) -> core::result::Result>::Error> -impl alloc::borrow::ToOwned for skyfeed::Request where T: core::clone::Clone -pub type skyfeed::Request::Owned = T -pub fn skyfeed::Request::clone_into(&self, target: &mut T) -pub fn skyfeed::Request::to_owned(&self) -> T -impl core::any::Any for skyfeed::Request where T: 'static + ?core::marker::Sized -pub fn skyfeed::Request::type_id(&self) -> core::any::TypeId -impl core::borrow::Borrow for skyfeed::Request where T: ?core::marker::Sized -pub fn skyfeed::Request::borrow(&self) -> &T -impl core::borrow::BorrowMut for skyfeed::Request where T: ?core::marker::Sized -pub fn skyfeed::Request::borrow_mut(&mut self) -> &mut T -impl core::clone::CloneToUninit for skyfeed::Request where T: core::clone::Clone -pub unsafe fn skyfeed::Request::clone_to_uninit(&self, dst: *mut u8) -impl core::convert::From for skyfeed::Request -pub fn skyfeed::Request::from(t: T) -> T -impl crossbeam_epoch::atomic::Pointable for skyfeed::Request -pub type skyfeed::Request::Init = T -pub const skyfeed::Request::ALIGN: usize -pub unsafe fn skyfeed::Request::deref<'a>(ptr: usize) -> &'a T -pub unsafe fn skyfeed::Request::deref_mut<'a>(ptr: usize) -> &'a mut T -pub unsafe fn skyfeed::Request::drop(ptr: usize) -pub unsafe fn skyfeed::Request::init(init: ::Init) -> usize -impl icu_provider::any::MaybeSendSync for skyfeed::Request -impl tracing::instrument::Instrument for skyfeed::Request -impl tracing::instrument::WithSubscriber for skyfeed::Request -impl typenum::type_operators::Same for skyfeed::Request -pub type skyfeed::Request::Output = T -impl yoke::erased::ErasedDestructor for skyfeed::Request where T: 'static -impl ppv_lite86::types::VZip for skyfeed::Request where V: ppv_lite86::types::MultiLane -pub fn skyfeed::Request::vzip(self) -> V pub struct skyfeed::Uri(pub alloc::string::String) impl core::clone::Clone for skyfeed::Uri pub fn skyfeed::Uri::clone(&self) -> skyfeed::Uri @@ -671,7 +723,7 @@ pub fn skyfeed::Uri::borrow(&self) -> &T impl core::borrow::BorrowMut for skyfeed::Uri where T: ?core::marker::Sized pub fn skyfeed::Uri::borrow_mut(&mut self) -> &mut T impl core::clone::CloneToUninit for skyfeed::Uri where T: core::clone::Clone -pub unsafe fn skyfeed::Uri::clone_to_uninit(&self, dst: *mut u8) +pub unsafe fn skyfeed::Uri::clone_to_uninit(&self, dest: *mut u8) impl core::convert::From for skyfeed::Uri pub fn skyfeed::Uri::from(t: T) -> T impl crossbeam_epoch::atomic::Pointable for skyfeed::Uri @@ -681,12 +733,12 @@ pub unsafe fn skyfeed::Uri::deref<'a>(ptr: usize) -> &'a T pub unsafe fn skyfeed::Uri::deref_mut<'a>(ptr: usize) -> &'a mut T pub unsafe fn skyfeed::Uri::drop(ptr: usize) pub unsafe fn skyfeed::Uri::init(init: ::Init) -> usize -impl icu_provider::any::MaybeSendSync for skyfeed::Uri +impl libipld_core::codec::References for skyfeed::Uri +pub fn skyfeed::Uri::references(_c: libipld_core::raw::RawCodec, _r: &mut R, _set: &mut E) -> core::result::Result<(), anyhow::Error> where R: std::io::Read, E: core::iter::traits::collect::Extend> impl tracing::instrument::Instrument for skyfeed::Uri impl tracing::instrument::WithSubscriber for skyfeed::Uri impl typenum::type_operators::Same for skyfeed::Uri pub type skyfeed::Uri::Output = T -impl yoke::erased::ErasedDestructor for skyfeed::Uri where T: 'static impl ppv_lite86::types::VZip for skyfeed::Uri where V: ppv_lite86::types::MultiLane pub fn skyfeed::Uri::vzip(self) -> V pub struct skyfeed::VideoEmbed @@ -725,7 +777,7 @@ pub fn skyfeed::VideoEmbed::borrow(&self) -> &T impl core::borrow::BorrowMut for skyfeed::VideoEmbed where T: ?core::marker::Sized pub fn skyfeed::VideoEmbed::borrow_mut(&mut self) -> &mut T impl core::clone::CloneToUninit for skyfeed::VideoEmbed where T: core::clone::Clone -pub unsafe fn skyfeed::VideoEmbed::clone_to_uninit(&self, dst: *mut u8) +pub unsafe fn skyfeed::VideoEmbed::clone_to_uninit(&self, dest: *mut u8) impl core::convert::From for skyfeed::VideoEmbed pub fn skyfeed::VideoEmbed::from(t: T) -> T impl crossbeam_epoch::atomic::Pointable for skyfeed::VideoEmbed @@ -735,21 +787,19 @@ pub unsafe fn skyfeed::VideoEmbed::deref<'a>(ptr: usize) -> &'a T pub unsafe fn skyfeed::VideoEmbed::deref_mut<'a>(ptr: usize) -> &'a mut T pub unsafe fn skyfeed::VideoEmbed::drop(ptr: usize) pub unsafe fn skyfeed::VideoEmbed::init(init: ::Init) -> usize -impl icu_provider::any::MaybeSendSync for skyfeed::VideoEmbed +impl libipld_core::codec::References for skyfeed::VideoEmbed +pub fn skyfeed::VideoEmbed::references(_c: libipld_core::raw::RawCodec, _r: &mut R, _set: &mut E) -> core::result::Result<(), anyhow::Error> where R: std::io::Read, E: core::iter::traits::collect::Extend> impl tracing::instrument::Instrument for skyfeed::VideoEmbed impl tracing::instrument::WithSubscriber for skyfeed::VideoEmbed impl typenum::type_operators::Same for skyfeed::VideoEmbed pub type skyfeed::VideoEmbed::Output = T -impl yoke::erased::ErasedDestructor for skyfeed::VideoEmbed where T: 'static impl ppv_lite86::types::VZip for skyfeed::VideoEmbed where V: ppv_lite86::types::MultiLane pub fn skyfeed::VideoEmbed::vzip(self) -> V -pub trait skyfeed::Feed -pub fn skyfeed::Feed::handler(&mut self) -> Handler -pub fn skyfeed::Feed::start(&mut self, name: impl core::convert::AsRef, address: impl core::convert::Into + core::fmt::Debug + core::clone::Clone + core::marker::Send) -> impl core::future::future::Future + core::marker::Send -pub fn skyfeed::Feed::start_with_config(&mut self, name: impl core::convert::AsRef, config: skyfeed::config::Config, address: impl core::convert::Into + core::fmt::Debug + core::clone::Clone + core::marker::Send) -> impl core::future::future::Future + core::marker::Send pub trait skyfeed::FeedHandler +pub fn skyfeed::FeedHandler::available_feeds(&mut self) -> impl core::future::future::Future> + core::marker::Send pub fn skyfeed::FeedHandler::delete_like(&mut self, like_uri: skyfeed::Uri) -> impl core::future::future::Future + core::marker::Send pub fn skyfeed::FeedHandler::delete_post(&mut self, uri: skyfeed::Uri) -> impl core::future::future::Future + core::marker::Send +pub fn skyfeed::FeedHandler::insert_like(&mut self, like_uri: skyfeed::Uri, liked_post_uri: skyfeed::Uri) -> impl core::future::future::Future + core::marker::Send pub fn skyfeed::FeedHandler::insert_post(&mut self, post: skyfeed::Post) -> impl core::future::future::Future + core::marker::Send -pub fn skyfeed::FeedHandler::like_post(&mut self, like_uri: skyfeed::Uri, liked_post_uri: skyfeed::Uri) -> impl core::future::future::Future + core::marker::Send -pub fn skyfeed::FeedHandler::serve_feed(&self, request: skyfeed::Request) -> impl core::future::future::Future + core::marker::Send +pub fn skyfeed::FeedHandler::serve_feed(&self, request: skyfeed::FeedRequest) -> impl core::future::future::Future + core::marker::Send +pub async fn skyfeed::start(config: skyfeed::Config, queue_limit: usize, feed_handler: alloc::sync::Arc>, address: impl core::convert::Into + core::marker::Send + 'static) From 1e77afb39348dde805923314a01b13be7986bfa5 Mon Sep 17 00:00:00 2001 From: cyypherus Date: Sun, 21 Dec 2025 14:36:02 -0800 Subject: [PATCH 52/53] update readme --- README.md | 80 ++++++++++++++----------------------- examples/sqlite/Cargo.lock | 2 +- examples/sqlite/Cargo.toml | 2 +- examples/sqlite/src/main.rs | 8 ++-- 4 files changed, 37 insertions(+), 55 deletions(-) diff --git a/README.md b/README.md index ef5d103..0a9d941 100644 --- a/README.md +++ b/README.md @@ -61,12 +61,16 @@ See the [sqlite example](./examples/sqlite) ## Implement the `FeedHandler` Trait -Your feed handler is responsible for storing and managing firehose input. For the sake of simplicity, we'll just use Vec and HashMap to manage posts and likes. +Your feed handler is responsible for storing and managing firehose input. For the sake of simplicity, we'll just use a Vec to manage posts and likes. ```rust +use skyfeed::{Config, FeedHandler, FeedRequest, FeedResult, Post, Uri, start}; +use std::{collections::HashSet, sync::Arc}; +use tokio::sync::Mutex; + #[derive(Clone)] struct MyFeedHandler { - posts: Arc>>, + posts: Vec, } #[derive(Debug, Clone)] @@ -76,55 +80,44 @@ struct MyPost { } impl FeedHandler for MyFeedHandler { + async fn available_feeds(&mut self) -> Vec { + vec!["Cats".to_string()] + } + async fn insert_post(&mut self, post: Post) { if post.text.to_lowercase().contains(" cat ") { - info!("Storing {post:?}"); const MAX_POSTS: usize = 100; - let mut posts = self.posts.lock().await; - - posts.push(MyPost { + self.posts.push(MyPost { post, likes: HashSet::new(), }); - if posts.len() > MAX_POSTS { - posts.remove(0); + if self.posts.len() > MAX_POSTS { + self.posts.remove(0); } } } async fn delete_post(&mut self, uri: Uri) { self.posts - .lock() - .await .retain(|post_with_likes| post_with_likes.post.uri != uri); } - async fn like_post(&mut self, like_uri: Uri, liked_post_uri: Uri) { - if let Some(post_with_likes) = self - .posts - .lock() - .await - .iter_mut() - .find(|p| p.post.uri == liked_post_uri) + async fn insert_like(&mut self, like_uri: Uri, liked_post_uri: Uri) { + if let Some(post_with_likes) = self.posts.iter_mut().find(|p| p.post.uri == liked_post_uri) { post_with_likes.likes.insert(like_uri); } } async fn delete_like(&mut self, like_uri: Uri) { - let mut posts = self.posts.lock().await; - for post_with_likes in posts.iter_mut() { + for post_with_likes in self.posts.iter_mut() { post_with_likes.likes.remove(&like_uri); } } - async fn serve_feed(&self, request: Request) -> FeedResult { - info!("Serving {request:?}"); - - let posts = self.posts.lock().await; - + async fn serve_feed(&self, request: FeedRequest) -> FeedResult { // Parse the cursor from the request let start_index = if let Some(cursor) = &request.cursor { cursor.parse::().unwrap_or(0) @@ -135,7 +128,7 @@ impl FeedHandler for MyFeedHandler { let posts_per_page = 5; // Sort posts by likes - let mut sorted_posts: Vec<_> = posts.iter().collect(); + let mut sorted_posts: Vec<_> = self.posts.iter().collect(); sorted_posts.sort_by(|a, b| b.likes.len().cmp(&a.likes.len())); // Paginate posts @@ -147,7 +140,7 @@ impl FeedHandler for MyFeedHandler { .collect(); // Calculate the next cursor - let next_cursor = if start_index + posts_per_page < posts.len() { + let next_cursor = if start_index + posts_per_page < self.posts.len() { Some((start_index + posts_per_page).to_string()) } else { None @@ -162,38 +155,27 @@ impl FeedHandler for MyFeedHandler { } } } - -``` - -## Implement the `Feed` trait - -We'll need to use `Arc>` to enable concurrent shared access. - -```rust -struct MyFeed { - handler: MyFeedHandler, -} - -impl Feed for MyFeed { - fn handler(&mut self) -> MyFeedHandler { - self.handler.clone() - } -} ``` ## Start your feed! -Now we can create an instance of our `Feed` and start it on a local address. +Now we can create an instance of our feed handler and start the server using the `start()` function with a `Config`. ```rust #[tokio::main] async fn main() { - let mut feed = MyFeed { - handler: MyFeedHandler { - posts: Arc::new(Mutex::new(Vec::new())), - }, + let handler = MyFeedHandler { posts: Vec::new() }; + let config = Config { + publisher_did: "did:web:example.com".to_string(), + feed_generator_hostname: "example.com".to_string(), }; - feed.start("Cats", ([0, 0, 0, 0], 3030)).await + start( + config, + 5_000, + Arc::new(Mutex::new(handler)), + ([0, 0, 0, 0], 3030), + ) + .await } ``` diff --git a/examples/sqlite/Cargo.lock b/examples/sqlite/Cargo.lock index d6e0d3f..3446299 100644 --- a/examples/sqlite/Cargo.lock +++ b/examples/sqlite/Cargo.lock @@ -2646,7 +2646,7 @@ checksum = "c1e9a774a6c28142ac54bb25d25562e6bcf957493a184f15ad4eebccb23e410a" [[package]] name = "skyfeed" version = "0.6.0" -source = "git+https://github.com/cyypherus/skyfeed.git?rev=f8b748151c026806431f148e52ae55f5a2eb2960#f8b748151c026806431f148e52ae55f5a2eb2960" +source = "git+https://github.com/cyypherus/skyfeed.git?rev=cc0a252f7aaf7f4e46f9252ba9b7c213f0191c93#cc0a252f7aaf7f4e46f9252ba9b7c213f0191c93" dependencies = [ "anyhow", "async-trait", diff --git a/examples/sqlite/Cargo.toml b/examples/sqlite/Cargo.toml index db6f0e4..c7df24c 100644 --- a/examples/sqlite/Cargo.toml +++ b/examples/sqlite/Cargo.toml @@ -10,7 +10,7 @@ local = [] [dependencies] log = "0.4.25" -skyfeed = { git = "https://github.com/cyypherus/skyfeed.git", rev = "f8b748151c026806431f148e52ae55f5a2eb2960" } +skyfeed = { git = "https://github.com/cyypherus/skyfeed.git", rev = "cc0a252f7aaf7f4e46f9252ba9b7c213f0191c93" } # skyfeed = { path = "../.." } tokio = { version = "1.43.0", features = ["full", "time"] } rusqlite = { version = "0.33.0", features = ["bundled"] } diff --git a/examples/sqlite/src/main.rs b/examples/sqlite/src/main.rs index 9dfa7c9..1c2213d 100644 --- a/examples/sqlite/src/main.rs +++ b/examples/sqlite/src/main.rs @@ -1,5 +1,5 @@ use chrono_tz::America::Denver; -use dotenv::dotenv; +// use dotenv::dotenv; use log::{error, info, trace}; use rayon::prelude::*; use regex::Regex; @@ -28,9 +28,9 @@ struct PendingLike { #[tokio::main] async fn main() { - dotenv().expect("No .env"); - let db = Connection::open("feed.db").expect("Failed to open database"); - // let db = Connection::open("/space/feed.db").expect("Failed to open database"); + // dotenv().expect("No .env"); + // let db = Connection::open("feed.db").expect("Failed to open database"); + let db = Connection::open("/space/feed.db").expect("Failed to open database"); initialize_db(&db); let my_feed_regex = env::var("MY_FEED_REGEX").expect("Missing feed regex"); From b3b4ab2aa29cbfd3d3eccd41f4dc92adb5b68ffe Mon Sep 17 00:00:00 2001 From: cyypherus Date: Sat, 24 Jan 2026 14:12:32 -0700 Subject: [PATCH 53/53] fix busy loop --- src/bin/my_did.rs | 2 +- src/bin/verify.rs | 7 +++---- src/firehose.rs | 24 ++++++++++++------------ 3 files changed, 16 insertions(+), 17 deletions(-) diff --git a/src/bin/my_did.rs b/src/bin/my_did.rs index eadf7d9..f764f4b 100644 --- a/src/bin/my_did.rs +++ b/src/bin/my_did.rs @@ -1,6 +1,6 @@ use anyhow::Result; use atrium_api::{ - agent::atp_agent::{store::MemorySessionStore, AtpAgent}, + agent::atp_agent::{AtpAgent, store::MemorySessionStore}, types::string::Handle, }; use clap::Parser; diff --git a/src/bin/verify.rs b/src/bin/verify.rs index b77bf9e..afed869 100644 --- a/src/bin/verify.rs +++ b/src/bin/verify.rs @@ -87,13 +87,12 @@ async fn main() { println!( "Feed Skeleton Response (Page {}):\n{}", page + 1, - serde_json::to_string_pretty(&skeleton).expect("Failed to pretty print skeleton JSON") + serde_json::to_string_pretty(&skeleton) + .expect("Failed to pretty print skeleton JSON") ); // Extract cursor for next iteration - cursor = skeleton["cursor"] - .as_str() - .map(|s| s.to_string()); + cursor = skeleton["cursor"].as_str().map(|s| s.to_string()); if cursor.is_none() { break; diff --git a/src/firehose.rs b/src/firehose.rs index 9f6c4ab..0285306 100644 --- a/src/firehose.rs +++ b/src/firehose.rs @@ -185,6 +185,7 @@ pub enum FirehoseError { SendError(String), RecvError(RecvError), JoinError(String), + StreamClosed, } impl std::fmt::Display for FirehoseError { @@ -197,6 +198,7 @@ impl std::fmt::Display for FirehoseError { FirehoseError::SendError(msg) => write!(f, "send error: {}", msg), FirehoseError::RecvError(e) => write!(f, "receive error: {}", e), FirehoseError::JoinError(msg) => write!(f, "join error: {}", msg), + FirehoseError::StreamClosed => write!(f, "stream closed"), } } } @@ -303,16 +305,11 @@ impl FirehoseConnector { frame_tx: flume::Sender>, ) -> Result { loop { - match subscription.next().await { - Some(Ok(frame)) => frame_tx + if let Some(frame) = subscription.next().await? { + frame_tx .send_async(Ok(frame)) .await - .map_err(|e| FirehoseError::SendError(e.to_string()))?, - Some(Err(e)) => frame_tx - .send_async(Err(e)) - .await - .map_err(|e| FirehoseError::SendError(e.to_string()))?, - None => (), + .map_err(|e| FirehoseError::SendError(e.to_string()))?; } } } @@ -479,14 +476,17 @@ struct RepoSubscription { } impl RepoSubscription { - async fn next(&mut self) -> Option> { + async fn next(&mut self) -> Result, FirehoseError> { match self.stream.next().await { Some(Ok(Message::Binary(data))) => { let slice: &[u8] = &data; - Some(Frame::try_from(slice).map_err(FirehoseError::FrameError)) + Ok(Some( + Frame::try_from(slice).map_err(FirehoseError::FrameError)?, + )) } - Some(Ok(_)) | None => None, - Some(Err(e)) => Some(Err(FirehoseError::WebSocket(e))), + Some(Ok(_)) => Ok(None), + None => Err(FirehoseError::StreamClosed), + Some(Err(e)) => Err(FirehoseError::WebSocket(e)), } } }