feat(crdt): add @robonen/crdt package

Hand-built CRDT primitives: Lamport clock + version vectors, op-log,
LWW register/map, RGA sequence, fractional indexing, marks store, sync
encode, and doc/replica. Includes eslint flat config + composite tsconfig.
This commit is contained in:
2026-06-07 16:28:58 +07:00
parent 70a8678743
commit 008d85a8fd
35 changed files with 1152 additions and 0 deletions
+1
View File
@@ -0,0 +1 @@
export * from './op-log';
+43
View File
@@ -0,0 +1,43 @@
import type { OpId } from '../clock';
import { VersionVector } from '../clock';
/** Anything carrying an op id can live in the log. */
export interface HasOpId {
readonly id: OpId;
}
/**
* An append-only log of operations with a version vector for deduplication and
* delta computation. The op shape is domain-specific; the log only reads `id`.
*/
export class OpLog<Op extends HasOpId> {
private readonly ops: Op[] = [];
private readonly vv = new VersionVector();
/** Append an op unless already seen. Returns `true` if appended. */
append(op: Op): boolean {
if (this.vv.has(op.id))
return false;
this.ops.push(op);
this.vv.observe(op.id);
return true;
}
has(id: OpId): boolean {
return this.vv.has(id);
}
get version(): VersionVector {
return this.vv;
}
all(): readonly Op[] {
return this.ops;
}
/** Ops a remote replica (described by its version vector) hasn't seen. */
delta(remote: VersionVector): Op[] {
return this.ops.filter(op => !remote.has(op.id));
}
}