Skip to main content

omgbase_sync/
lib.rs

1//! # omgbase-sync
2//!
3//! The omgbase sync layer, Rust implementation of `spec/sync`: how bytes get
4//! *between* an omgbase repository (an [`omgbase_store::Store`]) and the
5//! places they live — the [`workspace`] on disk that holds the database, the
6//! source [`registry`] that says where a repo's bytes come from, the
7//! [`settings`] layers, the [`checkpoint`] rows and the filesystem fast path
8//! ([`freshness`] sweep, disk drift, [`recovery`]) over a [`fs::FileSystem`]
9//! seam, the adapter stdio protocol client ([`external`]), the [`driver`] and
10//! the [`coordinator`] over an [`engine::EngineClient`], and the advisory
11//! [`lock`]s. [`pipe`] is an in-memory pipe with a scripted adapter, for
12//! driving the protocol client without a process. The reconciliation itself is the store's (`spec/store` §5).
13//!
14//! ```no_run
15//! use omgbase_reconcile::Config;
16//! use omgbase_store::Store;
17//! use omgbase_sync::{fs::RealFileSystem, registry, freshness};
18//!
19//! let mut store = Store::open(".omgbase/omgbase.db")?;
20//! let repo = registry::ensure_repo(&mut store, "notes", Some("/home/me/notes"))?;
21//! let sweep = freshness::freshness_sweep(
22//!     &mut store, &repo, &RealFileSystem, "/home/me/notes".as_ref(),
23//!     "2026-09-26T10:00:00.000Z", None, &Config::default(),
24//! )?;
25//! println!("{} files scanned, changed: {}", sweep.scanned, sweep.changed);
26//! # Ok::<(), omgbase_sync::Error>(())
27//! ```
28
29#![deny(unsafe_code)]
30
31pub mod admin;
32pub mod checkpoint;
33pub mod coordinator;
34pub mod driver;
35pub mod engine;
36pub mod error;
37pub mod external;
38pub mod freshness;
39pub mod fs;
40pub mod lock;
41pub mod pipe;
42pub mod recovery;
43pub mod registry;
44pub mod settings;
45pub mod source;
46pub mod workspace;
47
48pub use admin::{DiskStatus, RepoStatus, SyncStatus, repos_status, sync_status};
49pub use checkpoint::{CheckpointResult, finish_checkpoint, process_checkpoint};
50pub use coordinator::{Coordinator, SyncInSummary, SyncOutSummary};
51pub use driver::{AttachResult, attach_source, reconcile_changes};
52pub use engine::{DocBytes, EngineClient, InProcessEngineClient};
53pub use error::{Error, Result};
54pub use external::ExternalSource;
55pub use freshness::{
56    DiskDrift, SweepPlan, SweepResult, detect_disk_drift, freshness_sweep, rebuild_file_stats,
57    record_file_stat, sweep_plan,
58};
59pub use fs::{FileStat, FileSystem, MemFileSystem, RealFileSystem, is_ignored_dir};
60pub use lock::{WatchLease, WriterLock, WriterLockOptions, pid_alive, with_writer_lock};
61pub use omgbase_store::{ChangesPage, CommitDigest, DeleteOutcome, DigestRevision, ObserveOutcome};
62pub use recovery::{RecoveryResult, recover_repo};
63pub use registry::{
64    AdapterRow, SourceRow, attach, create_source, delete_source, detach, ensure_adapter,
65    ensure_repo, list_adapters, list_sources, render_config_flags, source_by_name,
66    sources_for_repo,
67};
68pub use settings::{
69    Settings, deep_merge, repo_own_settings, resolve_settings, workspace_settings,
70    write_repo_settings, write_workspace_settings,
71};
72pub use source::{SourceCapabilities, SourceEntry, SourceIdentity, SourceItem, SyncSource};
73pub use workspace::{RepoRow, RepoSelection, Workspace, select_repo};
74
75/// The `spec/sync/VERSION` this crate implements (`major.minor`).
76pub const SPEC_VERSION: &str = "1.1";
77
78/// The adapter protocol number the handshake must carry (`spec/sync` §5).
79pub const PROTOCOL_VERSION: u64 = 1;
80
81/// The current time as the store writes it (`spec/store` §2.4:
82/// `YYYY-MM-DDTHH:MM:SS.fffZ`).
83#[must_use]
84pub fn now_ts() -> String {
85    let ms = std::time::SystemTime::now()
86        .duration_since(std::time::UNIX_EPOCH)
87        .map(|d| i64::try_from(d.as_millis()).unwrap_or(i64::MAX))
88        .unwrap_or(0);
89    omgbase_store::time::format_ms(ms)
90}