# g-counter _(no submodules)_ ## Purpose Provides `GCounter`, a grow-only counter CRDT. Each node in a distributed system maintains an independent counter; the global value is the sum of all node counters. Merge takes the element-wise maximum, ensuring convergence regardless of message ordering or duplicates. ## Features - `increment(nodeId, delta?)` — adds `delta` (default 1) to the node's counter; rejects non-positive deltas - `get(nodeId)` — returns the counter for a specific node - `total()` — returns the sum across all nodes (equivalent to `value()`) - `merge(state)` — element-wise maximum merge; idempotent and commutative - `toJSON()` / `fromJSON()` — round-trip serialization - `clone()` — deep copy ## Usage: Basic Example ```ts import { GCounter } from "@suaveplan/crdt"; const counter = new GCounter(); counter.increment("node-1", 5); counter.increment("node-2", 3); console.log(counter.total()); // 8 ``` ## Usage: Advanced Example ```ts import { GCounter } from "@suaveplan/crdt"; const a = new GCounter("ctr-1"); a.increment("n1", 10); const b = new GCounter("ctr-1"); b.increment("n2", 5); a.merge(b.state()); console.log(a.total()); // 15 ``` ## API Reference ### `GCounter` - `constructor(id?)` — optional stable ID - `increment(nodeId, delta?)` — throws `OPERATION_INVALID` if delta ≤ 0 - `get(nodeId): number` - `total(): number` — sum of all node counters - `merge(state: GCounterState): void` - `state(): GCounterState` - `toJSON(): string` / `fromJSON(json: string): void` - `clone(): this` ## Implementation Notes The merge operation is O(k) where k is the number of distinct nodes. The `clone()` method uses the same `GCounter` constructor — the `as this` cast is needed because TypeScript cannot statically know the concrete subclass type.