trellis
Version:
Agentic State Engine — event-sourced causal graph with branching, decision traces, and realtime sync for AI-native applications
73 lines • 2.51 kB
TypeScript
/**
* RealtimeText — a compact RGA-style sequence CRDT for collaborative text.
*
* Each character is a node with a globally-unique id (`<lamport>@<peerId>`) and
* an `after` pointer to the node it follows. Concurrent inserts sharing an
* anchor are ordered deterministically (higher lamport first, peer id as
* tiebreak), so all replicas converge regardless of delivery order. Deletes are
* tombstones, making them idempotent and commutative.
*
* This is intentionally minimal — enough for a genuine multiplayer editor demo
* without the weight of a full production CRDT (no block compaction, GC, or
* rich formatting).
*/
import type { RealtimeRoom } from './room.js';
export interface TextNode {
id: string;
ch: string;
after: string | null;
deleted: boolean;
}
export type TextOp = {
op: 'ins';
id: string;
ch: string;
after: string | null;
} | {
op: 'del';
id: string;
};
export interface RealtimeTextOptions {
peerId: string;
/** Optional room binding for automatic op + state sync. */
room?: RealtimeRoom;
/** Broadcast channel name when bound to a room. Default `text`. */
channel?: string;
}
export declare class RealtimeText {
private nodes;
private counter;
private peerId;
private listeners;
private room?;
private channel;
private unsubscribe?;
constructor(opts: RealtimeTextOptions);
/** Materialized visible text. */
toString(): string;
/** Current length of visible text. */
get length(): number;
/** Insert a string at a visible index. Broadcasts ops when room-bound. */
insert(index: number, str: string): TextOp[];
/** Delete `count` visible characters starting at `index`. */
delete(index: number, count?: number): TextOp[];
/** Apply a single remote op. Returns true if the document changed. */
applyOp(op: TextOp): boolean;
/** Apply a batch of remote ops, emitting once. */
applyOps(ops: TextOp[]): void;
/** Snapshot of all nodes (including tombstones) for state sync. */
getNodes(): TextNode[];
/** Merge a remote snapshot of nodes. */
mergeNodes(nodes: TextNode[]): void;
/** Subscribe to text changes. Returns an unsubscribe fn. */
onChange(cb: (text: string) => void): () => void;
/** Detach room bindings. */
dispose(): void;
private onRemote;
private publish;
private visibleNodes;
private nextId;
private bumpCounter;
private emit;
}
//# sourceMappingURL=text.d.ts.map