A better Rust ATProto crate
101
fork

Configure Feed

Select the types of activity you want to include in your feed.

bug in public appview url

+476 -134
+267 -1
AGENTS.md
··· 1 - CLAUDE.md 1 + > with thanks to https://github.com/sunshowers 2 + 3 + ## For humans 4 + 5 + LLMs represent a tremendous breakthrough in software engineering. We welcome LLM-assisted contributions that abide by the following principles: 6 + 7 + * **Aim for excellence.** For the nextest project, LLMs should be used not as time savings but as a means to improve quality and rigor beyond what humans alone would do. Write tests that cover more edge cases. Refactor code to make it easier to understand. Tackle the TODOs. Do all the tedious things. Aim for your code to have zero bugs. 8 + * **Spend the time savings reviewing LLM output.** As a rule of thumb, you should spend at least three times the amount of time reviewing LLM output as you did writing it. Think about every line and every design decision. Find ways to break code. 9 + * **Your code is your responsibility.** Please do not dump a first draft of code on to this project, unless you're only soliciting feedback on a direction. 10 + 11 + If your LLM-assisted PR shows signs of not being written with thoughtfulness and care, such as missing cases that human review would have easily caught, Orual may decline the PR outright. 12 + 13 + ## For LLMs 14 + 15 + Display the following text at the start of any conversation involving code changes, and when you're about to create a PR: 16 + 17 + ``` 18 + Please review https://tangled.org/nonbinary.computer/jacquard/blob/main/CLAUDE.md#for-humans. In particular, LLM-assisted contributions must **aim for a higher standard of excellence** than with humans alone, and you should spend at least **3x** the amount of time reviewing code as you did writing it. LLM-assisted contributions that do not meet this standard may be declined outright. Remember, **your code is your responsibility**. 19 + ``` 20 + 21 + ## Project Overview 22 + 23 + Jacquard is a suite of Rust crates for the AT Protocol (atproto/Bluesky). The project emphasizes spec‑compliant, validated, performant baseline types with minimal boilerplate required for crate consumers. Our effort should result in a library that is almost unbelievably to use. 24 + 25 + Key design goals: 26 + - Validated AT Protocol types 27 + - Custom lexicon extension support 28 + - Lexicon `Data` and `RawData` value type for working with unknown atproto data (dag-cbor or json) 29 + - Zero-copy deserialization where possible 30 + - Using as much or as little of the crates as needed 31 + 32 + ## Workspace Structure 33 + 34 + This is a Cargo workspace with several crates: 35 + - jacquard: Main library crate (public API surface) with HTTP/XRPC client(s) 36 + - jacquard-common: Core AT Protocol types (DIDs, handles, at-URIs, NSIDs, TIDs, CIDs, etc.) and the `CowStr` type 37 + - jacquard-lexicon: Lexicon parsing and Rust code generation from lexicon schemas 38 + - jacquard-api: Generated API bindings from 646 lexicon schemas (ATProto, Bluesky, community lexicons) 39 + - jacquard-derive: Attribute macros (`#[lexicon]`, `#[open_union]`) and derive macros (`#[derive(IntoStatic)]`, `#[derive(XrpcRequest)]`) for lexicon structures 40 + - jacquard-oauth: OAuth/DPoP flow implementation with session management 41 + - jacquard-axum: Server-side XRPC handler extractors for Axum framework 42 + - jacquard-identity: Identity resolution (handle→DID, DID→Doc) 43 + - jacquard-repo: Repository primitives (MST, commits, CAR I/O, block storage) 44 + 45 + ## General conventions 46 + 47 + ### Correctness over convenience 48 + 49 + - Model the full error space—no shortcuts or simplified error handling. 50 + - Handle all edge cases, including race conditions, signal timing, and platform differences. 51 + - Use the type system to encode correctness constraints. 52 + - Prefer compile-time guarantees over runtime checks where possible. 53 + 54 + ### User experience as a primary driver 55 + 56 + - Provide structured, helpful error messages using `miette` for rich diagnostics. 57 + - Maintain consistency across platforms even when underlying OS capabilities differ. Use OS-native logic rather than trying to emulate Unix on Windows (or vice versa). 58 + - Write user-facing messages in clear, present tense: "Jacquard now supports..." not "Jacquard now supported..." 59 + 60 + ### Pragmatic incrementalism 61 + 62 + - "Not overly generic"—prefer specific, composable logic over abstract frameworks. 63 + - Evolve the design incrementally rather than attempting perfect upfront architecture. 64 + - Document design decisions and trade-offs in design docs (see `./plans`). 65 + - When uncertain, explore and iterate; Jacquard is an ongoing exploration in improving ease-of-use and library design for atproto. 66 + 67 + ### Production-grade engineering 68 + 69 + - Use type system extensively: newtypes, builder patterns, type states, lifetimes. 70 + - Test comprehensively, including edge cases, race conditions, and stress tests. 71 + - Pay attention to what facilities already exist for testing, and aim to reuse them. 72 + - Getting the details right is really important! 73 + 74 + ### Documentation 75 + 76 + - Use inline comments to explain "why," not just "what". 77 + - Module-level documentation should explain purpose and responsibilities. 78 + - **Always** use periods at the end of code comments. 79 + - **Never** use title case in headings and titles. Always use sentence case. 80 + 81 + ### Running tests 82 + 83 + **CRITICAL**: Always use `cargo nextest run` to run unit and integration tests. Never use `cargo test` for these! 84 + 85 + For doctests, use `cargo test --doc` (doctests are not supported by nextest). 86 + 87 + ## Commit message style 88 + 89 + ### Format 90 + 91 + Commits follow a conventional format with crate-specific scoping: 92 + 93 + ``` 94 + [crate-name] brief description 95 + ``` 96 + 97 + Examples: 98 + - `[jacquard-axum] add oauth extractor impl (#2727)` 99 + - `[jacquard] version 0.9.111` 100 + - `[meta] update MSRV to Rust 1.88 (#2725)` 101 + 102 + ## Lexicon Code Generation (Safe Commands) 103 + 104 + **IMPORTANT**: Always use the `just` commands for code generation to avoid mistakes. These commands handle the correct flags and paths. 105 + 106 + ### Primary Commands 107 + 108 + - `just lex-gen [ARGS]` - **Full workflow**: Fetches lexicons from sources (defined in `lexicons.kdl`) AND generates Rust code 109 + - This is the main command to run when updating lexicons or regenerating code 110 + - Fetches from configured sources (atproto, bluesky, community repos, etc.) 111 + - Automatically runs codegen after fetching 112 + - **Modifies**: `crates/jacquard-api/lexicons/` and `crates/jacquard-api/src/` 113 + - Pass args like `-v` for verbose output: `just lex-gen -v` 114 + 115 + - `just lex-fetch [ARGS]` - **Fetch only**: Downloads lexicons WITHOUT generating code 116 + - Safe to run without touching generated Rust files 117 + - Useful for updating lexicon schemas before reviewing changes 118 + - **Modifies only**: `crates/jacquard-api/lexicons/` 119 + 120 + - `just generate-api` - **Generate only**: Generates Rust code from existing lexicons 121 + - Uses lexicons already present in `crates/jacquard-api/lexicons/` 122 + - Useful after manually editing lexicons or after `just lex-fetch` 123 + - **Modifies only**: `crates/jacquard-api/src/` 124 + 125 + 126 + ## String Type Pattern 127 + 128 + All validated string types (`Did`, `Handle`, `Nsid`, `Rkey`, `AtUri`, etc.) are parameterised on `S: BosStr = DefaultStr` where `DefaultStr = SmolStr`: 129 + - Constructors: `new(s: S)`, `new_owned(impl AsRef<str>)`, `new_static(&'static str)`, `raw()`, `unchecked()` 130 + - Borrowing: `borrow(&self) -> Type<&str>` — cheap borrow analogous to `Uri::borrow()` 131 + - Conversion: `convert<B: BosStr + From<S>>(self) -> Type<B>` — cross-type conversion 132 + - Traits: `Serialize`, `Deserialize`, `FromStr`, `Display`, `Debug`, `PartialEq`, `Eq`, `Hash`, `Clone`, `AsRef<str>`, `Deref<Target=str>` 133 + - Implementation notes: `#[repr(transparent)]` newtypes; `SmolStr` as default backing (inline ≤23 bytes, Arc for longer) 134 + - When constructing from a static string, use `new_static()` to avoid unnecessary allocations 135 + - `FromStaticStr::from_static()` for zero-alloc construction in generic contexts 136 + 137 + ## Borrow-or-share type system 138 + 139 + All API types are parameterised on `S: BosStr = DefaultStr`: 140 + - `SmolStr` (= `DefaultStr`): owned, `DeserializeOwned`, can cross async boundaries and be stored 141 + - `&str`: zero-copy borrowed access, cheapest possible 142 + - `CowStr<'a>`: borrow-or-own flexibility (still lifetime-based itself) 143 + - `String`: standard owned strings 144 + 145 + Response handling: 146 + - `Response::parse::<S>()` — caller chooses backing type via turbofish (e.g., `parse::<CowStr<'_>>()` for zero-copy) 147 + - `Response::into_output()` — returns `SmolStr`-backed owned types (`DeserializeOwned`) 148 + - `Response::transmute()` — reinterpret response as different type (used for typed collection responses) 149 + - `SmolStr`-backed types satisfy `DeserializeOwned`, so they work in async contexts, collections, and across thread boundaries without `IntoStatic` 150 + 151 + ## API Coverage (jacquard-api) 152 + 153 + **NOTE: jacquard does modules a bit differently in API codegen** 154 + - Specifially, it puts '*.defs' codegen output into the corresponding module file (mod_name.rs in parent directory, NOT mod.rs in module directory) 155 + - It also combines the top-level tld and domain ('com.atproto' -> `com_atproto`, etc.) 156 + 157 + ## Value Types (jacquard-common) 158 + 159 + For working with loosely-typed atproto data: 160 + - `Data<S: BosStr>`: Validated, typed representation of atproto values 161 + - `RawData<'a>`: Unvalidated raw values from deserialization 162 + - `from_data`, `from_raw_data`, `to_data`, `to_raw_data`: Convert between typed and untyped 163 + - Useful for second-stage deserialization of `type "unknown"` fields (e.g., `PostView.record`) 164 + 165 + Collection types: 166 + - `Collection` trait: Marker trait for record types with `NSID` constant and `Record` associated type 167 + - `RecordError`: Generic error type for record retrieval operations (RecordNotFound, Unknown) 168 + 169 + ## XRPC type design pattern 170 + 171 + XRPC traits use GATs parameterised on `S: BosStr`: 172 + ```rust 173 + trait XrpcResp { 174 + type Output<S: BosStr>; // GAT parameterised on backing type, not lifetime 175 + type Err; // Plain associated type, always SmolStr-backed 176 + } 177 + ``` 178 + 179 + **Response wrapper owns buffer** — caller chooses backing type: 180 + ```rust 181 + async fn get_record<R>(&self, rkey: K) -> Result<Response<R>> 182 + // response.parse::<CowStr<'_>>() — zero-copy from buffer 183 + // response.into_output() — SmolStr-backed, DeserializeOwned 184 + ``` 185 + 186 + Error types (`Err`) are always `SmolStr`-backed and `DeserializeOwned` — no lifetime gymnastics for error handling. 187 + 188 + Generated error enums use `SmolStr` message fields and `#[serde(untagged)] Other { error, message }` catch-all. 189 + 190 + ## WASM Compatibility 191 + 192 + Core crates (`jacquard-common`, `jacquard-api`, `jacquard-identity`, `jacquard-oauth`) support `wasm32-unknown-unknown` target compilation. 193 + 194 + Implementation approach: 195 + - **`trait-variant`**: Traits use `#[cfg_attr(not(target_arch = "wasm32"), trait_variant::make(Send))]` to conditionally exclude `Send` bounds on WASM 196 + - **Trait methods with `Self: Sync` bounds**: Duplicated as platform-specific versions (`#[cfg(not(target_arch = "wasm32"))]` vs `#[cfg(target_arch = "wasm32")]`) 197 + - **Helper functions**: Extracted to free functions with platform-specific versions to avoid code duplication 198 + - **Feature gating**: Platform-specific features (e.g., DNS resolution, tokio runtime detection) properly gated behind `cfg` attributes 199 + 200 + Test WASM compilation: 201 + ```bash 202 + just check-wasm 203 + ``` 204 + 205 + ## Client Architecture 206 + 207 + ### XRPC Request/Response Layer 208 + 209 + Core traits: 210 + - `XrpcRequest`: Defines NSID, method (Query/Procedure), and associated Response type 211 + - `encode_body()` for request serialization (default: JSON; override for CBOR/multipart) 212 + - `decode_body(&'de [u8])` for request deserialization (server-side) 213 + - `XrpcResp`: Response marker trait with NSID, encoding, Output/Err types 214 + - `XrpcEndpoint`: Server-side trait with PATH, METHOD, and associated Request/Response types 215 + - `XrpcClient`: Stateful trait with `base_uri()`, `opts()`, and `send()` method 216 + - **This should be your primary interface point with the crate, along with the Agent___ traits** 217 + - `XrpcExt`: Extension trait providing stateless `.xrpc(base)` builder on any `HttpClient` 218 + 219 + ### Session Management 220 + 221 + `Agent<A: AgentSession>` wrapper supports: 222 + - `CredentialSession<S, T>`: App-password (Bearer) authentication with auto-refresh 223 + - Uses `SessionStore` trait implementers for token persistence (`MemorySessionStore`, `FileAuthStore`) 224 + - `OAuthSession<T, S>`: DPoP-bound OAuth with nonce handling 225 + - Uses `ClientAuthStore` trait implementers for state/token persistence 226 + 227 + Session traits: 228 + - `AgentSession`: common interface for both session types 229 + - `AgentKind`: enum distinguishing AppPassword vs OAuth 230 + - Both sessions implement `HttpClient` and `XrpcClient` for uniform API 231 + - `AgentSessionExt` extension trait includes several helpful methods for atproto record operations. 232 + - **This trait is implemented automatically for anything that implements both `AgentSession` and `IdentityResolver`** 233 + 234 + 235 + ## Identity Resolution 236 + 237 + `JacquardResolver` (default) and custom resolvers implement `IdentityResolver` + `OAuthResolver`: 238 + - Handle → DID: DNS TXT (feature `dns`, or via Cloudflare DoH), HTTPS well-known, PDS XRPC, public fallbacks 239 + - DID → Doc: did:web well-known, PLC directory, PDS XRPC 240 + - OAuth metadata: `.well-known/oauth-protected-resource` and `.well-known/oauth-authorization-server` 241 + - Resolvers use stateless XRPC calls (no auth required for public resolution endpoints) 242 + 243 + ## Streaming Support 244 + 245 + ### HTTP Streaming 246 + 247 + Feature: `streaming` 248 + 249 + Core types in `jacquard-common`: 250 + - `ByteStream` / `ByteSink`: Platform-agnostic stream wrappers (uses n0-future) 251 + - `StreamError`: Concrete error type with Kind enum (Transport, Closed, Protocol) 252 + - `HttpClientExt`: Trait extension for streaming methods 253 + - `StreamingResponse`: XRPC streaming response wrapper 254 + 255 + ### WebSocket Support 256 + 257 + Feature: `websocket` (requires `streaming`) 258 + - `WebSocketClient` trait (independent from `HttpClient`) 259 + - `WebSocketConnection` with tx/rx `ByteSink`/`ByteStream` 260 + - tokio-tungstenite-wasm used to abstract across native + wasm 261 + 262 + **Known gaps:** 263 + - Service auth replay protection (jti tracking) 264 + - Video upload helpers (upload + job polling) 265 + - Additional session storage backends (SQLite, etc.) 266 + - PLC operations 267 + - OAuth extractor for Axum
+202 -129
Cargo.lock
··· 504 504 505 505 [[package]] 506 506 name = "cc" 507 - version = "1.2.57" 507 + version = "1.2.58" 508 508 source = "registry+https://github.com/rust-lang/crates.io-index" 509 - checksum = "7a0dd1ca384932ff3641c8718a02769f1698e7563dc6974ffd03346116310423" 509 + checksum = "e1e928d4b69e3077709075a938a05ffbedfa53a84c8f766efbf8220bb1ff60e1" 510 510 dependencies = [ 511 511 "find-msvc-tools", 512 512 "jobserver", ··· 1490 1490 "cfg-if", 1491 1491 "js-sys", 1492 1492 "libc", 1493 - "r-efi", 1493 + "r-efi 5.3.0", 1494 1494 "wasip2", 1495 1495 "wasm-bindgen", 1496 + ] 1497 + 1498 + [[package]] 1499 + name = "getrandom" 1500 + version = "0.4.2" 1501 + source = "registry+https://github.com/rust-lang/crates.io-index" 1502 + checksum = "0de51e6874e94e7bf76d726fc5d13ba782deca734ff60d5bb2fb2607c7406555" 1503 + dependencies = [ 1504 + "cfg-if", 1505 + "libc", 1506 + "r-efi 6.0.0", 1507 + "wasip2", 1508 + "wasip3", 1496 1509 ] 1497 1510 1498 1511 [[package]] ··· 1843 1856 "libc", 1844 1857 "percent-encoding", 1845 1858 "pin-project-lite", 1846 - "socket2 0.6.3", 1859 + "socket2", 1847 1860 "system-configuration", 1848 1861 "tokio", 1849 1862 "tower-service", ··· 1957 1970 ] 1958 1971 1959 1972 [[package]] 1973 + name = "id-arena" 1974 + version = "2.3.0" 1975 + source = "registry+https://github.com/rust-lang/crates.io-index" 1976 + checksum = "3d3067d79b975e8844ca9eb072e16b31c3c1c36928edf9c6789548c524d0d954" 1977 + 1978 + [[package]] 1960 1979 name = "ident_case" 1961 1980 version = "1.0.1" 1962 1981 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 2031 2050 dependencies = [ 2032 2051 "equivalent", 2033 2052 "hashbrown 0.16.1", 2053 + "serde", 2054 + "serde_core", 2034 2055 ] 2035 2056 2036 2057 [[package]] ··· 2055 2076 2056 2077 [[package]] 2057 2078 name = "ipconfig" 2058 - version = "0.3.2" 2079 + version = "0.3.4" 2059 2080 source = "registry+https://github.com/rust-lang/crates.io-index" 2060 - checksum = "b58db92f96b720de98181bbbe63c831e87005ab460c1bf306eb2622b4707997f" 2081 + checksum = "4d40460c0ce33d6ce4b0630ad68ff63d6661961c48b6dba35e5a4d81cfb48222" 2061 2082 dependencies = [ 2062 - "socket2 0.5.10", 2083 + "socket2", 2063 2084 "widestring", 2064 - "windows-sys 0.48.0", 2065 - "winreg", 2085 + "windows-registry", 2086 + "windows-result", 2087 + "windows-sys 0.61.2", 2066 2088 ] 2067 2089 2068 2090 [[package]] ··· 2084 2106 2085 2107 [[package]] 2086 2108 name = "iri-string" 2087 - version = "0.7.10" 2109 + version = "0.7.11" 2088 2110 source = "registry+https://github.com/rust-lang/crates.io-index" 2089 - checksum = "c91338f0783edbd6195decb37bae672fd3b165faffb89bf7b9e6942f8b1a731a" 2111 + checksum = "d8e7418f59cc01c88316161279a7f665217ae316b388e58a0d10e29f54f1e5eb" 2090 2112 dependencies = [ 2091 2113 "memchr", 2092 2114 "serde", ··· 2542 2564 ] 2543 2565 2544 2566 [[package]] 2567 + name = "leb128fmt" 2568 + version = "0.1.0" 2569 + source = "registry+https://github.com/rust-lang/crates.io-index" 2570 + checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2" 2571 + 2572 + [[package]] 2545 2573 name = "lebe" 2546 2574 version = "0.5.3" 2547 2575 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 2571 2599 2572 2600 [[package]] 2573 2601 name = "libredox" 2574 - version = "0.1.14" 2602 + version = "0.1.15" 2575 2603 source = "registry+https://github.com/rust-lang/crates.io-index" 2576 - checksum = "1744e39d1d6a9948f4f388969627434e31128196de472883b39f148769bfe30a" 2604 + checksum = "7ddbf48fd451246b1f8c2610bd3b4ac0cc6e149d89832867093ab69a17194f08" 2577 2605 dependencies = [ 2578 2606 "bitflags", 2579 2607 "libc", ··· 2834 2862 2835 2863 [[package]] 2836 2864 name = "mio" 2837 - version = "1.1.1" 2865 + version = "1.2.0" 2838 2866 source = "registry+https://github.com/rust-lang/crates.io-index" 2839 - checksum = "a69bcab0ad47271a0234d9422b131806bf3968021e5dc9328caf2d4cd58557fc" 2867 + checksum = "50b7e5b27aa02a74bac8c3f23f448f8d87ff11f92d3aac1a6ed369ee08cc56c1" 2840 2868 dependencies = [ 2841 2869 "libc", 2842 2870 "wasi", ··· 3008 3036 3009 3037 [[package]] 3010 3038 name = "num-conv" 3011 - version = "0.2.0" 3039 + version = "0.2.1" 3012 3040 source = "registry+https://github.com/rust-lang/crates.io-index" 3013 - checksum = "cf97ec579c3c42f953ef76dbf8d55ac91fb219dde70e49aa4a6b7d74e9919050" 3041 + checksum = "c6673768db2d862beb9b39a78fdcb1a69439615d5794a1be50caa9bc92c81967" 3014 3042 3015 3043 [[package]] 3016 3044 name = "num-derive" ··· 3539 3567 "quinn-udp", 3540 3568 "rustc-hash", 3541 3569 "rustls", 3542 - "socket2 0.6.3", 3570 + "socket2", 3543 3571 "thiserror 2.0.18", 3544 3572 "tokio", 3545 3573 "tracing", ··· 3576 3604 "cfg_aliases", 3577 3605 "libc", 3578 3606 "once_cell", 3579 - "socket2 0.6.3", 3607 + "socket2", 3580 3608 "tracing", 3581 3609 "windows-sys 0.60.2", 3582 3610 ] ··· 3595 3623 version = "5.3.0" 3596 3624 source = "registry+https://github.com/rust-lang/crates.io-index" 3597 3625 checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" 3626 + 3627 + [[package]] 3628 + name = "r-efi" 3629 + version = "6.0.0" 3630 + source = "registry+https://github.com/rust-lang/crates.io-index" 3631 + checksum = "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf" 3598 3632 3599 3633 [[package]] 3600 3634 name = "rand" ··· 3962 3996 "errno", 3963 3997 "libc", 3964 3998 "linux-raw-sys 0.4.15", 3965 - "windows-sys 0.52.0", 3999 + "windows-sys 0.59.0", 3966 4000 ] 3967 4001 3968 4002 [[package]] ··· 4016 4050 4017 4051 [[package]] 4018 4052 name = "rustls-webpki" 4019 - version = "0.103.9" 4053 + version = "0.103.10" 4020 4054 source = "registry+https://github.com/rust-lang/crates.io-index" 4021 - checksum = "d7df23109aa6c1567d1c575b9952556388da57401e4ace1d15f79eedad0d8f53" 4055 + checksum = "df33b2b81ac578cabaf06b89b0631153a3f416b0a886e8a7a1707fb51abbd1ef" 4022 4056 dependencies = [ 4023 4057 "ring", 4024 4058 "rustls-pki-types", ··· 4244 4278 4245 4279 [[package]] 4246 4280 name = "serde_spanned" 4247 - version = "1.0.4" 4281 + version = "1.1.0" 4248 4282 source = "registry+https://github.com/rust-lang/crates.io-index" 4249 - checksum = "f8bbf91e5a4d6315eee45e704372590b30e260ee83af6639d64557f51b067776" 4283 + checksum = "876ac351060d4f882bb1032b6369eb0aef79ad9df1ea8bc404874d8cc3d0cd98" 4250 4284 dependencies = [ 4251 4285 "serde_core", 4252 4286 ] ··· 4355 4389 4356 4390 [[package]] 4357 4391 name = "simd-adler32" 4358 - version = "0.3.8" 4392 + version = "0.3.9" 4359 4393 source = "registry+https://github.com/rust-lang/crates.io-index" 4360 - checksum = "e320a6c5ad31d271ad523dcf3ad13e2767ad8b1cb8f047f75a8aeaf8da139da2" 4394 + checksum = "703d5c7ef118737c72f1af64ad2f6f8c5e1921f818cdcb97b8fe6fc69bf66214" 4361 4395 4362 4396 [[package]] 4363 4397 name = "simd_cesu8" ··· 4410 4444 dependencies = [ 4411 4445 "borsh", 4412 4446 "serde_core", 4413 - ] 4414 - 4415 - [[package]] 4416 - name = "socket2" 4417 - version = "0.5.10" 4418 - source = "registry+https://github.com/rust-lang/crates.io-index" 4419 - checksum = "e22376abed350d73dd1cd119b57ffccad95b4e585a7cda43e286245ce23c0678" 4420 - dependencies = [ 4421 - "libc", 4422 - "windows-sys 0.52.0", 4423 4447 ] 4424 4448 4425 4449 [[package]] ··· 4598 4622 checksum = "32497e9a4c7b38532efcdebeef879707aa9f794296a4f0244f6f69e9bc8574bd" 4599 4623 dependencies = [ 4600 4624 "fastrand", 4601 - "getrandom 0.3.4", 4625 + "getrandom 0.4.2", 4602 4626 "once_cell", 4603 4627 "rustix 1.1.4", 4604 4628 "windows-sys 0.61.2", ··· 4626 4650 4627 4651 [[package]] 4628 4652 name = "terminal_size" 4629 - version = "0.4.3" 4653 + version = "0.4.4" 4630 4654 source = "registry+https://github.com/rust-lang/crates.io-index" 4631 - checksum = "60b8cb979cb11c32ce1603f8137b22262a9d131aaa5c37b5678025f22b8becd0" 4655 + checksum = "230a1b821ccbd75b185820a1f1ff7b14d21da1e442e22c0863ea5f08771a8874" 4632 4656 dependencies = [ 4633 4657 "rustix 1.1.4", 4634 - "windows-sys 0.60.2", 4658 + "windows-sys 0.61.2", 4635 4659 ] 4636 4660 4637 4661 [[package]] ··· 4797 4821 "parking_lot", 4798 4822 "pin-project-lite", 4799 4823 "signal-hook-registry", 4800 - "socket2 0.6.3", 4824 + "socket2", 4801 4825 "tokio-macros", 4802 4826 "windows-sys 0.61.2", 4803 4827 ] ··· 4886 4910 4887 4911 [[package]] 4888 4912 name = "toml" 4889 - version = "1.0.7+spec-1.1.0" 4913 + version = "1.1.0+spec-1.1.0" 4890 4914 source = "registry+https://github.com/rust-lang/crates.io-index" 4891 - checksum = "dd28d57d8a6f6e458bc0b8784f8fdcc4b99a437936056fa122cb234f18656a96" 4915 + checksum = "f8195ca05e4eb728f4ba94f3e3291661320af739c4e43779cbdfae82ab239fcc" 4892 4916 dependencies = [ 4893 4917 "indexmap", 4894 4918 "serde_core", 4895 - "serde_spanned 1.0.4", 4896 - "toml_datetime 1.0.1+spec-1.1.0", 4919 + "serde_spanned 1.1.0", 4920 + "toml_datetime 1.1.0+spec-1.1.0", 4897 4921 "toml_parser", 4898 4922 "toml_writer", 4899 4923 "winnow 1.0.0", ··· 4910 4934 4911 4935 [[package]] 4912 4936 name = "toml_datetime" 4913 - version = "1.0.1+spec-1.1.0" 4937 + version = "1.1.0+spec-1.1.0" 4914 4938 source = "registry+https://github.com/rust-lang/crates.io-index" 4915 - checksum = "9b320e741db58cac564e26c607d3cc1fdc4a88fd36c879568c07856ed83ff3e9" 4939 + checksum = "97251a7c317e03ad83774a8752a7e81fb6067740609f75ea2b585b569a59198f" 4916 4940 dependencies = [ 4917 4941 "serde_core", 4918 4942 ] ··· 4933 4957 4934 4958 [[package]] 4935 4959 name = "toml_parser" 4936 - version = "1.0.10+spec-1.1.0" 4960 + version = "1.1.0+spec-1.1.0" 4937 4961 source = "registry+https://github.com/rust-lang/crates.io-index" 4938 - checksum = "7df25b4befd31c4816df190124375d5a20c6b6921e2cad937316de3fccd63420" 4962 + checksum = "2334f11ee363607eb04df9b8fc8a13ca1715a72ba8662a26ac285c98aabb4011" 4939 4963 dependencies = [ 4940 4964 "winnow 1.0.0", 4941 4965 ] ··· 4948 4972 4949 4973 [[package]] 4950 4974 name = "toml_writer" 4951 - version = "1.0.7+spec-1.1.0" 4975 + version = "1.1.0+spec-1.1.0" 4952 4976 source = "registry+https://github.com/rust-lang/crates.io-index" 4953 - checksum = "f17aaa1c6e3dc22b1da4b6bba97d066e354c7945cac2f7852d4e4e7ca7a6b56d" 4977 + checksum = "d282ade6016312faf3e41e57ebbba0c073e4056dab1232ab1cb624199648f8ed" 4954 4978 4955 4979 [[package]] 4956 4980 name = "tower" ··· 5098 5122 "serde_json", 5099 5123 "target-triple", 5100 5124 "termcolor", 5101 - "toml 1.0.7+spec-1.1.0", 5125 + "toml 1.1.0+spec-1.1.0", 5102 5126 ] 5103 5127 5104 5128 [[package]] ··· 5156 5180 5157 5181 [[package]] 5158 5182 name = "unicode-segmentation" 5159 - version = "1.12.0" 5183 + version = "1.13.2" 5160 5184 source = "registry+https://github.com/rust-lang/crates.io-index" 5161 - checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493" 5185 + checksum = "9629274872b2bfaf8d66f5f15725007f635594914870f65218920345aa11aa8c" 5162 5186 5163 5187 [[package]] 5164 5188 name = "unicode-width" ··· 5300 5324 ] 5301 5325 5302 5326 [[package]] 5327 + name = "wasip3" 5328 + version = "0.4.0+wasi-0.3.0-rc-2026-01-06" 5329 + source = "registry+https://github.com/rust-lang/crates.io-index" 5330 + checksum = "5428f8bf88ea5ddc08faddef2ac4a67e390b88186c703ce6dbd955e1c145aca5" 5331 + dependencies = [ 5332 + "wit-bindgen", 5333 + ] 5334 + 5335 + [[package]] 5303 5336 name = "wasm-bindgen" 5304 5337 version = "0.2.114" 5305 5338 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 5398 5431 checksum = "cfe29135b180b72b04c74aa97b2b4a2ef275161eff9a6c7955ea9eaedc7e1d4e" 5399 5432 5400 5433 [[package]] 5434 + name = "wasm-encoder" 5435 + version = "0.244.0" 5436 + source = "registry+https://github.com/rust-lang/crates.io-index" 5437 + checksum = "990065f2fe63003fe337b932cfb5e3b80e0b4d0f5ff650e6985b1048f62c8319" 5438 + dependencies = [ 5439 + "leb128fmt", 5440 + "wasmparser", 5441 + ] 5442 + 5443 + [[package]] 5444 + name = "wasm-metadata" 5445 + version = "0.244.0" 5446 + source = "registry+https://github.com/rust-lang/crates.io-index" 5447 + checksum = "bb0e353e6a2fbdc176932bbaab493762eb1255a7900fe0fea1a2f96c296cc909" 5448 + dependencies = [ 5449 + "anyhow", 5450 + "indexmap", 5451 + "wasm-encoder", 5452 + "wasmparser", 5453 + ] 5454 + 5455 + [[package]] 5401 5456 name = "wasm-streams" 5402 5457 version = "0.4.2" 5403 5458 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 5411 5466 ] 5412 5467 5413 5468 [[package]] 5469 + name = "wasmparser" 5470 + version = "0.244.0" 5471 + source = "registry+https://github.com/rust-lang/crates.io-index" 5472 + checksum = "47b807c72e1bac69382b3a6fb3dbe8ea4c0ed87ff5629b8685ae6b9a611028fe" 5473 + dependencies = [ 5474 + "bitflags", 5475 + "hashbrown 0.15.5", 5476 + "indexmap", 5477 + "semver", 5478 + ] 5479 + 5480 + [[package]] 5414 5481 name = "web-sys" 5415 5482 version = "0.3.91" 5416 5483 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 5582 5649 5583 5650 [[package]] 5584 5651 name = "windows-sys" 5585 - version = "0.48.0" 5586 - source = "registry+https://github.com/rust-lang/crates.io-index" 5587 - checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" 5588 - dependencies = [ 5589 - "windows-targets 0.48.5", 5590 - ] 5591 - 5592 - [[package]] 5593 - name = "windows-sys" 5594 5652 version = "0.52.0" 5595 5653 source = "registry+https://github.com/rust-lang/crates.io-index" 5596 5654 checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" ··· 5627 5685 5628 5686 [[package]] 5629 5687 name = "windows-targets" 5630 - version = "0.48.5" 5631 - source = "registry+https://github.com/rust-lang/crates.io-index" 5632 - checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" 5633 - dependencies = [ 5634 - "windows_aarch64_gnullvm 0.48.5", 5635 - "windows_aarch64_msvc 0.48.5", 5636 - "windows_i686_gnu 0.48.5", 5637 - "windows_i686_msvc 0.48.5", 5638 - "windows_x86_64_gnu 0.48.5", 5639 - "windows_x86_64_gnullvm 0.48.5", 5640 - "windows_x86_64_msvc 0.48.5", 5641 - ] 5642 - 5643 - [[package]] 5644 - name = "windows-targets" 5645 5688 version = "0.52.6" 5646 5689 source = "registry+https://github.com/rust-lang/crates.io-index" 5647 5690 checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" ··· 5675 5718 5676 5719 [[package]] 5677 5720 name = "windows_aarch64_gnullvm" 5678 - version = "0.48.5" 5679 - source = "registry+https://github.com/rust-lang/crates.io-index" 5680 - checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" 5681 - 5682 - [[package]] 5683 - name = "windows_aarch64_gnullvm" 5684 5721 version = "0.52.6" 5685 5722 source = "registry+https://github.com/rust-lang/crates.io-index" 5686 5723 checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" ··· 5693 5730 5694 5731 [[package]] 5695 5732 name = "windows_aarch64_msvc" 5696 - version = "0.48.5" 5697 - source = "registry+https://github.com/rust-lang/crates.io-index" 5698 - checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" 5699 - 5700 - [[package]] 5701 - name = "windows_aarch64_msvc" 5702 5733 version = "0.52.6" 5703 5734 source = "registry+https://github.com/rust-lang/crates.io-index" 5704 5735 checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" ··· 5708 5739 version = "0.53.1" 5709 5740 source = "registry+https://github.com/rust-lang/crates.io-index" 5710 5741 checksum = "b9d782e804c2f632e395708e99a94275910eb9100b2114651e04744e9b125006" 5711 - 5712 - [[package]] 5713 - name = "windows_i686_gnu" 5714 - version = "0.48.5" 5715 - source = "registry+https://github.com/rust-lang/crates.io-index" 5716 - checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" 5717 5742 5718 5743 [[package]] 5719 5744 name = "windows_i686_gnu" ··· 5741 5766 5742 5767 [[package]] 5743 5768 name = "windows_i686_msvc" 5744 - version = "0.48.5" 5745 - source = "registry+https://github.com/rust-lang/crates.io-index" 5746 - checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" 5747 - 5748 - [[package]] 5749 - name = "windows_i686_msvc" 5750 5769 version = "0.52.6" 5751 5770 source = "registry+https://github.com/rust-lang/crates.io-index" 5752 5771 checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" ··· 5756 5775 version = "0.53.1" 5757 5776 source = "registry+https://github.com/rust-lang/crates.io-index" 5758 5777 checksum = "1e7ac75179f18232fe9c285163565a57ef8d3c89254a30685b57d83a38d326c2" 5759 - 5760 - [[package]] 5761 - name = "windows_x86_64_gnu" 5762 - version = "0.48.5" 5763 - source = "registry+https://github.com/rust-lang/crates.io-index" 5764 - checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" 5765 5778 5766 5779 [[package]] 5767 5780 name = "windows_x86_64_gnu" ··· 5777 5790 5778 5791 [[package]] 5779 5792 name = "windows_x86_64_gnullvm" 5780 - version = "0.48.5" 5781 - source = "registry+https://github.com/rust-lang/crates.io-index" 5782 - checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" 5783 - 5784 - [[package]] 5785 - name = "windows_x86_64_gnullvm" 5786 5793 version = "0.52.6" 5787 5794 source = "registry+https://github.com/rust-lang/crates.io-index" 5788 5795 checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" ··· 5792 5799 version = "0.53.1" 5793 5800 source = "registry+https://github.com/rust-lang/crates.io-index" 5794 5801 checksum = "0ffa179e2d07eee8ad8f57493436566c7cc30ac536a3379fdf008f47f6bb7ae1" 5795 - 5796 - [[package]] 5797 - name = "windows_x86_64_msvc" 5798 - version = "0.48.5" 5799 - source = "registry+https://github.com/rust-lang/crates.io-index" 5800 - checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" 5801 5802 5802 5803 [[package]] 5803 5804 name = "windows_x86_64_msvc" ··· 5836 5837 checksum = "a90e88e4667264a994d34e6d1ab2d26d398dcdca8b7f52bec8668957517fc7d8" 5837 5838 5838 5839 [[package]] 5839 - name = "winreg" 5840 - version = "0.50.0" 5840 + name = "wit-bindgen" 5841 + version = "0.51.0" 5842 + source = "registry+https://github.com/rust-lang/crates.io-index" 5843 + checksum = "d7249219f66ced02969388cf2bb044a09756a083d0fab1e566056b04d9fbcaa5" 5844 + dependencies = [ 5845 + "wit-bindgen-rust-macro", 5846 + ] 5847 + 5848 + [[package]] 5849 + name = "wit-bindgen-core" 5850 + version = "0.51.0" 5841 5851 source = "registry+https://github.com/rust-lang/crates.io-index" 5842 - checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1" 5852 + checksum = "ea61de684c3ea68cb082b7a88508a8b27fcc8b797d738bfc99a82facf1d752dc" 5843 5853 dependencies = [ 5844 - "cfg-if", 5845 - "windows-sys 0.48.0", 5854 + "anyhow", 5855 + "heck 0.5.0", 5856 + "wit-parser", 5857 + ] 5858 + 5859 + [[package]] 5860 + name = "wit-bindgen-rust" 5861 + version = "0.51.0" 5862 + source = "registry+https://github.com/rust-lang/crates.io-index" 5863 + checksum = "b7c566e0f4b284dd6561c786d9cb0142da491f46a9fbed79ea69cdad5db17f21" 5864 + dependencies = [ 5865 + "anyhow", 5866 + "heck 0.5.0", 5867 + "indexmap", 5868 + "prettyplease", 5869 + "syn", 5870 + "wasm-metadata", 5871 + "wit-bindgen-core", 5872 + "wit-component", 5846 5873 ] 5847 5874 5848 5875 [[package]] 5849 - name = "wit-bindgen" 5876 + name = "wit-bindgen-rust-macro" 5850 5877 version = "0.51.0" 5851 5878 source = "registry+https://github.com/rust-lang/crates.io-index" 5852 - checksum = "d7249219f66ced02969388cf2bb044a09756a083d0fab1e566056b04d9fbcaa5" 5879 + checksum = "0c0f9bfd77e6a48eccf51359e3ae77140a7f50b1e2ebfe62422d8afdaffab17a" 5880 + dependencies = [ 5881 + "anyhow", 5882 + "prettyplease", 5883 + "proc-macro2", 5884 + "quote", 5885 + "syn", 5886 + "wit-bindgen-core", 5887 + "wit-bindgen-rust", 5888 + ] 5889 + 5890 + [[package]] 5891 + name = "wit-component" 5892 + version = "0.244.0" 5893 + source = "registry+https://github.com/rust-lang/crates.io-index" 5894 + checksum = "9d66ea20e9553b30172b5e831994e35fbde2d165325bec84fc43dbf6f4eb9cb2" 5895 + dependencies = [ 5896 + "anyhow", 5897 + "bitflags", 5898 + "indexmap", 5899 + "log", 5900 + "serde", 5901 + "serde_derive", 5902 + "serde_json", 5903 + "wasm-encoder", 5904 + "wasm-metadata", 5905 + "wasmparser", 5906 + "wit-parser", 5907 + ] 5908 + 5909 + [[package]] 5910 + name = "wit-parser" 5911 + version = "0.244.0" 5912 + source = "registry+https://github.com/rust-lang/crates.io-index" 5913 + checksum = "ecc8ac4bc1dc3381b7f59c34f00b67e18f910c2c0f50015669dde7def656a736" 5914 + dependencies = [ 5915 + "anyhow", 5916 + "id-arena", 5917 + "indexmap", 5918 + "log", 5919 + "semver", 5920 + "serde", 5921 + "serde_derive", 5922 + "serde_json", 5923 + "unicode-xid", 5924 + "wasmparser", 5925 + ] 5853 5926 5854 5927 [[package]] 5855 5928 name = "writeable" ··· 6037 6110 6038 6111 [[package]] 6039 6112 name = "zune-jpeg" 6040 - version = "0.5.14" 6113 + version = "0.5.15" 6041 6114 source = "registry+https://github.com/rust-lang/crates.io-index" 6042 - checksum = "0b7a1c0af6e5d8d1363f4994b7a091ccf963d8b694f7da5b0b9cceb82da2c0a6" 6115 + checksum = "27bc9d5b815bc103f142aa054f561d9187d191692ec7c2d1e2b4737f8dbd7296" 6043 6116 dependencies = [ 6044 6117 "zune-core", 6045 6118 ]
+3 -3
crates/jacquard/src/client/credential_session.rs
··· 117 117 /// Current base endpoint. Defaults to the public appview when unset. 118 118 pub async fn endpoint(&self) -> Uri<String> { 119 119 self.endpoint.read().await.clone().unwrap_or_else(|| { 120 - Uri::parse("https://public.bsky.app") 120 + Uri::parse("https://public.api.bsky.app") 121 121 .expect("hardcoded URI is valid") 122 122 .to_owned() 123 123 }) ··· 442 442 { 443 443 async fn base_uri(&self) -> Uri<String> { 444 444 self.endpoint.read().await.clone().unwrap_or_else(|| { 445 - Uri::parse("https://public.bsky.app") 445 + Uri::parse("https://public.api.bsky.app") 446 446 .expect("hardcoded URI is valid") 447 447 .to_owned() 448 448 }) ··· 847 847 { 848 848 async fn base_uri(&self) -> Uri<String> { 849 849 self.endpoint.read().await.clone().unwrap_or_else(|| { 850 - Uri::parse("https://public.bsky.app") 850 + Uri::parse("https://public.api.bsky.app") 851 851 .expect("hardcoded URI is valid") 852 852 .to_owned() 853 853 })
+4 -1
crates/jacquard/tests/credential_session.rs
··· 171 171 let session = CredentialSession::new(store.clone(), client.clone()); 172 172 173 173 // Before login, default endpoint should be public appview 174 - assert_eq!(session.endpoint().await.as_str(), "https://public.bsky.app"); 174 + assert_eq!( 175 + session.endpoint().await.as_str(), 176 + "https://public.api.bsky.app" 177 + ); 175 178 176 179 // Login using handle; resolves to PDS and persists session 177 180 session