From 5448a3c389ce237c0ee7e9761ada2e5fb9e060dd Mon Sep 17 00:00:00 2001 From: Seongmin Lee Date: Fri, 24 Jul 2026 19:35:14 +0900 Subject: [PATCH] bobbin: add jacquard identity resolver to AppState Signed-off-by: Seongmin Lee --- Cargo.lock | 53 +++++++++++++++++++++++++ Cargo.toml | 1 + bobbin/crates/bobbin/Cargo.toml | 2 + bobbin/crates/bobbin/src/main.rs | 17 ++++++++ bobbin/crates/xrpc/Cargo.toml | 1 + bobbin/crates/xrpc/src/lib.rs | 4 ++ bobbin/crates/xrpc/tests/aggregation.rs | 1 + bobbin/crates/xrpc/tests/bulk.rs | 1 + bobbin/crates/xrpc/tests/cold_start.rs | 1 + bobbin/crates/xrpc/tests/coverage.rs | 1 + bobbin/crates/xrpc/tests/enrich.rs | 1 + bobbin/crates/xrpc/tests/extended.rs | 1 + bobbin/crates/xrpc/tests/knot_proxy.rs | 1 + bobbin/crates/xrpc/tests/search.rs | 1 + 14 files changed, 86 insertions(+) diff --git a/Cargo.lock b/Cargo.lock index 14f07b6e..564f053d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -351,6 +351,8 @@ dependencies = [ "clap", "confique", "futures", + "jacquard-common", + "jacquard-identity", "serde", "socket2", "thiserror 2.0.18", @@ -586,6 +588,7 @@ dependencies = [ "futures", "http", "jacquard-common", + "jacquard-identity", "serde", "serde_json", "thiserror 2.0.18", @@ -2104,6 +2107,29 @@ dependencies = [ "syn", ] +[[package]] +name = "jacquard-identity" +version = "0.12.0-beta.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49da1f0a0487051529a70891dac0d1c6699f47b95854514402b2642e66d96c7c" +dependencies = [ + "bon", + "bytes", + "http", + "jacquard-common", + "jacquard-lexicon", + "miette", + "mini-moka-wasm", + "n0-future", + "reqwest", + "serde", + "serde_html_form", + "serde_json", + "thiserror 2.0.18", + "tokio", + "trait-variant", +] + [[package]] name = "jacquard-lexicon" version = "0.12.0-beta.2" @@ -2361,6 +2387,21 @@ version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" +[[package]] +name = "mini-moka-wasm" +version = "0.10.99" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0102b9a2ad50fa47ca89eead2316c8222285ecfbd3f69ce99564fbe4253866e8" +dependencies = [ + "crossbeam-channel", + "crossbeam-utils", + "dashmap", + "smallvec", + "tagptr", + "triomphe", + "web-time", +] + [[package]] name = "minimal-lexical" version = "0.2.1" @@ -3863,6 +3904,12 @@ dependencies = [ "libc", ] +[[package]] +name = "tagptr" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b2093cf4c8eb1e67749a6762251bc9cd836b6fc171623bd0a9d324d37af2417" + [[package]] name = "tantivy" version = "0.26.1" @@ -4473,6 +4520,12 @@ dependencies = [ "syn", ] +[[package]] +name = "triomphe" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b40688ea6389c8171614b25491f71d4a27946e0c7ce2da1c6de27e25abf1a0ae" + [[package]] name = "try-lock" version = "0.2.5" diff --git a/Cargo.toml b/Cargo.toml index af637e65..0a71f3fc 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -45,6 +45,7 @@ bobbin-xrpc = { path = "bobbin/crates/xrpc" } jacquard-common = "0.12.0-beta.2" jacquard-derive = "0.12.0-beta.2" jacquard-lexicon = { version = "0.12.0-beta.2", default-features = false } +jacquard-identity = { version = "0.12.0-beta.2", features = ["cache"] } anyhow = "1" miette = "7" diff --git a/bobbin/crates/bobbin/Cargo.toml b/bobbin/crates/bobbin/Cargo.toml index 6ee7112b..e53a3ff4 100644 --- a/bobbin/crates/bobbin/Cargo.toml +++ b/bobbin/crates/bobbin/Cargo.toml @@ -19,6 +19,8 @@ bobbin-runtime = { workspace = true } bobbin-search = { workspace = true } bobbin-slingshot-client = { workspace = true } bobbin-xrpc = { workspace = true } +jacquard-common = { workspace = true } +jacquard-identity = { workspace = true } axum = { workspace = true } serde = { workspace = true, features = ["derive"] } diff --git a/bobbin/crates/bobbin/src/main.rs b/bobbin/crates/bobbin/src/main.rs index bdb082dd..c67d0e54 100644 --- a/bobbin/crates/bobbin/src/main.rs +++ b/bobbin/crates/bobbin/src/main.rs @@ -19,9 +19,13 @@ use bobbin_runtime::{ }; use bobbin_search::{SearchIndex, SearchReader}; use bobbin_slingshot_client::SlingshotClient; +use bobbin_slingshot_client::default_http_client; use bobbin_xrpc::{ AppState, HeavyLimiter, MaxInFlight, PerRequestAnonBytes, ReservedFloor, router, }; +use jacquard_common::deps::fluent_uri::Uri; +use jacquard_identity::JacquardResolver; +use jacquard_identity::resolver::{DidStep, PlcSource, ResolverOptions}; use clap::{Parser, Subcommand}; use tokio::signal::unix::{SignalKind, signal}; use tokio::task::JoinHandle; @@ -180,6 +184,18 @@ async fn run(cfg: BobbinConfig) -> anyhow::Result<()> { let records: Arc = Arc::new(LruRecordStore::new(CacheCapacity::from_bytes(lru_cap))); let slingshot = SlingshotClient::with_default_http(cfg.slingshot.url.clone())?; + let mut resolver_opts = ResolverOptions::default(); + // NOTE: see https://tangled.org/nonbinary.computer/jacquard/issues/39. + resolver_opts.did_order = vec![DidStep::DidWebHttps, /* DidStep::PlcHttp, */ DidStep::PdsResolveDid]; + let directory = Arc::new( + JacquardResolver::new(default_http_client()?, resolver_opts) + .with_plc_source(PlcSource::Slingshot { + base: Uri::parse(cfg.slingshot.url.as_str()) + .context("slingshot url is not a valid URI")? + .to_owned(), + }) + .with_cache(), + ); let resolver = Arc::new(RepoIdResolver::with_slingshot( slingshot.clone(), clock.clone(), @@ -315,6 +331,7 @@ async fn run(cfg: BobbinConfig) -> anyhow::Result<()> { knots, search as Arc, resolver, + directory, ) .with_limiter(limiter); let app = router(state); diff --git a/bobbin/crates/xrpc/Cargo.toml b/bobbin/crates/xrpc/Cargo.toml index 797dde60..a73aecc9 100644 --- a/bobbin/crates/xrpc/Cargo.toml +++ b/bobbin/crates/xrpc/Cargo.toml @@ -15,6 +15,7 @@ bobbin-search = { workspace = true } bobbin-slingshot-client = { workspace = true } bobbin-knot-proxy = { workspace = true } jacquard-common = { workspace = true } +jacquard-identity = { workspace = true } axum = { workspace = true } chrono = { workspace = true } diff --git a/bobbin/crates/xrpc/src/lib.rs b/bobbin/crates/xrpc/src/lib.rs index 6a70a2f0..a6e0f3ed 100644 --- a/bobbin/crates/xrpc/src/lib.rs +++ b/bobbin/crates/xrpc/src/lib.rs @@ -33,6 +33,7 @@ use bobbin_search::{ SearchCursor, SearchError, SearchFilters, SearchHit, SearchOffset, SearchReader, }; use bobbin_slingshot_client::{SlingshotClient, SlingshotError}; +use jacquard_identity::JacquardResolver; use bobbin_types::ids::{EdgeKey, SubjectRef, nsid_static}; use bobbin_types::knot_acl::{KnotOwnedSource, decode_knot_owned_source, knot_did_host}; use bobbin_types::record::RecordBody; @@ -120,6 +121,7 @@ pub struct AppState { pub knots: Arc, pub search: Arc, pub resolver: Arc, + pub directory: Arc, pub limiter: Option>, enrich_router: Arc>, } @@ -136,6 +138,7 @@ impl AppState { knots: Arc, search: Arc, resolver: Arc, + directory: Arc, ) -> Self { Self { records, @@ -147,6 +150,7 @@ impl AppState { knots, search, resolver, + directory, limiter: None, enrich_router: Arc::new(std::sync::OnceLock::new()), } diff --git a/bobbin/crates/xrpc/tests/aggregation.rs b/bobbin/crates/xrpc/tests/aggregation.rs index 8c61e077..f7eb54b7 100644 --- a/bobbin/crates/xrpc/tests/aggregation.rs +++ b/bobbin/crates/xrpc/tests/aggregation.rs @@ -92,6 +92,7 @@ impl Harness { SearchIndex::new(DEFAULT_WRITER_HEAP_BYTES, Arc::new(SystemClock::new())).unwrap(), ) as Arc, Arc::new(RepoIdResolver::detached(RuntimeHasher::default())), + Arc::new(jacquard_identity::JacquardResolver::default()), ); Self { server, diff --git a/bobbin/crates/xrpc/tests/bulk.rs b/bobbin/crates/xrpc/tests/bulk.rs index 06cee45b..5cc80eb5 100644 --- a/bobbin/crates/xrpc/tests/bulk.rs +++ b/bobbin/crates/xrpc/tests/bulk.rs @@ -69,6 +69,7 @@ impl Harness { SearchIndex::new(DEFAULT_WRITER_HEAP_BYTES, Arc::new(SystemClock::new())).unwrap(), ) as Arc, Arc::new(RepoIdResolver::detached(RuntimeHasher::default())), + Arc::new(jacquard_identity::JacquardResolver::default()), ); Self { server, state } } diff --git a/bobbin/crates/xrpc/tests/cold_start.rs b/bobbin/crates/xrpc/tests/cold_start.rs index 30bc3bea..4077f73c 100644 --- a/bobbin/crates/xrpc/tests/cold_start.rs +++ b/bobbin/crates/xrpc/tests/cold_start.rs @@ -56,6 +56,7 @@ async fn fresh_app(server_uri: &Url) -> AppState { Arc::new(SearchIndex::new(DEFAULT_WRITER_HEAP_BYTES, Arc::new(SystemClock::new())).unwrap()) as Arc, Arc::new(RepoIdResolver::detached(RuntimeHasher::default())), + Arc::new(jacquard_identity::JacquardResolver::default()), ) } diff --git a/bobbin/crates/xrpc/tests/coverage.rs b/bobbin/crates/xrpc/tests/coverage.rs index bc89a13c..ca10ac2c 100644 --- a/bobbin/crates/xrpc/tests/coverage.rs +++ b/bobbin/crates/xrpc/tests/coverage.rs @@ -44,6 +44,7 @@ impl Harness { SearchIndex::new(DEFAULT_WRITER_HEAP_BYTES, Arc::new(SystemClock::new())).unwrap(), ) as Arc, Arc::new(RepoIdResolver::detached(RuntimeHasher::default())), + Arc::new(jacquard_identity::JacquardResolver::default()), ); Self { coverage, state } } diff --git a/bobbin/crates/xrpc/tests/enrich.rs b/bobbin/crates/xrpc/tests/enrich.rs index 3f4daac2..0f6f8627 100644 --- a/bobbin/crates/xrpc/tests/enrich.rs +++ b/bobbin/crates/xrpc/tests/enrich.rs @@ -73,6 +73,7 @@ impl Harness { SearchIndex::new(DEFAULT_WRITER_HEAP_BYTES, Arc::new(SystemClock::new())).unwrap(), ) as Arc, Arc::new(RepoIdResolver::detached(RuntimeHasher::default())), + Arc::new(jacquard_identity::JacquardResolver::default()), ); Self { server, diff --git a/bobbin/crates/xrpc/tests/extended.rs b/bobbin/crates/xrpc/tests/extended.rs index 2c6df453..f0d36037 100644 --- a/bobbin/crates/xrpc/tests/extended.rs +++ b/bobbin/crates/xrpc/tests/extended.rs @@ -81,6 +81,7 @@ impl Harness { SearchIndex::new(DEFAULT_WRITER_HEAP_BYTES, Arc::new(SystemClock::new())).unwrap(), ) as Arc, Arc::new(RepoIdResolver::detached(RuntimeHasher::default())), + Arc::new(jacquard_identity::JacquardResolver::default()), ); Self { server, diff --git a/bobbin/crates/xrpc/tests/knot_proxy.rs b/bobbin/crates/xrpc/tests/knot_proxy.rs index d4bd032c..07737e3b 100644 --- a/bobbin/crates/xrpc/tests/knot_proxy.rs +++ b/bobbin/crates/xrpc/tests/knot_proxy.rs @@ -82,6 +82,7 @@ impl Harness { SearchIndex::new(DEFAULT_WRITER_HEAP_BYTES, Arc::new(SystemClock::new())).unwrap(), ) as Arc, Arc::new(RepoIdResolver::detached(RuntimeHasher::default())), + Arc::new(jacquard_identity::JacquardResolver::default()), ); Self { slingshot: slingshot_server, diff --git a/bobbin/crates/xrpc/tests/search.rs b/bobbin/crates/xrpc/tests/search.rs index e6b6ac9a..b416b5dc 100644 --- a/bobbin/crates/xrpc/tests/search.rs +++ b/bobbin/crates/xrpc/tests/search.rs @@ -76,6 +76,7 @@ impl Harness { ), search.clone() as Arc, Arc::new(RepoIdResolver::detached(RuntimeHasher::default())), + Arc::new(jacquard_identity::JacquardResolver::default()), ); Self { server, -- 2.51.2