Constellation, Spacedust, Slingshot, UFOs: atproto crates and services for microcosm

Merge branch 'videah-main'

+8
jetstream/.gitignore
···
+
target/
+
pkg/
+
**/*.rs.bk
+
dist/
+
traces/
+
*.DS_Store
+
.cargo/
+
.env
+1856
jetstream/Cargo.lock
···
+
# This file is automatically @generated by Cargo.
+
# 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"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627"
+
+
[[package]]
+
name = "aho-corasick"
+
version = "1.1.3"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916"
+
dependencies = [
+
"memchr",
+
]
+
+
[[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"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311"
+
dependencies = [
+
"libc",
+
]
+
+
[[package]]
+
name = "anstream"
+
version = "0.6.18"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "8acc5369981196006228e28809f761875c0327210a891e941f4c683b3a99529b"
+
dependencies = [
+
"anstyle",
+
"anstyle-parse",
+
"anstyle-query",
+
"anstyle-wincon",
+
"colorchoice",
+
"is_terminal_polyfill",
+
"utf8parse",
+
]
+
+
[[package]]
+
name = "anstyle"
+
version = "1.0.10"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "55cc3b69f167a1ef2e161439aa98aed94e6028e5f9a59be9a6ffb47aef1651f9"
+
+
[[package]]
+
name = "anstyle-parse"
+
version = "0.2.6"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "3b2d16507662817a6a20a9ea92df6652ee4f94f914589377d69f3b21bc5798a9"
+
dependencies = [
+
"utf8parse",
+
]
+
+
[[package]]
+
name = "anstyle-query"
+
version = "1.1.2"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "79947af37f4177cfead1110013d678905c37501914fba0efea834c3fe9a8d60c"
+
dependencies = [
+
"windows-sys 0.59.0",
+
]
+
+
[[package]]
+
name = "anstyle-wincon"
+
version = "3.0.6"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "2109dbce0e72be3ec00bed26e6a7479ca384ad226efdd66db8fa2e3a38c83125"
+
dependencies = [
+
"anstyle",
+
"windows-sys 0.59.0",
+
]
+
+
[[package]]
+
name = "anyhow"
+
version = "1.0.93"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "4c95c10ba0b00a02636238b814946408b1322d5ac4760326e6fb8ec956d85775"
+
+
[[package]]
+
name = "async-trait"
+
version = "0.1.83"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "721cae7de5c34fbb2acd27e21e6d2cf7b886dce0c27388d46c4e6c47ea4318dd"
+
dependencies = [
+
"proc-macro2",
+
"quote",
+
"syn 2.0.87",
+
]
+
+
[[package]]
+
name = "atrium-api"
+
version = "0.24.7"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "ee68ddf7cde9eb121eed3a28b138f6a9b4c4a90ab0c5c2e38bc2817af0b06da3"
+
dependencies = [
+
"atrium-xrpc",
+
"chrono",
+
"http",
+
"ipld-core",
+
"langtag",
+
"regex",
+
"serde",
+
"serde_bytes",
+
"serde_json",
+
"thiserror 1.0.69",
+
"trait-variant",
+
]
+
+
[[package]]
+
name = "atrium-xrpc"
+
version = "0.11.6"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "737eea1de2eb174bbfe720619cb25a22c30b9640ae0d3b78386cedf007712963"
+
dependencies = [
+
"http",
+
"serde",
+
"serde_html_form",
+
"serde_json",
+
"thiserror 1.0.69",
+
"trait-variant",
+
]
+
+
[[package]]
+
name = "autocfg"
+
version = "1.4.0"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26"
+
+
[[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",
+
]
+
+
[[package]]
+
name = "base-x"
+
version = "0.2.11"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "4cbbc9d0964165b47557570cce6c952866c2678457aca742aafc9fb771d30270"
+
+
[[package]]
+
name = "bitflags"
+
version = "2.6.0"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de"
+
+
[[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.16.0"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c"
+
+
[[package]]
+
name = "byteorder"
+
version = "1.5.0"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
+
+
[[package]]
+
name = "bytes"
+
version = "1.9.0"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "325918d6fe32f23b19878fe4b34794ae41fc19ddbe53b10571a4874d44ffd39b"
+
+
[[package]]
+
name = "cc"
+
version = "1.2.0"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "1aeb932158bd710538c73702db6945cb68a8fb08c519e6e12706b94263b36db8"
+
dependencies = [
+
"jobserver",
+
"libc",
+
"shlex",
+
]
+
+
[[package]]
+
name = "cfg-if"
+
version = "1.0.0"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
+
+
[[package]]
+
name = "chrono"
+
version = "0.4.38"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401"
+
dependencies = [
+
"android-tzdata",
+
"iana-time-zone",
+
"js-sys",
+
"num-traits",
+
"serde",
+
"wasm-bindgen",
+
"windows-targets",
+
]
+
+
[[package]]
+
name = "cid"
+
version = "0.11.1"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "3147d8272e8fa0ccd29ce51194dd98f79ddfb8191ba9e3409884e751798acf3a"
+
dependencies = [
+
"core2",
+
"multibase",
+
"multihash",
+
"serde",
+
"serde_bytes",
+
"unsigned-varint",
+
]
+
+
[[package]]
+
name = "clap"
+
version = "4.5.21"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "fb3b4b9e5a7c7514dfa52869339ee98b3156b0bfb4e8a77c4ff4babb64b1604f"
+
dependencies = [
+
"clap_builder",
+
"clap_derive",
+
]
+
+
[[package]]
+
name = "clap_builder"
+
version = "4.5.21"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "b17a95aa67cc7b5ebd32aa5370189aa0d79069ef1c64ce893bd30fb24bff20ec"
+
dependencies = [
+
"anstream",
+
"anstyle",
+
"clap_lex",
+
"strsim",
+
]
+
+
[[package]]
+
name = "clap_derive"
+
version = "4.5.18"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "4ac6a0c7b1a9e9a5186361f67dfa1b88213572f427fb9ab038efb2bd8c582dab"
+
dependencies = [
+
"heck",
+
"proc-macro2",
+
"quote",
+
"syn 2.0.87",
+
]
+
+
[[package]]
+
name = "clap_lex"
+
version = "0.7.3"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "afb84c814227b90d6895e01398aee0d8033c00e7466aca416fb6a8e0eb19d8a7"
+
+
[[package]]
+
name = "colorchoice"
+
version = "1.0.3"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990"
+
+
[[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-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.15"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "0ca741a962e1b0bff6d724a1a0958b686406e853bb14061f218562e1896f95e6"
+
dependencies = [
+
"libc",
+
]
+
+
[[package]]
+
name = "crypto-common"
+
version = "0.1.6"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3"
+
dependencies = [
+
"generic-array",
+
"typenum",
+
]
+
+
[[package]]
+
name = "data-encoding"
+
version = "2.6.0"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "e8566979429cf69b49a5c740c60791108e86440e8be149bbea4fe54d2c32d6e2"
+
+
[[package]]
+
name = "data-encoding-macro"
+
version = "0.1.15"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "f1559b6cba622276d6d63706db152618eeb15b89b3e4041446b05876e352e639"
+
dependencies = [
+
"data-encoding",
+
"data-encoding-macro-internal",
+
]
+
+
[[package]]
+
name = "data-encoding-macro-internal"
+
version = "0.1.13"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "332d754c0af53bc87c108fed664d121ecf59207ec4196041f04d6ab9002ad33f"
+
dependencies = [
+
"data-encoding",
+
"syn 1.0.109",
+
]
+
+
[[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.87",
+
]
+
+
[[package]]
+
name = "equivalent"
+
version = "1.0.1"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5"
+
+
[[package]]
+
name = "errno"
+
version = "0.3.9"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba"
+
dependencies = [
+
"libc",
+
"windows-sys 0.52.0",
+
]
+
+
[[package]]
+
name = "fastrand"
+
version = "2.2.0"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "486f806e73c5707928240ddc295403b1b93c96a02038563881c4a2fd84b81ac4"
+
+
[[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 = "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.1"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456"
+
dependencies = [
+
"percent-encoding",
+
]
+
+
[[package]]
+
name = "futures-core"
+
version = "0.3.31"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e"
+
+
[[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.87",
+
]
+
+
[[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-core",
+
"futures-macro",
+
"futures-sink",
+
"futures-task",
+
"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.15"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7"
+
dependencies = [
+
"cfg-if",
+
"js-sys",
+
"libc",
+
"wasi",
+
"wasm-bindgen",
+
]
+
+
[[package]]
+
name = "gimli"
+
version = "0.31.1"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f"
+
+
[[package]]
+
name = "hashbrown"
+
version = "0.15.1"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "3a9bfc1af68b1726ea47d3d5109de126281def866b33970e10fbab11b5dafab3"
+
+
[[package]]
+
name = "heck"
+
version = "0.5.0"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
+
+
[[package]]
+
name = "hermit-abi"
+
version = "0.3.9"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024"
+
+
[[package]]
+
name = "http"
+
version = "1.1.0"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "21b9ddb458710bc376481b842f5da65cdf31522de232c1ca8146abce2a358258"
+
dependencies = [
+
"bytes",
+
"fnv",
+
"itoa",
+
]
+
+
[[package]]
+
name = "httparse"
+
version = "1.9.5"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "7d71d3574edd2771538b901e6549113b4006ece66150fb69c0fb6d9a2adae946"
+
+
[[package]]
+
name = "iana-time-zone"
+
version = "0.1.61"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "235e081f3925a06703c2d0117ea8b91f042756fd6e7a6e5d901e8ca1a996b220"
+
dependencies = [
+
"android_system_properties",
+
"core-foundation-sys",
+
"iana-time-zone-haiku",
+
"js-sys",
+
"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 = "1.5.0"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "db2fa452206ebee18c4b5c2274dbf1de17008e874b4dc4f0aea9d01ca79e4526"
+
dependencies = [
+
"displaydoc",
+
"yoke",
+
"zerofrom",
+
"zerovec",
+
]
+
+
[[package]]
+
name = "icu_locid"
+
version = "1.5.0"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "13acbb8371917fc971be86fc8057c41a64b521c184808a698c02acc242dbf637"
+
dependencies = [
+
"displaydoc",
+
"litemap",
+
"tinystr",
+
"writeable",
+
"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"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "19ce3e0da2ec68599d193c93d088142efd7f9c5d6fc9b803774855747dc6a84f"
+
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"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "f8cafbf7aa791e9b22bec55a167906f9e1215fd475cd22adfcf660e03e989516"
+
+
[[package]]
+
name = "icu_properties"
+
version = "1.5.1"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "93d6020766cfc6302c15dbbc9c8778c37e62c14427cb7f6e601d849e092aeef5"
+
dependencies = [
+
"displaydoc",
+
"icu_collections",
+
"icu_locid_transform",
+
"icu_properties_data",
+
"icu_provider",
+
"tinystr",
+
"zerovec",
+
]
+
+
[[package]]
+
name = "icu_properties_data"
+
version = "1.5.0"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "67a8effbc3dd3e4ba1afa8ad918d5684b8868b3b26500753effea8d2eed19569"
+
+
[[package]]
+
name = "icu_provider"
+
version = "1.5.0"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "6ed421c8a8ef78d3e2dbc98a973be2f3770cb42b606e3ab18d6237c4dfde68d9"
+
dependencies = [
+
"displaydoc",
+
"icu_locid",
+
"icu_provider_macros",
+
"stable_deref_trait",
+
"tinystr",
+
"writeable",
+
"yoke",
+
"zerofrom",
+
"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.87",
+
]
+
+
[[package]]
+
name = "idna"
+
version = "1.0.3"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "686f825264d630750a544639377bae737628043f20d38bbc029e8f29ea968a7e"
+
dependencies = [
+
"idna_adapter",
+
"smallvec",
+
"utf8_iter",
+
]
+
+
[[package]]
+
name = "idna_adapter"
+
version = "1.2.0"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "daca1df1c957320b2cf139ac61e7bd64fed304c5040df000a745aa1de3b4ef71"
+
dependencies = [
+
"icu_normalizer",
+
"icu_properties",
+
]
+
+
[[package]]
+
name = "indexmap"
+
version = "2.6.0"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "707907fe3c25f5424cce2cb7e1cbcafee6bdbe735ca90ef77c29e84591e5b9da"
+
dependencies = [
+
"equivalent",
+
"hashbrown",
+
]
+
+
[[package]]
+
name = "ipld-core"
+
version = "0.4.1"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "b4ede82a79e134f179f4b29b5fdb1eb92bd1b38c4dfea394c539051150a21b9b"
+
dependencies = [
+
"cid",
+
"serde",
+
"serde_bytes",
+
]
+
+
[[package]]
+
name = "is_terminal_polyfill"
+
version = "1.70.1"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf"
+
+
[[package]]
+
name = "itoa"
+
version = "1.0.11"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b"
+
+
[[package]]
+
name = "jetstream-oxide"
+
version = "0.1.1"
+
dependencies = [
+
"anyhow",
+
"async-trait",
+
"atrium-api",
+
"chrono",
+
"clap",
+
"flume",
+
"futures-util",
+
"log",
+
"serde",
+
"serde_json",
+
"thiserror 2.0.11",
+
"tokio",
+
"tokio-tungstenite",
+
"tokio-util",
+
"url",
+
"zstd",
+
]
+
+
[[package]]
+
name = "jobserver"
+
version = "0.1.32"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "48d1dbcbbeb6a7fec7e059840aa538bd62aaccf972c7346c4d9d2059312853d0"
+
dependencies = [
+
"libc",
+
]
+
+
[[package]]
+
name = "js-sys"
+
version = "0.3.72"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "6a88f1bda2bd75b0452a14784937d796722fdebfe50df998aeb3f0b7603019a9"
+
dependencies = [
+
"wasm-bindgen",
+
]
+
+
[[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.162"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "18d287de67fe55fd7e1581fe933d965a5a9477b38e949cfa9f8574ef01506398"
+
+
[[package]]
+
name = "linux-raw-sys"
+
version = "0.4.14"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89"
+
+
[[package]]
+
name = "litemap"
+
version = "0.7.3"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "643cb0b8d4fcc284004d5fd0d67ccf61dfffadb7f75e1e71bc420f4688a3a704"
+
+
[[package]]
+
name = "lock_api"
+
version = "0.4.12"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17"
+
dependencies = [
+
"autocfg",
+
"scopeguard",
+
]
+
+
[[package]]
+
name = "log"
+
version = "0.4.22"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24"
+
+
[[package]]
+
name = "memchr"
+
version = "2.7.4"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
+
+
[[package]]
+
name = "miniz_oxide"
+
version = "0.8.0"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "e2d80299ef12ff69b16a84bb182e3b9df68b5a91574d3d4fa6e41b65deec4df1"
+
dependencies = [
+
"adler2",
+
]
+
+
[[package]]
+
name = "mio"
+
version = "1.0.2"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "80e04d1dcff3aae0704555fe5fee3bcfaf3d1fdf8a7e521d5b9d2b42acb52cec"
+
dependencies = [
+
"hermit-abi",
+
"libc",
+
"wasi",
+
"windows-sys 0.52.0",
+
]
+
+
[[package]]
+
name = "multibase"
+
version = "0.9.1"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "9b3539ec3c1f04ac9748a260728e855f261b4977f5c3406612c884564f329404"
+
dependencies = [
+
"base-x",
+
"data-encoding",
+
"data-encoding-macro",
+
]
+
+
[[package]]
+
name = "multihash"
+
version = "0.19.2"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "cc41f430805af9d1cf4adae4ed2149c759b877b01d909a1f40256188d09345d2"
+
dependencies = [
+
"core2",
+
"serde",
+
"unsigned-varint",
+
]
+
+
[[package]]
+
name = "nanorand"
+
version = "0.7.0"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "6a51313c5820b0b02bd422f4b44776fbf47961755c74ce64afc73bfad10226c3"
+
dependencies = [
+
"getrandom",
+
]
+
+
[[package]]
+
name = "native-tls"
+
version = "0.2.12"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "a8614eb2c83d59d1c8cc974dd3f920198647674a0a035e1af1fa58707e317466"
+
dependencies = [
+
"libc",
+
"log",
+
"openssl",
+
"openssl-probe",
+
"openssl-sys",
+
"schannel",
+
"security-framework",
+
"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.36.5"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "aedf0a2d09c573ed1d8d85b30c119153926a2b36dce0ab28322c09a117a4683e"
+
dependencies = [
+
"memchr",
+
]
+
+
[[package]]
+
name = "once_cell"
+
version = "1.20.2"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775"
+
+
[[package]]
+
name = "openssl"
+
version = "0.10.68"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "6174bc48f102d208783c2c84bf931bb75927a617866870de8a4ea85597f871f5"
+
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.87",
+
]
+
+
[[package]]
+
name = "openssl-probe"
+
version = "0.1.5"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf"
+
+
[[package]]
+
name = "openssl-src"
+
version = "300.4.0+3.4.0"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "a709e02f2b4aca747929cca5ed248880847c650233cf8b8cdc48f40aaf4898a6"
+
dependencies = [
+
"cc",
+
]
+
+
[[package]]
+
name = "openssl-sys"
+
version = "0.9.104"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "45abf306cbf99debc8195b66b7346498d7b10c210de50418b5ccd7ceba08c741"
+
dependencies = [
+
"cc",
+
"libc",
+
"openssl-src",
+
"pkg-config",
+
"vcpkg",
+
]
+
+
[[package]]
+
name = "parking_lot"
+
version = "0.12.3"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27"
+
dependencies = [
+
"lock_api",
+
"parking_lot_core",
+
]
+
+
[[package]]
+
name = "parking_lot_core"
+
version = "0.9.10"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8"
+
dependencies = [
+
"cfg-if",
+
"libc",
+
"redox_syscall",
+
"smallvec",
+
"windows-targets",
+
]
+
+
[[package]]
+
name = "percent-encoding"
+
version = "2.3.1"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e"
+
+
[[package]]
+
name = "pin-project-lite"
+
version = "0.2.15"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "915a1e146535de9163f3987b8944ed8cf49a18bb0056bcebcdcece385cece4ff"
+
+
[[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.31"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "953ec861398dccce10c670dfeaf3ec4911ca479e9c02154b3a215178c5f566f2"
+
+
[[package]]
+
name = "ppv-lite86"
+
version = "0.2.20"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04"
+
dependencies = [
+
"zerocopy",
+
]
+
+
[[package]]
+
name = "proc-macro2"
+
version = "1.0.89"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "f139b0662de085916d1fb67d2b4169d1addddda1919e696f3252b740b629986e"
+
dependencies = [
+
"unicode-ident",
+
]
+
+
[[package]]
+
name = "quote"
+
version = "1.0.37"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af"
+
dependencies = [
+
"proc-macro2",
+
]
+
+
[[package]]
+
name = "rand"
+
version = "0.8.5"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
+
dependencies = [
+
"libc",
+
"rand_chacha",
+
"rand_core",
+
]
+
+
[[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",
+
]
+
+
[[package]]
+
name = "rand_core"
+
version = "0.6.4"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
+
dependencies = [
+
"getrandom",
+
]
+
+
[[package]]
+
name = "redox_syscall"
+
version = "0.5.7"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "9b6dfecf2c74bce2466cabf93f6664d6998a69eb21e39f4207930065b27b771f"
+
dependencies = [
+
"bitflags",
+
]
+
+
[[package]]
+
name = "regex"
+
version = "1.11.1"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191"
+
dependencies = [
+
"aho-corasick",
+
"memchr",
+
"regex-automata",
+
"regex-syntax",
+
]
+
+
[[package]]
+
name = "regex-automata"
+
version = "0.4.9"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908"
+
dependencies = [
+
"aho-corasick",
+
"memchr",
+
"regex-syntax",
+
]
+
+
[[package]]
+
name = "regex-syntax"
+
version = "0.8.5"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c"
+
+
[[package]]
+
name = "rustc-demangle"
+
version = "0.1.24"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f"
+
+
[[package]]
+
name = "rustix"
+
version = "0.38.40"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "99e4ea3e1cdc4b559b8e5650f9c8e5998e3e5c1343b4eaf034565f32318d63c0"
+
dependencies = [
+
"bitflags",
+
"errno",
+
"libc",
+
"linux-raw-sys",
+
"windows-sys 0.52.0",
+
]
+
+
[[package]]
+
name = "ryu"
+
version = "1.0.18"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f"
+
+
[[package]]
+
name = "schannel"
+
version = "0.1.26"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "01227be5826fa0690321a2ba6c5cd57a19cf3f6a09e76973b58e61de6ab9d1c1"
+
dependencies = [
+
"windows-sys 0.59.0",
+
]
+
+
[[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",
+
"core-foundation-sys",
+
"libc",
+
"security-framework-sys",
+
]
+
+
[[package]]
+
name = "security-framework-sys"
+
version = "2.12.1"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "fa39c7303dc58b5543c94d22c1766b0d31f2ee58306363ea622b10bbc075eaa2"
+
dependencies = [
+
"core-foundation-sys",
+
"libc",
+
]
+
+
[[package]]
+
name = "serde"
+
version = "1.0.215"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "6513c1ad0b11a9376da888e3e0baa0077f1aed55c17f50e7b2397136129fb88f"
+
dependencies = [
+
"serde_derive",
+
]
+
+
[[package]]
+
name = "serde_bytes"
+
version = "0.11.15"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "387cc504cb06bb40a96c8e04e951fe01854cf6bc921053c954e4a606d9675c6a"
+
dependencies = [
+
"serde",
+
]
+
+
[[package]]
+
name = "serde_derive"
+
version = "1.0.215"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "ad1e866f866923f252f05c889987993144fb74e722403468a4ebd70c3cd756c0"
+
dependencies = [
+
"proc-macro2",
+
"quote",
+
"syn 2.0.87",
+
]
+
+
[[package]]
+
name = "serde_html_form"
+
version = "0.2.6"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "8de514ef58196f1fc96dcaef80fe6170a1ce6215df9687a93fe8300e773fefc5"
+
dependencies = [
+
"form_urlencoded",
+
"indexmap",
+
"itoa",
+
"ryu",
+
"serde",
+
]
+
+
[[package]]
+
name = "serde_json"
+
version = "1.0.132"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "d726bfaff4b320266d395898905d0eba0345aae23b54aee3a737e260fd46db03"
+
dependencies = [
+
"itoa",
+
"memchr",
+
"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 = "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.2"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "a9e9e0b4211b72e7b8b6e85c807d36c212bdb33ea8587f7569562a84df5465b1"
+
dependencies = [
+
"libc",
+
]
+
+
[[package]]
+
name = "slab"
+
version = "0.4.9"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67"
+
dependencies = [
+
"autocfg",
+
]
+
+
[[package]]
+
name = "smallvec"
+
version = "1.13.2"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67"
+
+
[[package]]
+
name = "socket2"
+
version = "0.5.7"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "ce305eb0b4296696835b71df73eb912e0f1ffd2556a501fcede6e0c50349191c"
+
dependencies = [
+
"libc",
+
"windows-sys 0.52.0",
+
]
+
+
[[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.0"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3"
+
+
[[package]]
+
name = "strsim"
+
version = "0.11.1"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f"
+
+
[[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.87"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "25aa4ce346d03a6dcd68dd8b4010bcb74e54e62c90c573f394c46eae99aba32d"
+
dependencies = [
+
"proc-macro2",
+
"quote",
+
"unicode-ident",
+
]
+
+
[[package]]
+
name = "synstructure"
+
version = "0.13.1"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971"
+
dependencies = [
+
"proc-macro2",
+
"quote",
+
"syn 2.0.87",
+
]
+
+
[[package]]
+
name = "tempfile"
+
version = "3.14.0"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "28cce251fcbc87fac86a866eeb0d6c2d536fc16d06f184bb61aeae11aa4cee0c"
+
dependencies = [
+
"cfg-if",
+
"fastrand",
+
"once_cell",
+
"rustix",
+
"windows-sys 0.59.0",
+
]
+
+
[[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.11"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "d452f284b73e6d76dd36758a0c8684b1d5be31f92b89d07fd5822175732206fc"
+
dependencies = [
+
"thiserror-impl 2.0.11",
+
]
+
+
[[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.87",
+
]
+
+
[[package]]
+
name = "thiserror-impl"
+
version = "2.0.11"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "26afc1baea8a989337eeb52b6e72a039780ce45c3edfcc9c5b9d112feeb173c2"
+
dependencies = [
+
"proc-macro2",
+
"quote",
+
"syn 2.0.87",
+
]
+
+
[[package]]
+
name = "tinystr"
+
version = "0.7.6"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "9117f5d4db391c1cf6927e7bea3db74b9a1c1add8f7eda9ffd5364f40f57b82f"
+
dependencies = [
+
"displaydoc",
+
"zerovec",
+
]
+
+
[[package]]
+
name = "tokio"
+
version = "1.41.1"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "22cfb5bee7a6a52939ca9224d6ac897bb669134078daa8735560897f69de4d33"
+
dependencies = [
+
"backtrace",
+
"bytes",
+
"libc",
+
"mio",
+
"parking_lot",
+
"pin-project-lite",
+
"signal-hook-registry",
+
"socket2",
+
"tokio-macros",
+
"windows-sys 0.52.0",
+
]
+
+
[[package]]
+
name = "tokio-macros"
+
version = "2.4.0"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752"
+
dependencies = [
+
"proc-macro2",
+
"quote",
+
"syn 2.0.87",
+
]
+
+
[[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-tungstenite"
+
version = "0.24.0"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "edc5f74e248dc973e0dbb7b74c7e0d6fcc301c694ff50049504004ef4d0cdcd9"
+
dependencies = [
+
"futures-util",
+
"log",
+
"native-tls",
+
"tokio",
+
"tokio-native-tls",
+
"tungstenite",
+
]
+
+
[[package]]
+
name = "tokio-util"
+
version = "0.7.13"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "d7fcaa8d55a2bdd6b83ace262b016eca0d79ee02818c5c1bcdf0305114081078"
+
dependencies = [
+
"bytes",
+
"futures-core",
+
"futures-sink",
+
"pin-project-lite",
+
"tokio",
+
]
+
+
[[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.87",
+
]
+
+
[[package]]
+
name = "tungstenite"
+
version = "0.24.0"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "18e5b8366ee7a95b16d32197d0b2604b43a0be89dc5fac9f8e96ccafbaedda8a"
+
dependencies = [
+
"byteorder",
+
"bytes",
+
"data-encoding",
+
"http",
+
"httparse",
+
"log",
+
"native-tls",
+
"rand",
+
"sha1",
+
"thiserror 1.0.69",
+
"url",
+
"utf-8",
+
]
+
+
[[package]]
+
name = "typenum"
+
version = "1.17.0"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825"
+
+
[[package]]
+
name = "unicode-ident"
+
version = "1.0.13"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe"
+
+
[[package]]
+
name = "unsigned-varint"
+
version = "0.8.0"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "eb066959b24b5196ae73cb057f45598450d2c5f71460e98c49b738086eff9c06"
+
+
[[package]]
+
name = "url"
+
version = "2.5.4"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "32f8b686cadd1473f4bd0117a5d28d36b1ade384ea9b5069a1c40aefed7fda60"
+
dependencies = [
+
"form_urlencoded",
+
"idna",
+
"percent-encoding",
+
]
+
+
[[package]]
+
name = "utf-8"
+
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"
+
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 = "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 = "wasi"
+
version = "0.11.0+wasi-snapshot-preview1"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
+
+
[[package]]
+
name = "wasm-bindgen"
+
version = "0.2.95"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "128d1e363af62632b8eb57219c8fd7877144af57558fb2ef0368d0087bddeb2e"
+
dependencies = [
+
"cfg-if",
+
"once_cell",
+
"wasm-bindgen-macro",
+
]
+
+
[[package]]
+
name = "wasm-bindgen-backend"
+
version = "0.2.95"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "cb6dd4d3ca0ddffd1dd1c9c04f94b868c37ff5fac97c30b97cff2d74fce3a358"
+
dependencies = [
+
"bumpalo",
+
"log",
+
"once_cell",
+
"proc-macro2",
+
"quote",
+
"syn 2.0.87",
+
"wasm-bindgen-shared",
+
]
+
+
[[package]]
+
name = "wasm-bindgen-macro"
+
version = "0.2.95"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "e79384be7f8f5a9dd5d7167216f022090cf1f9ec128e6e6a482a2cb5c5422c56"
+
dependencies = [
+
"quote",
+
"wasm-bindgen-macro-support",
+
]
+
+
[[package]]
+
name = "wasm-bindgen-macro-support"
+
version = "0.2.95"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "26c6ab57572f7a24a4985830b120de1594465e5d500f24afe89e16b4e833ef68"
+
dependencies = [
+
"proc-macro2",
+
"quote",
+
"syn 2.0.87",
+
"wasm-bindgen-backend",
+
"wasm-bindgen-shared",
+
]
+
+
[[package]]
+
name = "wasm-bindgen-shared"
+
version = "0.2.95"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "65fc09f10666a9f147042251e0dda9c18f166ff7de300607007e96bdebc1068d"
+
+
[[package]]
+
name = "windows-core"
+
version = "0.52.0"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9"
+
dependencies = [
+
"windows-targets",
+
]
+
+
[[package]]
+
name = "windows-sys"
+
version = "0.52.0"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
+
dependencies = [
+
"windows-targets",
+
]
+
+
[[package]]
+
name = "windows-sys"
+
version = "0.59.0"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b"
+
dependencies = [
+
"windows-targets",
+
]
+
+
[[package]]
+
name = "windows-targets"
+
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",
+
]
+
+
[[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_msvc"
+
version = "0.52.6"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
+
+
[[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_gnullvm"
+
version = "0.52.6"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
+
+
[[package]]
+
name = "windows_i686_msvc"
+
version = "0.52.6"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
+
+
[[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_gnullvm"
+
version = "0.52.6"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
+
+
[[package]]
+
name = "windows_x86_64_msvc"
+
version = "0.52.6"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
+
+
[[package]]
+
name = "write16"
+
version = "1.0.0"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "d1890f4022759daae28ed4fe62859b1236caebfc61ede2f63ed4e695f3f6d936"
+
+
[[package]]
+
name = "writeable"
+
version = "0.5.5"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "1e9df38ee2d2c3c5948ea468a8406ff0db0b29ae1ffde1bcf20ef305bcc95c51"
+
+
[[package]]
+
name = "yoke"
+
version = "0.7.4"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "6c5b1314b079b0930c31e3af543d8ee1757b1951ae1e1565ec704403a7240ca5"
+
dependencies = [
+
"serde",
+
"stable_deref_trait",
+
"yoke-derive",
+
"zerofrom",
+
]
+
+
[[package]]
+
name = "yoke-derive"
+
version = "0.7.4"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "28cc31741b18cb6f1d5ff12f5b7523e3d6eb0852bbbad19d73905511d9849b95"
+
dependencies = [
+
"proc-macro2",
+
"quote",
+
"syn 2.0.87",
+
"synstructure",
+
]
+
+
[[package]]
+
name = "zerocopy"
+
version = "0.7.35"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0"
+
dependencies = [
+
"byteorder",
+
"zerocopy-derive",
+
]
+
+
[[package]]
+
name = "zerocopy-derive"
+
version = "0.7.35"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e"
+
dependencies = [
+
"proc-macro2",
+
"quote",
+
"syn 2.0.87",
+
]
+
+
[[package]]
+
name = "zerofrom"
+
version = "0.1.4"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "91ec111ce797d0e0784a1116d0ddcdbea84322cd79e5d5ad173daeba4f93ab55"
+
dependencies = [
+
"zerofrom-derive",
+
]
+
+
[[package]]
+
name = "zerofrom-derive"
+
version = "0.1.4"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "0ea7b4a3637ea8669cedf0f1fd5c286a17f3de97b8dd5a70a6c167a1730e63a5"
+
dependencies = [
+
"proc-macro2",
+
"quote",
+
"syn 2.0.87",
+
"synstructure",
+
]
+
+
[[package]]
+
name = "zerovec"
+
version = "0.10.4"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "aa2b893d79df23bfb12d5461018d408ea19dfafe76c2c7ef6d4eba614f8ff079"
+
dependencies = [
+
"yoke",
+
"zerofrom",
+
"zerovec-derive",
+
]
+
+
[[package]]
+
name = "zerovec-derive"
+
version = "0.10.3"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "6eafa6dfb17584ea3e2bd6e76e0cc15ad7af12b09abdd1ca55961bed9b1063c6"
+
dependencies = [
+
"proc-macro2",
+
"quote",
+
"syn 2.0.87",
+
]
+
+
[[package]]
+
name = "zstd"
+
version = "0.13.2"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "fcf2b778a664581e31e389454a7072dab1647606d44f7feea22cd5abb9c9f3f9"
+
dependencies = [
+
"zstd-safe",
+
]
+
+
[[package]]
+
name = "zstd-safe"
+
version = "7.2.1"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "54a3ab4db68cea366acc5c897c7b4d4d1b8994a9cd6e6f841f8964566a419059"
+
dependencies = [
+
"zstd-sys",
+
]
+
+
[[package]]
+
name = "zstd-sys"
+
version = "2.0.13+zstd.1.5.6"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "38ff0f21cfee8f97d94cef41359e0c89aa6113028ab0291aa8ca0038995a95aa"
+
dependencies = [
+
"cc",
+
"pkg-config",
+
]
+35
jetstream/Cargo.toml
···
+
[package]
+
authors = ["videah <videah@selfish.systems>"]
+
name = "jetstream-oxide"
+
version = "0.1.1"
+
edition = "2021"
+
license = "MIT"
+
description = "Library for easily interacting with and consuming the Bluesky Jetstream service."
+
repository = "https://github.com/videah/jetstream-oxide"
+
readme = "README.md"
+
+
[dependencies]
+
async-trait = "0.1.83"
+
atrium-api = { version = "0.24.7", default-features = false, features = [
+
"namespace-appbsky",
+
] }
+
tokio = { version = "1.41.1", features = ["full", "sync", "time"] }
+
tokio-tungstenite = { version = "0.24.0", features = [
+
"connect",
+
"native-tls-vendored",
+
"url",
+
] }
+
futures-util = "0.3.31"
+
url = "2.5.4"
+
serde = { version = "1.0.215", features = ["derive"] }
+
serde_json = "1.0.132"
+
chrono = "0.4.38"
+
zstd = "0.13.2"
+
thiserror = "2.0.3"
+
flume = "0.11.1"
+
log = "0.4.22"
+
tokio-util = "0.7.13"
+
+
[dev-dependencies]
+
anyhow = "1.0.93"
+
clap = { version = "4.5.20", features = ["derive"] }
+21
jetstream/LICENSE
···
+
MIT License
+
+
Copyright (c) 2024 videah
+
+
Permission is hereby granted, free of charge, to any person obtaining a copy
+
of this software and associated documentation files (the "Software"), to deal
+
in the Software without restriction, including without limitation the rights
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+
copies of the Software, and to permit persons to whom the Software is
+
furnished to do so, subject to the following conditions:
+
+
The above copyright notice and this permission notice shall be included in all
+
copies or substantial portions of the Software.
+
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+
SOFTWARE.
+59
jetstream/README.md
···
+
# jetstream-oxide
+
+
[![Crate](https://img.shields.io/crates/v/jetstream-oxide.svg)](https://crates.io/crates/jetstream-oxide)
+
[![docs.rs](https://docs.rs/jetstream-oxide/badge.svg)](https://docs.rs/jetstream-oxide/latest/jetstream_oxide)
+
+
A typed Rust library for easily interacting with and consuming the
+
Bluesky [Jetstream](https://github.com/bluesky-social/jetstream)
+
service.
+
+
```rust
+
let config = JetstreamConfig {
+
endpoint: DefaultJetstreamEndpoints::USEastOne.into(),
+
compression: JetstreamCompression::Zstd,
+
..Default::default()
+
};
+
+
let jetstream = JetstreamConnector::new(config).unwrap();
+
let receiver = jetstream.connect().await?;
+
+
while let Ok(event) = receiver.recv_async().await {
+
if let Commit(commit) = event {
+
match commit {
+
CommitEvent::Create { info, commit } => {
+
println!("Received create event: {:#?}", info);
+
}
+
CommitEvent::Update { info, commit } => {
+
println!("Received update event: {:#?}", info);
+
}
+
CommitEvent::Delete { info, commit } => {
+
println!("Received delete event: {:#?}", info);
+
}
+
}
+
}
+
}
+
```
+
+
## Example
+
+
A small example CLI utility to show how to use this crate can be found in the `examples` directory. To run it, use the
+
following command:
+
+
```sh
+
cargo run --example basic -- --nsid "app.bsky.feed.post"
+
```
+
+
This will display a real-time feed of every single post that is being made or deleted in the entire Bluesky network,
+
right in your terminal!
+
+
You can filter it down to just specific accounts like this:
+
+
```sh
+
cargo run --example basic -- \
+
--nsid "app.bsky.feed.post" \
+
--did "did:plc:inze6wrmsm7pjl7yta3oig77"
+
```
+
+
This listens for posts that *I personally make*. You can substitute your own DID and make a few test posts yourself if
+
you'd
+
like of course!
+63
jetstream/examples/basic.rs
···
+
//! A very basic example of how to listen for create/delete events on a specific DID and NSID.
+
+
use atrium_api::{record::KnownRecord::AppBskyFeedPost, types::string};
+
use clap::Parser;
+
use jetstream_oxide::{
+
events::{commit::CommitEvent, JetstreamEvent::Commit},
+
DefaultJetstreamEndpoints, JetstreamCompression, JetstreamConfig, JetstreamConnector,
+
};
+
+
#[derive(Parser, Debug)]
+
#[command(version, about, long_about = None)]
+
struct Args {
+
/// The DIDs to listen for events on, if not provided we will listen for all DIDs.
+
#[arg(short, long)]
+
did: Option<Vec<string::Did>>,
+
/// The NSID for the collection to listen for (e.g. `app.bsky.feed.post`).
+
#[arg(short, long)]
+
nsid: string::Nsid,
+
}
+
+
#[tokio::main]
+
async fn main() -> anyhow::Result<()> {
+
let args = Args::parse();
+
+
let dids = args.did.unwrap_or_default();
+
let config = JetstreamConfig {
+
endpoint: DefaultJetstreamEndpoints::USEastOne.into(),
+
wanted_collections: vec![args.nsid.clone()],
+
wanted_dids: dids.clone(),
+
compression: JetstreamCompression::Zstd,
+
cursor: None,
+
};
+
+
let jetstream = JetstreamConnector::new(config)?;
+
let receiver = jetstream.connect().await?;
+
+
println!(
+
"Listening for '{}' events on DIDs: {:?}",
+
args.nsid.to_string(),
+
dids,
+
);
+
+
while let Ok(event) = receiver.recv_async().await {
+
if let Commit(commit) = event {
+
match commit {
+
CommitEvent::Create { info: _, commit } => {
+
if let AppBskyFeedPost(record) = commit.record {
+
println!(
+
"New post created! ({})\n\n'{}'",
+
commit.info.rkey, record.text
+
);
+
}
+
}
+
CommitEvent::Delete { info: _, commit } => {
+
println!("A post has been deleted. ({})", commit.rkey);
+
}
+
_ => {}
+
}
+
}
+
}
+
+
Ok(())
+
}
+6
jetstream/rustfmt.toml
···
+
group_imports = "StdExternalCrate"
+
comment_width = 100
+
format_code_in_doc_comments = true
+
imports_granularity = "Crate"
+
imports_layout = "Vertical"
+
wrap_comments = true
+43
jetstream/src/error.rs
···
+
//! Various error types.
+
use std::io;
+
+
use thiserror::Error;
+
+
/// Possible errors that can occur when a [JetstreamConfig](crate::JetstreamConfig) that is passed
+
/// to a [JetstreamConnector](crate::JetstreamConnector) is invalid.
+
#[derive(Error, Debug)]
+
pub enum ConfigValidationError {
+
#[error("too many wanted collections: {0} > 100")]
+
TooManyWantedCollections(usize),
+
#[error("too many wanted DIDs: {0} > 10,000")]
+
TooManyDids(usize),
+
}
+
+
/// Possible errors that can occur in the process of connecting to a Jetstream instance over
+
/// WebSockets.
+
///
+
/// See [JetstreamConnector::connect](crate::JetstreamConnector::connect).
+
#[derive(Error, Debug)]
+
pub enum ConnectionError {
+
#[error("invalid endpoint: {0}")]
+
InvalidEndpoint(#[from] url::ParseError),
+
#[error("failed to connect to Jetstream instance: {0}")]
+
WebSocketFailure(#[from] tokio_tungstenite::tungstenite::Error),
+
#[error("the Jetstream config is invalid (this really should not happen here): {0}")]
+
InvalidConfig(#[from] ConfigValidationError),
+
}
+
+
/// Possible errors that can occur when receiving events from a Jetstream instance over WebSockets.
+
///
+
/// See [websocket_task](crate::websocket_task).
+
#[derive(Error, Debug)]
+
pub enum JetstreamEventError {
+
#[error("received websocket message that could not be deserialized as JSON: {0}")]
+
ReceivedMalformedJSON(#[from] serde_json::Error),
+
#[error("failed to load built-in zstd dictionary for decoding: {0}")]
+
CompressionDictionaryError(io::Error),
+
#[error("failed to decode zstd-compressed message: {0}")]
+
CompressionDecoderError(io::Error),
+
#[error("all receivers were dropped but the websocket connection failed to close cleanly")]
+
WebSocketCloseFailure,
+
}
+40
jetstream/src/events/account.rs
···
+
use chrono::Utc;
+
use serde::Deserialize;
+
+
use crate::{
+
events::EventInfo,
+
exports,
+
};
+
+
/// An event representing a change to an account.
+
#[derive(Deserialize, Debug)]
+
pub struct AccountEvent {
+
/// Basic metadata included with every event.
+
#[serde(flatten)]
+
pub info: EventInfo,
+
/// Account specific data bundled with this event.
+
pub account: AccountData,
+
}
+
+
/// Account specific data bundled with an account event.
+
#[derive(Deserialize, Debug)]
+
pub struct AccountData {
+
/// Whether the account is currently active.
+
pub active: bool,
+
/// The DID of the account.
+
pub did: exports::Did,
+
pub seq: u64,
+
pub time: chrono::DateTime<Utc>,
+
/// If `active` is `false` this will be present to explain why the account is inactive.
+
pub status: Option<AccountStatus>,
+
}
+
+
/// The possible reasons an account might be listed as inactive.
+
#[derive(Deserialize, Debug)]
+
#[serde(rename_all = "lowercase")]
+
pub enum AccountStatus {
+
Deactivated,
+
Deleted,
+
Suspended,
+
TakenDown,
+
}
+61
jetstream/src/events/commit.rs
···
+
use atrium_api::record::KnownRecord;
+
use serde::Deserialize;
+
+
use crate::{
+
events::EventInfo,
+
exports,
+
};
+
+
/// An event representing a repo commit, which can be a `create`, `update`, or `delete` operation.
+
#[derive(Deserialize, Debug)]
+
#[serde(untagged, rename_all = "snake_case")]
+
pub enum CommitEvent {
+
Create {
+
#[serde(flatten)]
+
info: EventInfo,
+
commit: CommitData,
+
},
+
Update {
+
#[serde(flatten)]
+
info: EventInfo,
+
commit: CommitData,
+
},
+
Delete {
+
#[serde(flatten)]
+
info: EventInfo,
+
commit: CommitInfo,
+
},
+
}
+
+
/// The type of commit operation that was performed.
+
#[derive(Deserialize, Debug)]
+
#[serde(rename_all = "snake_case")]
+
pub enum CommitType {
+
Create,
+
Update,
+
Delete,
+
}
+
+
/// Basic commit specific info bundled with every event, also the only data included with a `delete`
+
/// operation.
+
#[derive(Deserialize, Debug)]
+
pub struct CommitInfo {
+
/// The type of commit operation that was performed.
+
pub operation: CommitType,
+
pub rev: String,
+
pub rkey: String,
+
/// The NSID of the record type that this commit is associated with.
+
pub collection: exports::Nsid,
+
}
+
+
/// Detailed data bundled with a commit event. This data is only included when the event is
+
/// `create` or `update`.
+
#[derive(Deserialize, Debug)]
+
pub struct CommitData {
+
#[serde(flatten)]
+
pub info: CommitInfo,
+
/// The CID of the record that was operated on.
+
pub cid: exports::Cid,
+
/// The record that was operated on.
+
pub record: KnownRecord,
+
}
+28
jetstream/src/events/identity.rs
···
+
use chrono::Utc;
+
use serde::Deserialize;
+
+
use crate::{
+
events::EventInfo,
+
exports,
+
};
+
+
/// An event representing a change to an identity.
+
#[derive(Deserialize, Debug)]
+
pub struct IdentityEvent {
+
/// Basic metadata included with every event.
+
#[serde(flatten)]
+
pub info: EventInfo,
+
/// Identity specific data bundled with this event.
+
pub identity: IdentityData,
+
}
+
+
/// Identity specific data bundled with an identity event.
+
#[derive(Deserialize, Debug)]
+
pub struct IdentityData {
+
/// The DID of the identity.
+
pub did: exports::Did,
+
/// The handle associated with the identity.
+
pub handle: Option<exports::Handle>,
+
pub seq: u64,
+
pub time: chrono::DateTime<Utc>,
+
}
+31
jetstream/src/events/mod.rs
···
+
pub mod account;
+
pub mod commit;
+
pub mod identity;
+
+
use serde::Deserialize;
+
+
use crate::exports;
+
+
/// Basic data that is included with every event.
+
#[derive(Deserialize, Debug)]
+
pub struct EventInfo {
+
pub did: exports::Did,
+
pub time_us: u64,
+
pub kind: EventKind,
+
}
+
+
#[derive(Deserialize, Debug)]
+
#[serde(untagged)]
+
pub enum JetstreamEvent {
+
Commit(commit::CommitEvent),
+
Identity(identity::IdentityEvent),
+
Account(account::AccountEvent),
+
}
+
+
#[derive(Deserialize, Debug)]
+
#[serde(rename_all = "snake_case")]
+
pub enum EventKind {
+
Commit,
+
Identity,
+
Account,
+
}
+8
jetstream/src/exports.rs
···
+
//! Useful exports for third-party crates used by this project.
+
+
pub use atrium_api::types::string::{
+
Cid,
+
Did,
+
Handle,
+
Nsid,
+
};
+367
jetstream/src/lib.rs
···
+
pub mod error;
+
pub mod events;
+
pub mod exports;
+
+
use std::{
+
io::{Cursor, Read},
+
sync::Arc,
+
time::Duration,
+
};
+
+
use chrono::Utc;
+
use futures_util::{stream::StreamExt, SinkExt};
+
use tokio::{net::TcpStream, sync::Mutex};
+
use tokio_tungstenite::{connect_async, tungstenite::Message, MaybeTlsStream, WebSocketStream};
+
use tokio_util::sync::CancellationToken;
+
use url::Url;
+
use zstd::dict::DecoderDictionary;
+
+
use crate::{
+
error::{ConfigValidationError, ConnectionError, JetstreamEventError},
+
events::JetstreamEvent,
+
};
+
+
/// The Jetstream endpoints officially provided by Bluesky themselves.
+
///
+
/// There are no guarantees that these endpoints will always be available, but you are free
+
/// to run your own Jetstream instance in any case.
+
pub enum DefaultJetstreamEndpoints {
+
/// `jetstream1.us-east.bsky.network`
+
USEastOne,
+
/// `jetstream2.us-east.bsky.network`
+
USEastTwo,
+
/// `jetstream1.us-west.bsky.network`
+
USWestOne,
+
/// `jetstream2.us-west.bsky.network`
+
USWestTwo,
+
}
+
+
impl From<DefaultJetstreamEndpoints> for String {
+
fn from(endpoint: DefaultJetstreamEndpoints) -> Self {
+
match endpoint {
+
DefaultJetstreamEndpoints::USEastOne => {
+
"wss://jetstream1.us-east.bsky.network/subscribe".to_owned()
+
}
+
DefaultJetstreamEndpoints::USEastTwo => {
+
"wss://jetstream2.us-east.bsky.network/subscribe".to_owned()
+
}
+
DefaultJetstreamEndpoints::USWestOne => {
+
"wss://jetstream1.us-west.bsky.network/subscribe".to_owned()
+
}
+
DefaultJetstreamEndpoints::USWestTwo => {
+
"wss://jetstream2.us-west.bsky.network/subscribe".to_owned()
+
}
+
}
+
}
+
}
+
+
/// The maximum number of wanted collections that can be requested on a single Jetstream connection.
+
const MAX_WANTED_COLLECTIONS: usize = 100;
+
/// The maximum number of wanted DIDs that can be requested on a single Jetstream connection.
+
const MAX_WANTED_DIDS: usize = 10_000;
+
+
/// The custom `zstd` dictionary used for decoding compressed Jetstream messages.
+
///
+
/// Sourced from the [official Bluesky Jetstream repo.](https://github.com/bluesky-social/jetstream/tree/main/pkg/models)
+
const JETSTREAM_ZSTD_DICTIONARY: &[u8] = include_bytes!("../zstd/dictionary");
+
+
/// A receiver channel for consuming Jetstream events.
+
pub type JetstreamReceiver = flume::Receiver<JetstreamEvent>;
+
+
/// An internal sender channel for sending Jetstream events to [JetstreamReceiver]'s.
+
type JetstreamSender = flume::Sender<JetstreamEvent>;
+
+
/// A wrapper connector type for working with a WebSocket connection to a Jetstream instance to
+
/// receive and consume events. See [JetstreamConnector::connect] for more info.
+
pub struct JetstreamConnector {
+
/// The configuration for the Jetstream connection.
+
config: JetstreamConfig,
+
}
+
+
pub enum JetstreamCompression {
+
/// No compression, just raw plaintext JSON.
+
None,
+
/// Use the `zstd` compression algorithm, which can result in a ~56% smaller messages on
+
/// average. See [here](https://github.com/bluesky-social/jetstream?tab=readme-ov-file#compression) for more info.
+
Zstd,
+
}
+
+
impl From<JetstreamCompression> for bool {
+
fn from(compression: JetstreamCompression) -> Self {
+
match compression {
+
JetstreamCompression::None => false,
+
JetstreamCompression::Zstd => true,
+
}
+
}
+
}
+
+
pub struct JetstreamConfig {
+
/// A Jetstream endpoint to connect to with a WebSocket Scheme i.e.
+
/// `wss://jetstream1.us-east.bsky.network/subscribe`.
+
pub endpoint: String,
+
/// A list of collection [NSIDs](https://atproto.com/specs/nsid) to filter events for.
+
///
+
/// An empty list will receive events for *all* collections.
+
///
+
/// Regardless of desired collections, all subscribers receive
+
/// [AccountEvent](events::account::AccountEvent) and
+
/// [IdentityEvent](events::identity::Identity) events.
+
pub wanted_collections: Vec<exports::Nsid>,
+
/// A list of repo [DIDs](https://atproto.com/specs/did) to filter events for.
+
///
+
/// An empty list will receive events for *all* repos, which is a lot of events!
+
pub wanted_dids: Vec<exports::Did>,
+
/// The compression algorithm to request and use for the WebSocket connection (if any).
+
pub compression: JetstreamCompression,
+
/// An optional timestamp to begin playback from.
+
///
+
/// An absent cursor or a cursor from the future will result in live-tail operation.
+
///
+
/// When reconnecting, use the time_us from your most recently processed event and maybe
+
/// provide a negative buffer (i.e. subtract a few seconds) to ensure gapless playback.
+
pub cursor: Option<chrono::DateTime<Utc>>,
+
}
+
+
impl Default for JetstreamConfig {
+
fn default() -> Self {
+
JetstreamConfig {
+
endpoint: DefaultJetstreamEndpoints::USEastOne.into(),
+
wanted_collections: Vec::new(),
+
wanted_dids: Vec::new(),
+
compression: JetstreamCompression::None,
+
cursor: None,
+
}
+
}
+
}
+
+
impl JetstreamConfig {
+
/// Constructs a new endpoint URL with the given [JetstreamConfig] applied.
+
pub fn construct_endpoint(&self, endpoint: &str) -> Result<Url, url::ParseError> {
+
let did_search_query = self
+
.wanted_dids
+
.iter()
+
.map(|s| ("wantedDids", s.to_string()));
+
+
let collection_search_query = self
+
.wanted_collections
+
.iter()
+
.map(|s| ("wantedCollections", s.to_string()));
+
+
let compression = (
+
"compress",
+
match self.compression {
+
JetstreamCompression::None => "false".to_owned(),
+
JetstreamCompression::Zstd => "true".to_owned(),
+
},
+
);
+
+
let cursor = self
+
.cursor
+
.map(|c| ("cursor", c.timestamp_micros().to_string()));
+
+
let params = did_search_query
+
.chain(collection_search_query)
+
.chain(std::iter::once(compression))
+
.chain(cursor)
+
.collect::<Vec<(&str, String)>>();
+
+
Url::parse_with_params(endpoint, params)
+
}
+
+
/// Validates the configuration to make sure it is within the limits of the Jetstream API.
+
///
+
/// # Constants
+
/// The following constants are used to validate the configuration and should only be changed
+
/// if the Jetstream API has itself changed.
+
/// - [MAX_WANTED_COLLECTIONS]
+
/// - [MAX_WANTED_DIDS]
+
pub fn validate(&self) -> Result<(), ConfigValidationError> {
+
let collections = self.wanted_collections.len();
+
let dids = self.wanted_dids.len();
+
+
if collections > MAX_WANTED_COLLECTIONS {
+
return Err(ConfigValidationError::TooManyWantedCollections(collections));
+
}
+
+
if dids > MAX_WANTED_DIDS {
+
return Err(ConfigValidationError::TooManyDids(dids));
+
}
+
+
Ok(())
+
}
+
}
+
+
impl JetstreamConnector {
+
/// Create a Jetstream connector with a valid [JetstreamConfig].
+
///
+
/// After creation, you can call [connect] to connect to the provided Jetstream instance.
+
pub fn new(config: JetstreamConfig) -> Result<Self, ConfigValidationError> {
+
// We validate the configuration here so any issues are caught early.
+
config.validate()?;
+
Ok(JetstreamConnector { config })
+
}
+
+
/// Connects to a Jetstream instance as defined in the [JetstreamConfig].
+
///
+
/// A [JetstreamReceiver] is returned which can be used to respond to events. When all instances
+
/// of this receiver are dropped, the connection and task are automatically closed.
+
pub async fn connect(&self) -> Result<JetstreamReceiver, ConnectionError> {
+
// We validate the config again for good measure. Probably not necessary but it can't hurt.
+
self.config
+
.validate()
+
.map_err(ConnectionError::InvalidConfig)?;
+
+
// TODO: Run some benchmarks and look into using a bounded channel instead.
+
let (send_channel, receive_channel) = flume::unbounded();
+
+
let configured_endpoint = self
+
.config
+
.construct_endpoint(&self.config.endpoint)
+
.map_err(ConnectionError::InvalidEndpoint)?;
+
+
tokio::task::spawn(async move {
+
let max_retries = 10;
+
let base_delay_ms = 1_000; // 1 second
+
let max_delay_ms = 30_000; // 30 seconds
+
+
for retry_attempt in 0..max_retries {
+
let dict = DecoderDictionary::copy(JETSTREAM_ZSTD_DICTIONARY);
+
+
if let Ok((ws_stream, _)) = connect_async(&configured_endpoint).await {
+
let _ = websocket_task(dict, ws_stream, send_channel.clone()).await;
+
}
+
+
// Exponential backoff
+
let delay_ms = base_delay_ms * (2_u64.pow(retry_attempt));
+
+
log::error!("Connection failed, retrying in {delay_ms}ms...");
+
tokio::time::sleep(Duration::from_millis(delay_ms.min(max_delay_ms))).await;
+
log::info!("Attempting to reconnect...")
+
}
+
log::error!("Connection retries exhausted. Jetstream is disconnected.");
+
});
+
+
Ok(receive_channel)
+
}
+
}
+
+
/// The main task that handles the WebSocket connection and sends [JetstreamEvent]'s to any
+
/// receivers that are listening for them.
+
async fn websocket_task(
+
dictionary: DecoderDictionary<'_>,
+
ws: WebSocketStream<MaybeTlsStream<TcpStream>>,
+
send_channel: JetstreamSender,
+
) -> Result<(), JetstreamEventError> {
+
// TODO: Use the write half to allow the user to change configuration settings on the fly.
+
let (socket_write, mut socket_read) = ws.split();
+
let shared_socket_write = Arc::new(Mutex::new(socket_write));
+
+
let ping_cancellation_token = CancellationToken::new();
+
let mut ping_interval = tokio::time::interval(Duration::from_secs(30));
+
let ping_cancelled = ping_cancellation_token.clone();
+
let ping_shared_socket_write = shared_socket_write.clone();
+
tokio::spawn(async move {
+
loop {
+
ping_interval.tick().await;
+
let false = ping_cancelled.is_cancelled() else {
+
break;
+
};
+
log::trace!("Sending ping");
+
match ping_shared_socket_write
+
.lock()
+
.await
+
.send(Message::Ping("ping".as_bytes().to_vec()))
+
.await
+
{
+
Ok(_) => (),
+
Err(error) => {
+
log::error!("Ping failed: {error}");
+
break;
+
}
+
}
+
}
+
});
+
+
let mut closing_connection = false;
+
loop {
+
match socket_read.next().await {
+
Some(Ok(message)) => {
+
match message {
+
Message::Text(json) => {
+
let event = serde_json::from_str::<JetstreamEvent>(&json)
+
.map_err(JetstreamEventError::ReceivedMalformedJSON)?;
+
+
if send_channel.send(event).is_err() {
+
// We can assume that all receivers have been dropped, so we can close the
+
// connection and exit the task.
+
log::info!(
+
"All receivers for the Jetstream connection have been dropped, closing connection."
+
);
+
closing_connection = true;
+
}
+
}
+
Message::Binary(zstd_json) => {
+
let mut cursor = Cursor::new(zstd_json);
+
let mut decoder = zstd::stream::Decoder::with_prepared_dictionary(
+
&mut cursor,
+
&dictionary,
+
)
+
.map_err(JetstreamEventError::CompressionDictionaryError)?;
+
+
let mut json = String::new();
+
decoder
+
.read_to_string(&mut json)
+
.map_err(JetstreamEventError::CompressionDecoderError)?;
+
+
let event = serde_json::from_str::<JetstreamEvent>(&json)
+
.map_err(JetstreamEventError::ReceivedMalformedJSON)?;
+
+
if send_channel.send(event).is_err() {
+
// We can assume that all receivers have been dropped, so we can close the
+
// connection and exit the task.
+
log::info!(
+
"All receivers for the Jetstream connection have been dropped, closing connection..."
+
);
+
closing_connection = true;
+
}
+
}
+
Message::Ping(vec) => {
+
log::trace!("Ping recieved, responding");
+
_ = shared_socket_write
+
.lock()
+
.await
+
.send(Message::Pong(vec))
+
.await;
+
}
+
Message::Close(close_frame) => {
+
if let Some(close_frame) = close_frame {
+
let reason = close_frame.reason;
+
let code = close_frame.code;
+
log::trace!("Connection closed. Reason: {reason}, Code: {code}");
+
}
+
}
+
Message::Pong(pong) => {
+
let pong_payload =
+
String::from_utf8(pong).unwrap_or("Invalid payload".to_string());
+
log::trace!("Pong recieved. Payload: {pong_payload}");
+
}
+
Message::Frame(_) => (),
+
}
+
}
+
Some(Err(error)) => {
+
log::error!("Web socket error: {error}");
+
ping_cancellation_token.cancel();
+
closing_connection = true;
+
}
+
None => {
+
log::error!("No web socket result");
+
ping_cancellation_token.cancel();
+
closing_connection = true;
+
}
+
}
+
if closing_connection {
+
_ = shared_socket_write.lock().await.close().await;
+
return Ok(());
+
}
+
}
+
}
jetstream/zstd/dictionary

This is a binary file and will not be displayed.