blockworx/log/mod.rs
1//! The change log: the document's only authoritative representation.
2//!
3//! A document is an append-only history of typed commands. Everything else —
4//! the editor's document state, routed geometry, spatial indexes — is derived
5//! from it and can be thrown away and rebuilt. That inversion is what makes
6//! several people editing at once tractable: two histories merge, whereas two
7//! documents can only overwrite each other.
8//!
9//! The layering is strictly one-way:
10//!
11//! ```text
12//! change log ──fold──▶ document state ──solve──▶ derived ──▶ caches
13//! ```
14//!
15//! Four rules keep it honest, and every one of them is load-bearing:
16//!
17//! 1. **All state is last-write-wins registers, creates, and tombstones.**
18//! Those three commute, so replicas converge no matter what order changes
19//! arrive in. A command that does not reduce to them breaks the merge.
20//! 2. **The fold is pure.** No I/O, no clock, no randomness, and no re-running
21//! of the logic that produced a command — identities are minted before a
22//! command is recorded, never during replay.
23//! 3. **Nothing derived is ever stored in the log.** Solver output cannot be
24//! merged, so it must be recomputable instead.
25//! 4. **Unknown encodings are refused, never skipped.** Half-loading a log
26//! written by a newer build forks the document silently.
27//!
28//! See `docs/collab-architecture.md` for the design and
29//! `docs/collab-migration-playbook.md` for how the editor is being moved onto
30//! it.
31
32// The engine lands before the editor moves onto it (playbook phase 5), so most
33// of this has no caller yet and its own tests are the only ones exercising it.
34// Both allows come off when `Drawing` starts emitting commands — after that,
35// anything unused here is genuinely unused.
36#![allow(dead_code, unused_imports)]
37
38pub mod change;
39pub mod command;
40#[cfg(test)]
41mod convergence;
42pub mod dag;
43pub mod encode;
44pub mod fold;
45pub mod id;
46pub mod state;
47
48pub use change::{Change, ChangeBuilder, ChangeV1, SemanticLabel, WallTime};
49pub use command::{Command, ElementKind, PropChange, PropSet, PropTag, PropWrite};
50pub use dag::Dag;
51pub use encode::DecodeError;
52pub use fold::{FoldError, apply, fold};
53pub use id::{
54 ActorId, AssetId, BatchIndex, ChangeHash, Clock, ElementId, Lamport, Stamp, WriteOrder,
55};
56pub use state::{Applied, DocState, Element, Liveness, Register};