Documentation
¶
Overview ¶
Async reactive context — a Go port of lazily-dart's lib/src/async_context.dart (docs/async.md).
This is a separate reactive surface for computations whose values are produced by blocking / future-returning functions. It is NOT an overload of the synchronous Context (see core.go); it is a distinct graph with its own handles, because async computes introduce in-flight state, cancellation, stale completion, and dependency tracking across suspension points that the synchronous graph does not have. Only resolved slot values would ever cross IPC/FFI — this file is compute, not protocol.
Channel-first architecture (share by communicating) ¶
The whole graph is owned by a SINGLE owner goroutine (AsyncContext.loop). Every graph mutation and read is serialized as a command func() sent over the command channel; the loop executes them one at a time, so no per-field mutex is needed and there are no data races on graph state. Callers that need a result capture it in closure variables and wait for the command to run (AsyncContext.do). Compute results are posted back to the loop by the compute goroutine (AsyncContext.post).
Async compute functions themselves run in their own goroutines (they may block), mirroring how Dart's futures run "concurrently" on the event loop while all synchronous state transitions happen on the single thread between await points. A compute reads its dependencies through an AsyncComputeContext whose TrackSource / TrackComputed helpers register dependency edges (via the loop) before the awaited read.
Supersession (Dart's _Superseded) == context cancellation ¶
When a slot's dependency changes, the in-flight compute is superseded: its per-compute context.Context is cancelled and every current waiter is told to re-resolve (asyncResult.superseded). The re-resolve loop in AsyncComputed.GetAsync observes that and starts over from the current slot state, exactly like Dart's re-resolve loop catching _Superseded. The stale compute goroutine may still finish, but its completion is discarded because the slot's in-flight token no longer matches (identity gate in onComplete).
Lifecycle ¶
DisposeAsync / Close mark the context disposed, cancel every in-flight compute, deliver a disposed error to blocked waiters, run and await effect cleanups, then tear down the owner goroutine. No goroutine is leaked: compute and effect goroutines observe their cancelled context or post through a stop-aware channel, and blocked callers unblock on the loop's stop signal.
Disposal, teardown scopes, and edge-degree introspection for the *async* reactive graph (#lzspecedgeindex).
The synchronous plane's counterpart lives in disposal.go, and the three semantics it documents hold here unchanged:
Disposal dirties the surviving dependent cone. The async graph makes this even sharper than the sync one: GetAsync short-circuits on AsyncComputedResolved, so a downstream slot left Resolved serves its cached value forever and no later pull can rescue it. This is the same shape as the cascade defect fixed in bdfdbce, reached by a different route. Teardown reuses AsyncContext.propagate — the very walk that fix installed — rather than adding a second one.
Effects reached by that walk are marked, not rerun. propagate's schedule=false branch is that rule.
Scope teardown is reverse creation order, for effect cleanups.
Everything here runs inside the owner goroutine via AsyncContext.do, so the loop-owned graph state stays single-threaded exactly as the rest of the file assumes.
Keyed cell collections — SourceMap, SourceTree, and keyed reconciliation (cell-model.md § Keyed cell collections).
A keyed cell collection is a *composition of cells*, not a new cell kind. It maps keys K to per-entry Cells and adds dedicated membership and order reactive signals so the three reactivity planes stay independent:
- writing one entry's value invalidates only that entry's value readers;
- adding/removing a key invalidates membership readers (Len / ContainsKey) and order readers (Keys), but not unrelated entry value readers;
- a pure reorder (atomic move) invalidates order readers only.
Ported from lazily-dart lib/src/collections.dart, mirroring lazily-rs/src/cell_family.rs (reactive) and lazily-rs/src/reconcile.rs (LIS). Validated against lazily-spec/conformance/collections/{cellmap_independence, cellmap_atomic_move,keyed_reconciliation_lis}.json.
Semantic note on the `comparable` constraint: core.go's Cell[T] requires a comparable T for the PartialEq guard, and keyed reconciliation compares entry values for the Update op. Both mean the value type V must support ==, so this module constrains V to `comparable` and stores per-key values in a plain Cell[V] (no boxing needed). This matches the Dart port's use of Dart `==` / PartialEq exactly, and gives real handle stability: an atomic move never re-mints the entry's *Cell, so the same pointer (and its dependents) survive.
Package lazily provides lazy reactive primitives for Go — the Cell kernel (#lzcellkernel) — plus the lazily-spec wire protocol, CRDT collection types, keyed cell collections, state machines/charts, and the distributed CRDT plane.
A Go port of the lazily reactive family (lazily-rs, lazily-py, lazily-kt, lazily-js, lazily-dart, lazily-zig), conformant with lazily-spec and lazily-formal.
The reactive family (v2 kernel). "Cell" is a conceptual word for a value-bearing reactive node, not a Go type — the two kinds are two concrete handle structs, and write protection lives in the type (design §3/§4):
- Source[T] — a value written from outside; the only kind with Set/Merge. Folds writes under a MergePolicy (KeepLatest by default = a plain cell; Sum/Max = the former MergeCell). Constructors: NewSource / NewSourceWithPolicy.
- Computed[T] — a value computed from upstream; lazily cached and dependency-tracking, with neither Set nor Merge (so computed.Set(…) does not compile). NewComputed(f) is GUARDED by default: a recompute yielding an equal value suppresses the downstream cascade. NewSlot(f) is the bound-free storage-sense primitive (T any, no guard) for non-comparable values. computed.Eager() makes it eager (the former Signal), returning the same handle; computed.Lazy() reverses it. The former Memo is removed — a Computed IS the guarded form.
- Effect — a side-effect sink (ctx.effect); outside the Cell hierarchy.
The v1 `Cell[T]` read-genus interface is dropped: no Go generic code used it as a bound, and v2 no longer needs a genus for write protection.
Values are lazy by default: dependents are marked dirty on invalidation but only recompute when read. For eager push-style semantics, call Eager on a Computed.
A Context is the shared scope. Dependency tracking is value-threaded through a per-recompute Compute view — there is no ambient recompute stack — and cached slot values live on the nodes themselves, not in a shared Context table, so reads stay O(1) regardless of graph size. All reactives that react to each other must share a Context. Context is not safe for concurrent use by multiple goroutines; use ThreadSafeContext (see thread_safe.go) or the channel-serialized AsyncContext (see async_context.go) for concurrent access.
Disposal, teardown scopes, and edge-degree introspection for the synchronous reactive graph (#lzspecedgeindex).
Why this exists: a Go handle is a pointer, and dropping the last pointer to a *Slot reclaims nothing reactive. The node's edge on each of its dependencies is a *strong* reference held by the context's graph, so a long-lived source retains every node that ever read it. Under subscribe/unsubscribe churn the dependent set grows without bound even though the live subscriber count is constant, and the cost is paid twice — memory, and propagation, since every write walks the whole list. Explicit disposal is the fix, exactly as in lazily-rs (`Context::dispose_slot` / `dispose_cell`) and lazily-js (`disposeSlot`).
Three semantics this file must preserve ¶
Disposal dirties the surviving dependent cone. Detaching edges without marking dependents leaves a live reader frozen on the value it cached before the disposal — the defect fixed in lazily-rs 5db90d2 and lazily-js 4d20670. The cone walk here reuses reactiveBase.invalidate (core.go) rather than adding a second walk that could drift from it.
Effects (and other eager nodes) reached by that walk are marked, not run. Disposal is not a publish: running an effect mid-teardown re-enters a compute that reads the node being disposed, which breaks idempotence. Context.disposing gates this; see Effect.onInvalidate and Memo.invalidate in core.go. A Signal's eager pull is an ordinary Effect, so it is covered by the Effect case rather than needing a rule of its own.
Scope teardown is reverse creation order. Graph state is order independent, but effect *cleanups* are side effects with an observable order, and ending a scope is proved observationally equal to disposing each member individually (lazily-formal `disposeScope_eq_disposeAll`).
Why reads of a disposed node panic ¶
A compute closure has signature `func(*Compute) T`. There is no error channel through it, so a nested read of a disposed dependency cannot be reported by a return value without changing every user compute's signature. Panic/recover is the only mechanism that crosses an arbitrary closure, and it matches the reference binding: lazily-rs panics on a read of a torn-down node too. Disposal is a caller contract ("nothing may still read it"), and Go already uses panic for contract violations. TryGet is the checked form at the boundary; Get is unchanged on the hot path.
Instrumentation — benchmark harness for reactive operations.
Lightweight micro-benchmarks for the reactive core, keyed collections, and CRDT types. This is the in-library instrumentation API (not Go `testing.B` benchmarks); drive it from a `main` or a tool.
Ported from lazily-dart lib/src/instrumentation.dart. Semantics match the Dart harness: each scenario is executed `iterations` times and the total wall-clock time is recorded in microseconds.
Reactive queue — QueueCell (SPSC primitive with MPSC usage rule) plus the pluggable QueueStorage backend (cell-model.md § Reactive queues).
A reactive queue is a FIFO collection *composed of cells* — not a new cell kind — that adds queue semantics (push to tail, pop from head) to the reactive graph. It adds no new merge unit; each element is an ordinary value subject to the same single-writer / multi-write classification.
The distinguishing property of a reactive queue is that invalidation is scoped to **reader kind**, not to individual positions:
- a push invalidates length/is_empty (and head when transitioning from empty), plus is_full when it fills a bounded queue;
- a pop invalidates head/length/is_empty (plus is_full when it un-fills);
- neither push nor pop touches the closed reader; only Close does;
- a no-op (push at capacity → Full, pop on empty → Empty/Closed, close of an already-closed queue) invalidates nothing.
QueueCell is specified as a single-producer, single-consumer (SPSC) primitive: one writer owns the tail, one reader owns the head, so the producer is the natural FIFO sequencer (push order = delivery order). MPSC (multi-producer, single-consumer) is a *usage rule on the same primitive*, not a separate type: multiple producers push to the same tail inside a Context.Batch boundary; the batch serializes the pushes into a deterministic order and coalesces the cascade into one observable transition. There is no MPSCQueueCell type — introducing one would imply SPMC/MPMC siblings that in fact differ in semantics, not cardinality (see TopicCell / WorkQueueCell).
The shell / storage split: the reactive shell owns the demand-driven reader-kinds and the invalidation logic (storage-agnostic — this is what the formal model LazilyFormal.QueueCell pins); the storage backend owns the FIFO data structure and is pluggable via the QueueStorage interface. The default VecDequeStorage is an unbounded slice-backed queue; a bounded one exposes a capacity and reactive backpressure via IsFull. Distribution is a storage-backend property, not a shell property.
Ported from lazily-rs/src/queue.rs, mirroring lazily-kt Queue.kt, lazily-cpp queue.hpp, lazily-js queue.js, and lazily-zig queue.zig. Validated against lazily-spec/conformance/collections/queuecell_*.json.
Memoized semantic tree — a reactive, incrementally-memoized fold tree.
One Memo slot per node folds (node value, [child derived values]). Editing one node recomputes only its ANCESTOR CHAIN; a sibling subtree's derived slot stays cached. A node edit that does not change the folded value does not re-run a downstream consumer (the Memo equality guard).
Composes over the reactive Context/Cell/Memo primitives in core.go. Ported from lazily-dart lib/src/sem_tree.dart (which mirrors lazily-js src/sem-tree.js). Conforms to lazily-spec conformance/collections/semtree_incremental.json.
Harel/SCXML hierarchical state chart — compound + parallel (orthogonal) regions, shallow + deep history, entry/exit/transition action ordering, named guards (fail-closed), and external + internal transitions.
Ported from lazily-dart lib/src/state_chart.dart (feature row "Harel state charts"). The native counterpart of lazily-formal's LazilyFormal.StateChart and lazily-rs/lazily-kt state charts. It is COMPUTE, not protocol: a chart is never serialized as a distinct wire kind — only its converged active configuration crosses the wire as an ordinary cell payload.
The active configuration is backed by a Cell so any Slot/Signal/Memo/observer reading Configuration, ActiveLeaves, or Matches is invalidated on a real transition; a no-op (configuration unchanged) is suppressed by the cell's structural-equality guard. Because Cell requires a comparable value type and a set of active states is not comparable, the cell holds a canonical sorted-and-joined configuration key (structural equality on that string == structural equality on the set); the authoritative set is kept alongside.
Send is deterministic by construction — a total function of (chart, configuration, history, guards, event), mirroring the Lean StateChart.send. The declarative chart form is parsed from JSON conforming to lazily-spec/schemas/statechart.json via ChartDefFromJSON. `run` actions and {"expr": …} context guards are rejected explicitly; `final` states are accepted as leaves without raising completion (done) events, matching lazily-py and lazily-kt.
Thread-safe reactive context — a lock-serialized batch boundary.
The Go counterpart of lazily-py's ThreadSafeContext and the Lean LazilyFormal.ThreadSafe model (lazily-spec § "Concurrency layers are required"). The behavioral contract: serializing concurrent cell writes through a batch boundary coalesces them into one invalidation pass whose result is a deterministic function of the writes — independent of the interleaving the lock happened to pick.
Go has real threads (goroutines), so this layer is required (feature row "Thread-safe context (lock-backed)" is ✅ for Go, unlike the single-isolate JS/Dart runtimes). ThreadSafeContext wraps a single-threaded Context with a reentrant lock and reuses the core batch coalescing, so a one-write section is observationally identical to a plain Cell.Set — the thread-safe context refines the single-threaded kernel.
Index ¶
- Constants
- Variables
- func ApplyBatch(nodes map[any]NodeEntry, batch []BatchWrite) (map[any]NodeEntry, []any)
- func AssignStableKeys(oldBlocks, newBlocks []Block) []string
- func BuildStateEvent(docHash, eventType string, fields map[string]any, eventSuffix string) map[string]any
- func CheckedDeadline(now, duration uint64) (uint64, error)
- func ContentHash(text string) uint64
- func DocumentHash(path string) uint64
- func FlushBatch(nodes map[any]NodeEntry, dependents map[any][]any, batch []BatchWrite) map[any]NodeEntry
- func Get[T any](c ComputeOps, h Trackable[T]) T
- func Normalize(text string) string
- func Own[N GraphNode](s *TeardownScope, n N) N
- func OwnAsync[N AsyncGraphNode](s *AsyncTeardownScope, n N) N
- func Read[T any](t *ThreadSafeContext, fn func(ctx *Context) T) T
- func ResolveValue(value IpcValue, backend BlobBackend) ([]byte, bool)
- func RetainLive[T any](e *ExpiryPolicy, batch []TimedValue[T]) []T
- func Similarity(a, b string) float64
- func TSSetCell[T comparable](t *ThreadSafeContext, cell *Source[T], value T)
- func TrackAsync[T any](cc *AsyncComputeContext, computed *AsyncComputed[T]) (T, error)deprecated
- func TrackCell[T any](cc *AsyncComputeContext, source *AsyncSource[T]) Tdeprecated
- func TrackComputed[T any](cc *AsyncComputeContext, computed *AsyncComputed[T]) (T, error)
- func TrackSource[T any](cc *AsyncComputeContext, cell *AsyncSource[T]) T
- func UnionDependents(dependents map[any][]any, sources []any) []any
- func UnlinkShmBackend(name string)
- func ValidateBlobRef(ref ShmBlobRef, maxLen *int64) bool
- type Alignment
- type ArrowBackend
- type AsyncCellHandledeprecated
- type AsyncCellMapdeprecated
- type AsyncComputeContext
- type AsyncComputed
- func NewAsyncComputed[T any](c *AsyncContext, compute func(cc *AsyncComputeContext) (T, error)) *AsyncComputed[T]
- func NewAsyncComputedRippleWhen[T any](c *AsyncContext, compute func(cc *AsyncComputeContext) (T, error), ...) *AsyncComputed[T]
- func NewAsyncComputedWithEquals[T any](c *AsyncContext, compute func(cc *AsyncComputeContext) (T, error), ...) *AsyncComputed[T]
- func NewAsyncMemo[T any](c *AsyncContext, compute func(cc *AsyncComputeContext) (T, error), ...) *AsyncComputed[T]deprecated
- func NewAsyncSlot[T any](c *AsyncContext, compute func(cc *AsyncComputeContext) (T, error)) *AsyncComputed[T]deprecated
- func (s *AsyncComputed[T]) Dispose()
- func (s *AsyncComputed[T]) DisposeAsync()
- func (s *AsyncComputed[T]) Get() (T, bool)
- func (s *AsyncComputed[T]) GetAsync(ctx context.Context) (T, error)
- func (s *AsyncComputed[T]) Revision() int
- func (s *AsyncComputed[T]) State() AsyncComputedState
- func (s *AsyncComputed[T]) Value() (T, bool)
- type AsyncComputedMap
- type AsyncComputedState
- type AsyncContext
- func (c *AsyncContext) Batch(run func())
- func (c *AsyncContext) Close() error
- func (c *AsyncContext) DependencyCount(n AsyncGraphNode) int
- func (c *AsyncContext) DependentCount(n AsyncGraphNode) int
- func (c *AsyncContext) DisposeAsync()
- func (c *AsyncContext) EffectAsync(body func(cc *AsyncComputeContext) func()) *AsyncEffectHandle
- func (c *AsyncContext) IsDisposed(n AsyncGraphNode) bool
- func (c *AsyncContext) Scope() *AsyncTeardownScope
- func (c *AsyncContext) WithScope(fn func(s *AsyncTeardownScope))
- type AsyncEffectHandle
- type AsyncGraphNode
- type AsyncMapHandle
- type AsyncQueueCell
- func NewAsyncQueueCell[T comparable](ctx *AsyncContext) *AsyncQueueCell[T, *VecDequeStorage[T]]
- func NewAsyncQueueCellWithStorage[T comparable, S QueueStorage[T]](ctx *AsyncContext, storage S) *AsyncQueueCell[T, S]
- func NewBoundedAsyncQueueCell[T comparable](ctx *AsyncContext, capacity int) *AsyncQueueCell[T, *VecDequeStorage[T]]
- func (q *AsyncQueueCell[T, S]) Capacity() (int, bool)
- func (q *AsyncQueueCell[T, S]) Close()
- func (q *AsyncQueueCell[T, S]) Elements() []T
- func (q *AsyncQueueCell[T, S]) Head(cc *AsyncComputeContext) (T, bool)
- func (q *AsyncQueueCell[T, S]) IsClosed(cc *AsyncComputeContext) bool
- func (q *AsyncQueueCell[T, S]) IsEmpty(cc *AsyncComputeContext) bool
- func (q *AsyncQueueCell[T, S]) IsFull(cc *AsyncComputeContext) bool
- func (q *AsyncQueueCell[T, S]) Len(cc *AsyncComputeContext) int
- func (q *AsyncQueueCell[T, S]) ReaderHandles() AsyncQueueReaderHandles[T]
- func (q *AsyncQueueCell[T, S]) TryPop() (T, QueuePopError)
- func (q *AsyncQueueCell[T, S]) TryPush(value T) QueuePushError
- type AsyncQueueReaderHandles
- type AsyncReactiveMap
- func (m *AsyncReactiveMap[K, V, H]) ContainsKey(cc *AsyncComputeContext, key K) bool
- func (m *AsyncReactiveMap[K, V, H]) Drive(key K, factory func(K) V) V
- func (m *AsyncReactiveMap[K, V, H]) Entry(key K) *AsyncSource[V]
- func (m *AsyncReactiveMap[K, V, H]) EntryID(key K) (uint64, bool)
- func (m *AsyncReactiveMap[K, V, H]) EntryKind() EntryKind
- func (m *AsyncReactiveMap[K, V, H]) GetOrInsertWith(key K, factory func(K) V) (V, bool)
- func (m *AsyncReactiveMap[K, V, H]) IsEmpty(cc *AsyncComputeContext) bool
- func (m *AsyncReactiveMap[K, V, H]) IsPresent(key K) bool
- func (m *AsyncReactiveMap[K, V, H]) IsResolved(key K) bool
- func (m *AsyncReactiveMap[K, V, H]) Keys(cc *AsyncComputeContext) []K
- func (m *AsyncReactiveMap[K, V, H]) Len(cc *AsyncComputeContext) int
- func (m *AsyncReactiveMap[K, V, H]) LenUntracked() int
- func (m *AsyncReactiveMap[K, V, H]) MoveAfter(key, anchor K) bool
- func (m *AsyncReactiveMap[K, V, H]) MoveBefore(key, anchor K) bool
- func (m *AsyncReactiveMap[K, V, H]) MoveTo(key K, index int) bool
- func (m *AsyncReactiveMap[K, V, H]) Observe(key K, factory func(K) V) (V, bool)
- func (m *AsyncReactiveMap[K, V, H]) ObserveTracked(cc *AsyncComputeContext, key K) (V, bool)
- func (m *AsyncReactiveMap[K, V, H]) Position(key K) (int, bool)
- func (m *AsyncReactiveMap[K, V, H]) PresentCount() int
- func (m *AsyncReactiveMap[K, V, H]) PresentKeys() []K
- func (m *AsyncReactiveMap[K, V, H]) Remove(key K) bool
- type AsyncSlotHandledeprecated
- type AsyncSlotMapdeprecated
- type AsyncSlotStatedeprecated
- type AsyncSource
- type AsyncSourceMap
- type AsyncTeardownScope
- type AsyncTopicCell
- func (t *AsyncTopicCell[T]) Advance(id string, count int) int
- func (t *AsyncTopicCell[T]) BaseOffset() int
- func (t *AsyncTopicCell[T]) Disconnect(id string)
- func (t *AsyncTopicCell[T]) Elements() []T
- func (t *AsyncTopicCell[T]) GC() int
- func (t *AsyncTopicCell[T]) Publish(value T) int
- func (t *AsyncTopicCell[T]) Read(cc *AsyncComputeContext, id string) (T, bool)
- func (t *AsyncTopicCell[T]) ReadStream(cc *AsyncComputeContext, id string) ([]T, bool)
- func (t *AsyncTopicCell[T]) ReaderHandle(id string) *AsyncComputed[TopicRead[T]]
- func (t *AsyncTopicCell[T]) Reconnect(id string)
- func (t *AsyncTopicCell[T]) Restart()
- func (t *AsyncTopicCell[T]) Snapshot() TopicSnapshot[T]
- func (t *AsyncTopicCell[T]) Subscribe(id string, durability TopicDurability) TopicSubscribeOutcome
- func (t *AsyncTopicCell[T]) Subscription(id string) (TopicSubscriptionSnapshot, bool)
- func (t *AsyncTopicCell[T]) TailOffset() int
- type AsyncWorkQueueCell
- func (q *AsyncWorkQueueCell[T]) Ack(worker string, deliveryID uint64) bool
- func (q *AsyncWorkQueueCell[T]) Claim(worker string, now int64) (WorkQueueDelivery[T], bool)
- func (q *AsyncWorkQueueCell[T]) DeadLetterItems() []WorkQueueDeadLetter[T]
- func (q *AsyncWorkQueueCell[T]) DeadLetterLen(cc *AsyncComputeContext) int
- func (q *AsyncWorkQueueCell[T]) InFlightDeliveries() []WorkQueueDelivery[T]
- func (q *AsyncWorkQueueCell[T]) InFlightLen(cc *AsyncComputeContext) int
- func (q *AsyncWorkQueueCell[T]) IsEmpty(cc *AsyncComputeContext) bool
- func (q *AsyncWorkQueueCell[T]) Nack(worker string, deliveryID uint64) bool
- func (q *AsyncWorkQueueCell[T]) PendingItems() []WorkQueueItem[T]
- func (q *AsyncWorkQueueCell[T]) PendingLen(cc *AsyncComputeContext) int
- func (q *AsyncWorkQueueCell[T]) Push(value T) uint64
- func (q *AsyncWorkQueueCell[T]) ReaderHandles() AsyncWorkQueueReaderHandles
- func (q *AsyncWorkQueueCell[T]) ReapExpired(now int64) int
- type AsyncWorkQueueReaderHandles
- type AwarenessCell
- type BackpressurePolicy
- type BarrierCell
- type BarrierCore
- type BatchFlush
- type BatchWrite
- type BenchmarkResult
- type BindingCapabilities
- type BlobBackend
- type BlobBackendKind
- type BlobRouter
- type Block
- type BlockKey
- type BoundDim
- type BoundedStorage
- type BreakerState
- type BulkheadCell
- type BulkheadCore
- type CallState
- type CallStateKind
- type CapabilityCheck
- type CapabilityHandshake
- func (h CapabilityHandshake) CheckCompatible(other CapabilityHandshake, requiredFeatures ...string) CapabilityCheck
- func (h CapabilityHandshake) EncodeJSON() ([]byte, error)
- func (h CapabilityHandshake) HasFeature(feature string) bool
- func (h CapabilityHandshake) IsCompatibleWith(other CapabilityHandshake) bool
- func (h CapabilityHandshake) MarshalJSON() ([]byte, error)
- func (h CapabilityHandshake) String() string
- func (h CapabilityHandshake) ToWire() any
- func (h *CapabilityHandshake) UnmarshalJSON(b []byte) error
- func (h CapabilityHandshake) WithCodec(codec string) CapabilityHandshake
- func (h CapabilityHandshake) WithFeatures(features []string) CapabilityHandshake
- func (h CapabilityHandshake) WithFragmentation(supported bool) CapabilityHandshake
- func (h CapabilityHandshake) WithMaxFrameSize(maxFrameSize int64) CapabilityHandshake
- func (h CapabilityHandshake) WithOrderedReliable(orderedReliable bool) CapabilityHandshake
- type CausalReceipt
- func AcceptedReceipt(receiptId, causationId, observer string, generation int64) CausalReceipt
- func AppliedReceipt(receiptId, causationId, observer string, generation int64) CausalReceipt
- func CausalReceiptFromWire(data []byte) (CausalReceipt, error)
- func NewCausalReceipt(receiptId, causationId, observer string, generation int64, ...) CausalReceipt
- func ObservedReceipt(receiptId, causationId, observer string, generation int64) CausalReceipt
- func RejectedReceipt(receiptId, causationId, observer string, generation int64) CausalReceipt
- type CausalReceipts
- type CellCrdt
- type CellMapdeprecated
- type CellTreedeprecated
- type ChartDef
- type CircuitBreakerCell
- type CircuitBreakerCore
- type ClientAnswer
- type ClientConn
- type ClientIce
- type ClientJoin
- type ClientLeave
- type ClientMessage
- type ClientOffer
- type ClientRelay
- type Clock
- type CommandApplyStatus
- type CommandApplyStatusKind
- type CommandCancel
- type CommandEvent
- type CommandEventKind
- type CommandEvents
- type CommandMessage
- func CommandMessageFromWire(data []byte) (CommandMessage, error)
- func NewCommandMessageCancel(c CommandCancel) CommandMessage
- func NewCommandMessageEvents(e CommandEvents) CommandMessage
- func NewCommandMessageProjection(p CommandProjectionImage) CommandMessage
- func NewCommandMessageSubmit(s CommandSubmit) CommandMessage
- type CommandMessageTag
- type CommandPolicy
- type CommandProjection
- func (p *CommandProjection) ApplyMessage(message CommandMessage) CommandApplyStatus
- func (p *CommandProjection) ApplyProjection(img CommandProjectionImage) CommandApplyStatus
- func (p *CommandProjection) Cancel(c CommandCancel) CommandApplyStatus
- func (p *CommandProjection) Entry(commandId string) (CommandProjectionEntry, bool)
- func (p *CommandProjection) Event(e CommandEvent) CommandApplyStatus
- func (p *CommandProjection) Generation() int64
- func (p *CommandProjection) HasConflict(commandId string) bool
- func (p *CommandProjection) ObserveReceipt(r CausalReceipt) CommandApplyStatus
- func (p *CommandProjection) Submit(s CommandSubmit) CommandApplyStatus
- func (p *CommandProjection) TerminalFor(commandId string) (CommandProjectionEntry, bool)
- func (p *CommandProjection) ToImage() CommandProjectionImage
- type CommandProjectionEntry
- type CommandProjectionImage
- type CommandRpcClient
- func (c *CommandRpcClient) Cancel(cancel CommandCancel)
- func (c *CommandRpcClient) IngestCommand(message CommandMessage) CommandApplyStatus
- func (c *CommandRpcClient) IngestReceipt(receipt CausalReceipt) CommandApplyStatus
- func (c *CommandRpcClient) PollCall(commandId string) CallState
- func (c *CommandRpcClient) Submit(s CommandSubmit) string
- type CommandStatus
- type CommandStatusDuplicate
- type CommandStatusRecorded
- type CommandStatusStaleGeneration
- type CommandStatusTerminalConflict
- type CommandStatusUnknown
- type CommandSubmit
- type CommandTransport
- type CommandTransportFunc
- type Compute
- type ComputeOps
- type Computed
- func NewComputed[T comparable](ctx *Context, compute func(c *Compute) T) *Computed[T]
- func NewComputedRippleWhen[T any](ctx *Context, compute func(c *Compute) T, changed func(old, next T) bool) *Computed[T]
- func NewNamedComputedRippleWhen[T any](ctx *Context, name string, compute func(c *Compute) T, ...) *Computed[T]
- func NewNamedSlot[T any](ctx *Context, name string, compute func(c *Compute) T) *Computed[T]
- func NewSlot[T any](ctx *Context, compute func(c *Compute) T) *Computed[T]
- type ComputedMap
- type Configuration
- type Context
- func (c *Context) Batch(fn func())
- func (c *Context) Clear()
- func (c *Context) DependencyCount(n GraphNode) int
- func (c *Context) DependentCount(n GraphNode) int
- func (c *Context) IsBatching() bool
- func (c *Context) IsDisposed(n GraphNode) bool
- func (c *Context) Scope() *TeardownScope
- func (c *Context) Size() int
- func (c *Context) Untracked() *Context
- func (c *Context) WithScope(fn func(s *TeardownScope))
- type ConvergedEntry
- type CrdtOp
- type CrdtPlane
- func (p *CrdtPlane) Clock() *Hlc
- func (p *CrdtPlane) Frontier() *StampFrontier
- func (p *CrdtPlane) IsCollectable(stamp HlcStamp) bool
- func (p *CrdtPlane) Membership() []PeerId
- func (p *CrdtPlane) ObserveRemote(remote HlcStamp, nowMicros int64) HlcStamp
- func (p *CrdtPlane) Self() PeerId
- func (p *CrdtPlane) StabilityWatermark() (HlcStamp, bool)
- func (p *CrdtPlane) Tick(nowMicros int64) HlcStamp
- type CrdtPlaneRuntime
- func (r *CrdtPlaneRuntime) Close()
- func (r *CrdtPlaneRuntime) Converged() []ConvergedEntry
- func (r *CrdtPlaneRuntime) ConvergedStream() <-chan ConvergedEntry
- func (r *CrdtPlaneRuntime) FamilyKeys(namespace string) []NodeKey
- func (r *CrdtPlaneRuntime) FamilySetLww(namespace, keySuffix string, state IpcValue, nowMicros int64) (CrdtOp, bool)
- func (r *CrdtPlaneRuntime) FamilyValueLww(namespace, keySuffix string) (IpcValue, bool)
- func (r *CrdtPlaneRuntime) FrontierEntries() []StampFrontierEntry
- func (r *CrdtPlaneRuntime) Ingest(sync CrdtSync) int
- func (r *CrdtPlaneRuntime) IngestOps(ops []CrdtOp) int
- func (r *CrdtPlaneRuntime) IsEmpty() bool
- func (r *CrdtPlaneRuntime) Membership() []PeerId
- func (r *CrdtPlaneRuntime) MembershipEpoch() uint64
- func (r *CrdtPlaneRuntime) Nodes() []NodeId
- func (r *CrdtPlaneRuntime) Ops() []CrdtOp
- func (r *CrdtPlaneRuntime) Peer() PeerId
- func (r *CrdtPlaneRuntime) RegisterFamilyLww(namespace string)
- func (r *CrdtPlaneRuntime) Size() int
- func (r *CrdtPlaneRuntime) Value(node NodeId) (IpcValue, bool)
- func (r *CrdtPlaneRuntime) WinningOp(node NodeId) (CrdtOp, bool)
- type CrdtSync
- type CrdtTree
- type CronCell
- type CronCore
- type DeadlineCell
- type DeadlineCore
- type Deadlined
- type DebounceCell
- type DebounceCore
- type DedupePolicy
- type Delta
- func (d Delta) ApplyStatus(lastEpoch Epoch) DeltaApplyStatus
- func (d Delta) FilterReadable(permissions *PeerPermissions, peer PeerId) Delta
- func (d Delta) IsNextAfter(lastEpoch Epoch) bool
- func (d Delta) MarshalJSON() ([]byte, error)
- func (d Delta) Span() Epoch
- func (d *Delta) UnmarshalJSON(b []byte) error
- type DeltaApplyStatus
- type DeltaApplyStatusApply
- type DeltaApplyStatusResyncRequired
- type DeltaOp
- type DeltaOpCellSet
- type DeltaOpEdgeAdd
- type DeltaOpEdgeRemove
- type DeltaOpInvalidate
- type DeltaOpNodeAdd
- type DeltaOpNodeRemove
- type DeltaOpSlotValue
- type DiffOp
- type DiffOpInsert
- type DiffOpMove
- type DiffOpRemove
- type DiffOpUpdate
- type DiscoveryCell
- func (d *DiscoveryCell[P]) Deregister(service string)
- func (d *DiscoveryCell[P]) Discovery() map[string]string
- func (d *DiscoveryCell[P]) DiscoveryCell() *Source[uint64]
- func (d *DiscoveryCell[P]) Evict(peer P)
- func (d *DiscoveryCell[P]) Register(service string, endpoint string, peer P)
- func (d *DiscoveryCell[P]) Resolve(service string) (string, bool)
- type DiscoveryCore
- type DisposedError
- type DriverError
- type DurableOutbox
- type DurableStoreOutbox
- func (o *DurableStoreOutbox[S]) AckThrough(epoch Epoch)
- func (o *DurableStoreOutbox[S]) AckedThrough() Epoch
- func (o *DurableStoreOutbox[S]) Append(epoch Epoch, msg IpcMessage)
- func (o *DurableStoreOutbox[S]) Err() error
- func (o *DurableStoreOutbox[S]) ReplayFrom(cursor Epoch) []OutboxEntry
- func (o *DurableStoreOutbox[S]) RetainedEpochs() []Epoch
- func (o *DurableStoreOutbox[S]) Store() S
- type EdgeSnapshot
- type Effect
- type EffectRun
- type EntryKind
- type EphemeralCell
- type EphemeralCore
- type EphemeralMapCore
- type Epoch
- type Equals
- type ExpiryPolicy
- type FfiCapability
- type FileOutbox
- type FileOutboxStore
- func (s *FileOutboxStore) DeleteThrough(epoch Epoch)
- func (s *FileOutboxStore) Err() error
- func (s *FileOutboxStore) LoadCursor() Epoch
- func (s *FileOutboxStore) Put(epoch Epoch, frame []byte)
- func (s *FileOutboxStore) SaveCursor(epoch Epoch)
- func (s *FileOutboxStore) ScanAfter(cursor Epoch) []StoredOutboxEntry
- type FoldFn
- type FramedTransport
- type GraphNode
- type Health
- type HealthCell
- type HealthCore
- type Hlc
- type HlcStamp
- type InMemoryOutbox
- type InMemoryStore
- type InProcTransport
- type InProcessBackend
- func (b *InProcessBackend) AdvanceEpoch()
- func (b *InProcessBackend) Arena() *ShmBlobArena
- func (b *InProcessBackend) Epoch() int64
- func (b *InProcessBackend) Kind() BlobBackendKind
- func (b *InProcessBackend) ReadView(descriptor ShmBlobRef) ([]byte, bool)
- func (b *InProcessBackend) Write(bytes []byte) (ShmBlobRef, error)
- type Inbox
- type IngressOutcome
- type InsertAt
- type IntervalCell
- type IntervalCore
- type IpcMessage
- type IpcMessageCrdtSync
- type IpcMessageDelta
- type IpcMessageOutboxAck
- type IpcMessageResyncRequest
- type IpcMessageSnapshot
- type IpcSink
- type IpcSource
- type IpcValue
- type IpcValueInline
- type IpcValueSharedBlob
- type KeyValue
- type KeyedRelay
- type LazilyFfiBytes
- type LazilyFfiChannel
- func (c *LazilyFfiChannel) IsEmpty() bool
- func (c *LazilyFfiChannel) Len() int
- func (c *LazilyFfiChannel) Recv() (IpcMessage, LazilyFfiStatus)
- func (c *LazilyFfiChannel) RecvJSONFrame() (LazilyFfiBytes, LazilyFfiStatus)
- func (c *LazilyFfiChannel) Send(message IpcMessage) LazilyFfiStatus
- func (c *LazilyFfiChannel) SendJSONFrame(frame LazilyFfiBytes) (status LazilyFfiStatus)
- type LazilyFfiClassification
- type LazilyFfiCloneResult
- type LazilyFfiMessageKind
- type LazilyFfiStatus
- type Lcg
- type LeaderCell
- func (c *LeaderCell[P]) Campaign(now, ttl uint64) LeaderRole
- func (c *LeaderCell[P]) Contend(peer P, now, ttl uint64) LeaderRole
- func (c *LeaderCell[P]) CurrentLeader(now uint64) (P, bool)
- func (c *LeaderCell[P]) CurrentLeaderCell() *Source[Opt[P]]
- func (c *LeaderCell[P]) Role(now uint64) LeaderRole
- func (c *LeaderCell[P]) Tick(now uint64) LeaderRole
- type LeaderRole
- type LeafKind
- type LeaseCell
- func (c *LeaseCell[P]) Acquire(peer P, now, ttl uint64) Opt[uint64]
- func (c *LeaseCell[P]) Fence() uint64
- func (c *LeaseCell[P]) Holder(now uint64) (P, bool)
- func (c *LeaseCell[P]) HolderCell() *Source[Opt[P]]
- func (c *LeaseCell[P]) IsHeld(now uint64) bool
- func (c *LeaseCell[P]) Release(peer P, now uint64)
- func (c *LeaseCell[P]) Renew(peer P, now, ttl uint64) bool
- func (c *LeaseCell[P]) Tick(now uint64) bool
- type LeaseCore
- func (c *LeaseCore[P]) Acquire(peer P, now, ttl uint64) (uint64, bool)
- func (c *LeaseCore[P]) Fence() uint64
- func (c *LeaseCore[P]) Holder(now uint64) (P, bool)
- func (c *LeaseCore[P]) IsHeld(now uint64) bool
- func (c *LeaseCore[P]) Release(peer P)
- func (c *LeaseCore[P]) Renew(peer P, now, ttl uint64) bool
- func (c *LeaseCore[P]) Tick(now uint64) bool
- type LockCell
- func (c *LockCell[P]) Acquire(peer P, now, ttl uint64) Opt[uint64]
- func (c *LockCell[P]) Fence() uint64
- func (c *LockCell[P]) IsLocked(now uint64) bool
- func (c *LockCell[P]) IsLockedCell() *Source[bool]
- func (c *LockCell[P]) Release(peer P, now uint64)
- func (c *LockCell[P]) Tick(now uint64) bool
- func (c *LockCell[P]) Validate(fence uint64) bool
- type LosslessTreeCrdt
- func (t *LosslessTreeCrdt) ApplyUpdate(update TreeUpdate)
- func (t *LosslessTreeCrdt) Children(parent OpId) []OpId
- func (t *LosslessTreeCrdt) CreateNode(parent OpId, after *OpId, seed TreeNodeSeed) OpId
- func (t *LosslessTreeCrdt) Diff(their *TreeVersionFrontier) TreeUpdate
- func (t *LosslessTreeCrdt) EditLeaf(node OpId, atByte, deleteBytes int, insert string)
- func (t *LosslessTreeCrdt) ElementKind(node OpId) string
- func (t *LosslessTreeCrdt) Fork(peer PeerId) *LosslessTreeCrdt
- func (t *LosslessTreeCrdt) Frontier() *TreeVersionFrontier
- func (t *LosslessTreeCrdt) LeafKind(node OpId) LeafKind
- func (t *LosslessTreeCrdt) LeafText(node OpId) string
- func (t *LosslessTreeCrdt) LiveNodeCount() int
- func (t *LosslessTreeCrdt) MergeAdjacentLeaves(left, right OpId)
- func (t *LosslessTreeCrdt) Render() string
- func (t *LosslessTreeCrdt) ReorderChild(node OpId, after *OpId)
- func (t *LosslessTreeCrdt) SplitLeaf(node OpId, atByte int) OpId
- func (t *LosslessTreeCrdt) TombstoneNode(node OpId)
- type LwwRegister
- type ManifestEntry
- type ManualClock
- type Match
- type MembershipCell
- func (c *MembershipCell[P]) Heartbeat(peer P, now uint64) []PeerChangeEvent[P]
- func (c *MembershipCell[P]) Join(peer P, now uint64) []PeerChangeEvent[P]
- func (c *MembershipCell[P]) Leave(peer P, now uint64) []PeerChangeEvent[P]
- func (c *MembershipCell[P]) PeerSet() []P
- func (c *MembershipCell[P]) State(peer P) (PeerState, bool)
- func (c *MembershipCell[P]) Tick(now uint64) []PeerChangeEvent[P]
- func (c *MembershipCell[P]) VersionCell() *Source[uint64]
- type MembershipConfig
- type MembershipCore
- func (m *MembershipCore[P]) AliveSet() []P
- func (m *MembershipCore[P]) Heartbeat(peer P, now uint64) []PeerChangeEvent[P]
- func (m *MembershipCore[P]) Join(peer P, now uint64) []PeerChangeEvent[P]
- func (m *MembershipCore[P]) Leave(peer P, _ uint64) []PeerChangeEvent[P]
- func (m *MembershipCore[P]) State(peer P) (PeerState, bool)
- func (m *MembershipCore[P]) Tick(now uint64) []PeerChangeEvent[P]
- type MergePolicy
- type MvRegister
- type NodeEntry
- type NodeId
- type NodeKey
- type NodeSnapshot
- type NodeState
- type NodeStateOpaque
- type NodeStatePayload
- type NodeStateSharedBlob
- type Number
- type OpId
- type OpKind
- type Opt
- type OptStr
- type OrSet
- type Outbox
- type OutboxAck
- type OutboxEntry
- type OutboxStore
- type Overflow
- type PeekableStorage
- type PeerChangeEvent
- type PeerChangeKind
- type PeerId
- type PeerPermissions
- func (p *PeerPermissions) Allow(peer PeerId, op RemoteOp) bool
- func (p *PeerPermissions) AllowMany(peer PeerId, kind OpKind, nodes []NodeId)
- func (p *PeerPermissions) CanRead(peer PeerId, node NodeId) bool
- func (p *PeerPermissions) Check(peer PeerId, op RemoteOp) error
- func (p *PeerPermissions) FilterReadable(peer PeerId, nodes []NodeId) []NodeId
- func (p *PeerPermissions) IsAllowed(peer PeerId, op RemoteOp) bool
- func (p *PeerPermissions) PeerCount() int
- func (p *PeerPermissions) Revoke(peer PeerId, op RemoteOp) bool
- func (p *PeerPermissions) RevokePeer(peer PeerId) bool
- type PeerState
- type PermissionDenied
- type PhiAccrual
- type Plane
- type PnCounter
- func (c *PnCounter) Copy() *PnCounter
- func (c *PnCounter) Decrement()
- func (c *PnCounter) DecrementBy(amount int64)
- func (c *PnCounter) Increment()
- func (c *PnCounter) IncrementBy(amount int64)
- func (c *PnCounter) Merge(other *PnCounter)
- func (c *PnCounter) Peer() PeerId
- func (c *PnCounter) ToWire() map[string]any
- func (c *PnCounter) Value() int64
- type Position
- type PresenceCell
- type PriorityStorage
- type ProbabilisticSampleCell
- type ProbabilisticSampleCore
- type Progress
- type QueueCell
- func (q *QueueCell[T, S]) Capacity() (int, bool)
- func (q *QueueCell[T, S]) Close()
- func (q *QueueCell[T, S]) Head() (T, bool)
- func (q *QueueCell[T, S]) IsClosed() bool
- func (q *QueueCell[T, S]) IsClosedUntracked() bool
- func (q *QueueCell[T, S]) IsEmpty() bool
- func (q *QueueCell[T, S]) IsFull() bool
- func (q *QueueCell[T, S]) Len() int
- func (q *QueueCell[T, S]) LenUntracked() int
- func (q *QueueCell[T, S]) ReaderHandles() QueueReaderHandles[T]
- func (q *QueueCell[T, S]) Storage() S
- func (q *QueueCell[T, S]) TryPop() (T, QueuePopError)
- func (q *QueueCell[T, S]) TryPush(value T) QueuePushError
- type QueuePopError
- type QueuePushError
- type QueueReaderHandles
- type QueueStorage
- type RatePolicy
- type ReactiveMap
- func (m *ReactiveMap[K, V, H]) ContainsKey(c ComputeOps, key K) bool
- func (m *ReactiveMap[K, V, H]) EntryKind() EntryKind
- func (m *ReactiveMap[K, V, H]) GetOrInsertWith(c ComputeOps, key K, factory func(K) V) V
- func (m *ReactiveMap[K, V, H]) Handle(key K) (H, bool)
- func (m *ReactiveMap[K, V, H]) IsEmpty(c ComputeOps) bool
- func (m *ReactiveMap[K, V, H]) IsPresent(key K) bool
- func (m *ReactiveMap[K, V, H]) Keys(c ComputeOps) []K
- func (m *ReactiveMap[K, V, H]) Len(c ComputeOps) int
- func (m *ReactiveMap[K, V, H]) LenUntracked() int
- func (m *ReactiveMap[K, V, H]) MoveAfter(key, anchor K) bool
- func (m *ReactiveMap[K, V, H]) MoveBefore(key, anchor K) bool
- func (m *ReactiveMap[K, V, H]) MoveTo(key K, index int) bool
- func (m *ReactiveMap[K, V, H]) Observe(c ComputeOps, key K) (V, bool)
- func (m *ReactiveMap[K, V, H]) Position(key K) (int, bool)
- func (m *ReactiveMap[K, V, H]) PresentCount() int
- func (m *ReactiveMap[K, V, H]) PresentKeys() []K
- func (m *ReactiveMap[K, V, H]) Remove(key K) bool
- type ReadinessCell
- type ReadinessCore
- type ReceiptApplyStatus
- type ReceiptDuplicate
- type ReceiptOutcome
- type ReceiptProjection
- func (p *ReceiptProjection) ContainsReceipt(receiptId string) bool
- func (p *ReceiptProjection) CurrentGeneration() int64
- func (p *ReceiptProjection) LatestFor(causationId string) (CausalReceipt, bool)
- func (p *ReceiptProjection) Observe(currentGeneration *int64, receipt CausalReceipt) ReceiptApplyStatus
- func (p *ReceiptProjection) ReceiptCount() int
- func (p *ReceiptProjection) StaleReceiptIds() []string
- func (p *ReceiptProjection) TerminalFor(causationId string) (CausalReceipt, bool)
- type ReceiptRecorded
- type ReceiptStaleGeneration
- type ReceiptTerminalConflict
- type RelayCell
- func (r *RelayCell[T]) Depth() uint64
- func (r *RelayCell[T]) DepthSlot() *Computed[uint64]
- func (r *RelayCell[T]) Drain() (T, bool)
- func (r *RelayCell[T]) Ingress(op T) IngressOutcome
- func (r *RelayCell[T]) IsEmpty() bool
- func (r *RelayCell[T]) IsEmptySlot() *Computed[bool]
- func (r *RelayCell[T]) IsFull() bool
- func (r *RelayCell[T]) IsFullSlot() *Computed[bool]
- func (r *RelayCell[T]) OverflowIsLegal() bool
- func (r *RelayCell[T]) Peek() (T, bool)
- type RelayConfigError
- type RemoteOp
- type ResyncAction
- type ResyncCoordinator
- func (c *ResyncCoordinator) Ack() IpcMessage
- func (c *ResyncCoordinator) Ingest(msg IpcMessage) (ResyncAction, Epoch)
- func (c *ResyncCoordinator) IngestDelta(delta Delta) (ResyncAction, Epoch)
- func (c *ResyncCoordinator) IngestSnapshot(snapshotEpoch Epoch) (ResyncAction, Epoch)
- func (c *ResyncCoordinator) IsResyncing() bool
- func (c *ResyncCoordinator) LastEpoch() Epoch
- type ResyncRequest
- type RetryPolicyCell
- type RetryPolicyCore
- type RevisionBarrier
- func (b *RevisionBarrier) Advance(revision uint64, predicate bool) RevisionBarrierObservation
- func (b *RevisionBarrier) Dispose() RevisionBarrierObservation
- func (b *RevisionBarrier) Observe(now uint64, predicate bool, cancellation func() TimeoutCancellation) RevisionBarrierObservation
- func (b *RevisionBarrier) Receipt(string) RevisionBarrierObservation
- func (b *RevisionBarrier) RegisterRecheck(now, observedRevision uint64, predicate bool) RevisionBarrierObservation
- type RevisionBarrierObservation
- type RoutedFrame
- type SampleCell
- type SampleCore
- type SampleKind
- type SampleMode
- type SampleRng
- type SemTree
- func (t *SemTree[V, D]) IsCached(id string) bool
- func (t *SemTree[V, D]) NodeHandle(id string) (*Computed[D], bool)
- func (t *SemTree[V, D]) NodeValue(id string) (D, bool)
- func (t *SemTree[V, D]) RemoveChild(parentID, childID string) error
- func (t *SemTree[V, D]) RootHandle() *Computed[D]
- func (t *SemTree[V, D]) SetValue(id string, value V) error
- func (t *SemTree[V, D]) Value() D
- type SemaphoreCell
- type SemaphoreCore
- type SeqCrdt
- func (s *SeqCrdt[Id, V]) Clone() *SeqCrdt[Id, V]
- func (s *SeqCrdt[Id, V]) Contains(id Id) bool
- func (s *SeqCrdt[Id, V]) EntryCount() int
- func (s *SeqCrdt[Id, V]) Fork(peer PeerId) *SeqCrdt[Id, V]
- func (s *SeqCrdt[Id, V]) Gc(watermark HlcStamp) int
- func (s *SeqCrdt[Id, V]) GcWith(isStable func(stamp HlcStamp) bool) int
- func (s *SeqCrdt[Id, V]) Get(id Id) (V, bool)
- func (s *SeqCrdt[Id, V]) InsertBack(id Id, value V, nowMicros int64)
- func (s *SeqCrdt[Id, V]) InsertBetween(id Id, value V, left, right *Id, nowMicros int64)
- func (s *SeqCrdt[Id, V]) InsertFront(id Id, value V, nowMicros int64)
- func (s *SeqCrdt[Id, V]) Len() int
- func (s *SeqCrdt[Id, V]) Merge(other *SeqCrdt[Id, V], nowMicros int64) bool
- func (s *SeqCrdt[Id, V]) MoveAfter(id, anchor Id, nowMicros int64) bool
- func (s *SeqCrdt[Id, V]) MoveBefore(id, anchor Id, nowMicros int64) bool
- func (s *SeqCrdt[Id, V]) MoveBetween(id Id, left, right *Id, nowMicros int64) bool
- func (s *SeqCrdt[Id, V]) Order() []Id
- func (s *SeqCrdt[Id, V]) Peer() PeerId
- func (s *SeqCrdt[Id, V]) Remove(id Id, nowMicros int64) bool
- func (s *SeqCrdt[Id, V]) SetValue(id Id, value V, nowMicros int64) bool
- func (s *SeqCrdt[Id, V]) TombstoneCount() int
- func (s *SeqCrdt[Id, V]) Values() []SeqValue[Id, V]
- type SeqValue
- type ServerAnswer
- type ServerError
- type ServerIce
- type ServerMessage
- type ServerOffer
- type ServerPeerJoined
- type ServerPeerLeft
- type ServerRelay
- type ServerWelcome
- type ServiceRegistry
- type ServiceRegistryCore
- type SessionCore
- type SessionWindow
- type ShmBackend
- func (b *ShmBackend) AdvanceEpoch()
- func (b *ShmBackend) Capacity() int
- func (b *ShmBackend) Close() error
- func (b *ShmBackend) Epoch() int64
- func (b *ShmBackend) Kind() BlobBackendKind
- func (b *ShmBackend) ReadView(descriptor ShmBlobRef) ([]byte, bool)
- func (b *ShmBackend) Write(bytes []byte) (ShmBlobRef, error)
- type ShmBlobArena
- func (a *ShmBlobArena) AdvanceEpoch()
- func (a *ShmBlobArena) Epoch() int64
- func (a *ShmBlobArena) Free(ref ShmBlobRef) bool
- func (a *ShmBlobArena) IsEmpty() bool
- func (a *ShmBlobArena) Length() int
- func (a *ShmBlobArena) Read(ref ShmBlobRef) []byte
- func (a *ShmBlobArena) ReadView(ref ShmBlobRef) ([]byte, bool)
- func (a *ShmBlobArena) Retain(ref ShmBlobRef) bool
- func (a *ShmBlobArena) Update(ref ShmBlobRef, bytes []byte) *ShmBlobRef
- func (a *ShmBlobArena) Write(bytes []byte) ShmBlobRef
- type ShmBlobRef
- type SignalingErrorCode
- type SignalingMode
- type SignalingRoom
- func (r *SignalingRoom) AllowJoin(peer PeerId) error
- func (r *SignalingRoom) AllowSignal(from, target PeerId) error
- func (r *SignalingRoom) Close()
- func (r *SignalingRoom) Connect(connID any) (*ClientConn, error)
- func (r *SignalingRoom) Disconnect(connID any) error
- func (r *SignalingRoom) Roster() []PeerId
- func (r *SignalingRoom) Size() int
- type SlidingCore
- type SlidingWindow
- type SlotMapdeprecated
- type Snapshot
- type SnapshotProvider
- type Source
- type SourceMap
- func (m *SourceMap[K, V]) Cell(key K) *Source[V]
- func (m *SourceMap[K, V]) Entry(key K, defaultValue V) *Source[V]
- func (m *SourceMap[K, V]) EntryWith(key K, defaultValue func() V) *Source[V]
- func (m *SourceMap[K, V]) Get(key K) (V, bool)
- func (m *SourceMap[K, V]) Insert(key K, value V, at InsertAt, anchor K) bool
- func (m *SourceMap[K, V]) Read(key K) (V, bool)
- func (m *SourceMap[K, V]) Reconcile(targetOrder []K, targetValues map[K]V)
- func (m *SourceMap[K, V]) Set(key K, value V)
- type SourceTree
- func (t *SourceTree[K, V]) Child(id K) *SourceTree[K, V]
- func (t *SourceTree[K, V]) ChildCount(c ComputeOps) int
- func (t *SourceTree[K, V]) ChildIDs(c ComputeOps) []K
- func (t *SourceTree[K, V]) Get() V
- func (t *SourceTree[K, V]) HasChild(c ComputeOps, id K) bool
- func (t *SourceTree[K, V]) InsertChild(id K, value V) *SourceTree[K, V]
- func (t *SourceTree[K, V]) MoveChildAfter(id, anchor K) bool
- func (t *SourceTree[K, V]) MoveChildBefore(id, anchor K) bool
- func (t *SourceTree[K, V]) MoveChildTo(id K, index int) bool
- func (t *SourceTree[K, V]) NodeID() K
- func (t *SourceTree[K, V]) RemoveChild(id K) bool
- func (t *SourceTree[K, V]) Set(next V)
- type SpillMode
- type SpillPage
- type SpillStore
- func (s *SpillStore[T]) AckThrough(id uint64)
- func (s *SpillStore[T]) FoldPages(s0 T) T
- func (s *SpillStore[T]) Manifest() []ManifestEntry
- func (s *SpillStore[T]) PageCount() int
- func (s *SpillStore[T]) PendingPages() []SpillPage[T]
- func (s *SpillStore[T]) Reclaim()
- func (s *SpillStore[T]) Reconstruct(s0 T, hot T, hasHot bool) T
- func (s *SpillStore[T]) ReplayUnacked(downstream T) T
- func (s *SpillStore[T]) Spill(window T, bytes uint64)
- type StaleComputeError
- type StampFrontier
- func (f *StampFrontier) Get(peer PeerId) (HlcStamp, bool)
- func (f *StampFrontier) Knows(peer PeerId) bool
- func (f *StampFrontier) Merge(other *StampFrontier) bool
- func (f *StampFrontier) Observe(peer PeerId, stamp HlcStamp) bool
- func (f *StampFrontier) Peers() []PeerId
- func (f *StampFrontier) ToWire() []StampFrontierEntry
- func (f *StampFrontier) Watermark(membership []PeerId) (HlcStamp, bool)
- type StampFrontierEntry
- type StateChart
- func (sc *StateChart) ActiveLeaves() []string
- func (sc *StateChart) Configuration() Configuration
- func (sc *StateChart) Ctx() *Context
- func (sc *StateChart) Def() *ChartDef
- func (sc *StateChart) LastActions() []string
- func (sc *StateChart) Matches(id string) bool
- func (sc *StateChart) Send(event string, guards map[string]bool) bool
- func (sc *StateChart) String() string
- type StateMachine
- type StateProjectionMirror
- func (m *StateProjectionMirror) BaseEpoch() Epoch
- func (m *StateProjectionMirror) DirtyNodes() []NodeId
- func (m *StateProjectionMirror) Flush() Delta
- func (m *StateProjectionMirror) IsDirty(node NodeId) bool
- func (m *StateProjectionMirror) MarkDirty(node NodeId)
- func (m *StateProjectionMirror) Resolve(node NodeId, value IpcValue)
- type StoredOutboxEntry
- type SyncDriver
- func (d *SyncDriver) Enqueue(epoch Epoch, msg IpcMessage)
- func (d *SyncDriver) IsStalled() bool
- func (d *SyncDriver) LastEpoch() Epoch
- func (d *SyncDriver) OnReconnect()
- func (d *SyncDriver) Outbox() DurableOutbox
- func (d *SyncDriver) StalledFor(now int64) int64
- func (d *SyncDriver) Tick() (Progress, error)
- type TeardownScope
- type TextCrdt
- func (t *TextCrdt) ApplyDelta(ops []TextOp) bool
- func (t *TextCrdt) Clock() OpId
- func (t *TextCrdt) Clone() *TextCrdt
- func (t *TextCrdt) Delete(index int)
- func (t *TextCrdt) DeltaSince(theirVv map[PeerId]int64) []TextOp
- func (t *TextCrdt) Fork(peer PeerId) *TextCrdt
- func (t *TextCrdt) GcWith(isStable func(deleteOpId OpId) bool) int
- func (t *TextCrdt) Insert(index int, ch string)
- func (t *TextCrdt) InsertStr(index int, s string)
- func (t *TextCrdt) IsEmpty() bool
- func (t *TextCrdt) Len() int
- func (t *TextCrdt) Merge(other *TextCrdt) bool
- func (t *TextCrdt) MergeFrom(other CrdtTree[map[PeerId]int64, []TextOp, string]) bool
- func (t *TextCrdt) Peer() PeerId
- func (t *TextCrdt) Text() string
- func (t *TextCrdt) TombstoneCount() int
- func (t *TextCrdt) Value() string
- func (t *TextCrdt) VersionVector() map[PeerId]int64
- type TextOp
- type ThreadSafeCellMapdeprecated
- type ThreadSafeComputedMap
- type ThreadSafeContext
- type ThreadSafeQueueCell
- func NewBoundedThreadSafeQueueCell[T comparable](ts *ThreadSafeContext, capacity int) *ThreadSafeQueueCell[T, *VecDequeStorage[T]]
- func NewThreadSafeQueueCell[T comparable](ts *ThreadSafeContext) *ThreadSafeQueueCell[T, *VecDequeStorage[T]]
- func NewThreadSafeQueueCellWithStorage[T comparable, S QueueStorage[T]](ts *ThreadSafeContext, storage S) *ThreadSafeQueueCell[T, S]
- func (q *ThreadSafeQueueCell[T, S]) Capacity() (int, bool)
- func (q *ThreadSafeQueueCell[T, S]) Close()
- func (q *ThreadSafeQueueCell[T, S]) Elements() []T
- func (q *ThreadSafeQueueCell[T, S]) Head() (T, bool)
- func (q *ThreadSafeQueueCell[T, S]) IsClosed() bool
- func (q *ThreadSafeQueueCell[T, S]) IsEmpty() bool
- func (q *ThreadSafeQueueCell[T, S]) IsFull() bool
- func (q *ThreadSafeQueueCell[T, S]) Len() int
- func (q *ThreadSafeQueueCell[T, S]) ReaderHandles() QueueReaderHandles[T]
- func (q *ThreadSafeQueueCell[T, S]) TryPop() (T, QueuePopError)
- func (q *ThreadSafeQueueCell[T, S]) TryPush(value T) QueuePushError
- type ThreadSafeReactiveMap
- func (m *ThreadSafeReactiveMap[K, V, H]) ContainsKey(c ComputeOps, key K) bool
- func (m *ThreadSafeReactiveMap[K, V, H]) EntryKind() EntryKind
- func (m *ThreadSafeReactiveMap[K, V, H]) GetOrInsertWith(c ComputeOps, key K, factory func(K) V) V
- func (m *ThreadSafeReactiveMap[K, V, H]) Handle(key K) (H, bool)
- func (m *ThreadSafeReactiveMap[K, V, H]) IsEmpty(c ComputeOps) bool
- func (m *ThreadSafeReactiveMap[K, V, H]) IsPresent(key K) bool
- func (m *ThreadSafeReactiveMap[K, V, H]) Keys(c ComputeOps) []K
- func (m *ThreadSafeReactiveMap[K, V, H]) Len(c ComputeOps) int
- func (m *ThreadSafeReactiveMap[K, V, H]) LenUntracked() int
- func (m *ThreadSafeReactiveMap[K, V, H]) MoveAfter(key, anchor K) bool
- func (m *ThreadSafeReactiveMap[K, V, H]) MoveBefore(key, anchor K) bool
- func (m *ThreadSafeReactiveMap[K, V, H]) MoveTo(key K, index int) bool
- func (m *ThreadSafeReactiveMap[K, V, H]) Observe(c ComputeOps, key K) (V, bool)
- func (m *ThreadSafeReactiveMap[K, V, H]) Position(key K) (int, bool)
- func (m *ThreadSafeReactiveMap[K, V, H]) PresentCount() int
- func (m *ThreadSafeReactiveMap[K, V, H]) PresentKeys() []K
- func (m *ThreadSafeReactiveMap[K, V, H]) Remove(key K) bool
- type ThreadSafeSlotMapdeprecated
- type ThreadSafeSourceMap
- type ThreadSafeTopicCell
- func (t *ThreadSafeTopicCell[T]) Advance(id string, count int) int
- func (t *ThreadSafeTopicCell[T]) BaseOffset() int
- func (t *ThreadSafeTopicCell[T]) Disconnect(id string)
- func (t *ThreadSafeTopicCell[T]) Elements() []T
- func (t *ThreadSafeTopicCell[T]) GC() int
- func (t *ThreadSafeTopicCell[T]) Publish(value T) int
- func (t *ThreadSafeTopicCell[T]) Read(id string) (T, bool)
- func (t *ThreadSafeTopicCell[T]) ReadStream(id string) ([]T, bool)
- func (t *ThreadSafeTopicCell[T]) ReaderHandle(id string) *Computed[TopicRead[T]]
- func (t *ThreadSafeTopicCell[T]) Reconnect(id string)
- func (t *ThreadSafeTopicCell[T]) Restart()
- func (t *ThreadSafeTopicCell[T]) Snapshot() TopicSnapshot[T]
- func (t *ThreadSafeTopicCell[T]) Subscribe(id string, durability TopicDurability) TopicSubscribeOutcome
- func (t *ThreadSafeTopicCell[T]) Subscription(id string) (TopicSubscriptionSnapshot, bool)
- func (t *ThreadSafeTopicCell[T]) TailOffset() int
- type ThreadSafeWorkQueueCell
- func (q *ThreadSafeWorkQueueCell[T]) Ack(worker string, deliveryID uint64) bool
- func (q *ThreadSafeWorkQueueCell[T]) Claim(worker string, now int64) (WorkQueueDelivery[T], bool)
- func (q *ThreadSafeWorkQueueCell[T]) DeadLetterItems() []WorkQueueDeadLetter[T]
- func (q *ThreadSafeWorkQueueCell[T]) DeadLetterLen() int
- func (q *ThreadSafeWorkQueueCell[T]) InFlightDeliveries() []WorkQueueDelivery[T]
- func (q *ThreadSafeWorkQueueCell[T]) InFlightLen() int
- func (q *ThreadSafeWorkQueueCell[T]) IsEmpty() bool
- func (q *ThreadSafeWorkQueueCell[T]) Nack(worker string, deliveryID uint64) bool
- func (q *ThreadSafeWorkQueueCell[T]) PendingItems() []WorkQueueItem[T]
- func (q *ThreadSafeWorkQueueCell[T]) PendingLen() int
- func (q *ThreadSafeWorkQueueCell[T]) Push(value T) uint64
- func (q *ThreadSafeWorkQueueCell[T]) ReaderHandles() WorkQueueReaderHandles
- func (q *ThreadSafeWorkQueueCell[T]) ReapExpired(now int64) int
- type ThrottleCell
- type ThrottleCore
- type ThrottleEdge
- type TimedValue
- type TimelineSource
- type Timeout
- type TimeoutCancellation
- type TimeoutCell
- type TimeoutCore
- type TimeoutObservation
- type TimeoutOperation
- type Timer
- type TimerCell
- type TimerCore
- type TimerError
- type TimerObservation
- type TopicCell
- func (t *TopicCell[T]) Advance(id string, count int) int
- func (t *TopicCell[T]) BaseOffset() int
- func (t *TopicCell[T]) Disconnect(id string)
- func (t *TopicCell[T]) Elements() []T
- func (t *TopicCell[T]) GC() int
- func (t *TopicCell[T]) Publish(value T) int
- func (t *TopicCell[T]) Read(id string) (T, bool)
- func (t *TopicCell[T]) ReadStream(id string) ([]T, bool)
- func (t *TopicCell[T]) ReaderHandle(id string) *Computed[TopicRead[T]]
- func (t *TopicCell[T]) Reconnect(id string)
- func (t *TopicCell[T]) Restart()
- func (t *TopicCell[T]) Snapshot() TopicSnapshot[T]
- func (t *TopicCell[T]) Subscribe(id string, durability TopicDurability) TopicSubscribeOutcome
- func (t *TopicCell[T]) Subscription(id string) (TopicSubscriptionSnapshot, bool)
- func (t *TopicCell[T]) TailOffset() int
- type TopicDurability
- type TopicRead
- type TopicSnapshot
- type TopicSubscribeOutcome
- type TopicSubscriptionSnapshot
- type Trackable
- type Transition
- type Transport
- type TreeDotRange
- type TreeNodeChildren
- type TreeNodeSeed
- type TreeNodeSeedElement
- type TreeNodeSeedLeaf
- type TreeNodeSpec
- type TreeOp
- type TreeOpCreateNode
- type TreeOpKind
- type TreeOpLeafEdit
- type TreeOpMergeLeaves
- type TreeOpReorder
- type TreeOpSplitLeaf
- type TreeOpTombstone
- type TreeSortKey
- type TreeUpdate
- type TreeVersionFrontier
- type TumblingCountCore
- type TumblingCountWindow
- type TumblingTimeCore
- type TumblingTimeWindow
- type VecDequeStorage
- func (s *VecDequeStorage[T]) Capacity() (int, bool)
- func (s *VecDequeStorage[T]) Close()
- func (s *VecDequeStorage[T]) Elements() []T
- func (s *VecDequeStorage[T]) IsClosed() bool
- func (s *VecDequeStorage[T]) Len() int
- func (s *VecDequeStorage[T]) Peek() (T, bool)
- func (s *VecDequeStorage[T]) TryPop() (T, QueuePopError)
- func (s *VecDequeStorage[T]) TryPush(value T) QueuePushError
- type WindowPolicy
- type WireLwwRegister
- type WireStamp
- type WorkQueueCell
- func (q *WorkQueueCell[T]) Ack(worker string, deliveryID uint64) bool
- func (q *WorkQueueCell[T]) Claim(worker string, now int64) (WorkQueueDelivery[T], bool)
- func (q *WorkQueueCell[T]) DeadLetterItems() []WorkQueueDeadLetter[T]
- func (q *WorkQueueCell[T]) DeadLetterLen() int
- func (q *WorkQueueCell[T]) InFlightDeliveries() []WorkQueueDelivery[T]
- func (q *WorkQueueCell[T]) InFlightLen() int
- func (q *WorkQueueCell[T]) IsEmpty() bool
- func (q *WorkQueueCell[T]) Nack(worker string, deliveryID uint64) bool
- func (q *WorkQueueCell[T]) PendingItems() []WorkQueueItem[T]
- func (q *WorkQueueCell[T]) PendingLen() int
- func (q *WorkQueueCell[T]) Push(value T) uint64
- func (q *WorkQueueCell[T]) ReaderHandles() WorkQueueReaderHandles
- func (q *WorkQueueCell[T]) ReapExpired(now int64) int
- type WorkQueueDeadLetter
- type WorkQueueDeadLetterReason
- type WorkQueueDelivery
- type WorkQueueItem
- type WorkQueueReaderHandles
Constants ¶
const ( // Deprecated: use AsyncComputedEmpty. AsyncSlotEmpty = AsyncComputedEmpty // Deprecated: use AsyncComputedComputing. AsyncSlotComputing = AsyncComputedComputing // Deprecated: use AsyncComputedResolved. AsyncSlotResolved = AsyncComputedResolved // Deprecated: use AsyncComputedError. AsyncSlotError = AsyncComputedError )
const AnchorPrefix = "a:"
AnchorPrefix is the anchored-key wire prefix.
const BindingName = "lazily-go"
BindingName is this binding's name.
const ContentPrefix = "c:"
ContentPrefix is the content-key wire prefix.
const DefaultBenchmarkIterations = 10000
DefaultBenchmarkIterations is the iteration count used when a caller does not specify one, matching the Dart harness default.
const DefaultCodec = "json"
DefaultCodec is the default codec negotiation token.
const DefaultMaxFrameSize int64 = 1 << 20
DefaultMaxFrameSize is the default maximum frame size (1 MiB).
const DefaultSpillThreshold = 512
DefaultSpillThreshold is the default byte size at or above which SpillValue / SpillMessage spill an inline payload to a backend. It is a deployment knob, not a protocol constant: payloads below the threshold stay Inline (copying a tiny value through the codec is cheaper than a backend round-trip). Callers pass their own threshold to the Spill* functions.
const EditThreshold = 0.5
EditThreshold is the edit-similarity threshold below which a match is treated as an insert.
const EntryKindCell = EntryKindSource
EntryKindCell is the pre-v2-kernel name for EntryKindSource, kept as an alias so existing callers keep compiling. The v2 kernel renamed the node kinds to Source and Computed; the entry kinds follow. The underlying value and its wire string ("cell") are unchanged.
Deprecated: renamed to EntryKindSource.
const EntryKindSlot = EntryKindComputed
EntryKindSlot is the pre-v2-kernel name for EntryKindComputed. The underlying value and its wire string ("slot") are unchanged.
Deprecated: renamed to EntryKindComputed.
const FFIHasCABI = true
FFIHasCABI reports whether the native C-ABI export layer is compiled into this build. True under CGO_ENABLED=1.
const ProtocolID = "lazily-ipc"
ProtocolID is the protocol identifier every lazily-ipc peer must advertise.
const ProtocolMajorVersion = 1
ProtocolMajorVersion is the current protocol major version.
Variables ¶
var ErrAsyncContextDisposed = errors.New("lazily: async context disposed")
ErrAsyncContextDisposed is returned by async reads once the owning AsyncContext has been disposed (Dart threw a StateError here).
var ErrConflateNotBounding = &RelayConfigError{msg: "ConflateNotBounding"}
ErrConflateNotBounding is returned when Conflate is chosen for a non-conflating policy (e.g. RawFifo).
var ErrConnAlreadyExists = errors.New("signaling connection already exists")
ErrConnAlreadyExists is returned by Connect when connID is already connected.
var ErrDisposed = errors.New("lazily: read of a disposed reactive node")
ErrDisposed is the sentinel behind every *DisposedError, for errors.Is.
var ErrSignalingRoomClosed = errors.New("signaling room is closed")
ErrSignalingRoomClosed is returned by SignalingRoom methods after Close.
var TreeRoot = OpId{}
TreeRoot is the sentinel id of the document root: {counter: 0, peer: 0}. Reuses OpId; the zero value is the root.
Functions ¶
func ApplyBatch ¶
ApplyBatch applies the batch's value updates (with the PartialEq guard) to a copy of nodes and returns the new table plus the list of source ids that actually changed. A faithful port of the Lean applyBatch.
func AssignStableKeys ¶
AssignStableKeys assigns stable keys to newBlocks by flowing identity through the alignment with oldBlocks. Same/Edited inherit the predecessor's key; Inserted get a fresh key.
func BuildStateEvent ¶
func BuildStateEvent(docHash, eventType string, fields map[string]any, eventSuffix string) map[string]any
BuildStateEvent builds a state-backbone event for the agent-doc ledger. The eventType and document_hash seed the fact; entries in fields are merged over them (so fields may override), mirroring the Dart map-spread semantics.
func CheckedDeadline ¶ added in v0.25.0
CheckedDeadline returns now+duration or a typed overflow error.
func ContentHash ¶
ContentHash computes the FNV-1a 64-bit content hash of the UTF-8 bytes of Normalize(text). Cross-language stable (NOT Go's hash/fnv is equivalent, but the byte source mirrors the Dart code-unit encoding exactly).
func DocumentHash ¶
DocumentHash computes the FNV-1a 64-bit document hash for a file path or string.
Cross-language stable (NOT Dart's hashCode). The Dart original hashes over String.codeUnits (UTF-16 code units), so this port hashes the UTF-16 encoding of path — not its UTF-8 bytes — to reproduce the same digest. Used as the canonical document key for the state backbone.
func FlushBatch ¶
func FlushBatch(nodes map[any]NodeEntry, dependents map[any][]any, batch []BatchWrite) map[any]NodeEntry
FlushBatch applies the batch's values, then marks the coalesced union of changed sources' dependents dirty in one pass — a faithful port of the Lean flushBatch (the coalesced frontier: each dependent appears at most once).
func Get ¶ added in v0.21.0
func Get[T any](c ComputeOps, h Trackable[T]) T
Get reads a reactive handle through a compute surface (#lzcellkernel). When c is a *Compute, the read registers a dependency edge against the recomputing node; when c is a *Context (or c.Untracked()), it registers none. This is the value-threaded replacement for the ambient zero-argument handle.Get(): the node to attribute to is threaded through c, never read from a shared stack.
func Normalize ¶
Normalize collapses whitespace: split on \s+, drop empties, join with a single space.
func Own ¶ added in v0.20.0
func Own[N GraphNode](s *TeardownScope, n N) N
Own places n under s's ownership and returns it, so a node can be created and scoped in one expression:
total := lazily.Own(scope, lazily.NewSlot(ctx, compute))
It is a free function rather than a method because Go methods cannot take type parameters — and being generic in the *node* type rather than in the value type means this one function covers Slot, Cell, Signal, Memo, and Effect, instead of mirroring every constructor onto the scope the way lazily-rs must.
func OwnAsync ¶ added in v0.20.0
func OwnAsync[N AsyncGraphNode](s *AsyncTeardownScope, n N) N
OwnAsync places n under s's ownership and returns it.
A free function for the same reason as the synchronous Own: Go methods cannot take type parameters, and being generic in the node type lets one function cover cells, slots, and effects.
func Read ¶
func Read[T any](t *ThreadSafeContext, fn func(ctx *Context) T) T
Read runs fn under the lock and returns its result — the read-oriented convenience over WithLock.
func ResolveValue ¶ added in v0.4.0
func ResolveValue(value IpcValue, backend BlobBackend) ([]byte, bool)
ResolveValue resolves an IpcValue against a single backend: Inline bytes are returned directly (ok=true), a SharedBlob is resolved zero-copy against backend. Returns (nil, false) when a SharedBlob fails to resolve (unknown / stale / corrupt). The returned slice aliases whichever of value or backend owns the bytes.
func RetainLive ¶ added in v0.11.0
func RetainLive[T any](e *ExpiryPolicy, batch []TimedValue[T]) []T
RetainLive returns only the live elements of a timestamped batch (drops the aged tail). A free function because Go methods cannot carry their own type parameters.
func Similarity ¶
Similarity returns a value in [0, 1]: 2*|word-LCS| / (|a| + |b|). Both-empty is 1.0; exactly-one-empty is 0.0.
func TSSetCell ¶
func TSSetCell[T comparable](t *ThreadSafeContext, cell *Source[T], value T)
TSSetCell writes a cell's value under the lock. Outside a batch it applies immediately (a singleton batch ≡ Cell.Set); inside a Batch it defers to the coalesced flush. It is a free function because Go methods cannot be generic.
func TrackAsync
deprecated
func TrackAsync[T any](cc *AsyncComputeContext, computed *AsyncComputed[T]) (T, error)
TrackAsync is the deprecated v1 computed-read helper.
Deprecated: use TrackComputed.
func TrackCell
deprecated
func TrackCell[T any](cc *AsyncComputeContext, source *AsyncSource[T]) T
TrackCell is the deprecated v1 source-read helper.
Deprecated: use TrackSource.
func TrackComputed ¶ added in v0.24.0
func TrackComputed[T any](cc *AsyncComputeContext, computed *AsyncComputed[T]) (T, error)
TrackComputed awaits a computed inside an async compute/effect, registering a dependency edge before the awaited read (Dart AsyncComputeContext.getAsync). The nested await uses this compute's cancellation context, so supersession unwinds nested reads too.
func TrackSource ¶ added in v0.24.0
func TrackSource[T any](cc *AsyncComputeContext, cell *AsyncSource[T]) T
TrackSource reads a cell inside an async compute/effect, registering a dependency edge before returning the value (Dart AsyncComputeContext.getCell).
func UnionDependents ¶
UnionDependents is the flat union of dependents over a list of source nodes — a faithful port of the Lean unionDependents.
func UnlinkShmBackend ¶ added in v0.4.0
func UnlinkShmBackend(name string)
UnlinkShmBackend removes the named region so it is reclaimed once all mappings are unmapped. It is a no-op if the region does not exist.
func ValidateBlobRef ¶
func ValidateBlobRef(ref ShmBlobRef, maxLen *int64) bool
ValidateBlobRef validates a ShmBlobRef descriptor against expected bounds: all header fields must be non-negative, and Len must not exceed maxLen when maxLen is non-nil. Mirrors Dart `validateBlobRef({int? maxLen})`.
Types ¶
type Alignment ¶
type Alignment struct {
NewMatches []Match // one per new block
Removed []int // old indices not matched
}
Alignment is the alignment of new blocks against old, plus the set of removed old indices.
type ArrowBackend ¶ added in v0.4.0
type ArrowBackend struct {
// contains filtered or unexported fields
}
ArrowBackend is the Apache Arrow blob backend: it holds spilled payloads as Arrow IPC stream bytes and resolves a descriptor to the buffer's raw bytes with no copy. The descriptor's bytes ARE an Arrow IPC stream — a columnar consumer imports them as an Array / RecordBatch zero-copy (the Arrow IPC format is itself zero-copy across a shared buffer). This adapter stores the raw stream bytes and tags the descriptor Backend = BackendArrow; bring your own Arrow reader to wrap the resolved []byte into typed Arrow.
Because Arrow's IPC format is zero-copy over a shared buffer, shm and arrow compose: an Arrow batch can live in a ShmBackend region and be resolved by either backend. New backends (RDMA/verbs, CUDA IPC) plug in by implementing BlobBackend and adding a BlobBackendKind value.
func NewArrowBackend ¶ added in v0.4.0
func NewArrowBackend() *ArrowBackend
NewArrowBackend creates an Arrow backend over a fresh arena at epoch 0.
func (*ArrowBackend) AdvanceEpoch ¶ added in v0.4.0
func (b *ArrowBackend) AdvanceEpoch()
AdvanceEpoch advances the backing arena's epoch, invalidating prior descriptors.
func (*ArrowBackend) Arena ¶ added in v0.4.0
func (b *ArrowBackend) Arena() *ShmBlobArena
Arena returns the backing arena.
func (*ArrowBackend) Epoch ¶ added in v0.4.0
func (b *ArrowBackend) Epoch() int64
Epoch returns the backend's current validity epoch.
func (*ArrowBackend) Kind ¶ added in v0.4.0
func (b *ArrowBackend) Kind() BlobBackendKind
Kind reports BackendArrow.
func (*ArrowBackend) ReadView ¶ added in v0.4.0
func (b *ArrowBackend) ReadView(descriptor ShmBlobRef) ([]byte, bool)
ReadView resolves the descriptor zero-copy against the backing arena.
func (*ArrowBackend) Write ¶ added in v0.4.0
func (b *ArrowBackend) Write(bytes []byte) (ShmBlobRef, error)
Write stores the Arrow IPC stream bytes and stamps the descriptor with the Arrow backend discriminator.
type AsyncCellHandle
deprecated
type AsyncCellHandle[T any] = AsyncSource[T]
AsyncCellHandle is the deprecated v1 name for AsyncSource.
Deprecated: use AsyncSource.
type AsyncCellMap
deprecated
added in
v0.7.0
type AsyncCellMap[K comparable, V comparable] = AsyncSourceMap[K, V]
AsyncCellMap is the pre-v2-kernel name for AsyncSourceMap, kept as an alias so existing callers keep compiling.
Deprecated: renamed to AsyncSourceMap.
type AsyncComputeContext ¶
type AsyncComputeContext struct {
// contains filtered or unexported fields
}
AsyncComputeContext is handed to an async compute/effect body. Dependencies are registered through TrackSource / TrackComputed (free functions, because Go methods cannot be generic) which record the edge before the awaited read.
func (*AsyncComputeContext) Context ¶
func (cc *AsyncComputeContext) Context() context.Context
Context returns the per-compute cancellation context. It is cancelled when this compute is superseded or the AsyncContext is disposed; long-running compute bodies should observe Context().Done().
type AsyncComputed ¶ added in v0.24.0
type AsyncComputed[T any] struct { // contains filtered or unexported fields }
AsyncComputed is a computed async slot: a blocking/future-returning computation that recomputes when its dependencies change.
func NewAsyncComputed ¶ added in v0.24.0
func NewAsyncComputed[T any](c *AsyncContext, compute func(cc *AsyncComputeContext) (T, error)) *AsyncComputed[T]
NewAsyncComputed creates an async computed slot (Dart AsyncContext.computedAsync). compute reads its dependencies through the AsyncComputeContext and returns a value or an error.
func NewAsyncComputedRippleWhen ¶ added in v0.21.0
func NewAsyncComputedRippleWhen[T any](c *AsyncContext, compute func(cc *AsyncComputeContext) (T, error), changed func(old, next T) bool) *AsyncComputed[T]
NewAsyncComputedRippleWhen is the async mirror of NewComputedRippleWhen (#lzcellkernel): a guarded async computed whose downstream propagation is gated by an explicit, PURE predicate changed(old, next) — true propagates the recompute to dependents, false suppresses it. It installs the engine's equality guard as its negation (equal => suppress), so NewAsyncComputedWithEquals(f, eq) and NewAsyncComputedRippleWhen(f, func(o, n) bool { return !eq(o, n) }) are the same. changed MUST be pure in (old, next); value-carried state is fine, external mutable state is not.
func NewAsyncComputedWithEquals ¶ added in v0.24.0
func NewAsyncComputedWithEquals[T any](c *AsyncContext, compute func(cc *AsyncComputeContext) (T, error), eq Equals[T]) *AsyncComputed[T]
NewAsyncComputedWithEquals is like NewAsyncComputed but with an equality memo guard: a recompute that yields an equal value (per eq) keeps the cached value and suppresses the dependency cascade (Dart AsyncContext.memoAsync).
func NewAsyncMemo
deprecated
func NewAsyncMemo[T any]( c *AsyncContext, compute func(cc *AsyncComputeContext) (T, error), eq Equals[T], ) *AsyncComputed[T]
NewAsyncMemo is the deprecated guarded-computed constructor. Memo is not a separate node kind.
Deprecated: use NewAsyncComputedWithEquals.
func NewAsyncSlot
deprecated
func NewAsyncSlot[T any]( c *AsyncContext, compute func(cc *AsyncComputeContext) (T, error), ) *AsyncComputed[T]
NewAsyncSlot is the deprecated v1 computed constructor.
Deprecated: use NewAsyncComputed.
func (*AsyncComputed[T]) Dispose ¶ added in v0.24.0
func (s *AsyncComputed[T]) Dispose()
Dispose is an alias for DisposeAsync.
func (*AsyncComputed[T]) DisposeAsync ¶ added in v0.24.0
func (s *AsyncComputed[T]) DisposeAsync()
DisposeAsync tears down this async slot: it cancels any in-flight compute, detaches both edge directions, and dirties the surviving dependent cone. Idempotent.
Blocked waiters and any later reader receive a *DisposedError — the same "errors on next recompute" contract as the synchronous Slot.Dispose.
func (*AsyncComputed[T]) Get ¶ added in v0.24.0
func (s *AsyncComputed[T]) Get() (T, bool)
Get is the synchronous cached read (Dart get()): it returns (value, true) when the slot is resolved, else (zero, false). It does not spawn a compute.
func (*AsyncComputed[T]) GetAsync ¶ added in v0.24.0
func (s *AsyncComputed[T]) GetAsync(ctx context.Context) (T, error)
GetAsync awaits the slot's value. Resolved slots return immediately; otherwise the caller attaches to the in-flight compute (spawning one if none is running — in-flight deduplication). ctx cancels this waiter only: dropping one waiter never cancels a shared in-flight compute (cancellation contract point 1). Supersession causes a transparent re-resolve.
func (*AsyncComputed[T]) Revision ¶ added in v0.24.0
func (s *AsyncComputed[T]) Revision() int
Revision reports the current revision (incremented on each invalidation; a completion whose revision is stale is discarded).
func (*AsyncComputed[T]) State ¶ added in v0.24.0
func (s *AsyncComputed[T]) State() AsyncComputedState
State reports the current state-machine state.
func (*AsyncComputed[T]) Value ¶ added in v0.24.0
func (s *AsyncComputed[T]) Value() (T, bool)
Value returns the cached value when resolved, else (zero, false) (Dart value getter).
type AsyncComputedMap ¶ added in v0.22.0
type AsyncComputedMap[K comparable, V comparable] struct { *AsyncReactiveMap[K, V, asyncComputedNodeHandle] }
AsyncComputedMap is the derived-slot specialization of AsyncReactiveMap: entries are minted pending and driven to resolution via Drive; MaterializeAll pre-mints the keyset (still pending until driven). No Set.
func NewAsyncComputedMap ¶ added in v0.22.0
func NewAsyncComputedMap[K comparable, V comparable](c *AsyncContext) *AsyncComputedMap[K, V]
NewAsyncComputedMap creates an empty async derived-slot map.
func NewAsyncSlotMap
deprecated
added in
v0.7.0
func NewAsyncSlotMap[K comparable, V comparable](c *AsyncContext) *AsyncComputedMap[K, V]
NewAsyncSlotMap creates an empty async derived-slot map through the v1 name.
Deprecated: renamed to NewAsyncComputedMap.
func (*AsyncComputedMap[K, V]) MaterializeAll ¶ added in v0.22.0
func (m *AsyncComputedMap[K, V]) MaterializeAll(keys []K, factory func(K) V)
MaterializeAll eagerly pre-mints (allocates, still pending) a derived slot for every key. Drive each to resolution. Observationally identical (once driven) to minting lazily on first access.
type AsyncComputedState ¶ added in v0.24.0
type AsyncComputedState string
AsyncComputedState is the public projection of an async computed's finite-state machine. The formal model retains the storage-oriented AsyncSlotState theorem/module name.
const ( // AsyncComputedEmpty: no cached value, no in-flight computation. Entered on // creation and after a hard clear. AsyncComputedEmpty AsyncComputedState = "empty" // AsyncComputedComputing: a compute is in flight for the current revision. // Concurrent GetAsync callers attach as waiters instead of spawning // duplicate computations. AsyncComputedComputing AsyncComputedState = "computing" // AsyncComputedResolved: the cached value is fresh, until dependency // invalidation transitions back to computing. AsyncComputedResolved AsyncComputedState = "resolved" // AsyncComputedError: the last computation failed. Waiters on that attempt // receive its error; the error is not cached. The next GetAsync re-spawns // (Error -> Computing), per docs/async.md § Async slot state machine and // LazilyFormal.AsyncSlotState SlotEvent.retry. AsyncComputedError AsyncComputedState = "error" )
type AsyncContext ¶
type AsyncContext struct {
// contains filtered or unexported fields
}
AsyncContext is the async reactive surface: a distinct graph owned by a single goroutine that serializes all mutations and reads over a command channel. Unlike core Context, AsyncContext is safe for concurrent use.
func NewAsyncContext ¶
func NewAsyncContext() *AsyncContext
NewAsyncContext creates an async reactive context and starts its owner goroutine. Call DisposeAsync or Close to tear it down.
func (*AsyncContext) Batch ¶
func (c *AsyncContext) Batch(run func())
Batch delimits a synchronous batch on the calling goroutine. Cell writes made during run queue their invalidation roots; at the outermost batch exit the queued roots propagate once. Async reruns fire after run returns. Re-entrant.
Note: because the batch flag is loop-owned, cell writes from other goroutines during the batch are also coalesced; batch from a single goroutine.
func (*AsyncContext) Close ¶
func (c *AsyncContext) Close() error
Close disposes the context (io.Closer-style). It always returns nil.
func (*AsyncContext) DependencyCount ¶ added in v0.20.0
func (c *AsyncContext) DependencyCount(n AsyncGraphNode) int
DependencyCount reports how many nodes n currently depends on — the size of its forward edge set. Returns 0 for a disposed node and for a cell, which is a pure source.
func (*AsyncContext) DependentCount ¶ added in v0.20.0
func (c *AsyncContext) DependentCount(n AsyncGraphNode) int
DependentCount reports how many nodes currently depend on n — the size of its reverse edge set (#lzspecedgeindex). Returns 0 for a disposed node and for an effect, which is a pure sink.
As on the synchronous plane, this counts *live* edges: invalidation consumes the reverse edge and each dependent re-registers when it recomputes, so a degree read between a write and the pull that follows it reports the post-cascade state.
func (*AsyncContext) DisposeAsync ¶
func (c *AsyncContext) DisposeAsync()
DisposeAsync disposes the context: cancels all in-flight computations, delivers a disposed error to blocked waiters, runs and awaits every active effect cleanup, then stops the owner goroutine. Subsequent operations are no-ops / disposed errors. Idempotent.
func (*AsyncContext) EffectAsync ¶
func (c *AsyncContext) EffectAsync(body func(cc *AsyncComputeContext) func()) *AsyncEffectHandle
EffectAsync creates an async effect. The body receives a compute context and returns an optional cleanup callback run before the next body and on disposal. Reruns are serialized: a rerun does not start until the prior cleanup runs.
func (*AsyncContext) IsDisposed ¶ added in v0.20.0
func (c *AsyncContext) IsDisposed(n AsyncGraphNode) bool
IsDisposed reports whether n has been torn down.
func (*AsyncContext) Scope ¶ added in v0.20.0
func (c *AsyncContext) Scope() *AsyncTeardownScope
Scope opens a teardown scope on this async context.
func (*AsyncContext) WithScope ¶ added in v0.20.0
func (c *AsyncContext) WithScope(fn func(s *AsyncTeardownScope))
WithScope runs fn with a fresh async teardown scope and closes it on return, including on panic.
type AsyncEffectHandle ¶
type AsyncEffectHandle struct {
// contains filtered or unexported fields
}
AsyncEffectHandle is an async effect returned by AsyncContext.EffectAsync. Reruns are serialized per effect (a rerun does not start until the previous cleanup completes), and disposal awaits the current cleanup.
func (*AsyncEffectHandle) Dispose ¶
func (e *AsyncEffectHandle) Dispose()
Dispose is an alias for DisposeAsync.
func (*AsyncEffectHandle) DisposeAsync ¶
func (e *AsyncEffectHandle) DisposeAsync()
DisposeAsync disposes the effect: cancels any in-flight body and runs its pending cleanup. Idempotent.
func (*AsyncEffectHandle) IsActive ¶ added in v0.20.0
func (e *AsyncEffectHandle) IsActive() bool
IsActive reports whether this effect is still registered (not disposed).
type AsyncGraphNode ¶ added in v0.20.0
type AsyncGraphNode interface {
// contains filtered or unexported methods
}
AsyncGraphNode is any node in an AsyncContext's graph: *AsyncSource, *AsyncComputed, or *AsyncEffectHandle.
Sealed by an unexported method, and — like the synchronous GraphNode — it exposes counts only, never the edge sets.
type AsyncMapHandle ¶ added in v0.7.0
type AsyncMapHandle interface {
// contains filtered or unexported methods
}
AsyncMapHandle is the entry-handle kind an AsyncReactiveMap abstracts over — the async analog of the Rust AsyncMapHandle trait. Sealed to the two node kinds of the cell model. resolvedOnMint reports whether a freshly-minted entry is resolved (a cell — always resolved) or pending (a derived slot).
type AsyncQueueCell ¶ added in v0.24.0
type AsyncQueueCell[T comparable, S QueueStorage[T]] struct { // contains filtered or unexported fields }
AsyncQueueCell is the AsyncContext FIFO flavor. Storage is serialized by mu; changed reader kinds are invalidated together through AsyncContext.Batch.
func NewAsyncQueueCell ¶ added in v0.24.0
func NewAsyncQueueCell[T comparable](ctx *AsyncContext) *AsyncQueueCell[T, *VecDequeStorage[T]]
func NewAsyncQueueCellWithStorage ¶ added in v0.24.0
func NewAsyncQueueCellWithStorage[T comparable, S QueueStorage[T]]( ctx *AsyncContext, storage S, ) *AsyncQueueCell[T, S]
func NewBoundedAsyncQueueCell ¶ added in v0.24.0
func NewBoundedAsyncQueueCell[T comparable]( ctx *AsyncContext, capacity int, ) *AsyncQueueCell[T, *VecDequeStorage[T]]
func (*AsyncQueueCell[T, S]) Capacity ¶ added in v0.24.0
func (q *AsyncQueueCell[T, S]) Capacity() (int, bool)
func (*AsyncQueueCell[T, S]) Close ¶ added in v0.24.0
func (q *AsyncQueueCell[T, S]) Close()
func (*AsyncQueueCell[T, S]) Elements ¶ added in v0.24.0
func (q *AsyncQueueCell[T, S]) Elements() []T
func (*AsyncQueueCell[T, S]) Head ¶ added in v0.24.0
func (q *AsyncQueueCell[T, S]) Head(cc *AsyncComputeContext) (T, bool)
func (*AsyncQueueCell[T, S]) IsClosed ¶ added in v0.24.0
func (q *AsyncQueueCell[T, S]) IsClosed(cc *AsyncComputeContext) bool
func (*AsyncQueueCell[T, S]) IsEmpty ¶ added in v0.24.0
func (q *AsyncQueueCell[T, S]) IsEmpty(cc *AsyncComputeContext) bool
func (*AsyncQueueCell[T, S]) IsFull ¶ added in v0.24.0
func (q *AsyncQueueCell[T, S]) IsFull(cc *AsyncComputeContext) bool
func (*AsyncQueueCell[T, S]) Len ¶ added in v0.24.0
func (q *AsyncQueueCell[T, S]) Len(cc *AsyncComputeContext) int
func (*AsyncQueueCell[T, S]) ReaderHandles ¶ added in v0.24.0
func (q *AsyncQueueCell[T, S]) ReaderHandles() AsyncQueueReaderHandles[T]
func (*AsyncQueueCell[T, S]) TryPop ¶ added in v0.24.0
func (q *AsyncQueueCell[T, S]) TryPop() (T, QueuePopError)
func (*AsyncQueueCell[T, S]) TryPush ¶ added in v0.24.0
func (q *AsyncQueueCell[T, S]) TryPush(value T) QueuePushError
type AsyncQueueReaderHandles ¶ added in v0.24.0
type AsyncQueueReaderHandles[T comparable] struct { Head *AsyncComputed[queueHead[T]] Len *AsyncComputed[int] IsEmpty *AsyncComputed[bool] IsFull *AsyncComputed[bool] IsClosed *AsyncSource[bool] }
AsyncQueueReaderHandles exposes the five queue reader kinds on the async graph. The content readers are memoized derives; Closed is a direct input.
type AsyncReactiveMap ¶ added in v0.7.0
type AsyncReactiveMap[K comparable, V comparable, H AsyncMapHandle] struct { // contains filtered or unexported fields }
AsyncReactiveMap is the async keyed reactive map (#reactivemap) generic over the entry handle kind H, each entry carrying a resolution flag. V is comparable to mirror the single-threaded map.
Once built its address is stable, so concurrent readers may share a *AsyncReactiveMap. See the package doc for the eager/lazy contract, present-set monotonicity, and the eventual-transparency law.
func (*AsyncReactiveMap[K, V, H]) ContainsKey ¶ added in v0.23.0
func (m *AsyncReactiveMap[K, V, H]) ContainsKey(cc *AsyncComputeContext, key K) bool
ContainsKey reports the reactive membership test for key.
func (*AsyncReactiveMap[K, V, H]) Drive ¶ added in v0.7.0
func (m *AsyncReactiveMap[K, V, H]) Drive(key K, factory func(K) V) V
Drive drives key to resolution — the analog of AsyncContext.GetAsync: allocate if absent, resolve if pending (produce + cache the canonical value via factory), and return the resolved value. A warm-resolved key returns its cached value unchanged. The eventual-transparency completion.
func (*AsyncReactiveMap[K, V, H]) Entry ¶ added in v0.23.0
func (m *AsyncReactiveMap[K, V, H]) Entry(key K) *AsyncSource[V]
Entry returns key's node on the async graph, or nil. Reading it through TrackSource inside an async compute registers a per-entry dependency edge.
func (*AsyncReactiveMap[K, V, H]) EntryID ¶ added in v0.23.0
func (m *AsyncReactiveMap[K, V, H]) EntryID(key K) (uint64, bool)
EntryID returns key's stable birth identity — the async analog of a node handle. It survives a reorder and changes only on a re-mint.
func (*AsyncReactiveMap[K, V, H]) EntryKind ¶ added in v0.7.0
func (m *AsyncReactiveMap[K, V, H]) EntryKind() EntryKind
EntryKind returns this map's entry kind.
func (*AsyncReactiveMap[K, V, H]) GetOrInsertWith ¶ added in v0.7.0
func (m *AsyncReactiveMap[K, V, H]) GetOrInsertWith(key K, factory func(K) V) (V, bool)
GetOrInsertWith mints key on first access and returns the current observation: (value, true) for a cell or a warm-resolved slot, (_, false) for a freshly pending slot. Mint-on-access; drive a pending slot with Drive.
func (*AsyncReactiveMap[K, V, H]) IsEmpty ¶ added in v0.23.0
func (m *AsyncReactiveMap[K, V, H]) IsEmpty(cc *AsyncComputeContext) bool
IsEmpty reports the reactive emptiness check.
func (*AsyncReactiveMap[K, V, H]) IsPresent ¶ added in v0.7.0
func (m *AsyncReactiveMap[K, V, H]) IsPresent(key K) bool
IsPresent reports whether key is currently allocated (present). Non-reactive.
func (*AsyncReactiveMap[K, V, H]) IsResolved ¶ added in v0.7.0
func (m *AsyncReactiveMap[K, V, H]) IsResolved(key K) bool
IsResolved reports whether key is allocated AND resolved (a non-blocking Observe would return a value).
func (*AsyncReactiveMap[K, V, H]) Keys ¶ added in v0.23.0
func (m *AsyncReactiveMap[K, V, H]) Keys(cc *AsyncComputeContext) []K
Keys returns a reactive snapshot of the keys in their current order. Subscribes the caller to order changes when read inside an async compute.
func (*AsyncReactiveMap[K, V, H]) Len ¶ added in v0.23.0
func (m *AsyncReactiveMap[K, V, H]) Len(cc *AsyncComputeContext) int
Len reports the reactive entry count. Subscribes to membership changes only.
func (*AsyncReactiveMap[K, V, H]) LenUntracked ¶ added in v0.23.0
func (m *AsyncReactiveMap[K, V, H]) LenUntracked() int
LenUntracked reports the non-reactive count.
func (*AsyncReactiveMap[K, V, H]) MoveAfter ¶ added in v0.23.0
func (m *AsyncReactiveMap[K, V, H]) MoveAfter(key, anchor K) bool
MoveAfter atomically moves key to just after anchor (#lzcellmove).
func (*AsyncReactiveMap[K, V, H]) MoveBefore ¶ added in v0.23.0
func (m *AsyncReactiveMap[K, V, H]) MoveBefore(key, anchor K) bool
MoveBefore atomically moves key to just before anchor (#lzcellmove).
func (*AsyncReactiveMap[K, V, H]) MoveTo ¶ added in v0.23.0
func (m *AsyncReactiveMap[K, V, H]) MoveTo(key K, index int) bool
MoveTo atomically moves key to index in the order (#lzcellmove). The entry keeps its identity and its resolution state; only the order signal is bumped, so Keys readers recompute while Len / ContainsKey readers stay cached. index is clamped to [0, len).
func (*AsyncReactiveMap[K, V, H]) Observe ¶ added in v0.7.0
func (m *AsyncReactiveMap[K, V, H]) Observe(key K, factory func(K) V) (V, bool)
Observe is a non-blocking read: (value, true) once resolved, (_, false) while pending. Allocates the entry via factory if absent — a freshly allocated slot is pending, so a first Observe of a slot returns (_, false) until Driven; a cell is resolved at allocation, so it returns (value, true) immediately.
func (*AsyncReactiveMap[K, V, H]) ObserveTracked ¶ added in v0.23.0
func (m *AsyncReactiveMap[K, V, H]) ObserveTracked(cc *AsyncComputeContext, key K) (V, bool)
ObserveTracked is the reactive per-entry read: inside an async compute it registers an edge against that entry's node, so a later write to this key invalidates the reader and a write to any OTHER key does not.
func (*AsyncReactiveMap[K, V, H]) Position ¶ added in v0.23.0
func (m *AsyncReactiveMap[K, V, H]) Position(key K) (int, bool)
Position reports key's current 0-based position in the order. Non-reactive.
func (*AsyncReactiveMap[K, V, H]) PresentCount ¶ added in v0.7.0
func (m *AsyncReactiveMap[K, V, H]) PresentCount() int
PresentCount returns the number of currently-allocated entries.
func (*AsyncReactiveMap[K, V, H]) PresentKeys ¶ added in v0.7.0
func (m *AsyncReactiveMap[K, V, H]) PresentKeys() []K
PresentKeys returns a stable snapshot of the currently-allocated keys, in first-materialization order (a copy — the internal order must not escape the lock).
func (*AsyncReactiveMap[K, V, H]) Remove ¶ added in v0.23.0
func (m *AsyncReactiveMap[K, V, H]) Remove(key K) bool
Remove removes key's entry and bumps reactive membership. Returns whether the key was present. The removed entry's cached value goes with it, so a later read cannot serve a stale resolution.
type AsyncSlotHandle
deprecated
type AsyncSlotHandle[T any] = AsyncComputed[T]
AsyncSlotHandle is the deprecated v1 name for AsyncComputed.
Deprecated: use AsyncComputed.
type AsyncSlotMap
deprecated
added in
v0.7.0
type AsyncSlotMap[K comparable, V comparable] = AsyncComputedMap[K, V]
AsyncSlotMap is the pre-v2-kernel name for AsyncComputedMap, kept as an alias so existing callers keep compiling.
Deprecated: renamed to AsyncComputedMap.
type AsyncSlotState
deprecated
type AsyncSlotState = AsyncComputedState
AsyncSlotState is the deprecated v1 name for AsyncComputedState.
Deprecated: use AsyncComputedState.
type AsyncSource ¶ added in v0.24.0
type AsyncSource[T any] struct { // contains filtered or unexported fields }
AsyncSource is a mutable input cell on the async graph. Reads registered inside an async compute/effect (via TrackSource) create a dependency edge; writes invalidate dependents.
func NewAsyncCell
deprecated
func NewAsyncCell[T any](c *AsyncContext, value T) *AsyncSource[T]
NewAsyncCell is the deprecated v1 source constructor.
Deprecated: use NewAsyncSource.
func NewAsyncSource ¶ added in v0.24.0
func NewAsyncSource[T any](c *AsyncContext, value T) *AsyncSource[T]
NewAsyncSource creates a mutable input cell bound to c (Dart AsyncContext.cell).
func (*AsyncSource[T]) Dispose ¶ added in v0.24.0
func (h *AsyncSource[T]) Dispose()
Dispose is an alias for DisposeAsync.
func (*AsyncSource[T]) DisposeAsync ¶ added in v0.24.0
func (h *AsyncSource[T]) DisposeAsync()
DisposeAsync tears down this async cell: it detaches its dependents and dirties the surviving cone. Cells are pure sources, so only downstream edges need detaching. Idempotent.
func (*AsyncSource[T]) Get ¶ added in v0.24.0
func (h *AsyncSource[T]) Get() T
Get returns the current value. It does NOT register a dependency (there is no ambient compute outside a goroutine in Go); use TrackSource inside an async compute for reactive reads. Kept for parity with the Dart surface.
func (*AsyncSource[T]) Peek ¶ added in v0.24.0
func (h *AsyncSource[T]) Peek() T
Peek returns the current value without registering a dependency (non-reactive). Use TrackSource to read reactively inside an async compute.
func (*AsyncSource[T]) Set ¶ added in v0.24.0
func (h *AsyncSource[T]) Set(value T)
Set assigns a new value. If it differs from the current value, dependent async slots/effects are invalidated (or queued when inside Batch).
func (*AsyncSource[T]) TryGet ¶ added in v0.24.0
func (h *AsyncSource[T]) TryGet() (T, error)
TryGet is the checked read: it returns a *DisposedError instead of panicking when this cell has been disposed.
type AsyncSourceMap ¶ added in v0.22.0
type AsyncSourceMap[K comparable, V comparable] struct { *AsyncReactiveMap[K, V, asyncSourceNodeHandle] }
AsyncSourceMap is the input-cell specialization of AsyncReactiveMap: every entry is an always-resolved input cell. Adds the cell-only Set.
func NewAsyncCellMap
deprecated
added in
v0.7.0
func NewAsyncCellMap[K comparable, V comparable](c *AsyncContext) *AsyncSourceMap[K, V]
NewAsyncCellMap creates an empty async input-cell map through the v1 name.
Deprecated: renamed to NewAsyncSourceMap.
func NewAsyncSourceMap ¶ added in v0.22.0
func NewAsyncSourceMap[K comparable, V comparable](c *AsyncContext) *AsyncSourceMap[K, V]
NewAsyncSourceMap creates an empty async input-cell map.
func (*AsyncSourceMap[K, V]) Set ¶ added in v0.22.0
func (m *AsyncSourceMap[K, V]) Set(key K, value V)
Set overwrites key's value (cells are writable, always resolved), materializing the entry if absent. Cell-only: a derived AsyncComputedMap slot is not settable.
type AsyncTeardownScope ¶ added in v0.20.0
type AsyncTeardownScope struct {
// contains filtered or unexported fields
}
AsyncTeardownScope groups async nodes so they can be torn down together. The Close/Disarm/Own shape and its rationale are identical to the synchronous TeardownScope; see disposal.go.
func (*AsyncTeardownScope) Close ¶ added in v0.20.0
func (s *AsyncTeardownScope) Close()
Close tears down every node this scope owns, in reverse creation order. Idempotent.
func (*AsyncTeardownScope) Disarm ¶ added in v0.20.0
func (s *AsyncTeardownScope) Disarm()
Disarm cancels this scope's teardown: Close then disposes nothing and the nodes revert to plain context ownership, untouched and individually disposable.
func (*AsyncTeardownScope) Len ¶ added in v0.20.0
func (s *AsyncTeardownScope) Len() int
Len reports how many nodes this scope currently owns.
type AsyncTopicCell ¶ added in v0.24.0
type AsyncTopicCell[T any] struct { // contains filtered or unexported fields }
AsyncTopicCell is the AsyncContext broadcast-log flavor.
func NewAsyncTopicCell ¶ added in v0.24.0
func NewAsyncTopicCell[T any](ctx *AsyncContext) *AsyncTopicCell[T]
func NewAsyncTopicCellFromSnapshot ¶ added in v0.24.0
func NewAsyncTopicCellFromSnapshot[T any]( ctx *AsyncContext, snapshot TopicSnapshot[T], ) *AsyncTopicCell[T]
func (*AsyncTopicCell[T]) Advance ¶ added in v0.24.0
func (t *AsyncTopicCell[T]) Advance(id string, count int) int
func (*AsyncTopicCell[T]) BaseOffset ¶ added in v0.24.0
func (t *AsyncTopicCell[T]) BaseOffset() int
func (*AsyncTopicCell[T]) Disconnect ¶ added in v0.24.0
func (t *AsyncTopicCell[T]) Disconnect(id string)
func (*AsyncTopicCell[T]) Elements ¶ added in v0.24.0
func (t *AsyncTopicCell[T]) Elements() []T
func (*AsyncTopicCell[T]) GC ¶ added in v0.24.0
func (t *AsyncTopicCell[T]) GC() int
func (*AsyncTopicCell[T]) Publish ¶ added in v0.24.0
func (t *AsyncTopicCell[T]) Publish(value T) int
func (*AsyncTopicCell[T]) Read ¶ added in v0.24.0
func (t *AsyncTopicCell[T]) Read(cc *AsyncComputeContext, id string) (T, bool)
func (*AsyncTopicCell[T]) ReadStream ¶ added in v0.24.0
func (t *AsyncTopicCell[T]) ReadStream(cc *AsyncComputeContext, id string) ([]T, bool)
func (*AsyncTopicCell[T]) ReaderHandle ¶ added in v0.24.0
func (t *AsyncTopicCell[T]) ReaderHandle(id string) *AsyncComputed[TopicRead[T]]
func (*AsyncTopicCell[T]) Reconnect ¶ added in v0.24.0
func (t *AsyncTopicCell[T]) Reconnect(id string)
func (*AsyncTopicCell[T]) Restart ¶ added in v0.24.0
func (t *AsyncTopicCell[T]) Restart()
func (*AsyncTopicCell[T]) Snapshot ¶ added in v0.24.0
func (t *AsyncTopicCell[T]) Snapshot() TopicSnapshot[T]
func (*AsyncTopicCell[T]) Subscribe ¶ added in v0.24.0
func (t *AsyncTopicCell[T]) Subscribe( id string, durability TopicDurability, ) TopicSubscribeOutcome
func (*AsyncTopicCell[T]) Subscription ¶ added in v0.24.0
func (t *AsyncTopicCell[T]) Subscription(id string) (TopicSubscriptionSnapshot, bool)
func (*AsyncTopicCell[T]) TailOffset ¶ added in v0.24.0
func (t *AsyncTopicCell[T]) TailOffset() int
type AsyncWorkQueueCell ¶ added in v0.24.0
type AsyncWorkQueueCell[T any] struct { // contains filtered or unexported fields }
AsyncWorkQueueCell is the AsyncContext competing-consumer flavor.
func NewAsyncWorkQueueCell ¶ added in v0.24.0
func NewAsyncWorkQueueCell[T any]( ctx *AsyncContext, visibilityTimeout int64, maxDeliveries uint64, ) *AsyncWorkQueueCell[T]
func (*AsyncWorkQueueCell[T]) Ack ¶ added in v0.24.0
func (q *AsyncWorkQueueCell[T]) Ack(worker string, deliveryID uint64) bool
func (*AsyncWorkQueueCell[T]) Claim ¶ added in v0.24.0
func (q *AsyncWorkQueueCell[T]) Claim(worker string, now int64) (WorkQueueDelivery[T], bool)
func (*AsyncWorkQueueCell[T]) DeadLetterItems ¶ added in v0.24.0
func (q *AsyncWorkQueueCell[T]) DeadLetterItems() []WorkQueueDeadLetter[T]
func (*AsyncWorkQueueCell[T]) DeadLetterLen ¶ added in v0.24.0
func (q *AsyncWorkQueueCell[T]) DeadLetterLen(cc *AsyncComputeContext) int
func (*AsyncWorkQueueCell[T]) InFlightDeliveries ¶ added in v0.24.0
func (q *AsyncWorkQueueCell[T]) InFlightDeliveries() []WorkQueueDelivery[T]
func (*AsyncWorkQueueCell[T]) InFlightLen ¶ added in v0.24.0
func (q *AsyncWorkQueueCell[T]) InFlightLen(cc *AsyncComputeContext) int
func (*AsyncWorkQueueCell[T]) IsEmpty ¶ added in v0.24.0
func (q *AsyncWorkQueueCell[T]) IsEmpty(cc *AsyncComputeContext) bool
func (*AsyncWorkQueueCell[T]) Nack ¶ added in v0.24.0
func (q *AsyncWorkQueueCell[T]) Nack(worker string, deliveryID uint64) bool
func (*AsyncWorkQueueCell[T]) PendingItems ¶ added in v0.24.0
func (q *AsyncWorkQueueCell[T]) PendingItems() []WorkQueueItem[T]
func (*AsyncWorkQueueCell[T]) PendingLen ¶ added in v0.24.0
func (q *AsyncWorkQueueCell[T]) PendingLen(cc *AsyncComputeContext) int
func (*AsyncWorkQueueCell[T]) Push ¶ added in v0.24.0
func (q *AsyncWorkQueueCell[T]) Push(value T) uint64
func (*AsyncWorkQueueCell[T]) ReaderHandles ¶ added in v0.24.0
func (q *AsyncWorkQueueCell[T]) ReaderHandles() AsyncWorkQueueReaderHandles
func (*AsyncWorkQueueCell[T]) ReapExpired ¶ added in v0.24.0
func (q *AsyncWorkQueueCell[T]) ReapExpired(now int64) int
type AsyncWorkQueueReaderHandles ¶ added in v0.24.0
type AsyncWorkQueueReaderHandles struct {
PendingLen *AsyncComputed[int]
IsEmpty *AsyncComputed[bool]
InFlightLen *AsyncComputed[int]
DeadLetterLen *AsyncComputed[int]
}
AsyncWorkQueueReaderHandles exposes the four lifecycle derives.
type AwarenessCell ¶ added in v0.15.0
type AwarenessCell[K comparable, V comparable] struct { // contains filtered or unexported fields }
AwarenessCell is a reactive typed ephemeral broadcast (cursors / selections): last-writer-per-peer with a TTL. Values do NOT merge.
func NewAwarenessCell ¶ added in v0.15.0
func NewAwarenessCell[K comparable, V comparable](ctx *Context, ttl uint64) *AwarenessCell[K, V]
NewAwarenessCell builds an awareness cell with a TTL.
func (*AwarenessCell[K, V]) Get ¶ added in v0.15.0
func (c *AwarenessCell[K, V]) Get(peer K, now uint64) (V, bool)
Get returns a peer's live value (respecting now).
func (*AwarenessCell[K, V]) Present ¶ added in v0.15.0
func (c *AwarenessCell[K, V]) Present() map[K]V
Present returns the live peer -> value snapshot.
func (*AwarenessCell[K, V]) PresentCell ¶ added in v0.15.0
func (c *AwarenessCell[K, V]) PresentCell() *Source[uint64]
PresentCell exposes the internal version cell backing the present projection.
func (*AwarenessCell[K, V]) Set ¶ added in v0.15.0
func (c *AwarenessCell[K, V]) Set(peer K, value V, now uint64)
Set a peer's awareness value (last-writer wins, no merge).
func (*AwarenessCell[K, V]) Tick ¶ added in v0.15.0
func (c *AwarenessCell[K, V]) Tick(now uint64)
Tick evicts expired entries.
type BackpressurePolicy ¶ added in v0.11.0
type BackpressurePolicy struct {
Dimension *Source[BoundDim]
HighWater *Source[uint64]
LowWater *Source[uint64]
Overflow *Source[Overflow]
}
BackpressurePolicy holds reactive backpressure limits (analysis §4.4). Every field is a cell, so an operator or adaptive controller retunes it live and dependent relays react. Hysteresis (HighWater ≠ LowWater) prevents flapping.
func NewBackpressurePolicy ¶ added in v0.11.0
func NewBackpressurePolicy(ctx *Context, dimension BoundDim, highWater, lowWater uint64, overflow Overflow) BackpressurePolicy
NewBackpressurePolicy builds a reactive backpressure policy over ctx.
type BarrierCell ¶ added in v0.15.0
type BarrierCell[P comparable] struct { // contains filtered or unexported fields }
BarrierCell is a reactive wait-for-N gate. Quorum is a barrier with required = total/2 + 1.
func NewBarrierCell ¶ added in v0.15.0
func NewBarrierCell[P comparable](ctx *Context, required uint64) *BarrierCell[P]
NewBarrierCell constructs a reactive wait-for-N gate.
func Quorum ¶ added in v0.15.0
func Quorum[P comparable](ctx *Context, total uint64) *BarrierCell[P]
Quorum constructs a quorum gate: opens at strict majority of total.
func (*BarrierCell[P]) Arrive ¶ added in v0.15.0
func (c *BarrierCell[P]) Arrive(peer P) bool
Arrive registers an arrival / vote; returns whether the gate is open after.
func (*BarrierCell[P]) Count ¶ added in v0.15.0
func (c *BarrierCell[P]) Count() uint64
Count returns the number of distinct arrivals.
func (*BarrierCell[P]) IsOpen ¶ added in v0.15.0
func (c *BarrierCell[P]) IsOpen() bool
IsOpen reports whether the gate has opened.
func (*BarrierCell[P]) IsOpenCell ¶ added in v0.15.0
func (c *BarrierCell[P]) IsOpenCell() *Source[bool]
IsOpenCell exposes the reactive is_open projection.
type BarrierCore ¶ added in v0.15.0
type BarrierCore[P comparable] struct { // contains filtered or unexported fields }
BarrierCore is a wait-for-N gate compute core over distinct arriving peers.
func NewBarrierCore ¶ added in v0.15.0
func NewBarrierCore[P comparable](required uint64) *BarrierCore[P]
NewBarrierCore returns a barrier that opens once required distinct peers arrive.
func (*BarrierCore[P]) Arrive ¶ added in v0.15.0
func (c *BarrierCore[P]) Arrive(peer P) bool
Arrive registers a distinct arrival; returns whether the gate is open after.
func (*BarrierCore[P]) Count ¶ added in v0.15.0
func (c *BarrierCore[P]) Count() uint64
Count returns the number of distinct arrivals.
func (*BarrierCore[P]) IsOpen ¶ added in v0.15.0
func (c *BarrierCore[P]) IsOpen() bool
IsOpen reports whether the gate has opened.
type BatchFlush ¶
type BatchFlush struct {
// ChangedCells are the cells that changed in this batch (informational; not
// serialized).
ChangedCells []NodeId
// Frontier is the coalesced, duplicate-free invalidation frontier.
Frontier []NodeId
// Ops is Frontier mapped to DeltaOpInvalidate (theorem
// `batch_flush_ops_are_frontier_invalidations`).
Ops []DeltaOp
}
BatchFlush is lean `BatchFlush` + theorems `batch_frontier_is_coalesced`, `batch_flush_advances_epoch_once`, `batch_flush_ops_are_frontier_invalidations`.
One outermost batch-flush invalidation pass produces a no-duplicate frontier (Frontier) and emits exactly one delta that advances the IPC epoch once. The frontier is coalesced: a dependent reached through many changed cells appears at most once.
func NewBatchFlush ¶
func NewBatchFlush(changedCells, frontier []NodeId) BatchFlush
NewBatchFlush coalesces frontier and derives the invalidation ops.
func (BatchFlush) ToDelta ¶
func (b BatchFlush) ToDelta(baseEpoch Epoch) Delta
ToDelta builds the single delta this flush emits, advancing the epoch exactly once (theorem `batch_flush_advances_epoch_once`).
type BatchWrite ¶
BatchWrite is a (nodeID, value) write in the pure kernel.
type BenchmarkResult ¶
type BenchmarkResult struct {
Name string
Iterations int
// TotalMicros is the total elapsed time across all iterations, in
// microseconds.
TotalMicros int64
}
BenchmarkResult is a single benchmark measurement.
func Benchmark ¶
func Benchmark(name string, body func(), iterations int) BenchmarkResult
Benchmark runs body iterations times and measures the total elapsed time.
func RunBenchmarkSuite ¶
func RunBenchmarkSuite(iterations int) []BenchmarkResult
RunBenchmarkSuite runs the full benchmark suite and returns every result. Pass DefaultBenchmarkIterations to match the Dart default.
func (BenchmarkResult) AvgMicros ¶
func (r BenchmarkResult) AvgMicros() float64
AvgMicros returns the average time per iteration in microseconds.
func (BenchmarkResult) OpsPerSecond ¶
func (r BenchmarkResult) OpsPerSecond() float64
OpsPerSecond returns the operations per second.
func (BenchmarkResult) String ¶
func (r BenchmarkResult) String() string
String renders the result the same way the Dart toString does.
type BindingCapabilities ¶
type BindingCapabilities struct {
Binding string
Ffi FfiCapability
ReactiveCore bool
Collections bool
StateMachine bool
StateCharts bool
Ipc bool
Crdt bool
Permissions bool
CapabilityNegotiation bool
Async bool
}
BindingCapabilities is the lazily-go binding's conformance declaration (protocol.md § Binding Conformance Matrix). This binding implements every MUST layer.
The Dart original models this as a class of static consts; in Go the canonical declaration is a value returned by NewBindingCapabilities. The `Ffi` capability is `host` because Go can host a native C ABI via cgo; never `none` (the `none` carve-out is reserved for platforms with no shared in-process address space, e.g. browser/Worker JS).
func NewBindingCapabilities ¶
func NewBindingCapabilities() BindingCapabilities
NewBindingCapabilities returns the canonical lazily-go conformance declaration (every MUST layer implemented, ffi = host).
func (BindingCapabilities) MarshalJSON ¶
func (b BindingCapabilities) MarshalJSON() ([]byte, error)
MarshalJSON emits the conformance declaration with the spec field order.
func (BindingCapabilities) ToWire ¶
func (b BindingCapabilities) ToWire() any
ToWire returns the JSON object (as an ordered marshaling struct) a peer introspects at build/link time.
type BlobBackend ¶ added in v0.4.0
type BlobBackend interface {
// Kind reports which backend discriminator this adapter serves.
Kind() BlobBackendKind
// Write mints a fresh descriptor for bytes: it stores the bytes immutably
// and returns a descriptor whose Checksum is the bytes' FNV-1a-64, tagged
// with this backend's Kind.
Write(bytes []byte) (ShmBlobRef, error)
// ReadView resolves descriptor zero-copy: it returns the stored bytes and
// ok=true iff generation + epoch + len + checksum all match; (nil, false)
// otherwise. No copy, no checksum recompute. The returned slice aliases the
// backend's storage and is valid only while the backend holds the entry.
ReadView(descriptor ShmBlobRef) ([]byte, bool)
// AdvanceEpoch advances the validity epoch. Descriptors minted before an
// epoch advance no longer resolve (models compaction / restart).
AdvanceEpoch()
}
BlobBackend is the adapter seam: a backend mints descriptors via Write and resolves them zero-copy via ReadView. Entries are immutable and stably addressed for any descriptor's lifetime, so the transport laws (resolve_write identity, backend isolation, ABA generation safety, checksum rejection) hold for every backend by construction.
type BlobBackendKind ¶ added in v0.4.0
type BlobBackendKind string
BlobBackendKind selects which pluggable blob backend resolves a descriptor (cross-process zero-copy transport, #lzzcpy). A receiver routes resolution by this discriminator: a `shm` descriptor never resolves in an Arrow backend and vice versa (the resolve_wrong_backend theorem). It is the wire mirror of the Rust `BlobBackendKind` enum; the `arena` itself is backend-agnostic and does not store it — the discriminator is wire-level routing only.
The zero value ("") is the default backend, Shm, so a legacy descriptor with no `backend` field resolves unchanged. Unknown strings also fall back to Shm (never a hard failure), matching the Rust `from_str`.
const ( // BackendShm is the POSIX shared-memory backend (shm_open + mmap) — the // default cross-process backend (same host). Omitted on the wire. BackendShm BlobBackendKind = "shm" // BackendArrow holds Apache Arrow IPC stream bytes — the descriptor's bytes // are an Arrow IPC stream the receiver imports zero-copy. BackendArrow BlobBackendKind = "arrow" // BackendInProcess is an in-process arena (single address space — the FFI // host / an editor plugin loaded in the same process). BackendInProcess BlobBackendKind = "in_process" )
func (BlobBackendKind) IsDefault ¶ added in v0.4.0
func (k BlobBackendKind) IsDefault() bool
IsDefault reports whether this is the default backend (Shm). Used to omit the `backend` field on the wire so legacy descriptors validate unchanged.
func (BlobBackendKind) Normalized ¶ added in v0.4.0
func (k BlobBackendKind) Normalized() BlobBackendKind
Normalized collapses the zero value and any unknown discriminator to the default backend (Shm), so resolution never hard-fails on a legacy or forward-compatible descriptor.
type BlobRouter ¶ added in v0.4.0
type BlobRouter struct {
// contains filtered or unexported fields
}
BlobRouter is the receiver-side multi-backend resolver. It holds backends by BlobBackendKind and resolves any descriptor by its Backend discriminator — a shm descriptor routes to the shm backend, an arrow descriptor to the arrow backend, etc. This is the resolve_wrong_backend theorem in practice: a descriptor never resolves against a backend of the wrong kind (an unregistered kind resolves to nothing).
The zero value is a ready empty router; NewBlobRouter is the explicit constructor.
func NewBlobRouter ¶ added in v0.4.0
func NewBlobRouter() *BlobRouter
NewBlobRouter creates an empty router with no backends registered.
func (*BlobRouter) ReadView ¶ added in v0.4.0
func (r *BlobRouter) ReadView(descriptor ShmBlobRef) ([]byte, bool)
ReadView resolves a descriptor by routing to its Backend kind. Returns (nil, false) if no backend is registered for this kind, or the descriptor did not resolve.
func (*BlobRouter) Register ¶ added in v0.4.0
func (r *BlobRouter) Register(backend BlobBackend) *BlobRouter
Register installs backend for its Kind, replacing any previously-registered backend of the same kind. It returns the router for chaining.
type Block ¶
Block is a text block, optionally anchored.
func NewAnchoredBlock ¶
NewAnchoredBlock constructs an anchored block (Dart Block.anchored).
type BlockKey ¶
type BlockKey struct {
Kind string // "anchored" | "content"
AnchorValue string // valid when Kind == "anchored"
ContentValue uint64 // valid when Kind == "content"
// contains filtered or unexported fields
}
BlockKey is a manufactured block key: either anchored or content-derived. Anchored keys carry a string value; content keys carry a 64-bit FNV-1a hash.
func AnchoredBlockKey ¶
AnchoredBlockKey constructs an anchored key (Dart BlockKey.anchored).
func BlockKeyOf ¶
BlockKeyOf computes the manufactured key for block: anchor wins, else content hash (Dart blockKey).
func ContentBlockKey ¶
ContentBlockKey constructs a content-derived key (Dart BlockKey.content).
func (BlockKey) AsString ¶
AsString renders the wire form: "a:<anchor>" or "c:" + 16-char zero-padded hex of the 64-bit content hash.
func (BlockKey) IsAnchored ¶
IsAnchored reports whether this is an anchored key.
type BoundDim ¶ added in v0.11.0
type BoundDim string
BoundDim is what a bound measures (analysis §4.4). The core meters Count.
type BoundedStorage ¶ added in v0.9.0
type BoundedStorage interface {
// Capacity reports the bound and true for a bounded backend, or 0 and
// false for the unbounded default.
Capacity() (int, bool)
}
BoundedStorage is the OPTIONAL bound capability. A backend implementing it and reporting a bound gains a reactive IsFull backpressure reader; a backend without it is treated as unbounded (IsFull is always false).
type BreakerState ¶ added in v0.15.0
type BreakerState int
BreakerState is the circuit-breaker state.
const ( // BreakerClosed — calls pass; failures accumulate in the window. BreakerClosed BreakerState = iota // BreakerOpen — fast-fail until the reset deadline. BreakerOpen // BreakerHalfOpen — allow a single probe. BreakerHalfOpen )
func (BreakerState) String ¶ added in v0.15.0
func (s BreakerState) String() string
type BulkheadCell ¶ added in v0.15.0
type BulkheadCell struct {
// contains filtered or unexported fields
}
BulkheadCell is a reactive bulkhead: projects permitsInUse onto a Cell.
func NewBulkheadCell ¶ added in v0.15.0
func NewBulkheadCell(ctx *Context, capacity uint64) *BulkheadCell
NewBulkheadCell builds a reactive bulkhead.
func (*BulkheadCell) Acquire ¶ added in v0.15.0
func (b *BulkheadCell) Acquire() bool
Acquire takes a permit if one is free, updating the projection.
func (*BulkheadCell) PermitsInUse ¶ added in v0.15.0
func (b *BulkheadCell) PermitsInUse() uint64
PermitsInUse returns the projected number of permits in use.
func (*BulkheadCell) PermitsInUseCell ¶ added in v0.15.0
func (b *BulkheadCell) PermitsInUseCell() *Source[uint64]
PermitsInUseCell returns the reactive permits-in-use reader.
func (*BulkheadCell) Release ¶ added in v0.15.0
func (b *BulkheadCell) Release()
Release frees a permit, updating the projection.
type BulkheadCore ¶ added in v0.15.0
type BulkheadCore struct {
// contains filtered or unexported fields
}
BulkheadCore is a bounded isolation-pool compute core.
func NewBulkheadCore ¶ added in v0.15.0
func NewBulkheadCore(capacity uint64) *BulkheadCore
NewBulkheadCore builds a core.
func (*BulkheadCore) Acquire ¶ added in v0.15.0
func (b *BulkheadCore) Acquire() bool
Acquire takes a permit if one is free.
func (*BulkheadCore) InUse ¶ added in v0.15.0
func (b *BulkheadCore) InUse() uint64
InUse returns the number of permits in use.
func (*BulkheadCore) Release ¶ added in v0.15.0
func (b *BulkheadCore) Release()
Release frees a permit.
type CallState ¶ added in v0.2.0
type CallState struct {
Kind CallStateKind
Entry CommandProjectionEntry // populated when Kind == Resolved
}
CallState is the unary-RPC resolution state. A call resolves only when the command projection reaches a terminal causal receipt.
type CallStateKind ¶ added in v0.2.0
type CallStateKind string
CallStateKind enumerates the unary-RPC resolution states.
const ( CallStateKindPending CallStateKind = "pending" CallStateKindResolved CallStateKind = "resolved" CallStateKindConflict CallStateKind = "conflict" )
type CapabilityCheck ¶
CapabilityCheck is the result of CapabilityHandshake.CheckCompatible. On failure, Field is the offending handshake field and Reason the human-readable fail-closed cause; both are empty on success.
func CapabilityCheckFail ¶
func CapabilityCheckFail(field, reason string) CapabilityCheck
CapabilityCheckFail builds a failed check for the offending field.
func CapabilityCheckOk ¶
func CapabilityCheckOk() CapabilityCheck
CapabilityCheckOk builds a successful check.
func (CapabilityCheck) IsOk ¶
func (c CapabilityCheck) IsOk() bool
IsOk reports whether the handshake is compatible.
func (CapabilityCheck) String ¶
func (c CapabilityCheck) String() string
type CapabilityHandshake ¶
type CapabilityHandshake struct {
ProtocolID string
ProtocolMajorVersion int
Codec string
MaxFrameSize int64
FragmentationSupported bool
OrderedReliable bool
PeerID PeerId
SessionID string
Features []string
}
CapabilityHandshake is the compatibility handshake exchanged before any graph state flows (protocol.md § Capability Negotiation). It is serialized as a plain JSON object (NOT externally tagged — a standalone frame, not an IpcMessage variant).
func DecodeCapabilityHandshakeJSON ¶
func DecodeCapabilityHandshakeJSON(data []byte) (CapabilityHandshake, error)
DecodeCapabilityHandshakeJSON decodes UTF-8 JSON bytes into a handshake.
func NewCapabilityHandshake ¶
func NewCapabilityHandshake(peerID PeerId, sessionID string) CapabilityHandshake
NewCapabilityHandshake builds a handshake with protocol defaults (JSON codec, 1 MiB frame, ordered-reliable, no features). Mirrors the Dart `CapabilityHandshake.defaults` factory; customize with the With* builders.
func (CapabilityHandshake) CheckCompatible ¶
func (h CapabilityHandshake) CheckCompatible(other CapabilityHandshake, requiredFeatures ...string) CapabilityCheck
CheckCompatible is a structured compatibility check. It returns the offending field (and reason) on mismatch so a caller can produce a clean fail-closed diagnostic — mirrors `lazily-js::SessionHandshake.checkCompatible`.
requiredFeatures are checked against the OTHER peer's offered set: if this peer requires a feature the other does not offer, the handshake fails closed on `features`.
func (CapabilityHandshake) EncodeJSON ¶
func (h CapabilityHandshake) EncodeJSON() ([]byte, error)
EncodeJSON returns the UTF-8 JSON bytes of the plain-JSON wire form.
func (CapabilityHandshake) HasFeature ¶
func (h CapabilityHandshake) HasFeature(feature string) bool
HasFeature reports whether this peer advertises feature.
func (CapabilityHandshake) IsCompatibleWith ¶
func (h CapabilityHandshake) IsCompatibleWith(other CapabilityHandshake) bool
IsCompatibleWith reports whether this handshake is mutually compatible with other.
Peers are compatible when both advertise ProtocolID, both advertise ProtocolMajorVersion, their major versions and codecs agree, and both require ordered-reliable delivery. Feature negotiation is caller-driven via HasFeature / CheckCompatible's requiredFeatures argument.
func (CapabilityHandshake) MarshalJSON ¶
func (h CapabilityHandshake) MarshalJSON() ([]byte, error)
MarshalJSON emits the plain-JSON wire object with the spec field order, always rendering `features` as an array (never null).
func (CapabilityHandshake) String ¶
func (h CapabilityHandshake) String() string
func (CapabilityHandshake) ToWire ¶
func (h CapabilityHandshake) ToWire() any
ToWire returns the plain-JSON wire shape (a standalone frame, NOT externally tagged) as an ordered marshaling struct.
func (*CapabilityHandshake) UnmarshalJSON ¶
func (h *CapabilityHandshake) UnmarshalJSON(b []byte) error
UnmarshalJSON decodes a plain-JSON wire object. It defaults fragmentation_supported = false, ordered_reliable = true, codec = "json", protocol_id = "lazily-ipc", protocol_major_version = 1, max_frame_size = 1 MiB, and features = [] when absent (mirrors the lazily-rs serde defaults and the Dart fromWire). peer_id is required and must be a non-negative integer; max_frame_size, when present, must be non-negative.
func (CapabilityHandshake) WithCodec ¶
func (h CapabilityHandshake) WithCodec(codec string) CapabilityHandshake
WithCodec returns a copy with the codec negotiation token set.
func (CapabilityHandshake) WithFeatures ¶
func (h CapabilityHandshake) WithFeatures(features []string) CapabilityHandshake
WithFeatures returns a copy with the features list set.
func (CapabilityHandshake) WithFragmentation ¶
func (h CapabilityHandshake) WithFragmentation(supported bool) CapabilityHandshake
WithFragmentation returns a copy with fragmentation support set.
func (CapabilityHandshake) WithMaxFrameSize ¶
func (h CapabilityHandshake) WithMaxFrameSize(maxFrameSize int64) CapabilityHandshake
WithMaxFrameSize returns a copy with the max frame size set.
func (CapabilityHandshake) WithOrderedReliable ¶
func (h CapabilityHandshake) WithOrderedReliable(orderedReliable bool) CapabilityHandshake
WithOrderedReliable returns a copy with ordered-reliable set.
type CausalReceipt ¶
type CausalReceipt struct {
// ReceiptId is the idempotency key for this receipt event.
ReceiptId string `json:"receipt_id"`
// CausationId is the stable id of the command/effect this receipt observes.
CausationId string `json:"causation_id"`
// Observer is the peer, process, or subsystem that produced the receipt.
Observer string `json:"observer"`
// Generation is the producer/editor generation. Consumers discard receipts
// outside the current generation for the causation id.
Generation int64 `json:"generation"`
// Outcome is the receipt lifecycle outcome.
Outcome ReceiptOutcome `json:"outcome"`
// Reason is an optional human/debug rejection reason (null when absent).
Reason *string `json:"reason"`
// PayloadHash is an optional hash of the observed state/payload (null when
// absent).
PayloadHash *string `json:"payload_hash"`
}
CausalReceipt is one receipt event for a command/effect causation id.
Reason and PayloadHash are nullable wire fields: they marshal to JSON null when nil (the schema lists both as required), so they carry no `omitempty`.
func AcceptedReceipt ¶
func AcceptedReceipt(receiptId, causationId, observer string, generation int64) CausalReceipt
AcceptedReceipt constructs an `accepted` receipt.
func AppliedReceipt ¶
func AppliedReceipt(receiptId, causationId, observer string, generation int64) CausalReceipt
AppliedReceipt constructs an `applied` (terminal) receipt.
func CausalReceiptFromWire ¶
func CausalReceiptFromWire(data []byte) (CausalReceipt, error)
CausalReceiptFromWire decodes a single receipt from JSON bytes.
func NewCausalReceipt ¶
func NewCausalReceipt(receiptId, causationId, observer string, generation int64, outcome ReceiptOutcome) CausalReceipt
NewCausalReceipt constructs a receipt with the given outcome and no reason or payload hash.
func ObservedReceipt ¶
func ObservedReceipt(receiptId, causationId, observer string, generation int64) CausalReceipt
ObservedReceipt constructs an `observed` receipt.
func RejectedReceipt ¶
func RejectedReceipt(receiptId, causationId, observer string, generation int64) CausalReceipt
RejectedReceipt constructs a `rejected` (terminal) receipt.
func (CausalReceipt) IsTerminal ¶
func (r CausalReceipt) IsTerminal() bool
IsTerminal reports whether this receipt's outcome is terminal.
func (*CausalReceipt) UnmarshalJSON ¶
func (r *CausalReceipt) UnmarshalJSON(b []byte) error
UnmarshalJSON decodes a receipt and validates the outcome enum.
func (CausalReceipt) WithPayloadHash ¶
func (r CausalReceipt) WithPayloadHash(hash string) CausalReceipt
WithPayloadHash returns a copy of the receipt carrying a payload hash.
func (CausalReceipt) WithReason ¶
func (r CausalReceipt) WithReason(reason string) CausalReceipt
WithReason returns a copy of the receipt carrying a debug/rejection reason.
type CausalReceipts ¶
type CausalReceipts struct {
// Receipts is the receipt batch.
Receipts []CausalReceipt `json:"receipts"`
}
CausalReceipts is the wire body for a batch of receipts.
func CausalReceiptsFromWire ¶
func CausalReceiptsFromWire(data []byte) (CausalReceipts, error)
CausalReceiptsFromWire decodes a receipt batch from JSON bytes.
func NewCausalReceipts ¶
func NewCausalReceipts(receipts []CausalReceipt) CausalReceipts
NewCausalReceipts constructs a receipt batch, copying the input slice.
func (CausalReceipts) MarshalJSON ¶
func (c CausalReceipts) MarshalJSON() ([]byte, error)
MarshalJSON emits { receipts } with receipts always an array (never null).
type CellCrdt ¶
type CellCrdt[T comparable] struct { // contains filtered or unexported fields }
CellCrdt is a reactive cell whose value is resolved by merging concurrent writes. Backed by a Cell[T] and a pluggable merge function (LWW, MV, or custom). Reads are reactive; writes fold the incoming value into the current one via the merge function.
T must be comparable because the backing Cell uses the == PartialEq guard.
func NewCellCrdt ¶
func NewCellCrdt[T comparable](ctx *Context, initial T, merge func(current, incoming T) T) *CellCrdt[T]
NewCellCrdt creates a CRDT-backed cell with initial value and merge function.
type CellMap
deprecated
type CellMap[K comparable, V comparable] = SourceMap[K, V]
CellMap is the pre-v2-kernel name for SourceMap, kept as an alias so existing callers keep compiling. The v2 kernel renamed the node kinds to Source and Computed; the keyed collections follow.
Deprecated: renamed to SourceMap.
type CellTree
deprecated
type CellTree[K comparable, V comparable] = SourceTree[K, V]
CellTree is the pre-v2-kernel name for SourceTree, kept as an alias so existing callers keep compiling. The v2 kernel renamed the node kinds to Source and Computed; the keyed collections follow.
Deprecated: renamed to SourceTree.
type ChartDef ¶
type ChartDef struct {
// contains filtered or unexported fields
}
ChartDef is a parsed, immutable chart definition — the node-labeled functions of the declarative JSON form materialized as maps for deterministic descent. Build it via ChartDefFromJSON and hand it to NewStateChart.
func ChartDefFromJSON ¶
ChartDefFromJSON parses a chart definition from the declarative JSON form (lazily-spec/schemas/statechart.json). `run` actions and {"expr": …} context guards are rejected explicitly.
type CircuitBreakerCell ¶ added in v0.15.0
type CircuitBreakerCell struct {
// contains filtered or unexported fields
}
CircuitBreakerCell is a reactive circuit breaker: projects the state onto a Cell.
func NewCircuitBreakerCell ¶ added in v0.15.0
func NewCircuitBreakerCell(ctx *Context, window, failureThreshold int, resetTimeout uint64) *CircuitBreakerCell
NewCircuitBreakerCell builds a reactive circuit breaker.
func (*CircuitBreakerCell) Allow ¶ added in v0.15.0
func (c *CircuitBreakerCell) Allow(now uint64) bool
Allow reports whether a call is permitted, updating the projected state.
func (*CircuitBreakerCell) Record ¶ added in v0.15.0
func (c *CircuitBreakerCell) Record(success bool, now uint64)
Record feeds a call outcome, updating the projected state.
func (*CircuitBreakerCell) State ¶ added in v0.15.0
func (c *CircuitBreakerCell) State() BreakerState
State returns the current breaker state.
func (*CircuitBreakerCell) StateCell ¶ added in v0.15.0
func (c *CircuitBreakerCell) StateCell() *Source[BreakerState]
StateCell returns the reactive state reader.
type CircuitBreakerCore ¶ added in v0.15.0
type CircuitBreakerCore struct {
// contains filtered or unexported fields
}
CircuitBreakerCore is the circuit-breaker compute core: a sliding window of outcomes trips Closed->Open at failureThreshold; Open->HalfOpen at the deadline; a HalfOpen success closes, a failure re-opens.
func NewCircuitBreakerCore ¶ added in v0.15.0
func NewCircuitBreakerCore(window, failureThreshold int, resetTimeout uint64) *CircuitBreakerCore
NewCircuitBreakerCore builds a core; window and failureThreshold clamp to >= 1.
func (*CircuitBreakerCore) Allow ¶ added in v0.15.0
func (c *CircuitBreakerCore) Allow(now uint64) bool
Allow reports whether a call is permitted; performs the Open->HalfOpen transition at the deadline.
func (*CircuitBreakerCore) Record ¶ added in v0.15.0
func (c *CircuitBreakerCore) Record(success bool, now uint64)
Record feeds a call outcome and drives the state machine.
func (*CircuitBreakerCore) State ¶ added in v0.15.0
func (c *CircuitBreakerCore) State() BreakerState
State returns the current breaker state.
type ClientAnswer ¶
ClientAnswer carries a WebRTC SDP answer to a target peer.
func (ClientAnswer) MarshalJSON ¶
func (m ClientAnswer) MarshalJSON() ([]byte, error)
func (ClientAnswer) Type ¶
func (ClientAnswer) Type() string
type ClientConn ¶
type ClientConn struct {
// contains filtered or unexported fields
}
ClientConn is a per-connection handle into a SignalingRoom. Send client frames on the inbound channel (Inbound) and read server frames from the outbound channel (Outbound). The outbound channel is closed when the connection is disconnected or the room is closed.
func (*ClientConn) ConnID ¶
func (c *ClientConn) ConnID() any
ConnID returns the opaque connection id.
func (*ClientConn) Inbound ¶
func (c *ClientConn) Inbound() chan<- ClientMessage
Inbound is the send side for client -> room frames.
func (*ClientConn) Outbound ¶
func (c *ClientConn) Outbound() <-chan ServerMessage
Outbound is the receive side for room -> client frames. It is closed when the connection is torn down.
type ClientIce ¶
ClientIce carries an ICE candidate to a target peer.
func (ClientIce) MarshalJSON ¶
type ClientJoin ¶
ClientJoin registers a connection with the session under a peer id. The optional Capabilities list is omitted from the wire when nil (an explicit empty list is preserved).
func (ClientJoin) MarshalJSON ¶
func (m ClientJoin) MarshalJSON() ([]byte, error)
func (ClientJoin) Type ¶
func (ClientJoin) Type() string
type ClientLeave ¶
type ClientLeave struct{}
ClientLeave disconnects the connection from the session.
func (ClientLeave) MarshalJSON ¶
func (ClientLeave) MarshalJSON() ([]byte, error)
func (ClientLeave) Type ¶
func (ClientLeave) Type() string
type ClientMessage ¶
type ClientMessage interface {
// Type returns the wire discriminant.
Type() string
MarshalJSON() ([]byte, error)
// contains filtered or unexported methods
}
ClientMessage is a client -> server signaling frame. It is a sealed union (mirroring the Dart `sealed class ClientMessage`); concrete variants are ClientJoin/ClientOffer/ClientAnswer/ClientIce/ClientRelay/ClientLeave. Decode wire bytes with ParseClientMessage; each variant implements MarshalJSON.
func ParseClientMessage ¶
func ParseClientMessage(data []byte) (ClientMessage, error)
ParseClientMessage decodes an internally-tagged client frame from JSON bytes.
type ClientOffer ¶
ClientOffer carries a WebRTC SDP offer to a target peer.
func (ClientOffer) MarshalJSON ¶
func (m ClientOffer) MarshalJSON() ([]byte, error)
func (ClientOffer) Type ¶
func (ClientOffer) Type() string
type ClientRelay ¶
type ClientRelay struct {
To PeerId
Payload json.RawMessage
}
ClientRelay relays an opaque JSON payload to a target peer. Payload is kept as json.RawMessage so it round-trips byte-for-byte through the server.
func (ClientRelay) MarshalJSON ¶
func (m ClientRelay) MarshalJSON() ([]byte, error)
func (ClientRelay) Type ¶
func (ClientRelay) Type() string
type Clock ¶ added in v0.8.0
type Clock interface {
// NowMillis returns milliseconds from an arbitrary fixed origin; monotonic,
// non-decreasing.
NowMillis() int64
}
Clock is the monotonic clock seam (spec § SyncDriver — policy injected, no runtime in core). The driver never schedules itself; the host calls Tick on its own cadence and supplies wall-free monotonic millis so the driver can timestamp progress and expose a stall signal without owning a clock source.
type CommandApplyStatus ¶ added in v0.2.0
type CommandApplyStatus interface {
// contains filtered or unexported methods
}
CommandApplyStatus is the result of folding a frame into a CommandProjection.
type CommandApplyStatusKind ¶ added in v0.2.0
type CommandApplyStatusKind string
CommandApplyStatusKind enumerates the result variants.
const ( CommandApplyStatusRecorded CommandApplyStatusKind = "recorded" CommandApplyStatusDuplicate CommandApplyStatusKind = "duplicate" CommandApplyStatusUnknown CommandApplyStatusKind = "unknown" CommandApplyStatusStaleGeneration CommandApplyStatusKind = "stale_generation" CommandApplyStatusTerminalConflict CommandApplyStatusKind = "terminal_conflict" )
type CommandCancel ¶ added in v0.2.0
type CommandCancel struct {
CommandId string `json:"command_id"`
CausationId string `json:"causation_id"`
Source string `json:"source"`
AuthorityGeneration int64 `json:"authority_generation"`
Reason *string `json:"reason"`
}
CommandCancel preempts a still-non-terminal command by command_id at a given authority_generation, with an optional reason. A stale-generation cancel is ignored. A cancel after a terminal outcome never rewrites it.
type CommandEvent ¶ added in v0.2.0
type CommandEvent struct {
EventId string `json:"event_id"`
CommandId string `json:"command_id"`
Kind CommandEventKind `json:"kind"`
Generation int64 `json:"generation"`
Detail *string `json:"detail"`
}
CommandEvent is one progress/detail event keyed by command_id.
func (*CommandEvent) UnmarshalJSON ¶ added in v0.2.0
func (e *CommandEvent) UnmarshalJSON(b []byte) error
UnmarshalJSON decodes a CommandEvent, validating the kind enum.
type CommandEventKind ¶ added in v0.2.0
type CommandEventKind string
CommandEventKind is a progress/detail event kind. These are UX/diagnostics only and are NEVER terminal proof; terminal proof folds through CausalReceipt. cancelled/superseded/timed_out are surfaced here for UX but their terminal authority is a matching rejected receipt.
const ( CommandEventKindObserved CommandEventKind = "observed" CommandEventKindAccepted CommandEventKind = "accepted" CommandEventKindStarted CommandEventKind = "started" CommandEventKindProgress CommandEventKind = "progress" CommandEventKindCancelled CommandEventKind = "cancelled" CommandEventKindSuperseded CommandEventKind = "superseded" CommandEventKindTimedOut CommandEventKind = "timed_out" )
type CommandEvents ¶ added in v0.2.0
type CommandEvents struct {
Events []CommandEvent `json:"events"`
}
CommandEvents is a batch of progress/detail events.
func (CommandEvents) MarshalJSON ¶ added in v0.2.0
func (c CommandEvents) MarshalJSON() ([]byte, error)
MarshalJSON emits { events } with events always an array (never null).
type CommandMessage ¶ added in v0.2.0
type CommandMessage struct {
Tag CommandMessageTag
Submit *CommandSubmit
Cancel *CommandCancel
Events *CommandEvents
Projection *CommandProjectionImage
}
CommandMessage is one externally-tagged frame of the command plane.
func CommandMessageFromWire ¶ added in v0.2.0
func CommandMessageFromWire(data []byte) (CommandMessage, error)
CommandMessageFromWire decodes a CommandMessage from JSON bytes.
func NewCommandMessageCancel ¶ added in v0.2.0
func NewCommandMessageCancel(c CommandCancel) CommandMessage
NewCommandMessageCancel wraps a CommandCancel frame.
func NewCommandMessageEvents ¶ added in v0.2.0
func NewCommandMessageEvents(e CommandEvents) CommandMessage
NewCommandMessageEvents wraps a CommandEvents frame.
func NewCommandMessageProjection ¶ added in v0.2.0
func NewCommandMessageProjection(p CommandProjectionImage) CommandMessage
NewCommandMessageProjection wraps a CommandProjection frame.
func NewCommandMessageSubmit ¶ added in v0.2.0
func NewCommandMessageSubmit(s CommandSubmit) CommandMessage
NewCommandMessageSubmit wraps a CommandSubmit frame.
func (CommandMessage) MarshalJSON ¶ added in v0.2.0
func (m CommandMessage) MarshalJSON() ([]byte, error)
MarshalJSON renders the externally-tagged wire form {"<Tag>": body}.
func (*CommandMessage) UnmarshalJSON ¶ added in v0.2.0
func (m *CommandMessage) UnmarshalJSON(b []byte) error
UnmarshalJSON decodes an externally-tagged CommandMessage.
type CommandMessageTag ¶ added in v0.2.0
type CommandMessageTag string
CommandMessageTag identifies the frame variant.
const ( CommandMessageTagSubmit CommandMessageTag = "CommandSubmit" CommandMessageTagCancel CommandMessageTag = "CommandCancel" CommandMessageTagEvents CommandMessageTag = "CommandEvents" CommandMessageTagProjection CommandMessageTag = "CommandProjection" )
type CommandPolicy ¶ added in v0.2.0
type CommandPolicy struct {
Dedupe DedupePolicy `json:"dedupe"`
Supersede bool `json:"supersede"`
CancelOnPreempt bool `json:"cancel_on_preempt"`
}
CommandPolicy is the per-submit admission policy.
type CommandProjection ¶ added in v0.2.0
type CommandProjection struct {
// contains filtered or unexported fields
}
CommandProjection is the folded, queryable image of known command state. It is the reducer over CommandMessage frames and CausalReceipt events.
Projection rules (lazily-spec § Command / RPC Message Plane):
- Terminal authority is the causal receipt, not the event or the transport.
- Generation guards: events/receipts outside the command's current authority generation are ignored and retained only as audit data.
- Idempotency: a replayed submit/event/receipt (same id) is a no-op.
- Cancel before terminal only: a cancel terminally rejects a non-terminal command; a cancel after applied is ignored.
- Terminal conflict fails closed: two terminal receipts at the same generation with different outcomes is a conflict; consumers fail closed rather than pick a winner.
- Reconnect equivalence: folding a CommandProjection image is equivalent to folding the events and receipts it summarizes.
Not safe for concurrent use.
func NewCommandProjection ¶ added in v0.2.0
func NewCommandProjection() *CommandProjection
NewCommandProjection creates an empty projection.
func (*CommandProjection) ApplyMessage ¶ added in v0.2.0
func (p *CommandProjection) ApplyMessage(message CommandMessage) CommandApplyStatus
ApplyMessage dispatches a CommandMessage frame to the matching fold method.
func (*CommandProjection) ApplyProjection ¶ added in v0.2.0
func (p *CommandProjection) ApplyProjection(img CommandProjectionImage) CommandApplyStatus
ApplyProjection folds a reconnect resync image. Equivalent to folding the events and receipts it summarizes.
func (*CommandProjection) Cancel ¶ added in v0.2.0
func (p *CommandProjection) Cancel(c CommandCancel) CommandApplyStatus
Cancel records a cancel request. A cancel is non-terminal by itself; the rejected receipt makes it terminal. Stale-generation and duplicate cancel causation_ids are no-ops.
func (*CommandProjection) Entry ¶ added in v0.2.0
func (p *CommandProjection) Entry(commandId string) (CommandProjectionEntry, bool)
Entry returns the folded entry for commandId, or false if unknown.
func (*CommandProjection) Event ¶ added in v0.2.0
func (p *CommandProjection) Event(e CommandEvent) CommandApplyStatus
Event folds one progress/detail event. Stale-generation and duplicate event_ids are no-ops. Status advances monotonically (never backward, never on a terminal command).
func (*CommandProjection) Generation ¶ added in v0.2.0
func (p *CommandProjection) Generation() int64
Generation is the highest authority generation observed so far.
func (*CommandProjection) HasConflict ¶ added in v0.2.0
func (p *CommandProjection) HasConflict(commandId string) bool
HasConflict reports whether commandId has a terminal conflict.
func (*CommandProjection) ObserveReceipt ¶ added in v0.2.0
func (p *CommandProjection) ObserveReceipt(r CausalReceipt) CommandApplyStatus
ObserveReceipt folds a causal receipt. This is the sole terminal authority: a terminal receipt (applied/rejected) flips the command to terminal. A differing terminal outcome at the same generation is a conflict (fail-closed).
func (*CommandProjection) Submit ¶ added in v0.2.0
func (p *CommandProjection) Submit(s CommandSubmit) CommandApplyStatus
Submit admits a command. A duplicate command_id is an idempotent no-op.
func (*CommandProjection) TerminalFor ¶ added in v0.2.0
func (p *CommandProjection) TerminalFor(commandId string) (CommandProjectionEntry, bool)
TerminalFor returns the terminal entry for commandId, or false if the command is unknown or not yet terminal.
func (*CommandProjection) ToImage ¶ added in v0.2.0
func (p *CommandProjection) ToImage() CommandProjectionImage
ToImage returns a snapshot of the projection sorted by command_id.
type CommandProjectionEntry ¶ added in v0.2.0
type CommandProjectionEntry struct {
CommandId string `json:"command_id"`
Status CommandStatus `json:"status"`
Terminal bool `json:"terminal"`
Generation int64 `json:"generation"`
Reason *string `json:"reason"`
TerminalReceiptId *string `json:"terminal_receipt_id"`
LastEventId *string `json:"last_event_id"`
}
CommandProjectionEntry is the folded, queryable image of one command's state. Reason, TerminalReceiptId, and LastEventId are nullable wire fields: they marshal to JSON null when nil (the schema lists them as required), so they carry no `omitempty`.
func (*CommandProjectionEntry) UnmarshalJSON ¶ added in v0.2.0
func (e *CommandProjectionEntry) UnmarshalJSON(b []byte) error
UnmarshalJSON decodes an entry, validating the status enum.
type CommandProjectionImage ¶ added in v0.2.0
type CommandProjectionImage struct {
Generation int64 `json:"generation"`
Commands []CommandProjectionEntry `json:"commands"`
}
CommandProjectionImage is the resync snapshot: an authority generation plus the per-command folded entries.
func (CommandProjectionImage) MarshalJSON ¶ added in v0.2.0
func (i CommandProjectionImage) MarshalJSON() ([]byte, error)
MarshalJSON emits commands always as an array (never null).
type CommandRpcClient ¶ added in v0.2.0
type CommandRpcClient struct {
Projection *CommandProjection
// contains filtered or unexported fields
}
CommandRpcClient is the RPC facade over the command plane. It builds and sends CommandSubmit/CommandCancel frames, folds replies into its projection, and exposes a polled unary-call resolution that completes only on a terminal causal receipt.
func NewCommandRpcClient ¶ added in v0.2.0
func NewCommandRpcClient(transport CommandTransport) *CommandRpcClient
NewCommandRpcClient constructs an RPC client over the given transport.
func (*CommandRpcClient) Cancel ¶ added in v0.2.0
func (c *CommandRpcClient) Cancel(cancel CommandCancel)
Cancel builds and sends a CommandCancel and folds it into the projection.
func (*CommandRpcClient) IngestCommand ¶ added in v0.2.0
func (c *CommandRpcClient) IngestCommand(message CommandMessage) CommandApplyStatus
IngestCommand folds an inbound CommandMessage into the projection.
func (*CommandRpcClient) IngestReceipt ¶ added in v0.2.0
func (c *CommandRpcClient) IngestReceipt(receipt CausalReceipt) CommandApplyStatus
IngestReceipt folds an inbound causal receipt into the projection.
func (*CommandRpcClient) PollCall ¶ added in v0.2.0
func (c *CommandRpcClient) PollCall(commandId string) CallState
PollCall returns the current resolution state of a unary call. Resolves only when the command projection reaches a terminal causal receipt — a transport ACK, controller admission, or accepted/queued event never resolves it.
func (*CommandRpcClient) Submit ¶ added in v0.2.0
func (c *CommandRpcClient) Submit(s CommandSubmit) string
Submit builds and sends a CommandSubmit, folds it into the projection, and returns the command id.
type CommandStatus ¶ added in v0.2.0
type CommandStatus string
CommandStatus is the folded projection status. Submitted/Accepted/Running are non-terminal; Applied/Rejected/Cancelled/Superseded/TimedOut are terminal and backed by a terminal CausalReceipt.
const ( CommandStatusSubmitted CommandStatus = "submitted" CommandStatusAccepted CommandStatus = "accepted" CommandStatusRunning CommandStatus = "running" CommandStatusApplied CommandStatus = "applied" CommandStatusRejected CommandStatus = "rejected" CommandStatusCancelled CommandStatus = "cancelled" CommandStatusSuperseded CommandStatus = "superseded" CommandStatusTimedOut CommandStatus = "timed_out" )
type CommandStatusDuplicate ¶ added in v0.2.0
type CommandStatusDuplicate struct{}
CommandStatusDuplicate means the frame was an idempotent no-op (duplicate command_id / event_id / receipt_id / cancel causation_id).
func (CommandStatusDuplicate) Kind ¶ added in v0.2.0
func (CommandStatusDuplicate) Kind() CommandApplyStatusKind
Kind returns the result variant tag.
type CommandStatusRecorded ¶ added in v0.2.0
type CommandStatusRecorded struct{}
CommandStatusRecorded means the frame updated the projection.
func (CommandStatusRecorded) Kind ¶ added in v0.2.0
func (CommandStatusRecorded) Kind() CommandApplyStatusKind
Kind returns the result variant tag.
type CommandStatusStaleGeneration ¶ added in v0.2.0
CommandStatusStaleGeneration means the frame's generation did not match the command's current authority generation; the frame was ignored.
func (CommandStatusStaleGeneration) Kind ¶ added in v0.2.0
func (CommandStatusStaleGeneration) Kind() CommandApplyStatusKind
Kind returns the result variant tag.
type CommandStatusTerminalConflict ¶ added in v0.2.0
type CommandStatusTerminalConflict struct {
CommandId string
Existing CommandStatus
Incoming CommandStatus
}
CommandStatusTerminalConflict means a different terminal outcome already exists for this command_id (fail-closed).
func (CommandStatusTerminalConflict) Kind ¶ added in v0.2.0
func (CommandStatusTerminalConflict) Kind() CommandApplyStatusKind
Kind returns the result variant tag.
type CommandStatusUnknown ¶ added in v0.2.0
type CommandStatusUnknown struct{}
CommandStatusUnknown means the command_id was not in the projection.
func (CommandStatusUnknown) Kind ¶ added in v0.2.0
func (CommandStatusUnknown) Kind() CommandApplyStatusKind
Kind returns the result variant tag.
type CommandSubmit ¶ added in v0.2.0
type CommandSubmit struct {
CommandId string `json:"command_id"`
CausationId string `json:"causation_id"`
Source string `json:"source"`
Target string `json:"target"`
Namespace string `json:"namespace"`
Name string `json:"name"`
AuthorityGeneration int64 `json:"authority_generation"`
IdempotencyKey string `json:"idempotency_key"`
DeadlineMs int64 `json:"deadline_ms"`
Policy CommandPolicy `json:"policy"`
PayloadType string `json:"payload_type"`
PayloadHash string `json:"payload_hash"`
Payload IpcValue `json:"payload"`
RequiredFeatures []string `json:"required_features"`
}
CommandSubmit admits a command. Lazily owns the envelope (command_id, correlation, idempotency, generation, policy, payload framing); the namespace owns the payload body, which lazily never interprets.
func (CommandSubmit) MarshalJSON ¶ added in v0.2.0
func (s CommandSubmit) MarshalJSON() ([]byte, error)
MarshalJSON renders the canonical wire object with required_features always an array (never null).
func (*CommandSubmit) UnmarshalJSON ¶ added in v0.2.0
func (s *CommandSubmit) UnmarshalJSON(b []byte) error
UnmarshalJSON decodes a CommandSubmit, validating the dedupe policy and the payload's externally-tagged IpcValue form.
type CommandTransport ¶ added in v0.2.0
type CommandTransport interface {
Send(message CommandMessage)
}
CommandTransport is the outbound sink for command frames.
type CommandTransportFunc ¶ added in v0.2.0
type CommandTransportFunc func(message CommandMessage)
CommandTransportFunc adapts a function into a CommandTransport.
func (CommandTransportFunc) Send ¶ added in v0.2.0
func (f CommandTransportFunc) Send(m CommandMessage)
Send satisfies CommandTransport.
type Compute ¶ added in v0.21.0
type Compute struct {
// contains filtered or unexported fields
}
Compute is the per-recompute view handed to a value-threaded compute/effect closure. It carries the recomputing node id AS A VALUE (node), so a tracked read — Get(c, handle) — attributes the edge to that node by construction, never to ambient state. It is the sole tracking surface: reading a handle through the owning Context (or Compute.Untracked()) forms no edge.
Fortification, and its Go limits. lazily-rs makes the view non-escapable by construction — a lifetime binds it to the recompute and !Send stops it moving to another thread — so it is impossible to store and replay against the wrong node. Go has neither lifetimes nor a compile-time move check, so non-escapability is by convention, backed by a RUNTIME guard: each Compute is generation-stamped (gen) and marked dead (live=false) the instant its recompute returns. Any trackNode() on a dead or superseded Compute panics rather than silently registering an edge against a node that is no longer recomputing. That converts the rust compile-time guarantee into a fail-fast runtime one — the strongest fortification Go allows.
type ComputeOps ¶ added in v0.21.0
type ComputeOps interface {
// Batch runs fn inside a coalescing batch on the owning scope.
Batch(fn func())
// Untracked returns the untracked read surface (the owning *Context). A read
// through it — Get(c.Untracked(), handle) — forms no dependency edge. It is
// the sole, explicit escape from tracking, mirroring rs Compute::untracked.
Untracked() *Context
// contains filtered or unexported methods
}
ComputeOps is the compute-time operations subset shared by the two read surfaces (#lzcellkernel). It is the Go analogue of lazily-rs's `ComputeOps` trait, implemented by exactly two types:
- *Context — the owning scope, whose reads are UNTRACKED (trackNode is nil).
- *Compute — the per-recompute view handed to a compute/effect closure, whose reads register a dependency edge against the recomputing node.
Go methods cannot be generic, so the value-carrying operations of the rs trait (get/source/cell/computed/slot) are expressed as free generic functions that take a ComputeOps — Get(c, handle) for tracked reads, and the New*C constructors for building nodes. This interface carries only the non-generic operations plus the tracking identity itself; it mirrors the same split the async surface already uses (AsyncComputeContext + free TrackSource/TrackComputed).
There is deliberately no GetRc: Rc handles are a rust ownership device with no Go analogue (the runtime is garbage-collected), exactly as on the async side.
type Computed ¶ added in v0.21.0
Computed is a lazy, cached, dependency-tracking computation.
Get returns the cached value if present; otherwise it computes the value (tracking every Cell, Signal, or Computed read during computation as a dependency), caches it, and returns it. When any dependency changes, the cached value is invalidated and the next Get recomputes.
The cached value lives on the Computed itself (value/cached fields), not in a shared Context map — so a Get is a direct field read on the node you already hold, and read latency does not grow with the total number of nodes. The cache is three-state, which pull-time checking requires and a lone `cached bool` cannot express:
hasValue=false — no value has ever been computed.
hasValue=true, cached=false — a PREVIOUS value is still held, but it is
stale. The value is kept precisely so a
recompute can compare against it (the
equality guard) instead of blindly
cascading.
hasValue=true, cached=true — the value is current.
`cached` keeps its original meaning — "this value is current" — so Peek, cachedNow, Context.Size, and every collection layer built on them are unchanged. `hasValue` is the added state.
func NewComputed ¶ added in v0.21.0
func NewComputed[T comparable](ctx *Context, compute func(c *Compute) T) *Computed[T]
NewComputed creates a guarded Computed cell bound to ctx — the design's computed(f), guarded by default (§9.3). All computed cells are guarded: a recompute yielding a value equal (==) to the previous one suppresses the downstream cascade. This is the sole derived constructor now that the former Memo is removed — a computed cell IS the guarded form.
The `T comparable` bound is what the guard needs (Go ==). For a value type that is not comparable, drop to NewSlot, the bound-free storage-sense primitive (T any, no guard) — the escape hatch that mirrors lazily-rs's slot(). The guard is a pull-time check (see Computed.refresh), so it recomputes nothing during invalidation.
func NewComputedRippleWhen ¶ added in v0.21.0
func NewComputedRippleWhen[T any](ctx *Context, compute func(c *Compute) T, changed func(old, next T) bool) *Computed[T]
NewComputedRippleWhen creates a guarded Computed cell with an explicit change predicate (#lzcellkernel). Like NewComputed, but downstream propagation is gated by changed(old, new) instead of the value's natural == : changed returns true to PROPAGATE (ripple) the recompute to dependents, and false to SUPPRESS it (treat it as "no meaningful change"). So NewComputed(f) is exactly NewComputedRippleWhen(f, func(o, n T) bool { return o != n }), and an unguarded NewSlot(f) is NewComputedRippleWhen(f, func(_, _ T) bool { return true }) (always propagate).
Because the predicate is supplied, T carries no comparable bound: this is the guarded escape for non-comparable derived values — e.g. a []string / map computed guarded via func(o, n []string) bool { return !slices.Equal(o, n) }. It also serves a custom significance policy: dedup a large value by a version/hash field, epsilon float compare, hysteresis, a monotonic gate, or "propagate every N" when the counter lives in the value.
The value is ALWAYS computed (the predicate needs new); changed gates only the downstream cascade, not the computation. changed MUST be a pure function of (old, new) — reading value-carried state (version/counter/sequence) is fine and stays deterministic; capturing external mutable state is not (it keys off recompute/read frequency under laziness and breaks determinism).
The engine guards on equality (equal => suppress), so this installs equals = !changed(old, new).
func NewNamedComputedRippleWhen ¶ added in v0.21.0
func NewNamedComputedRippleWhen[T any](ctx *Context, name string, compute func(c *Compute) T, changed func(old, next T) bool) *Computed[T]
NewNamedComputedRippleWhen is NewComputedRippleWhen with a debug name.
func NewNamedSlot ¶
NewNamedSlot creates a lazy slot with a debug name.
func NewSlot ¶
NewSlot creates a lazy slot bound to ctx. Its closure receives the per-recompute Compute view and reads its dependencies via Get(c, handle) — the value-threaded tracking surface (#lzcellkernel). No ambient frame is pushed, so Compute.Untracked() is genuinely untracked.
func (*Computed[T]) Dispose ¶ added in v0.21.0
func (s *Computed[T]) Dispose()
Dispose tears down this slot: detaches both edge directions, drops the cached value, and dirties the surviving dependent cone. Idempotent.
Callers must ensure nothing still reads the slot in a live compute. A reader that still names it errors on its next recompute — the same contract as Effect.Dispose and lazily-rs's dispose_slot.
func (*Computed[T]) DisposeNode ¶ added in v0.21.0
func (m *Computed[T]) DisposeNode()
DisposeNode tears down this memoized slot. Same contract as Computed.Dispose.
func (*Computed[T]) Eager ¶ added in v0.21.0
Eager makes this Computed eager and returns the same handle (design §9.3.1).
Eager is a state a Computed is in, not a separate kind: Eager attaches a puller Effect that reads the computed now — materializing its value and its dependency edges immediately — and again after every invalidation, from inside the invalidating write's effect flush. Because the puller is an ordinary Effect and effects are scheduled rather than inline, N invalidations inside a Batch coalesce into a single scheduled pull at the flush: the value re-materializes once at batch exit, not once per write (#lzsignaleager clause 3). The former Signal built the same slot+puller pair as a bespoke type that could, and in lazily-go once did, weld a per-write puller into invalidation. Composing it out of computed().Eager() makes that bug structurally unwritable.
Eager is idempotent — the eager bit short-circuits a second call, so f.Eager().Eager() attaches exactly one puller. It returns f itself (mutated), not a driver handle, so the caller holds the thing it reads via ordinary Get.
func (*Computed[T]) Get ¶ added in v0.21.0
func (s *Computed[T]) Get() T
Get reads (and caches if needed) the value.
Panics with a *DisposedError if this slot has been disposed. Use TryGet for the checked form; see disposal.go for why a read of a torn-down node is a panic rather than a returned error.
func (*Computed[T]) IsEager ¶ added in v0.21.0
IsEager reports whether this Computed is eager (has a live puller).
func (*Computed[T]) Lazy ¶ added in v0.21.0
func (s *Computed[T]) Lazy()
Lazy reverts an eager Computed to lazy: it disposes the puller Effect and clears the eager bit and side-table entry. The value remains readable and recomputes on demand. Idempotent; a no-op on a lazy computed. This is the reverse transition that replaces the old dispose_signal.
func (*Computed[T]) Peek ¶ added in v0.21.0
Peek returns the cached value without recomputing, and whether it was cached.
func (*Computed[T]) TryGet ¶ added in v0.21.0
TryGet reads the slot, returning a *DisposedError instead of panicking when this slot — or any node it reads while recomputing — has been disposed.
This is the boundary form: use it where a read may race a teardown. It recovers the *DisposedError panic and returns it. Dependency tracking is value-threaded through a per-recompute Compute view (there is no ambient stack to unwind), so a read that panics out of a half-finished compute strands no frame; the superseded view is simply discarded.
type ComputedMap ¶ added in v0.22.0
type ComputedMap[K comparable, V comparable] struct { *ReactiveMap[K, V, *Computed[V]] }
ComputedMap is the derived-slot specialization of ReactiveMap: every entry is a derived *Slot[V]. GetOrInsertWith mints a slot on first access (lazy materialization); MaterializeAll pre-mints the keyset (eager). A slot's value is derived, so ComputedMap has no Set.
func NewComputedMap ¶ added in v0.22.0
func NewComputedMap[K comparable, V comparable](ctx *Context) *ComputedMap[K, V]
NewComputedMap creates an empty derived-slot map bound to ctx.
func NewSlotMap
deprecated
added in
v0.7.0
func NewSlotMap[K comparable, V comparable](ctx *Context) *ComputedMap[K, V]
NewSlotMap creates an empty derived-slot map bound to ctx.
Deprecated: renamed to NewComputedMap.
func (*ComputedMap[K, V]) MaterializeAll ¶ added in v0.22.0
func (m *ComputedMap[K, V]) MaterializeAll(c ComputeOps, keys []K, factory func(K) V)
MaterializeAll eagerly pre-mints a derived slot for every key via factory, up front. Observationally identical to minting each key lazily on first read (GetOrInsertWith) — it only changes when the nodes are allocated.
func (*ComputedMap[K, V]) Slot ¶ added in v0.22.0
func (m *ComputedMap[K, V]) Slot(key K) *Computed[V]
Slot returns the derived slot handle for key (nil if not materialized). Non-reactive.
type Configuration ¶
type Configuration struct {
// contains filtered or unexported fields
}
Configuration is the active configuration: the set of active states (atomic leaves plus all active ancestors). It holds a sorted, unique snapshot.
func (Configuration) Contains ¶
func (c Configuration) Contains(id string) bool
Contains reports whether id is in the active configuration.
func (Configuration) IsEmpty ¶
func (c Configuration) IsEmpty() bool
IsEmpty reports whether the configuration is empty.
func (Configuration) ToSet ¶
func (c Configuration) ToSet() []string
ToSet returns a sorted snapshot of the active states.
type Context ¶
type Context struct {
// contains filtered or unexported fields
}
Context is a reactive scope: batch/effect scheduling plus the node registry. Dependency tracking is value-threaded through the per-recompute Compute view (there is no ambient recompute stack); a read attributes to the recomputing node only when it goes through that view (Get(c, handle)). Cached slot values are stored on the nodes themselves, not here. All Slots, Cells, and Signals that should react to each other must be created with (and thus share) the same Context.
Context is not safe for concurrent use. Wrap it with ThreadSafeContext for lock-backed concurrency, or drive it from a single goroutine via AsyncContext.
func (*Context) Batch ¶
func (c *Context) Batch(fn func())
Batch runs fn inside a batch. Cell writes inside the batch defer their invalidation cascades until the outermost batch exits, at which point a single coalesced cascade fires and pending Effects flush once. Re-entrant.
func (*Context) Clear ¶
func (c *Context) Clear()
Clear drops every cached slot value. Dependency edges are re-established lazily as slots are read again. Cell values are unaffected.
func (*Context) DependencyCount ¶ added in v0.20.0
DependencyCount reports how many nodes n currently depends on — the size of its forward edge set (#lzspecedgeindex).
Counterpart to DependentCount: disposal must detach both directions, and a binding that detaches only one leaves a dangling half-edge visible here. Returns 0 for a disposed node and for *Cell, which is a pure source.
func (*Context) DependentCount ¶ added in v0.20.0
DependentCount reports how many nodes currently depend on n — the size of its reverse edge set (#lzspecedgeindex).
This is the observable the disposal contract is written against: a subscribe/unsubscribe cycle that disposes what it creates must leave this at its starting value no matter how many cycles run. A binding that leaks shows total-ever-created here instead of live-subscriber count.
Returns 0 for a disposed node, and for *Effect, which is a pure sink.
Note that this counts *live* edges. Invalidation does not consume them: the cascade is a non-consuming mark-frontier walk (core.go, markCone), so a degree read immediately after a write and before the dependents are pulled reports the same edges as before the write. An edge changes only when a node recomputes and re-tracks, or when disposal detaches it.
func (*Context) IsBatching ¶
IsBatching reports whether a Batch is currently active.
func (*Context) IsDisposed ¶ added in v0.20.0
IsDisposed reports whether n has been torn down.
func (*Context) Scope ¶ added in v0.20.0
func (c *Context) Scope() *TeardownScope
Scope opens a teardown scope. Nodes added with Own are disposed by Close.
func (*Context) Untracked ¶ added in v0.21.0
Untracked on *Context returns itself — the context is already the untracked surface, so this is idempotent and lets *Context satisfy ComputeOps uniformly.
func (*Context) WithScope ¶ added in v0.20.0
func (c *Context) WithScope(fn func(s *TeardownScope))
WithScope runs fn with a fresh teardown scope and closes it on return, including on panic — the callback form of Scope/Close.
type ConvergedEntry ¶
ConvergedEntry is the converged state of a single node: its id, the winning op's optional wire-stable key (the bare NodeKey path string, nil when the node is addressed only by id), and the winning op's state payload.
Mirrors Dart `ConvergedEntry`; Key is the `String?` the Dart plane tracks in `_nodeToKey`, and State is the winning op's IpcValue (Dart stores the already-wire `IpcValue.toWire()` result; ToWire / MarshalJSON here produce the identical wire shape via the IpcValue codec).
func (ConvergedEntry) MarshalJSON ¶
func (e ConvergedEntry) MarshalJSON() ([]byte, error)
MarshalJSON emits { node[, key], state }, omitting key when nil. The State is serialized through the IpcValue codec (e.g. {"Inline":[66]}).
func (ConvergedEntry) String ¶
func (e ConvergedEntry) String() string
func (ConvergedEntry) ToWire ¶
func (e ConvergedEntry) ToWire() map[string]any
ToWire returns the { node, state[, key] } wire map, omitting key when nil (mirrors Dart `ConvergedEntry.toWire`).
type CrdtOp ¶
CrdtOp is one CRDT cell op on the wire (state-based / CvRDT): the converged State for Node, tagged with the WireStamp that produced it and an optional wire-stable NodeKey.
Wire note (mirrors lazily-rs derived serde and every sibling): Key is ALWAYS present in the wire object (null when unset), unlike NodeSnapshot / DeltaOpNodeAdd which omit it. The decoder also accepts an absent field.
func NewKeyedCrdtOp ¶
NewKeyedCrdtOp constructs an op carrying a wire-stable NodeKey.
func (CrdtOp) MarshalJSON ¶
func (CrdtOp) TargetReadable ¶
func (o CrdtOp) TargetReadable(permissions *PeerPermissions, peer PeerId) bool
TargetReadable reports whether peer may read Node. Filtered ops are omitted (not redacted) from a permission-filtered CrdtSync.
func (*CrdtOp) UnmarshalJSON ¶
type CrdtPlane ¶
type CrdtPlane struct {
// contains filtered or unexported fields
}
CrdtPlane is the CRDT plane: an Hlc + a StampFrontier + the live membership set.
This is the runtime hub a `merge: crdt` root cell drives. Local edits (Tick) and remote observations (ObserveRemote) both fold into the frontier; the StabilityWatermark is what the tombstone-GC contract consumes.
func NewCrdtPlane ¶
NewCrdtPlane creates a plane for the given self peer id.
func (*CrdtPlane) Clock ¶
Clock returns the HLC (wall time is caller-supplied via Tick/ObserveRemote).
func (*CrdtPlane) Frontier ¶
func (p *CrdtPlane) Frontier() *StampFrontier
Frontier returns the stamp frontier (highest observed stamp per peer).
func (*CrdtPlane) IsCollectable ¶
IsCollectable reports whether stamp is collectable: its delete stamp is <= the stability watermark (so every replica has provably observed it).
func (*CrdtPlane) Membership ¶
Membership returns the live membership set (peers this plane has observed, including self), sorted by peer id for deterministic iteration.
func (*CrdtPlane) ObserveRemote ¶
ObserveRemote observes a remote stamp: expand membership, fold into the frontier, and advance the HLC. Returns the new local stamp.
func (*CrdtPlane) StabilityWatermark ¶
StabilityWatermark is the causal-stability watermark: min over membership of the frontier. The second return is false until every member has been observed.
type CrdtPlaneRuntime ¶
type CrdtPlaneRuntime struct {
// contains filtered or unexported fields
}
CrdtPlaneRuntime is a state-based CRDT plane runtime with anti-entropy. A single owner goroutine owns the plane state; public methods serialize their work over an inbound command channel (blocking until the owner replies), and converged entries are fanned out over an optional outbound stream (ConvergedStream). Call Close (or cancel the context passed to NewCrdtPlaneRuntimeWithContext) to stop the owner goroutine; no goroutine is leaked.
func NewCrdtPlaneRuntime ¶
func NewCrdtPlaneRuntime(peer PeerId) *CrdtPlaneRuntime
NewCrdtPlaneRuntime creates a runtime for the given local peer id and starts its owner goroutine. Call Close to release it.
func NewCrdtPlaneRuntimeWithContext ¶
func NewCrdtPlaneRuntimeWithContext(ctx context.Context, peer PeerId) *CrdtPlaneRuntime
NewCrdtPlaneRuntimeWithContext creates a runtime that also stops when ctx is cancelled (in addition to Close). Either signal cleanly tears the owner goroutine down.
func (*CrdtPlaneRuntime) Close ¶
func (r *CrdtPlaneRuntime) Close()
Close stops the owner goroutine and closes the converged stream (if any). It is idempotent and safe to call from any goroutine.
func (*CrdtPlaneRuntime) Converged ¶
func (r *CrdtPlaneRuntime) Converged() []ConvergedEntry
Converged returns the full converged state: one entry per node (ascending). Mirrors Dart `converged`.
func (*CrdtPlaneRuntime) ConvergedStream ¶
func (r *CrdtPlaneRuntime) ConvergedStream() <-chan ConvergedEntry
ConvergedStream returns the outbound channel on which converged entries are emitted as ops are applied (one entry per node whose winning op changed in each ingest, ascending). Only one subscriber is supported — the most recent call wins. The channel is closed when the runtime closes. If the runtime is already closed, a closed channel is returned.
func (*CrdtPlaneRuntime) FamilyKeys ¶ added in v0.6.0
func (r *CrdtPlaneRuntime) FamilyKeys(namespace string) []NodeKey
FamilyKeys returns the materialized keys of family namespace, in first-materialization order.
func (*CrdtPlaneRuntime) FamilySetLww ¶ added in v0.6.0
func (r *CrdtPlaneRuntime) FamilySetLww(namespace, keySuffix string, state IpcValue, nowMicros int64) (CrdtOp, bool)
FamilySetLww inserts or updates the local LWW family entry namespace/<keySuffix> to state at nowMicros, materializing it (and bumping the membership epoch) on first insert. Returns the broadcast op and true, or a zero op and false if the key is invalid or the write was stamp-dominated. The converged entry is fanned out on ConvergedStream.
func (*CrdtPlaneRuntime) FamilyValueLww ¶ added in v0.6.0
func (r *CrdtPlaneRuntime) FamilyValueLww(namespace, keySuffix string) (IpcValue, bool)
FamilyValueLww returns the current converged state of family entry namespace/<keySuffix>, and whether the key is present.
func (*CrdtPlaneRuntime) FrontierEntries ¶
func (r *CrdtPlaneRuntime) FrontierEntries() []StampFrontierEntry
FrontierEntries returns the per-peer frontier as wire entries (ascending by peer). Mirrors Dart `frontierEntries` (which returns MapEntry pairs; the Go wire type StampFrontierEntry carries the same (peer, stamp) pair).
func (*CrdtPlaneRuntime) Ingest ¶
func (r *CrdtPlaneRuntime) Ingest(sync CrdtSync) int
Ingest folds a CrdtSync frame (observe frontier, then apply ops) and returns the number of newly applied ops. Mirrors Dart `ingest`.
func (*CrdtPlaneRuntime) IngestOps ¶
func (r *CrdtPlaneRuntime) IngestOps(ops []CrdtOp) int
IngestOps applies a batch of ops and returns the number of newly applied ops (0 = idempotent re-delivery). Converged entries for changed nodes are fanned out on ConvergedStream. Mirrors Dart `ingestOps` (whose unused `nowMicros` parameter is omitted).
func (*CrdtPlaneRuntime) IsEmpty ¶
func (r *CrdtPlaneRuntime) IsEmpty() bool
IsEmpty reports whether no node has converged yet. Mirrors Dart `isEmpty`.
func (*CrdtPlaneRuntime) Membership ¶
func (r *CrdtPlaneRuntime) Membership() []PeerId
Membership returns the known peer ids (ascending). Mirrors Dart `membership`.
func (*CrdtPlaneRuntime) MembershipEpoch ¶ added in v0.6.0
func (r *CrdtPlaneRuntime) MembershipEpoch() uint64
MembershipEpoch returns the reactive membership signal (#lzfamilysync): a derived aggregate over a family depends on it so a remote-materialized key forces a recompute. Bumped whenever a family entry materializes.
func (*CrdtPlaneRuntime) Nodes ¶
func (r *CrdtPlaneRuntime) Nodes() []NodeId
Nodes returns all winning node ids ascending. Mirrors Dart `nodes`.
func (*CrdtPlaneRuntime) Ops ¶
func (r *CrdtPlaneRuntime) Ops() []CrdtOp
Ops returns a copy of the full op log in insertion order. Mirrors Dart `ops`.
func (*CrdtPlaneRuntime) Peer ¶
func (r *CrdtPlaneRuntime) Peer() PeerId
Peer returns the local peer id.
func (*CrdtPlaneRuntime) RegisterFamilyLww ¶ added in v0.6.0
func (r *CrdtPlaneRuntime) RegisterFamilyLww(namespace string)
RegisterFamilyLww registers a last-writer-wins family under namespace so an inbound keyed op for an unregistered entry of this family materializes on ingest instead of being dropped. Replicas sharing a session must register the same namespace.
func (*CrdtPlaneRuntime) Size ¶
func (r *CrdtPlaneRuntime) Size() int
Size returns the number of converged nodes. Mirrors Dart `size`.
type CrdtSync ¶
type CrdtSync struct {
Frontier []StampFrontierEntry
Ops []CrdtOp
}
CrdtSync is a CRDT anti-entropy sync frame (the multi-writer plane). The sender advertises its per-peer stamp Frontier (the highest WireStamp observed from each peer) and ships a batch of Ops. The exchange is bounded, idempotent, and resumable; re-sending a frame the receiver already has is a no-op.
func (CrdtSync) FilterReadable ¶
func (c CrdtSync) FilterReadable(permissions *PeerPermissions, peer PeerId) CrdtSync
FilterReadable returns a peer-specific frame that omits ops for non-readable nodes entirely (omission, not redaction — mirroring Delta.FilterReadable). The Frontier advertisement is retained in full: it names peers and stamps, not node content, and the receiver needs the whole frontier to compute a sound causal-stability watermark.
func (CrdtSync) MarshalJSON ¶
func (*CrdtSync) UnmarshalJSON ¶
type CrdtTree ¶ added in v0.13.0
type CrdtTree[V any, D any, T any] interface { VersionVector() V DeltaSince(V) D ApplyDelta(D) bool Text() string Value() T MergeFrom(CrdtTree[V, D, T]) bool }
CrdtTree is the lossless mergeable document contract (#lzcrdttree).
Snapshot and incremental replication use the same identity-preserving delta: DeltaSince(empty frontier) is the whole-state snapshot. MergeFrom and ApplyDelta must therefore be commutative, associative, and idempotent.
type CronCell ¶ added in v0.15.0
type CronCell struct {
// contains filtered or unexported fields
}
CronCell is a reactive cron source: same reactive contract as IntervalCell.
func NewCronCell ¶ added in v0.15.0
NewCronCell creates a reactive cron source.
type CronCore ¶ added in v0.15.0
type CronCore struct {
// contains filtered or unexported fields
}
CronCore is a pattern-periodic compute core: a tick m >= 1 fires iff m mod cycle is in offsets. The match count in (cursor, now] is computed arithmetically, so a large now jump is O(offsets).
func NewCronCore ¶ added in v0.15.0
NewCronCore creates a cron core. offsets are reduced mod cycle, sorted, and deduped; cycle is clamped to >=1; empty offsets means the source never fires.
type DeadlineCell ¶ added in v0.15.0
type DeadlineCell[T any] struct { // contains filtered or unexported fields }
DeadlineCell is a reactive value + deadline: flips Live(v) -> Expired(v) at the deadline, preserving the value; the state reader invalidates only on the expiry edge.
func NewDeadlineCell ¶ added in v0.15.0
func NewDeadlineCell[T any](ctx *Context, value T, deadline uint64) *DeadlineCell[T]
NewDeadlineCell creates a reactive value + deadline pair.
func (*DeadlineCell[T]) ExpiredCell ¶ added in v0.15.0
func (d *DeadlineCell[T]) ExpiredCell() *Source[bool]
ExpiredCell returns the backing expiry cell.
func (*DeadlineCell[T]) IsExpired ¶ added in v0.15.0
func (d *DeadlineCell[T]) IsExpired() bool
IsExpired reports whether the deadline has passed (reactive read).
func (*DeadlineCell[T]) NextFire ¶ added in v0.15.0
func (d *DeadlineCell[T]) NextFire() (uint64, bool)
NextFire reports the deadline, or ok=false once expired.
func (*DeadlineCell[T]) State ¶ added in v0.15.0
func (d *DeadlineCell[T]) State() Deadlined[T]
State returns the current state, preserving the value (reactive read).
func (*DeadlineCell[T]) Tick ¶ added in v0.15.0
func (d *DeadlineCell[T]) Tick(now uint64) bool
Tick advances to logical time now; returns the expiry edge.
type DeadlineCore ¶ added in v0.15.0
type DeadlineCore struct {
// contains filtered or unexported fields
}
DeadlineCore is a deadline compute core (bytes-eligible): a TimerCore over the deadline. The value lives in the reactive cell.
func NewDeadlineCore ¶ added in v0.15.0
func NewDeadlineCore(deadline uint64) *DeadlineCore
NewDeadlineCore creates a deadline core expiring at deadline.
func (*DeadlineCore) IsExpired ¶ added in v0.15.0
func (d *DeadlineCore) IsExpired() bool
IsExpired reports whether the deadline has passed.
func (*DeadlineCore) NextFire ¶ added in v0.15.0
func (d *DeadlineCore) NextFire() (uint64, bool)
NextFire reports the deadline, or ok=false once expired.
func (*DeadlineCore) Tick ¶ added in v0.15.0
func (d *DeadlineCore) Tick(now uint64) bool
Tick advances to now; returns the expiry edge.
type Deadlined ¶ added in v0.15.0
type Deadlined[T any] struct { // contains filtered or unexported fields }
Deadlined pairs a value with a liveness state: Live until its deadline, then Expired — the value is preserved across the flip.
type DebounceCell ¶ added in v0.15.0
type DebounceCell[T comparable] struct { // contains filtered or unexported fields }
DebounceCell is the reactive debounce over any comparable-valued source.
func NewDebounceCell ¶ added in v0.15.0
func NewDebounceCell[T comparable](ctx *Context, quiet uint64) *DebounceCell[T]
NewDebounceCell builds a reactive debounce bound to ctx.
func (*DebounceCell[T]) Input ¶ added in v0.15.0
func (c *DebounceCell[T]) Input(now uint64, v T)
Input buffers an input; does not emit.
func (*DebounceCell[T]) Output ¶ added in v0.15.0
func (c *DebounceCell[T]) Output() Opt[T]
Output returns the last emitted value (subscribes the current computation).
func (*DebounceCell[T]) OutputCell ¶ added in v0.15.0
func (c *DebounceCell[T]) OutputCell() *Source[Opt[T]]
OutputCell exposes the reader cell for invalidation observation.
func (*DebounceCell[T]) Tick ¶ added in v0.15.0
func (c *DebounceCell[T]) Tick(now uint64) Opt[T]
Tick advances the clock and returns the emitted value (if any), projecting it onto the output reader.
type DebounceCore ¶ added in v0.15.0
type DebounceCore[T comparable] struct { // contains filtered or unexported fields }
DebounceCore coalesces inputs (KeepLatest) and emits the latest value only after `quiet` ticks with no new input — every input resets the deadline.
func NewDebounceCore ¶ added in v0.15.0
func NewDebounceCore[T comparable](quiet uint64) *DebounceCore[T]
NewDebounceCore builds a debounce core with the given quiet period.
func (*DebounceCore[T]) Input ¶ added in v0.15.0
func (d *DebounceCore[T]) Input(now uint64, v T)
Input records an input; resets the quiet deadline to now + quiet.
func (*DebounceCore[T]) Tick ¶ added in v0.15.0
func (d *DebounceCore[T]) Tick(now uint64) Opt[T]
Tick advances; emits the latest value once the quiet period has elapsed.
type DedupePolicy ¶ added in v0.2.0
type DedupePolicy string
DedupePolicy is how the admitter collapses concurrent/duplicate submits.
const ( // DedupePolicyNone performs no dedupe. DedupePolicyNone DedupePolicy = "none" // DedupePolicySameIdempotencyKey collapses by idempotency_key. DedupePolicySameIdempotencyKey DedupePolicy = "same_idempotency_key" // DedupePolicySameCommandId collapses by command_id. DedupePolicySameCommandId DedupePolicy = "same_command_id" )
type Delta ¶
Delta is an incremental change set.
func DeltaNext ¶
DeltaNext builds the next sequential delta after baseEpoch carrying ops.
lean theorem `nextDelta_epoch`: the returned Epoch is always baseEpoch + 1.
func (Delta) ApplyStatus ¶
func (d Delta) ApplyStatus(lastEpoch Epoch) DeltaApplyStatus
ApplyStatus applies iff sequential, otherwise fails closed (lean `applyDelta`).
func (Delta) FilterReadable ¶
func (d Delta) FilterReadable(permissions *PeerPermissions, peer PeerId) Delta
FilterReadable drops ops whose target node(s) are unreadable by peer.
func (Delta) IsNextAfter ¶
IsNextAfter reports whether this delta continues immediately after lastEpoch (lean `isSequentialAfter`).
func (Delta) MarshalJSON ¶
func (Delta) Span ¶ added in v0.8.0
Span returns the number of epochs an applied Delta advances (epoch - base_epoch); 1 for an ordinary delta, > 1 for a coalesced multi-epoch flush.
func (*Delta) UnmarshalJSON ¶
type DeltaApplyStatus ¶
type DeltaApplyStatus interface {
IsApply() bool
IsResyncRequired() bool
// contains filtered or unexported methods
}
DeltaApplyStatus is the outcome of attempting to apply a Delta.
type DeltaApplyStatusApply ¶
type DeltaApplyStatusApply struct {
NewEpoch Epoch
}
DeltaApplyStatusApply means the delta was sequential and may be applied; the new epoch is NewEpoch.
func (DeltaApplyStatusApply) IsApply ¶
func (DeltaApplyStatusApply) IsApply() bool
func (DeltaApplyStatusApply) IsResyncRequired ¶
func (DeltaApplyStatusApply) IsResyncRequired() bool
type DeltaApplyStatusResyncRequired ¶
DeltaApplyStatusResyncRequired means a gap, reorder, or sender restart was detected; request a fresh snapshot.
func (DeltaApplyStatusResyncRequired) IsApply ¶
func (DeltaApplyStatusResyncRequired) IsApply() bool
func (DeltaApplyStatusResyncRequired) IsResyncRequired ¶
func (DeltaApplyStatusResyncRequired) IsResyncRequired() bool
type DeltaOp ¶
type DeltaOp interface {
MarshalJSON() ([]byte, error)
// TargetReadable reports whether peer may read every node this op names. Ops
// targeting an unreadable node are omitted from a permission-filtered delta.
TargetReadable(permissions *PeerPermissions, peer PeerId) bool
// contains filtered or unexported methods
}
DeltaOp is one incremental operation in a Delta. All variants are externally tagged; DeltaOpNodeAdd carries the optional wire-stable NodeKey.
func CellSetOps ¶
CellSetOps is lean `cellSetOps` + theorems `equal_cell_set_is_silent` / `changed_cell_set_emits_cell_set`: the PartialEq cell guard. An equal write emits no op; a changed write emits exactly one DeltaOpCellSet.
func DownstreamInvalidations ¶
DownstreamInvalidations is lean `downstreamInvalidations`: each downstream node becomes a DeltaOpInvalidate, preserving order.
func MemoOps ¶
MemoOps is lean `memoOps` + theorems `equal_memo_suppresses_downstream` / `changed_memo_publishes_then_invalidates`: memo equality suppression. An equal recompute is silent; a changed recompute publishes a DeltaOpSlotValue then invalidates the downstream frontier.
type DeltaOpCellSet ¶
DeltaOpCellSet is a changed-value cell write, PartialEq-guarded at the source.
func (DeltaOpCellSet) MarshalJSON ¶
func (o DeltaOpCellSet) MarshalJSON() ([]byte, error)
func (DeltaOpCellSet) TargetReadable ¶
func (o DeltaOpCellSet) TargetReadable(p *PeerPermissions, peer PeerId) bool
type DeltaOpEdgeAdd ¶
DeltaOpEdgeAdd adds a new dependency edge.
func (DeltaOpEdgeAdd) MarshalJSON ¶
func (o DeltaOpEdgeAdd) MarshalJSON() ([]byte, error)
func (DeltaOpEdgeAdd) TargetReadable ¶
func (o DeltaOpEdgeAdd) TargetReadable(p *PeerPermissions, peer PeerId) bool
type DeltaOpEdgeRemove ¶
DeltaOpEdgeRemove removes a dependency edge.
func (DeltaOpEdgeRemove) MarshalJSON ¶
func (o DeltaOpEdgeRemove) MarshalJSON() ([]byte, error)
func (DeltaOpEdgeRemove) TargetReadable ¶
func (o DeltaOpEdgeRemove) TargetReadable(p *PeerPermissions, peer PeerId) bool
type DeltaOpInvalidate ¶
type DeltaOpInvalidate struct {
Node NodeId
}
DeltaOpInvalidate marks a node dirtied but not yet recomputed (lazy).
func (DeltaOpInvalidate) MarshalJSON ¶
func (o DeltaOpInvalidate) MarshalJSON() ([]byte, error)
func (DeltaOpInvalidate) TargetReadable ¶
func (o DeltaOpInvalidate) TargetReadable(p *PeerPermissions, peer PeerId) bool
type DeltaOpNodeAdd ¶
DeltaOpNodeAdd adds a new node (optional wire-stable Key, omitted when nil).
func (DeltaOpNodeAdd) MarshalJSON ¶
func (o DeltaOpNodeAdd) MarshalJSON() ([]byte, error)
func (DeltaOpNodeAdd) TargetReadable ¶
func (o DeltaOpNodeAdd) TargetReadable(p *PeerPermissions, peer PeerId) bool
type DeltaOpNodeRemove ¶
type DeltaOpNodeRemove struct {
Node NodeId
}
DeltaOpNodeRemove removes a node (free-list reuse: Remove then Add).
func (DeltaOpNodeRemove) MarshalJSON ¶
func (o DeltaOpNodeRemove) MarshalJSON() ([]byte, error)
func (DeltaOpNodeRemove) TargetReadable ¶
func (o DeltaOpNodeRemove) TargetReadable(p *PeerPermissions, peer PeerId) bool
type DeltaOpSlotValue ¶
DeltaOpSlotValue signals that a recompute published a new value.
func (DeltaOpSlotValue) MarshalJSON ¶
func (o DeltaOpSlotValue) MarshalJSON() ([]byte, error)
func (DeltaOpSlotValue) TargetReadable ¶
func (o DeltaOpSlotValue) TargetReadable(p *PeerPermissions, peer PeerId) bool
type DiffOp ¶
type DiffOp[K comparable, V comparable] interface { // contains filtered or unexported methods }
DiffOp is a keyed reconciliation op (cell-model.md § Keyed reconciliation): one of DiffOpInsert, DiffOpRemove, DiffOpMove, or DiffOpUpdate. It is a sealed union — only the four concrete types in this package implement it.
func ReconcileDiff ¶
func ReconcileDiff[K comparable, V comparable]( prior []KeyValue[K, V], target []KeyValue[K, V], ) []DiffOp[K, V]
ReconcileDiff computes the move-minimized keyed reconciliation (cell-model.md § Keyed reconciliation).
Diffs two keyed sequences by stable key, not position, emitting the minimal {insert, remove, move, update} op set: removes, then inserts + moves (in target order), then updates. Moves are move-minimized: the longest-increasing-subsequence (LIS) over prior indices of the common keys is held fixed, and only the remainder move. O(n log n) via patience sorting (strictly increasing), mirroring lazily-rs/src/reconcile.rs::longest_increasing_subsequence.
type DiffOpInsert ¶
type DiffOpInsert[K comparable, V comparable] struct { Key K Value V Index int }
DiffOpInsert inserts a brand-new key (not present in prior) at Index (its final position in the target sequence).
type DiffOpMove ¶
type DiffOpMove[K comparable, V comparable] struct { Key K To int }
DiffOpMove atomic-moves a common key from its prior position to To (the target index). Keeps the entry's same cell handle, dependents, and lineage.
type DiffOpRemove ¶
type DiffOpRemove[K comparable, V comparable] struct { Key K }
DiffOpRemove removes a key present in prior but absent in target.
type DiffOpUpdate ¶
type DiffOpUpdate[K comparable, V comparable] struct { Key K Value V }
DiffOpUpdate updates an existing key's value (PartialEq-guarded at the cell).
type DiscoveryCell ¶ added in v0.15.0
type DiscoveryCell[P comparable] struct { // contains filtered or unexported fields }
DiscoveryCell is the reactive service discovery. The discovery map is a collection reader, so it uses the version-cell pattern: bump version only when the projected map structurally changes.
func NewDiscoveryCell ¶ added in v0.15.0
func NewDiscoveryCell[P comparable](ctx *Context) *DiscoveryCell[P]
NewDiscoveryCell creates a reactive discovery cell bound to ctx.
func (*DiscoveryCell[P]) Deregister ¶ added in v0.15.0
func (d *DiscoveryCell[P]) Deregister(service string)
Deregister removes a service and refreshes the map.
func (*DiscoveryCell[P]) Discovery ¶ added in v0.15.0
func (d *DiscoveryCell[P]) Discovery() map[string]string
Discovery returns the live service -> endpoint map, subscribing the reader to the version cell.
func (*DiscoveryCell[P]) DiscoveryCell ¶ added in v0.15.0
func (d *DiscoveryCell[P]) DiscoveryCell() *Source[uint64]
DiscoveryCell returns the underlying version cell (the reactive handle).
func (*DiscoveryCell[P]) Evict ¶ added in v0.15.0
func (d *DiscoveryCell[P]) Evict(peer P)
Evict removes all endpoints owned by peer and refreshes the map.
func (*DiscoveryCell[P]) Register ¶ added in v0.15.0
func (d *DiscoveryCell[P]) Register(service string, endpoint string, peer P)
Register records a service endpoint owned by peer and refreshes the map.
type DiscoveryCore ¶ added in v0.15.0
type DiscoveryCore[P comparable] struct { // contains filtered or unexported fields }
DiscoveryCore is the service-discovery core: service -> (endpoint, owner). A peer's departure (Evict) removes its endpoints.
func NewDiscoveryCore ¶ added in v0.15.0
func NewDiscoveryCore[P comparable]() *DiscoveryCore[P]
NewDiscoveryCore creates an empty discovery core.
func (*DiscoveryCore[P]) Deregister ¶ added in v0.15.0
func (c *DiscoveryCore[P]) Deregister(service string)
Deregister removes a service.
func (*DiscoveryCore[P]) Discovery ¶ added in v0.15.0
func (c *DiscoveryCore[P]) Discovery() map[string]string
Discovery returns the live service -> endpoint map.
func (*DiscoveryCore[P]) Evict ¶ added in v0.15.0
func (c *DiscoveryCore[P]) Evict(peer P)
Evict removes all endpoints owned by peer (membership loss).
func (*DiscoveryCore[P]) Register ¶ added in v0.15.0
func (c *DiscoveryCore[P]) Register(service string, endpoint string, peer P)
Register records a service endpoint owned by peer.
type DisposedError ¶ added in v0.20.0
type DisposedError struct {
// Name is the node's debug name when it has one (NewNamedSlot).
Name string
// Kind is "slot", "cell", or "signal".
Kind string
}
DisposedError is the panic value raised by a read of a disposed node, and the error returned by TryGet.
func (*DisposedError) Error ¶ added in v0.20.0
func (e *DisposedError) Error() string
func (*DisposedError) Unwrap ¶ added in v0.20.0
func (e *DisposedError) Unwrap() error
Unwrap makes errors.Is(err, ErrDisposed) work.
type DriverError ¶ added in v0.8.0
type DriverError struct {
// Source is the inbound source read failure that stalled the tick.
Source error
}
DriverError is a transport error surfaced by SyncDriver.Tick.
A sink failure is not fatal — the frame is retained in the outbox and replayed on the next SyncDriver.OnReconnect, so it is reported as a stall, not an error. Only a source read failure is returned as a DriverError, signalling the host to re-establish the transport and call OnReconnect.
func (*DriverError) Error ¶ added in v0.8.0
func (e *DriverError) Error() string
Error implements the error interface.
func (*DriverError) Unwrap ¶ added in v0.8.0
func (e *DriverError) Unwrap() error
Unwrap exposes the underlying source error.
type DurableOutbox ¶ added in v0.8.0
type DurableOutbox interface {
// Append persists msg at epoch before it is handed to the transport.
Append(epoch Epoch, msg IpcMessage)
// AckThrough records that the peer proved receipt through epoch; retained
// frames <= epoch MAY be pruned.
AckThrough(epoch Epoch)
// ReplayFrom returns retained frames with epoch > cursor, ascending.
ReplayFrom(cursor Epoch) []OutboxEntry
// RetainedEpochs lists epochs still retained (not yet acked), ascending.
RetainedEpochs() []Epoch
}
DurableOutbox is the sender-side at-least-once outbox contract (spec § DurableOutbox).
Every frame is durably Appended BEFORE it is sent, retained until the peer proves receipt (AckThrough), and ReplayFrom a reconnect cursor re-sends everything the peer has not yet acked. Combined with the receiver's idempotent Ignore of already-applied deltas, this is at-least-once delivery with exactly-once effect.
type DurableStoreOutbox ¶ added in v0.13.0
type DurableStoreOutbox[S OutboxStore] struct { // contains filtered or unexported fields }
DurableStoreOutbox is Go's storage-independent outbox. The longer name avoids colliding with RelayCell's established Outbox role facade.
func NewDurableStoreOutbox ¶ added in v0.13.0
func NewDurableStoreOutbox[S OutboxStore](store S) *DurableStoreOutbox[S]
NewDurableStoreOutbox loads the durable cursor from store.
func (*DurableStoreOutbox[S]) AckThrough ¶ added in v0.13.0
func (o *DurableStoreOutbox[S]) AckThrough(epoch Epoch)
AckThrough advances the monotonic cursor and prunes the acknowledged prefix.
func (*DurableStoreOutbox[S]) AckedThrough ¶ added in v0.13.0
func (o *DurableStoreOutbox[S]) AckedThrough() Epoch
AckedThrough returns the highest loaded or observed peer acknowledgement.
func (*DurableStoreOutbox[S]) Append ¶ added in v0.13.0
func (o *DurableStoreOutbox[S]) Append(epoch Epoch, msg IpcMessage)
Append serializes and stores a frame before transport send.
func (*DurableStoreOutbox[S]) Err ¶ added in v0.13.0
func (o *DurableStoreOutbox[S]) Err() error
Err returns the most recent frame serialization/decoding error.
func (*DurableStoreOutbox[S]) ReplayFrom ¶ added in v0.13.0
func (o *DurableStoreOutbox[S]) ReplayFrom(cursor Epoch) []OutboxEntry
ReplayFrom returns decoded frames after both the caller and durable cursors.
func (*DurableStoreOutbox[S]) RetainedEpochs ¶ added in v0.13.0
func (o *DurableStoreOutbox[S]) RetainedEpochs() []Epoch
RetainedEpochs lists the unacknowledged suffix in ascending order.
func (*DurableStoreOutbox[S]) Store ¶ added in v0.13.0
func (o *DurableStoreOutbox[S]) Store() S
Store returns the byte adapter owned by the shared protocol.
type EdgeSnapshot ¶
type EdgeSnapshot struct {
Dependent NodeId `json:"dependent"`
Dependency NodeId `json:"dependency"`
}
EdgeSnapshot is a dependency edge: Dependent reads Dependency.
func (EdgeSnapshot) IsReadableBy ¶
func (e EdgeSnapshot) IsReadableBy(permissions *PeerPermissions, peer PeerId) bool
IsReadableBy reports whether both endpoints are readable by peer (so the edge is observable).
func (EdgeSnapshot) String ¶
func (e EdgeSnapshot) String() string
type Effect ¶
type Effect struct {
// contains filtered or unexported fields
}
Effect is a side-effect observer that reruns whenever a tracked dependency changes. It is the eager-push primitive for side effects (logging, I/O). Any Cell, Slot, or Signal read inside run becomes a dependency; when any changes, the effect is scheduled and reruns after the current cascade (or at Batch exit).
func NewEffect ¶
NewEffect creates and immediately runs a side-effect observer whose body receives the per-recompute Compute view and tracks via Get(c, handle) — the fortified, value-threaded surface (#lzcellkernel).
type EffectRun ¶
type EffectRun func(c *Compute) (cleanup func())
EffectRun is a side-effect function that may return a cleanup callback. It receives the per-recompute Compute view and reads its dependencies via Get(c, handle) — the value-threaded tracking surface (#lzcellkernel). The cleanup (if non-nil) is invoked before the next rerun and on Dispose.
type EntryKind ¶ added in v0.5.0
type EntryKind int
EntryKind is which kind of reactive node a ReactiveMap entry is — the handle-kind axis the map abstracts over. Mirrors EntryKind in lazily-formal's Materialization module and the Rust MapHandle::KIND.
type EphemeralCell ¶ added in v0.15.0
type EphemeralCell[V comparable] struct { // contains filtered or unexported fields }
EphemeralCell is a reactive single-value ephemeral cell. Value() invalidates only when the live value changes (the Cell == guard).
func NewEphemeralCell ¶ added in v0.15.0
func NewEphemeralCell[V comparable](ctx *Context) *EphemeralCell[V]
NewEphemeralCell builds an empty ephemeral cell in ctx.
func (*EphemeralCell[V]) Set ¶ added in v0.15.0
func (c *EphemeralCell[V]) Set(value V, now, ttl uint64)
Set stamps the value with expiry = now + ttl.
func (*EphemeralCell[V]) Tick ¶ added in v0.15.0
func (c *EphemeralCell[V]) Tick(now uint64)
Tick clears the value at now >= expiry.
func (*EphemeralCell[V]) Value ¶ added in v0.15.0
func (c *EphemeralCell[V]) Value() (V, bool)
Value returns the live value and whether one is present.
func (*EphemeralCell[V]) ValueCell ¶ added in v0.15.0
func (c *EphemeralCell[V]) ValueCell() *Source[Opt[V]]
ValueCell exposes the underlying reactive reader (Option scalar).
type EphemeralCore ¶ added in v0.15.0
type EphemeralCore[V comparable] struct { // contains filtered or unexported fields }
EphemeralCore is the single-value auto-expiry compute core — "the last value seen in window N".
func NewEphemeralCore ¶ added in v0.15.0
func NewEphemeralCore[V comparable]() *EphemeralCore[V]
NewEphemeralCore returns an empty core.
func (*EphemeralCore[V]) Set ¶ added in v0.15.0
func (c *EphemeralCore[V]) Set(value V, now, ttl uint64)
Set the value, expiring at now + ttl.
func (*EphemeralCore[V]) Tick ¶ added in v0.15.0
func (c *EphemeralCore[V]) Tick(now uint64)
Tick clears the value once now >= expiry.
func (*EphemeralCore[V]) Value ¶ added in v0.15.0
func (c *EphemeralCore[V]) Value() (V, bool)
Value returns the live value (respecting the last tick).
type EphemeralMapCore ¶ added in v0.15.0
type EphemeralMapCore[K comparable, V any] struct { // contains filtered or unexported fields }
EphemeralMapCore is a per-key ephemeral map with TTL eviction — the shared core behind presence and awareness. Each entry carries an expiry; Tick evicts lapsed entries.
func NewEphemeralMapCore ¶ added in v0.15.0
func NewEphemeralMapCore[K comparable, V any]() *EphemeralMapCore[K, V]
NewEphemeralMapCore returns an empty core.
func (*EphemeralMapCore[K, V]) Evict ¶ added in v0.15.0
func (c *EphemeralMapCore[K, V]) Evict(key K)
Evict drops key immediately (membership Dead/Left).
func (*EphemeralMapCore[K, V]) Get ¶ added in v0.15.0
func (c *EphemeralMapCore[K, V]) Get(key K, now uint64) (V, bool)
Get returns the live value for key (respecting now).
func (*EphemeralMapCore[K, V]) Present ¶ added in v0.15.0
func (c *EphemeralMapCore[K, V]) Present(now uint64) map[K]V
Present returns the live key -> value map at now.
func (*EphemeralMapCore[K, V]) Set ¶ added in v0.15.0
func (c *EphemeralMapCore[K, V]) Set(key K, value V, now, ttl uint64)
Set/refresh key's value (last-writer wins), expiring at now + ttl.
func (*EphemeralMapCore[K, V]) Tick ¶ added in v0.15.0
func (c *EphemeralMapCore[K, V]) Tick(now uint64)
Tick evicts entries whose TTL has lapsed (now >= expiry).
type Epoch ¶
type Epoch = int64
Epoch is the monotonically increasing snapshot/delta sequence number.
type ExpiryPolicy ¶ added in v0.11.0
type ExpiryPolicy struct {
// contains filtered or unexported fields
}
ExpiryPolicy — Case 10, TTL / deadline expiry. Drops elements whose age exceeds ttl against a logical clock. Lossy-by-age (explicit); used to shed cold data.
func NewExpiryPolicy ¶ added in v0.11.0
func NewExpiryPolicy(ttl uint64) *ExpiryPolicy
NewExpiryPolicy creates a TTL policy with the given time-to-live.
func (*ExpiryPolicy) Advance ¶ added in v0.11.0
func (e *ExpiryPolicy) Advance(by uint64)
Advance advances the logical clock.
func (*ExpiryPolicy) IsLive ¶ added in v0.11.0
func (e *ExpiryPolicy) IsLive(stampedAt uint64) bool
IsLive reports whether an element stamped at stampedAt is still live.
func (*ExpiryPolicy) Now ¶ added in v0.11.0
func (e *ExpiryPolicy) Now() uint64
Now is the current logical time.
type FfiCapability ¶
type FfiCapability string
FfiCapability is the `ffi` capability declaration. Its string value is the wire token.
const ( // FfiCapabilityHost means this binding hosts a native C ABI and may be // loaded in-process. FfiCapabilityHost FfiCapability = "host" // FfiCapabilityNone means this binding's runtime cannot host a native C ABI // (e.g. browser/Worker JS). It conforms to the interop contract but NOT the // in-process embedding contract, and MUST NOT advertise itself as // embeddable. FfiCapabilityNone FfiCapability = "none" )
func ParseFfiCapability ¶
func ParseFfiCapability(s string) (FfiCapability, error)
ParseFfiCapability parses a wire token into an FfiCapability.
func (FfiCapability) Wire ¶
func (f FfiCapability) Wire() string
Wire returns the wire token for this capability.
type FileOutbox ¶ added in v0.13.0
type FileOutbox struct {
*DurableStoreOutbox[*FileOutboxStore]
}
FileOutbox is the ready-to-use durable filesystem adapter.
func NewFileOutbox ¶ added in v0.13.0
func NewFileOutbox(path string) (*FileOutbox, error)
NewFileOutbox opens a durable outbox journal.
type FileOutboxStore ¶ added in v0.13.0
type FileOutboxStore struct {
// contains filtered or unexported fields
}
FileOutboxStore is a durable append-only journal adapter. Cursor records are folded with max, rather than overwritten, so stale writers cannot regress the persisted acknowledgement. O_APPEND also gives separate handles one serialized record boundary without a shared in-memory lock.
func NewFileOutboxStore ¶ added in v0.13.0
func NewFileOutboxStore(path string) (*FileOutboxStore, error)
NewFileOutboxStore opens (or creates) an append-only outbox journal.
func (*FileOutboxStore) DeleteThrough ¶ added in v0.13.0
func (s *FileOutboxStore) DeleteThrough(epoch Epoch)
func (*FileOutboxStore) Err ¶ added in v0.13.0
func (s *FileOutboxStore) Err() error
Err returns the latest journal I/O or decoding error.
func (*FileOutboxStore) LoadCursor ¶ added in v0.13.0
func (s *FileOutboxStore) LoadCursor() Epoch
func (*FileOutboxStore) Put ¶ added in v0.13.0
func (s *FileOutboxStore) Put(epoch Epoch, frame []byte)
func (*FileOutboxStore) SaveCursor ¶ added in v0.13.0
func (s *FileOutboxStore) SaveCursor(epoch Epoch)
func (*FileOutboxStore) ScanAfter ¶ added in v0.13.0
func (s *FileOutboxStore) ScanAfter(cursor Epoch) []StoredOutboxEntry
type FoldFn ¶
type FoldFn[V, D any] func(value V, childDerived []D) D
FoldFn combines a node's value with its children's derived values.
type FramedTransport ¶ added in v0.11.0
type FramedTransport[T any] struct { // contains filtered or unexported fields }
FramedTransport models CrossThread/Ipc/Ws: ops are delivered in bounded frames of at most frameSize (an MTU / batch boundary). Different frameSizes are different framings of the same op stream.
func NewFramedTransport ¶ added in v0.11.0
func NewFramedTransport[T any](frameSize int) *FramedTransport[T]
NewFramedTransport creates a framed transport with the given frame size.
func (*FramedTransport[T]) Deliver ¶ added in v0.11.0
func (t *FramedTransport[T]) Deliver(op T)
func (*FramedTransport[T]) HasPending ¶ added in v0.11.0
func (t *FramedTransport[T]) HasPending() bool
func (*FramedTransport[T]) Poll ¶ added in v0.11.0
func (t *FramedTransport[T]) Poll() []T
type GraphNode ¶ added in v0.20.0
type GraphNode interface {
// contains filtered or unexported methods
}
GraphNode is any node in a Context's reactive graph: *Slot, *Cell, *Signal, *Memo, or *Effect.
Sealed — its only method is unexported, so it cannot be implemented outside this package. It exists so the degree accessors and TeardownScope.Own take any node kind without exposing the edge sets themselves. The accessors return *counts*, never the sets: there is no path from here to a node's internals and no way to mutate the graph through it.
type Health ¶ added in v0.15.0
type Health int
Health is the composed health status (worst component dominates).
type HealthCell ¶ added in v0.15.0
type HealthCell struct {
// contains filtered or unexported fields
}
HealthCell is the reactive health projection onto a Cell for /health.
func NewHealthCell ¶ added in v0.15.0
func NewHealthCell(ctx *Context) *HealthCell
NewHealthCell creates a reactive health cell bound to ctx.
func (*HealthCell) Health ¶ added in v0.15.0
func (h *HealthCell) Health() Health
Health returns the current aggregate health.
func (*HealthCell) HealthCell ¶ added in v0.15.0
func (h *HealthCell) HealthCell() *Source[Health]
HealthCell returns the underlying reactive cell for /health.
type HealthCore ¶ added in v0.15.0
type HealthCore struct {
// contains filtered or unexported fields
}
HealthCore is the composed liveness-probe core. Each probe reports up and whether it is critical.
func NewHealthCore ¶ added in v0.15.0
func NewHealthCore() *HealthCore
NewHealthCore creates an empty health core.
func (*HealthCore) Health ¶ added in v0.15.0
func (c *HealthCore) Health() Health
Health is the aggregate: Unhealthy if any critical probe is down, else Degraded if any is down, else Healthy.
type Hlc ¶
type Hlc struct {
// contains filtered or unexported fields
}
Hlc is a hybrid logical clock. Wall time is caller-supplied (Tick/Observe take nowMicros) so the clock is deterministic and never reads the system clock.
func (*Hlc) Observe ¶
Observe folds a remote stamp: the returned local stamp is strictly greater than remote (the standard HLC recv rule).
type HlcStamp ¶
HlcStamp is a runtime HLC stamp — a total order (WallTime, Logical, Peer). Order is lexicographic, so equal (wall, logical) from different peers is still totally ordered by Peer. HlcStamp is a comparable value type.
func HlcStampFromWire ¶
HlcStampFromWire converts a wire WireStamp back to the runtime HlcStamp.
func NewHlcStamp ¶
NewHlcStamp constructs a stamp.
func (HlcStamp) Compare ¶
Compare returns -1, 0, or +1 for the lexicographic (wall, logical, peer) order.
func (HlcStamp) GreaterEqual ¶
type InMemoryOutbox ¶ added in v0.8.0
type InMemoryOutbox struct {
*DurableStoreOutbox[*InMemoryStore]
}
InMemoryOutbox preserves the established default constructor and API while delegating all protocol behavior to DurableStoreOutbox.
func NewInMemoryOutbox ¶ added in v0.8.0
func NewInMemoryOutbox() *InMemoryOutbox
NewInMemoryOutbox returns an empty outbox.
type InMemoryStore ¶ added in v0.13.0
type InMemoryStore struct {
// contains filtered or unexported fields
}
InMemoryStore is an ordered process-local OutboxStore.
func NewInMemoryStore ¶ added in v0.13.0
func NewInMemoryStore() *InMemoryStore
NewInMemoryStore returns an empty byte store.
func (*InMemoryStore) DeleteThrough ¶ added in v0.13.0
func (s *InMemoryStore) DeleteThrough(epoch Epoch)
func (*InMemoryStore) LoadCursor ¶ added in v0.13.0
func (s *InMemoryStore) LoadCursor() Epoch
func (*InMemoryStore) Put ¶ added in v0.13.0
func (s *InMemoryStore) Put(epoch Epoch, frame []byte)
func (*InMemoryStore) SaveCursor ¶ added in v0.13.0
func (s *InMemoryStore) SaveCursor(epoch Epoch)
func (*InMemoryStore) ScanAfter ¶ added in v0.13.0
func (s *InMemoryStore) ScanAfter(cursor Epoch) []StoredOutboxEntry
type InProcTransport ¶ added in v0.11.0
type InProcTransport[T any] struct { // contains filtered or unexported fields }
InProcTransport is direct delivery: every buffered op is handed over in one frame.
func NewInProcTransport ¶ added in v0.11.0
func NewInProcTransport[T any]() *InProcTransport[T]
NewInProcTransport creates a direct in-process transport.
func (*InProcTransport[T]) Deliver ¶ added in v0.11.0
func (t *InProcTransport[T]) Deliver(op T)
func (*InProcTransport[T]) HasPending ¶ added in v0.11.0
func (t *InProcTransport[T]) HasPending() bool
func (*InProcTransport[T]) Poll ¶ added in v0.11.0
func (t *InProcTransport[T]) Poll() []T
type InProcessBackend ¶ added in v0.4.0
type InProcessBackend struct {
// contains filtered or unexported fields
}
InProcessBackend is the default in-process backend: it wraps a ShmBlobArena for the single-address-space case (the FFI host ↔ a binding loaded in the same process, an editor plugin). Descriptors carry Backend = BackendInProcess. For a genuine cross-process store, spill to a ShmBackend (linux) instead.
func InProcessBackendFromArena ¶ added in v0.4.0
func InProcessBackendFromArena(arena *ShmBlobArena) *InProcessBackend
InProcessBackendFromArena wraps an existing arena.
func NewInProcessBackend ¶ added in v0.4.0
func NewInProcessBackend() *InProcessBackend
NewInProcessBackend creates an in-process backend over a fresh arena at epoch 0.
func (*InProcessBackend) AdvanceEpoch ¶ added in v0.4.0
func (b *InProcessBackend) AdvanceEpoch()
AdvanceEpoch advances the backing arena's epoch, invalidating prior descriptors.
func (*InProcessBackend) Arena ¶ added in v0.4.0
func (b *InProcessBackend) Arena() *ShmBlobArena
Arena returns the backing arena.
func (*InProcessBackend) Epoch ¶ added in v0.4.0
func (b *InProcessBackend) Epoch() int64
Epoch returns the backend's current validity epoch.
func (*InProcessBackend) Kind ¶ added in v0.4.0
func (b *InProcessBackend) Kind() BlobBackendKind
Kind reports BackendInProcess.
func (*InProcessBackend) ReadView ¶ added in v0.4.0
func (b *InProcessBackend) ReadView(descriptor ShmBlobRef) ([]byte, bool)
ReadView resolves the descriptor zero-copy against the backing arena.
func (*InProcessBackend) Write ¶ added in v0.4.0
func (b *InProcessBackend) Write(bytes []byte) (ShmBlobRef, error)
Write stores bytes in the arena and stamps the descriptor with the in-process backend discriminator.
type Inbox ¶ added in v0.11.0
type Inbox[T comparable] struct { // contains filtered or unexported fields }
Inbox is the transport → app receive side (§4.7). Cannot block the remote directly; backpressure is a credit meter the app replenishes.
func NewInbox ¶ added in v0.11.0
func NewInbox[T comparable](ctx *Context, highWater, maxCredits uint64, merge MergePolicy[T]) (*Inbox[T], error)
NewInbox builds an inbox bounded by highWater with the role default overflow (Conflate for inbound state) and a credit budget of maxCredits.
func NewInboxWithOverflow ¶ added in v0.11.0
func NewInboxWithOverflow[T comparable](ctx *Context, highWater uint64, overflow Overflow, maxCredits uint64, merge MergePolicy[T]) (*Inbox[T], error)
NewInboxWithOverflow builds an inbox with an explicit overflow policy.
func (*Inbox[T]) Consume ¶ added in v0.11.0
Consume has the app consume the coalesced window and replenish n credits (up to the budget), re-opening the remote's flow.
func (*Inbox[T]) Credits ¶ added in v0.11.0
Credits are the credits currently available to the remote.
func (*Inbox[T]) Ready ¶ added in v0.11.0
Ready reports whether the transport may deliver another message (a credit is available). When false, the transport must stop reading → the remote throttles.
func (*Inbox[T]) Receive ¶ added in v0.11.0
func (i *Inbox[T]) Receive(op T) IngressOutcome
Receive has the transport deliver a received op. Consumes a credit; the caller MUST have checked Ready (a delivery without credit still applies but drives credits to zero, signalling the remote to stop).
type IngressOutcome ¶ added in v0.11.0
type IngressOutcome string
IngressOutcome is the outcome of a single ingress op.
const ( // IngressAccepted — merged into an empty window (window depth was 0). IngressAccepted IngressOutcome = "Accepted" // IngressConflated — merged into a non-empty window (coalesced with prior). IngressConflated IngressOutcome = "Conflated" // IngressDropped — dropped by DropNewest/DropOldest overflow. IngressDropped IngressOutcome = "Dropped" // IngressBlocked — refused by Block overflow; retry after a drain. IngressBlocked IngressOutcome = "Blocked" )
type InsertAt ¶
type InsertAt string
InsertAt is the position specifier for SourceMap.Insert (mirrors lazily-kt::InsertAt). The string values are the normative wire tokens.
const ( // InsertAtEnd appends at the end (default). InsertAtEnd InsertAt = "end" // InsertAtIndex inserts at an absolute index (use SourceMap.MoveTo after // insert to position). InsertAtIndex InsertAt = "at" // InsertAtBefore inserts just before the anchor. InsertAtBefore InsertAt = "before" // InsertAtAfter inserts just after the anchor. InsertAtAfter InsertAt = "after" )
type IntervalCell ¶ added in v0.15.0
type IntervalCell struct {
// contains filtered or unexported fields
}
IntervalCell is a reactive periodic interval: projects IntervalCore's fire count onto a cell (invalidates only when count changes).
func NewIntervalCell ¶ added in v0.15.0
func NewIntervalCell(ctx *Context, period uint64) *IntervalCell
NewIntervalCell creates a reactive periodic interval with the given period.
func (*IntervalCell) Count ¶ added in v0.15.0
func (iv *IntervalCell) Count() uint64
Count reports the total fires so far (reactive read).
func (*IntervalCell) CountCell ¶ added in v0.15.0
func (iv *IntervalCell) CountCell() *Source[uint64]
CountCell returns the backing count cell.
func (*IntervalCell) NextFire ¶ added in v0.15.0
func (iv *IntervalCell) NextFire() (uint64, bool)
NextFire reports the next boundary.
func (*IntervalCell) Tick ¶ added in v0.15.0
func (iv *IntervalCell) Tick(now uint64) bool
Tick advances to logical time now; returns whether a boundary fired. The count cell mirrors the core's total fire count.
type IntervalCore ¶ added in v0.15.0
type IntervalCore struct {
// contains filtered or unexported fields
}
IntervalCore is a periodic compute core: fire boundaries at period, 2*period, … A tick counts every boundary in (frontier, now], so a jump past several boundaries counts them all.
func NewIntervalCore ¶ added in v0.15.0
func NewIntervalCore(period uint64) *IntervalCore
NewIntervalCore creates a periodic core with the given period (clamped to >=1).
func (*IntervalCore) Count ¶ added in v0.15.0
func (iv *IntervalCore) Count() uint64
Count reports the total number of fires so far.
func (*IntervalCore) NextFire ¶ added in v0.15.0
func (iv *IntervalCore) NextFire() (uint64, bool)
NextFire reports the next boundary (always present for an interval).
func (*IntervalCore) Tick ¶ added in v0.15.0
func (iv *IntervalCore) Tick(now uint64) bool
Tick advances to now; returns whether a boundary fired.
type IpcMessage ¶
type IpcMessage interface {
MarshalJSON() ([]byte, error)
// EncodeJSON returns the UTF-8 JSON bytes of the tagged wire form.
EncodeJSON() ([]byte, error)
// contains filtered or unexported methods
}
IpcMessage is a length-prefixed, tagged Snapshot, Delta, CrdtSync, or one of the reliable-sync reverse-channel control frames (ResyncRequest / OutboxAck). The CrdtSync variant carries multi-writer plane traffic alongside the single-producer mirror. Externally tagged: {"Snapshot": ...} / {"Delta": ...} / {"CrdtSync": ...} / {"ResyncRequest": ...} / {"OutboxAck": ...}.
func DecodeIpcMessageJSON ¶
func DecodeIpcMessageJSON(data []byte) (IpcMessage, error)
DecodeIpcMessageJSON decodes UTF-8 JSON bytes into an IpcMessage.
func IpcMessageFromWire ¶
func IpcMessageFromWire(data []byte) (IpcMessage, error)
IpcMessageFromWire decodes an externally-tagged IpcMessage from JSON bytes.
func SpillMessage ¶ added in v0.4.0
func SpillMessage(message IpcMessage, backend BlobBackend, threshold int) (IpcMessage, int)
SpillMessage spills large payloads across an IpcMessage's value/state sites — Snapshot node states, Delta CellSet/SlotValue payloads + NodeAdd states, and CrdtSync op states — returning a message whose oversized payloads are replaced by SharedBlob descriptors, plus the total bytes spilled. The message stays small on the wire. Sites already carrying a descriptor are left untouched. The input message is not mutated; the returned message shares unspilled substructure.
type IpcMessageCrdtSync ¶
type IpcMessageCrdtSync struct{ Value CrdtSync }
IpcMessageCrdtSync wraps a CrdtSync.
func (IpcMessageCrdtSync) EncodeJSON ¶
func (m IpcMessageCrdtSync) EncodeJSON() ([]byte, error)
func (IpcMessageCrdtSync) MarshalJSON ¶
func (m IpcMessageCrdtSync) MarshalJSON() ([]byte, error)
type IpcMessageDelta ¶
type IpcMessageDelta struct{ Value Delta }
IpcMessageDelta wraps a Delta.
func (IpcMessageDelta) EncodeJSON ¶
func (m IpcMessageDelta) EncodeJSON() ([]byte, error)
func (IpcMessageDelta) MarshalJSON ¶
func (m IpcMessageDelta) MarshalJSON() ([]byte, error)
type IpcMessageOutboxAck ¶ added in v0.8.0
type IpcMessageOutboxAck struct{ Value OutboxAck }
IpcMessageOutboxAck wraps an OutboxAck control frame (#lzsync).
func (IpcMessageOutboxAck) EncodeJSON ¶ added in v0.8.0
func (m IpcMessageOutboxAck) EncodeJSON() ([]byte, error)
func (IpcMessageOutboxAck) MarshalJSON ¶ added in v0.8.0
func (m IpcMessageOutboxAck) MarshalJSON() ([]byte, error)
type IpcMessageResyncRequest ¶ added in v0.8.0
type IpcMessageResyncRequest struct{ Value ResyncRequest }
IpcMessageResyncRequest wraps a ResyncRequest control frame (#lzsync).
func (IpcMessageResyncRequest) EncodeJSON ¶ added in v0.8.0
func (m IpcMessageResyncRequest) EncodeJSON() ([]byte, error)
func (IpcMessageResyncRequest) MarshalJSON ¶ added in v0.8.0
func (m IpcMessageResyncRequest) MarshalJSON() ([]byte, error)
type IpcMessageSnapshot ¶
type IpcMessageSnapshot struct{ Value Snapshot }
IpcMessageSnapshot wraps a Snapshot.
func (IpcMessageSnapshot) EncodeJSON ¶
func (m IpcMessageSnapshot) EncodeJSON() ([]byte, error)
func (IpcMessageSnapshot) MarshalJSON ¶
func (m IpcMessageSnapshot) MarshalJSON() ([]byte, error)
type IpcSink ¶ added in v0.8.0
type IpcSink interface {
Send(msg IpcMessage) error
}
IpcSink is the outbound transport seam. Send returns a non-nil error when the frame could not be handed to the transport; the driver treats that as a stall (retain-and-retry), not a fatal error.
type IpcSource ¶ added in v0.8.0
type IpcSource interface {
Recv() (msg IpcMessage, present bool, err error)
}
IpcSource is the inbound transport seam. Recv returns (msg, true, nil) for a frame, (_, false, nil) when the inbound queue is momentarily empty, and a non-nil error on a read failure (which the driver surfaces as DriverError).
type IpcValue ¶
type IpcValue interface {
MarshalJSON() ([]byte, error)
// contains filtered or unexported methods
}
IpcValue is a DeltaOp / CrdtOp cell payload. Externally tagged: {"Inline": [u8]} or {"SharedBlob": ShmBlobRef}.
func IpcValueOf ¶
IpcValueOf normalizes an IpcValue, ShmBlobRef, []byte, or []int into an IpcValue (mirrors `IpcValue.of` in the sibling bindings).
func SpillValue ¶ added in v0.4.0
func SpillValue(value IpcValue, backend BlobBackend, threshold int) (IpcValue, int)
SpillValue spills an IpcValue to backend when it is Inline and >= threshold bytes: it writes the bytes and returns a SharedBlob descriptor value plus the number of bytes spilled. Otherwise it returns the value unchanged and 0. Payloads below the threshold stay inline — cheaper than a backend round-trip for tiny values. A backend write failure leaves the value inline (returns 0).
type IpcValueInline ¶
type IpcValueInline struct {
Bytes []byte
}
IpcValueInline is an inline byte-array payload ({"Inline": [u8]}).
func (IpcValueInline) MarshalJSON ¶
func (v IpcValueInline) MarshalJSON() ([]byte, error)
type IpcValueSharedBlob ¶
type IpcValueSharedBlob struct {
}
IpcValueSharedBlob is a payload descriptor into shared memory ({"SharedBlob": ShmBlobRef}).
func (IpcValueSharedBlob) MarshalJSON ¶
func (v IpcValueSharedBlob) MarshalJSON() ([]byte, error)
type KeyValue ¶
type KeyValue[K comparable, V comparable] struct { Key K Value V }
KeyValue is an ordered key/value pair, the input unit for ReconcileDiff (mirrors Dart's MapEntry<K, V>).
type KeyedRelay ¶ added in v0.11.0
type KeyedRelay[K comparable, T comparable] struct { // contains filtered or unexported fields }
KeyedRelay — Case 18, keyed sharding. N independent relays keyed by K; an op routes to its key's shard. Merging across shards requires a commutative merge. The converged per-key state equals a single relay per key.
func NewKeyedRelay ¶ added in v0.11.0
func NewKeyedRelay[K comparable, T comparable](ctx *Context, highWater uint64, overflow Overflow, merge MergePolicy[T]) (*KeyedRelay[K, T], error)
NewKeyedRelay creates a keyed relay. Returns ErrConflateNotBounding if overflow is Conflate on a non-conflating policy (same guard as RelayCell).
func (*KeyedRelay[K, T]) Drain ¶ added in v0.11.0
func (k *KeyedRelay[K, T]) Drain(key K) (T, bool)
Drain drains a key's coalesced window (false when the key has no shard/window).
func (*KeyedRelay[K, T]) Ingress ¶ added in v0.11.0
func (k *KeyedRelay[K, T]) Ingress(key K, op T) IngressOutcome
Ingress routes op to key's shard, creating the shard on first use.
func (*KeyedRelay[K, T]) Keys ¶ added in v0.11.0
func (k *KeyedRelay[K, T]) Keys() []K
Keys returns the shard keys in first-use order.
type LazilyFfiBytes ¶
type LazilyFfiBytes struct {
// Bytes is the owned byte buffer.
Bytes []byte
}
LazilyFfiBytes is an owned byte buffer crossing the FFI boundary. On the real C ABI this is `{ uint8_t* ptr; size_t len; }` with explicit allocation ownership: the caller owns input bytes; the host owns output buffers until the paired free function (`lazily_ffi_bytes_free`) is called. This pure-Go mirror carries the bytes inline; the ownership contract is realized in ffi_cgo.go, which marshals to/from C-allocated buffers.
func LazilyFfiBytesFromOwned ¶
func LazilyFfiBytesFromOwned(b []byte) LazilyFfiBytes
LazilyFfiBytesFromOwned wraps an already-owned buffer without copying.
func NewLazilyFfiBytes ¶
func NewLazilyFfiBytes(b []byte) LazilyFfiBytes
NewLazilyFfiBytes copies b into a newly-owned LazilyFfiBytes buffer.
func (LazilyFfiBytes) AsJSON ¶
func (b LazilyFfiBytes) AsJSON() string
AsJSON decodes the buffer as UTF-8 JSON text.
func (LazilyFfiBytes) Len ¶
func (b LazilyFfiBytes) Len() int
Len returns the buffer length in bytes.
type LazilyFfiChannel ¶
type LazilyFfiChannel struct {
// contains filtered or unexported fields
}
LazilyFfiChannel is an in-process FFI message channel that mirrors the C-ABI `lazily_ffi_channel_send_json` / `lazily_ffi_channel_recv_json` pair. Each accepted frame is decoded as IpcMessage and re-encoded to canonical JSON bytes on the way in, so a round-trip exercises the same "decode + re-encode canonical JSON" contract regardless of the sender's codec.
It is a local ownership/ABI adapter, not a second graph-state model. Unlike the Dart original, this channel is safe for concurrent use (the C-ABI handle may be shared across goroutines).
func NewLazilyFfiChannel ¶
func NewLazilyFfiChannel() *LazilyFfiChannel
NewLazilyFfiChannel creates an empty channel. Mirrors `lazily_ffi_channel_new`.
func (*LazilyFfiChannel) IsEmpty ¶
func (c *LazilyFfiChannel) IsEmpty() bool
IsEmpty reports whether the channel has no pending frame.
func (*LazilyFfiChannel) Len ¶
func (c *LazilyFfiChannel) Len() int
Len returns the number of queued frames. Mirrors `lazily_ffi_channel_len`.
func (*LazilyFfiChannel) Recv ¶
func (c *LazilyFfiChannel) Recv() (IpcMessage, LazilyFfiStatus)
Recv dequeues and decodes the next message. Returns LazilyFfiStatusEmpty (and a nil message) if the queue is empty. Mirrors `lazily_ffi_channel_recv_json`.
func (*LazilyFfiChannel) RecvJSONFrame ¶
func (c *LazilyFfiChannel) RecvJSONFrame() (LazilyFfiBytes, LazilyFfiStatus)
RecvJSONFrame dequeues the next canonical frame bytes. Returns LazilyFfiStatusEmpty when the queue is empty. Mirrors `lazily_ffi_channel_recv_json`.
func (*LazilyFfiChannel) Send ¶
func (c *LazilyFfiChannel) Send(message IpcMessage) LazilyFfiStatus
Send encodes message to canonical JSON and queues it. Returns LazilyFfiStatusOk on success or LazilyFfiStatusEncodeFailed if encoding fails. Mirrors `lazily_ffi_channel_send_json` with an already-typed message.
func (*LazilyFfiChannel) SendJSONFrame ¶
func (c *LazilyFfiChannel) SendJSONFrame(frame LazilyFfiBytes) (status LazilyFfiStatus)
SendJSONFrame accepts raw frame bytes, decoding and re-encoding to canonical form on the way in so the recv side always sees canonical bytes. Mirrors `lazily_ffi_channel_send_json`.
type LazilyFfiClassification ¶
type LazilyFfiClassification struct {
Status LazilyFfiStatus
Kind LazilyFfiMessageKind
}
LazilyFfiClassification is the result of a frame classification: the status plus (on success) the decoded message kind.
func LazilyFfiKindJSON ¶
func LazilyFfiKindJSON(frame LazilyFfiBytes) (result LazilyFfiClassification)
LazilyFfiKindJSON classifies a frame: decode it and return the variant kind. On a decode failure the status is LazilyFfiStatusInvalidMessage and the kind is LazilyFfiMessageKindUnknown. Mirrors `lazily_ffi_ipc_message_kind_json`.
func (LazilyFfiClassification) IsOk ¶
func (c LazilyFfiClassification) IsOk() bool
IsOk reports whether classification succeeded.
type LazilyFfiCloneResult ¶
type LazilyFfiCloneResult struct {
Status LazilyFfiStatus
// Output is the re-encoded canonical JSON bytes (nil unless Status is ok).
Output *LazilyFfiBytes
}
LazilyFfiCloneResult is the result of cloning a frame through the channel: decode as IpcMessage, then re-encode canonical JSON bytes. Output is set iff Status is ok.
func LazilyFfiCloneJSON ¶
func LazilyFfiCloneJSON(frame LazilyFfiBytes) (result LazilyFfiCloneResult)
LazilyFfiCloneJSON clones a frame: decode the bytes as IpcMessage, then re-encode canonical JSON bytes. Mirrors `lazily_ffi_ipc_message_clone_json`. This is the contract pin: the channel decodes each accepted frame and re-encodes canonical JSON bytes.
type LazilyFfiMessageKind ¶
type LazilyFfiMessageKind int
LazilyFfiMessageKind is the IPC message kind discriminant, derived by decoding a frame as IpcMessage and matching on the variant. CrdtSync = 3 is normative.
const ( // LazilyFfiMessageKindUnknown is the unknown / unset zero value. LazilyFfiMessageKindUnknown LazilyFfiMessageKind = 0 // LazilyFfiMessageKindSnapshot classifies an IpcMessageSnapshot. LazilyFfiMessageKindSnapshot LazilyFfiMessageKind = 1 // LazilyFfiMessageKindDelta classifies an IpcMessageDelta. LazilyFfiMessageKindDelta LazilyFfiMessageKind = 2 // LazilyFfiMessageKindCrdtSync classifies an IpcMessageCrdtSync (the // multi-writer CRDT plane). LazilyFfiMessageKindCrdtSync LazilyFfiMessageKind = 3 // LazilyFfiMessageKindResyncRequest classifies an IpcMessageResyncRequest // (the reliable-sync reverse-channel gap-recovery frame, #lzsync). LazilyFfiMessageKindResyncRequest LazilyFfiMessageKind = 4 // LazilyFfiMessageKindOutboxAck classifies an IpcMessageOutboxAck (the // reliable-sync reverse-channel ack/resume-cursor frame, #lzsync). LazilyFfiMessageKindOutboxAck LazilyFfiMessageKind = 5 )
func LazilyFfiMessageKindFromCode ¶
func LazilyFfiMessageKindFromCode(code int) LazilyFfiMessageKind
LazilyFfiMessageKindFromCode decodes the integer discriminant, returning LazilyFfiMessageKindUnknown for an out-of-range value (matches the C enum's zero-default).
type LazilyFfiStatus ¶
type LazilyFfiStatus int
LazilyFfiStatus is the FFI operation status code. Errors return one of the non-zero codes; recovered panics surface as LazilyFfiStatusPanic before crossing the C ABI. The integer values are the normative C-ABI wire discriminants (0..5).
const ( // LazilyFfiStatusOk is success. LazilyFfiStatusOk LazilyFfiStatus = 0 // LazilyFfiStatusEmpty means no message was available (empty channel read). LazilyFfiStatusEmpty LazilyFfiStatus = 1 // LazilyFfiStatusNullPointer means a required pointer argument was null. LazilyFfiStatusNullPointer LazilyFfiStatus = 2 // LazilyFfiStatusInvalidMessage means the frame did not decode as a valid // IpcMessage. LazilyFfiStatusInvalidMessage LazilyFfiStatus = 3 // LazilyFfiStatusEncodeFailed means the frame decoded but could not be // re-encoded as canonical bytes. LazilyFfiStatusEncodeFailed LazilyFfiStatus = 4 // LazilyFfiStatusPanic means a panic was caught before crossing the C ABI. LazilyFfiStatusPanic LazilyFfiStatus = 5 )
func LazilyFfiStatusFromCode ¶
func LazilyFfiStatusFromCode(code int) (LazilyFfiStatus, bool)
LazilyFfiStatusFromCode decodes the integer discriminant, returning ok=false for an unknown value (mirrors the Dart/Rust enum's strictness on out-of-range discriminants).
func LazilyFfiValidateJSON ¶
func LazilyFfiValidateJSON(frame LazilyFfiBytes) (status LazilyFfiStatus)
LazilyFfiValidateJSON validates a frame: decode the bytes as IpcMessage and confirm the result is well-formed. Returns LazilyFfiStatusOk on success. Mirrors `lazily_ffi_ipc_message_validate_json`.
func (LazilyFfiStatus) IsOk ¶
func (s LazilyFfiStatus) IsOk() bool
IsOk reports whether this status represents success.
type Lcg ¶ added in v0.15.0
type Lcg struct {
// contains filtered or unexported fields
}
Lcg is a small deterministic SplitMix64-style generator — no external dependency, reproducible for the distribution property test.
func (*Lcg) NextFloat64 ¶ added in v0.15.0
NextFloat64 returns the next draw in [0, 1). Go unsigned arithmetic wraps, so this matches rs `wrapping_add`/`wrapping_mul` bit-for-bit.
type LeaderCell ¶ added in v0.15.0
type LeaderCell[P comparable] struct { // contains filtered or unexported fields }
LeaderCell is reactive leadership over a lease from node me's perspective.
func NewLeaderCell ¶ added in v0.15.0
func NewLeaderCell[P comparable](ctx *Context, me P) *LeaderCell[P]
NewLeaderCell constructs reactive leadership for node me.
func (*LeaderCell[P]) Campaign ¶ added in v0.15.0
func (c *LeaderCell[P]) Campaign(now, ttl uint64) LeaderRole
Campaign tries to acquire leadership for me.
func (*LeaderCell[P]) Contend ¶ added in v0.15.0
func (c *LeaderCell[P]) Contend(peer P, now, ttl uint64) LeaderRole
Contend simulates another peer contending (for tests / co-hosted nodes).
func (*LeaderCell[P]) CurrentLeader ¶ added in v0.15.0
func (c *LeaderCell[P]) CurrentLeader(now uint64) (P, bool)
CurrentLeader returns the live leader at now.
func (*LeaderCell[P]) CurrentLeaderCell ¶ added in v0.15.0
func (c *LeaderCell[P]) CurrentLeaderCell() *Source[Opt[P]]
CurrentLeaderCell exposes the reactive current-leader projection.
func (*LeaderCell[P]) Role ¶ added in v0.15.0
func (c *LeaderCell[P]) Role(now uint64) LeaderRole
Role derives the local node's role at now.
func (*LeaderCell[P]) Tick ¶ added in v0.15.0
func (c *LeaderCell[P]) Tick(now uint64) LeaderRole
Tick advances the logical clock, expiring the lease if due.
type LeaderRole ¶ added in v0.15.0
type LeaderRole int
LeaderRole is the local node's role, derived from lease ownership.
const ( // Leader — the local node holds the lease. Leader LeaderRole = iota // Follower — another peer holds the lease. Follower // Candidate — the lease is free. Candidate )
func (LeaderRole) String ¶ added in v0.15.0
func (r LeaderRole) String() string
String renders the role name (matches fixture strings).
type LeafKind ¶ added in v0.2.0
type LeafKind string
LeafKind classifies a leaf's exact source span. Every rendered byte belongs to a leaf; unknown/invalid spans are Raw/Error so nothing is discarded. Serialized as the PascalCase wire string.
const ( // LeafKindToken is a syntax delimiter or marker. LeafKindToken LeafKind = "Token" // LeafKindTrivia is whitespace, blank lines, indentation, comments. LeafKindTrivia LeafKind = "Trivia" // LeafKindRaw is valid text the adapter deliberately keeps opaque. LeafKindRaw LeafKind = "Raw" // LeafKindError is invalid/ambiguous text that must still round-trip. LeafKindError LeafKind = "Error" )
type LeaseCell ¶ added in v0.15.0
type LeaseCell[P comparable] struct { // contains filtered or unexported fields }
LeaseCell is a reactive lease: projects the holder onto a Cell (invalidates on holder change).
func NewLeaseCell ¶ added in v0.15.0
func NewLeaseCell[P comparable](ctx *Context) *LeaseCell[P]
NewLeaseCell constructs a reactive lease.
func (*LeaseCell[P]) Acquire ¶ added in v0.15.0
Acquire grants the lease, returning the fencing token (present=false if denied).
func (*LeaseCell[P]) HolderCell ¶ added in v0.15.0
HolderCell exposes the reactive holder projection.
func (*LeaseCell[P]) IsHeld ¶ added in v0.15.0
IsHeld reports whether the lease is currently held at now.
type LeaseCore ¶ added in v0.15.0
type LeaseCore[P comparable] struct { // contains filtered or unexported fields }
LeaseCore is a single-writer lease authority with a monotone fencing token.
func NewLeaseCore ¶ added in v0.15.0
func NewLeaseCore[P comparable]() *LeaseCore[P]
NewLeaseCore returns an empty lease core.
func (*LeaseCore[P]) Acquire ¶ added in v0.15.0
Acquire grants if free/expired (new grant increments fence); renew by the holder keeps the same fence; held by another -> (0, false). The bool reports whether a token was granted.
func (*LeaseCore[P]) IsHeld ¶ added in v0.15.0
IsHeld reports whether the lease is currently held (and not expired at now).
func (*LeaseCore[P]) Release ¶ added in v0.15.0
func (c *LeaseCore[P]) Release(peer P)
Release drops the grant if peer holds it.
type LockCell ¶ added in v0.15.0
type LockCell[P comparable] struct { // contains filtered or unexported fields }
LockCell is a reactive distributed mutex over a lease + fencing token.
func NewLockCell ¶ added in v0.15.0
func NewLockCell[P comparable](ctx *Context) *LockCell[P]
NewLockCell constructs a reactive distributed lock.
func (*LockCell[P]) Acquire ¶ added in v0.15.0
Acquire acquires the lock, returning a fencing token (present=false if held).
func (*LockCell[P]) IsLockedCell ¶ added in v0.15.0
IsLockedCell exposes the reactive is_locked projection.
type LosslessTreeCrdt ¶ added in v0.2.0
type LosslessTreeCrdt struct {
// contains filtered or unexported fields
}
LosslessTreeCrdt is a lossless concrete-syntax tree CRDT (M1 core).
Not safe for concurrent use; share across goroutines via a single owner goroutine or wrap in a lock.
func NewLosslessTreeCrdt ¶ added in v0.2.0
func NewLosslessTreeCrdt(peer PeerId) *LosslessTreeCrdt
NewLosslessTreeCrdt creates an empty replica for the given peer id, seeded with just the document root element.
func (*LosslessTreeCrdt) ApplyUpdate ¶ added in v0.2.0
func (t *LosslessTreeCrdt) ApplyUpdate(update TreeUpdate)
ApplyUpdate applies a batch of remote ops. Idempotent (already-held ops skipped) and order-tolerant (an op whose target/parent has not arrived is buffered and retried). Advances the Lamport counter past every observed op.
func (*LosslessTreeCrdt) Children ¶ added in v0.2.0
func (t *LosslessTreeCrdt) Children(parent OpId) []OpId
Children returns the live children of parent in rendered order.
func (*LosslessTreeCrdt) CreateNode ¶ added in v0.2.0
func (t *LosslessTreeCrdt) CreateNode(parent OpId, after *OpId, seed TreeNodeSeed) OpId
CreateNode creates a node under parent, positioned after after (front when nil), and returns the new node's id.
func (*LosslessTreeCrdt) Diff ¶ added in v0.2.0
func (t *LosslessTreeCrdt) Diff(their *TreeVersionFrontier) TreeUpdate
Diff returns the ops this replica holds that their frontier lacks, ordered by dotted id.
func (*LosslessTreeCrdt) EditLeaf ¶ added in v0.2.0
func (t *LosslessTreeCrdt) EditLeaf(node OpId, atByte, deleteBytes int, insert string)
EditLeaf edits a leaf's text: delete deleteBytes and insert insert at UTF-8 byte offset atByte (leaf-local). Offsets must land on rune boundaries.
func (*LosslessTreeCrdt) ElementKind ¶ added in v0.2.0
func (t *LosslessTreeCrdt) ElementKind(node OpId) string
ElementKind returns the kind of an element node, or "" if absent or a leaf.
func (*LosslessTreeCrdt) Fork ¶ added in v0.2.0
func (t *LosslessTreeCrdt) Fork(peer PeerId) *LosslessTreeCrdt
Fork deep-copies this replica's full state under a new owning peer (new identity).
func (*LosslessTreeCrdt) Frontier ¶ added in v0.2.0
func (t *LosslessTreeCrdt) Frontier() *TreeVersionFrontier
Frontier returns this replica's dotted version frontier (what to advertise to a partner).
func (*LosslessTreeCrdt) LeafKind ¶ added in v0.2.0
func (t *LosslessTreeCrdt) LeafKind(node OpId) LeafKind
LeafKind returns the kind of a leaf node, or "" if absent or an element.
func (*LosslessTreeCrdt) LeafText ¶ added in v0.2.0
func (t *LosslessTreeCrdt) LeafText(node OpId) string
LeafText returns a leaf's current text. Panics if node is absent or an element.
func (*LosslessTreeCrdt) LiveNodeCount ¶ added in v0.2.0
func (t *LosslessTreeCrdt) LiveNodeCount() int
LiveNodeCount returns the live nodes excluding the root — grows by one on split, restored on merge.
func (*LosslessTreeCrdt) MergeAdjacentLeaves ¶ added in v0.2.0
func (t *LosslessTreeCrdt) MergeAdjacentLeaves(left, right OpId)
MergeAdjacentLeaves merges right into left when they are adjacent live leaf siblings.
func (*LosslessTreeCrdt) Render ¶ added in v0.2.0
func (t *LosslessTreeCrdt) Render() string
Render returns the whole document by concatenating live-leaf text in tree order (depth-first over live children).
func (*LosslessTreeCrdt) ReorderChild ¶ added in v0.2.0
func (t *LosslessTreeCrdt) ReorderChild(node OpId, after *OpId)
ReorderChild reorders node within its parent to just after after (front when nil).
func (*LosslessTreeCrdt) SplitLeaf ¶ added in v0.2.0
func (t *LosslessTreeCrdt) SplitLeaf(node OpId, atByte int) OpId
SplitLeaf splits a leaf at UTF-8 byte offset atByte into two adjacent leaves of the same kind (head keeps node, tail is a fresh node returned here).
func (*LosslessTreeCrdt) TombstoneNode ¶ added in v0.2.0
func (t *LosslessTreeCrdt) TombstoneNode(node OpId)
TombstoneNode tombstones a node (its subtree renders away once the ancestor is gone).
type LwwRegister ¶
LwwRegister is a last-writer-wins register. Ties (equal stamps) are broken in favor of the incumbent (Set requires a strictly greater stamp).
func NewLwwRegister ¶
func NewLwwRegister[V any](value V, stamp HlcStamp) *LwwRegister[V]
NewLwwRegister creates a register holding value stamped at stamp.
func (*LwwRegister[V]) Copy ¶
func (r *LwwRegister[V]) Copy() *LwwRegister[V]
Copy returns a shallow copy of the register.
func (*LwwRegister[V]) MergeFrom ¶
func (r *LwwRegister[V]) MergeFrom(other *LwwRegister[V]) bool
MergeFrom merges another register into this one. Returns whether the value changed.
func (*LwwRegister[V]) Set ¶
func (r *LwwRegister[V]) Set(newValue V, newStamp HlcStamp) bool
Set assigns newValue if newStamp is strictly greater than the current stamp. Returns whether the value was updated.
type ManifestEntry ¶ added in v0.11.0
ManifestEntry is a bounded per-page metadata record (page id, bytes).
type ManualClock ¶ added in v0.15.0
type ManualClock struct {
// contains filtered or unexported fields
}
ManualClock is a monotone logical clock a manual runtime (game loop, test) can own to drive sources. Advance clamps backwards moves so now is always non-decreasing.
func NewManualClock ¶ added in v0.15.0
func NewManualClock() *ManualClock
NewManualClock creates a clock at logical time 0.
func (*ManualClock) Advance ¶ added in v0.15.0
func (c *ManualClock) Advance(now uint64) uint64
Advance moves to now (monotone: a smaller value is clamped to the current time). Returns the effective now a source should be ticked with.
func (*ManualClock) Now ¶ added in v0.15.0
func (c *ManualClock) Now() uint64
Now reports the current logical time.
type Match ¶
type Match struct {
Kind string // "same" | "edited" | "inserted"
OldIndex int // -1 for inserted
Similarity float64
}
Match is the kind of match for a new block against the old set.
func MatchEdited ¶
MatchEdited constructs an Edited match.
type MembershipCell ¶ added in v0.15.0
MembershipCell is the reactive membership view: it drives a MembershipCore and projects the alive set onto a version Cell so PeerSet invalidates only on a set change (mirrors the rs Cell<BTreeSet<P>> PartialEq guard).
func NewMembershipCell ¶ added in v0.15.0
func NewMembershipCell[P cmp.Ordered](ctx *Context, config MembershipConfig) *MembershipCell[P]
NewMembershipCell builds a reactive membership cell bound to ctx.
func (*MembershipCell[P]) Heartbeat ¶ added in v0.15.0
func (c *MembershipCell[P]) Heartbeat(peer P, now uint64) []PeerChangeEvent[P]
Heartbeat records a heartbeat, then refreshes the projection.
func (*MembershipCell[P]) Join ¶ added in v0.15.0
func (c *MembershipCell[P]) Join(peer P, now uint64) []PeerChangeEvent[P]
Join adds/refreshes a peer, then refreshes the projection.
func (*MembershipCell[P]) Leave ¶ added in v0.15.0
func (c *MembershipCell[P]) Leave(peer P, now uint64) []PeerChangeEvent[P]
Leave records a graceful departure, then refreshes the projection.
func (*MembershipCell[P]) PeerSet ¶ added in v0.15.0
func (c *MembershipCell[P]) PeerSet() []P
PeerSet returns a fresh snapshot of the alive peer set (sorted). Reading it inside a computation subscribes the reader to the alive-set version, so it invalidates only when the set changes.
func (*MembershipCell[P]) State ¶ added in v0.15.0
func (c *MembershipCell[P]) State(peer P) (PeerState, bool)
State returns the state of a known peer.
func (*MembershipCell[P]) Tick ¶ added in v0.15.0
func (c *MembershipCell[P]) Tick(now uint64) []PeerChangeEvent[P]
Tick advances the clock, then refreshes the projection.
func (*MembershipCell[P]) VersionCell ¶ added in v0.15.0
func (c *MembershipCell[P]) VersionCell() *Source[uint64]
VersionCell exposes the backing version Cell for direct subscription.
type MembershipConfig ¶ added in v0.15.0
type MembershipConfig struct {
// PhiThreshold — phi > PhiThreshold marks a peer Suspect.
PhiThreshold float64
// SuspectTimeout — ticks a peer stays Suspect before being declared Dead.
SuspectTimeout uint64
// MaxSamples — sliding window size for heartbeat inter-arrival samples.
MaxSamples int
// MinStd — floor on the sample standard deviation (avoids div-by-zero).
MinStd float64
}
MembershipConfig holds the failure-detector + SWIM tunables.
func DefaultMembershipConfig ¶ added in v0.15.0
func DefaultMembershipConfig() MembershipConfig
DefaultMembershipConfig returns the standard tunables.
type MembershipCore ¶ added in v0.15.0
MembershipCore is the pure SWIM state machine over a keyed peer map, driven by heartbeats and a logical clock. It emits PeerChangeEvent diffs.
func NewMembershipCore ¶ added in v0.15.0
func NewMembershipCore[P cmp.Ordered](config MembershipConfig) *MembershipCore[P]
NewMembershipCore builds an empty core with the given config.
func (*MembershipCore[P]) AliveSet ¶ added in v0.15.0
func (m *MembershipCore[P]) AliveSet() []P
AliveSet returns the current alive peer set as a sorted slice (the reactive PeerSet).
func (*MembershipCore[P]) Heartbeat ¶ added in v0.15.0
func (m *MembershipCore[P]) Heartbeat(peer P, now uint64) []PeerChangeEvent[P]
Heartbeat records a heartbeat. An unknown peer is a join; a Suspect/Dead peer returns to Alive (SWIM refutation).
func (*MembershipCore[P]) Join ¶ added in v0.15.0
func (m *MembershipCore[P]) Join(peer P, now uint64) []PeerChangeEvent[P]
Join adds a peer (or refreshes a re-joining one): Alive with a fresh detector.
func (*MembershipCore[P]) Leave ¶ added in v0.15.0
func (m *MembershipCore[P]) Leave(peer P, _ uint64) []PeerChangeEvent[P]
Leave records a graceful departure.
func (*MembershipCore[P]) State ¶ added in v0.15.0
func (m *MembershipCore[P]) State(peer P) (PeerState, bool)
State returns the state of a known peer.
func (*MembershipCore[P]) Tick ¶ added in v0.15.0
func (m *MembershipCore[P]) Tick(now uint64) []PeerChangeEvent[P]
Tick advances the clock: escalate Alive -> Suspect (phi crossed) and Suspect -> Dead (timeout elapsed).
type MergePolicy ¶ added in v0.10.0
type MergePolicy[T any] struct { Name string Merge func(old, op T) T Commutative bool Idempotent bool Conflates bool }
MergePolicy is an associative merge ⊕ with its transport-selected property flags. Associativity ((a⊕b)⊕c == a⊕(b⊕c)) is a law, verified by the law-tests, not a flag. Commutative is the reordering tax; Idempotent the durability tax; Conflates gates the Conflate overflow (Phase 2 — only RawFifo cannot bound).
func KeepLatest ¶ added in v0.10.0
func KeepLatest[T any]() MergePolicy[T]
KeepLatest is the keep-latest band (old ⊕ op = op) — the policy behind a plain Cell. Associative and idempotent, not commutative.
func Max ¶ added in v0.10.0
func Max[T Number]() MergePolicy[T]
Max is the max semilattice (max(old, op)). Associative, commutative, idempotent.
func RawFifo ¶ added in v0.10.0
func RawFifo[E any]() MergePolicy[[]E]
RawFifo is raw FIFO append over []E (old ++ op). Order + multiplicity are meaning — associative only; cannot conflate.
func SetUnion ¶ added in v0.10.0
func SetUnion[E comparable]() MergePolicy[map[E]struct{}]
SetUnion is the grow-only set-union semilattice over map[E]struct{}.
func Sum ¶ added in v0.10.0
func Sum[T Number]() MergePolicy[T]
Sum is the additive commutative monoid (old + op). Not idempotent.
type MvRegister ¶
type MvRegister[V any] struct { // contains filtered or unexported fields }
MvRegister is a multi-value register. Concurrent writes surface as a set of values; a write that observes all prior values collapses back to a singleton.
stamps and values are kept index-parallel: entry i is the value written under stamp i. HLC stamps are unique per event, so no de-duplication of stamps is required on write.
func NewMvRegister ¶
func NewMvRegister[V any]() *MvRegister[V]
NewMvRegister creates an empty multi-value register.
func (*MvRegister[V]) Copy ¶
func (r *MvRegister[V]) Copy() *MvRegister[V]
Copy returns a deep copy of the register.
func (*MvRegister[V]) Merge ¶
func (r *MvRegister[V]) Merge(other *MvRegister[V])
Merge folds another MV register into this one (state-based, idempotent).
func (*MvRegister[V]) ObservedStamps ¶
func (r *MvRegister[V]) ObservedStamps() map[HlcStamp]struct{}
ObservedStamps returns a copy of the stamps observed by this register.
func (*MvRegister[V]) Values ¶
func (r *MvRegister[V]) Values() []V
Values returns the current visible values (concurrent writes = multiple, causal write = one). The returned slice is a copy.
func (*MvRegister[V]) Write ¶
func (r *MvRegister[V]) Write(value V, stamp HlcStamp, observedStamps map[HlcStamp]struct{})
Write adds value under stamp. If observedStamps covers every current stamp, the register collapses to the singleton being written. A nil observedStamps means the write observed nothing prior.
type NodeEntry ¶
NodeEntry is a node's (value, state) pair in the pure kernel. State is one of "clean" / "dirty".
type NodeKey ¶
type NodeKey struct {
// contains filtered or unexported fields
}
NodeKey is a validated `/`-joined path addressing a keyed collection entry.
It is an additive, optional wire-stable address: unlike the volatile NodeId (which a producer may re-mint after a resync or a remove-then-readd), a key is producer-defined and stable across NodeId churn. Serialized as a bare JSON string; the containing field is omitted when the key is absent (see NodeSnapshot / DeltaOpNodeAdd).
Bounds, enforced on construction:
- path <= 1024 bytes (UTF-8);
- <= 32 `/`-separated segments;
- no empty path and no empty segments (leading/trailing/double `/`).
func NewNodeKey ¶
NewNodeKey validates and constructs a NodeKey.
func NodeKeyFromWire ¶
NodeKeyFromWire parses and re-validates a wire path string.
func (NodeKey) MarshalJSON ¶
MarshalJSON emits the bare path string.
func (*NodeKey) UnmarshalJSON ¶
UnmarshalJSON parses a JSON string and re-validates the NodeKey bounds.
type NodeSnapshot ¶
NodeSnapshot is a serialized node in a Snapshot. The optional Key is a wire-stable NodeKey, omitted from JSON when nil.
func (NodeSnapshot) MarshalJSON ¶
func (n NodeSnapshot) MarshalJSON() ([]byte, error)
MarshalJSON emits { node, type_tag, state[, key] }, omitting key when nil.
func (*NodeSnapshot) UnmarshalJSON ¶
func (n *NodeSnapshot) UnmarshalJSON(b []byte) error
type NodeState ¶
type NodeState interface {
MarshalJSON() ([]byte, error)
// contains filtered or unexported methods
}
NodeState is the body of a NodeSnapshot / NodeAdd. Externally tagged: a single-key object keyed by the PascalCase variant name, except Opaque which is the bare unit string "Opaque".
type NodeStateOpaque ¶
type NodeStateOpaque struct{}
NodeStateOpaque is a visible node whose value cannot be serialized (the bare unit string "Opaque").
func (NodeStateOpaque) MarshalJSON ¶
func (NodeStateOpaque) MarshalJSON() ([]byte, error)
type NodeStatePayload ¶
type NodeStatePayload struct {
Bytes []byte
}
NodeStatePayload holds concrete serialized value bytes ({"Payload": [u8]}).
func (NodeStatePayload) MarshalJSON ¶
func (p NodeStatePayload) MarshalJSON() ([]byte, error)
MarshalJSON emits {"Payload": [u8]} with bytes as a JSON u8 array (not base64).
type NodeStateSharedBlob ¶
type NodeStateSharedBlob struct {
}
NodeStateSharedBlob is a concrete value stored in shared memory ({"SharedBlob": ShmBlobRef}).
func (NodeStateSharedBlob) MarshalJSON ¶
func (s NodeStateSharedBlob) MarshalJSON() ([]byte, error)
type Number ¶ added in v0.10.0
type Number interface {
~int | ~int8 | ~int16 | ~int32 | ~int64 |
~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64 |
~float32 | ~float64
}
Number constrains the additive/ordered policies (Sum, Max).
type OpId ¶
OpId is a globally-unique operation identifier for a character CRDT op.
Ordered ascending by (Counter, Peer) so later ops sort after earlier ones from the same peer, and ties between peers break deterministically. OpId is a comparable value type, usable directly as a map key.
func OpIdFromWire ¶
OpIdFromWire parses an OpId from its decoded-JSON map form.
type OpKind ¶
type OpKind string
OpKind is one of the three independently-gated remote operation kinds. A read grant never implies write or effect.
type Opt ¶ added in v0.15.0
type Opt[T comparable] struct { Present bool Value T }
Opt is a comparable optional value. Present distinguishes a set value from the zero value. Comparable whenever T is comparable, so it can back a Cell.
type OrSet ¶ added in v0.8.0
type OrSet struct {
// contains filtered or unexported fields
}
OrSet is an observed-remove set (OR-set) liveness cell.
It models one entry's presence via add/remove tags: a (doc, pid) is present iff some add-tag is not shadowed by a remove that observed it. This gives the add-wins-over-stale-remove bias liveness needs (a re-open concurrent with a lagging close keeps the doc open). Join is the union of both tag sets, so it is a semilattice — out-of-order and duplicate delivery converge.
func (*OrSet) Add ¶ added in v0.8.0
Add mints a presence tag (an editor open / attach event mints a fresh tag).
func (*OrSet) Join ¶ added in v0.8.0
Join folds another replica's OR-set (union of adds and of removes).
func (*OrSet) Present ¶ added in v0.8.0
Present reports whether the entry is currently present (some add-tag not shadowed).
func (*OrSet) RemoveObserved ¶ added in v0.8.0
RemoveObserved removes, observing tags — only the add-tags this remove saw are shadowed.
type Outbox ¶ added in v0.11.0
type Outbox[T comparable] struct { // contains filtered or unexported fields }
Outbox is the app → transport send side (§4.7). Backpressures the local producer directly via IsFull. Default overflow Conflate (state broadcast).
func NewOutbox ¶ added in v0.11.0
func NewOutbox[T comparable](ctx *Context, highWater uint64, merge MergePolicy[T]) (*Outbox[T], error)
NewOutbox builds an outbox bounded by highWater with the role default overflow (Conflate — the state-broadcast case). Validates the policy flags.
func NewOutboxWithOverflow ¶ added in v0.11.0
func NewOutboxWithOverflow[T comparable](ctx *Context, dimension BoundDim, highWater uint64, overflow Overflow, merge MergePolicy[T]) (*Outbox[T], error)
NewOutboxWithOverflow builds an outbox with an explicit dimension/overflow (e.g. Spill for a lossless event channel).
func (*Outbox[T]) Drain ¶ added in v0.11.0
Drain has the transport drain the coalesced window for egress.
func (*Outbox[T]) IsFull ¶ added in v0.11.0
IsFull is the producer-facing backpressure signal (window at/over watermark).
func (*Outbox[T]) IsFullSlot ¶ added in v0.11.0
IsFullSlot exposes the backpressure reader slot.
func (*Outbox[T]) Relay ¶ added in v0.11.0
Relay accesses the underlying relay (for wiring extra egress stages).
func (*Outbox[T]) Send ¶ added in v0.11.0
func (o *Outbox[T]) Send(op T) IngressOutcome
Send has the local producer send an op. A Blocked outcome is the producer's backpressure signal — it should await a drain before retrying.
type OutboxAck ¶ added in v0.8.0
type OutboxAck struct {
// ThroughEpoch is the highest epoch the receiver has fully applied.
ThroughEpoch Epoch `json:"through_epoch"`
}
OutboxAck is a reliable-sync reverse-channel control frame: prove receipt through ThroughEpoch (#lzsync, spec § DurableOutbox). It advances the sender's outbox retention cursor and doubles as the reconnect resume cursor; it carries no node content. Wire form: {"through_epoch": N}.
type OutboxEntry ¶ added in v0.8.0
type OutboxEntry struct {
Epoch Epoch
Msg IpcMessage
}
OutboxEntry pairs a retained frame with its outbox retention key (the frame's accepted-event count).
type OutboxStore ¶ added in v0.13.0
type OutboxStore interface {
Put(epoch Epoch, frame []byte)
DeleteThrough(epoch Epoch)
ScanAfter(cursor Epoch) []StoredOutboxEntry
LoadCursor() Epoch
SaveCursor(epoch Epoch)
}
OutboxStore is dumb ordered byte storage for the durable outbox protocol. Serialization, cursor monotonicity, pruning, and replay ordering belong to DurableStoreOutbox; adapters implement only these five operations.
type Overflow ¶ added in v0.11.0
type Overflow string
Overflow is the action taken when the hot head crosses high_water (§4.4).
const ( // OverflowBlock refuses ingress; the producer backpressures (observes // IsFull). Lossless. OverflowBlock Overflow = "Block" // OverflowDropNewest discards the incoming op. Lossy. OverflowDropNewest Overflow = "DropNewest" // OverflowDropOldest resets the window to the incoming op, discarding what // accumulated. Lossy. OverflowDropOldest Overflow = "DropOldest" // OverflowConflate keeps merging — the coalescence *is* the bound. Requires // the policy's Conflates flag. OverflowConflate Overflow = "Conflate" // OverflowSpill pages the accumulated window to a durable tail (Phase 3). OverflowSpill Overflow = "Spill" )
type PeekableStorage ¶ added in v0.9.0
type PeekableStorage[T any] interface { // Peek returns the current head element and true, or the zero T and false // when empty. Non-mutating. Peek() (T, bool) }
PeekableStorage is the OPTIONAL peek capability. A backend implementing it gains a reactive Head reader; a backend without it has no Head (Head returns the zero value and false), exactly as an unbounded backend has no IsFull.
type PeerChangeEvent ¶ added in v0.15.0
type PeerChangeEvent[P cmp.Ordered] struct { Kind PeerChangeKind Peer P From PeerState To PeerState }
PeerChangeEvent is a diff event over the membership cell. For PeerJoined and PeerDeparted, only Peer is meaningful; for PeerStateChanged, From/To carry the transition.
type PeerChangeKind ¶ added in v0.15.0
type PeerChangeKind int
PeerChangeKind discriminates the PeerChangeEvent variants.
const ( // PeerJoined — a previously unknown peer joined. PeerJoined PeerChangeKind = iota // PeerDeparted — a peer gracefully left. PeerDeparted // PeerStateChanged — a known peer transitioned between states. PeerStateChanged )
type PeerPermissions ¶
type PeerPermissions struct {
// contains filtered or unexported fields
}
PeerPermissions is a default-deny, per-peer allowlist of RemoteOp grants. The three OpKinds are gated independently. Non-allowlisted nodes are omitted entirely from a permission-filtered snapshot/delta (not redacted).
Like the Dart original, PeerPermissions is not safe for concurrent use.
func NewPeerPermissions ¶
func NewPeerPermissions() *PeerPermissions
NewPeerPermissions creates an empty allowlist.
func (*PeerPermissions) Allow ¶
func (p *PeerPermissions) Allow(peer PeerId, op RemoteOp) bool
Allow grants peer the op; returns whether this added a new grant.
func (*PeerPermissions) AllowMany ¶
func (p *PeerPermissions) AllowMany(peer PeerId, kind OpKind, nodes []NodeId)
AllowMany grants peer every node in nodes for kind.
func (*PeerPermissions) CanRead ¶
func (p *PeerPermissions) CanRead(peer PeerId, node NodeId) bool
CanRead reports whether peer may read node.
func (*PeerPermissions) Check ¶
func (p *PeerPermissions) Check(peer PeerId, op RemoteOp) error
Check returns a *PermissionDenied error unless peer holds op.
func (*PeerPermissions) FilterReadable ¶
func (p *PeerPermissions) FilterReadable(peer PeerId, nodes []NodeId) []NodeId
FilterReadable returns the readable subset of nodes for peer.
func (*PeerPermissions) IsAllowed ¶
func (p *PeerPermissions) IsAllowed(peer PeerId, op RemoteOp) bool
IsAllowed reports whether peer holds op.
func (*PeerPermissions) PeerCount ¶
func (p *PeerPermissions) PeerCount() int
PeerCount reports the number of peers with at least one grant.
func (*PeerPermissions) Revoke ¶
func (p *PeerPermissions) Revoke(peer PeerId, op RemoteOp) bool
Revoke removes a single grant; returns whether anything was removed.
func (*PeerPermissions) RevokePeer ¶
func (p *PeerPermissions) RevokePeer(peer PeerId) bool
RevokePeer drops every grant for peer; returns whether the peer was present.
type PeerState ¶ added in v0.15.0
type PeerState int
PeerState is the per-peer liveness state (SWIM).
type PermissionDenied ¶
PermissionDenied is returned by PeerPermissions.Check when Peer lacks Op.
func (*PermissionDenied) Error ¶
func (e *PermissionDenied) Error() string
type PhiAccrual ¶ added in v0.15.0
type PhiAccrual struct {
// contains filtered or unexported fields
}
PhiAccrual is a Phi-accrual failure detector over a sliding window of heartbeat inter-arrival times. phi is bit-portable across bindings via the Akka-style logistic approximation of the normal CDF.
func NewPhiAccrual ¶ added in v0.15.0
func NewPhiAccrual(maxSamples int, minStd float64) *PhiAccrual
NewPhiAccrual builds a detector with the given window bound and std floor.
func (*PhiAccrual) Heartbeat ¶ added in v0.15.0
func (d *PhiAccrual) Heartbeat(now uint64)
Heartbeat records a heartbeat arrival, appending its inter-arrival sample.
func (*PhiAccrual) Phi ¶ added in v0.15.0
func (d *PhiAccrual) Phi(now uint64) float64
Phi is the suspicion level at now. 0.0 when there is no estimate yet.
type Plane ¶ added in v0.15.0
type Plane int
Plane marks which plane a value lives on. Ephemeral values MUST NOT be persisted; Durable values may be written to the durable outbox. In lazily-rs these are the `Ephemeral`/`Durable` marker traits (a durable sink statically rejects an ephemeral value — a compile-fail doctest). Go has no equivalent static rejection, so the markers are exposed as simple plane constants.
type PnCounter ¶
type PnCounter struct {
// contains filtered or unexported fields
}
PnCounter is a positive-negative counter (state-based CvRDT). Each peer owns its own positive and negative components; the value is the sum of all positives minus the sum of all negatives. Merge is component-wise max.
func NewPnCounter ¶
NewPnCounter creates a counter owned by peer.
func (*PnCounter) Decrement ¶
func (c *PnCounter) Decrement()
Decrement adds 1 to this peer's negative component.
func (*PnCounter) DecrementBy ¶
DecrementBy adds amount to this peer's negative component.
func (*PnCounter) Increment ¶
func (c *PnCounter) Increment()
Increment adds 1 to this peer's positive component.
func (*PnCounter) IncrementBy ¶
IncrementBy adds amount to this peer's positive component.
type Position ¶
Position is a fractional-index position: (frac bytes, peer) ordered lexicographically. Frac bytes are 0..255.
type PresenceCell ¶ added in v0.15.0
type PresenceCell[K comparable, V comparable] struct { // contains filtered or unexported fields }
PresenceCell is reactive per-peer presence: heartbeat-kept, membership- and TTL-evicted. Present() is the live peer -> value map, invalidating only when the live view changes.
func NewPresenceCell ¶ added in v0.15.0
func NewPresenceCell[K comparable, V comparable](ctx *Context, ttl uint64) *PresenceCell[K, V]
NewPresenceCell builds a presence cell with a heartbeat TTL.
func (*PresenceCell[K, V]) Evict ¶ added in v0.15.0
func (c *PresenceCell[K, V]) Evict(peer K, now uint64)
Evict a peer on membership loss.
func (*PresenceCell[K, V]) Heartbeat ¶ added in v0.15.0
func (c *PresenceCell[K, V]) Heartbeat(peer K, value V, now uint64)
Heartbeat a peer's presence (expiring at now + ttl).
func (*PresenceCell[K, V]) Present ¶ added in v0.15.0
func (c *PresenceCell[K, V]) Present() map[K]V
Present returns the live peer -> value snapshot.
func (*PresenceCell[K, V]) PresentCell ¶ added in v0.15.0
func (c *PresenceCell[K, V]) PresentCell() *Source[uint64]
PresentCell exposes the internal version cell backing the present projection.
func (*PresenceCell[K, V]) Tick ¶ added in v0.15.0
func (c *PresenceCell[K, V]) Tick(now uint64)
Tick evicts peers whose TTL has lapsed.
type PriorityStorage ¶ added in v0.11.0
type PriorityStorage[T any] struct { // contains filtered or unexported fields }
PriorityStorage — Case 11, priority egress. Ingress carries a priority; egress pops the highest priority first (not FIFO), FIFO within equal priority. Reordering, so sound for a commutative merge downstream (reorder_adjacent).
func NewPriorityStorage ¶ added in v0.11.0
func NewPriorityStorage[T any]() *PriorityStorage[T]
NewPriorityStorage creates an empty priority storage.
func (*PriorityStorage[T]) IsEmpty ¶ added in v0.11.0
func (p *PriorityStorage[T]) IsEmpty() bool
IsEmpty reports whether the storage is empty.
func (*PriorityStorage[T]) Len ¶ added in v0.11.0
func (p *PriorityStorage[T]) Len() int
Len is the number of stored elements.
func (*PriorityStorage[T]) Pop ¶ added in v0.11.0
func (p *PriorityStorage[T]) Pop() (T, bool)
Pop removes and returns the highest-priority element (FIFO within equal priority). The second return is false when empty.
func (*PriorityStorage[T]) Push ¶ added in v0.11.0
func (p *PriorityStorage[T]) Push(priority uint64, value T)
Push adds a value at the given priority.
type ProbabilisticSampleCell ¶ added in v0.15.0
type ProbabilisticSampleCell[T comparable] struct { // contains filtered or unexported fields }
ProbabilisticSampleCell is the reactive probabilistic sampler; it owns an injectable SampleRng.
func NewProbabilisticSampleCell ¶ added in v0.15.0
func NewProbabilisticSampleCell[T comparable](ctx *Context, rate float64, rng SampleRng) *ProbabilisticSampleCell[T]
NewProbabilisticSampleCell builds a reactive probabilistic sampler bound to ctx.
func (*ProbabilisticSampleCell[T]) Input ¶ added in v0.15.0
func (c *ProbabilisticSampleCell[T]) Input(v T) Opt[T]
Input samples an input using the owned RNG.
func (*ProbabilisticSampleCell[T]) InputWithDraw ¶ added in v0.15.0
func (c *ProbabilisticSampleCell[T]) InputWithDraw(v T, draw float64) Opt[T]
InputWithDraw samples an input against an explicit draw (deterministic / conformance). Emits iff draw < rate.
func (*ProbabilisticSampleCell[T]) Output ¶ added in v0.15.0
func (c *ProbabilisticSampleCell[T]) Output() Opt[T]
Output returns the last emitted value (subscribes the current computation).
func (*ProbabilisticSampleCell[T]) OutputCell ¶ added in v0.15.0
func (c *ProbabilisticSampleCell[T]) OutputCell() *Source[Opt[T]]
OutputCell exposes the reader cell for invalidation observation.
type ProbabilisticSampleCore ¶ added in v0.15.0
type ProbabilisticSampleCore struct {
// contains filtered or unexported fields
}
ProbabilisticSampleCore is the tail-sampling compute core. A draw in [0, 1) passes iff draw < rate.
func NewProbabilisticSampleCore ¶ added in v0.15.0
func NewProbabilisticSampleCore(rate float64) ProbabilisticSampleCore
NewProbabilisticSampleCore builds a core with rate clamped to [0, 1].
func (ProbabilisticSampleCore) Decide ¶ added in v0.15.0
func (c ProbabilisticSampleCore) Decide(draw float64) bool
Decide reports whether an input with this random draw is sampled.
func (ProbabilisticSampleCore) Rate ¶ added in v0.15.0
func (c ProbabilisticSampleCore) Rate() float64
Rate returns the (clamped) sampling rate.
type Progress ¶ added in v0.8.0
type Progress struct {
// Sent is the count of data frames pushed to the sink this tick (fresh
// enqueues + reconnect replays).
Sent int
// Applied are inbound frames the host must fold into its projection.
Applied []IpcMessage
// ResyncRequested reports that a gap was detected inbound and a
// ResyncRequest was emitted to the peer.
ResyncRequested bool
// SnapshotsServed is the count of inbound ResyncRequests answered with a
// provider snapshot this tick.
SnapshotsServed int
// PeerAckedThrough is the peer's ack cursor after this tick (our outbox
// retention / resume point).
PeerAckedThrough Epoch
// Retained is the count of outbox frames still unacked (retained for
// reconnect replay).
Retained int
}
Progress is what one SyncDriver.Tick accomplished (spec § SyncDriver).
Applied are the inbound Snapshot/Delta/CrdtSync frames the host MUST fold into its projection this tick — the driver has already advanced the receiver cursor for them, so folding is the caller's remaining obligation.
type QueueCell ¶ added in v0.3.0
type QueueCell[T comparable, S QueueStorage[T]] struct { // contains filtered or unexported fields }
QueueCell is a reactive FIFO queue — a shell of reader-kind version cells layered over a pluggable QueueStorage backend (cell-model.md § Reactive queues).
The shell owns five reader-kind cells whose values are re-derived from storage after each successful op:
- Head — the current head value, or none when empty. Invalidated on every pop (the head value always changes) and on a push that transitions the queue from empty to non-empty (the head appears for the first time); NOT invalidated by a push to a non-empty queue (the head is unchanged).
- Len — the element count. Invalidated on every push and every pop that changes the count.
- IsEmpty — the emptiness flag. Invalidated when the queue transitions between empty and non-empty.
- IsFull — the fullness flag (bounded queues only). Invalidated when the queue transitions across the capacity boundary in either direction, so a consumer's pop that makes room wakes a producer's IsFull subscription (reactive backpressure).
- IsClosed — the closed flag. Invalidated only by the first Close (a terminal false→true transition); neither push nor pop touches it.
Reader-kind independence comes "for free" from the host Cell's PartialEq guard: after each op the shell re-derives all four content cells and writes them back inside one Context.Batch; a cell whose value did not change suppresses its cascade, so a push to a non-empty queue (head unchanged) invalidates Len/IsEmpty but not Head.
T must be comparable so the head cell's PartialEq guard can detect a head change; storage itself needs no equality. SPSC by construction; for MPSC, push inside Context.Batch.
func NewBoundedQueueCell ¶ added in v0.3.0
func NewBoundedQueueCell[T comparable](ctx *Context, capacity int) *QueueCell[T, *VecDequeStorage[T]]
NewBoundedQueueCell builds a bounded QueueCell with a VecDequeStorage of the given capacity. The queue exposes IsFull as a reactive reader (the backpressure signal): a pop that makes room invalidates IsFull readers. Panics if capacity <= 0.
func NewQueueCell ¶ added in v0.3.0
func NewQueueCell[T comparable](ctx *Context) *QueueCell[T, *VecDequeStorage[T]]
NewQueueCell builds an unbounded QueueCell with the default VecDequeStorage backend. The queue can grow without bound and has no IsFull reader to invalidate.
func NewQueueCellWithStorage ¶ added in v0.3.0
func NewQueueCellWithStorage[T comparable, S QueueStorage[T]](ctx *Context, storage S) *QueueCell[T, S]
NewQueueCellWithStorage builds a QueueCell over an arbitrary QueueStorage backend (custom ring buffer, broker client, consensus log, ...). The shell is storage-agnostic: it reads Len / IsClosed (the required contract) and, when the backend offers them, the optional PeekableStorage / BoundedStorage capabilities. Pass a pointer to your storage so the shell observes mutations.
func (*QueueCell[T, S]) Capacity ¶ added in v0.3.0
Capacity reports the bound and true for a bounded backend, or 0 and false for the unbounded default. Non-reactive (a queue's capacity never changes after construction).
func (*QueueCell[T, S]) Close ¶ added in v0.3.0
func (q *QueueCell[T, S]) Close()
Close marks the queue closed. Idempotent: closing an already-closed queue is a no-op that invalidates nothing. Terminal: a closed queue cannot reopen (the formal Closed_then_stays_Closed invariant). Neither push nor pop can change the closed flag.
func (*QueueCell[T, S]) Head ¶ added in v0.3.0
Head is the reactive head read. Subscribes the caller to the head reader-kind cell: it recomputes (is invalidated) on every pop and on a push that transitions empty→non-empty, but not on a push to a non-empty queue. Returns the head value and true, or the zero T and false when empty.
func (*QueueCell[T, S]) IsClosed ¶ added in v0.3.0
IsClosed is the reactive closed flag. Subscribes the caller to the closed reader-kind cell, which transitions only once (the first Close).
func (*QueueCell[T, S]) IsClosedUntracked ¶ added in v0.3.0
IsClosedUntracked reports the closed flag without subscribing the caller. Non-reactive.
func (*QueueCell[T, S]) IsEmpty ¶ added in v0.3.0
IsEmpty is the reactive emptiness flag. Subscribes the caller to the emptiness reader-kind cell.
func (*QueueCell[T, S]) IsFull ¶ added in v0.3.0
IsFull is the reactive fullness flag (bounded queues only). Subscribes the caller to the fullness reader-kind cell — the backpressure signal: a consumer's pop that makes room invalidates this reader so a push-side effect can resume without polling. An unbounded queue's IsFull is always false and never invalidates.
func (*QueueCell[T, S]) Len ¶ added in v0.3.0
Len is the reactive element count. Subscribes the caller to the length reader-kind cell.
func (*QueueCell[T, S]) LenUntracked ¶ added in v0.3.0
LenUntracked reports the current element count without subscribing the caller to the length reader-kind cell. Non-reactive.
func (*QueueCell[T, S]) ReaderHandles ¶ added in v0.3.0
func (q *QueueCell[T, S]) ReaderHandles() QueueReaderHandles[T]
ReaderHandles returns the five reader-kinds backing the reactive reads.
func (*QueueCell[T, S]) Storage ¶ added in v0.3.0
func (q *QueueCell[T, S]) Storage() S
Storage returns the backing QueueStorage. Exposed so callers can reach a backend-specific surface (e.g. (*VecDequeStorage[T]).Elements() for a snapshot, or a consensus backend's anti-entropy handle).
func (*QueueCell[T, S]) TryPop ¶ added in v0.3.0
func (q *QueueCell[T, S]) TryPop() (T, QueuePopError)
TryPop removes and returns the head element. A closed non-empty queue keeps draining (returns the next element); only a closed empty queue returns QueuePopClosed, and only an open empty queue returns QueuePopEmpty. On success the reader-kind cells are synced; a failed pop invalidates nothing.
func (*QueueCell[T, S]) TryPush ¶ added in v0.3.0
func (q *QueueCell[T, S]) TryPush(value T) QueuePushError
TryPush appends value to the tail. On success it syncs the reader-kind cells and returns QueuePushOk. On reject (Full / Closed) it leaves all readers untouched — a failed push invalidates nothing.
For MPSC, call TryPush inside a Context.Batch so the per-producer pushes appear as one atomic, coalesced transition to concurrent observers.
type QueuePopError ¶ added in v0.3.0
type QueuePopError string
QueuePopError is the failure mode of a pop attempt. The zero value (QueuePopOk, the empty string) means a value was returned.
- Empty — the queue is open but holds no elements.
- Closed — the queue is closed and empty. This is distinct from Empty so a consumer can tell "no work right now" from "no work will ever arrive" (the drain-completion signal).
const ( // QueuePopOk is the zero-value success sentinel (a value was popped). QueuePopOk QueuePopError = "" // QueuePopEmpty means the open queue had no element to pop. QueuePopEmpty QueuePopError = "Empty" // QueuePopClosed means a closed, empty queue was popped (drain complete). QueuePopClosed QueuePopError = "Closed" )
func (QueuePopError) Ok ¶ added in v0.3.0
func (e QueuePopError) Ok() bool
Ok reports whether the pop succeeded (the error is the zero value).
func (QueuePopError) String ¶ added in v0.3.0
func (e QueuePopError) String() string
String renders the fixture/wire label ("Empty" / "Closed"; "" for success).
type QueuePushError ¶ added in v0.3.0
type QueuePushError string
QueuePushError is the outcome of a push attempt. The zero value (QueuePushOk, the empty string) means success; the sentinels distinguish the two failure modes the observable contract separates.
- Full — the bounded queue is at capacity (overflow policy = reject, the default VecDequeStorage behavior; other backends may block / drop-oldest / drop-newest, but the shell only distinguishes Full from Empty/Closed).
- Closed — the queue is closed; push after close is an error.
const ( // QueuePushOk is the zero-value success sentinel (push accepted). QueuePushOk QueuePushError = "" // QueuePushFull means a bounded queue rejected the push at capacity. QueuePushFull QueuePushError = "Full" // QueuePushClosed means the push was rejected because the queue is closed. QueuePushClosed QueuePushError = "Closed" )
func (QueuePushError) Ok ¶ added in v0.3.0
func (e QueuePushError) Ok() bool
Ok reports whether the push succeeded (the error is the zero value).
func (QueuePushError) String ¶ added in v0.3.0
func (e QueuePushError) String() string
String renders the fixture/wire label ("Full" / "Closed"; "" for success).
type QueueReaderHandles ¶ added in v0.3.0
type QueueReaderHandles[T comparable] struct { Head *Computed[queueHead[T]] Len *Computed[int] IsEmpty *Computed[bool] IsFull *Computed[bool] IsClosed *Source[bool] }
QueueReaderHandles exposes the underlying reader-kinds directly, for advanced wiring (custom slots, effect dependency tracking, graph bridges). The four derived reader-kinds are demand-driven Slots; IsClosed is the Cell backing the closed flag (a direct input).
type QueueStorage ¶ added in v0.3.0
type QueueStorage[T any] interface { // TryPush appends value to the tail. Returns QueuePushOk on success, // QueuePushFull if a bounded queue is at capacity, or QueuePushClosed if // the queue is closed (push after close is rejected regardless of // capacity). TryPush(value T) QueuePushError // TryPop removes and returns the head element. On success it returns the // value and QueuePopOk. On an open empty queue it returns the zero T and // QueuePopEmpty; on a closed empty queue it returns the zero T and // QueuePopClosed (drain-complete). Pop on a closed non-empty queue keeps // draining — it returns the next element, not Closed. TryPop() (T, QueuePopError) // Len reports the number of elements currently held. Len() int // IsClosed reports whether the queue has been closed. Closure is monotonic // (once closed, stays closed). IsClosed() bool // Close marks the queue closed. Idempotent: closing an already-closed // queue is a no-op. Close is terminal: a closed queue cannot reopen. Close() }
QueueStorage is the backend contract a QueueCell reactive shell sits over (cell-model.md § Storage backend contract). A conforming backend:
- preserves FIFO order — TryPop returns elements in the order they were TryPush-ed (no reordering, no silent drops);
- exposes a native producer/consumer shape that is a superset of the shell's required SPSC shape (MPSC usage needs a multi-writer backend);
- optionally exposes a capacity: TryPush returns QueuePushFull when at capacity. The overflow policy is a backend property;
- phrases state over reader kind (head/len/empty/full), never exposing storage indices that could cause spurious invalidations when (say) a ring-buffer slot index wraps.
Invalidation is the shell's job, not the backend's: the backend reports raw state (Len / IsClosed) and the shell layers its own demand-driven reader-kinds above it.
Minimal required contract (Phase 0, #relaycell): TryPush / TryPop / Len / IsClosed / Close. Peek and Capacity are OPTIONAL capabilities — a backend that implements PeekableStorage[T] gains a Head reader; one that implements BoundedStorage gains an IsFull reader. A raw-channel-style backend that satisfies only QueueStorage is fully conforming (no Head, never full).
Implement QueueStorage with a pointer receiver so mutation is visible to the owning shell; pass that pointer as the QueueCell's S.
type RatePolicy ¶ added in v0.11.0
type RatePolicy struct {
// contains filtered or unexported fields
}
RatePolicy — Case 9, rate-limited egress (token bucket). A drain is permitted only when a token is available. Refilled refillPerTick tokens per logical tick, capped at capacity.
func NewRatePolicy ¶ added in v0.11.0
func NewRatePolicy(capacity, refillPerTick uint64) *RatePolicy
NewRatePolicy creates a token bucket that starts full.
func (*RatePolicy) Tick ¶ added in v0.11.0
func (r *RatePolicy) Tick()
Tick advances the logical clock, refilling the bucket (saturating at capacity).
func (*RatePolicy) Tokens ¶ added in v0.11.0
func (r *RatePolicy) Tokens() uint64
Tokens are the tokens currently available.
func (*RatePolicy) TryEgress ¶ added in v0.11.0
func (r *RatePolicy) TryEgress() bool
TryEgress consumes one token for an egress; returns true if paced through.
type ReactiveMap ¶ added in v0.7.0
type ReactiveMap[K comparable, V comparable, H any] struct { // contains filtered or unexported fields }
ReactiveMap is a keyed reactive collection generic over the entry handle kind H (*Cell[V] input cells or *Slot[V] derived slots): a hash map of K -> H with reactive membership and independently-tracked per-entry nodes.
Operations run against the owning Context, single-goroutine like the rest of lazily (the reactive graph is not itself synchronized). The three reactivity planes stay independent: writing one entry's value invalidates only that entry's readers; add/remove invalidates membership readers (Len / ContainsKey) and order readers (Keys); a pure reorder (atomic move) invalidates order readers only.
The handle-kind operations (mint / observe / clear) are supplied by the SourceMap / ComputedMap constructor — the Go analog of the Rust MapHandle trait.
func (*ReactiveMap[K, V, H]) ContainsKey ¶ added in v0.7.0
func (m *ReactiveMap[K, V, H]) ContainsKey(c ComputeOps, key K) bool
ContainsKey reports the reactive membership test for key. Subscribes the caller to membership changes (add/remove of any key), not to value changes.
func (*ReactiveMap[K, V, H]) EntryKind ¶ added in v0.7.0
func (m *ReactiveMap[K, V, H]) EntryKind() EntryKind
EntryKind returns this map's entry kind (EntryKindSource for a SourceMap, EntryKindComputed for a ComputedMap).
func (*ReactiveMap[K, V, H]) GetOrInsertWith ¶ added in v0.7.0
func (m *ReactiveMap[K, V, H]) GetOrInsertWith(c ComputeOps, key K, factory func(K) V) V
GetOrInsertWith returns the value at key, minting the entry via factory(key) first if absent — the mint-on-access recipe. For a ComputedMap this is the lazy materialization pull; for a SourceMap it seeds an input cell. Bumps reactive membership only on insert; an existing key returns its current value without re-running the factory.
func (*ReactiveMap[K, V, H]) Handle ¶ added in v0.7.0
func (m *ReactiveMap[K, V, H]) Handle(key K) (H, bool)
Handle returns the existing entry handle for key, or (zero, false). Non-reactive: does not subscribe the caller to membership.
func (*ReactiveMap[K, V, H]) IsEmpty ¶ added in v0.7.0
func (m *ReactiveMap[K, V, H]) IsEmpty(c ComputeOps) bool
IsEmpty reports the reactive emptiness check. Subscribes the caller to membership changes.
func (*ReactiveMap[K, V, H]) IsPresent ¶ added in v0.7.0
func (m *ReactiveMap[K, V, H]) IsPresent(key K) bool
IsPresent reports whether key is currently materialized (present in the allocated set). Non-reactive.
func (*ReactiveMap[K, V, H]) Keys ¶ added in v0.7.0
func (m *ReactiveMap[K, V, H]) Keys(c ComputeOps) []K
Keys returns a reactive snapshot of the keys in their current order. Subscribes the caller to order changes (add/remove and move/reorder), not to per-entry value changes.
func (*ReactiveMap[K, V, H]) Len ¶ added in v0.7.0
func (m *ReactiveMap[K, V, H]) Len(c ComputeOps) int
Len reports the reactive entry count. Subscribes the caller to membership changes only.
func (*ReactiveMap[K, V, H]) LenUntracked ¶ added in v0.7.0
func (m *ReactiveMap[K, V, H]) LenUntracked() int
LenUntracked reports the non-reactive count. Does not subscribe the caller to anything.
func (*ReactiveMap[K, V, H]) MoveAfter ¶ added in v0.7.0
func (m *ReactiveMap[K, V, H]) MoveAfter(key, anchor K) bool
MoveAfter atomically moves key to just after anchor (#lzcellmove).
func (*ReactiveMap[K, V, H]) MoveBefore ¶ added in v0.7.0
func (m *ReactiveMap[K, V, H]) MoveBefore(key, anchor K) bool
MoveBefore atomically moves key to just before anchor (#lzcellmove). Returns whether the move could be expressed.
func (*ReactiveMap[K, V, H]) MoveTo ¶ added in v0.7.0
func (m *ReactiveMap[K, V, H]) MoveTo(key K, index int) bool
MoveTo atomically moves key to index in the order (#lzcellmove).
This is the atomic, optimized reorder: the entry keeps the same node, the same dependents, and its CRDT lineage — unlike the naive Remove + re-mint which re-allocates the node and bumps membership twice. Only the order signal is bumped (once), so Keys readers recompute but Len / ContainsKey readers stay cached.
index is clamped to [0, len). A no-op move (already at position) bumps nothing. Returns whether key was present.
func (*ReactiveMap[K, V, H]) Observe ¶ added in v0.7.0
func (m *ReactiveMap[K, V, H]) Observe(c ComputeOps, key K) (V, bool)
Observe reads the value at key if present, subscribing the caller to that entry's node (reactive on that entry only). Returns (zero, false) if absent.
func (*ReactiveMap[K, V, H]) Position ¶ added in v0.7.0
func (m *ReactiveMap[K, V, H]) Position(key K) (int, bool)
Position reports the current 0-based position of key in the order, or false if absent. Non-reactive.
func (*ReactiveMap[K, V, H]) PresentCount ¶ added in v0.7.0
func (m *ReactiveMap[K, V, H]) PresentCount() int
PresentCount returns the number of currently-materialized entries. Non-reactive.
func (*ReactiveMap[K, V, H]) PresentKeys ¶ added in v0.7.0
func (m *ReactiveMap[K, V, H]) PresentKeys() []K
PresentKeys returns the currently-materialized keys in first-materialization order. Non-reactive; the present set only grows (deferral, not de-allocation).
func (*ReactiveMap[K, V, H]) Remove ¶ added in v0.7.0
func (m *ReactiveMap[K, V, H]) Remove(key K) bool
Remove removes key's entry. Bumps reactive membership and clears the removed entry's dependents. Returns whether the key was present.
The orphaned node stops driving any dependents; the runtime exposes no node-recycle yet (mirrors lazily-rs).
type ReadinessCell ¶ added in v0.15.0
type ReadinessCell struct {
// contains filtered or unexported fields
}
ReadinessCell is the reactive readiness projection onto a Cell for /ready.
func NewReadinessCell ¶ added in v0.15.0
func NewReadinessCell(ctx *Context) *ReadinessCell
NewReadinessCell creates a reactive readiness cell bound to ctx.
func (*ReadinessCell) Ready ¶ added in v0.15.0
func (r *ReadinessCell) Ready() bool
Ready reports whether the service is ready.
func (*ReadinessCell) ReadyCell ¶ added in v0.15.0
func (r *ReadinessCell) ReadyCell() *Source[bool]
ReadyCell returns the underlying reactive cell for /ready.
func (*ReadinessCell) Set ¶ added in v0.15.0
func (r *ReadinessCell) Set(name string, ready bool)
Set sets or refreshes a condition and refreshes the projection.
type ReadinessCore ¶ added in v0.15.0
type ReadinessCore struct {
// contains filtered or unexported fields
}
ReadinessCore is the composed readiness-probe core: ready iff every condition holds.
func NewReadinessCore ¶ added in v0.15.0
func NewReadinessCore() *ReadinessCore
NewReadinessCore creates an empty readiness core.
func (*ReadinessCore) Ready ¶ added in v0.15.0
func (c *ReadinessCore) Ready() bool
Ready reports whether every condition is ready.
func (*ReadinessCore) Set ¶ added in v0.15.0
func (c *ReadinessCore) Set(name string, ready bool)
Set sets or refreshes a condition.
type ReceiptApplyStatus ¶
type ReceiptApplyStatus interface {
// contains filtered or unexported methods
}
ReceiptApplyStatus is the result of observing a receipt into a ReceiptProjection. It is a sealed union realized as an interface with the concrete variants ReceiptRecorded / ReceiptDuplicate / ReceiptStaleGeneration / ReceiptTerminalConflict.
type ReceiptDuplicate ¶
type ReceiptDuplicate struct{}
ReceiptDuplicate means the receipt id was already seen (idempotent no-op).
type ReceiptOutcome ¶
type ReceiptOutcome string
ReceiptOutcome is the lifecycle outcome of a receipt. Serialized as its bare wire string; `observed`/`accepted` are non-terminal, `applied`/`rejected` are terminal.
const ( // ReceiptOutcomeObserved: a peer/process observed the causation request. ReceiptOutcomeObserved ReceiptOutcome = "observed" // ReceiptOutcomeAccepted: a peer/process accepted or queued the request. ReceiptOutcomeAccepted ReceiptOutcome = "accepted" // ReceiptOutcomeApplied: the requested effect/state change was applied // (terminal). ReceiptOutcomeApplied ReceiptOutcome = "applied" // ReceiptOutcomeRejected: the requested effect/state change was rejected // (terminal). ReceiptOutcomeRejected ReceiptOutcome = "rejected" )
func ReceiptOutcomeFromWire ¶
func ReceiptOutcomeFromWire(v string) (ReceiptOutcome, error)
ReceiptOutcomeFromWire parses a wire string into a ReceiptOutcome, rejecting unknown values.
func (ReceiptOutcome) IsTerminal ¶
func (o ReceiptOutcome) IsTerminal() bool
IsTerminal reports whether this outcome is terminal (no further transitions expected).
func (ReceiptOutcome) Wire ¶
func (o ReceiptOutcome) Wire() string
Wire returns the bare wire string of this outcome.
type ReceiptProjection ¶
type ReceiptProjection struct {
// contains filtered or unexported fields
}
ReceiptProjection is the folded receipt ledger: it tracks the latest and terminal receipt per causation id, deduplicates by receipt id, and retains stale (out-of-generation) receipt ids separately.
Like the sibling bindings, ReceiptProjection is not safe for concurrent use.
func NewReceiptProjection ¶
func NewReceiptProjection() *ReceiptProjection
NewReceiptProjection creates an empty projection.
func (*ReceiptProjection) ContainsReceipt ¶
func (p *ReceiptProjection) ContainsReceipt(receiptId string) bool
ContainsReceipt reports whether receiptId has been observed (recorded or stale).
func (*ReceiptProjection) CurrentGeneration ¶
func (p *ReceiptProjection) CurrentGeneration() int64
CurrentGeneration is the highest current generation observed so far.
func (*ReceiptProjection) LatestFor ¶
func (p *ReceiptProjection) LatestFor(causationId string) (CausalReceipt, bool)
LatestFor returns the latest recorded receipt for causationId, terminal or not, and whether one exists.
func (*ReceiptProjection) Observe ¶
func (p *ReceiptProjection) Observe(currentGeneration *int64, receipt CausalReceipt) ReceiptApplyStatus
Observe applies one receipt and returns its ReceiptApplyStatus.
When currentGeneration is non-nil, a receipt whose generation differs from it is retained only as a stale id and does not update the projection. When nil, the generation check is skipped (mirrors the canonical Option<u64> semantics).
Ordering (mirrors the Rust/JS reference):
- Duplicate: a receipt id already recorded or already stale is a no-op.
- StaleGeneration: generation mismatch -> record the id as stale.
- TerminalConflict: a differing terminal outcome for the same causation id fails closed and is not recorded.
- Otherwise: set terminal (first terminal wins), set latest, record by id.
func (*ReceiptProjection) ReceiptCount ¶
func (p *ReceiptProjection) ReceiptCount() int
ReceiptCount is the number of tracked receipts (recorded plus stale).
func (*ReceiptProjection) StaleReceiptIds ¶
func (p *ReceiptProjection) StaleReceiptIds() []string
StaleReceiptIds returns the receipt ids observed outside the current generation.
func (*ReceiptProjection) TerminalFor ¶
func (p *ReceiptProjection) TerminalFor(causationId string) (CausalReceipt, bool)
TerminalFor returns the terminal receipt for causationId and whether one exists.
type ReceiptRecorded ¶
type ReceiptRecorded struct{}
ReceiptRecorded means the receipt was recorded into the projection.
type ReceiptStaleGeneration ¶
type ReceiptStaleGeneration struct {
// Expected is the current authority generation.
Expected int64
// Actual is the generation carried by the receipt.
Actual int64
}
ReceiptStaleGeneration means the receipt's generation did not match the current authority generation; the receipt is retained only as a stale id and does not update the projection.
type ReceiptTerminalConflict ¶
type ReceiptTerminalConflict struct {
// CausationId is the causation id with conflicting terminal receipts.
CausationId string
// Existing is the already-recorded terminal outcome.
Existing ReceiptOutcome
// Incoming is the conflicting incoming terminal outcome.
Incoming ReceiptOutcome
}
ReceiptTerminalConflict means a different terminal outcome already exists for this causation id (fail-closed).
type RelayCell ¶ added in v0.11.0
type RelayCell[T comparable] struct { // contains filtered or unexported fields }
RelayCell is the algebra-typed conflating relay (Phase 2, in-proc core). The hot head is a cell; Depth/IsFull/IsEmpty are demand-driven slots, so an unobserved relay costs N·⊕ and no more (the merge cost law).
func NewRelayCell ¶ added in v0.11.0
func NewRelayCell[T comparable](ctx *Context, policy BackpressurePolicy, merge MergePolicy[T]) (*RelayCell[T], error)
NewRelayCell builds a relay over policy, validating the initial overflow against the merge policy's algebra flags (§4.3): Conflate requires merge.Conflates. Returns ErrConflateNotBounding otherwise.
func (*RelayCell[T]) Depth ¶ added in v0.11.0
Depth is the demand-driven reader: current window depth (Count).
func (*RelayCell[T]) DepthSlot ¶ added in v0.11.0
DepthSlot / IsFullSlot / IsEmptySlot expose the reader slots for wiring into effects and computations.
func (*RelayCell[T]) Drain ¶ added in v0.11.0
Drain takes the hot head's value and resets the window. The second return is false for an empty window. relay_converges guarantees the egress fold equals the flat fold of every ingested op, for any drain schedule.
func (*RelayCell[T]) Ingress ¶ added in v0.11.0
func (r *RelayCell[T]) Ingress(op T) IngressOutcome
Ingress ingests one op. Applies the reactive overflow policy when the window is at HighWater; otherwise merges the op into the hot head under the merge policy.
func (*RelayCell[T]) IsEmpty ¶ added in v0.11.0
IsEmpty is the demand-driven reader: window is empty (nothing to drain).
func (*RelayCell[T]) IsEmptySlot ¶ added in v0.11.0
func (*RelayCell[T]) IsFull ¶ added in v0.11.0
IsFull is the demand-driven reader: window is at/over HighWater.
func (*RelayCell[T]) IsFullSlot ¶ added in v0.11.0
func (*RelayCell[T]) OverflowIsLegal ¶ added in v0.11.0
OverflowIsLegal reports whether the current overflow choice is legal for the merge policy — a runtime guard mirroring NewRelayCell's construction check (the overflow cell is reactive).
type RelayConfigError ¶ added in v0.11.0
type RelayConfigError struct {
// contains filtered or unexported fields
}
RelayConfigError is why a construction/merge-swap was rejected (§4.3).
func (*RelayConfigError) Error ¶ added in v0.11.0
func (e *RelayConfigError) Error() string
type RemoteOp ¶
RemoteOp is a { kind, node } gated remote operation.
func TriggerEffectOp ¶
TriggerEffectOp constructs a trigger_effect RemoteOp.
type ResyncAction ¶ added in v0.8.0
type ResyncAction int
ResyncAction is the receiver decision for an inbound frame (spec § ResyncCoordinator). When the action is ResyncActionRequestSnapshot the ingest method also returns the from-epoch the sender must cover; the from-epoch is zero and meaningless for the other actions.
const ( // ResyncActionApply means apply the frame and advance the receiver epoch. ResyncActionApply ResyncAction = iota // ResyncActionRequestSnapshot means a gap was detected; request a fresh // Snapshot covering the returned from-epoch. ResyncActionRequestSnapshot // ResyncActionIgnore means drop the frame (already-applied re-delivery, // malformed, a duplicate request suppressed while resyncing, or a // reverse-channel control frame arriving at a data receiver). ResyncActionIgnore )
func (ResyncAction) String ¶ added in v0.8.0
func (a ResyncAction) String() string
String renders the action name (parity with the fixture expect_action words).
type ResyncCoordinator ¶ added in v0.8.0
type ResyncCoordinator struct {
// contains filtered or unexported fields
}
ResyncCoordinator is the receiver-side reliable-sync coordinator.
It holds lastEpoch (the highest epoch fully applied) and a resyncing flag (a RequestSnapshot is outstanding until a covering Snapshot lands, so further ahead-of-cursor deltas are ignored instead of re-requesting).
Ingest advances lastEpoch on Apply — the caller MUST fold the frame's ops into its projection on Apply. This mirrors the ReliableSync.step Lean model.
func NewResyncCoordinator ¶ added in v0.8.0
func NewResyncCoordinator() *ResyncCoordinator
NewResyncCoordinator returns a coordinator at epoch 0 (fresh; a Snapshot seeds the first real epoch).
func NewResyncCoordinatorWithEpoch ¶ added in v0.8.0
func NewResyncCoordinatorWithEpoch(lastEpoch Epoch) *ResyncCoordinator
NewResyncCoordinatorWithEpoch returns a coordinator that has already applied through lastEpoch.
func (*ResyncCoordinator) Ack ¶ added in v0.8.0
func (c *ResyncCoordinator) Ack() IpcMessage
Ack returns the OutboxAck control frame that advertises this receiver's resume cursor on reconnect (and for periodic retention advance).
func (*ResyncCoordinator) Ingest ¶ added in v0.8.0
func (c *ResyncCoordinator) Ingest(msg IpcMessage) (ResyncAction, Epoch)
Ingest classifies an inbound IpcMessage. CrdtSync is handled by the CRDT plane, and the reverse-channel control frames (ResyncRequest / OutboxAck) are for the sender's driver, not this data receiver, so both are Ignored here.
func (*ResyncCoordinator) IngestDelta ¶ added in v0.8.0
func (c *ResyncCoordinator) IngestDelta(delta Delta) (ResyncAction, Epoch)
IngestDelta classifies and folds an inbound Delta. On Apply this advances lastEpoch to delta.Epoch (multi-epoch-span aware) and clears resyncing. The second return value is the request-from epoch (only meaningful for ResyncActionRequestSnapshot).
func (*ResyncCoordinator) IngestSnapshot ¶ added in v0.8.0
func (c *ResyncCoordinator) IngestSnapshot(snapshotEpoch Epoch) (ResyncAction, Epoch)
IngestSnapshot adopts a Snapshot at snapshotEpoch — a full-state frame always applies, setting lastEpoch and clearing resyncing.
func (*ResyncCoordinator) IsResyncing ¶ added in v0.8.0
func (c *ResyncCoordinator) IsResyncing() bool
IsResyncing reports whether a resync request is outstanding (awaiting a covering snapshot).
func (*ResyncCoordinator) LastEpoch ¶ added in v0.8.0
func (c *ResyncCoordinator) LastEpoch() Epoch
LastEpoch returns the highest epoch fully applied.
type ResyncRequest ¶ added in v0.8.0
type ResyncRequest struct {
// FromEpoch is the requesting receiver's last_epoch; the sender replies with
// a Snapshot { epoch >= from_epoch }.
FromEpoch Epoch `json:"from_epoch"`
}
ResyncRequest is a reliable-sync reverse-channel control frame: request a covering Snapshot on a detected gap (#lzsync, spec § ResyncCoordinator). It carries no node content, so it is permission-filter- and blob-spill- transparent. Wire form: {"from_epoch": N}.
type RetryPolicyCell ¶ added in v0.15.0
type RetryPolicyCell struct {
// contains filtered or unexported fields
}
RetryPolicyCell is a reactive retry policy: projects the current delay onto a Cell.
func NewRetryPolicyCell ¶ added in v0.15.0
func NewRetryPolicyCell(ctx *Context, base, capacity uint64) *RetryPolicyCell
NewRetryPolicyCell builds a reactive retry policy.
func (*RetryPolicyCell) Delay ¶ added in v0.15.0
func (r *RetryPolicyCell) Delay() uint64
Delay returns the current projected delay.
func (*RetryPolicyCell) DelayCell ¶ added in v0.15.0
func (r *RetryPolicyCell) DelayCell() *Source[uint64]
DelayCell returns the reactive delay reader.
func (*RetryPolicyCell) NextDelay ¶ added in v0.15.0
func (r *RetryPolicyCell) NextDelay() uint64
NextDelay returns the current attempt's delay, advances, and projects it.
func (*RetryPolicyCell) Reset ¶ added in v0.15.0
func (r *RetryPolicyCell) Reset()
Reset resets the attempt counter and the projected delay.
type RetryPolicyCore ¶ added in v0.15.0
type RetryPolicyCore struct {
// contains filtered or unexported fields
}
RetryPolicyCore is the exponential-backoff compute core: delay(attempt) = min(cap, base*2^attempt), saturating to cap on shift overflow.
func NewRetryPolicyCore ¶ added in v0.15.0
func NewRetryPolicyCore(base, capacity uint64) *RetryPolicyCore
NewRetryPolicyCore builds a core.
func (*RetryPolicyCore) Delay ¶ added in v0.15.0
func (r *RetryPolicyCore) Delay(attempt uint32) uint64
Delay returns the delay for attempt, saturating at cap.
func (*RetryPolicyCore) NextDelay ¶ added in v0.15.0
func (r *RetryPolicyCore) NextDelay() uint64
NextDelay returns the current attempt's delay, then advances.
func (*RetryPolicyCore) Reset ¶ added in v0.15.0
func (r *RetryPolicyCore) Reset()
Reset resets the attempt counter.
type RevisionBarrier ¶ added in v0.25.0
type RevisionBarrier struct {
// contains filtered or unexported fields
}
RevisionBarrier separates the authoritative revision from its wake generation. Receipts may wake a waiter, but only an accepted revision advance mutates either observable counter.
func NewRevisionBarrier ¶ added in v0.25.0
func NewRevisionBarrier(revision, requiredRevision uint64, deadline *uint64) *RevisionBarrier
func (*RevisionBarrier) Advance ¶ added in v0.25.0
func (b *RevisionBarrier) Advance(revision uint64, predicate bool) RevisionBarrierObservation
func (*RevisionBarrier) Dispose ¶ added in v0.25.0
func (b *RevisionBarrier) Dispose() RevisionBarrierObservation
func (*RevisionBarrier) Observe ¶ added in v0.25.0
func (b *RevisionBarrier) Observe( now uint64, predicate bool, cancellation func() TimeoutCancellation, ) RevisionBarrierObservation
func (*RevisionBarrier) Receipt ¶ added in v0.25.0
func (b *RevisionBarrier) Receipt(string) RevisionBarrierObservation
Receipt is deliberately not an authority for barrier progress.
func (*RevisionBarrier) RegisterRecheck ¶ added in v0.25.0
func (b *RevisionBarrier) RegisterRecheck( now, observedRevision uint64, predicate bool, ) RevisionBarrierObservation
RegisterRecheck models register-then-recheck: a revision accepted during registration is applied before the predicate is checked.
type RevisionBarrierObservation ¶ added in v0.25.0
type RevisionBarrierObservation struct {
Outcome string
Reason string
Revision uint64
Generation uint64
}
RevisionBarrierObservation is the portable logical observation of a barrier.
type RoutedFrame ¶
type RoutedFrame struct {
ConnID any
Message ServerMessage
}
RoutedFrame pairs a target connection id with the ServerMessage to deliver on that connection. ConnID is an opaque, caller-supplied handle (mirroring the Dart `Object connId`); it must be a comparable value (usable as a map key).
func NewRoutedFrame ¶
func NewRoutedFrame(connID any, message ServerMessage) RoutedFrame
NewRoutedFrame constructs a RoutedFrame.
type SampleCell ¶ added in v0.15.0
type SampleCell[T comparable] struct { // contains filtered or unexported fields }
SampleCell is the reactive sampler over any comparable-valued source.
func NewSampleCell ¶ added in v0.15.0
func NewSampleCell[T comparable](ctx *Context, mode SampleMode) *SampleCell[T]
NewSampleCell builds a reactive sampler bound to ctx.
func (*SampleCell[T]) Input ¶ added in v0.15.0
func (c *SampleCell[T]) Input(v T) Opt[T]
Input records an input, returning the emitted value (if any).
func (*SampleCell[T]) Output ¶ added in v0.15.0
func (c *SampleCell[T]) Output() Opt[T]
Output returns the last emitted value (subscribes the current computation).
func (*SampleCell[T]) OutputCell ¶ added in v0.15.0
func (c *SampleCell[T]) OutputCell() *Source[Opt[T]]
OutputCell exposes the reader cell for invalidation observation.
func (*SampleCell[T]) Tick ¶ added in v0.15.0
func (c *SampleCell[T]) Tick(now uint64) Opt[T]
Tick advances the clock, returning the emitted value (if any).
type SampleCore ¶ added in v0.15.0
type SampleCore[T comparable] struct { // contains filtered or unexported fields }
SampleCore is the deterministic sampling compute core.
func NewSampleCore ¶ added in v0.15.0
func NewSampleCore[T comparable](mode SampleMode) *SampleCore[T]
NewSampleCore builds a sampling core.
func (*SampleCore[T]) Input ¶ added in v0.15.0
func (c *SampleCore[T]) Input(v T) Opt[T]
Input records an input. Count mode emits on every n-th; Time mode holds the latest for the next boundary.
func (*SampleCore[T]) Tick ¶ added in v0.15.0
func (c *SampleCore[T]) Tick(now uint64) Opt[T]
Tick advances. Time mode emits the held latest once per period boundary crossed.
type SampleKind ¶ added in v0.15.0
type SampleKind int
SampleKind selects count-based vs time-based sampling.
const ( // SampleCountKind: emit every n-th input. SampleCountKind SampleKind = iota // SampleTimeKind: emit the held latest at each period boundary. SampleTimeKind )
type SampleMode ¶ added in v0.15.0
type SampleMode struct {
Kind SampleKind
N uint64
Period uint64
}
SampleMode is the sampling mode for SampleCore — the Go analogue of rs `SampleMode::Count(n)` / `SampleMode::Time(period)`.
func SampleCount ¶ added in v0.15.0
func SampleCount(n uint64) SampleMode
SampleCount builds a count-based mode (emit every n-th input).
func SampleTime ¶ added in v0.15.0
func SampleTime(period uint64) SampleMode
SampleTime builds a time-based mode (emit at each period boundary).
type SampleRng ¶ added in v0.15.0
type SampleRng interface {
NextFloat64() float64
}
SampleRng is an injectable RNG so probabilistic sampling is deterministic under a fixed seed. NextFloat64 yields a draw in [0, 1).
type SemTree ¶
type SemTree[V comparable, D comparable] struct { // contains filtered or unexported fields }
SemTree is a memoized semantic tree.
Build via BuildSemTree. The child-slot map is fixed at build time; inserting a brand-new child requires a fresh build (mirrors lazily-rs/lazily-kt). Removals mutate the parent's child-keys cell.
func BuildSemTree ¶
func BuildSemTree[V comparable, D comparable]( ctx *Context, rootSpec TreeNodeSpec[V], fold FoldFn[V, D], ) *SemTree[V, D]
BuildSemTree builds a SemTree from rootSpec using fold.
func (*SemTree[V, D]) IsCached ¶
IsCached reports whether node id's derived value is currently cached.
func (*SemTree[V, D]) NodeHandle ¶
NodeHandle returns the slot handle for node id and true, or nil and false if the node is absent.
func (*SemTree[V, D]) NodeValue ¶
NodeValue returns the derived value of node id and true, or the zero value and false if the node is absent.
func (*SemTree[V, D]) RemoveChild ¶
RemoveChild removes childID from parentID's ordered children. Returns an error if the parent is absent.
func (*SemTree[V, D]) RootHandle ¶
RootHandle returns the root slot handle.
type SemaphoreCell ¶ added in v0.15.0
type SemaphoreCell struct {
// contains filtered or unexported fields
}
SemaphoreCell is a reactive semaphore: projects permits_available onto a Cell.
func NewSemaphoreCell ¶ added in v0.15.0
func NewSemaphoreCell(ctx *Context, capacity uint64) *SemaphoreCell
NewSemaphoreCell constructs a reactive semaphore of the given capacity.
func (*SemaphoreCell) Acquire ¶ added in v0.15.0
func (c *SemaphoreCell) Acquire() bool
Acquire takes a permit if one is available.
func (*SemaphoreCell) PermitsAvailable ¶ added in v0.15.0
func (c *SemaphoreCell) PermitsAvailable() uint64
PermitsAvailable returns the number of free permits.
func (*SemaphoreCell) PermitsAvailableCell ¶ added in v0.15.0
func (c *SemaphoreCell) PermitsAvailableCell() *Source[uint64]
PermitsAvailableCell exposes the reactive permits_available projection.
func (*SemaphoreCell) Release ¶ added in v0.15.0
func (c *SemaphoreCell) Release()
Release returns a permit, saturating at capacity.
type SemaphoreCore ¶ added in v0.15.0
type SemaphoreCore struct {
// contains filtered or unexported fields
}
SemaphoreCore is a bounded permit pool compute core.
func NewSemaphoreCore ¶ added in v0.15.0
func NewSemaphoreCore(capacity uint64) *SemaphoreCore
NewSemaphoreCore returns a permit pool of the given capacity.
func (*SemaphoreCore) Acquire ¶ added in v0.15.0
func (c *SemaphoreCore) Acquire() bool
Acquire takes a permit if one is available.
func (*SemaphoreCore) Available ¶ added in v0.15.0
func (c *SemaphoreCore) Available() uint64
Available returns the number of free permits.
func (*SemaphoreCore) Release ¶ added in v0.15.0
func (c *SemaphoreCore) Release()
Release returns a permit, saturating at capacity.
type SeqCrdt ¶
type SeqCrdt[Id comparable, V any] struct { // contains filtered or unexported fields }
SeqCrdt is a move-aware sequence CRDT. IDs are caller-supplied. Id must be comparable (it keys the entry map); V is unconstrained.
func NewSeqCrdt ¶
func NewSeqCrdt[Id comparable, V any](peer PeerId) *SeqCrdt[Id, V]
NewSeqCrdt creates an empty sequence CRDT for the given peer.
func (*SeqCrdt[Id, V]) EntryCount ¶
EntryCount returns the total entry count including tombstones.
func (*SeqCrdt[Id, V]) Fork ¶
Fork deep-copies the CRDT with a new peer id, preserving the clock state.
func (*SeqCrdt[Id, V]) GcWith ¶
GcWith garbage-collects entries whose tombstone is stable per isStable. Returns the number of removed entries.
func (*SeqCrdt[Id, V]) Get ¶
Get returns the value for id and true, or the zero value and false if the element is absent or tombstoned.
func (*SeqCrdt[Id, V]) InsertBack ¶
InsertBack inserts at the back (+∞).
func (*SeqCrdt[Id, V]) InsertBetween ¶
InsertBetween inserts a new element between left and right (nil means -∞/+∞). No-op if id already exists.
func (*SeqCrdt[Id, V]) InsertFront ¶
InsertFront inserts at the front (-∞).
func (*SeqCrdt[Id, V]) Merge ¶
Merge folds another replica's state into this one. Returns whether anything changed. The clock is advanced past every remote stamp first.
func (*SeqCrdt[Id, V]) MoveBefore ¶
MoveBefore moves id to just before anchor.
func (*SeqCrdt[Id, V]) MoveBetween ¶
MoveBetween moves id between left and right (nil means -∞/+∞) via a single LWW reassignment of the position register. Returns whether the move applied.
func (*SeqCrdt[Id, V]) Order ¶
func (s *SeqCrdt[Id, V]) Order() []Id
Order returns the live element ids in position order.
func (*SeqCrdt[Id, V]) TombstoneCount ¶
TombstoneCount returns the count of tombstoned elements.
type SeqValue ¶
type SeqValue[Id comparable, V any] struct { Id Id Value V }
SeqValue is a live (id, value) pair in position order, returned by SeqCrdt.Values.
type ServerAnswer ¶
ServerAnswer is a forwarded WebRTC SDP answer, stamped with the sender's From.
func (ServerAnswer) MarshalJSON ¶
func (m ServerAnswer) MarshalJSON() ([]byte, error)
func (ServerAnswer) Type ¶
func (ServerAnswer) Type() string
type ServerError ¶
ServerError reports a rejected client frame. Code is the wire string form of a SignalingErrorCode.
func (ServerError) MarshalJSON ¶
func (m ServerError) MarshalJSON() ([]byte, error)
func (ServerError) Type ¶
func (ServerError) Type() string
type ServerIce ¶
ServerIce is a forwarded ICE candidate, stamped with the sender's From.
func (ServerIce) MarshalJSON ¶
type ServerMessage ¶
type ServerMessage interface {
// Type returns the wire discriminant.
Type() string
MarshalJSON() ([]byte, error)
// contains filtered or unexported methods
}
ServerMessage is a server -> client signaling frame. It is a sealed union (mirroring the Dart `sealed class ServerMessage`); concrete variants are ServerWelcome/ServerPeerJoined/ServerPeerLeft/ServerOffer/ServerAnswer/ ServerIce/ServerRelay/ServerError. Decode wire bytes with ParseServerMessage; each variant implements MarshalJSON.
func ParseServerMessage ¶
func ParseServerMessage(data []byte) (ServerMessage, error)
ParseServerMessage decodes an internally-tagged server frame from JSON bytes.
type ServerOffer ¶
ServerOffer is a forwarded WebRTC SDP offer, stamped with the sender's From.
func (ServerOffer) MarshalJSON ¶
func (m ServerOffer) MarshalJSON() ([]byte, error)
func (ServerOffer) Type ¶
func (ServerOffer) Type() string
type ServerPeerJoined ¶
type ServerPeerJoined struct {
Peer PeerId
}
ServerPeerJoined notifies existing peers that a new peer joined.
func (ServerPeerJoined) MarshalJSON ¶
func (m ServerPeerJoined) MarshalJSON() ([]byte, error)
func (ServerPeerJoined) Type ¶
func (ServerPeerJoined) Type() string
type ServerPeerLeft ¶
type ServerPeerLeft struct {
Peer PeerId
}
ServerPeerLeft notifies remaining peers that a peer disconnected.
func (ServerPeerLeft) MarshalJSON ¶
func (m ServerPeerLeft) MarshalJSON() ([]byte, error)
func (ServerPeerLeft) Type ¶
func (ServerPeerLeft) Type() string
type ServerRelay ¶
type ServerRelay struct {
From PeerId
Payload json.RawMessage
}
ServerRelay is a forwarded opaque payload, stamped with the sender's From.
func (ServerRelay) MarshalJSON ¶
func (m ServerRelay) MarshalJSON() ([]byte, error)
func (ServerRelay) Type ¶
func (ServerRelay) Type() string
type ServerWelcome ¶
ServerWelcome is sent to a joiner with the roster (excluding self). Peers is always emitted, as [] when empty.
func (ServerWelcome) MarshalJSON ¶
func (m ServerWelcome) MarshalJSON() ([]byte, error)
func (ServerWelcome) Type ¶
func (ServerWelcome) Type() string
type ServiceRegistry ¶ added in v0.15.0
type ServiceRegistry struct {
// contains filtered or unexported fields
}
ServiceRegistry is the reactive durable service registry. The projection is a collection reader, so it uses the version-cell pattern.
func NewServiceRegistry ¶ added in v0.15.0
func NewServiceRegistry(ctx *Context) *ServiceRegistry
NewServiceRegistry creates a reactive durable registry bound to ctx.
func (*ServiceRegistry) Deregister ¶ added in v0.15.0
func (r *ServiceRegistry) Deregister(service string)
Deregister appends a deregister op and refreshes the projection.
func (*ServiceRegistry) Projection ¶ added in v0.15.0
func (r *ServiceRegistry) Projection() map[string]string
Projection returns the current projection, subscribing the reader to the version cell.
func (*ServiceRegistry) ProjectionCell ¶ added in v0.15.0
func (r *ServiceRegistry) ProjectionCell() *Source[uint64]
ProjectionCell returns the underlying version cell (the reactive handle).
func (*ServiceRegistry) Register ¶ added in v0.15.0
func (r *ServiceRegistry) Register(service string, endpoint string)
Register appends a register op and refreshes the projection.
func (*ServiceRegistry) Replay ¶ added in v0.15.0
func (r *ServiceRegistry) Replay()
Replay rebuilds the projection from the durable log and refreshes.
type ServiceRegistryCore ¶ added in v0.15.0
type ServiceRegistryCore struct {
// contains filtered or unexported fields
}
ServiceRegistryCore is the durable service-registry core: an ordered log (the DurableOutbox pattern) whose left-fold is the projection, so replay reconstructs it.
func NewServiceRegistryCore ¶ added in v0.15.0
func NewServiceRegistryCore() *ServiceRegistryCore
NewServiceRegistryCore creates an empty durable registry core.
func (*ServiceRegistryCore) Deregister ¶ added in v0.15.0
func (c *ServiceRegistryCore) Deregister(service string)
Deregister appends a deregister op to the log and updates the projection.
func (*ServiceRegistryCore) Projection ¶ added in v0.15.0
func (c *ServiceRegistryCore) Projection() map[string]string
Projection returns a snapshot of the current projection.
func (*ServiceRegistryCore) Register ¶ added in v0.15.0
func (c *ServiceRegistryCore) Register(service string, endpoint string)
Register appends a register op to the log and updates the projection.
func (*ServiceRegistryCore) Replay ¶ added in v0.15.0
func (c *ServiceRegistryCore) Replay()
Replay rebuilds the projection from the durable log (restart / crash-replay).
type SessionCore ¶ added in v0.15.0
type SessionCore[T comparable] struct { // contains filtered or unexported fields }
SessionCore is the gap-based sessionization compute core.
func NewSessionCore ¶ added in v0.15.0
func NewSessionCore[T comparable](gap uint64, policy MergePolicy[T]) *SessionCore[T]
NewSessionCore builds a session core closing sessions after an idle `gap`.
func (*SessionCore[T]) Flush ¶ added in v0.15.0
func (c *SessionCore[T]) Flush(now uint64) Opt[T]
Flush closes the open session if it has been idle longer than `gap`.
func (*SessionCore[T]) Push ¶ added in v0.15.0
func (c *SessionCore[T]) Push(now uint64, v T) Opt[T]
Push adds an element; a gap larger than `gap` closes the current session (emitting its fold) and opens a new one.
type SessionWindow ¶ added in v0.15.0
type SessionWindow[T comparable] struct { // contains filtered or unexported fields }
SessionWindow is a reactive gap-based session window (Push(now,v) + Flush(now)).
func Session ¶ added in v0.15.0
func Session[T comparable](ctx *Context, gap uint64, policy MergePolicy[T]) *SessionWindow[T]
Session constructs a reactive session window over ctx.
func (*SessionWindow[T]) Flush ¶ added in v0.15.0
func (w *SessionWindow[T]) Flush(now uint64) Opt[T]
Flush closes an idle-open session, projecting its fold onto output.
func (*SessionWindow[T]) Output ¶ added in v0.15.0
func (w *SessionWindow[T]) Output() Opt[T]
Output reads the last emitted aggregate (subscribes in a computation).
func (*SessionWindow[T]) OutputCell ¶ added in v0.15.0
func (w *SessionWindow[T]) OutputCell() *Source[Opt[T]]
OutputCell returns the reactive cell holding the last emitted aggregate.
func (*SessionWindow[T]) Push ¶ added in v0.15.0
func (w *SessionWindow[T]) Push(now uint64, v T) Opt[T]
Push adds an element; a large idle gap closes the session (projecting its fold onto output) and opens a new one.
type ShmBackend ¶ added in v0.4.0
type ShmBackend struct {
// contains filtered or unexported fields
}
ShmBackend is a POSIX shared-memory blob backend backed by a named /dev/shm region. It implements BlobBackend with cross-process resolution: a descriptor minted by Create's handle resolves against any Open handle mapping the same region. Not safe to use after Close.
func CreateShmBackend ¶ added in v0.4.0
func CreateShmBackend(name string, capacity int) (*ShmBackend, error)
CreateShmBackend creates (or truncates) a named POSIX shared-memory region of capacity bytes and maps it MAP_SHARED. The caller owns unlink timing — call UnlinkShmBackend(name) once no further readers/writers remain.
func OpenShmBackend ¶ added in v0.4.0
func OpenShmBackend(name string) (*ShmBackend, error)
OpenShmBackend opens (without creating) an existing named POSIX shared-memory region and maps it at the capacity recorded in its header. A distinct process uses this to resolve descriptors minted by the creator.
func (*ShmBackend) AdvanceEpoch ¶ added in v0.4.0
func (b *ShmBackend) AdvanceEpoch()
AdvanceEpoch advances the region's validity epoch, invalidating every prior descriptor across all mappings.
func (*ShmBackend) Capacity ¶ added in v0.4.0
func (b *ShmBackend) Capacity() int
Capacity returns the region's total byte capacity.
func (*ShmBackend) Close ¶ added in v0.4.0
func (b *ShmBackend) Close() error
Close unmaps the region and closes the descriptor. It does not unlink the name; call UnlinkShmBackend for that.
func (*ShmBackend) Epoch ¶ added in v0.4.0
func (b *ShmBackend) Epoch() int64
Epoch returns the backend's current validity epoch.
func (*ShmBackend) Kind ¶ added in v0.4.0
func (b *ShmBackend) Kind() BlobBackendKind
Kind reports BackendShm.
func (*ShmBackend) ReadView ¶ added in v0.4.0
func (b *ShmBackend) ReadView(descriptor ShmBlobRef) ([]byte, bool)
ReadView resolves a descriptor zero-copy against the shared region: it returns a slice aliasing the mapped bytes iff the slot header's generation / len / checksum and the region's current epoch all match; (nil, false) otherwise.
func (*ShmBackend) Write ¶ added in v0.4.0
func (b *ShmBackend) Write(bytes []byte) (ShmBlobRef, error)
Write bump-allocates a slot, copies bytes into shared memory, and returns a descriptor tagged BackendShm. The bump/generation counters are advanced with atomics, so concurrent writers across mappings never overlap.
type ShmBlobArena ¶
type ShmBlobArena struct {
// contains filtered or unexported fields
}
ShmBlobArena is an in-process shared-memory blob arena. It manages blob storage with generation/epoch tracking and header validation, handing out ShmBlobRef descriptors that callers exchange over the control transport in place of large inline payloads.
The zero value is not usable; construct one with NewShmBlobArena.
func NewShmBlobArena ¶
func NewShmBlobArena(epoch int64) *ShmBlobArena
NewShmBlobArena creates an empty arena starting at the given epoch (Dart's `ShmBlobArena({this.epoch = 0})`; pass 0 for the default).
func (*ShmBlobArena) AdvanceEpoch ¶
func (a *ShmBlobArena) AdvanceEpoch()
AdvanceEpoch bumps the arena epoch and restamps every live entry, so all previously-minted descriptors become stale (their Epoch no longer matches). Mirrors Dart `advanceEpoch`.
func (*ShmBlobArena) Epoch ¶
func (a *ShmBlobArena) Epoch() int64
Epoch returns the arena's current epoch. All descriptors carry the epoch that was current when they were minted; AdvanceEpoch invalidates them.
func (*ShmBlobArena) Free ¶
func (a *ShmBlobArena) Free(ref ShmBlobRef) bool
Free drops one reference to a blob and reports whether the reference was released. When the reference count reaches zero the slot is reclaimed (its descriptor becomes permanently stale); the offset index is preserved so other descriptors keep resolving to the correct slots. Returns false if ref is stale or already freed. This is a genuine-arena extension with no Dart equivalent (Dart's arena never frees).
func (*ShmBlobArena) IsEmpty ¶
func (a *ShmBlobArena) IsEmpty() bool
IsEmpty reports whether the arena holds no live blobs (Dart `isEmpty`).
func (*ShmBlobArena) Length ¶
func (a *ShmBlobArena) Length() int
Length returns the number of live (unfreed) stored blobs. With no Free calls this equals the number of Write calls, matching the Dart `length` getter.
func (*ShmBlobArena) Read ¶
func (a *ShmBlobArena) Read(ref ShmBlobRef) []byte
Read returns a blob's payload by descriptor, or nil if header validation fails (out-of-range offset, freed slot, or a mismatched generation, epoch, length, or checksum). The returned slice is a defensive copy. Mirrors Dart `read`, which returns null on validation failure.
func (*ShmBlobArena) ReadView ¶ added in v0.4.0
func (a *ShmBlobArena) ReadView(ref ShmBlobRef) ([]byte, bool)
ReadView resolves a descriptor zero-copy: it returns the arena's own backing payload slice (NOT a defensive copy) and ok=true iff the descriptor passes full header validation (offset in range, slot live, matching generation / epoch / len / checksum); otherwise (nil, false). This is the transport read_view primitive — the caller reads the backend's bytes in place. The returned slice aliases arena storage; the arena entry is immutable for the lifetime a descriptor may reference it (Write never mutates a stored buffer; Update/Free bump the generation, invalidating the descriptor), so the view is stable. Callers that intend to retain the bytes past a possible Free should copy. Contrast Read, which always copies.
func (*ShmBlobArena) Retain ¶
func (a *ShmBlobArena) Retain(ref ShmBlobRef) bool
Retain increments a live blob's reference count and reports success. It fails (returns false) when ref is stale or the slot is freed. This is a genuine-arena extension with no Dart equivalent.
func (*ShmBlobArena) Update ¶
func (a *ShmBlobArena) Update(ref ShmBlobRef, bytes []byte) *ShmBlobRef
Update rewrites an existing blob in place (bumping its generation) and returns the new descriptor, or nil if ref is stale. Mirrors Dart `update`: the payload buffer is overwritten from offset 0 and keeps its original length, so the new descriptor's Len matches the stored buffer, not len(bytes). bytes longer than the stored payload are truncated (Go copy semantics) instead of raising, keeping the operation recoverable.
func (*ShmBlobArena) Write ¶
func (a *ShmBlobArena) Write(bytes []byte) ShmBlobRef
Write allocates a blob and returns its descriptor. The payload bytes are copied into the arena; the returned ShmBlobRef is the header a reader validates. The blob starts with a reference count of one (mirrors Dart's `write`, which has no free path).
type ShmBlobRef ¶
type ShmBlobRef struct {
Offset int64 `json:"offset"`
Len int64 `json:"len"`
Generation int64 `json:"generation"`
Epoch int64 `json:"epoch"`
Checksum int64 `json:"checksum"`
Backend BlobBackendKind `json:"backend,omitempty"`
}
ShmBlobRef is a descriptor into a blob backend (zero-copy transport). The arena writes a fixed header { generation, epoch, length, checksum } before each payload; this struct is the wire mirror of that descriptor. The optional Backend discriminator selects which pluggable backend resolves it; it defaults to Shm and is omitted on the wire when default, so legacy descriptors validate unchanged (a strict superset of the pre-existing shared-memory blob path).
func NewShmBlobRef ¶
func NewShmBlobRef(offset, length, generation, epoch, checksum int64) (ShmBlobRef, error)
NewShmBlobRef constructs a ShmBlobRef, rejecting negative fields.
func (ShmBlobRef) MarshalJSON ¶ added in v0.4.0
func (r ShmBlobRef) MarshalJSON() ([]byte, error)
MarshalJSON emits the descriptor with fields in schema order, omitting the `backend` field when it is the default (Shm) so the wire form is a strict superset of the legacy backend-absent descriptor.
func (ShmBlobRef) String ¶
func (r ShmBlobRef) String() string
func (*ShmBlobRef) UnmarshalJSON ¶
func (r *ShmBlobRef) UnmarshalJSON(b []byte) error
UnmarshalJSON validates non-negative fields to match the Dart fromWire and normalizes the optional `backend` discriminator (absent or unknown → Shm).
func (ShmBlobRef) WithBackend ¶ added in v0.4.0
func (r ShmBlobRef) WithBackend(kind BlobBackendKind) ShmBlobRef
WithBackend returns a copy of the descriptor tagged with the given backend discriminator (the producer stamps this when spilling to a non-default backend; the receiver routes resolution by it).
type SignalingErrorCode ¶
type SignalingErrorCode string
SignalingErrorCode is the `code` of a ServerError frame. The string value is the wire form (snake_case), matching lazily-dart's enum wire tags.
const ( // SignalingErrorBadMessage is an unparseable / malformed client frame. SignalingErrorBadMessage SignalingErrorCode = "bad_message" // SignalingErrorNotJoined is a signaling frame from a connection that has // not joined the session. SignalingErrorNotJoined SignalingErrorCode = "not_joined" // SignalingErrorAlreadyJoined is a join from a connection that already // joined. SignalingErrorAlreadyJoined SignalingErrorCode = "already_joined" // SignalingErrorDuplicatePeer is a join for a peer id already present in the // session. SignalingErrorDuplicatePeer SignalingErrorCode = "duplicate_peer" // SignalingErrorUnknownTarget is a directed frame to a peer not in the // session. SignalingErrorUnknownTarget SignalingErrorCode = "unknown_target" // SignalingErrorPermissionDenied is an allowlist-gated join or directed // frame that was not granted. SignalingErrorPermissionDenied SignalingErrorCode = "permission_denied" )
func (SignalingErrorCode) Wire ¶
func (c SignalingErrorCode) Wire() string
Wire returns the on-wire string form of the error code.
type SignalingMode ¶
type SignalingMode string
SignalingMode is the permission mode for a signaling room.
const ( // SignalingModeOpen lets any peer join and signal any other joined peer. SignalingModeOpen SignalingMode = "open" // SignalingModeAllowlist is default-deny: peers require explicit grants, and // directed frames only reach allowed targets. SignalingModeAllowlist SignalingMode = "allowlist" )
type SignalingRoom ¶
type SignalingRoom struct {
// contains filtered or unexported fields
}
SignalingRoom is a transport-agnostic signaling room. A single owner goroutine owns all room and per-connection state; callers interact only through channels and the (channel-backed) methods below. It never interprets CRDT state.
func NewSignalingRoom ¶
func NewSignalingRoom(mode SignalingMode) *SignalingRoom
NewSignalingRoom starts a signaling room in the given mode and launches its owner goroutine. Call Close to stop the room and release its goroutines.
func (*SignalingRoom) AllowJoin ¶
func (r *SignalingRoom) AllowJoin(peer PeerId) error
AllowJoin grants peer permission to join in allowlist mode (no-op semantics in open mode, where every peer may already join).
func (*SignalingRoom) AllowSignal ¶
func (r *SignalingRoom) AllowSignal(from, target PeerId) error
AllowSignal grants from permission to send directed frames to target in allowlist mode.
func (*SignalingRoom) Close ¶
func (r *SignalingRoom) Close()
Close stops the room. It tears down every connection (closing outbound channels) and blocks until all owner/reader/pump goroutines have exited.
func (*SignalingRoom) Connect ¶
func (r *SignalingRoom) Connect(connID any) (*ClientConn, error)
Connect registers a connection under connID and returns its *ClientConn. The connID must be a comparable value. It errors if the room is closed or connID is already connected.
func (*SignalingRoom) Disconnect ¶
func (r *SignalingRoom) Disconnect(connID any) error
Disconnect tears down the connection connID, emitting peer-left to remaining peers and closing the connection's outbound channel.
func (*SignalingRoom) Roster ¶
func (r *SignalingRoom) Roster() []PeerId
Roster returns the joined peer ids, sorted ascending.
func (*SignalingRoom) Size ¶
func (r *SignalingRoom) Size() int
Size returns the number of joined peers.
type SlidingCore ¶ added in v0.15.0
type SlidingCore[T comparable] struct { // contains filtered or unexported fields }
SlidingCore is the count-based sliding window compute core (fold-recompute, correct for any associative merge).
func NewSlidingCore ¶ added in v0.15.0
func NewSlidingCore[T comparable](size int, slide uint64, policy MergePolicy[T]) *SlidingCore[T]
NewSlidingCore builds a sliding core retaining `size` elements, emitting every `slide` pushes.
func (*SlidingCore[T]) Push ¶ added in v0.15.0
func (c *SlidingCore[T]) Push(v T) Opt[T]
Push adds an element; every `slide` pushes emit the fold over the last `size`.
type SlidingWindow ¶ added in v0.15.0
type SlidingWindow[T comparable] struct { // contains filtered or unexported fields }
SlidingWindow is a reactive count-based sliding window projecting the last emitted aggregate.
func Sliding ¶ added in v0.15.0
func Sliding[T comparable](ctx *Context, size int, slide uint64, policy MergePolicy[T]) *SlidingWindow[T]
Sliding constructs a reactive sliding window over ctx.
func (*SlidingWindow[T]) Output ¶ added in v0.15.0
func (w *SlidingWindow[T]) Output() Opt[T]
Output reads the last emitted aggregate (subscribes in a computation).
func (*SlidingWindow[T]) OutputCell ¶ added in v0.15.0
func (w *SlidingWindow[T]) OutputCell() *Source[Opt[T]]
OutputCell returns the reactive cell holding the last emitted aggregate.
func (*SlidingWindow[T]) Push ¶ added in v0.15.0
func (w *SlidingWindow[T]) Push(v T) Opt[T]
Push adds an element, projecting the fold onto output on a slide boundary.
type SlotMap
deprecated
added in
v0.7.0
type SlotMap[K comparable, V comparable] = ComputedMap[K, V]
SlotMap is the pre-v2-kernel name for ComputedMap, kept as an alias so existing callers keep compiling.
Deprecated: renamed to ComputedMap.
type Snapshot ¶
type Snapshot struct {
Epoch Epoch
Nodes []NodeSnapshot
Edges []EdgeSnapshot
Roots []NodeId
}
Snapshot is the full graph state, sent on connect and on resync.
func (Snapshot) FilterReadable ¶
func (s Snapshot) FilterReadable(permissions *PeerPermissions, peer PeerId) Snapshot
FilterReadable drops non-readable nodes/edges/roots before serialization (omission, not redaction — protocol.md § Permission Boundary).
func (Snapshot) MarshalJSON ¶
MarshalJSON emits { epoch, nodes, edges, roots }, always as arrays (never null) to match the Dart toWire.
func (*Snapshot) UnmarshalJSON ¶
type SnapshotProvider ¶ added in v0.8.0
type SnapshotProvider interface {
// Snapshot returns a full-state IpcMessageSnapshot covering fromEpoch (its
// epoch MUST be >= fromEpoch).
Snapshot(fromEpoch Epoch) IpcMessage
}
SnapshotProvider is the sender-side answer to a peer's ResyncRequest (spec § SyncDriver). When a receiver detects a gap it can no longer close from retained deltas, it asks for a covering Snapshot; the host plugs its projection in here to produce one at epoch >= fromEpoch.
type Source ¶ added in v0.10.0
type Source[T comparable] struct { // contains filtered or unexported fields }
Source is a value written from outside the graph; it invalidates its dependents when it changes. It is the source kind of the Cell genus (Cell[T]): the only kind that carries Set/Merge. A Computed computes from upstream and has neither, so `formulaCell.Set(…)` does not compile — the write protection the Cell kernel design (§3/§4) puts in the type rather than a runtime gate.
A Source folds writes under a MergePolicy M. The default policy is KeepLatest, so a plain Source is exactly the old plain Cell; a Source with M ≠ KeepLatest is the old MergeCell. One kind, the policy in a field — the Go analogue of the design's Source<T, M>.
Reading Get inside a Computed/Effect computation registers a dependency. Set triggers a cascade only when the new value is not equal to the old one — the ==-guard. Source uses Go == for equality, so T must be comparable.
func NewSource ¶ added in v0.21.0
func NewSource[T comparable](ctx *Context, initial T) *Source[T]
NewSource creates a mutable source cell bound to ctx under the default KeepLatest policy (the plain cell). This is the design's source(v).
func NewSourceWithPolicy ¶ added in v0.21.0
func NewSourceWithPolicy[T comparable](ctx *Context, initial T, policy MergePolicy[T]) *Source[T]
NewSourceWithPolicy creates a source cell whose Merge folds under policy — the design's source::<M>(v). With KeepLatest it is a plain cell; with Sum/Max it is the former MergeCell.
func (*Source[T]) Dispose ¶ added in v0.21.0
func (c *Source[T]) Dispose()
Dispose tears down this source cell: detaches its dependents and dirties the surviving cone. Cells have no dependencies, so only downstream edges need detaching. Same contract as Slot.Dispose. Idempotent.
func (*Source[T]) Get ¶ added in v0.21.0
func (c *Source[T]) Get() T
Get reads the value. Reading inside a computation subscribes the reader.
Panics with a *DisposedError if this cell has been disposed; use TryGet for the checked form.
func (*Source[T]) Invalidate ¶ added in v0.21.0
func (c *Source[T]) Invalidate()
Invalidate force-invalidates this cell's dependents without changing the value. Used by collection layers when an entry is removed.
func (*Source[T]) Merge ¶ added in v0.10.0
func (c *Source[T]) Merge(op T)
Merge folds op into the current value under this cell's policy and writes the result through the ==-guarded Set, so an idempotent policy's no-op merge fires no cascade (free dedup). Reads the current value untracked (Peek). Merge, like Set, exists only on Source — the write half of the Cell genus.
func (*Source[T]) Peek ¶ added in v0.21.0
func (c *Source[T]) Peek() T
Peek returns the current value without registering a dependency.
func (*Source[T]) Policy ¶ added in v0.21.0
func (c *Source[T]) Policy() MergePolicy[T]
Policy returns this cell's merge policy.
type SourceMap ¶ added in v0.22.0
type SourceMap[K comparable, V comparable] struct { *ReactiveMap[K, V, *Source[V]] }
SourceMap is the input-cell specialization of ReactiveMap: a keyed collection of reactive cells with independent value / membership / order reactivity (cell-model.md § Keyed cell collections).
Each entry is an ordinary Cell[V]; the collection adds no new merge unit. The shared reactive-membership / order / move / remove surface is inherited from the embedded ReactiveMap; SourceMap adds the cell-only Set and eager value-minting (Entry / EntryWith), plus the Go-specific Insert / Reconcile keyed-reconciliation helpers.
- Keys subscribes only to the order signal;
- Len / ContainsKey subscribe only to the membership signal;
- a value read subscribes only to that entry's cell.
An atomic move (MoveTo / MoveBefore / MoveAfter, inherited) bumps only the order signal once and keeps the moved entry's same Cell handle, dependents, and lineage — it is not a remove + re-mint.
func NewCellMap
deprecated
func NewCellMap[K comparable, V comparable](ctx *Context) *SourceMap[K, V]
NewCellMap creates an empty keyed cell collection bound to ctx.
Deprecated: renamed to NewSourceMap.
func NewSourceMap ¶ added in v0.22.0
func NewSourceMap[K comparable, V comparable](ctx *Context) *SourceMap[K, V]
NewSourceMap creates an empty keyed cell collection bound to ctx.
func (*SourceMap[K, V]) Cell ¶ added in v0.22.0
Cell returns the existing value cell for key, or nil. Non-reactive: does not subscribe the caller to membership.
func (*SourceMap[K, V]) Entry ¶ added in v0.22.0
Entry returns the value cell for key, minting it with defaultValue on first access. Convenience wrapper over EntryWith.
func (*SourceMap[K, V]) EntryWith ¶ added in v0.22.0
EntryWith returns the value cell for key, minting it with defaultValue() on first access. Adding a new key bumps reactive membership; re-fetching an existing key does not.
func (*SourceMap[K, V]) Get ¶ added in v0.22.0
Get reads the value at key if present (peek). Non-reactive.
func (*SourceMap[K, V]) Insert ¶ added in v0.22.0
Insert inserts key with value at the position specified by at (relative to anchor for InsertAtBefore / InsertAtAfter; anchor is ignored otherwise). Bumps membership + order. Returns whether the key was newly inserted (false if it already existed; in that case the value is updated in place and only the entry's value readers invalidate).
Go lacks Dart's optional named args: pass InsertAtEnd with a zero anchor for the common append case.
func (*SourceMap[K, V]) Read ¶ added in v0.22.0
Read reads the value at key if present, subscribing the caller to that entry's cell (reactive inside a Slot / Signal computation).
func (*SourceMap[K, V]) Reconcile ¶ added in v0.22.0
func (m *SourceMap[K, V]) Reconcile(targetOrder []K, targetValues map[K]V)
Reconcile reconciles to targetOrder + targetValues: compute the minimal diff and apply it per-cell. Stable entries (unchanged value, in the LIS) keep their cell handles and stay cached.
func (*SourceMap[K, V]) Set ¶ added in v0.22.0
func (m *SourceMap[K, V]) Set(key K, value V)
Set assigns the value at key, inserting a new entry (and bumping membership) if it does not exist yet. Updating an existing entry leaves membership untouched and invalidates only that entry's dependents.
Cell-only: an input is settable; a derived ComputedMap slot is not.
type SourceTree ¶ added in v0.23.0
type SourceTree[K comparable, V comparable] struct { ID K Value *Source[V] Children *SourceMap[K, *SourceTree[K, V]] // contains filtered or unexported fields }
SourceTree is an ordered keyed tree (cell-model.md § Ordered keyed tree).
Each node is (stable id, value cell, ordered keyed child collection). A node's children are a SourceMap keyed by child id, so per-level membership/order reactivity and the atomic-move guarantee are inherited. The tree is still a composition of cells — not a new cell kind — so per-cell merge applies node-by-node. Recursive, mirroring lazily-rs/src/cell_tree.rs.
func NewCellTree
deprecated
func NewCellTree[K comparable, V comparable](ctx *Context, id K, initialValue V) *SourceTree[K, V]
NewCellTree creates a tree node with id and initialValue and an empty child collection.
Deprecated: renamed to NewSourceTree.
func NewSourceTree ¶ added in v0.23.0
func NewSourceTree[K comparable, V comparable](ctx *Context, id K, initialValue V) *SourceTree[K, V]
NewSourceTree creates a tree node with id and initialValue and an empty child collection.
func (*SourceTree[K, V]) Child ¶ added in v0.23.0
func (t *SourceTree[K, V]) Child(id K) *SourceTree[K, V]
Child returns the child node for id, or nil. Non-reactive.
func (*SourceTree[K, V]) ChildCount ¶ added in v0.23.0
func (t *SourceTree[K, V]) ChildCount(c ComputeOps) int
ChildCount returns the reactive child count for this node.
func (*SourceTree[K, V]) ChildIDs ¶ added in v0.23.0
func (t *SourceTree[K, V]) ChildIDs(c ComputeOps) []K
ChildIDs returns a reactive snapshot of this node's child ids in order.
func (*SourceTree[K, V]) Get ¶ added in v0.23.0
func (t *SourceTree[K, V]) Get() V
Get reads this node's value (reactive).
func (*SourceTree[K, V]) HasChild ¶ added in v0.23.0
func (t *SourceTree[K, V]) HasChild(c ComputeOps, id K) bool
HasChild reports the reactive membership test for a child of this node.
func (*SourceTree[K, V]) InsertChild ¶ added in v0.23.0
func (t *SourceTree[K, V]) InsertChild(id K, value V) *SourceTree[K, V]
InsertChild inserts a fresh child id with value, returning the child node. If the child already exists, its value is updated and the existing node returned.
func (*SourceTree[K, V]) MoveChildAfter ¶ added in v0.23.0
func (t *SourceTree[K, V]) MoveChildAfter(id, anchor K) bool
MoveChildAfter atomically moves child id to just after anchor.
func (*SourceTree[K, V]) MoveChildBefore ¶ added in v0.23.0
func (t *SourceTree[K, V]) MoveChildBefore(id, anchor K) bool
MoveChildBefore atomically moves child id to just before anchor.
func (*SourceTree[K, V]) MoveChildTo ¶ added in v0.23.0
func (t *SourceTree[K, V]) MoveChildTo(id K, index int) bool
MoveChildTo atomically moves child id to index within this node's children.
func (*SourceTree[K, V]) NodeID ¶ added in v0.23.0
func (t *SourceTree[K, V]) NodeID() K
NodeID returns the id of this node (stable handle).
func (*SourceTree[K, V]) RemoveChild ¶ added in v0.23.0
func (t *SourceTree[K, V]) RemoveChild(id K) bool
RemoveChild removes the child id. Returns whether it was present.
func (*SourceTree[K, V]) Set ¶ added in v0.23.0
func (t *SourceTree[K, V]) Set(next V)
Set sets this node's value (PartialEq-guarded).
type SpillMode ¶ added in v0.11.0
type SpillMode string
SpillMode is how spilled windows are laid out on the durable tail (§6).
const ( // SpillCompactOnWrite merges each spilled window into the open page until it // fills — minimizes disk (keep-latest / semilattice). One page holds a // coalesced run. SpillCompactOnWrite SpillMode = "CompactOnWrite" // SpillAppendCompact appends each spilled window as its own page — preserves // increments for an accumulating (non-idempotent) policy that must not // double-count. SpillAppendCompact SpillMode = "AppendCompact" )
type SpillPage ¶ added in v0.11.0
SpillPage is one immutable cold page: a coalesced window summary plus its manifest entry.
type SpillStore ¶ added in v0.11.0
type SpillStore[T any] struct { // contains filtered or unexported fields }
SpillStore is a paged durable tail for a RelayCell (Phase 3, in-memory reference backend). Holds immutable cold pages, a bounded manifest, an egress cursor, and ack-before-reclaim. Memory is O(hot) + O(manifest).
func NewSpillStore ¶ added in v0.11.0
func NewSpillStore[T any](mode SpillMode, pageSize uint64, merge MergePolicy[T]) *SpillStore[T]
NewSpillStore creates a spill store in the given mode with the given page size.
func (*SpillStore[T]) AckThrough ¶ added in v0.11.0
func (s *SpillStore[T]) AckThrough(id uint64)
AckThrough acks every page through id (inclusive), advancing the reclaim cursor.
func (*SpillStore[T]) FoldPages ¶ added in v0.11.0
func (s *SpillStore[T]) FoldPages(s0 T) T
FoldPages folds every live cold page (oldest first) into s0 — the durable tail's contribution to the converged state.
func (*SpillStore[T]) Manifest ¶ added in v0.11.0
func (s *SpillStore[T]) Manifest() []ManifestEntry
Manifest returns (id, bytes) for every live page (bounded metadata).
func (*SpillStore[T]) PageCount ¶ added in v0.11.0
func (s *SpillStore[T]) PageCount() int
PageCount is the number of live pages.
func (*SpillStore[T]) PendingPages ¶ added in v0.11.0
func (s *SpillStore[T]) PendingPages() []SpillPage[T]
PendingPages returns the pages the egress has not yet acked (at/after cursor).
func (*SpillStore[T]) Reclaim ¶ added in v0.11.0
func (s *SpillStore[T]) Reclaim()
Reclaim drops acked pages (durable reclaim). Manifest/cursor stay consistent.
func (*SpillStore[T]) Reconstruct ¶ added in v0.11.0
func (s *SpillStore[T]) Reconstruct(s0 T, hot T, hasHot bool) T
Reconstruct (spill_lossless) folds the cold tail then the hot head, reproducing the flat fold of every op the relay ever ingested. hasHot=false means an empty hot window.
func (*SpillStore[T]) ReplayUnacked ¶ added in v0.11.0
func (s *SpillStore[T]) ReplayUnacked(downstream T) T
ReplayUnacked (crash replay) re-delivers every unacked page from the ack cursor into downstream. For an idempotent policy re-applying an already-delivered page is a no-op (spill_replay_idempotent), so at-least-once replay converges.
func (*SpillStore[T]) Spill ¶ added in v0.11.0
func (s *SpillStore[T]) Spill(window T, bytes uint64)
Spill writes one coalesced window summary to the durable tail. AppendCompact always opens a new page; CompactOnWrite merges into the open page until it reaches pageSize, then seals it.
type StaleComputeError ¶ added in v0.21.0
type StaleComputeError struct {
// contains filtered or unexported fields
}
StaleComputeError is raised when a Compute view is used outside the recompute it belongs to — the runtime half of the non-escapability guarantee (Go cannot bind the view by lifetime the way lazily-rs does).
func (*StaleComputeError) Error ¶ added in v0.21.0
func (e *StaleComputeError) Error() string
type StampFrontier ¶
type StampFrontier struct {
// contains filtered or unexported fields
}
StampFrontier is the per-peer stamp frontier: the highest HlcStamp observed from each peer.
Mirrors lazily-rs StampFrontier (a BTreeMap<PeerId, HlcStamp>). The merge laws (commutative, associative, idempotent) are formally proven (stampJoin_{comm,assoc,idem}): fold Observe over an incoming frontier in any order and the result is identical.
func NewStampFrontier ¶
func NewStampFrontier() *StampFrontier
NewStampFrontier creates an empty frontier.
func StampFrontierFromWire ¶
func StampFrontierFromWire(entries []StampFrontierEntry) *StampFrontier
StampFrontierFromWire builds a frontier from (peer, stamp) wire entries.
func (*StampFrontier) Get ¶
func (f *StampFrontier) Get(peer PeerId) (HlcStamp, bool)
Get returns the highest stamp observed for peer, and whether it was observed.
func (*StampFrontier) Knows ¶
func (f *StampFrontier) Knows(peer PeerId) bool
Knows reports whether peer has been observed.
func (*StampFrontier) Merge ¶
func (f *StampFrontier) Merge(other *StampFrontier) bool
Merge folds Observe over other. Commutative, associative, idempotent. Returns whether anything changed.
func (*StampFrontier) Observe ¶
func (f *StampFrontier) Observe(peer PeerId, stamp HlcStamp) bool
Observe folds one observation: keep the per-peer max. Idempotent — older or equal stamps are ignored. Returns whether the frontier changed.
func (*StampFrontier) Peers ¶
func (f *StampFrontier) Peers() []PeerId
Peers returns the set of peers this frontier has observed, sorted by peer id for deterministic iteration.
func (*StampFrontier) ToWire ¶
func (f *StampFrontier) ToWire() []StampFrontierEntry
ToWire emits the wire form: one StampFrontierEntry per observed peer, sorted by peer id for deterministic output.
func (*StampFrontier) Watermark ¶
func (f *StampFrontier) Watermark(membership []PeerId) (HlcStamp, bool)
Watermark is the causal-stability watermark: the min over the given membership's observed stamps. The second return is false until every member has been observed — a single unseen member means the frontier is not yet causally complete (formally: collectable_implies_observed_everywhere).
type StampFrontierEntry ¶
StampFrontierEntry is a (peer, WireStamp) entry in the per-peer stamp frontier. On the wire this is a 2-tuple array [peer, stamp] (per distributed.json#/$defs/StampFrontierEntry prefixItems), not a {peer, stamp} object — mirroring lazily-rs's Vec<(u64, WireStamp)> serde representation.
func (StampFrontierEntry) MarshalJSON ¶
func (e StampFrontierEntry) MarshalJSON() ([]byte, error)
func (StampFrontierEntry) String ¶
func (e StampFrontierEntry) String() string
func (*StampFrontierEntry) UnmarshalJSON ¶
func (e *StampFrontierEntry) UnmarshalJSON(b []byte) error
type StateChart ¶
type StateChart struct {
// contains filtered or unexported fields
}
StateChart is a reactive full-Harel state chart backed by a configuration Cell.
Construct via NewStateChart (descending the root's initial configuration, recording initial entry actions). Drive with Send; query with Configuration, ActiveLeaves, Matches; inspect the last step's action trace with LastActions.
func NewStateChart ¶
func NewStateChart(ctx *Context, def *ChartDef) *StateChart
NewStateChart creates a chart bound to ctx that enters the initial configuration by descending from def's root.
func (*StateChart) ActiveLeaves ¶
func (sc *StateChart) ActiveLeaves() []string
ActiveLeaves returns the active atomic leaves, sorted (one per parallel region; one for a single-region chart).
func (*StateChart) Configuration ¶
func (sc *StateChart) Configuration() Configuration
Configuration returns the full active configuration (active leaves plus all active ancestors). Reading inside a computation subscribes the reader.
func (*StateChart) Ctx ¶
func (sc *StateChart) Ctx() *Context
Ctx returns the reactive context this chart belongs to.
func (*StateChart) Def ¶
func (sc *StateChart) Def() *ChartDef
Def returns the parsed chart definition.
func (*StateChart) LastActions ¶
func (sc *StateChart) LastActions() []string
LastActions returns the ordered action names fired by the initial entry or the most recent Send (exit innermost-first -> transition -> entry outermost-first).
func (*StateChart) Matches ¶
func (sc *StateChart) Matches(id string) bool
Matches is the hierarchical "state-in" predicate: true iff id is in the active configuration. Reading inside a computation subscribes the reader.
func (*StateChart) Send ¶
func (sc *StateChart) Send(event string, guards map[string]bool) bool
Send delivers an event (run-to-completion). It returns true if any transition was taken, false if rejected (configuration unchanged, no actions fired).
guards resolves named guards for this send (absent/unknown name -> fail-closed false). Pass nil for no guards.
func (*StateChart) String ¶
func (sc *StateChart) String() string
String renders the chart as its active leaves.
type StateMachine ¶
type StateMachine[S comparable, E comparable] struct { // contains filtered or unexported fields }
StateMachine is a flat finite state machine whose current state lives in a reactive Cell. Reading State inside a computation subscribes the reader, so downstream reactives recompute when the machine transitions to a different state.
func NewStateMachine ¶
func NewStateMachine[S comparable, E comparable](ctx *Context, initial S, transition Transition[S, E]) *StateMachine[S, E]
NewStateMachine creates a machine bound to ctx with the given initial state and transition function.
func (*StateMachine[S, E]) Cell ¶
func (m *StateMachine[S, E]) Cell() *Source[S]
Cell returns the underlying Cell holding the state value.
func (*StateMachine[S, E]) OnTransition ¶
func (m *StateMachine[S, E]) OnTransition(handler func(oldState, newState S)) func()
OnTransition registers a handler fired with (old, new) on a transition to a different state. It is not called on registration. It returns a disposer; call it to stop observing.
This is an EFFECT, not a callback registered on the Cell — observation in a reactive graph is a declared dependency edge. The effect reads the state cell, which is what makes it a dependent; a captured `prev` turns the level-triggered rerun into an edge-triggered (old, new) pair. Mirrors lazily-rs StateMachine::on_transition (src/state_machine.rs).
Batching consequence: an effect reruns once per settled cascade, so a batch that walks A -> B -> C reports the single transition (A, C) rather than (A, B) and (B, C). That is intended — a batch asserts atomicity, and the intermediate B was never an observable state of the graph.
func (*StateMachine[S, E]) Send ¶
func (m *StateMachine[S, E]) Send(event E) bool
Send delivers an event to the machine. It returns true if the transition function accepted the event (ok == true), false if it was rejected. A self-transition that returns an equal state returns true but does not invalidate dependents (the != guard on the cell).
func (*StateMachine[S, E]) State ¶
func (m *StateMachine[S, E]) State() S
State returns the current state. Reading inside a computation subscribes the reader.
type StateProjectionMirror ¶
type StateProjectionMirror struct {
// contains filtered or unexported fields
}
StateProjectionMirror tracks which slots are dirty and produces a coalesced flush Delta.
The caller marks slots dirty as the reactive graph invalidates them. At flush, the mirror collects the resolved values and builds a single Delta (DeltaNext) with one DeltaOpSlotValue per resolved slot; slots still dirty at flush are emitted as DeltaOpInvalidate (the mirror-lazy path).
Like the Dart original, StateProjectionMirror is not safe for concurrent use.
func NewStateProjectionMirror ¶
func NewStateProjectionMirror() *StateProjectionMirror
NewStateProjectionMirror constructs an empty mirror at base epoch 0.
func (*StateProjectionMirror) BaseEpoch ¶
func (m *StateProjectionMirror) BaseEpoch() Epoch
BaseEpoch returns the current base epoch.
func (*StateProjectionMirror) DirtyNodes ¶
func (m *StateProjectionMirror) DirtyNodes() []NodeId
DirtyNodes returns all dirty node ids, sorted ascending.
func (*StateProjectionMirror) Flush ¶
func (m *StateProjectionMirror) Flush() Delta
Flush produces a Delta with one DeltaOpInvalidate per still-dirty slot (ascending) followed by one DeltaOpSlotValue per resolved slot (ascending), then clears the pending state and advances the base epoch once.
func (*StateProjectionMirror) IsDirty ¶
func (m *StateProjectionMirror) IsDirty(node NodeId) bool
IsDirty reports whether node is currently dirty.
func (*StateProjectionMirror) MarkDirty ¶
func (m *StateProjectionMirror) MarkDirty(node NodeId)
MarkDirty marks slot node as dirty.
func (*StateProjectionMirror) Resolve ¶
func (m *StateProjectionMirror) Resolve(node NodeId, value IpcValue)
Resolve records a dirty slot's value (called by the graph at flush time) and clears its dirty mark.
type StoredOutboxEntry ¶ added in v0.13.0
StoredOutboxEntry is one serialized frame returned by an OutboxStore.
type SyncDriver ¶ added in v0.8.0
type SyncDriver struct {
// contains filtered or unexported fields
}
SyncDriver is the full-duplex reliable-sync loop driver (spec § SyncDriver).
One driver drives one peer connection over a caller-supplied IpcSink/IpcSource pair (agent-doc wraps its Unix-domain socket). It composes the three pure-protocol pieces into the loop shape the spec pins:
- drain — pop host-enqueued outbound data frames, Append each to the DurableOutbox before sending (at-least-once durability), send via the sink;
- retain-on-fail — a send error leaves the frame in the outbox (unacked) and stops the drain; it is re-sent on the next reconnect;
- receive — read inbound frames, route control frames (OutboxAck → advance retention; ResyncRequest → answer with a provider snapshot) and feed data frames through the ResyncCoordinator (Apply → hand to the host + owe an ack; RequestSnapshot → emit a ResyncRequest; Ignore → drop);
- resync-on-reconnect — OnReconnect replays the unacked outbox suffix from the peer's ack cursor and re-advertises our own receiver cursor, so a dropped-frame gap converges.
The driver owns no goroutines, no clock source, and no storage engine — the host injects all three and decides the tick cadence.
func NewSyncDriver ¶ added in v0.8.0
func NewSyncDriver(sink IpcSink, source IpcSource, outbox DurableOutbox, clock Clock, provider SnapshotProvider) *SyncDriver
NewSyncDriver returns a fresh driver at receiver epoch 0 (a Snapshot seeds the first epoch).
func NewSyncDriverWithEpoch ¶ added in v0.8.0
func NewSyncDriverWithEpoch(sink IpcSink, source IpcSource, outbox DurableOutbox, clock Clock, provider SnapshotProvider, lastEpoch Epoch) *SyncDriver
NewSyncDriverWithEpoch returns a driver whose receiver has already applied through lastEpoch (resume).
func (*SyncDriver) Enqueue ¶ added in v0.8.0
func (d *SyncDriver) Enqueue(epoch Epoch, msg IpcMessage)
Enqueue stages an outbound data frame at epoch for the next tick's drain. epoch is the frame's accepted-event count (Delta.Epoch / Snapshot.Epoch); it becomes the outbox retention key.
func (*SyncDriver) IsStalled ¶ added in v0.8.0
func (d *SyncDriver) IsStalled() bool
IsStalled reports whether the sink is currently stalled (last send failed, awaiting reconnect).
func (*SyncDriver) LastEpoch ¶ added in v0.8.0
func (d *SyncDriver) LastEpoch() Epoch
LastEpoch returns the receiver's current applied epoch.
func (*SyncDriver) OnReconnect ¶ added in v0.8.0
func (d *SyncDriver) OnReconnect()
OnReconnect signals that the transport was re-established; the next Tick replays the unacked outbox suffix and re-advertises our receiver cursor.
func (*SyncDriver) Outbox ¶ added in v0.8.0
func (d *SyncDriver) Outbox() DurableOutbox
Outbox borrows the underlying outbox (diagnostics / durable-store flush).
func (*SyncDriver) StalledFor ¶ added in v0.8.0
func (d *SyncDriver) StalledFor(now int64) int64
StalledFor returns the millis the sink has been stalled as of now, or 0 when healthy — a backoff signal for the host scheduler.
func (*SyncDriver) Tick ¶ added in v0.8.0
func (d *SyncDriver) Tick() (Progress, error)
Tick runs one loop pass. See the type docs for the drain → retain → receive → resync shape. Sink failures retain-and-stall (not an error); only an inbound source read failure returns a *DriverError.
type TeardownScope ¶ added in v0.20.0
type TeardownScope struct {
// contains filtered or unexported fields
}
TeardownScope groups nodes so they can be torn down together.
Why Close, and not a destructor ¶
lazily-rs ends a scope when it drops. Go has no destructors, so the end of a scope has to be a call. Close is that call, named for `defer scope.Close()` — the Go idiom that already means "this ends when the enclosing function does", which is precisely Rust's Drop timing expressed in the language Go actually has. It returns nothing: teardown cannot fail, and an error return would make every `defer scope.Close()` an unchecked-error lint. Context.WithScope wraps the same thing as a callback for the common lexical case.
Grouping bounds *teardown*, not visibility: a scoped node reads unscoped or sibling-scope nodes freely, and an unscoped node may read a scoped one. Same caveat as Slot.Dispose — closing a scope tears down its members even if something outside still reads them, and that reader errors on its next recompute.
func (*TeardownScope) Close ¶ added in v0.20.0
func (s *TeardownScope) Close()
Close tears down every node this scope owns, in reverse creation order, then marks the scope closed. Idempotent.
Reverse order matters for effect cleanups, which are observable side effects; graph state alone is order independent. It also keeps a scope from transiently dangling inside itself, since dependents go before what they read.
func (*TeardownScope) Disarm ¶ added in v0.20.0
func (s *TeardownScope) Disarm()
Disarm cancels this scope's teardown: it releases every node it owns back to plain context ownership, so Close disposes nothing. The nodes themselves are untouched — no disposal, no detachment — and each stays individually disposable. Same sense as defusing a scope guard.
func (*TeardownScope) Len ¶ added in v0.20.0
func (s *TeardownScope) Len() int
Len reports how many nodes this scope currently owns.
type TextCrdt ¶
type TextCrdt struct {
// contains filtered or unexported fields
}
TextCrdt is a Fugue/RGA-style free-text character CRDT.
func NewTextCrdt ¶
NewTextCrdt creates an empty replica for the given peer id.
func TextCrdtFromStr ¶
TextCrdtFromStr seeds a new CRDT from s as if a single peer typed it sequentially.
func (*TextCrdt) ApplyDelta ¶
ApplyDelta applies a delta with the same commutative/associative/idempotent algebra as Merge. Returns whether the visible text changed.
func (*TextCrdt) DeltaSince ¶
DeltaSince returns the elements whose insert id or tombstone delete id is newer than theirVv. A whole-state snapshot is DeltaSince(nil).
func (*TextCrdt) Fork ¶
Fork deep-copies this replica under a new peer, adopting the same element set and copying the counter so future ops don't collide with prior ones.
func (*TextCrdt) GcWith ¶
GcWith collects stable tombstones. An element is collectable when it is deleted, isStable confirms its delete op is stable, AND nothing references it as a left-origin. Runs to a fixpoint (collecting a leaf may expose its parent). Returns the number removed.
func (*TextCrdt) InsertStr ¶
InsertStr inserts a multi-character string at the visible index with origin chaining (#lztextinsertchain): one `orderedIds()` pass + N chain appends instead of N full-tree rebuilds. Sequential chars chain naturally — char i+1's left-origin is char i's just-minted OpId — so DFS visits them in chain order (counter strictly increases under one peer). Concurrent inserts at the same point still sort by peer tiebreak (standard CRDT convergence).
func (*TextCrdt) Merge ¶
Merge folds another replica's state into this one. Returns whether the visible text changed.
func (*TextCrdt) MergeFrom ¶ added in v0.13.0
MergeFrom joins another CrdtTree through the identity-preserving delta path.
func (*TextCrdt) TombstoneCount ¶
TombstoneCount returns the count of tombstoned (deleted) elements.
func (*TextCrdt) VersionVector ¶
VersionVector returns {peer -> max counter} taken over BOTH insert ids and tombstone delete ids. An absent peer implies 0. Serializes to JSON with string peer keys (e.g. {"1":4}), matching the spec fixtures.
type TextOp ¶
type TextOp struct {
Id OpId `json:"id"`
Ch string `json:"ch"`
Origin *OpId `json:"origin"`
Deleted *OpId `json:"deleted"`
}
TextOp is a single text-CRDT operation in delta-sync wire form. Origin and Deleted serialize as JSON null when absent (matching the Dart toWire, which always emits all four keys).
func TextOpFromWire ¶
TextOpFromWire parses a TextOp from its decoded-JSON map form.
type ThreadSafeCellMap
deprecated
added in
v0.7.0
type ThreadSafeCellMap[K comparable, V comparable] = ThreadSafeSourceMap[K, V]
ThreadSafeCellMap is the pre-v2-kernel name for ThreadSafeSourceMap.
Deprecated: renamed to ThreadSafeSourceMap.
type ThreadSafeComputedMap ¶ added in v0.22.0
type ThreadSafeComputedMap[K comparable, V comparable] struct { *ThreadSafeReactiveMap[K, V, *Computed[V]] }
ThreadSafeComputedMap is the derived-slot specialization: GetOrInsertWith mints a slot on first access (lazy); MaterializeAll pre-mints the keyset (eager). No Set.
func NewThreadSafeComputedMap ¶ added in v0.22.0
func NewThreadSafeComputedMap[K comparable, V comparable](ts *ThreadSafeContext) *ThreadSafeComputedMap[K, V]
NewThreadSafeComputedMap creates an empty thread-safe derived-slot map.
func NewThreadSafeSlotMap
deprecated
added in
v0.7.0
func NewThreadSafeSlotMap[K comparable, V comparable](ts *ThreadSafeContext) *ThreadSafeComputedMap[K, V]
NewThreadSafeSlotMap creates an empty thread-safe derived-slot map.
Deprecated: renamed to NewThreadSafeComputedMap.
func (*ThreadSafeComputedMap[K, V]) MaterializeAll ¶ added in v0.22.0
func (m *ThreadSafeComputedMap[K, V]) MaterializeAll(keys []K, factory func(K) V)
MaterializeAll eagerly pre-mints every key via factory. Observationally identical to minting each lazily on first read.
func (*ThreadSafeComputedMap[K, V]) Slot ¶ added in v0.23.0
func (m *ThreadSafeComputedMap[K, V]) Slot(key K) *Computed[V]
Slot returns key's derived slot handle, or nil. Non-reactive.
type ThreadSafeContext ¶
type ThreadSafeContext struct {
// contains filtered or unexported fields
}
ThreadSafeContext serializes all access to an underlying Context behind a reentrant lock. Build reactives and read/write cells only inside WithLock or Batch (or via TSSetCell); concurrent callers are linearized by the lock, so every batch flush is glitch-free.
func NewThreadSafeContext ¶
func NewThreadSafeContext() *ThreadSafeContext
NewThreadSafeContext creates a lock-backed reactive context.
func (*ThreadSafeContext) Batch ¶
func (t *ThreadSafeContext) Batch(fn func())
Batch runs fn under the lock inside an underlying Context batch, so all cell writes queued in fn flush in a single coalesced invalidation pass at the outermost boundary. Nested Batch calls only flush at the outermost boundary.
func (*ThreadSafeContext) Context ¶
func (t *ThreadSafeContext) Context() *Context
Context returns the underlying single-threaded Context. Only touch it while holding the lock (inside WithLock/Batch) — direct concurrent use is unsafe.
func (*ThreadSafeContext) WithLock ¶
func (t *ThreadSafeContext) WithLock(fn func(ctx *Context))
WithLock runs fn while holding the lock, giving it exclusive, race-free access to the reactive graph (build nodes, read slots, write cells). Reentrant: fn may itself call WithLock/Batch/TSSetCell.
type ThreadSafeQueueCell ¶ added in v0.24.0
type ThreadSafeQueueCell[T comparable, S QueueStorage[T]] struct { // contains filtered or unexported fields }
ThreadSafeQueueCell is the lock-serialized QueueCell flavor.
func NewBoundedThreadSafeQueueCell ¶ added in v0.24.0
func NewBoundedThreadSafeQueueCell[T comparable](ts *ThreadSafeContext, capacity int) *ThreadSafeQueueCell[T, *VecDequeStorage[T]]
NewBoundedThreadSafeQueueCell creates a bounded thread-safe queue.
func NewThreadSafeQueueCell ¶ added in v0.24.0
func NewThreadSafeQueueCell[T comparable](ts *ThreadSafeContext) *ThreadSafeQueueCell[T, *VecDequeStorage[T]]
NewThreadSafeQueueCell creates an unbounded thread-safe queue.
func NewThreadSafeQueueCellWithStorage ¶ added in v0.24.0
func NewThreadSafeQueueCellWithStorage[T comparable, S QueueStorage[T]]( ts *ThreadSafeContext, storage S, ) *ThreadSafeQueueCell[T, S]
NewThreadSafeQueueCellWithStorage creates a thread-safe queue over storage.
func (*ThreadSafeQueueCell[T, S]) Capacity ¶ added in v0.24.0
func (q *ThreadSafeQueueCell[T, S]) Capacity() (int, bool)
func (*ThreadSafeQueueCell[T, S]) Close ¶ added in v0.24.0
func (q *ThreadSafeQueueCell[T, S]) Close()
func (*ThreadSafeQueueCell[T, S]) Elements ¶ added in v0.24.0
func (q *ThreadSafeQueueCell[T, S]) Elements() []T
func (*ThreadSafeQueueCell[T, S]) Head ¶ added in v0.24.0
func (q *ThreadSafeQueueCell[T, S]) Head() (T, bool)
func (*ThreadSafeQueueCell[T, S]) IsClosed ¶ added in v0.24.0
func (q *ThreadSafeQueueCell[T, S]) IsClosed() bool
func (*ThreadSafeQueueCell[T, S]) IsEmpty ¶ added in v0.24.0
func (q *ThreadSafeQueueCell[T, S]) IsEmpty() bool
func (*ThreadSafeQueueCell[T, S]) IsFull ¶ added in v0.24.0
func (q *ThreadSafeQueueCell[T, S]) IsFull() bool
func (*ThreadSafeQueueCell[T, S]) Len ¶ added in v0.24.0
func (q *ThreadSafeQueueCell[T, S]) Len() int
func (*ThreadSafeQueueCell[T, S]) ReaderHandles ¶ added in v0.24.0
func (q *ThreadSafeQueueCell[T, S]) ReaderHandles() QueueReaderHandles[T]
func (*ThreadSafeQueueCell[T, S]) TryPop ¶ added in v0.24.0
func (q *ThreadSafeQueueCell[T, S]) TryPop() (T, QueuePopError)
func (*ThreadSafeQueueCell[T, S]) TryPush ¶ added in v0.24.0
func (q *ThreadSafeQueueCell[T, S]) TryPush(value T) QueuePushError
type ThreadSafeReactiveMap ¶ added in v0.7.0
type ThreadSafeReactiveMap[K comparable, V comparable, H any] struct { // contains filtered or unexported fields }
ThreadSafeReactiveMap is the thread-safe keyed reactive map (#reactivemap), generic over the entry handle kind H, with all present-set mutation serialized by an internal mutex and all graph work serialized by the owning ThreadSafeContext's lock.
It is graph-backed. Before the Core-surface work this map stored plain values in a map[K]V with no reactive nodes at all, no context, and no ordering surface: it had PresentKeys and PresentCount and nothing else. "Thread-safe map" was a mutex-guarded cache wearing the reactive family's name. Entries are now real nodes on the underlying graph, and membership and order are real signals minted on that same graph — the ordering plane binds this flavor exactly as it binds the single-threaded one, because a move touches no entry handle and awaits nothing.
Reads take a ComputeOps read surface (#lzcellkernel). A *Compute registers a dependency edge; a *Context registers none. A read spellable only as a zero-argument call could never subscribe from inside a derived node — which is precisely how the single-threaded map's Keys/Len/ContainsKey silently registered no edge at all.
V is constrained comparable to mirror the single-threaded map (an input entry needs an equality guard). Once built its address is stable, so concurrent readers may share a *ThreadSafeReactiveMap.
func (*ThreadSafeReactiveMap[K, V, H]) ContainsKey ¶ added in v0.23.0
func (m *ThreadSafeReactiveMap[K, V, H]) ContainsKey(c ComputeOps, key K) bool
ContainsKey reports the reactive membership test for key. Subscribes the caller to membership changes (add/remove of any key), not to value changes.
func (*ThreadSafeReactiveMap[K, V, H]) EntryKind ¶ added in v0.7.0
func (m *ThreadSafeReactiveMap[K, V, H]) EntryKind() EntryKind
EntryKind returns this map's entry kind.
func (*ThreadSafeReactiveMap[K, V, H]) GetOrInsertWith ¶ added in v0.7.0
func (m *ThreadSafeReactiveMap[K, V, H]) GetOrInsertWith(c ComputeOps, key K, factory func(K) V) V
GetOrInsertWith returns key's value, minting the entry via factory(key) on first access (the lazy pull). An existing key returns its current value without re-running the factory.
func (*ThreadSafeReactiveMap[K, V, H]) Handle ¶ added in v0.23.0
func (m *ThreadSafeReactiveMap[K, V, H]) Handle(key K) (H, bool)
Handle returns key's existing entry handle, or (zero, false). Non-minting.
func (*ThreadSafeReactiveMap[K, V, H]) IsEmpty ¶ added in v0.23.0
func (m *ThreadSafeReactiveMap[K, V, H]) IsEmpty(c ComputeOps) bool
IsEmpty reports the reactive emptiness check.
func (*ThreadSafeReactiveMap[K, V, H]) IsPresent ¶ added in v0.7.0
func (m *ThreadSafeReactiveMap[K, V, H]) IsPresent(key K) bool
IsPresent reports whether key is currently materialized. Non-reactive.
func (*ThreadSafeReactiveMap[K, V, H]) Keys ¶ added in v0.23.0
func (m *ThreadSafeReactiveMap[K, V, H]) Keys(c ComputeOps) []K
Keys returns a reactive snapshot of the keys in their current order. Subscribes the caller to order changes (add/remove and move/reorder), not to per-entry value changes.
func (*ThreadSafeReactiveMap[K, V, H]) Len ¶ added in v0.23.0
func (m *ThreadSafeReactiveMap[K, V, H]) Len(c ComputeOps) int
Len reports the reactive entry count. Subscribes the caller to membership changes only.
func (*ThreadSafeReactiveMap[K, V, H]) LenUntracked ¶ added in v0.23.0
func (m *ThreadSafeReactiveMap[K, V, H]) LenUntracked() int
LenUntracked reports the non-reactive count.
func (*ThreadSafeReactiveMap[K, V, H]) MoveAfter ¶ added in v0.23.0
func (m *ThreadSafeReactiveMap[K, V, H]) MoveAfter(key, anchor K) bool
MoveAfter atomically moves key to just after anchor (#lzcellmove).
func (*ThreadSafeReactiveMap[K, V, H]) MoveBefore ¶ added in v0.23.0
func (m *ThreadSafeReactiveMap[K, V, H]) MoveBefore(key, anchor K) bool
MoveBefore atomically moves key to just before anchor (#lzcellmove).
func (*ThreadSafeReactiveMap[K, V, H]) MoveTo ¶ added in v0.23.0
func (m *ThreadSafeReactiveMap[K, V, H]) MoveTo(key K, index int) bool
MoveTo atomically moves key to index in the order (#lzcellmove). The entry keeps the same node, the same dependents, and its CRDT lineage — unlike a Remove + re-mint, which re-allocates and bumps membership twice. Only the order signal is bumped, so Keys readers recompute while Len / ContainsKey readers stay cached. index is clamped to [0, len).
func (*ThreadSafeReactiveMap[K, V, H]) Observe ¶ added in v0.7.0
func (m *ThreadSafeReactiveMap[K, V, H]) Observe(c ComputeOps, key K) (V, bool)
Observe reads key's value if the entry is present, subscribing the caller to that entry's node. Returns (zero, false) if absent. Non-minting.
func (*ThreadSafeReactiveMap[K, V, H]) Position ¶ added in v0.23.0
func (m *ThreadSafeReactiveMap[K, V, H]) Position(key K) (int, bool)
Position reports key's current 0-based position in the order. Non-reactive.
func (*ThreadSafeReactiveMap[K, V, H]) PresentCount ¶ added in v0.7.0
func (m *ThreadSafeReactiveMap[K, V, H]) PresentCount() int
PresentCount returns the number of currently-materialized entries.
func (*ThreadSafeReactiveMap[K, V, H]) PresentKeys ¶ added in v0.7.0
func (m *ThreadSafeReactiveMap[K, V, H]) PresentKeys() []K
PresentKeys returns a snapshot of the currently-materialized keys, in current order. Non-reactive — see Keys for the tracked read.
func (*ThreadSafeReactiveMap[K, V, H]) Remove ¶ added in v0.23.0
func (m *ThreadSafeReactiveMap[K, V, H]) Remove(key K) bool
Remove removes key's entry, detaching the removed node so no reader is left on a stale value, and bumps reactive membership. Returns whether the key was present.
type ThreadSafeSlotMap
deprecated
added in
v0.7.0
type ThreadSafeSlotMap[K comparable, V comparable] = ThreadSafeComputedMap[K, V]
ThreadSafeSlotMap is the pre-v2-kernel name for ThreadSafeComputedMap.
Deprecated: renamed to ThreadSafeComputedMap.
type ThreadSafeSourceMap ¶ added in v0.22.0
type ThreadSafeSourceMap[K comparable, V comparable] struct { *ThreadSafeReactiveMap[K, V, *Source[V]] }
ThreadSafeSourceMap is the input-cell specialization of ThreadSafeReactiveMap: every entry is a settable input cell. Adds the cell-only Set.
func NewThreadSafeCellMap
deprecated
added in
v0.7.0
func NewThreadSafeCellMap[K comparable, V comparable](ts *ThreadSafeContext) *ThreadSafeSourceMap[K, V]
NewThreadSafeCellMap creates an empty thread-safe input-cell map.
Deprecated: renamed to NewThreadSafeSourceMap.
func NewThreadSafeSourceMap ¶ added in v0.22.0
func NewThreadSafeSourceMap[K comparable, V comparable](ts *ThreadSafeContext) *ThreadSafeSourceMap[K, V]
NewThreadSafeSourceMap creates an empty thread-safe input-cell map bound to ts.
func (*ThreadSafeSourceMap[K, V]) Cell ¶ added in v0.23.0
func (m *ThreadSafeSourceMap[K, V]) Cell(key K) *Source[V]
Cell returns key's existing input cell, or nil. Non-reactive.
func (*ThreadSafeSourceMap[K, V]) Set ¶ added in v0.22.0
func (m *ThreadSafeSourceMap[K, V]) Set(key K, value V)
Set overwrites key's value, materializing the entry if absent. Cell-only: a derived ComputedMap slot is not settable. Updating an existing entry leaves membership and order untouched and invalidates only that entry's dependents.
type ThreadSafeTopicCell ¶ added in v0.24.0
type ThreadSafeTopicCell[T any] struct { // contains filtered or unexported fields }
ThreadSafeTopicCell is the lock-serialized TopicCell flavor.
func NewThreadSafeTopicCell ¶ added in v0.24.0
func NewThreadSafeTopicCell[T any](ts *ThreadSafeContext) *ThreadSafeTopicCell[T]
func NewThreadSafeTopicCellFromSnapshot ¶ added in v0.24.0
func NewThreadSafeTopicCellFromSnapshot[T any]( ts *ThreadSafeContext, snapshot TopicSnapshot[T], ) *ThreadSafeTopicCell[T]
func (*ThreadSafeTopicCell[T]) Advance ¶ added in v0.24.0
func (t *ThreadSafeTopicCell[T]) Advance(id string, count int) int
func (*ThreadSafeTopicCell[T]) BaseOffset ¶ added in v0.24.0
func (t *ThreadSafeTopicCell[T]) BaseOffset() int
func (*ThreadSafeTopicCell[T]) Disconnect ¶ added in v0.24.0
func (t *ThreadSafeTopicCell[T]) Disconnect(id string)
func (*ThreadSafeTopicCell[T]) Elements ¶ added in v0.24.0
func (t *ThreadSafeTopicCell[T]) Elements() []T
func (*ThreadSafeTopicCell[T]) GC ¶ added in v0.24.0
func (t *ThreadSafeTopicCell[T]) GC() int
func (*ThreadSafeTopicCell[T]) Publish ¶ added in v0.24.0
func (t *ThreadSafeTopicCell[T]) Publish(value T) int
func (*ThreadSafeTopicCell[T]) Read ¶ added in v0.24.0
func (t *ThreadSafeTopicCell[T]) Read(id string) (T, bool)
func (*ThreadSafeTopicCell[T]) ReadStream ¶ added in v0.24.0
func (t *ThreadSafeTopicCell[T]) ReadStream(id string) ([]T, bool)
func (*ThreadSafeTopicCell[T]) ReaderHandle ¶ added in v0.24.0
func (t *ThreadSafeTopicCell[T]) ReaderHandle(id string) *Computed[TopicRead[T]]
func (*ThreadSafeTopicCell[T]) Reconnect ¶ added in v0.24.0
func (t *ThreadSafeTopicCell[T]) Reconnect(id string)
func (*ThreadSafeTopicCell[T]) Restart ¶ added in v0.24.0
func (t *ThreadSafeTopicCell[T]) Restart()
func (*ThreadSafeTopicCell[T]) Snapshot ¶ added in v0.24.0
func (t *ThreadSafeTopicCell[T]) Snapshot() TopicSnapshot[T]
func (*ThreadSafeTopicCell[T]) Subscribe ¶ added in v0.24.0
func (t *ThreadSafeTopicCell[T]) Subscribe(id string, durability TopicDurability) TopicSubscribeOutcome
func (*ThreadSafeTopicCell[T]) Subscription ¶ added in v0.24.0
func (t *ThreadSafeTopicCell[T]) Subscription(id string) (TopicSubscriptionSnapshot, bool)
func (*ThreadSafeTopicCell[T]) TailOffset ¶ added in v0.24.0
func (t *ThreadSafeTopicCell[T]) TailOffset() int
type ThreadSafeWorkQueueCell ¶ added in v0.24.0
type ThreadSafeWorkQueueCell[T any] struct { // contains filtered or unexported fields }
ThreadSafeWorkQueueCell is the lock-serialized WorkQueueCell flavor.
func NewThreadSafeWorkQueueCell ¶ added in v0.24.0
func NewThreadSafeWorkQueueCell[T any]( ts *ThreadSafeContext, visibilityTimeout int64, maxDeliveries uint64, ) *ThreadSafeWorkQueueCell[T]
func (*ThreadSafeWorkQueueCell[T]) Ack ¶ added in v0.24.0
func (q *ThreadSafeWorkQueueCell[T]) Ack(worker string, deliveryID uint64) bool
func (*ThreadSafeWorkQueueCell[T]) Claim ¶ added in v0.24.0
func (q *ThreadSafeWorkQueueCell[T]) Claim(worker string, now int64) (WorkQueueDelivery[T], bool)
func (*ThreadSafeWorkQueueCell[T]) DeadLetterItems ¶ added in v0.24.0
func (q *ThreadSafeWorkQueueCell[T]) DeadLetterItems() []WorkQueueDeadLetter[T]
func (*ThreadSafeWorkQueueCell[T]) DeadLetterLen ¶ added in v0.24.0
func (q *ThreadSafeWorkQueueCell[T]) DeadLetterLen() int
func (*ThreadSafeWorkQueueCell[T]) InFlightDeliveries ¶ added in v0.24.0
func (q *ThreadSafeWorkQueueCell[T]) InFlightDeliveries() []WorkQueueDelivery[T]
func (*ThreadSafeWorkQueueCell[T]) InFlightLen ¶ added in v0.24.0
func (q *ThreadSafeWorkQueueCell[T]) InFlightLen() int
func (*ThreadSafeWorkQueueCell[T]) IsEmpty ¶ added in v0.24.0
func (q *ThreadSafeWorkQueueCell[T]) IsEmpty() bool
func (*ThreadSafeWorkQueueCell[T]) Nack ¶ added in v0.24.0
func (q *ThreadSafeWorkQueueCell[T]) Nack(worker string, deliveryID uint64) bool
func (*ThreadSafeWorkQueueCell[T]) PendingItems ¶ added in v0.24.0
func (q *ThreadSafeWorkQueueCell[T]) PendingItems() []WorkQueueItem[T]
func (*ThreadSafeWorkQueueCell[T]) PendingLen ¶ added in v0.24.0
func (q *ThreadSafeWorkQueueCell[T]) PendingLen() int
func (*ThreadSafeWorkQueueCell[T]) Push ¶ added in v0.24.0
func (q *ThreadSafeWorkQueueCell[T]) Push(value T) uint64
func (*ThreadSafeWorkQueueCell[T]) ReaderHandles ¶ added in v0.24.0
func (q *ThreadSafeWorkQueueCell[T]) ReaderHandles() WorkQueueReaderHandles
func (*ThreadSafeWorkQueueCell[T]) ReapExpired ¶ added in v0.24.0
func (q *ThreadSafeWorkQueueCell[T]) ReapExpired(now int64) int
type ThrottleCell ¶ added in v0.15.0
type ThrottleCell[T comparable] struct { // contains filtered or unexported fields }
ThrottleCell is the reactive throttle over any comparable-valued source.
func NewThrottleCell ¶ added in v0.15.0
func NewThrottleCell[T comparable](ctx *Context, edge ThrottleEdge, window uint64) *ThrottleCell[T]
NewThrottleCell builds a reactive throttle bound to ctx.
func (*ThrottleCell[T]) Input ¶ added in v0.15.0
func (c *ThrottleCell[T]) Input(now uint64, v T) Opt[T]
Input records an input, returning the emitted value (if any).
func (*ThrottleCell[T]) Output ¶ added in v0.15.0
func (c *ThrottleCell[T]) Output() Opt[T]
Output returns the last emitted value (subscribes the current computation).
func (*ThrottleCell[T]) OutputCell ¶ added in v0.15.0
func (c *ThrottleCell[T]) OutputCell() *Source[Opt[T]]
OutputCell exposes the reader cell for invalidation observation.
func (*ThrottleCell[T]) Tick ¶ added in v0.15.0
func (c *ThrottleCell[T]) Tick(now uint64) Opt[T]
Tick advances the clock, returning the emitted value (if any).
type ThrottleCore ¶ added in v0.15.0
type ThrottleCore[T comparable] struct { // contains filtered or unexported fields }
ThrottleCore emits at most one value per `window`.
func NewThrottleCore ¶ added in v0.15.0
func NewThrottleCore[T comparable](edge ThrottleEdge, window uint64) *ThrottleCore[T]
NewThrottleCore builds a throttle core.
func (*ThrottleCore[T]) Input ¶ added in v0.15.0
func (c *ThrottleCore[T]) Input(now uint64, v T) Opt[T]
Input records an input. Leading emits (or drops); Trailing coalesces and holds.
func (*ThrottleCore[T]) Tick ¶ added in v0.15.0
func (c *ThrottleCore[T]) Tick(now uint64) Opt[T]
Tick advances. Trailing emits the coalesced latest at the window boundary.
type ThrottleEdge ¶ added in v0.15.0
type ThrottleEdge int
ThrottleEdge selects which edge of the window a ThrottleCore emits on.
const ( // ThrottleLeading: first input of a window passes immediately; rest dropped. ThrottleLeading ThrottleEdge = iota // ThrottleTrailing: first input opens the window; the latest is emitted at // the window boundary. ThrottleTrailing )
type TimedValue ¶ added in v0.11.0
TimedValue is a (timestamp, value) pair for RetainLive.
type TimelineSource ¶ added in v0.15.0
type TimelineSource interface {
// Tick advances to logical time now (callers must not go backwards).
// Returns true on a fire edge — a fire happened on this tick.
Tick(now uint64) bool
// NextFire reports the logical time of the next fire; ok is false when the
// source is exhausted (models Option<u64> as (uint64, bool)).
NextFire() (fire uint64, ok bool)
}
TimelineSource is a pure temporal compute core driven by a monotone logical clock. A runtime advances any source uniformly via Tick; NextFire lets a scheduler compute the delay to the next wake-up.
type Timeout ¶ added in v0.25.0
type Timeout[T any] struct { // contains filtered or unexported fields }
func NewTimeout ¶ added in v0.25.0
func (*Timeout[T]) Poll ¶ added in v0.25.0
func (t *Timeout[T]) Poll( now uint64, operation func() TimeoutOperation[T], cancellation func() TimeoutCancellation, ) TimeoutObservation[T]
Poll invokes both adapters exactly once before the deadline. Precedence is completion, unavailable operation, cancellation, then pending. At or after the deadline neither adapter is called. Terminal reads also call neither.
type TimeoutCancellation ¶ added in v0.25.0
type TimeoutCancellation string
TimeoutCancellation is returned by a cancellation adapter owned by the caller. "unavailable" represents a foreign or unreadable cancellation seam.
const ( CancellationPending TimeoutCancellation = "pending" CancellationCancelled TimeoutCancellation = "cancelled" )
type TimeoutCell ¶ added in v0.15.0
type TimeoutCell struct {
// contains filtered or unexported fields
}
TimeoutCell is a reactive timeout: projects isTimedOut onto a Cell.
func NewTimeoutCell ¶ added in v0.15.0
func NewTimeoutCell(ctx *Context) *TimeoutCell
NewTimeoutCell builds a reactive timeout.
func (*TimeoutCell) Arm ¶ added in v0.15.0
func (t *TimeoutCell) Arm(now, timeout uint64)
Arm arms the timeout with deadline = now + timeout.
func (*TimeoutCell) IsTimedOut ¶ added in v0.15.0
func (t *TimeoutCell) IsTimedOut() bool
IsTimedOut reports the projected timeout state.
func (*TimeoutCell) IsTimedOutCell ¶ added in v0.15.0
func (t *TimeoutCell) IsTimedOutCell() *Source[bool]
IsTimedOutCell returns the reactive is-timed-out reader.
func (*TimeoutCell) Tick ¶ added in v0.15.0
func (t *TimeoutCell) Tick(now uint64) bool
Tick fast-fails when now >= deadline; returns the timeout edge (once).
type TimeoutCore ¶ added in v0.15.0
type TimeoutCore struct {
// contains filtered or unexported fields
}
TimeoutCore is a deadline-bounded call compute core.
func NewTimeoutCore ¶ added in v0.15.0
func NewTimeoutCore() *TimeoutCore
NewTimeoutCore builds a core.
func (*TimeoutCore) Arm ¶ added in v0.15.0
func (t *TimeoutCore) Arm(now, timeout uint64)
Arm arms the timeout with deadline = now + timeout.
func (*TimeoutCore) IsTimedOut ¶ added in v0.15.0
func (t *TimeoutCore) IsTimedOut() bool
IsTimedOut reports whether the timeout has fired.
func (*TimeoutCore) Tick ¶ added in v0.15.0
func (t *TimeoutCore) Tick(now uint64) bool
Tick fast-fails when now >= deadline; returns the timeout edge (once).
type TimeoutObservation ¶ added in v0.25.0
TimeoutObservation is the deterministic, terminal-latching timeout result.
type TimeoutOperation ¶ added in v0.25.0
TimeoutOperation is the result returned by one operation adapter poll.
func CompletedOperation ¶ added in v0.25.0
func CompletedOperation[T any](value T) TimeoutOperation[T]
func PendingOperation ¶ added in v0.25.0
func PendingOperation[T any]() TimeoutOperation[T]
func UnavailableOperation ¶ added in v0.25.0
func UnavailableOperation[T any]() TimeoutOperation[T]
type Timer ¶ added in v0.25.0
type Timer struct {
// contains filtered or unexported fields
}
Timer is a deterministic single-shot timer driven by caller-supplied ticks. Its mutex makes concurrent observations race-free while preserving the no-state-change rule for a regressing clock.
type TimerCell ¶ added in v0.15.0
type TimerCell struct {
// contains filtered or unexported fields
}
TimerCell is a reactive single-shot timer: projects TimerCore's fire edge onto a cell so HasFired/Value dependents invalidate only on the fire (idempotent).
func NewTimerCell ¶ added in v0.15.0
NewTimerCell creates a reactive single-shot timer firing at fireAt.
func (*TimerCell) FiredCell ¶ added in v0.15.0
FiredCell returns the backing cell for dependents that subscribe directly.
func (*TimerCell) HasFired ¶ added in v0.15.0
HasFired reports whether the timer has fired (reactive read).
func (*TimerCell) NextFire ¶ added in v0.15.0
NextFire reports the next fire time, or ok=false once fired.
type TimerCore ¶ added in v0.15.0
type TimerCore struct {
// contains filtered or unexported fields
}
TimerCore is a single-shot compute core: fires exactly once at the first tick with now >= fireAt (idempotent thereafter).
func NewTimerCore ¶ added in v0.15.0
NewTimerCore creates a single-shot core firing at fireAt.
type TimerError ¶ added in v0.25.0
type TimerError string
TimerError is a typed failure reported by the portable logical-clock timer.
const ( TimerDeadlineOverflow TimerError = "deadline_overflow" TimerClockRegression TimerError = "clock_regression" )
func (TimerError) Error ¶ added in v0.25.0
func (e TimerError) Error() string
type TimerObservation ¶ added in v0.25.0
TimerObservation is the externally observable state of Timer.
type TopicCell ¶ added in v0.12.0
type TopicCell[T any] struct { // contains filtered or unexported fields }
TopicCell is a broadcast log with one absolute reactive cursor per subscriber. Durable offline subscribers retain their cursor; ephemeral ones disappear on disconnect. GC drops only the prefix below the slowest durable cursor.
func NewTopicCell ¶ added in v0.12.0
NewTopicCell creates an empty broadcast topic.
func NewTopicCellFromSnapshot ¶ added in v0.12.0
func NewTopicCellFromSnapshot[T any](ctx *Context, snapshot TopicSnapshot[T]) *TopicCell[T]
NewTopicCellFromSnapshot restores retained elements and absolute cursors.
func (*TopicCell[T]) Advance ¶ added in v0.12.0
Advance moves only the named subscriber's absolute cursor.
func (*TopicCell[T]) BaseOffset ¶ added in v0.12.0
func (*TopicCell[T]) Disconnect ¶ added in v0.12.0
Disconnect retains durable cursors and removes ephemeral subscriptions.
func (*TopicCell[T]) GC ¶ added in v0.12.0
GC drops only the prefix below every durable cursor and invalidates nothing.
func (*TopicCell[T]) Publish ¶ added in v0.12.0
Publish appends a value and invalidates each connected reader independently.
func (*TopicCell[T]) Read ¶ added in v0.12.0
Read reactively reads the next value without advancing the cursor.
func (*TopicCell[T]) ReadStream ¶ added in v0.12.0
ReadStream reactively reads the complete retained suffix at this cursor.
func (*TopicCell[T]) ReaderHandle ¶ added in v0.12.0
func (*TopicCell[T]) Reconnect ¶ added in v0.12.0
Reconnect resumes an offline durable subscription at its saved cursor.
func (*TopicCell[T]) Restart ¶ added in v0.12.0
func (t *TopicCell[T]) Restart()
Restart models a process restart; persisted state and reader values are stable.
func (*TopicCell[T]) Snapshot ¶ added in v0.12.0
func (t *TopicCell[T]) Snapshot() TopicSnapshot[T]
Snapshot copies the retained log and stable subscription table.
func (*TopicCell[T]) Subscribe ¶ added in v0.12.0
func (t *TopicCell[T]) Subscribe(id string, durability TopicDurability) TopicSubscribeOutcome
Subscribe starts a new cursor at the current tail, or resumes an offline durable cursor with the same stable id.
func (*TopicCell[T]) Subscription ¶ added in v0.12.0
func (t *TopicCell[T]) Subscription(id string) (TopicSubscriptionSnapshot, bool)
Subscription reports a copy of a subscriber's current state.
func (*TopicCell[T]) TailOffset ¶ added in v0.12.0
type TopicDurability ¶ added in v0.12.0
type TopicDurability string
TopicDurability controls whether a subscription survives disconnect and participates in the retained-log GC frontier.
const ( TopicDurable TopicDurability = "durable" TopicEphemeral TopicDurability = "ephemeral" )
type TopicRead ¶ added in v0.12.0
TopicRead is the memoized per-subscriber suffix returned by a reader Slot.
type TopicSnapshot ¶ added in v0.12.0
type TopicSnapshot[T any] struct { BaseOffset int Elements []T Subscriptions []TopicSubscriptionSnapshot }
TopicSnapshot is a portable TopicCell retained-log snapshot.
type TopicSubscribeOutcome ¶ added in v0.12.0
type TopicSubscribeOutcome string
TopicSubscribeOutcome describes whether Subscribe minted or resumed a cursor.
const ( TopicSubscribed TopicSubscribeOutcome = "subscribed" TopicReconnected TopicSubscribeOutcome = "reconnected" TopicAlreadySubscribed TopicSubscribeOutcome = "already_subscribed" )
type TopicSubscriptionSnapshot ¶ added in v0.12.0
type TopicSubscriptionSnapshot struct {
ID string
Cursor int
Durability TopicDurability
Connected bool
}
TopicSubscriptionSnapshot is the persistent state for one stable subscriber.
type Trackable ¶ added in v0.21.0
type Trackable[T any] interface { // contains filtered or unexported methods }
Trackable is any value-bearing node that can be read through a ComputeOps. Both *Computed[T] and *Source[T] implement it, so a single generic Get serves slots, computed cells, and source cells alike.
type Transition ¶
type Transition[S comparable, E comparable] func(state S, event E) (next S, ok bool)
Transition is the pure transition function for a StateMachine. Given the current state and an incoming event it returns the next state and whether the event was accepted. Returning ok == false rejects the event (acts as a guard); the machine's state is left unchanged.
type Transport ¶ added in v0.11.0
Transport is a pluggable delivery mechanism for relay ops. Deliver enqueues; Poll pulls the next transport-defined frame (a batch of ready ops). Framing is the transport's business; the relay merges whatever each frame delivers.
type TreeDotRange ¶ added in v0.2.0
TreeDotRange is the observed dots for one peer: a contiguous prefix plus out-of-order holes. Never a per-peer max — a hole above Contiguous stays representable in Sparse so it is re-requested rather than skipped.
func NewTreeDotRange ¶ added in v0.2.0
func NewTreeDotRange() *TreeDotRange
NewTreeDotRange returns an empty dot range.
func (*TreeDotRange) Contains ¶ added in v0.2.0
func (r *TreeDotRange) Contains(counter int64) bool
Contains reports whether counter is held.
func (*TreeDotRange) Copy ¶ added in v0.2.0
func (r *TreeDotRange) Copy() *TreeDotRange
Copy returns a deep copy.
func (*TreeDotRange) Observe ¶ added in v0.2.0
func (r *TreeDotRange) Observe(counter int64)
Observe records a counter, collapsing the contiguous prefix forward.
type TreeNodeChildren ¶
type TreeNodeChildren[V any] struct { Order []string Values map[string]TreeNodeSpec[V] }
TreeNodeChildren describes the ordered children of a TreeNodeSpec. Order is optional; when nil the child keys of Values are used (sorted for determinism — see note in BuildSemTree).
type TreeNodeSeed ¶ added in v0.2.0
type TreeNodeSeed interface {
// contains filtered or unexported methods
}
TreeNodeSeed is what a CreateNode materializes: an element shell or a text leaf seeded from exact text. Externally tagged on the wire ({"Element": {"kind": ...}} or {"Leaf": {"kind": ..., "text": ...}}).
type TreeNodeSeedElement ¶ added in v0.2.0
type TreeNodeSeedElement struct {
Kind string
}
TreeNodeSeedElement is an internal semantic node with a kind and ordered children. Owns structure only, never text.
func (TreeNodeSeedElement) MarshalJSON ¶ added in v0.2.0
func (s TreeNodeSeedElement) MarshalJSON() ([]byte, error)
MarshalJSON renders the externally-tagged wire form.
type TreeNodeSeedLeaf ¶ added in v0.2.0
TreeNodeSeedLeaf is a leaf seeded from exact source text.
func (TreeNodeSeedLeaf) MarshalJSON ¶ added in v0.2.0
func (s TreeNodeSeedLeaf) MarshalJSON() ([]byte, error)
MarshalJSON renders the externally-tagged wire form.
type TreeNodeSpec ¶
type TreeNodeSpec[V any] struct { ID string Value V Children *TreeNodeChildren[V] }
TreeNodeSpec is a node spec for building a SemTree.
type TreeOp ¶ added in v0.2.0
type TreeOp struct {
Id OpId
Kind TreeOpKind
}
TreeOp is a transport-ready tree operation: its dotted id plus the change it encodes.
func (TreeOp) MarshalJSON ¶ added in v0.2.0
MarshalJSON renders {"id": ..., "kind": <externally-tagged kind>}.
func (*TreeOp) UnmarshalJSON ¶ added in v0.2.0
UnmarshalJSON decodes a TreeOp from its externally-tagged kind form.
type TreeOpCreateNode ¶ added in v0.2.0
type TreeOpCreateNode struct {
Id OpId
Parent OpId
Sort TreeSortKey
Seed TreeNodeSeed
}
TreeOpCreateNode materializes an element shell or a text leaf seeded from exact text.
func (TreeOpCreateNode) MarshalJSON ¶ added in v0.2.0
func (k TreeOpCreateNode) MarshalJSON() ([]byte, error)
MarshalJSON renders the externally-tagged wire form for an op kind.
type TreeOpKind ¶ added in v0.2.0
type TreeOpKind interface {
// contains filtered or unexported methods
}
TreeOpKind is the M1 op vocabulary: CreateNode / Tombstone / Reorder / LeafEdit / SplitLeaf / MergeLeaves. Externally tagged on the wire. Positions and seed text travel inside the op so both replicas store byte-identical keys and converge without consulting local clocks.
type TreeOpLeafEdit ¶ added in v0.2.0
TreeOpLeafEdit applies an embedded text-CRDT delta to one leaf. Prev is the prior text-op id (the leaf's textHead), forming a per-leaf causal chain.
func (TreeOpLeafEdit) MarshalJSON ¶ added in v0.2.0
func (k TreeOpLeafEdit) MarshalJSON() ([]byte, error)
MarshalJSON renders the externally-tagged wire form for an op kind.
type TreeOpMergeLeaves ¶ added in v0.2.0
TreeOpMergeLeaves merges two adjacent leaf siblings; total text unchanged.
func (TreeOpMergeLeaves) MarshalJSON ¶ added in v0.2.0
func (k TreeOpMergeLeaves) MarshalJSON() ([]byte, error)
MarshalJSON renders the externally-tagged wire form for an op kind.
type TreeOpReorder ¶ added in v0.2.0
type TreeOpReorder struct {
Node OpId
Sort TreeSortKey
}
TreeOpReorder is a LWW position reassignment within the parent (identity + payload preserved).
func (TreeOpReorder) MarshalJSON ¶ added in v0.2.0
func (k TreeOpReorder) MarshalJSON() ([]byte, error)
MarshalJSON renders the externally-tagged wire form for an op kind.
type TreeOpSplitLeaf ¶ added in v0.2.0
type TreeOpSplitLeaf struct {
Node OpId
NewId OpId
Sort TreeSortKey
AtChar int
Prev OpId
}
TreeOpSplitLeaf splits a leaf at a char boundary into two adjacent leaves of the same kind. AtChar is a Unicode scalar count (binding-stable).
func (TreeOpSplitLeaf) MarshalJSON ¶ added in v0.2.0
func (k TreeOpSplitLeaf) MarshalJSON() ([]byte, error)
MarshalJSON renders the externally-tagged wire form for an op kind.
type TreeOpTombstone ¶ added in v0.2.0
type TreeOpTombstone struct {
Node OpId
}
TreeOpTombstone tombstones a node (sticky; smaller op id wins concurrently).
func (TreeOpTombstone) MarshalJSON ¶ added in v0.2.0
func (k TreeOpTombstone) MarshalJSON() ([]byte, error)
MarshalJSON renders the externally-tagged wire form for an op kind.
type TreeSortKey ¶ added in v0.2.0
TreeSortKey is a fractional-index child position: orderable bytes (0..255) tiebroken by the minting peer. Frac is a []int (not []byte) so it marshals as a JSON number array, never base64.
type TreeUpdate ¶ added in v0.2.0
type TreeUpdate struct {
Ops []TreeOp
}
TreeUpdate is the op-delta wire message: the output of Diff and the input to ApplyUpdate. Ops are ordered by dotted id; dependencies are buffered on apply until they arrive, so delivery need not be contiguous.
func TreeUpdateFromWire ¶ added in v0.2.0
func TreeUpdateFromWire(data []byte) (TreeUpdate, error)
TreeUpdateFromWire decodes a TreeUpdate from JSON bytes.
func (TreeUpdate) MarshalJSON ¶ added in v0.2.0
func (u TreeUpdate) MarshalJSON() ([]byte, error)
MarshalJSON renders {"ops": [...]} with ops always an array (never null).
func (*TreeUpdate) UnmarshalJSON ¶ added in v0.2.0
func (u *TreeUpdate) UnmarshalJSON(b []byte) error
UnmarshalJSON decodes a TreeUpdate.
type TreeVersionFrontier ¶ added in v0.2.0
type TreeVersionFrontier struct {
// contains filtered or unexported fields
}
TreeVersionFrontier is a dotted version frontier: per peer, exactly which op dots are held. Unlike a version vector (per-peer max), this represents non-contiguous delivery so Diff never omits a missing interior op.
func NewTreeVersionFrontier ¶ added in v0.2.0
func NewTreeVersionFrontier() *TreeVersionFrontier
NewTreeVersionFrontier returns an empty frontier.
func (*TreeVersionFrontier) Contains ¶ added in v0.2.0
func (f *TreeVersionFrontier) Contains(id OpId) bool
Contains reports whether id is held by this frontier.
func (*TreeVersionFrontier) Copy ¶ added in v0.2.0
func (f *TreeVersionFrontier) Copy() *TreeVersionFrontier
Copy returns a deep copy.
func (*TreeVersionFrontier) Observe ¶ added in v0.2.0
func (f *TreeVersionFrontier) Observe(id OpId)
Observe records id as held.
type TumblingCountCore ¶ added in v0.15.0
type TumblingCountCore[T comparable] struct { // contains filtered or unexported fields }
TumblingCountCore is the count-based tumbling window compute core.
func NewTumblingCountCore ¶ added in v0.15.0
func NewTumblingCountCore[T comparable](n uint64, policy MergePolicy[T]) *TumblingCountCore[T]
NewTumblingCountCore builds a count-tumbling core emitting every n elements.
func (*TumblingCountCore[T]) Push ¶ added in v0.15.0
func (c *TumblingCountCore[T]) Push(v T) Opt[T]
Push accumulates an element; on the n-th it emits the window fold and resets.
type TumblingCountWindow ¶ added in v0.15.0
type TumblingCountWindow[T comparable] struct { // contains filtered or unexported fields }
TumblingCountWindow is a reactive count-tumbling window projecting the last emitted aggregate.
func TumblingCount ¶ added in v0.15.0
func TumblingCount[T comparable](ctx *Context, n uint64, policy MergePolicy[T]) *TumblingCountWindow[T]
TumblingCount constructs a reactive count-tumbling window over ctx.
func (*TumblingCountWindow[T]) Output ¶ added in v0.15.0
func (w *TumblingCountWindow[T]) Output() Opt[T]
Output reads the last emitted aggregate (subscribes in a computation).
func (*TumblingCountWindow[T]) OutputCell ¶ added in v0.15.0
func (w *TumblingCountWindow[T]) OutputCell() *Source[Opt[T]]
OutputCell returns the reactive cell holding the last emitted aggregate.
func (*TumblingCountWindow[T]) Push ¶ added in v0.15.0
func (w *TumblingCountWindow[T]) Push(v T) Opt[T]
Push accumulates an element, projecting the aggregate onto the output cell when the window emits. Returns the emitted aggregate (absent if none).
type TumblingTimeCore ¶ added in v0.15.0
type TumblingTimeCore[T comparable] struct { // contains filtered or unexported fields }
TumblingTimeCore is the time-based tumbling window compute core.
func NewTumblingTimeCore ¶ added in v0.15.0
func NewTumblingTimeCore[T comparable](period uint64, policy MergePolicy[T]) *TumblingTimeCore[T]
NewTumblingTimeCore builds a time-tumbling core with the given period.
func (*TumblingTimeCore[T]) Push ¶ added in v0.15.0
func (c *TumblingTimeCore[T]) Push(_ uint64, v T)
Push accumulates an element into the current window (no emit).
func (*TumblingTimeCore[T]) Tick ¶ added in v0.15.0
func (c *TumblingTimeCore[T]) Tick(now uint64) Opt[T]
Tick emits the window fold at a period boundary (empty window emits absent).
type TumblingTimeWindow ¶ added in v0.15.0
type TumblingTimeWindow[T comparable] struct { // contains filtered or unexported fields }
TumblingTimeWindow is a reactive time-tumbling window (Push(now,v) + Tick(now)).
func TumblingTime ¶ added in v0.15.0
func TumblingTime[T comparable](ctx *Context, period uint64, policy MergePolicy[T]) *TumblingTimeWindow[T]
TumblingTime constructs a reactive time-tumbling window over ctx.
func (*TumblingTimeWindow[T]) Output ¶ added in v0.15.0
func (w *TumblingTimeWindow[T]) Output() Opt[T]
Output reads the last emitted aggregate (subscribes in a computation).
func (*TumblingTimeWindow[T]) OutputCell ¶ added in v0.15.0
func (w *TumblingTimeWindow[T]) OutputCell() *Source[Opt[T]]
OutputCell returns the reactive cell holding the last emitted aggregate.
func (*TumblingTimeWindow[T]) Push ¶ added in v0.15.0
func (w *TumblingTimeWindow[T]) Push(now uint64, v T)
Push accumulates an element into the current window (no emit).
func (*TumblingTimeWindow[T]) Tick ¶ added in v0.15.0
func (w *TumblingTimeWindow[T]) Tick(now uint64) Opt[T]
Tick emits the window fold at a period boundary, projecting it onto output.
type VecDequeStorage ¶ added in v0.3.0
type VecDequeStorage[T any] struct { // contains filtered or unexported fields }
VecDequeStorage is the reference QueueStorage backend: an unbounded (or optionally bounded) slice-backed FIFO. This is the default and the storage form the conformance fixtures serialize — element order is FIFO order.
The overflow policy is reject: TryPush on a bounded, full queue returns QueuePushFull and leaves the queue unchanged.
func NewBoundedVecDequeStorage ¶ added in v0.3.0
func NewBoundedVecDequeStorage[T any](n int) *VecDequeStorage[T]
NewBoundedVecDequeStorage returns a bounded VecDequeStorage with capacity n. Panics if n <= 0 (a zero-capacity queue can never accept an element and has no meaningful backpressure signal).
func NewVecDequeStorage ¶ added in v0.3.0
func NewVecDequeStorage[T any]() *VecDequeStorage[T]
NewVecDequeStorage returns an unbounded VecDequeStorage.
func (*VecDequeStorage[T]) Capacity ¶ added in v0.3.0
func (s *VecDequeStorage[T]) Capacity() (int, bool)
Capacity reports the bound and true for a bounded storage, or 0 and false.
func (*VecDequeStorage[T]) Close ¶ added in v0.3.0
func (s *VecDequeStorage[T]) Close()
Close marks the queue closed. Idempotent and terminal.
func (*VecDequeStorage[T]) Elements ¶ added in v0.3.0
func (s *VecDequeStorage[T]) Elements() []T
Elements returns a copy of the FIFO contents in delivery order (head first). Used by the conformance harness and for snapshot serialization; production code may choose a more efficient binary encoding.
func (*VecDequeStorage[T]) IsClosed ¶ added in v0.3.0
func (s *VecDequeStorage[T]) IsClosed() bool
IsClosed reports whether the queue has been closed.
func (*VecDequeStorage[T]) Len ¶ added in v0.3.0
func (s *VecDequeStorage[T]) Len() int
Len reports the number of elements held.
func (*VecDequeStorage[T]) Peek ¶ added in v0.3.0
func (s *VecDequeStorage[T]) Peek() (T, bool)
Peek returns the head element and true, or the zero T and false when empty.
func (*VecDequeStorage[T]) TryPop ¶ added in v0.3.0
func (s *VecDequeStorage[T]) TryPop() (T, QueuePopError)
TryPop removes and returns the head element. A closed non-empty queue keeps draining; only a closed empty queue returns Closed.
func (*VecDequeStorage[T]) TryPush ¶ added in v0.3.0
func (s *VecDequeStorage[T]) TryPush(value T) QueuePushError
TryPush appends value, or returns Full/Closed without mutating on reject.
type WindowPolicy ¶ added in v0.11.0
type WindowPolicy struct {
// contains filtered or unexported fields
}
WindowPolicy — Case 8, time-windowed coalescence (debounce/throttle). Flushes when it reaches windowOps ops or on an explicit Tick. Because a window is just a flush group, associativity keeps the converged state unchanged.
func NewWindowPolicy ¶ added in v0.11.0
func NewWindowPolicy(windowOps uint64) *WindowPolicy
NewWindowPolicy creates a window that flushes every windowOps ops (min 1).
func (*WindowPolicy) OnIngress ¶ added in v0.11.0
func (w *WindowPolicy) OnIngress() bool
OnIngress records one ingress; returns true when the window is full and should flush.
func (*WindowPolicy) Tick ¶ added in v0.11.0
func (w *WindowPolicy) Tick() bool
Tick signals the debounce/throttle interval elapsed: flush whatever is pending.
type WireLwwRegister ¶ added in v0.8.0
type WireLwwRegister[V any] struct { // contains filtered or unexported fields }
WireLwwRegister is a last-writer-wins register liveness cell (per-pid alive, owner lease).
Keyed by WireStamp ((wall_time, logical, peer) total order): the highest stamp wins, so an OS process-exit write (alive = false at a fresh stamp) dominates a stale re-assert. Join is the stamp-max, a semilattice.
func NewWireLwwRegister ¶ added in v0.8.0
func NewWireLwwRegister[V any](stamp WireStamp, value V) *WireLwwRegister[V]
NewWireLwwRegister returns a register holding value written at stamp.
func (*WireLwwRegister[V]) Join ¶ added in v0.8.0
func (r *WireLwwRegister[V]) Join(other *WireLwwRegister[V])
Join folds another replica's register (keep the higher stamp).
func (*WireLwwRegister[V]) Set ¶ added in v0.8.0
func (r *WireLwwRegister[V]) Set(stamp WireStamp, value V)
Set writes value at stamp iff it dominates the current stamp.
func (*WireLwwRegister[V]) Stamp ¶ added in v0.8.0
func (r *WireLwwRegister[V]) Stamp() WireStamp
Stamp returns the current decisive stamp.
func (*WireLwwRegister[V]) Value ¶ added in v0.8.0
func (r *WireLwwRegister[V]) Value() V
Value returns the current value.
type WireStamp ¶
type WireStamp struct {
WallTime int64 `json:"wall_time"`
Logical int64 `json:"logical"`
Peer PeerId `json:"peer"`
}
WireStamp is the codec-stable wire mirror of the runtime HLC stamp — a total order (wall_time, logical, peer). It is all plain integers so the wire format is stable whether or not a peer compiles the CRDT runtime in; the runtime representation is HlcStamp (hlc.go). Conversion HlcStamp<->WireStamp is owned by crdt.go.
func NewWireStamp ¶
NewWireStamp constructs a WireStamp.
type WorkQueueCell ¶ added in v0.14.0
type WorkQueueCell[T any] struct { VisibilityTimeout int64 MaxDeliveries uint64 // contains filtered or unexported fields }
WorkQueueCell is a process-local competing-consumer work queue.
Item ids survive retries while every claim receives a fresh delivery id. Nack and expired deliveries requeue at the tail until MaxDeliveries is reached, then move to the dead-letter list. A lease is live at its deadline and expires strictly after it.
This object is a local serialization point. Distributed/HA deployments must place a consensus-backed leader or adapter in front of it.
func NewWorkQueueCell ¶ added in v0.14.0
func NewWorkQueueCell[T any](ctx *Context, visibilityTimeout int64, maxDeliveries uint64) *WorkQueueCell[T]
NewWorkQueueCell creates an empty queue. It panics for invalid configuration.
func (*WorkQueueCell[T]) Ack ¶ added in v0.14.0
func (q *WorkQueueCell[T]) Ack(worker string, deliveryID uint64) bool
func (*WorkQueueCell[T]) Claim ¶ added in v0.14.0
func (q *WorkQueueCell[T]) Claim(worker string, now int64) (WorkQueueDelivery[T], bool)
func (*WorkQueueCell[T]) DeadLetterItems ¶ added in v0.14.0
func (q *WorkQueueCell[T]) DeadLetterItems() []WorkQueueDeadLetter[T]
func (*WorkQueueCell[T]) DeadLetterLen ¶ added in v0.14.0
func (q *WorkQueueCell[T]) DeadLetterLen() int
func (*WorkQueueCell[T]) InFlightDeliveries ¶ added in v0.14.0
func (q *WorkQueueCell[T]) InFlightDeliveries() []WorkQueueDelivery[T]
func (*WorkQueueCell[T]) InFlightLen ¶ added in v0.14.0
func (q *WorkQueueCell[T]) InFlightLen() int
func (*WorkQueueCell[T]) IsEmpty ¶ added in v0.14.0
func (q *WorkQueueCell[T]) IsEmpty() bool
func (*WorkQueueCell[T]) Nack ¶ added in v0.14.0
func (q *WorkQueueCell[T]) Nack(worker string, deliveryID uint64) bool
func (*WorkQueueCell[T]) PendingItems ¶ added in v0.14.0
func (q *WorkQueueCell[T]) PendingItems() []WorkQueueItem[T]
func (*WorkQueueCell[T]) PendingLen ¶ added in v0.14.0
func (q *WorkQueueCell[T]) PendingLen() int
func (*WorkQueueCell[T]) Push ¶ added in v0.14.0
func (q *WorkQueueCell[T]) Push(value T) uint64
func (*WorkQueueCell[T]) ReaderHandles ¶ added in v0.14.0
func (q *WorkQueueCell[T]) ReaderHandles() WorkQueueReaderHandles
func (*WorkQueueCell[T]) ReapExpired ¶ added in v0.14.0
func (q *WorkQueueCell[T]) ReapExpired(now int64) int
type WorkQueueDeadLetter ¶ added in v0.14.0
type WorkQueueDeadLetter[T any] struct { ItemID uint64 Value T Attempts uint64 Reason WorkQueueDeadLetterReason }
type WorkQueueDeadLetterReason ¶ added in v0.14.0
type WorkQueueDeadLetterReason string
const ( WorkQueueDeadLetterNack WorkQueueDeadLetterReason = "nack" WorkQueueDeadLetterExpired WorkQueueDeadLetterReason = "expired" )
type WorkQueueDelivery ¶ added in v0.14.0
type WorkQueueDelivery[T any] struct { DeliveryID uint64 ItemID uint64 Value T Worker string Attempt uint64 Deadline int64 }
WorkQueueDelivery is one exclusive leased delivery to a worker.
type WorkQueueItem ¶ added in v0.14.0
WorkQueueItem is a stable logical item. Attempts counts completed claims.
Source Files
¶
- async_context.go
- async_disposal.go
- async_queue_family.go
- async_reactive_map.go
- capability.go
- causal_receipts.go
- collections.go
- command_plane.go
- coordination.go
- core.go
- crdt.go
- crdt_tree.go
- disposal.go
- distributed.go
- durable_outbox_store.go
- ffi.go
- ffi_cgo.go
- hlc.go
- instrumentation.go
- ipc.go
- keyed_order.go
- lossless_tree_crdt.go
- membership.go
- merge.go
- option.go
- presence.go
- queue.go
- rateshape.go
- reactive_map.go
- registers.go
- relay.go
- reliable_sync.go
- resilience.go
- sem_tree.go
- seq_crdt.go
- service.go
- shm_blob_arena.go
- signaling.go
- stable_id.go
- state_chart.go
- state_machine.go
- state_projection.go
- stdlib.go
- temporal.go
- text_crdt.go
- thread_safe.go
- thread_safe_queue_family.go
- thread_safe_reactive_map.go
- transport.go
- transport_shm.go
- types.go
- windowing.go
- work_queue.go
Directories
¶
| Path | Synopsis |
|---|---|
|
cmd
|
|
|
lazily-interop-peer
command
Command lazily-interop-peer is NDJSON test infrastructure for the cross-binding Lazily interoperability suite.
|
Command lazily-interop-peer is NDJSON test infrastructure for the cross-binding Lazily interoperability suite. |
|
internal
|
|
|
goid
Package goid provides a fast goroutine-id lookup for reentrant locking.
|
Package goid provides a fast goroutine-id lookup for reentrant locking. |