A better Rust ATProto crate

moved the examples around

Orual 902ce17a cf2a03ef

+37 -71
+23 -22
README.md
··· 22 22 - Use as much or as little from the crates as you need 23 23 24 24 25 - ### Streaming Support 26 - 27 - Jacquard supports efficient streaming for large payloads: 28 - 29 - - **Blob uploads/downloads**: Stream media without loading into memory 30 - - **CAR file streaming**: Efficient repo sync operations 31 - - **Thin forwarding**: Pipe data between endpoints 32 - - **WebSocket support**: Bidirectional streaming connections 33 - 34 - Enable with the `streaming` feature flag. See `jacquard-common` documentation for details. 35 - 36 25 ## Example 37 26 38 27 Dead simple API client. Logs in with OAuth and prints the latest 5 posts from your timeline. ··· 123 112 - `AgentSessionExt` trait with a host of convenience methods for working with records and preferences 124 113 - Improvements to the `Collection` trait, code generation, and addition of the `VecUpdate` trait to enable that 125 114 115 + 116 + ## Experimental WASM Support 117 + 118 + Core crates (`jacquard-common`, `jacquard-api`, `jacquard-identity`, `jacquard-oauth`) compile for `wasm32-unknown-unknown`. Traits use [`trait-variant`](https://docs.rs/trait-variant) to conditionally exclude `Send` bounds on WASM targets. DNS-based handle resolution is gated behind the `dns` feature and unavailable on WASM (HTTPS well-known and PDS resolution still work). 119 + 120 + Test WASM compilation: 121 + ```bash 122 + just check-wasm 123 + # or: cargo build --target wasm32-unknown-unknown -p jacquard-common --no-default-features 124 + ``` 125 + 126 + 127 + ### Streaming Support 128 + 129 + Jacquard supports efficient streaming for large payloads: 130 + 131 + - **Blob uploads/downloads**: Stream media without loading into memory 132 + - **CAR file streaming**: Efficient repo sync operations 133 + - **Thin forwarding**: Pipe data between endpoints 134 + - **WebSocket support**: Bidirectional streaming connections 135 + 136 + Enable with the `streaming` feature flag. See `jacquard-common` documentation for details. 137 + 126 138 ## Development 127 139 128 140 This repo uses [Flakes](https://nixos.asia/en/flakes) ··· 139 151 ``` 140 152 141 153 There's also a [`justfile`](https://just.systems/) for Makefile-esque commands to be run inside of the devShell, and you can generally `cargo ...` or `just ...` whatever just fine if you don't want to use Nix and have the prerequisites installed. 142 - 143 - 144 - ## Experimental WASM Support 145 - 146 - Core crates (`jacquard-common`, `jacquard-api`, `jacquard-identity`, `jacquard-oauth`) compile for `wasm32-unknown-unknown`. Traits use [`trait-variant`](https://docs.rs/trait-variant) to conditionally exclude `Send` bounds on WASM targets. DNS-based handle resolution is gated behind the `dns` feature and unavailable on WASM (HTTPS well-known and PDS resolution still work). 147 - 148 - Test WASM compilation: 149 - ```bash 150 - just check-wasm 151 - # or: cargo build --target wasm32-unknown-unknown -p jacquard-common --no-default-features 152 - ``` 153 154 154 155 [![License](https://img.shields.io/crates/l/jacquard.svg)](./LICENSE)
-45
crates/jacquard-common/README.md
··· 1 - # jacquard-common 2 - 3 - Core AT Protocol types and HTTP client abstraction for Jacquard. 4 - 5 - ## Features 6 - 7 - ### `streaming` (optional) 8 - 9 - Adds support for streaming HTTP request and response bodies: 10 - 11 - - `ByteStream` / `ByteSink`: Platform-agnostic stream abstractions 12 - - `HttpClientExt`: Streaming methods for HTTP client 13 - - `StreamingResponse`: XRPC streaming response wrapper 14 - - Error types: `StreamError` with `StreamErrorKind` 15 - 16 - Works on both native and WASM targets via `n0-future`. 17 - 18 - **Example:** 19 - ```rust 20 - use jacquard_common::http_client::{HttpClient, HttpClientExt}; 21 - use futures::StreamExt; 22 - 23 - let client = reqwest::Client::new(); 24 - let response = client.send_http_streaming(request).await?; 25 - 26 - let stream = response.into_parts().1.into_inner(); 27 - futures::pin_mut!(stream); 28 - while let Some(chunk) = stream.next().await { 29 - // Process streaming chunks 30 - } 31 - ``` 32 - 33 - ### `websocket` (optional) 34 - 35 - Adds WebSocket client abstraction: 36 - 37 - - `WebSocketClient` trait 38 - - `WebSocketConnection` with bidirectional streams 39 - - Uses same `ByteStream`/`ByteSink` as HTTP streaming 40 - 41 - Requires the `streaming` feature. 42 - 43 - ### `reqwest-client` (optional) 44 - 45 - Implements `HttpClient` and `HttpClientExt` for `reqwest::Client`.
-2
crates/jacquard-common/examples/streaming_download.rs examples/streaming_download.rs
··· 1 1 //! Example: Download large file using streaming 2 - #![cfg(all(feature = "streaming", feature = "reqwest-client"))] 3 - 4 2 use jacquard_common::http_client::HttpClientExt; 5 3 6 4 #[tokio::main]
-1
crates/jacquard-common/examples/streaming_upload.rs examples/streaming_upload.rs
··· 1 1 //! Example: Upload data using streaming request body 2 - #![cfg(all(feature = "streaming", feature = "reqwest-client"))] 3 2 4 3 use bytes::Bytes; 5 4 use futures::stream;
+14 -1
crates/jacquard/Cargo.toml
··· 28 28 # Enable tracing instrumentation 29 29 tracing = ["dep:tracing", "jacquard-common/tracing", "jacquard-oauth/tracing", "jacquard-identity/tracing"] 30 30 dns = ["jacquard-identity/dns"] 31 - 31 + streaming = ["jacquard-common/streaming"] 32 + websocket = ["jacquard-common/websocket"] 32 33 33 34 [[example]] 34 35 name = "oauth_timeline" ··· 70 71 name = "update_preferences" 71 72 path = "../../examples/update_preferences.rs" 72 73 required-features = ["api_bluesky"] 74 + 75 + 76 + [[example]] 77 + name = "streaming_upload" 78 + path = "../../examples/streaming_upload.rs" 79 + required-features = ["api_bluesky", "streaming"] 80 + 81 + [[example]] 82 + name = "streaming_download" 83 + path = "../../examples/streaming_download.rs" 84 + required-features = ["api_bluesky", "streaming"] 85 + 73 86 74 87 [dependencies] 75 88 jacquard-api = { version = "0.5", path = "../jacquard-api" }