A better Rust ATProto crate
103
fork

Configure Feed

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

at pretty-codegen 726 lines 32 kB view raw view rendered
1# Changelog 2 3## [0.10.1] - 2026-03-20 (`jacquard-common`) 4 5### Fixed 6 7**CID deserialization** (`jacquard-common`) 8- Fixed `CidLink` deserialization from CBOR tag-42 bytes through internally-tagged enums (reported by @natalie.sh, fixed by adorable robot) 9- `serde_ipld_dagcbor` buffers tag-42 CIDs as a newtype struct wrapping raw bytes when deserializing through `Content`; the visitor now handles `visit_bytes`, `visit_byte_buf`, and `visit_newtype_struct` to cover this path 10 11## [0.10.0] - 2026-03-20 12 13### Breaking changes 14 15**URL type migration** (`jacquard-common`, `jacquard`, `jacquard-oauth`, `jacquard-identity`, `jacquard-api`) 16- Migrated from `url` crate to `fluent_uri` for validated URL/URI types 17- All `Url` types are now `Uri` from `fluent_uri` 18- Affects any code that constructs, passes, or pattern-matches on endpoint URLs 19 20**Re-exported crate paths** (`jacquard-api`, `jacquard-common`) 21- Re-exported crates (including non-proc-macro dependencies of the generated API crate) are now centralized into a distinct module 22- Import paths for re-exported types have changed as a result 23 24### Added 25 26**`no_std` groundwork** (`jacquard-common`, `jacquard-api`) 27- Initial steps toward `no_std` support for core types 28- `jacquard-api` gains feature gating for `std`/`no_std` usage 29 30**Datetime improvements** (`jacquard-common`) 31- [PR from @blyoom.dev](https://tangled.org/nonbinary.computer/jacquard/pulls/6/) exposing timestamps directly on `Datetime` type 32- Naming aligned with `chrono` conventions 33 34**Handle normalization** (`jacquard-common`) 35- Handles are now lowercase-normalized on construction 36 37**Embedded PDS primitives** (`jacquard-repo`) 38- Initial lazy disk-spilling collection types for embedded PDS use cases 39- Repo firehose types now use generated API types instead of hand-written equivalents 40 41**Lexicon codegen improvements** (`jacquard-lexicon`, `jacquard-api`) 42- `knownValues` generation now aligned with AT Protocol spec and triggers more frequently 43- Improved feature dependency tracking for API crate features 44 45**Additional signing algorithms** (`jacquard-oauth`) 46- Keyset signing now supports ES384 (P-384), ES256K (secp256k1), and EdDSA (Ed25519) in addition to ES256 47- `Keyset::create_jwt` now accepts `&[Signing]` (from `jose_jwa`) instead of string-based algorithm names 48 49**Documentation** (`jacquard-oauth`, `jacquard-identity`) 50- Doc comments across all public items in both crates (thanks Claude, but I played editor pretty heavily) 51 52### Fixed 53 54**Identity resolution** (`jacquard-identity`) 55- [PR from @alephcubed.com](https://tangled.org/nonbinary.computer/jacquard/pulls/7/) fixing `DidDocument::handles()` always failing when parsed from `MiniDoc` 56 57**Error handling** (`jacquard-common`, `jacquard`, `jacquard-oauth`) 58- Big error quality-of-life pass with richer, more actionable diagnostics 59- More resilient error parsing for auth errors 60- Better lexicon parsing error messages 61 62**WASM** (`jacquard-common`) 63- Fixed WASM CI smoke test compilation 64 65### Changed 66 67**Lexicons** (`jacquard-api`) 68- Large batch of lexicon schema updates with manual cleanup 69 70## [0.9.6] - 2025-12-19 71 72### Changed 73 74**Logging** (`jacquard`, `jacquard-axum`) 75- [PR from @nekomimi.pet](https://tangled.org/nonbinary.computer/jacquard/pulls/5) cleaning up more debug logs, and adding tracing feature gate to jacquard-axum 76 77### Fixed 78 79**Repo commit signatures** (`jacquard-repo`) 80- commit signatures generated by `jacquard-repo` should now be consistent with other implementations 81- previously, they included an empty `sig` bytes field in the signed struct, which has a different CBOR serialization from the canonical relay implementation expectations. 82 83## [0.9.5] - 2025-12-19 84 85### Fixed 86 87**docs.rs configuration** 88- Fixed typo in `jacquard-common` docs.rs features (`crypto-ed22519``crypto-ed25519`) that was causing documentation builds to fail 89- Moved `loopback` feature documentation to `jacquard-oauth` where the feature is defined 90 91**OAuth flow** (`jacquard-oauth`) 92- Minor OAuth flow compatibility improvements 93 94**Serialization** (`jacquard-common`, `jacquard-identity`) 95- Fixed CID deserialization edge cases in `Data` and `RawData` types 96- Fixed DID document serialization when optional fields are absent 97 98**Lexicon code generation** (`jacquard-lexicon`, `jacquard-api`) 99- Fixed nullable field handling in generated code 100- Fixed lifetime handling in codegen of binary xrpc outputs 101- Fixed lifetime handling in unions 102- Fixed incorrectly unescaped rust keywords in module paths 103 104**Observability** (`jacquard`) 105- Fixed tracing span issues associated with some build failures 106 107### Added 108 109**mini-moka-wasm** (`mini-moka-wasm`, `jacquard-identity`) 110- Publishing vendored version of mini-moka with wasm browser compat fix to make usage easier 111 112**Service authentication** (`jacquard-axum`) 113- Optional service auth extractor option 114 115**Data handling** (`jacquard-common`) 116- Serde bytes helpers for JSON fields 117- Made PLC source fields public for library consumers 118 119**Lexicons** (`jacquard-api`) 120- Updated to latest AT Protocol lexicon schemas 121- API regeneration with builder fixes 122 123### Changed 124 125**Logging** (`jacquard`) 126- Improved client error logging with better context 127 128## [0.9.3] - 2025-11-17 (`jacquard`) 129 130### Fixed 131 132- SessionKey is now a proper tuple struct and not a type alias, which should help rustc not freak out when you do things like put MemoryCredentialSession in an Arc 133 134## [0.9.2] - 2025-11-17 135 136### Added 137 138**WASM compatibility improvements** (`jacquard-common`, `jacquard-identity`) 139- Vendored mini-moka implementation with WASM support for caching 140- regex-lite usage on WASM targets for reduced binary size 141- Schema resolver now works on WASM targets 142 143**Data query improvements** (`jacquard-common`) 144- Mutable path query access and setting for `Data` values 145 146### Changed 147 148**URL handling** (`jacquard-common`) 149- Rework of some internal URL handling for better compatibility 150- Includes a minor change to the return type of the endpoint() method of XrpcClient and equivalents. 151 152**OAuth improvements** (`jacquard-oauth`) 153- Fixed OAuth scope handling in loopback flow 154- OAuth metadata resolution improvements 155- Various OAuth flow enhancements and bug fixes 156 157**Identity resolution** (`jacquard-identity`) 158- Fixed non-DNS lexicon and did:web resolution using Cloudflare DoH 159- Reduced noisy logging in identity resolution 160 161**Lexicons** (`jacquard-api`) 162- Updated to latest AT Protocol lexicons 163 164### Fixed 165 166**Data deserialization** (`jacquard-common`) 167- Fixed CID deserialization edge cases for better spec compliance 168- More permissive JSON shape handling for better interoperability with varied implementations 169 170## [0.9.1] - 2025-11-04 (`jacquard-identity`, `jacquard-lexicon`) 171 172### Fixed 173 174- slingshot resolver no longer spuriously warns when cross-validating handles 175 176## [0.9.0] - 2025-11-03 177 178### Added 179 180**Runtime schema validation** (`jacquard-lexicon`) 181- `SchemaValidator` for validating `Data` values against lexicon schemas 182- CID-based validation caching for efficient repeated validation 183- `ValidationResult` with structural and constraint error separation 184- Comprehensive error types: `StructuralError` (type mismatches, missing fields, union errors) and `ConstraintError` (length, grapheme, numeric bounds) 185- `ValidationPath` for precise error location reporting 186- Ref cycle detection with configurable max depth 187- Support for validating partial/malformed data without full deserialization 188 189**Value query DSL** (`jacquard-common`) 190- Pattern-based querying of nested `Data` structures 191- `data.query(pattern)` with expressive syntax: 192 - `field.nested` - exact path navigation 193 - `[..]` - wildcard over collections (array elements or object values) 194 - `field..nested` - scoped recursion (find nested within field, expect one) 195 - `...field` - global recursion (find all occurrences anywhere) 196- `QueryResult` enum with `Single`, `Multiple`, and `None` variants 197- `QueryMatch` with path tracking for multiple results 198- Iterator support via `.values()`, `.first()`, `.single()`, `.multiple()` 199 200**Data value enhancements** (`jacquard-common`) 201- `get_at_path()` for simple path-based field access on `Data` and `RawData` 202- Path syntax: `embed.images[0].alt` for navigating nested structures 203- `type_discriminator()` helper methods for AT Protocol union discrimination 204- Returns `$type` field value for objects with type discriminators 205- Added on `Data`, `Object`, and `RawData` types 206- Collection helper methods: `get()`, `contains_key()`, `len()`, `is_empty()`, `iter()`, `keys()`, `values()` 207- Index operator support: `obj["key"]` and `arr[0]` 208 209**Lexicon resolution** (`jacquard-identity`) 210- `LexiconResolver` for fetching lexicon schemas from AT Protocol services 211- Resolves lexicons from PDS instances and lexicon hosts 212- `resolve_lexicon()` fetches and parses lexicon schemas 213- `resolve_lexicon_raw()` fetches raw schema JSON 214- New example: `resolve_lexicon.rs` 215 216**Identity resolver caching** (`jacquard-identity`) 217- Optional `cache` feature with configurable in-memory caching 218- `JacquardResolver::with_cache()` constructor for cached resolver 219- Separate TTLs for handle→DID, DID→doc, and lexicon resolution 220 221**XRPC client improvements** (`jacquard-common`, `jacquard`, `jacquard-oauth`) 222- `set_options()` and `set_endpoint()` methods on `XrpcClient` trait 223- Default no-op implementations for stateless clients 224- Enables runtime reconfiguration of stateful clients 225- Better support for custom endpoint and option overrides 226 227**Lexicon schema generation from Rust types** (`jacquard-derive`, `jacquard-lexicon`) 228- New `#[derive(LexiconSchema)]` macro for generating lexicon schemas from Rust structs 229- New `#[lexicon_union]` attribute macro for lexicon union types (tagged enums) 230- Automatic schema generation for custom lexicons without writing JSON manually 231- Field-level attributes: `ref` for explicit type references, `union` for union fields 232- Fragment support for multi-def lexicons via `fragment = "..."` attribute 233- Generates `LexiconDoc` at compile time for runtime validation 234- Enables type-safe custom lexicon development 235 236**Lexicon codegen improvements** (`jacquard-lexicon`, `jacquard-api`) 237- Vendored in an implementation of the typed builder pattern from `bon` to **substantially** improve compile times 238- Feature-gated heavy code generation features so `jacquard-api` and other consumers of the validation capabilities don't pay the `syn` tax as badly. 239- LexiconSchema trait generated implementations for runtime validation 240 241**Session store improvements** (`jacquard`) 242- Improved trait bounds for `SessionStore` implementations 243- Better ergonomics for credential session types 244- Memory-based credential session helpers 245 246**New crate: `jacquard-lexgen`** 247- Lexicon code generation tooling extracted from `jacquard-lexicon` 248- Separates binary/CLI tools from library code 249- Contains lexicon fetching and code generation binaries 250- `jacquard-lexicon` remains as pure library for lexicon parsing, code generation, and validation 251 252**Examples** 253- `app_password_create_post.rs`: App password authentication example 254 255### Changed 256 257**Feature gating** (`jacquard-identity`) 258- Better conditional compilation for platform-specific features 259- Improved WASM target support 260 261**Dependency updates** 262- Updated to latest lexicons from atproto/bluesky 263- Added workspace dependencies: sha2, multihash, dashmap, cid 264- Various minor dependency version updates 265 266### Fixed 267 268**File auth store** (`jacquard`) 269- Fixed serialization/deserialization bugs in `FileAuthStore` implementation 270 271**Packaging** (`jacquard-lexgen`) 272- Added Nix flake apps for lexicon tools 273 274## [0.8.0] - 2025-10-23 275 276### Breaking Changes 277 278**Error type refactor** (`jacquard-common`, `jacquard-identity`, `jacquard-oauth`, `jacquard`) 279- Better error messages with contextual information and help text 280- Breaking: Error variant names and structures changed across all crates 281 282### Added 283 284**New crate: `jacquard-repo`** 285- AT Protocol repository primitives for working with atproto data structures 286- **MST (Merkle Search Tree)**: Immutable, deterministic tree operations with proper fanout 287 - Optimized block allocation (4.5% oversupply, validated against retr0id's test suite) 288 - Diff operations with protocol limit enforcement 289 - Cursor-based traversal 290- **Commits**: 291 - Proof generation and validation for Sync v1 and v1.1 Relay protocol 292- **CAR I/O**: 293 - Proof CAR validation with MST path verification 294- **Storage**: Pluggable block storage abstraction 295 - `MemoryBlockStore`: In-memory storage for testing 296 - `FileBlockStore`: Persistent file-based storage 297 - `LayeredBlockStore`: Layered read-through cache (memory over file, etc.) 298 299### Changed 300 301- Dependency updates (upgraded various crypto and serialization dependencies) 302- Documentation improvements throughout 303- Made handle parsing a bit more permissive for a common case ('handle.invalid' when someone has a messed up handle), added a method to confirm syntactic validity (the correct way to confirm validity is resolve_handle() from IdentityResolver, and comparing to the DID document). 304 305## [0.7.0] - 2025-10-19 306 307### Added 308 309**Bluesky-style rich text utilities** (`jacquard`) 310- Rich text parsing with automatic facet detection (mentions, links, hashtags) 311- Compatible with Bluesky, with the addition of support for markdown-style links (`[display](url)` syntax) 312- Embed candidate detection from URLs and at-URIs 313 - Record embeds (posts, lists, starter packs, feeds) 314 - External embeds with optional OpenGraph metadata fetching 315- Configurable embed domains for at-URI extraction (default: bsky.app, deer.social, blacksky.community, catsky.social) 316- Overlap detection and validation for facet byte ranges 317 318**Moderation/labeling client utilities** (`jacquard`) 319- Trait-based content moderation with `Labeled` and `Moderateable` traits 320- Generic moderation decision making via `moderate()` and `moderate_all()` 321- User preference handling (`ModerationPrefs`) with global and per-labeler overrides 322- `ModerationIterExt` trait for filtering/mapping moderation over iterators 323- `Labeled` implementations for Bluesky types (PostView, ProfileView, ListView, Generator, Notification, etc.) 324- `Labeled` implementations for community lexicons (net.anisota, social.grain) 325- `fetch_labels()` and `fetch_labeled_record()` helpers for retrieving labels via XRPC 326- `fetch_labeler_defs()` and `fetch_labeler_defs_direct()` for fetching labeler definitions 327 328**Subscription control** (`jacquard-common`) 329- `SubscriptionControlMessage` trait for dynamic subscription configuration 330- `SubscriptionController` for sending control messages to active WebSocket subscriptions 331- Enables runtime reconfiguration of subscriptions (e.g., Jetstream filtering) 332 333**Lexicons** (`jacquard-api`) 334- teal.fm alpha lexicons for music sharing (fm.teal.alpha.*) 335 - Actor profiles with music service status 336 - Feed generation from play history 337 - Statistics endpoints (top artists, top releases, user stats) 338 339**Examples** 340- Updated `create_post.rs` to demonstrate richtext parsing with automatic facet detection 341- New `moderated_timeline.rs` to demonstrate fetching timeline with labelers enabled and applying moderation decisions 342 343### Fixed 344 345**Data deserialization** (`jacquard-common`) 346- Fixed `Option<Vec<T>>` deserialization from `Data` values 347- Implemented explicit `deserialize_option` for `Data` and `RawData` deserializers 348- Properly handles null vs present array values when deserializing into optional fields 349 350 351## [0.6.0] - 2025-10-18 352 353### Added 354 355**HTTP streaming support** (`jacquard-common`, `jacquard`) 356- `HttpClientExt` trait for streaming HTTP requests/responses 357- `send_http_streaming()` for streaming response bodies 358- `send_http_bidirectional()` for streaming both request and response 359- `StreamingResponse` wrapper type with parts + `ByteStream` 360- `XrpcResponseStream<R>` for typed XRPC streaming responses 361- `ByteStream` / `ByteSink` platform-agnostic stream wrappers (uses n0-future) 362- `StreamError` concrete error type with kind enum (Transport, Closed, Protocol) 363- Native support via reqwest's `bytes_stream()` and `Body::wrap_stream()` 364- WASM compatibility via n0-future (no Send bounds required) 365 366 367**WebSocket subscription support** (`jacquard-common`) 368- Full XRPC WebSocket subscription infrastructure 369- `SubscriptionResp` trait for defining subscription message/error types 370- `XrpcSubscription` trait for subscription parameters 371- `SubscriptionStream<S>` typed wrapper with automatic message decoding 372- `SubscriptionClient` stateful trait + `TungsteniteSubscriptionClient` implementation 373- `SubscriptionExt` for stateless subscription calls 374- Support for both JSON and DAG-CBOR message encodings 375- Custom path support via `CUSTOM_PATH` constant for non-XRPC endpoints 376- WebSocket integration into `Agent` struct (agents can now subscribe) 377- `into_stream()`, `into_raw_data_stream()`, `into_data_stream()` methods for different deserialization modes 378 379**Framed DAG-CBOR message decoding** (`jacquard-common`, `jacquard-api`, `jacquard-lexicon`) 380- Two-stage deserialization for AT Protocol event streams (header + body) 381- `EventHeader` struct and `parse_event_header()` function 382- `decode_framed()` methods generated for all DAG-CBOR subscription message enums 383- `decode_message()` override in `SubscriptionResp` trait for custom decoding 384- `UnknownEventType` variant in `DecodeError` for unknown discriminators 385- Fixes "TrailingData" errors when consuming subscribeRepos and subscribeLabels 386 387**Jetstream support** (`jacquard-common`) 388- Full typed support for Jetstream JSON firehose 389- `JetstreamMessage` enum with `Commit`, `Identity`, `Account` variants 390- `JetstreamCommit`, `JetstreamIdentity`, `JetstreamAccount` detail structs 391- `CommitOperation` enum for create/update/delete operations 392- `JetstreamParams` with filtering options (collections, DIDs, cursor, compression) 393- Uses proper AT Protocol types (`Did`, `Handle`, `Datetime`, `Data`) 394 395**Zstd compression** (`jacquard-common`) 396- Optional `zstd` feature for Jetstream message decompression 397- Automatic detection and decompression of zstd-compressed binary frames 398- Includes official Bluesky Jetstream zstd dictionary 399- Transparent fallback to uncompressed when zstd unavailable 400- Works across all JSON stream methods (`into_stream()`, `into_raw_data_stream()`, `into_data_stream()`) 401 402**Typed AT URI wrapper** (`jacquard-common`, `jacquard-api`, `jacquard-lexicon`) 403- `AtUri<'a>` newtype wrapper for `at://` URIs with proper validation 404- Generated `fetch_uri()` method on all record types for fetching by AT URI 405- `AtUri::from_parts()` constructor for building URIs from components 406- Proper Display and FromStr implementations 407 408**Memory-based credential session helpers** (`jacquard`) (ty [@vielle.dev](https://tangled.org/@vielle.dev)) 409 410**Axum improvements** (`jacquard-axum`) 411- `XrpcError` now implements `IntoResponse` for better error handling 412- Proper typed error responses without manual conversion 413- Better integration with Axum's response system 414 415**Examples** 416- `subscribe_repos.rs`: Subscribe to PDS firehose with typed DAG-CBOR messages 417- `subscribe_jetstream.rs`: Subscribe to Jetstream with typed JSON messages and optional compression 418- `stream_get_blob.rs`: Download blobs using HTTP streaming 419- `app_password_example.rs`: App password authentication example (ty [@vielle.dev](https://tangled.org/@vielle.dev)) 420 421**CID deserialization improvements** (`jacquard-common`) 422- Fixed `Cid` type to properly deserialize CBOR tag 42 via `IpldCid::deserialize` 423- Separate handling for JSON (string) vs CBOR (tag 42) formats 424- `CidLink` correctly delegates to `Cid` for both formats 425 426### Changed 427 428**Default features** (`jacquard-common`) 429- Added `zstd` to default features for better Jetstream experience 430- Jetstream compression enabled by default when using the full feature set 431 432**Generated code** (`jacquard-lexicon`, `jacquard-api`) 433- All DAG-CBOR subscriptions (subscribeRepos, subscribeLabels) now use framed decoding 434- Generated `decode_framed()` implementations match on event type discriminator 435- Override `decode_message()` in trait impls to use framed decoding 436- All record types now have `fetch_uri()` and `fetch_record()` methods generated 437 438**Dependencies** (`jacquard-axum`) (ty [@thoth.ptnote.dev](https://tangled.org/@thoth.ptnote.dev)) 439- Disabled default features for `jacquard` dependency to reduce bloat 440 441### Fixed 442 443**Blob upload** (`jacquard`) (ty [@vielle.dev](https://tangled.org/@vielle.dev) for reporting this one) 444- Fixed `upload_blob()` authentication issues 445- Properly authenticates while allowing custom Content-Type headers 446 447**XRPC client** (`jacquard-common`, `jacquard-oauth`, `jacquard`) 448- Added `send_with_options()` method for per-request option overrides 449- Stateful clients can now override options while preserving internal auth 450 451 452--- 453 454## `jacquard-api` [0.5.5], `jacquard-lexicon` [0.5.4] - 2025-10-16 455 456### Fixed 457 458- events.smokesignal.invokeWebhook lexicon now generates valid code 459- lexicon code generation now uses `Data` for blank objects, rather than naming and then failing to generate a struct 460 461## [0.5.4] - 2025-10-16 462 463### Added 464 465**Initial streaming client support** (`jacquard-common`) 466- First primitives for streamed requests and responses 467 468**`send_with_options()` method on XrpcClient** (`jacquard-common`, `jacquard-oauth`, `jacquard`) 469- allows setting custom options per request in stateful client 470- updated oauth and credential session clients to use it 471- implementations should generally override provided auth with own internal auth 472 473**Prelude providing common traits into scope** 474 475### Fixed 476 477**`AgentSessionExt::upload_blob()` failed to authenticate** (`jacquard`) 478- new `XrpcClient::send_with_options()` method now allows properly overriding the content-type header while still handling auth internally 479 480## [0.5.3] - 2025-10-15 481 482### Added 483 484**Experimental WASM Support** (`jacquard-common`, `jacquard-api`, `jacquard-identity`, `jacquard-oauth`) 485- Core crates now compile for `wasm32-unknown-unknown` target 486- Traits use `trait-variant` to conditionally exclude `Send` bounds on WASM 487- Platform-specific trait method implementations for methods with `Self: Sync` bounds 488- DNS-based handle resolution remains gated behind `dns` feature (unavailable on WASM) 489- HTTPS well-known and PDS resolution work on all platforms 490 491### Fixed 492 493**OAuth client** (`jacquard-oauth`) 494- Fixed tokio runtime detection for non-WASM targets 495- Conditional compilation for tokio-specific features 496 497 498--- 499 500## [0.5.2] - 2025-10-14 501 502### Added 503 504**Value type deserialization** (`jacquard-common`) 505- `from_json_value()`: Deserialize typed data directly from `serde_json::Value` without borrowing 506- `from_data_owned()`, `from_raw_data_owned()`: Owned deserialization helpers 507- `Data::from_json_owned()`: Parse JSON into owned `Data<'static>` 508- `IntoStatic` implementation for `RawData` enabling owned conversions 509- Re-exported value types from crate root for easier imports 510- `Deserializer` trait implementations for `Data<'static>` and `RawData<'static>` 511- Owned deserializer helpers: `OwnedArrayDeserializer`, `OwnedObjectDeserializer`, `OwnedBlobDeserializer` 512 513**Service Auth** (`jacquard-axum`, `jacquard-common`) 514- Full service authentication implementation for inter-service JWT verification 515- `ExtractServiceAuth` Axum extractor for validating service auth tokens 516- Axum service auth middleware 517- JWT parsing and signature verification (ES256, ES256K) 518- Service auth claims validation (issuer, audience, expiration, method binding) 519- DID document resolution for signing key verification 520 521**XrpcRequest derive macro** (`jacquard-derive`) 522- `#[derive(XrpcRequest)]` for custom XRPC endpoints 523- Automatically generates response marker struct and trait implementations 524- Supports both client-side (`XrpcRequest`) and server-side (`XrpcEndpoint`) with `server` flag 525- Simplifies defining custom XRPC endpoints outside of generated API 526 527**Builder integration** (`jacquard-derive`) 528- `#[lexicon]` macro now detects `bon::Builder` derive 529- Automatically adds `#[builder(default)]` to `extra_data` field when Builder is present 530- Makes `extra_data` optional in generated builders 531 532### Fixed 533 534**String deserialization** (`jacquard-common`) 535- All string types (Did, Handle, Nsid, etc.) now properly handle URL-encoded values 536- `serde_html_form` correctly decodes percent-encoded characters during deserialization 537- Fixes issues with DIDs and other identifiers containing colons in query parameters 538 539**Axum extractor** (`jacquard-axum`) 540- Removed unnecessary URL-decoding workaround (now handled by improved string deserialization) 541- Added comprehensive tests for URL-encoded query parameters 542- Cleaner implementation with proper delegation to serde 543 544### Changed 545 546**Dependencies** 547- Moved `clap` to dev-dependencies in `jacquard` (only used in examples) 548- Moved `axum-macros` and `tracing-subscriber` to dev-dependencies in `jacquard-axum` (only used in examples) 549- Removed unused dependencies: `urlencoding` (jacquard, jacquard-axum), `uuid` (jacquard-oauth), `serde_with` (jacquard-common) 550- Removed `fancy` feature from `jacquard` (design smell for library crates) 551- Moved various proc-macro crate dependencies to dev-dependencies in `jacquard-derive` 552 553**Development tooling** 554- Improved justfile with dynamic example discovery 555- `just examples` now auto-discovers all examples 556- `just example <name>` auto-detects package without manual configuration 557- Better error messages when examples not found 558 559**Documentation** (`jacquard`, `jacquard-common`) 560- Improved lifetime pattern explanations 561- Better documentation of zero-copy deserialization approach 562- Links to docs.rs for generated documentation 563 564--- 565 566## [0.5.1] - 2025-10-13 567 568### Fixed 569 570**Trait bounds** (`jacquard-common`) 571- Removed lifetime parameter from `XrpcRequest` trait, simplifying trait bounds 572- Lifetime now only appears on `XrpcEndpoint::Request<'de>` associated type 573- Fixes issues with using XRPC types in async contexts like Axum extractors 574 575### Changed 576 577- Updated all workspace crates to 0.5.1 for consistency 578- `jacquard-axum` remains at 0.5.1 (unchanged) 579 580--- 581 582## `jacquard-axum` [0.5.1] - 2025-10-13 583 584### Fixed 585 586- Axum extractor now sets the correct Content-Type header during error path. 587 588--- 589 590## [0.5.0] - 2025-10-13 591 592### Added 593 594**Agent convenience methods** (`jacquard`) 595- New `AgentSessionExt` trait automatically implemented for `AgentSession + IdentityResolver` 596- **Basic CRUD**: `create_record()`, `get_record()`, `put_record()`, `delete_record()` 597- **Update patterns**: `update_record()` (fetch-modify-put), `update_vec()`, `update_vec_item()` 598- **Blob operations**: `upload_blob()` 599- All methods auto-fill repo from session or URI parameter as relevant, and collection from type's `Collection::NSID` 600 601**VecUpdate trait** (`jacquard`) 602- `VecUpdate` trait for fetch-modify-put patterns on array-based endpoints 603- `PreferencesUpdate` implementation for updating Bluesky user preferences 604- Enables simpler updates to preferences and other 'array of union' types 605 606**Typed record retrieval** (`jacquard-api`, `jacquard-common`, `jacquard-lexicon`) 607- Each collection generates `{Type}Record` marker struct implementing `XrpcResp` 608- `Collection::Record` associated type points to the marker 609- `get_record::<R>()` returns `Response<R::Record>` with zero-copy `.parse()` 610- Response transmutation enables type-safe record operations 611 612**Examples** 613- `create_post.rs`: Creating posts with Agent convenience methods 614- `update_profile.rs`: Updating profile with fetch-modify-put 615- `post_with_image.rs`: Uploading images and creating posts with embeds 616- `update_preferences.rs`: Using VecUpdate for preferences 617- `create_whitewind_post.rs`, `read_whitewind_post.rs`: Third-party lexicons 618- `read_tangled_repo.rs`: Reading git repo metadata from tangled.org 619- `resolve_did.rs`: Identity resolution examples 620- `public_atproto_feed.rs`: Unauthenticated feed access 621- `axum_server.rs`: Server-side XRPC handler 622 623 624**Documentation** (`jacquard`) 625- A whole host of examples added, as well as a lengthy explainer of the trait patterns. 626 627## [0.4.1] - 2025-10-13 628 629### Added 630 631**Collection trait improvements** (`jacquard-api`) 632- Generated `{Type}Record` marker structs for all record types 633- Each implements `XrpcResp` with `Output<'de> = {Type}<'de>` and `Err<'de> = RecordError<'de>` 634- Enables typed `get_record` returning `Response<R::Record>` 635 636### Changed 637 638- Minor improvements to derive macros (`jacquard-derive`) 639- Identity resolution refinements (`jacquard-identity`) 640- OAuth client improvements (`jacquard-oauth`) 641 642--- 643 644## [0.4.0] - 2025-10-11 645 646### Breaking Changes 647 648**Zero-copy deserialization** (`jacquard-common`, `jacquard-api`) 649- `XrpcRequest` now takes a `'de` lifetime parameter and requires `Deserialize<'de>` 650- For raw data, `Response::parse_data()` gives validated loosely-typed atproto data, while `Response::parse_raw()` gives the raw values, with minimal validation. 651 652**XRPC module moved** (`jacquard-common`) 653- `xrpc.rs` is now top-level instead of under `types` 654- Import from `jacquard_common::xrpc::*` not `jacquard_common::types::xrpc::*` 655 656**Response API changes** (`jacquard-common`) 657- `XrpcRequest::Output` and `XrpcRequest::Err` are associated types with lifetimes 658- Split response and request traits: `XrpcRequest<'de>` for client, `XrpcEndpoint` for server 659- Added `XrpcResp` marker trait 660 661**Various traits** (`jacquard`, `jacquard-common`, `jacquard-lexicon`, `jacquard-oauth`) 662- Removed #[async_trait] attribute macro usage in favour of `impl Future` return types with manual bounds. 663- Boxing imposed by asyc_trait negatively affected borrowing modes in async methods. 664- Currently no semver guarantees on API trait bounds, if they need to tighten, they will. 665 666### Added 667 668**New crate: `jacquard-axum`** 669- Server-side XRPC handlers for Axum 670- `ExtractXrpc<R>` deserializes incoming requests (query params for Query, body for Procedure) 671- Automatic error responses 672 673**Lexicon codegen fixes** (`jacquard-lexicon`) 674- Union variant collision detection: when multiple namespaces have similar type names, foreign ones get prefixed (e.g., `Images` vs `BskyImages`) 675- Token types generate unit structs with `Display` instead of being skipped 676- Namespace dependency tracking during union generation 677- `generate_cargo_features()` outputs Cargo.toml features with correct deps 678- `sanitize_name()` ensures valid Rust identifiers 679 680**Lexicons** (`jacquard-api`) 681 682Added 646 lexicon schemas. Highlights: 683 684Core ATProto: 685- `com.atproto.*` 686- `com.bad-example.*` for identity resolution 687 688Bluesky: 689- `app.bsky.*` bluesky app 690- `chat.bsky.*` chat client 691- `tools.ozone.*` moderation 692 693Third-party: 694- `sh.tangled.*` - git forge 695- `sh.weaver.*` - orual's WIP markdown blog platform 696- `pub.leaflet.*` - longform publishing 697- `net.anisota.*` - gamified and calming take on bluesky 698- `network.slices.*` - serverless atproto hosting 699- `tools.smokesignal.*` - automation 700- `com.whtwnd.*` - markdown blogging 701- `place.stream.*` - livestreaming 702- `blue.2048.*` - 2048 game 703- `community.lexicon.*` - community extensions (bookmarks, calendar, location, payments) 704- `my.skylights.*` - media tracking 705- `social.psky.*` - social extensions 706- `blue.linkat.*` - link boards 707 708Plus 30+ more experimental/community namespaces. 709 710**Value types** (`jacquard-common`) 711- `RawData` to `Data` conversion with type inference 712- `from_data`, `from_raw_data`, `to_data`, and `to_raw_data` to serialize to and deserialize from the loosely typed value data formats. Particularly useful for second-stage deserialization of type "unknown" fields in lexicons, such as `PostView.record`. 713 714### Changed 715 716- `generate_union()` takes current NSID for dependency tracking 717- Generated code uses `sanitize_name()` for identifiers more consistently 718- Added derive macro for IntoStatic trait implementation 719 720### Fixed 721 722- Methods to extract the output from an XRPC response now behave well with respect to lifetimes and borrowing. 723- Now possible to use jacquard types in places like axum extractors due to lifetime improvements 724- Union variants don't collide when multiple namespaces define similar types and another namespace includes them 725 726---