feat(server): lightweight s3 client (#14348)

#### PR Dependency Tree


* **PR #14348** 👈

This tree was auto-generated by
[Charcoal](https://github.com/danerwilliams/charcoal)

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Added a dedicated S3-compatible client package and expanded
S3-compatible storage config (endpoint, region, forcePathStyle,
requestTimeoutMs, minPartSize, presign options, sessionToken).
* Document sync now broadcasts batched/compressed doc updates for more
efficient real-time syncing.

* **Tests**
* New unit and benchmark tests for base64 utilities and S3 multipart
listing; updated storage-related tests to match new formats.

<sub>✏️ Tip: You can customize this high-level summary in your review
settings.</sub>
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
DarkSky
2026-02-01 21:54:39 +08:00
committed by GitHub
parent 059d3aa04a
commit f1a6e409cb
37 changed files with 1539 additions and 1712 deletions
+47 -1
View File
@@ -89,11 +89,57 @@ impl TryFrom<DocUpdate> for affine_nbstore::DocUpdate {
timestamp: chrono::DateTime::<chrono::Utc>::from_timestamp_millis(update.timestamp)
.ok_or(UniffiError::TimestampDecodingError)?
.naive_utc(),
bin: update.bin.into(),
bin: Into::<Data>::into(
base64_simd::STANDARD
.decode_to_vec(update.bin)
.map_err(|e| UniffiError::Base64DecodingError(e.to_string()))?,
),
})
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn doc_update_roundtrip_base64() {
let timestamp = chrono::DateTime::<chrono::Utc>::from_timestamp_millis(1_700_000_000_000)
.unwrap()
.naive_utc();
let original = affine_nbstore::DocUpdate {
doc_id: "doc-1".to_string(),
timestamp,
bin: vec![1, 2, 3, 4, 5],
};
let encoded: DocUpdate = original.into();
let decoded = affine_nbstore::DocUpdate::try_from(encoded).unwrap();
assert_eq!(decoded.doc_id, "doc-1");
assert_eq!(decoded.timestamp, timestamp);
assert_eq!(decoded.bin, vec![1, 2, 3, 4, 5]);
}
#[test]
fn doc_update_rejects_invalid_base64() {
let update = DocUpdate {
doc_id: "doc-2".to_string(),
timestamp: 0,
bin: "not-base64!!".to_string(),
};
let err = match affine_nbstore::DocUpdate::try_from(update) {
Ok(_) => panic!("expected base64 decode error"),
Err(err) => err,
};
match err {
UniffiError::Base64DecodingError(_) => {}
other => panic!("unexpected error: {other:?}"),
}
}
}
#[derive(uniffi::Record)]
pub struct DocClock {
pub doc_id: String,