Add ely_sync_client crate

Build the Rust counterpart to `ely-browser-cloud`: a Bearer-token
authenticated HTTP client with the JSON wire types for the worker's
device + snapshot routes.

What lands:
- `BearerToken` + `BearerTokenStore` so Better Auth sessions persist
  per profile data dir with atomic rename writes.
- `DeviceIdentity` (UUIDv7 + Ed25519-shaped public key, persisted
  alongside the token so the worker keeps the same `device_id` across
  restarts).
- `SyncApiClient` with `register_device`, `list_devices`,
  `upload_snapshot`, and `download_snapshot` over `ureq`, mapping the
  worker's strict error envelopes onto typed `SyncClientError`s.
- `SnapshotPayload` enforces the worker's 10 MiB / SHA-256-hash
  contract before the wire encode, so callers fail fast.

Out of scope for this commit: the BrowserCore integration that swaps
snapshots in and out, and the in-app Better Auth + device-approval UX.
Those land in subsequent commits — `cloudflare/src/api_controls.ts`
rejects sync from devices that aren't already approved, so first-use
also requires a one-shot D1 approval until that path exists in the UI.
This commit is contained in:
2026-05-15 17:05:10 -04:00
parent 3d2c3ed1bf
commit 7366a0dffe
8 changed files with 795 additions and 0 deletions
+18
View File
@@ -0,0 +1,18 @@
[package]
name = "ely_sync_client"
version = "0.1.0"
edition.workspace = true
license.workspace = true
rust-version.workspace = true
[dependencies]
ely_domain = { path = "../ely_domain" }
serde = { workspace = true }
serde_json = { workspace = true }
sha2 = { workspace = true }
thiserror = { workspace = true }
ureq = { workspace = true, features = ["json"] }
uuid = { workspace = true }
[lints]
workspace = true