history

package
v1.0.30-beta.2 Latest Latest
Warning

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

Go to latest
Published: Aug 1, 2026 License: MIT Imports: 12 Imported by: 0

Documentation

Overview

Package history provides bounded, local undo/redo and version-history metadata for CRDT applications. It is deliberately outside the replicated CRDT frame protocols: undo emits new compensating operations through a host supplied executor, while version records reference complete local snapshots.

Index

Constants

This section is empty.

Variables

View Source
var (
	// ErrInvalidOptions reports an unusable local-history resource policy.
	ErrInvalidOptions = errors.New("history: invalid options")
	// ErrInvalidCommand reports an empty, oversized, or otherwise invalid
	// local command. Commands are opaque to this package after this check.
	ErrInvalidCommand = errors.New("history: invalid command")
	// ErrInvalidState reports a malformed, non-canonical, or over-limit local
	// history record. It is intentionally distinct from a CRDT frame error.
	ErrInvalidState = errors.New("history: invalid state")
	// ErrNoUndo reports that no local command is available for undo.
	ErrNoUndo = errors.New("history: no undo operation")
	// ErrNoRedo reports that no undone local command is available for redo.
	ErrNoRedo = errors.New("history: no redo operation")
	// ErrExecutor reports a nil or panicking command executor.
	ErrExecutor = errors.New("history: executor failure")
	// ErrResourceLimit reports a configured local history limit.
	ErrResourceLimit = errors.New("history: resource limit exceeded")
)

Functions

This section is empty.

Types

type Event

type Event struct {
	Scope   string
	Command []byte
	Emitted []byte
}

Event describes one successfully applied local command. Emitted is copied so a caller can append it to a durable outbox without exposing manager storage.

type Executor

type Executor interface {
	Execute(scope string, command []byte) (Result, error)
}

Executor interprets one opaque command for a named local scope. It must either leave the scope unchanged and return an error, or atomically apply the command and return the compensating command. It must not retain aliases to command bytes. The executor owns CRDT type checks, authorization, and output framing; history only owns stack ordering and local-record bounds.

type ExecutorFunc

type ExecutorFunc func(scope string, command []byte) (Result, error)

ExecutorFunc adapts a function to Executor.

func (ExecutorFunc) Execute

func (f ExecutorFunc) Execute(scope string, command []byte) (Result, error)

Execute calls f.

type ID

type ID [sha256.Size]byte

ID is the content address of one immutable version. It includes canonical parent IDs and canonical local snapshots, so changing either creates a new ID. It is not a replica identity, cryptographic signature, or authorization token.

func (ID) String

func (id ID) String() string

String returns the lowercase hexadecimal content address.

type Manager

type Manager struct {
	// contains filtered or unexported fields
}

Manager tracks commands from any number of named scopes in one local stack. A scope normally identifies one concrete type instance, such as "richtext/body", "list/tasks", or "tree/outline". It does not observe direct CRDT mutations: call Execute for every local mutation that must be undoable, and route remote mutations directly to the CRDT without recording them.

Manager serializes command execution so the stack order and host executor order agree. It never holds its state mutex while invoking Executor.

func NewManager

func NewManager(executor Executor, options Options) (*Manager, error)

NewManager creates an empty local history manager.

func NewManagerFromBinary

func NewManagerFromBinary(executor Executor, options Options, data []byte) (*Manager, error)

NewManagerFromBinary restores a local undo/redo stack after the host has restored the corresponding CRDT state. The host must persist both records in one transaction; restoring a history against a different CRDT snapshot is a semantic error outside this package's ability to repair.

func (*Manager) CanRedo

func (m *Manager) CanRedo() bool

CanRedo reports whether one previously undone local command is available.

func (*Manager) CanUndo

func (m *Manager) CanUndo() bool

CanUndo reports whether one captured local command is available.

func (*Manager) Clear

func (m *Manager) Clear()

Clear discards local history without modifying any CRDT scope.

func (*Manager) Execute

func (m *Manager) Execute(scope string, command []byte) (Event, error)

Execute applies a new local command and records its returned compensating command. A successful new command clears the redo stack. The returned event contains the canonical payload to persist/publish; no remote operation is ever captured automatically.

func (*Manager) Len

func (m *Manager) Len() int

Len returns the total number of retained undo and redo entries.

func (*Manager) MarshalBinary

func (m *Manager) MarshalBinary() ([]byte, error)

MarshalBinary returns a canonical, checksummed local-history record. It is not a CRDT frame and must not be sent to peers.

func (*Manager) Redo

func (m *Manager) Redo() (Event, error)

Redo re-applies the most recently undone local change. Its executor result becomes the next undo command for the same reason described by Undo.

func (*Manager) Undo

func (m *Manager) Undo() (Event, error)

Undo applies the compensating command for the latest captured local change. Its executor result replaces the redo command, allowing a type adapter to allocate fresh CRDT identities rather than trying to resurrect old ones.

type Options

type Options struct {
	MaxEntries      int
	MaxStateBytes   int
	MaxScopeBytes   int
	MaxCommandBytes int
	MaxResultBytes  int
}

Options bounds one process-local undo/redo stack. The defaults are intended for interactive documents, not as a substitute for a product retention policy. Applications should choose smaller values for untrusted plugins or constrained devices.

func DefaultOptions

func DefaultOptions() Options

DefaultOptions returns conservative interactive-history limits.

type Repository

type Repository struct {
	// contains filtered or unexported fields
}

Repository is a concurrent-safe, local content-addressed version DAG. It does not merge CRDTs itself: a caller first materializes a merged State by using each concrete CRDT's merge and snapshot APIs, then records that State with Merge. This prevents the metadata layer from guessing type-specific conflict semantics or bypassing HLC recovery requirements.

func NewRepository

func NewRepository(options RepositoryOptions) (*Repository, error)

NewRepository creates an empty local version repository.

func NewRepositoryFromBinary

func NewRepositoryFromBinary(options RepositoryOptions, data []byte) (*Repository, error)

NewRepositoryFromBinary restores a complete local version DAG. Callers must still validate and restore a selected concrete snapshot through that CRDT's own recovery constructor before reusing a replica ID.

func (*Repository) Branches

func (r *Repository) Branches() []string

Branches returns sorted local branch names.

func (*Repository) Commit

func (r *Repository) Commit(branch string, state State) (ID, error)

Commit records one new version on branch. The branch must already exist; its prior head becomes the sole parent, or the version is a genesis commit for an empty branch.

func (*Repository) CreateBranch

func (r *Repository) CreateBranch(name string, from ID) error

CreateBranch creates an empty branch when from is zero, or a branch rooted at an existing version. Branch names are local metadata and are never sent as CRDT fields.

func (*Repository) Fork

func (r *Repository) Fork(target, source string) error

Fork creates target at source's current head. Source must have at least one version; use CreateBranch with a zero ID for a new genesis branch.

func (*Repository) Head

func (r *Repository) Head(branch string) (ID, bool)

Head returns the current content address for branch.

func (*Repository) History

func (r *Repository) History(branch string) []Version

History returns branch's reachable versions in deterministic newest-first depth-first order. Shared ancestors appear only once.

func (*Repository) Len

func (r *Repository) Len() int

Len returns the number of retained immutable versions.

func (*Repository) MarshalBinary

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

MarshalBinary returns a canonical, checksummed local version-DAG record. It contains complete snapshots and should receive the same encryption-at-rest, authorization, retention, and backup treatment as application data.

func (*Repository) Merge

func (r *Repository) Merge(target, source string, state State) (ID, error)

Merge records a host-materialized merge snapshot on target. target and source must both have heads. The resulting version has the two distinct heads as parents in canonical order. This method intentionally does not call Merge on arbitrary snapshot bytes because concrete CRDT and schema semantics must remain the authority for conflict resolution.

func (*Repository) Version

func (r *Repository) Version(id ID) (Version, bool)

Version returns a copy of one immutable version.

type RepositoryOptions

type RepositoryOptions struct {
	MaxVersions        int
	MaxBranches        int
	MaxParents         int
	MaxSnapshots       int
	MaxScopeBytes      int
	MaxSnapshotBytes   int
	MaxFrontierEntries int
	MaxReplicaIDBytes  int
	MaxEncodedBytes    int
}

RepositoryOptions bounds local version browsing and persistence metadata. MaxEncodedBytes bounds the complete MarshalBinary result, while MaxSnapshotBytes bounds one embedded CRDT state frame before it is decoded.

func DefaultRepositoryOptions

func DefaultRepositoryOptions() RepositoryOptions

DefaultRepositoryOptions returns a conservative bounded local history policy. A production host should select limits from its document count, checkpoint policy, and storage budget.

type Result

type Result struct {
	Reverse []byte
	Emitted []byte
}

Result is the outcome of applying one opaque local command. Reverse is the command that compensates exactly the mutation just applied; it may differ from the original command because CRDT undo/redo commonly allocates fresh tags. Emitted is the canonical local delta or batch a host should persist and publish after it has atomically persisted its own CRDT state and this manager's MarshalBinary output.

type Snapshot

type Snapshot struct {
	Scope string
	Value snapshot.Snapshot
}

Snapshot names one complete CRDT snapshot within a logical version. Scope names let a host version several independently typed CRDTs together without creating a new combined replication frame.

type State

type State struct {
	Snapshots []Snapshot
}

State is the complete local materialization recorded at one version point. Its snapshots are copied and kept in canonical scope order by Repository.

type Version

type Version struct {
	ID      ID
	Parents []ID
	State   State
}

Version is an immutable node in the local version DAG. Parents are in canonical content-address order. A merge version has two or more parents.

Jump to

Keyboard shortcuts

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