text

package
v1.0.25-beta.3 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 30, 2026 License: MIT Imports: 10 Imported by: 0

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

Examples

Constants

View Source
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
)

Variables

View Source
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")
)
View Source
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")
)
View Source
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")
)
View Source
var ErrNoRedo = errHistoryEmpty("text: no redo operation")

ErrNoRedo reports that no previously undone local operation can be redone.

View Source
var ErrNoUndo = errHistoryEmpty("text: no undo operation")

ErrNoUndo reports that no captured local operation can be undone.

Functions

func LegacyFrameType added in v1.0.25

func LegacyFrameType() crdt.FrameType

LegacyFrameType returns the stable scalar RGA v1 state/delta pair. It is a migration-compatible contract, not the default for new text groups.

func StableFrameType added in v1.0.24

func StableFrameType() crdt.FrameType

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 local cursor or selection metadata for an RGA boundary. It is deliberately not a CRDT state field and has no framed wire format: applications may transport it as ephemeral presence only after authenticating their peer and group. A retained tombstone continues to resolve; exact tombstone compaction invalidates an anchor rather than relocating it.

func (Anchor) Valid added in v1.0.23

func (anchor Anchor) Valid() bool

Valid reports whether anchor has a supported association and either a valid RGA position or the zero root position.

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 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

func UnmarshalRGADelta(data []byte) (Delta, error)

UnmarshalRGADelta decodes one bounded canonical RGA delta frame.

func UnmarshalRGADeltaWithLimits

func UnmarshalRGADeltaWithLimits(data []byte, limits frame.DecoderLimits) (Delta, error)

func UnmarshalRGARunDelta added in v1.0.6

func UnmarshalRGARunDelta(data []byte) (Delta, error)

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

func (d Delta) MarshalBinary() ([]byte, error)

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

func (d Delta) MarshalJSON() ([]byte, error)

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

func (d Delta) MarshalObfuscatedBinary() ([]byte, error)

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

func (d Delta) MarshalObfuscatedRunBinary() ([]byte, error)

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) MarshalRunBinary added in v1.0.6

func (d Delta) MarshalRunBinary() ([]byte, error)

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) Merge

func (d Delta) Merge(other Delta) (Delta, error)

func (Delta) NodePositions added in v1.0.21

func (d Delta) NodePositions() []Position

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

func (d Delta) Obfuscate() (Delta, error)

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

type Options struct {
	MaxNodes        int
	MaxTombstones   int
	MaxPendingNodes int
	MaxPendingBytes int
}

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

type Position = crdt.Tag

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 New

func New(replicaID string) (*RGA, error)

func NewFromClock

func NewFromClock(state clock.State) (*RGA, error)

func NewFromClockWithOptions added in v1.0.6

func NewFromClockWithOptions(state clock.State, options Options) (*RGA, error)

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 NewFromSnapshot

func NewFromSnapshot(saved snapshot.Snapshot) (*RGA, error)

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

func NewWithOptions(replicaID string, options Options) (*RGA, error)

NewWithOptions constructs an RGA with explicit retention limits.

func (*RGA) AnchorAt added in v1.0.23

func (r *RGA) AnchorAt(offset int) (Anchor, error)

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) ApplyDelta

func (r *RGA) ApplyDelta(delta Delta) error
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 (r *RGA) ClockState() clock.State

func (*RGA) CompactEligibleTombstones added in v1.0.19

func (r *RGA) CompactEligibleTombstones(tags []Position) (int, error)

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. Callers still need an authenticated exact-acknowledgement epoch, a durable post-compaction checkpoint, and retirement of old deltas before using this method.

func (*RGA) CompactTombstones added in v1.0.6

func (r *RGA) CompactTombstones(tags []Position) (int, error)

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

func (r *RGA) Delete(offset, count int) (Delta, error)

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

func (r *RGA) DeleteBinaryWithLimits(offset, count int, limits frame.DecoderLimits) ([]byte, error)

DeleteBinaryWithLimits deletes visible text and returns the same preflighted canonical tombstone frame used to establish the local output budget.

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) DeleteWithLimits added in v1.0.19

func (r *RGA) DeleteWithLimits(offset, count int, limits frame.DecoderLimits) (Delta, error)

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

func (r *RGA) DeltaSince(base snapshot.Snapshot) (Delta, error)

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

func (r *RGA) Insert(offset int, value string) (Delta, error)

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) 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) InsertWithLimits added in v1.0.19

func (r *RGA) InsertWithLimits(offset int, value string, limits frame.DecoderLimits) (Delta, error)

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

func (r *RGA) Len() int

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

func (r *RGA) MarshalBinary() ([]byte, error)

MarshalBinary returns the canonical framed RGA state.

func (*RGA) MarshalBinaryWithClockState

func (r *RGA) MarshalBinaryWithClockState() ([]byte, clock.State, error)

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

func (r *RGA) MarshalDeltaSince(base snapshot.Snapshot) ([]byte, error)

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

func (r *RGA) MarshalJSON() ([]byte, error)

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

func (r *RGA) MarshalObfuscatedBinary() ([]byte, error)

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

func (r *RGA) MarshalObfuscatedRunBinary() ([]byte, error)

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) MarshalRunBinary added in v1.0.6

func (r *RGA) MarshalRunBinary() ([]byte, error)

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) Merge

func (r *RGA) Merge(other *RGA) error

func (*RGA) MissingParents added in v1.0.6

func (r *RGA) MissingParents() []Position

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

func (r *RGA) NextTag() (Position, error)

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

func (r *RGA) PendingCount() int

PendingCount reports the number of accepted nodes still waiting for a missing parent. It is useful for replication diagnostics and backpressure.

func (*RGA) Positions

func (r *RGA) Positions() []Position

Positions returns a copy of visible stable IDs in display order.

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) 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) 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) 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) ResolveAnchor added in v1.0.23

func (r *RGA) ResolveAnchor(anchor Anchor) (int, error)

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) RetainsPosition added in v1.0.24

func (r *RGA) RetainsPosition(position Position) bool

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) Snapshot

func (r *RGA) Snapshot(frontier map[string]crdt.Tag) (snapshot.Snapshot, error)

func (*RGA) SnapshotCurrentState

func (r *RGA) SnapshotCurrentState() (snapshot.Snapshot, error)

func (*RGA) SnapshotCurrentStateWithLimits added in v1.0.19

func (r *RGA) SnapshotCurrentStateWithLimits(limits frame.DecoderLimits) (snapshot.Snapshot, error)

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) SnapshotRunCurrentState added in v1.0.6

func (r *RGA) SnapshotRunCurrentState() (snapshot.Snapshot, error)

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) State

func (r *RGA) State() crdt.StateSnapshot

func (*RGA) String

func (r *RGA) String() string

func (*RGA) TombstoneTags added in v1.0.6

func (r *RGA) TombstoneTags() []Position

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 (r *RGA) UnmarshalBinary(data []byte) error

func (*RGA) UnmarshalBinaryWithLimits

func (r *RGA) UnmarshalBinaryWithLimits(data []byte, limits frame.DecoderLimits) error

func (*RGA) UnmarshalRunBinary added in v1.0.6

func (r *RGA) UnmarshalRunBinary(data []byte) error

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

func (r *RGA) VisibleRunes() ([]Position, []rune)

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

func (r *RGA) WitnessTag(tag Position) error

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.

func NewUndoManager added in v1.0.21

func NewUndoManager(value *RGA) (*UndoManager, error)

NewUndoManager creates a local history for value.

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) 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.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL