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

1.6 KiB

pn-counter

(no submodules)

Purpose

Provides PNCounter, a positive-negative counter CRDT that supports both increment and decrement operations. Built from two G-Counters (one for increments, one for decrements), the net value is sum(increments) - sum(decrements). All CRDT invariants (commutativity, associativity, idempotency) are preserved.

Features

  • increment(nodeId, delta?) — adds to the increment counter for nodeId
  • decrement(nodeId, delta?) — adds to the decrement counter for nodeId
  • total() — net value: sum of all increments minus sum of all decrements
  • merge(state) — element-wise maximum on both increment and decrement counters
  • toJSON() / fromJSON() — serialization round-trip
  • clone() — deep copy

Usage: Basic Example

import { PNCounter } from "@suaveplan/crdt";

const counter = new PNCounter();
counter.increment("n1", 10);
counter.decrement("n1", 3);
console.log(counter.total()); // 7

Usage: Advanced Example

import { PNCounter } from "@suaveplan/crdt";

const a = new PNCounter("likes");
a.increment("user-1", 5);

const b = new PNCounter("likes");
b.decrement("user-2", 2);

a.merge(b.state());
console.log(a.total()); // 3 (5 - 2)

API Reference

PNCounter

  • increment(nodeId, delta?) — throws OPERATION_INVALID if delta ≤ 0
  • decrement(nodeId, delta?) — throws OPERATION_INVALID if delta ≤ 0
  • total(): number — net counter value

Implementation Notes

The value can be negative if decrements exceed increments. This is intentional — PNCounter does not enforce a floor of 0.