session 1 commit 3/4: CrdtOp moved to pmacs-protocol
CrdtOp { peer_id: u64, bytes: Vec<u8> } moves from src/rope.rs to
pmacs-protocol::crdt. The type is unconditional (not #[cfg]-gated),
matching the original's 'always present to avoid feature-flag
proliferation through every Edit consumer' decision: the parent
pmacs crate's 'crdt' feature gates loro and op application, not
wire shape.
Removed the unused 'crdt' feature stub I'd added to
pmacs-protocol/Cargo.toml at session start; nothing in pmacs-protocol
needs it.
src/rope.rs adds 'pub use pmacs_protocol::CrdtOp;' so existing
crate::rope::CrdtOp imports keep resolving.
Lib gate: still 1314 passing.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
2c04102aad
commit
5ffc47aa33
|
|
@ -32,13 +32,11 @@ cast_precision_loss = "allow"
|
||||||
similar_names = "allow"
|
similar_names = "allow"
|
||||||
multiple_crate_versions = "allow"
|
multiple_crate_versions = "allow"
|
||||||
|
|
||||||
[features]
|
# No features — the wire type set is unconditional. `CrdtOp` is
|
||||||
# Mirrors the `crdt` feature on the parent `pmacs` crate. When enabled,
|
# always compiled (matching the original `pmacs::rope::CrdtOp`'s
|
||||||
# the `InstanceMessage::CrdtOp` / `FrontendEvent::CrdtOp` variants exist
|
# "not `#[cfg]`-gated to avoid feature-flag proliferation through
|
||||||
# and the wire-level `CrdtOp` struct is in scope. When disabled, those
|
# every Edit consumer" decision); the parent `pmacs` crate's `crdt`
|
||||||
# variants are compiled out so v0.1-era binaries built without `crdt`
|
# feature gates loro and op-application, not wire shape.
|
||||||
# match the pre-v1.0 wire surface byte-for-byte.
|
|
||||||
crdt = []
|
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
serde = { workspace = true }
|
serde = { workspace = true }
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,44 @@
|
||||||
|
//! `CrdtOp` — moved from `pmacs::rope` in session 1 of the `pmacs-gpu`
|
||||||
|
//! arc. Carried on the `InstanceMessage::CrdtOp` /
|
||||||
|
//! `FrontendEvent::CrdtOp` wire variants when an attached session
|
||||||
|
//! negotiated `crdt_replica: true`.
|
||||||
|
//!
|
||||||
|
//! The type is unconditional (not `#[cfg]`-gated) — the comment on
|
||||||
|
//! the original `pmacs::rope::CrdtOp` explained why: "Always present
|
||||||
|
//! (not `#[cfg]`-gated) to avoid feature-flag proliferation through
|
||||||
|
//! every Edit consumer." Keeping the same shape here. The `crdt`
|
||||||
|
//! feature on the parent `pmacs` crate gates loro and the actual
|
||||||
|
//! application of CRDT ops; the wire-type definition stays compiled
|
||||||
|
//! unconditionally so consumers (`pmacs-gpu`, debug tools) don't have
|
||||||
|
//! to mirror the feature flag to handle a wire-level variant they
|
||||||
|
//! may never see.
|
||||||
|
|
||||||
|
/// T M10.2 Day 3: CRDT-op metadata carried by `Edit` in CRDT mode.
|
||||||
|
///
|
||||||
|
/// Two fields:
|
||||||
|
///
|
||||||
|
/// * `peer_id` — the producing-frontend identity. M10.4's per-frontend
|
||||||
|
/// undo reads this as the "is this op mine?" filter; saves the
|
||||||
|
/// consumer from parsing the op bytes to extract identity.
|
||||||
|
/// * `bytes` — wire-format serialization of the CRDT ops produced by
|
||||||
|
/// the originating edit, as returned by loro's
|
||||||
|
/// `ExportMode::updates_owned(pre_version)`. M10.5+ sends these
|
||||||
|
/// over the wire; receiving frontends import them via loro's
|
||||||
|
/// `import` to apply on their local CRDT.
|
||||||
|
///
|
||||||
|
/// Constructed by `Buffer::apply_edit` (and `undo` / `redo`) in CRDT
|
||||||
|
/// mode; rope's edit constructors set `Edit::crdt_op` to `None` and
|
||||||
|
/// the Buffer wraps after the rope returns.
|
||||||
|
///
|
||||||
|
/// T M10.5: serde derives added so this type can be the payload of
|
||||||
|
/// `InstanceMessage::CrdtOp` and `FrontendEvent::CrdtOp` on the wire.
|
||||||
|
/// `bytes` is opaque to the protocol layer — it's loro's incremental-
|
||||||
|
/// update format; the receiving end's `CrdtState::import_updates`
|
||||||
|
/// decodes it.
|
||||||
|
#[derive(Clone, Debug, Eq, PartialEq, serde::Serialize, serde::Deserialize)]
|
||||||
|
pub struct CrdtOp {
|
||||||
|
/// Producing frontend's identity (loro `PeerID`).
|
||||||
|
pub peer_id: u64,
|
||||||
|
/// Wire-format op bytes (loro `ExportMode::updates_owned` output).
|
||||||
|
pub bytes: Vec<u8>,
|
||||||
|
}
|
||||||
|
|
@ -35,12 +35,14 @@
|
||||||
//! directly.
|
//! directly.
|
||||||
|
|
||||||
pub mod cell;
|
pub mod cell;
|
||||||
|
pub mod crdt;
|
||||||
pub mod ids;
|
pub mod ids;
|
||||||
|
|
||||||
pub use cell::{
|
pub use cell::{
|
||||||
Attachment, Cell, CellCoord, CellSize, Color, DiffSpan, Glyph, Style, UnderlineStyle,
|
Attachment, Cell, CellCoord, CellSize, Color, DiffSpan, Glyph, Style, UnderlineStyle,
|
||||||
};
|
};
|
||||||
|
pub use crdt::CrdtOp;
|
||||||
pub use ids::{BufferId, ByteRange, FrontendId, Position};
|
pub use ids::{BufferId, ByteRange, FrontendId, Position};
|
||||||
|
|
||||||
// The `SemanticFrame` family, top-level message envelopes, and the
|
// The `SemanticFrame` family and the top-level message envelopes
|
||||||
// feature-gated `CrdtOp` follow in subsequent commits within this PR.
|
// follow in the final commit within this PR.
|
||||||
|
|
|
||||||
33
src/rope.rs
33
src/rope.rs
|
|
@ -330,35 +330,10 @@ pub struct Edit {
|
||||||
pub crdt_op: Option<Box<CrdtOp>>,
|
pub crdt_op: Option<Box<CrdtOp>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// T M10.2 Day 3: CRDT-op metadata carried by [`Edit`] in CRDT mode.
|
// `CrdtOp` moved to `pmacs-protocol::crdt` (session 1 of the
|
||||||
///
|
// `pmacs-gpu` arc — see `docs/pmacs-gpu-design.md`). Re-exported here
|
||||||
/// Two fields:
|
// so existing `crate::rope::CrdtOp` import paths continue to resolve.
|
||||||
///
|
pub use pmacs_protocol::CrdtOp;
|
||||||
/// * `peer_id` — the producing-frontend identity. M10.4's per-frontend
|
|
||||||
/// undo reads this as the "is this op mine?" filter; saves the
|
|
||||||
/// consumer from parsing the op bytes to extract identity.
|
|
||||||
/// * `bytes` — wire-format serialization of the CRDT ops produced by
|
|
||||||
/// the originating edit, as returned by loro's
|
|
||||||
/// `ExportMode::updates_owned(pre_version)`. M10.5+ sends these
|
|
||||||
/// over the wire; receiving frontends import them via loro's
|
|
||||||
/// `import` to apply on their local CRDT.
|
|
||||||
///
|
|
||||||
/// Constructed by `Buffer::apply_edit` (and `undo` / `redo`) in CRDT
|
|
||||||
/// mode; rope's edit constructors set `Edit::crdt_op` to `None` and
|
|
||||||
/// the Buffer wraps after the rope returns.
|
|
||||||
///
|
|
||||||
/// T M10.5: serde derives added so this type can be the payload of
|
|
||||||
/// `InstanceMessage::CrdtOp` and `FrontendEvent::CrdtOp` on the wire.
|
|
||||||
/// `bytes` is opaque to the protocol layer — it's loro's incremental-
|
|
||||||
/// update format; the receiving end's `CrdtState::import_updates`
|
|
||||||
/// decodes it.
|
|
||||||
#[derive(Clone, Debug, Eq, PartialEq, serde::Serialize, serde::Deserialize)]
|
|
||||||
pub struct CrdtOp {
|
|
||||||
/// Producing frontend's identity (loro `PeerID`).
|
|
||||||
pub peer_id: u64,
|
|
||||||
/// Wire-format op bytes (loro `ExportMode::updates_owned` output).
|
|
||||||
pub bytes: Vec<u8>,
|
|
||||||
}
|
|
||||||
|
|
||||||
/// A half-open byte range `[start, end)` into a rope.
|
/// A half-open byte range `[start, end)` into a rope.
|
||||||
///
|
///
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue