
Security News
Inside Lodash’s Security Reset and Maintenance Reboot
Lodash 4.17.23 marks a security reset, with maintainers rebuilding governance and infrastructure to support long-term, sustainable maintenance.
@loro-dev/flock
Advanced tools
TypeScript bindings for the Flock CRDT with mergeable export/import utilities.
TypeScript bindings for the Flock Conflict-free Replicated Data Type (CRDT). Flock stores JSON-like values at composite keys, keeps causal metadata, and synchronises peers through mergeable export bundles. This package wraps the core MoonBit implementation and exposes a typed Flock class for JavaScript runtimes (Node.js ≥18, modern browsers, and workers).
pnpm add @loro-dev/flock
# or
npm install @loro-dev/flock
# or
yarn add @loro-dev/flock
The library ships ESM, CommonJS, and TypeScript declaration files. It has no runtime dependencies beyond the standard Web Crypto API for secure peer identifiers (falls back to Math.random when unavailable).
import { Flock } from "@loro-dev/flock";
// Each replica uses a stable UTF-8 peer id (<128 bytes) to maintain version vectors.
const peerId = crypto.randomUUID();
const store = new Flock(peerId);
store.put(["users", "42"], { name: "Ada", online: true });
console.log(store.get(["users", "42"]));
// Share incremental updates with a remote replica.
const bundle = store.exportJson();
// On another node, merge and materialise the same data.
const other = new Flock();
other.importJson(bundle);
other.merge(store);
// Subscribe to local or remote mutations.
const unsubscribe = store.subscribe(({ source, events }) => {
for (const { key, value } of events) {
console.log(`[${source}]`, key, value ?? "<deleted>");
}
});
store.delete(["users", "42"]);
unsubscribe();
exportJson() to serialise local changes since an optional version vector.importJson() and reconcile replicas using merge().version() and getMaxPhysicalTime() when orchestrating incremental syncs.Flock.checkConsistency() in tests to assert that two replicas converged to the same state.Value: JSON-compatible data (string, number, boolean, null, nested arrays/objects).KeyPart: string | number | boolean. Keys are arrays of parts (e.g. ["users", 42]). Invalid keys raise at runtime.ExportRecord: { c: string; d?: Value } – CRDT payload with hybrid logical clock data.ExportBundle: Record<string, ExportRecord> mapping composite keys to last-writer metadata.VersionVector: Record<string, { physicalTime: number; logicalCounter: number }> indexed by peer identifiers (UTF-8 strings ordered by their byte representation).ScanRow: { key: KeyPart[]; raw: ExportRecord; value?: Value } returned by scan().EventBatch: { source: string; events: Array<{ key: KeyPart[]; value?: Value }> } emitted to subscribers.All types are exported from the package entry point for use in TypeScript projects.
new Flock(peerId?: string) – creates a replica. When omitted, a random 64-character hex peer id is generated. The id persists only in memory; persist it yourself for durable replicas.
Flock.fromJson(bundle: ExportBundle, peerId: string): Flock – instantiate directly from a full snapshot bundle.Flock.checkConsistency(a: Flock, b: Flock): boolean – deep equality check useful for tests; returns true when both replicas expose the same key/value pairs and metadata.setPeerId(peerId: string): void – replace the current peer id. Use cautiously; changing ids affects causality tracking.peerId(): string – returns the identifier for the replica.getMaxPhysicalTime(): number – highest physical timestamp observed by this replica (same units as the timestamps you pass to now, e.g. Date.now() output). Helpful for synchronising clocks and diagnosing divergence.version(): VersionVector – current version vector including logical counters per peer.checkInvariants(): void – throws if internal CRDT invariants are violated. Intended for assertions in tests or diagnostics, not for production control flow.put(key: KeyPart[], value: Value, now?: number): void – write a JSON value. The optional now overrides the physical time (numeric timestamp such as Date.now() output) used for the replica’s hybrid logical clock. Invalid keys or non-finite timestamps throw.set(key: KeyPart[], value: Value, now?: number): void – alias of put for frameworks that prefer “set” terminology.delete(key: KeyPart[], now?: number): void – tombstone a key. The optional time override follows the same rules as put.putMvr(key: KeyPart[], value: Value, now?: number): void – attach a value to the key’s Multi-Value Register. Unlike put, concurrent writes remain alongside each other.get(key: KeyPart[]): Value | undefined – fetch the latest visible value. Deleted keys resolve to undefined.getMvr(key: KeyPart[]): Value[] – read all concurrent values associated with a key’s Multi-Value Register (empty array when unset).kvToJson(): ExportBundle – snapshot of every key/value pair including tombstones. Useful for debugging or serialising the entire store.scan(options?: ScanOptions): ScanRow[] – in-order range scan. Supports:
start / end: { kind: "inclusive" | "exclusive"; key: KeyPart[] } or { kind: "unbounded" }.prefix: restrict results to keys beginning with the provided prefix.
Results include the materialised value (if any) and raw CRDT record.exportJson(from?: VersionVector): ExportBundle – export causal updates. Provide a VersionVector from a remote replica to stream only novel changes; omit to export the entire dataset.importJson(bundle: ExportBundle): void – apply a bundle received from another replica. Invalid payloads throw.merge(other: Flock): void – merge another replica instance directly (both replicas end up with the joined state).subscribe(listener: (batch: EventBatch) => void): () => void – register for mutation batches. Each callback receives the source ("local" for writes on this replica, peer id string for remote batches when available) and an ordered list of events. Return value unsubscribes the listener.exportJson, importJson, kvToJson, and fromJson all work with plain JavaScript objects, so they serialise cleanly through JSON or structured clone.undefined) throws a TypeError.TypeError or propagates an underlying runtime error from the native module.try/catch when dealing with untrusted data.Flock.checkConsistency() to assert two replicas match after a sequence of operations.checkInvariants() is safe inside unit tests to catch bugs in integration layers.exportJson snapshots with expect to capture deterministic state transitions.MIT © Loro contributors
FAQs
TypeScript bindings for the Flock CRDT with mergeable export/import utilities.
We found that @loro-dev/flock demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 2 open source maintainers collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
Lodash 4.17.23 marks a security reset, with maintainers rebuilding governance and infrastructure to support long-term, sustainable maintenance.

Security News
n8n led JavaScript Rising Stars 2025 by a wide margin, with workflow platforms seeing the largest growth across categories.

Security News
The U.S. government is rolling back software supply chain mandates, shifting from mandatory SBOMs and attestations to a risk-based approach.