Documentation
¶
Overview ¶
Package text implements a state-based Replicated Growable Array (RGA).
Positions are stable mutation tags, not offsets. Offsets are resolved only for a local edit, which makes duplicate and out-of-order deltas safe.
Index ¶
- Constants
- Variables
- func LegacyFrameType() crdt.FrameType
- func PackedFrameType() crdt.FrameType
- func StableFrameType() crdt.FrameType
- type Anchor
- type AnchorAssociation
- type AnchorEncodingLimits
- type AnchorRange
- type Delta
- func UnmarshalRGADelta(data []byte) (Delta, error)
- func UnmarshalRGADeltaWithLimits(data []byte, limits frame.DecoderLimits) (Delta, error)
- func UnmarshalRGAPackedDelta(data []byte) (Delta, error)
- func UnmarshalRGAPackedDeltaWithLimits(data []byte, limits frame.DecoderLimits) (Delta, error)
- func UnmarshalRGARunDelta(data []byte) (Delta, error)
- func UnmarshalRGARunDeltaWithLimits(data []byte, limits frame.DecoderLimits) (Delta, error)
- func (d Delta) MarshalBinary() ([]byte, error)
- func (d Delta) MarshalBinaryWithLimits(limits frame.DecoderLimits) ([]byte, error)
- func (d Delta) MarshalJSON() ([]byte, error)
- func (d Delta) MarshalObfuscatedBinary() ([]byte, error)
- func (d Delta) MarshalObfuscatedBinaryWithLimits(limits frame.DecoderLimits) ([]byte, error)
- func (d Delta) MarshalObfuscatedRunBinary() ([]byte, error)
- func (d Delta) MarshalObfuscatedRunBinaryWithLimits(limits frame.DecoderLimits) ([]byte, error)
- func (d Delta) MarshalPackedBinary() ([]byte, error)
- func (d Delta) MarshalPackedBinaryWithLimits(limits frame.DecoderLimits) ([]byte, error)
- func (d Delta) MarshalPackedFrameV2() ([]byte, error)
- func (d Delta) MarshalPackedFrameV2WithLimits(limits frame.DecoderLimits) ([]byte, error)
- func (d Delta) MarshalRunBinary() ([]byte, error)
- func (d Delta) MarshalRunBinaryWithLimits(limits frame.DecoderLimits) ([]byte, error)
- func (d Delta) MarshalRunFrameV2() ([]byte, error)
- func (d Delta) MarshalRunFrameV2WithLimits(limits frame.DecoderLimits) ([]byte, error)
- func (d Delta) Merge(other Delta) (Delta, error)
- func (d Delta) NodePositions() []Position
- func (d Delta) Obfuscate() (Delta, error)
- type Options
- type Position
- type RGA
- func New(replicaID string) (*RGA, error)
- func NewFromClock(state clock.State) (*RGA, error)
- func NewFromClockWithOptions(state clock.State, options Options) (*RGA, error)
- func NewFromSnapshot(saved snapshot.Snapshot) (*RGA, error)
- func NewFromSnapshotWithOptions(saved snapshot.Snapshot, options Options, limits frame.DecoderLimits) (*RGA, error)
- func NewWithOptions(replicaID string, options Options) (*RGA, error)
- func (r *RGA) AnchorAt(offset int) (Anchor, error)
- func (r *RGA) AnchorRangeAt(start, end int) (AnchorRange, error)
- func (r *RGA) ApplyDelta(delta Delta) error
- func (r *RGA) ClockState() clock.State
- func (r *RGA) CompactEligibleTombstones(tags []Position) (int, error)
- func (r *RGA) CompactTombstones(tags []Position) (int, error)
- func (r *RGA) Delete(offset, count int) (Delta, error)
- func (r *RGA) DeleteBinaryWithLimits(offset, count int, limits frame.DecoderLimits) ([]byte, error)
- func (r *RGA) DeletePackedBinaryWithLimits(offset, count int, limits frame.DecoderLimits) ([]byte, error)
- func (r *RGA) DeletePackedFrameV2WithLimits(offset, count int, limits frame.DecoderLimits) ([]byte, error)
- func (r *RGA) DeleteRunBinaryWithLimits(offset, count int, limits frame.DecoderLimits) ([]byte, error)
- func (r *RGA) DeleteRunFrameV2WithLimits(offset, count int, limits frame.DecoderLimits) ([]byte, error)
- func (r *RGA) DeleteWithLimits(offset, count int, limits frame.DecoderLimits) (Delta, error)
- func (r *RGA) DeltaSince(base snapshot.Snapshot) (Delta, error)
- func (r *RGA) DeltaSinceBase(base SnapshotBase) (Delta, error)
- func (r *RGA) Insert(offset int, value string) (Delta, error)
- func (r *RGA) InsertBinaryWithLimits(offset int, value string, limits frame.DecoderLimits) ([]byte, error)
- func (r *RGA) InsertPackedBinaryWithLimits(offset int, value string, limits frame.DecoderLimits) ([]byte, error)
- func (r *RGA) InsertPackedFrameV2WithLimits(offset int, value string, limits frame.DecoderLimits) ([]byte, error)
- func (r *RGA) InsertRunBinaryWithLimits(offset int, value string, limits frame.DecoderLimits) ([]byte, error)
- func (r *RGA) InsertRunFrameV2WithLimits(offset int, value string, limits frame.DecoderLimits) ([]byte, error)
- func (r *RGA) InsertWithLimits(offset int, value string, limits frame.DecoderLimits) (Delta, error)
- func (r *RGA) Len() int
- func (r *RGA) MarshalBinary() ([]byte, error)
- func (r *RGA) MarshalBinaryWithClockState() ([]byte, clock.State, error)
- func (r *RGA) MarshalBinaryWithClockStateAndLimits(limits frame.DecoderLimits) ([]byte, clock.State, error)
- func (r *RGA) MarshalBinaryWithLimits(limits frame.DecoderLimits) ([]byte, error)
- func (r *RGA) MarshalDeltaSince(base snapshot.Snapshot) ([]byte, error)
- func (r *RGA) MarshalDeltaSinceBase(base SnapshotBase) ([]byte, error)
- func (r *RGA) MarshalDeltaSinceBaseWithLimits(base SnapshotBase, limits frame.DecoderLimits) ([]byte, error)
- func (r *RGA) MarshalDeltaSinceWithLimits(base snapshot.Snapshot, limits frame.DecoderLimits) ([]byte, error)
- func (r *RGA) MarshalJSON() ([]byte, error)
- func (r *RGA) MarshalObfuscatedBinary() ([]byte, error)
- func (r *RGA) MarshalObfuscatedBinaryWithLimits(limits frame.DecoderLimits) ([]byte, error)
- func (r *RGA) MarshalObfuscatedRunBinary() ([]byte, error)
- func (r *RGA) MarshalObfuscatedRunBinaryWithLimits(limits frame.DecoderLimits) ([]byte, error)
- func (r *RGA) MarshalPackedBinary() ([]byte, error)
- func (r *RGA) MarshalPackedBinaryWithLimits(limits frame.DecoderLimits) ([]byte, error)
- func (r *RGA) MarshalPackedDeltaSinceFrameV2(base snapshot.Snapshot) ([]byte, error)
- func (r *RGA) MarshalPackedDeltaSinceFrameV2Base(base SnapshotBase) ([]byte, error)
- func (r *RGA) MarshalPackedDeltaSinceFrameV2BaseWithLimits(base SnapshotBase, limits frame.DecoderLimits) ([]byte, error)
- func (r *RGA) MarshalPackedDeltaSinceFrameV2WithLimits(base snapshot.Snapshot, limits frame.DecoderLimits) ([]byte, error)
- func (r *RGA) MarshalPackedFrameV2() ([]byte, error)
- func (r *RGA) MarshalPackedFrameV2WithLimits(limits frame.DecoderLimits) ([]byte, error)
- func (r *RGA) MarshalRunBinary() ([]byte, error)
- func (r *RGA) MarshalRunBinaryWithLimits(limits frame.DecoderLimits) ([]byte, error)
- func (r *RGA) MarshalRunDeltaSinceFrameV2(base snapshot.Snapshot) ([]byte, error)
- func (r *RGA) MarshalRunDeltaSinceFrameV2Base(base SnapshotBase) ([]byte, error)
- func (r *RGA) MarshalRunDeltaSinceFrameV2BaseWithLimits(base SnapshotBase, limits frame.DecoderLimits) ([]byte, error)
- func (r *RGA) MarshalRunDeltaSinceFrameV2WithLimits(base snapshot.Snapshot, limits frame.DecoderLimits) ([]byte, error)
- func (r *RGA) MarshalRunFrameV2() ([]byte, error)
- func (r *RGA) MarshalRunFrameV2WithLimits(limits frame.DecoderLimits) ([]byte, error)
- func (r *RGA) Merge(other *RGA) error
- func (r *RGA) MissingParents() []Position
- func (r *RGA) NextTag() (Position, error)
- func (r *RGA) PendingCount() int
- func (r *RGA) Positions() []Position
- func (r *RGA) PrepareDeletePackedBinaryWithLimits(offset, count int, limits frame.DecoderLimits) (Delta, []byte, error)
- func (r *RGA) PrepareDeletePackedFrameV2WithLimits(offset, count int, limits frame.DecoderLimits) (Delta, []byte, error)
- func (r *RGA) PrepareDeleteRunBinaryWithLimits(offset, count int, limits frame.DecoderLimits) (Delta, []byte, error)
- func (r *RGA) PrepareDeleteRunFrameV2WithLimits(offset, count int, limits frame.DecoderLimits) (Delta, []byte, error)
- func (r *RGA) PrepareInsertPackedBinaryWithLimits(offset int, value string, limits frame.DecoderLimits) (Delta, []byte, error)
- func (r *RGA) PrepareInsertPackedFrameV2WithLimits(offset int, value string, limits frame.DecoderLimits) (Delta, []byte, error)
- func (r *RGA) PrepareInsertRunBinaryWithLimits(offset int, value string, limits frame.DecoderLimits) (Delta, []byte, error)
- func (r *RGA) PrepareInsertRunFrameV2WithLimits(offset int, value string, limits frame.DecoderLimits) (Delta, []byte, error)
- func (r *RGA) ReplaceBinaryWithLimits(offset, count int, value string, limits frame.DecoderLimits) ([]byte, error)
- func (r *RGA) ReplacePackedBinaryWithLimits(offset, count int, value string, limits frame.DecoderLimits) ([]byte, error)
- func (r *RGA) ReplacePackedFrameV2WithLimits(offset, count int, value string, limits frame.DecoderLimits) ([]byte, error)
- func (r *RGA) ReplaceRunBinaryWithLimits(offset, count int, value string, limits frame.DecoderLimits) ([]byte, error)
- func (r *RGA) ReplaceRunFrameV2WithLimits(offset, count int, value string, limits frame.DecoderLimits) ([]byte, error)
- func (r *RGA) ResolveAnchor(anchor Anchor) (int, error)
- func (r *RGA) ResolveAnchorRange(anchors AnchorRange) (start, end int, err error)
- func (r *RGA) RetainsPosition(position Position) bool
- func (r *RGA) Snapshot(frontier map[string]crdt.Tag) (snapshot.Snapshot, error)
- func (r *RGA) SnapshotCurrentState() (snapshot.Snapshot, error)
- func (r *RGA) SnapshotCurrentStateWithLimits(limits frame.DecoderLimits) (snapshot.Snapshot, error)
- func (r *RGA) SnapshotPackedCurrentState() (snapshot.Snapshot, error)
- func (r *RGA) SnapshotPackedCurrentStateWithLimits(limits frame.DecoderLimits) (snapshot.Snapshot, error)
- func (r *RGA) SnapshotPackedFrameV2CurrentState() (snapshot.Snapshot, error)
- func (r *RGA) SnapshotPackedFrameV2CurrentStateWithLimits(limits frame.DecoderLimits) (snapshot.Snapshot, error)
- func (r *RGA) SnapshotRunCurrentState() (snapshot.Snapshot, error)
- func (r *RGA) SnapshotRunCurrentStateWithLimits(limits frame.DecoderLimits) (snapshot.Snapshot, error)
- func (r *RGA) SnapshotRunFrameV2CurrentState() (snapshot.Snapshot, error)
- func (r *RGA) SnapshotRunFrameV2CurrentStateWithLimits(limits frame.DecoderLimits) (snapshot.Snapshot, error)
- func (r *RGA) State() crdt.StateSnapshot
- func (r *RGA) String() string
- func (r *RGA) TombstoneTags() []Position
- func (r *RGA) UnmarshalBinary(data []byte) error
- func (r *RGA) UnmarshalBinaryWithLimits(data []byte, limits frame.DecoderLimits) error
- func (r *RGA) UnmarshalPackedBinary(data []byte) error
- func (r *RGA) UnmarshalPackedBinaryWithLimits(data []byte, limits frame.DecoderLimits) error
- func (r *RGA) UnmarshalRunBinary(data []byte) error
- func (r *RGA) UnmarshalRunBinaryWithLimits(data []byte, limits frame.DecoderLimits) error
- func (r *RGA) VisibleRunes() ([]Position, []rune)
- func (r *RGA) WitnessTag(tag Position) error
- type SnapshotBase
- type UndoManager
- func (m *UndoManager) CanRedo() bool
- func (m *UndoManager) CanUndo() bool
- func (m *UndoManager) Clear()
- func (m *UndoManager) Delete(offset, count int) (Delta, error)
- func (m *UndoManager) Insert(offset int, value string) (Delta, error)
- func (m *UndoManager) Len() int
- func (m *UndoManager) Redo() (Delta, error)
- func (m *UndoManager) Undo() (Delta, error)
- type UndoOptions
Examples ¶
Constants ¶
const ( // LegacySemanticsVersion is the immutable scalar RGA v1 contract for // TypeIDs 11/12. It is stable but remains a distinct protocol from run-v2. LegacySemanticsVersion uint64 = crdt.SemanticsVersionRGA // RunV2SemanticsVersion is the immutable semantics version for the stable // run-v2 text protocol (TypeIDs 19/20). It belongs in every run-v2 replica // manifest. Scalar-v1 frames must never be substituted for run-v2 frames. RunV2SemanticsVersion uint64 = crdt.SemanticsVersionRGARun // PackedV3SemanticsVersion is the separately negotiated compact RGA // protocol. It retains every scalar Position while packing dense local HLC // runs; v1 and run-v2 frames remain distinct protocols. PackedV3SemanticsVersion uint64 = crdt.SemanticsVersionRGAPacked )
Variables ¶
var ( // ErrInvalidAnchor reports an anchor with an unknown association or a // malformed non-root position. Anchors are local metadata, not CRDT deltas, // so callers must validate them before using untrusted presence payloads. ErrInvalidAnchor = errors.New("text: invalid anchor") // ErrAnchorGone reports that the referenced position was compacted. The // caller must drop or refresh the cursor instead of guessing a new offset. ErrAnchorGone = errors.New("text: anchor is no longer retained") )
var ( ErrNilText = errors.New("text: nil RGA") ErrInvalidReplicaID = errors.New("text: invalid replica ID") ErrInvalidText = errors.New("text: invalid UTF-8 text") ErrRange = errors.New("text: range outside visible text") ErrInvalidDelta = errors.New("text: invalid RGA delta") // ErrIncompleteState indicates a state snapshot contains an unresolved // parent reference. Deltas may be partial for out-of-order delivery, but a // recoverable state frame must include the complete parent closure. ErrIncompleteState = errors.New("text: incomplete RGA state") ErrTagConflict = errors.New("text: conflicting node for one tag") // ErrUnsafeCompaction means a tombstone still anchors local or unresolved // descendants, so removing it would change RGA ordering or permit a stale // insertion to become visible. ErrUnsafeCompaction = errors.New("text: unsafe RGA tombstone compaction") // ErrResourceLimit indicates that accepting a delta would exceed the // receiver's configured in-memory safety limits. ErrResourceLimit = errors.New("text: RGA resource limit exceeded") // ErrUndoAnchorGone indicates that a local undo/redo operation can no // longer preserve its original insertion intent because the structural // predecessor was compacted. Callers must clear local history after a // compaction boundary rather than silently placing content elsewhere. ErrUndoAnchorGone = errors.New("text: undo anchor is no longer retained") )
var ( // ErrInvalidSnapshot indicates that a delta base is not a canonical, // complete RGA state snapshot in either supported RGA wire format. ErrInvalidSnapshot = errors.New("text: invalid RGA snapshot") // ErrIncompatibleSnapshot indicates that the current RGA no longer contains // state retained by the base checkpoint. A delta can add nodes and // tombstones, but cannot express physical removal or resurrection, so the // peer must install a newer complete checkpoint instead. ErrIncompatibleSnapshot = errors.New("text: RGA snapshot is incompatible with current state") )
var ( // ErrNoUndo reports that no captured local operation can be undone. ErrNoUndo = errHistoryEmpty("text: no undo operation") // ErrNoRedo reports that no previously undone local operation can be redone. ErrNoRedo = errHistoryEmpty("text: no redo operation") // ErrInvalidUndoOptions reports an unusable local undo-history policy. ErrInvalidUndoOptions = errors.New("text: invalid undo options") // ErrUndoHistoryLimit reports that one local edit cannot fit in the // configured history budget. It leaves both the RGA and history unchanged. ErrUndoHistoryLimit = errors.New("text: undo history resource limit") )
Functions ¶
func LegacyFrameType ¶ added in v1.0.25
LegacyFrameType returns the stable scalar RGA v1 state/delta pair. It is a migration-compatible contract, not the default for new text groups.
func PackedFrameType ¶ added in v1.0.31
PackedFrameType returns the explicitly negotiated compact RGA v3 pair. It is not a fallback for stable run-v2: a replication group must bind this exact pair and semantics version in its authenticated manifest before using the packed encoder or decoder.
func StableFrameType ¶ added in v1.0.24
StableFrameType returns the stable run-v2 state/delta pair for new text replication groups. It is equivalent to crdt.DefaultRGAFrameType and is provided here so callers can bind the text package's semantic version and frame pair without treating legacy scalar-v1 helpers as the default.
Types ¶
type Anchor ¶ added in v1.0.23
type Anchor struct {
Position Position
Association AnchorAssociation
}
Anchor is stable cursor, selection, or comment metadata for an RGA boundary. It is deliberately not a CRDT state field: Anchor values can be stored or sent in a host-owned metadata record with MarshalBinary, but never in an RGA state/delta frame, snapshot, or unauthenticated peer message. A retained tombstone continues to resolve; exact tombstone compaction invalidates an anchor rather than relocating it.
func UnmarshalAnchor ¶ added in v1.0.32
UnmarshalAnchor decodes a canonical relative-position metadata record using default bounded limits. It does not prove that the anchor belongs to the current document; ResolveAnchor performs that check against retained state.
func UnmarshalAnchorWithLimits ¶ added in v1.0.32
func UnmarshalAnchorWithLimits(data []byte, limits AnchorEncodingLimits) (Anchor, error)
UnmarshalAnchorWithLimits decodes one complete canonical anchor record. It rejects unknown versions, non-canonical varints, trailing bytes, malformed tags, and oversized replica IDs before retaining any decoded string.
func (Anchor) MarshalBinary ¶ added in v1.0.32
MarshalBinary returns the canonical, versioned relative-position encoding for anchor. The bytes are portable host metadata, not a rich-text or RGA frame; applications must bind their envelope to one authenticated document, group, epoch, and retention policy.
func (Anchor) MarshalBinaryWithLimits ¶ added in v1.0.32
func (anchor Anchor) MarshalBinaryWithLimits(limits AnchorEncodingLimits) ([]byte, error)
MarshalBinaryWithLimits returns the canonical relative-position encoding while checking the receiver's metadata budget before allocating output.
type AnchorAssociation ¶ added in v1.0.23
type AnchorAssociation uint8
AnchorAssociation selects the boundary represented by an Anchor.
AnchorBefore resolves immediately before Position. AnchorAfter resolves immediately after Position itself, before any of its descendants. For the root Position{}, AnchorBefore is the document start and AnchorAfter is the document end.
const ( AnchorBefore AnchorAssociation = iota + 1 AnchorAfter )
type AnchorEncodingLimits ¶ added in v1.0.32
AnchorEncodingLimits bounds host-owned relative-position metadata before it allocates a replica ID or attempts to resolve an RGA position. Applications receiving anchors from a peer should use the authenticated group limit, not a process-global default.
func DefaultAnchorEncodingLimits ¶ added in v1.0.32
func DefaultAnchorEncodingLimits() AnchorEncodingLimits
DefaultAnchorEncodingLimits returns conservative limits for an encoded cursor, selection, or comment range. They intentionally remain independent from CRDT frame limits because anchors are not CRDT frames.
type AnchorRange ¶ added in v1.0.32
AnchorRange is two relative RGA boundaries captured from one document revision. It is suitable for a selection or a comment range; Start and End intentionally preserve their caller-provided order so a backwards editor selection does not lose its direction. Comment hosts should require the resolved Start offset to be at or before End before attaching content.
AnchorRange is host-owned metadata, not CRDT state. Its binary form is versioned by MarshalBinary and is safe to retain next to an authenticated document checkpoint, subject to the same compaction lifecycle as Anchor.
func UnmarshalAnchorRange ¶ added in v1.0.32
func UnmarshalAnchorRange(data []byte) (AnchorRange, error)
UnmarshalAnchorRange decodes one complete, canonical pair of relative boundaries with default metadata limits.
func UnmarshalAnchorRangeWithLimits ¶ added in v1.0.32
func UnmarshalAnchorRangeWithLimits(data []byte, limits AnchorEncodingLimits) (AnchorRange, error)
UnmarshalAnchorRangeWithLimits decodes one complete range metadata record without accepting unknown versions, trailing data, or malformed positions.
func (AnchorRange) MarshalBinary ¶ added in v1.0.32
func (anchors AnchorRange) MarshalBinary() ([]byte, error)
MarshalBinary returns the canonical, versioned metadata encoding for both relative boundaries. It does not normalize their order so editor selections can retain an anchor/head direction.
func (AnchorRange) MarshalBinaryWithLimits ¶ added in v1.0.32
func (anchors AnchorRange) MarshalBinaryWithLimits(limits AnchorEncodingLimits) ([]byte, error)
MarshalBinaryWithLimits encodes both boundaries after preflighting the full result against the supplied metadata budget.
func (AnchorRange) Valid ¶ added in v1.0.32
func (anchors AnchorRange) Valid() bool
Valid reports whether both boundaries use the supported Anchor form.
type Delta ¶
type Delta struct {
// contains filtered or unexported fields
}
Delta is a joinable partial RGA state. Nodes and tombstones are deliberately opaque so a malformed delta cannot be assembled by direct field mutation.
func UnmarshalRGADelta ¶
UnmarshalRGADelta decodes one bounded canonical RGA delta frame.
func UnmarshalRGADeltaWithLimits ¶
func UnmarshalRGADeltaWithLimits(data []byte, limits frame.DecoderLimits) (Delta, error)
func UnmarshalRGAPackedDelta ¶ added in v1.0.31
UnmarshalRGAPackedDelta decodes one bounded compact RGA v3 delta.
func UnmarshalRGAPackedDeltaWithLimits ¶ added in v1.0.31
func UnmarshalRGAPackedDeltaWithLimits(data []byte, limits frame.DecoderLimits) (Delta, error)
UnmarshalRGAPackedDeltaWithLimits decodes one compact RGA v3 delta with caller-selected resource limits.
func UnmarshalRGARunDelta ¶ added in v1.0.6
UnmarshalRGARunDelta decodes a bounded run-v2 delta.
func UnmarshalRGARunDeltaWithLimits ¶ added in v1.0.19
func UnmarshalRGARunDeltaWithLimits(data []byte, limits frame.DecoderLimits) (Delta, error)
UnmarshalRGARunDeltaWithLimits decodes a bounded run-v2 delta while enforcing caller-selected input limits.
func (Delta) MarshalBinary ¶
MarshalBinary returns the canonical framed RGA delta.
func (Delta) MarshalBinaryWithLimits ¶ added in v1.0.19
func (d Delta) MarshalBinaryWithLimits(limits frame.DecoderLimits) ([]byte, error)
MarshalBinaryWithLimits returns the canonical framed RGA delta while enforcing caller-selected frame limits.
func (Delta) MarshalJSON ¶ added in v1.0.5
MarshalJSON returns a diagnostic summary for structured logs. It omits text content, positions, tombstone identities, and clock state.
func (Delta) MarshalObfuscatedBinary ¶ added in v1.0.24
MarshalObfuscatedBinary encodes an obfuscated legacy scalar RGA delta for isolated debugging. The result uses the normal TypeIDRGA delta contract.
func (Delta) MarshalObfuscatedBinaryWithLimits ¶ added in v1.0.24
func (d Delta) MarshalObfuscatedBinaryWithLimits(limits frame.DecoderLimits) ([]byte, error)
MarshalObfuscatedBinaryWithLimits encodes an obfuscated legacy scalar RGA delta while enforcing the supplied output limits.
func (Delta) MarshalObfuscatedRunBinary ¶ added in v1.0.24
MarshalObfuscatedRunBinary encodes an obfuscated run-v2 RGA delta for isolated debugging. The result remains valid only for a separately negotiated run-v2 group.
func (Delta) MarshalObfuscatedRunBinaryWithLimits ¶ added in v1.0.24
func (d Delta) MarshalObfuscatedRunBinaryWithLimits(limits frame.DecoderLimits) ([]byte, error)
MarshalObfuscatedRunBinaryWithLimits encodes an obfuscated run-v2 delta while enforcing the supplied output limits.
func (Delta) MarshalPackedBinary ¶ added in v1.0.31
MarshalPackedBinary encodes one delta with compact dense local HLC chains. Its TypeID is distinct from stable run-v2 and requires PackedFrameType.
func (Delta) MarshalPackedBinaryWithLimits ¶ added in v1.0.31
func (d Delta) MarshalPackedBinaryWithLimits(limits frame.DecoderLimits) ([]byte, error)
MarshalPackedBinaryWithLimits encodes one bounded compact RGA v3 delta.
func (Delta) MarshalPackedFrameV2 ¶ added in v1.0.32
MarshalPackedFrameV2 encodes a packed-v3 delta in the separately negotiated compression-aware outer frame v2. The decoded payload remains canonical packed-v3 bytes.
func (Delta) MarshalPackedFrameV2WithLimits ¶ added in v1.0.32
func (d Delta) MarshalPackedFrameV2WithLimits(limits frame.DecoderLimits) ([]byte, error)
MarshalPackedFrameV2WithLimits encodes a bounded packed-v3 delta in outer frame v2. It may select a raw v2 payload for a small edit, so callers must negotiate v2 even when DEFLATE is not selected.
func (Delta) MarshalRunBinary ¶ added in v1.0.6
MarshalRunBinary encodes a delta with compact same-replica parent chains.
func (Delta) MarshalRunBinaryWithLimits ¶ added in v1.0.19
func (d Delta) MarshalRunBinaryWithLimits(limits frame.DecoderLimits) ([]byte, error)
MarshalRunBinaryWithLimits encodes a delta with compact same-replica parent chains while enforcing caller-selected output limits.
func (Delta) MarshalRunFrameV2 ¶ added in v1.0.27
MarshalRunFrameV2 encodes a run-v2 delta in the separately negotiated compression-aware outer frame v2. It does not change the canonical run-v2 payload, RGA IDs, or merge semantics.
func (Delta) MarshalRunFrameV2WithLimits ¶ added in v1.0.27
func (d Delta) MarshalRunFrameV2WithLimits(limits frame.DecoderLimits) ([]byte, error)
MarshalRunFrameV2WithLimits encodes a bounded run-v2 delta in outer frame v2. It may select a raw v2 payload when DEFLATE would not reduce the final frame, so callers must negotiate v2 even for small edits.
func (Delta) NodePositions ¶ added in v1.0.21
NodePositions returns sorted stable IDs for the nodes carried by d. It does not expose their text or parent links, and is useful when an enclosing CRDT needs to attach metadata to an insertion before it applies the delta.
func (Delta) Obfuscate ¶ added in v1.0.24
Obfuscate returns a join-compatible debug copy of d with every inserted character replaced by an inert placeholder of the same uvarint width. Positions, parent links, tombstones, and operation cardinality are retained so independently obfuscated deltas from the same document remain safe to decode, deduplicate, and merge with one another.
Obfuscation is diagnostic redaction, not encryption or anonymization. It intentionally retains CRDT identifiers, topology, operation counts, and HLC-derived metadata. Never feed the returned delta into a replica that may already contain the original values: the same immutable position with a different rune is correctly rejected as ErrTagConflict.
type Options ¶ added in v1.0.6
Options bounds retained RGA metadata. Values must be positive. The defaults match the maximum element count of one default framed payload while keeping unresolved dependency state substantially smaller than a full document. Applications handling untrusted peers should choose limits appropriate to a replication group instead of relying on process-wide memory availability.
func DefaultOptions ¶ added in v1.0.6
func DefaultOptions() Options
DefaultOptions returns conservative per-RGA retention limits.
type Position ¶
Position is a stable, opaque identifier for one Unicode scalar value. It remains valid after inserts before it and after it has been deleted.
type RGA ¶
type RGA struct {
// contains filtered or unexported fields
}
RGA is a collaborative text CRDT. A tombstone retained for a deleted position wins even if it arrives before the corresponding insertion.
func NewFromClockWithOptions ¶ added in v1.0.6
NewFromClockWithOptions restores an RGA clock with explicit retention limits. Clock state must be persisted atomically with a complete snapshot before reusing its replica ID.
func NewFromSnapshotWithOptions ¶ added in v1.0.19
func NewFromSnapshotWithOptions(saved snapshot.Snapshot, options Options, limits frame.DecoderLimits) (*RGA, error)
NewFromSnapshotWithOptions restores an RGA snapshot using explicit retained state and frame limits. It validates the full state before installation and witnesses the saved frontier before returning, so a reused replica ID cannot create a tag that predates the recovered state.
func NewWithOptions ¶ added in v1.0.6
NewWithOptions constructs an RGA with explicit retention limits.
func (*RGA) AnchorAt ¶ added in v1.0.23
AnchorAt returns a relative cursor boundary for visible rune offset. The returned anchor references the following visible position; an end offset is represented by AnchorAfter on the root. Consequently it tracks the same logical boundary as concurrent inserts shift absolute offsets.
func (*RGA) AnchorRangeAt ¶ added in v1.0.32
func (r *RGA) AnchorRangeAt(start, end int) (AnchorRange, error)
AnchorRangeAt captures two relative boundaries under one RGA read lock. Unlike two separate AnchorAt calls, a concurrent document change cannot leave the pair referring to different revisions.
func (*RGA) ApplyDelta ¶
Example ¶
ExampleRGA_ApplyDelta shows a bounded RGA delivery. RGA frames are experimental: enabling local support is separate from authenticating peers and agreeing the manifest for a replication group.
policy := crdt.ProtocolPolicy{AllowExperimental: true}
if !policy.SupportsFrame(crdt.TypeIDRGADelta) {
panic("RGA must be enabled by the replication-group policy")
}
options := Options{
MaxNodes: 64,
MaxTombstones: 64,
MaxPendingNodes: 16,
MaxPendingBytes: 4 << 10,
}
writer, err := NewWithOptions("writer", options)
if err != nil {
panic(err)
}
reader, err := NewWithOptions("reader", options)
if err != nil {
panic(err)
}
delta, err := writer.Insert(0, "field note")
if err != nil {
panic(err)
}
encoded, err := delta.MarshalBinary()
if err != nil {
panic(err)
}
received, err := UnmarshalRGADeltaWithLimits(encoded, frame.DecoderLimits{
MaxFrameBytes: 4 << 10,
MaxPayload: 3 << 10,
MaxCodecID: 128,
MaxElements: 64,
MaxTags: 64,
MaxStringBytes: 256,
})
if err != nil {
panic(err)
}
if err := reader.ApplyDelta(received); err != nil {
panic(err)
}
fmt.Println(reader.String())
Output: field note
func (*RGA) ClockState ¶
func (*RGA) CompactEligibleTombstones ¶ added in v1.0.19
CompactEligibleTombstones makes best-effort structural progress through an exact-acknowledged batch. Unlike CompactTombstones, a non-leaf in tags does not block unrelated leaves. Deleted descendants are removed before their deleted ancestors, so a fully deleted chain can compact in one call.
It remains deliberately fail-closed for unresolved state: any pending node returns ErrUnsafeCompaction without changing the RGA. For replicated state, callers still need an authenticated exact-acknowledgement epoch, a durable post-compaction checkpoint, and retirement of old deltas. tombstonegc. SimpleCollector may use this structural operation only for its documented local-only lifecycle.
func (*RGA) CompactTombstones ¶ added in v1.0.6
CompactTombstones physically removes exactly the requested tombstoned leaf nodes. It is deliberately stricter than OR-Set compaction: an RGA deletion remains a structural anchor while any integrated or pending child refers to it. Call this only after an authenticated, exact-acknowledgement epoch has durably checkpointed a post-compaction snapshot and retired old deltas.
The operation is all-or-nothing. Unknown tags are ignored; invalid tags, unresolved dependencies, non-leaf nodes, or tombstones received before their insertion return ErrUnsafeCompaction without changing the RGA.
func (*RGA) Delete ¶
Delete marks count visible runes starting at offset as removed. The delta carries only tombstones; replicas that have not received the inserts yet retain those tombstones until the matching nodes arrive.
func (*RGA) DeleteBinaryWithLimits ¶ added in v1.0.19
DeleteBinaryWithLimits deletes visible text and returns the same preflighted canonical tombstone frame used to establish the local output budget.
func (*RGA) DeletePackedBinaryWithLimits ¶ added in v1.0.31
func (r *RGA) DeletePackedBinaryWithLimits(offset, count int, limits frame.DecoderLimits) ([]byte, error)
DeletePackedBinaryWithLimits deletes visible text and returns the same preflighted compact RGA v3 tombstone delta used for the output budget.
func (*RGA) DeletePackedFrameV2WithLimits ¶ added in v1.0.32
func (r *RGA) DeletePackedFrameV2WithLimits(offset, count int, limits frame.DecoderLimits) ([]byte, error)
DeletePackedFrameV2WithLimits deletes visible text and returns the same preflighted packed-v3 tombstone delta in a separately negotiated outer frame v2. Callers must bind frame.FormatVersionV2 in their manifest.
func (*RGA) DeleteRunBinaryWithLimits ¶ added in v1.0.19
func (r *RGA) DeleteRunBinaryWithLimits(offset, count int, limits frame.DecoderLimits) ([]byte, error)
DeleteRunBinaryWithLimits deletes visible text and returns the same preflighted run-v2 tombstone frame used to establish the local output budget. Callers must have separately negotiated the run-v2 RGA protocol.
func (*RGA) DeleteRunFrameV2WithLimits ¶ added in v1.0.27
func (r *RGA) DeleteRunFrameV2WithLimits(offset, count int, limits frame.DecoderLimits) ([]byte, error)
DeleteRunFrameV2WithLimits deletes visible text and returns the same preflighted run-v2 tombstone delta in a separately negotiated outer frame v2. Callers must bind frame.FormatVersionV2 in their manifest.
func (*RGA) DeleteWithLimits ¶ added in v1.0.19
DeleteWithLimits deletes visible runes only when the canonical tombstone delta fits limits. A rejected output frame leaves the RGA content and tombstone set unchanged.
func (*RGA) DeltaSince ¶ added in v1.0.19
DeltaSince returns the mutations that move a receiver known to contain base toward r's current state. The result includes every required structural ancestor absent from base, so it remains safe when the receiver installs the resulting delta before any later updates.
base is deliberately a validated complete snapshot rather than a map of greatest HLC tags. HLC tags are ordered but not contiguous, so a greatest-tag frontier cannot prove that a receiver has every earlier mutation and could otherwise make a differential update omit data it still needs.
func (*RGA) DeltaSinceBase ¶ added in v1.0.19
func (r *RGA) DeltaSinceBase(base SnapshotBase) (Delta, error)
DeltaSinceBase is DeltaSince with a reusable parsed snapshot base.
func (*RGA) Insert ¶
Insert inserts valid UTF-8 text before visible rune offset. It creates one node per Unicode scalar, so offset/count are rune based rather than byte based and can never split UTF-8.
func (*RGA) InsertBinaryWithLimits ¶ added in v1.0.19
func (r *RGA) InsertBinaryWithLimits(offset int, value string, limits frame.DecoderLimits) ([]byte, error)
InsertBinaryWithLimits inserts text and returns the same preflighted canonical delta frame used to establish the local output budget.
func (*RGA) InsertPackedBinaryWithLimits ¶ added in v1.0.31
func (r *RGA) InsertPackedBinaryWithLimits(offset int, value string, limits frame.DecoderLimits) ([]byte, error)
InsertPackedBinaryWithLimits inserts text and returns a preflighted compact RGA v3 delta. Callers must negotiate PackedFrameType before publishing it.
func (*RGA) InsertPackedFrameV2WithLimits ¶ added in v1.0.32
func (r *RGA) InsertPackedFrameV2WithLimits(offset int, value string, limits frame.DecoderLimits) ([]byte, error)
InsertPackedFrameV2WithLimits inserts text and returns the same preflighted packed-v3 delta in a separately negotiated outer frame v2. The RGA payload is unchanged; DEFLATE is selected only when it reduces the final bounded frame.
func (*RGA) InsertRunBinaryWithLimits ¶ added in v1.0.19
func (r *RGA) InsertRunBinaryWithLimits(offset int, value string, limits frame.DecoderLimits) ([]byte, error)
InsertRunBinaryWithLimits inserts text and returns the same preflighted run-v2 delta frame used to establish the local output budget. Callers must have separately negotiated the run-v2 RGA protocol before using this frame.
func (*RGA) InsertRunFrameV2WithLimits ¶ added in v1.0.27
func (r *RGA) InsertRunFrameV2WithLimits(offset int, value string, limits frame.DecoderLimits) ([]byte, error)
InsertRunFrameV2WithLimits inserts text and returns the same preflighted run-v2 delta in a separately negotiated outer frame v2. The RGA payload is unchanged; the outer representation may use DEFLATE only when it reduces the complete bounded frame.
func (*RGA) InsertWithLimits ¶ added in v1.0.19
InsertWithLimits inserts text only when its complete canonical delta fits limits. A rejected output frame does not add nodes or tombstones to the RGA, which lets a transport-facing caller fail the local edit before it becomes state that cannot be replicated under its own budget. The HLC may still advance while reserving local tags; those un-emitted tags are safe to skip.
func (*RGA) Len ¶ added in v1.0.23
Len returns the number of visible Unicode scalar values without allocating a projection. It is safe to call concurrently with other RGA operations.
func (*RGA) MarshalBinary ¶
MarshalBinary returns the canonical framed RGA state.
func (*RGA) MarshalBinaryWithClockState ¶
func (*RGA) MarshalBinaryWithClockStateAndLimits ¶ added in v1.0.19
func (r *RGA) MarshalBinaryWithClockStateAndLimits(limits frame.DecoderLimits) ([]byte, clock.State, error)
MarshalBinaryWithClockStateAndLimits returns one complete state frame and the HLC state that must be persisted atomically before the replica ID is reused. The frame is constrained by limits.
func (*RGA) MarshalBinaryWithLimits ¶ added in v1.0.19
func (r *RGA) MarshalBinaryWithLimits(limits frame.DecoderLimits) ([]byte, error)
MarshalBinaryWithLimits returns the canonical framed RGA state while enforcing caller-selected frame limits. It refuses incomplete state rather than serializing unresolved parent references.
func (*RGA) MarshalDeltaSince ¶ added in v1.0.19
MarshalDeltaSince encodes DeltaSince(base) using the matching delta wire protocol for base. The receiver must apply the result to a state that contains base (or a CRDT superset of base).
func (*RGA) MarshalDeltaSinceBase ¶ added in v1.0.19
func (r *RGA) MarshalDeltaSinceBase(base SnapshotBase) ([]byte, error)
MarshalDeltaSinceBase encodes DeltaSinceBase(base) using the matching delta wire protocol and default frame limits. Reuse a SnapshotBase when a peer checkpoint serves multiple anti-entropy rounds.
func (*RGA) MarshalDeltaSinceBaseWithLimits ¶ added in v1.0.19
func (r *RGA) MarshalDeltaSinceBaseWithLimits(base SnapshotBase, limits frame.DecoderLimits) ([]byte, error)
MarshalDeltaSinceBaseWithLimits is MarshalDeltaSinceBase with caller-selected output frame bounds.
func (*RGA) MarshalDeltaSinceWithLimits ¶ added in v1.0.19
func (r *RGA) MarshalDeltaSinceWithLimits(base snapshot.Snapshot, limits frame.DecoderLimits) ([]byte, error)
MarshalDeltaSinceWithLimits is MarshalDeltaSince with caller-selected bounds for both decoding the base snapshot and producing the matching delta frame.
func (*RGA) MarshalJSON ¶ added in v1.0.5
MarshalJSON returns a diagnostic summary for structured logs. It omits text content, positions, tombstone identities, and clock state.
func (*RGA) MarshalObfuscatedBinary ¶ added in v1.0.24
MarshalObfuscatedBinary encodes a complete obfuscated legacy scalar RGA state. It does not alter r and refuses incomplete state just like MarshalBinary.
func (*RGA) MarshalObfuscatedBinaryWithLimits ¶ added in v1.0.24
func (r *RGA) MarshalObfuscatedBinaryWithLimits(limits frame.DecoderLimits) ([]byte, error)
MarshalObfuscatedBinaryWithLimits encodes complete obfuscated legacy state while enforcing the supplied output limits.
func (*RGA) MarshalObfuscatedRunBinary ¶ added in v1.0.24
MarshalObfuscatedRunBinary encodes a complete obfuscated run-v2 RGA state. It does not alter r and refuses incomplete state just like MarshalRunBinary.
func (*RGA) MarshalObfuscatedRunBinaryWithLimits ¶ added in v1.0.24
func (r *RGA) MarshalObfuscatedRunBinaryWithLimits(limits frame.DecoderLimits) ([]byte, error)
MarshalObfuscatedRunBinaryWithLimits encodes complete obfuscated run-v2 state while enforcing the supplied output limits.
func (*RGA) MarshalPackedBinary ¶ added in v1.0.31
MarshalPackedBinary encodes complete state with the separately negotiated packed RGA v3 protocol. v1 and run-v2 bytes remain unchanged and are never accepted through this API.
func (*RGA) MarshalPackedBinaryWithLimits ¶ added in v1.0.31
func (r *RGA) MarshalPackedBinaryWithLimits(limits frame.DecoderLimits) ([]byte, error)
MarshalPackedBinaryWithLimits encodes complete packed RGA v3 state while enforcing the caller-selected output limits.
func (*RGA) MarshalPackedDeltaSinceFrameV2 ¶ added in v1.0.32
MarshalPackedDeltaSinceFrameV2 encodes the packed-v3 delta from base to r in a separately negotiated compression-aware outer frame v2. The base must be a complete packed-v3 RGA snapshot.
func (*RGA) MarshalPackedDeltaSinceFrameV2Base ¶ added in v1.0.32
func (r *RGA) MarshalPackedDeltaSinceFrameV2Base(base SnapshotBase) ([]byte, error)
MarshalPackedDeltaSinceFrameV2Base is MarshalPackedDeltaSinceFrameV2 for a validated snapshot base that can be reused across anti-entropy rounds.
func (*RGA) MarshalPackedDeltaSinceFrameV2BaseWithLimits ¶ added in v1.0.32
func (r *RGA) MarshalPackedDeltaSinceFrameV2BaseWithLimits(base SnapshotBase, limits frame.DecoderLimits) ([]byte, error)
MarshalPackedDeltaSinceFrameV2BaseWithLimits encodes a delta against a cached packed-v3 snapshot base without building an intermediate v1 envelope.
func (*RGA) MarshalPackedDeltaSinceFrameV2WithLimits ¶ added in v1.0.32
func (r *RGA) MarshalPackedDeltaSinceFrameV2WithLimits(base snapshot.Snapshot, limits frame.DecoderLimits) ([]byte, error)
MarshalPackedDeltaSinceFrameV2WithLimits is MarshalPackedDeltaSinceFrameV2 with explicit bounds for both base validation and final v2 output.
func (*RGA) MarshalPackedFrameV2 ¶ added in v1.0.32
MarshalPackedFrameV2 encodes complete packed RGA v3 state in the separately negotiated compression-aware outer frame v2. It preserves the packed-v3 payload and scalar Position semantics; only the outer representation changes.
func (*RGA) MarshalPackedFrameV2WithLimits ¶ added in v1.0.32
func (r *RGA) MarshalPackedFrameV2WithLimits(limits frame.DecoderLimits) ([]byte, error)
MarshalPackedFrameV2WithLimits encodes complete packed RGA v3 state in a bounded outer frame v2. Peers must negotiate frame.FormatVersionV2 before accepting it.
func (*RGA) MarshalRunBinary ¶ added in v1.0.6
MarshalRunBinary encodes complete RGA state using the separately negotiated run-v2 frame. It retains v1 scalar Positions and is therefore safe to merge with v1 deltas after decoding.
func (*RGA) MarshalRunBinaryWithLimits ¶ added in v1.0.19
func (r *RGA) MarshalRunBinaryWithLimits(limits frame.DecoderLimits) ([]byte, error)
MarshalRunBinaryWithLimits encodes complete RGA state using the run-v2 frame while enforcing caller-selected output limits.
func (*RGA) MarshalRunDeltaSinceFrameV2 ¶ added in v1.0.27
MarshalRunDeltaSinceFrameV2 encodes the run-v2 delta from base to r in a separately negotiated compression-aware outer frame v2. The base must be a complete run-v2 RGA snapshot; scalar-v1 bases remain a distinct protocol.
func (*RGA) MarshalRunDeltaSinceFrameV2Base ¶ added in v1.0.27
func (r *RGA) MarshalRunDeltaSinceFrameV2Base(base SnapshotBase) ([]byte, error)
MarshalRunDeltaSinceFrameV2Base is MarshalRunDeltaSinceFrameV2 for a validated snapshot base that can be reused across anti-entropy rounds.
func (*RGA) MarshalRunDeltaSinceFrameV2BaseWithLimits ¶ added in v1.0.27
func (r *RGA) MarshalRunDeltaSinceFrameV2BaseWithLimits(base SnapshotBase, limits frame.DecoderLimits) ([]byte, error)
MarshalRunDeltaSinceFrameV2BaseWithLimits encodes a delta against a cached run-v2 snapshot base without building an intermediate v1 envelope.
func (*RGA) MarshalRunDeltaSinceFrameV2WithLimits ¶ added in v1.0.27
func (r *RGA) MarshalRunDeltaSinceFrameV2WithLimits(base snapshot.Snapshot, limits frame.DecoderLimits) ([]byte, error)
MarshalRunDeltaSinceFrameV2WithLimits is MarshalRunDeltaSinceFrameV2 with explicit bounds for both base validation and final v2 output.
func (*RGA) MarshalRunFrameV2 ¶ added in v1.0.27
MarshalRunFrameV2 encodes complete RGA state in the separately negotiated compression-aware outer frame v2. It preserves the run-v2 RGA payload and scalar Position semantics; only the outer representation changes.
func (*RGA) MarshalRunFrameV2WithLimits ¶ added in v1.0.27
func (r *RGA) MarshalRunFrameV2WithLimits(limits frame.DecoderLimits) ([]byte, error)
MarshalRunFrameV2WithLimits encodes complete RGA state in a bounded outer frame v2. Peers must negotiate frame.FormatVersionV2 before accepting it.
func (*RGA) MissingParents ¶ added in v1.0.6
MissingParents returns stable IDs that must arrive before pending nodes can integrate. The returned slice is sorted and safe for callers to retain.
func (*RGA) NextTag ¶ added in v1.0.21
NextTag reserves a local HLC tag without creating an RGA node. It exists for composed CRDTs that persist their formatting metadata with this RGA's clock state. A reserved but un-emitted tag is safe to skip.
func (*RGA) PendingCount ¶ added in v1.0.6
PendingCount reports the number of accepted nodes still waiting for a missing parent. It is useful for replication diagnostics and backpressure.
func (*RGA) PrepareDeletePackedBinaryWithLimits ¶ added in v1.0.31
func (r *RGA) PrepareDeletePackedBinaryWithLimits(offset, count int, limits frame.DecoderLimits) (Delta, []byte, error)
PrepareDeletePackedBinaryWithLimits returns a compact RGA v3 tombstone delta without mutating r.
func (*RGA) PrepareDeletePackedFrameV2WithLimits ¶ added in v1.0.32
func (r *RGA) PrepareDeletePackedFrameV2WithLimits(offset, count int, limits frame.DecoderLimits) (Delta, []byte, error)
PrepareDeletePackedFrameV2WithLimits returns a preflighted packed-v3 deletion delta in a separately negotiated outer frame v2 without applying it.
func (*RGA) PrepareDeleteRunBinaryWithLimits ¶ added in v1.0.21
func (r *RGA) PrepareDeleteRunBinaryWithLimits(offset, count int, limits frame.DecoderLimits) (Delta, []byte, error)
PrepareDeleteRunBinaryWithLimits returns a canonical run-v2 deletion delta without applying its tombstones. It is intended for a composed CRDT that must preflight an enclosing frame before committing local text changes.
func (*RGA) PrepareDeleteRunFrameV2WithLimits ¶ added in v1.0.27
func (r *RGA) PrepareDeleteRunFrameV2WithLimits(offset, count int, limits frame.DecoderLimits) (Delta, []byte, error)
PrepareDeleteRunFrameV2WithLimits returns a preflighted run-v2 deletion delta in a separately negotiated outer frame v2 without applying it.
func (*RGA) PrepareInsertPackedBinaryWithLimits ¶ added in v1.0.31
func (r *RGA) PrepareInsertPackedBinaryWithLimits(offset int, value string, limits frame.DecoderLimits) (Delta, []byte, error)
PrepareInsertPackedBinaryWithLimits returns a preflighted compact RGA v3 insertion without mutating r. Reserved HLC tags remain safe to skip if the caller abandons the surrounding transaction.
func (*RGA) PrepareInsertPackedFrameV2WithLimits ¶ added in v1.0.32
func (r *RGA) PrepareInsertPackedFrameV2WithLimits(offset int, value string, limits frame.DecoderLimits) (Delta, []byte, error)
PrepareInsertPackedFrameV2WithLimits returns a preflighted packed-v3 insertion delta in a separately negotiated outer frame v2 without applying it. Reserved HLC tags remain safe to skip when a caller abandons the surrounding transaction.
func (*RGA) PrepareInsertRunBinaryWithLimits ¶ added in v1.0.21
func (r *RGA) PrepareInsertRunBinaryWithLimits(offset int, value string, limits frame.DecoderLimits) (Delta, []byte, error)
PrepareInsertRunBinaryWithLimits returns a canonical run-v2 insertion delta without adding its nodes to r. It reserves HLC tags, so a failed enclosing transaction may leave safely skipped tags in ClockState. Callers that need an atomic composed CRDT operation can encode and validate their outer frame before applying the returned delta with ApplyDelta.
func (*RGA) PrepareInsertRunFrameV2WithLimits ¶ added in v1.0.27
func (r *RGA) PrepareInsertRunFrameV2WithLimits(offset int, value string, limits frame.DecoderLimits) (Delta, []byte, error)
PrepareInsertRunFrameV2WithLimits returns a preflighted run-v2 insertion delta in a separately negotiated outer frame v2 without applying it.
func (*RGA) ReplaceBinaryWithLimits ¶ added in v1.0.24
func (r *RGA) ReplaceBinaryWithLimits(offset, count int, value string, limits frame.DecoderLimits) ([]byte, error)
ReplaceBinaryWithLimits atomically replaces count visible runes at offset with value and returns one preflighted scalar-v1 delta. A rejected frame or state-limit check leaves both visible text and tombstones unchanged. The HLC may reserve un-emitted insertion tags, which are safe to skip.
func (*RGA) ReplacePackedBinaryWithLimits ¶ added in v1.0.31
func (r *RGA) ReplacePackedBinaryWithLimits(offset, count int, value string, limits frame.DecoderLimits) ([]byte, error)
ReplacePackedBinaryWithLimits atomically replaces visible text with one compact RGA v3 delta. Frame or retention rejection leaves r unchanged.
func (*RGA) ReplacePackedFrameV2WithLimits ¶ added in v1.0.32
func (r *RGA) ReplacePackedFrameV2WithLimits(offset, count int, value string, limits frame.DecoderLimits) ([]byte, error)
ReplacePackedFrameV2WithLimits atomically replaces visible text and returns one preflighted packed-v3 delta in a separately negotiated outer frame v2.
func (*RGA) ReplaceRunBinaryWithLimits ¶ added in v1.0.24
func (r *RGA) ReplaceRunBinaryWithLimits(offset, count int, value string, limits frame.DecoderLimits) ([]byte, error)
ReplaceRunBinaryWithLimits atomically replaces count visible runes at offset with value and returns one preflighted run-v2 delta. It is the editor-facing operation: a text binding must never publish a delete and insert half-pair when a local frame or retention bound rejects the replacement.
func (*RGA) ReplaceRunFrameV2WithLimits ¶ added in v1.0.27
func (r *RGA) ReplaceRunFrameV2WithLimits(offset, count int, value string, limits frame.DecoderLimits) ([]byte, error)
ReplaceRunFrameV2WithLimits atomically replaces visible text and returns one preflighted run-v2 delta in a separately negotiated outer frame v2.
func (*RGA) ResolveAnchor ¶ added in v1.0.23
ResolveAnchor returns the current visible rune offset represented by anchor. Resolution is O(log n) and does not materialize Positions. A tombstoned position remains a structural boundary; a compacted position returns ErrAnchorGone so callers never silently move a selection or cursor.
func (*RGA) ResolveAnchorRange ¶ added in v1.0.32
func (r *RGA) ResolveAnchorRange(anchors AnchorRange) (start, end int, err error)
ResolveAnchorRange resolves both boundaries from one RGA projection. The returned offsets retain the Start/End ordering captured by AnchorRangeAt. A compacted boundary fails closed with ErrAnchorGone.
func (*RGA) RetainsPosition ¶ added in v1.0.24
RetainsPosition reports whether position is still retained as an integrated node or an out-of-order pending node. It intentionally differs from visibility: a deleted position remains an ordering anchor until a safe tombstone compaction removes it. Callers can use it to retire metadata that is attached to a position only after that compaction boundary.
func (*RGA) SnapshotCurrentStateWithLimits ¶ added in v1.0.19
SnapshotCurrentStateWithLimits returns a complete, HLC-backed snapshot while enforcing caller-selected frame limits. Persist the returned snapshot atomically so that state and clock recovery cannot reuse a mutation tag.
func (*RGA) SnapshotPackedCurrentState ¶ added in v1.0.31
SnapshotPackedCurrentState returns a complete HLC-backed compact RGA v3 snapshot. Persist it with its frontier and clock state before reusing the replica ID.
func (*RGA) SnapshotPackedCurrentStateWithLimits ¶ added in v1.0.31
func (r *RGA) SnapshotPackedCurrentStateWithLimits(limits frame.DecoderLimits) (snapshot.Snapshot, error)
SnapshotPackedCurrentStateWithLimits returns a bounded compact RGA v3 snapshot. Externally supplied snapshots still pass full decode validation in NewFromSnapshotWithOptions before installation.
func (*RGA) SnapshotPackedFrameV2CurrentState ¶ added in v1.0.32
SnapshotPackedFrameV2CurrentState returns an HLC-backed packed-v3 snapshot in the separately negotiated compression-aware outer frame v2.
func (*RGA) SnapshotPackedFrameV2CurrentStateWithLimits ¶ added in v1.0.32
func (r *RGA) SnapshotPackedFrameV2CurrentStateWithLimits(limits frame.DecoderLimits) (snapshot.Snapshot, error)
SnapshotPackedFrameV2CurrentStateWithLimits returns a bounded packed-v3 snapshot in outer frame v2. Persist its state, frontier, and clock atomically before reusing the same replica ID.
func (*RGA) SnapshotRunCurrentState ¶ added in v1.0.6
SnapshotRunCurrentState returns an HLC-backed run-v2 snapshot.
func (*RGA) SnapshotRunCurrentStateWithLimits ¶ added in v1.0.19
func (r *RGA) SnapshotRunCurrentStateWithLimits(limits frame.DecoderLimits) (snapshot.Snapshot, error)
SnapshotRunCurrentStateWithLimits returns an HLC-backed, validated run-v2 snapshot while enforcing caller-selected output limits.
func (*RGA) SnapshotRunFrameV2CurrentState ¶ added in v1.0.27
SnapshotRunFrameV2CurrentState returns an HLC-backed run-v2 snapshot in a separately negotiated compression-aware outer frame v2.
func (*RGA) SnapshotRunFrameV2CurrentStateWithLimits ¶ added in v1.0.27
func (r *RGA) SnapshotRunFrameV2CurrentStateWithLimits(limits frame.DecoderLimits) (snapshot.Snapshot, error)
SnapshotRunFrameV2CurrentStateWithLimits returns a bounded HLC-backed run-v2 snapshot in outer frame v2. Persist its state, frontier, and clock atomically before reusing the same replica ID.
func (*RGA) State ¶
func (r *RGA) State() crdt.StateSnapshot
func (*RGA) TombstoneTags ¶ added in v1.0.6
TombstoneTags returns every retained deletion tag in canonical order. It is an acknowledgement input, not proof that a tag is safe to collect.
func (*RGA) UnmarshalBinary ¶
func (*RGA) UnmarshalBinaryWithLimits ¶
func (r *RGA) UnmarshalBinaryWithLimits(data []byte, limits frame.DecoderLimits) error
func (*RGA) UnmarshalPackedBinary ¶ added in v1.0.31
UnmarshalPackedBinary installs one complete compact RGA v3 state frame.
func (*RGA) UnmarshalPackedBinaryWithLimits ¶ added in v1.0.31
func (r *RGA) UnmarshalPackedBinaryWithLimits(data []byte, limits frame.DecoderLimits) error
UnmarshalPackedBinaryWithLimits installs one complete compact RGA v3 state frame after complete validation and pre-allocation bounds checks.
func (*RGA) UnmarshalRunBinary ¶ added in v1.0.6
UnmarshalRunBinary installs one complete run-v2 RGA state frame.
func (*RGA) UnmarshalRunBinaryWithLimits ¶ added in v1.0.19
func (r *RGA) UnmarshalRunBinaryWithLimits(data []byte, limits frame.DecoderLimits) error
UnmarshalRunBinaryWithLimits installs one complete run-v2 RGA state frame while enforcing caller-selected input limits.
func (*RGA) VisibleRunes ¶ added in v1.0.23
VisibleRunes returns copies of the visible stable positions and their runes in display order from one consistent projection. Callers may modify either returned slice. It avoids the duplicated traversal required by separately calling Positions and String when both are needed by a renderer.
func (*RGA) WitnessTag ¶ added in v1.0.21
WitnessTag advances the RGA clock beyond a remote composed-CRDT tag without changing text content. Callers must persist the resulting ClockState with their enclosing state before reusing the replica ID.
type SnapshotBase ¶ added in v1.0.19
type SnapshotBase struct {
// contains filtered or unexported fields
}
SnapshotBase is an immutable, decoded complete RGA state that can be reused for repeated differential encodes against the same peer checkpoint. It has no exported mutable state; create it only with NewSnapshotBase.
func NewSnapshotBase ¶ added in v1.0.19
func NewSnapshotBase(saved snapshot.Snapshot) (SnapshotBase, error)
NewSnapshotBase validates and decodes the saved snapshot once so callers that repeatedly synchronize against the same checkpoint do not reparse its full state frame for every delta.
func NewSnapshotBaseWithLimits ¶ added in v1.0.19
func NewSnapshotBaseWithLimits(saved snapshot.Snapshot, limits frame.DecoderLimits) (SnapshotBase, error)
NewSnapshotBaseWithLimits is NewSnapshotBase with caller-selected decoder limits for the supplied checkpoint.
type UndoManager ¶ added in v1.0.21
type UndoManager struct {
// contains filtered or unexported fields
}
UndoManager records local RGA edits made through it. Undo and redo emit new monotonic RGA deltas; they never rewind shared state, remove tombstones, or erase remote edits. This makes a local history safe to replicate through an at-least-once, out-of-order transport.
The manager intentionally observes no direct RGA mutations. Use its Insert and Delete methods for edits that should be undoable. A caller must Clear history before compacting old structural anchors; otherwise replay fails closed with ErrUndoAnchorGone. The local stack is bounded: when a successful edit would exceed its total retained budget, the manager discards its complete local history and records that newest edit as the next undo step. An individual edit larger than the configured rune budget is rejected before it changes the RGA.
func NewUndoManager ¶ added in v1.0.21
func NewUndoManager(value *RGA) (*UndoManager, error)
NewUndoManager creates a local history for value with the default bounded interactive-text policy.
func NewUndoManagerWithOptions ¶ added in v1.0.36
func NewUndoManagerWithOptions(value *RGA, options UndoOptions) (*UndoManager, error)
NewUndoManagerWithOptions creates a local history for value with explicit local-only retention limits. It neither changes RGA wire semantics nor serializes history for replication.
func (*UndoManager) CanRedo ¶ added in v1.0.21
func (m *UndoManager) CanRedo() bool
CanRedo reports whether a previously undone local edit is available for redo.
func (*UndoManager) CanUndo ¶ added in v1.0.21
func (m *UndoManager) CanUndo() bool
CanUndo reports whether a captured local edit is available for undo.
func (*UndoManager) Clear ¶ added in v1.0.21
func (m *UndoManager) Clear()
Clear discards local history. It does not mutate the shared RGA state.
func (*UndoManager) Delete ¶ added in v1.0.21
func (m *UndoManager) Delete(offset, count int) (Delta, error)
Delete removes one visible range and captures a reinsertion intent as one undo step. Undo does not resurrect deleted positions: it inserts new positions after the original retained predecessor.
func (*UndoManager) Insert ¶ added in v1.0.21
func (m *UndoManager) Insert(offset int, value string) (Delta, error)
Insert applies one local insertion and captures it as one undo step.
func (*UndoManager) Len ¶ added in v1.0.36
func (m *UndoManager) Len() int
Len returns the total number of retained local undo and redo entries.
func (*UndoManager) Redo ¶ added in v1.0.21
func (m *UndoManager) Redo() (Delta, error)
Redo reapplies the most recently undone local edit and moves it back to the undo stack. A failed replay leaves both stacks unchanged.
func (*UndoManager) Undo ¶ added in v1.0.21
func (m *UndoManager) Undo() (Delta, error)
Undo emits the inverse of the most recent captured local edit and moves it to the redo stack. A failed inverse leaves both stacks unchanged.
type UndoOptions ¶ added in v1.0.36
UndoOptions bounds one process-local text undo/redo stack. MaxRunes counts Unicode scalar values retained by both stacks, rather than UTF-8 bytes, so it matches text RGA offsets and position ownership.
func DefaultUndoOptions ¶ added in v1.0.36
func DefaultUndoOptions() UndoOptions
DefaultUndoOptions returns conservative interactive-text history limits. They bound local metadata only and do not replace RGA, frame, outbox, or transport limits.