Something went wrong

Thank you for being patient! We're working hard on resolving the issue

Layered architecture - Lona Docs Log in

Layered architecture

tento-lona-connector            ← dispatch surface, host-data-free
        ▲
        │  Row + Integration impls
        │
tento-{garmin,whoop,google,weather}
   ├── (default)                   SDK only, no host-* deps
   ├── connector feature           + tento-lona-connector
   └── sync-plugin feature         + lona-sync (also host-data-free)
        ▲
        │  per-provider Backend + Sync seam traits
        │
host (lona-rows + lona-so today)  ← adapter; host data shapes live here

Three layers, three responsibilities

  1. Provider SDK crate (tento-garmin, etc.) — owns the provider-specific HTTP/OAuth/types. Default-build is just the SDK; no tento-lona-connector dependency, no lona-sync dependency.

  2. Connector module (behind connector feature) — owns the Row + Integration impls that map the provider's reserved rowkey patterns onto the connector trait surface. Declares the per-provider <Provider>BackendDeps trait the host implements.

  3. Sync-plugin module (behind sync-plugin feature, optional) — owns the lona_sync::SyncProvider/SyncExecutor impls plus the <Provider>SyncDeps host-seam trait.

The host (e.g. lona-rows + an embedder's app crate) supplies:

  • An impl of the connector's UserAuth trait against its credential store.
  • Impls of each enabled provider's <Provider>BackendDeps trait.
  • (For sync-plugin consumers) impls of <Provider>SyncDeps and <Provider>ApiContext.
  • A type-conversion bridge between connector data ([tento_lona_connector::Cell], [Owner]) and its own data types.

Why two features, not one

The connector is a small, generic dispatch surface — light enough to pull into any host. The sync-plugin feature pulls in lona-sync (a heavier orchestrator runtime). Hosts that don't need orchestrated background sync (e.g. a CLI that drives sync synchronously) can use just connector.

tento-google ships only the connector feature; the trait-async-fn Send-bound friction makes a generic-enough executor hard to express, so the host writes that executor itself.