first commit

This commit is contained in:
2026-05-29 08:20:56 +01:00
commit 949299f58d
6368 changed files with 527176 additions and 0 deletions

View File

@@ -0,0 +1,60 @@
# g-counter
<!-- begin:auto-docs -->
_(no submodules)_
<!-- end:auto-docs -->
## 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.