Files
skills/docs/foundation/flow/crdt/src/crdts/g-counter/g-counter.md
2026-05-29 08:20:56 +01:00

1.8 KiB

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

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

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.