Skip to content

calternal_collab::history

Live document history contract (DESIGN §61, #975 Phase 2).

Points are durable, ordered edits within one stable item identity. The caller supplies authenticated authors and starts a lineage with a full v1 update. Restore and undo must apply a new update through the collaboration event path. Retention removes a prefix only; retained point IDs never change or get reused.

Source: crates/calternal-collab/src/history/mod.rs

Module Summary
restore Restore and selective undo for #975 Phase 2 C (DESIGN §§60–61).
store History stores (DESIGN §61, #975 Phase 2, slice A).
write Shared admission and batching for Canvas and Notes (DESIGN §60–61, #975).
conformance Test-only backend contract checks; production builds carry no fixture data.
adversarial Reusable hostile-input probes for the #975 HistoryStore contract.
pub struct DocKey

Stable identity and the Home owner whose quota includes this history.

Fields

  • pub owner: UserId
  • pub item_id: ItemId

Implements: Clone, Debug, Eq, PartialEq, Hash, Serialize, Deserialize

Source: crates/calternal-collab/src/history/mod.rs:33

pub struct FoldReport

Prefix retention result; the anchor remains readable as a full checkpoint.

Fields

  • pub removed_points: u64
  • pub reclaimed_bytes: u64
  • pub oldest_point: Option<PointId>

Implements: Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize

Source: crates/calternal-collab/src/history/mod.rs:61

pub struct HistoryPoint

Metadata for one update; bytes is its original v1 size, not compressed size.

Fields

  • pub id: PointId
  • pub at_ms: i64
  • pub author: Author
  • pub bytes: u32

Implements: Clone, Debug, Eq, PartialEq, Serialize, Deserialize

Source: crates/calternal-collab/src/history/mod.rs:52

pub struct PointId(pub u64);

Monotonic identifier within one DocKey; IDs start at one. Zero is a cursor.

Implements: Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd, Hash, Serialize, Deserialize

Source: crates/calternal-collab/src/history/mod.rs:48

pub struct RestoreReceipt

Result of applying one Restore through the live collaboration path.

Fields

  • pub change: Option<HistoryPoint>: Newly recorded forward edit; absent when content already matches (#975).
  • pub point: PointId: The historical point applied to the live document.
  • pub update_bytes: u32: Size of the normal Yjs update published to the live room.

Implements: Clone, Debug, PartialEq, Eq

Source: crates/calternal-collab/src/history/mod.rs:191

pub struct UndoReport

Per-item outcome of undoing one author’s changes.

Fields

  • pub reverted: Vec<String>: Element IDs or Note block IDs that the undo changed.
  • pub kept: Vec<String>: IDs kept because a different author changed them later.

Implements: Clone, Debug, Default, PartialEq, Eq

Source: crates/calternal-collab/src/history/mod.rs:202

pub enum Author

Authenticated origin; never inferred from a Yjs client ID or update bytes.

Variants

  • User(UserId)
  • Guest(String)
  • AgentTurn(TurnId)

Implements: Clone, Debug, Eq, PartialEq, Hash, Serialize, Deserialize

Source: crates/calternal-collab/src/history/mod.rs:40

pub enum Error

Typed failures shared by persistent and reference stores (#975).

Variants

  • Invalid
  • Conflict
  • Unavailable
  • Internal
  • Bridge(#[from] crate::BridgeError)
  • Restore(#[from] restore::RestoreError)
  • Db(#[from] calternal_db::DbError)
  • Json(#[from] serde_json::Error)
  • Decode(#[from] yrs::encoding::read::Error)
  • Other(#[from] Box<dyn std::error::Error + Send + Sync>)
  • NotFound
  • InvalidInput(&'static str)
  • Corrupt(&'static str)
  • Fs(#[from] calternal_fs::Error)
  • Io(#[from] std::io::Error)
  • Index(#[from] sqlx::Error)
  • Worker(#[from] tokio::task::JoinError)

Implements: Debug, Error, From<&'static str>

pub fn downcast_ref<T: std::error::Error + 'static>(&self) -> Option<&T>

Preserve preparation-error inspection in shared conformance tests (#975).

Source: crates/calternal-collab/src/history/mod.rs:69

pub trait HistoryMutations: Send + Sync

Restore and selective undo operations delegated to the collaboration writer.

The API calls preflight and apply separately. undo_author must rebuild its report at apply time because edits can land after the preflight response.

async fn restore(&self, doc: &DocKey, point: PointId, actor: &Author)
-> Result<RestoreReceipt>;

Publish the state at point as one normal Yjs update by actor.

async fn preflight_undo(
&self,
doc: &DocKey,
author: &Author,
from: PointId,
to: PointId,
) -> Result<UndoReport>;

Report the effects of an author’s requested point range without writing.

async fn undo_author(
&self,
doc: &DocKey,
author: &Author,
from: PointId,
to: PointId,
actor: &Author,
) -> Result<UndoReport>;

Recompute and publish the selective undo as one normal Yjs update.

Source: crates/calternal-collab/src/history/mod.rs:214

pub trait HistoryStore: Send + Sync

Shared store boundary. Ranges in updates_by include both endpoints; points uses an exclusive cursor and returns ascending IDs, capped at 1,000 rows. Successful append is durable. state_at returns a standalone v1 state update.

async fn materialized_etag(&self, _doc: &DocKey) -> Result<Option<String>>

Accepted materialized hashes: one saved hash, or old:new during a save. Recovery recognizes either side of an interrupted replacement and keeps later durable edits (DESIGN §61, #975 integration review).

async fn mark_materialized(&self, _doc: &DocKey, _etag: &str) -> Result<()>

Publish a saved hash or old:new intent before file replacement. Initial seeding also records its source hash; fixture stores have no file.

async fn idle(&self, _doc: &DocKey) -> Result<()>

Persist an idle checkpoint then release decoded state. Fixtures need no disk lifecycle; segment stores keep bounded room caches (#975, §61).

async fn latest(&self, doc: &DocKey) -> Result<Option<HistoryPoint>>

Latest metadata without decoding content. Persistent stores override the bounded-page fallback so history opens in constant time (#975 integration).

async fn append_reserved(
&self,
doc: &DocKey,
author: &Author,
update: &[u8],
at: i64,
_reservations: &[String],
) -> Result<PointId>

Consume only this batch’s quota reservations during durable installation. The default is for fixture stores with no filesystem quota (#975).

async fn append(
&self,
doc: &DocKey,
author: &Author,
update_v1: &[u8],
at_ms: i64,
) -> Result<PointId>;

No doc comment.

async fn points(
&self,
doc: &DocKey,
after: Option<PointId>,
limit: u16,
) -> Result<Vec<HistoryPoint>>;

No doc comment.

async fn state_at(&self, doc: &DocKey, point: PointId) -> Result<Vec<u8>>;

No doc comment.

async fn updates_by(
&self,
doc: &DocKey,
author: &Author,
from: PointId,
to: PointId,
) -> Result<Vec<(PointId, Vec<u8>)>>;

No doc comment.

async fn fold(&self, doc: &DocKey, keep_after_ms: i64) -> Result<FoldReport>;

No doc comment.

async fn usage(&self, owner: &UserId) -> Result<u64>;

No doc comment.

Source: crates/calternal-collab/src/history/mod.rs:110

pub type HistoryError = Error;

API uses the same typed failures as the store; causes stay server-side (#975).

Source: crates/calternal-collab/src/history/mod.rs:240

pub type ItemId = String;

Stable item identity, independent of its Home path (DESIGN §33).

Source: crates/calternal-collab/src/history/mod.rs:25

pub type Result<T> = std::result::Result<T, Error>;

History operation result; corruption never becomes a missing point (#975).

Source: crates/calternal-collab/src/history/mod.rs:29

pub type TurnId = String;

Immutable agent turn identity (DESIGN §10).

Source: crates/calternal-collab/src/history/mod.rs:27

pub type UserId = String;

Immutable User identity, using the server’s existing string IDs (#975).

Source: crates/calternal-collab/src/history/mod.rs:23