@nxtedition/sequence
v1.1.5
Published
A compact, ordered sequence tracker for distributed systems.
Maintainers
Keywords
Readme
@nxtedition/sequence
A compact, ordered sequence tracker for distributed systems.
Why
In distributed systems with multiple concurrent producers, you need a way to track "how far along" each producer is. A naive approach uses a single counter, but that loses per-producer granularity. A map of producer IDs to sequence numbers works but is verbose to serialize and expensive to compare.
Sequence solves this by packing per-producer sequence numbers into a single string representation (count-seq~id_seq~id_...) that is cheap to parse, serialize, and compare. The leading total count doubles as a cheap corruption check when parsing. Identity hashing lets you detect when two sequences track different producer sets without comparing every ID.
has() implements per-component domination — a.has(b) is true only when a has reached or passed b on every producer — which is the correct semantics for resumption tokens (vector clocks). It is a partial order: two sequences can be incomparable (each ahead of the other on a different producer), in which case a.has(b) and b.has(a) are both false.
Install
npm install @nxtedition/sequenceUsage
import { Sequence } from '@nxtedition/sequence'
// Create from parts
const seq = new Sequence([
{ id: 'producer-a', sequence: 100 },
{ id: 'producer-b', sequence: 50 },
])
seq.count // 150
seq.length // 2
seq.at(0) // 100
seq.idAt(0) // 'producer-a'
seq.identity // stable hash of producer IDs
;[...seq.entries()] // [['producer-a', 100], ['producer-b', 50]]
// Serialize and parse
const str = seq.toString() // '150-100~producer-a_50~producer-b'
const parsed = new Sequence(str)
// Compare (per-component domination)
seq.has(parsed) // true (this has reached parsed on every producer)
// Mutate
seq.set(0, 200)
seq.count // 250
seq.toString() // re-serialized with updated values
// Safe parsing
Sequence.tryParse('maybe-valid') // Sequence | nullAPI
Sequence
new Sequence(value?, identity?)
Creates a new sequence.
value— One of:null | undefined— empty sequence (count 0)string— parse from serialized format (count-seq~id_seq~id_...)Sequence— copy constructorArray<{ id: string, sequence: number }>— from partsArray<string>— from"sequence~id"stringsArray<number>— from anonymous sequence numbers
identity— Optional identity validation:number— assert computed identity matches (a carrier value for anonymous/numeric sequences)Array<string | { id: string }>— assert IDs (and length) match parts
Throws if the input is malformed, counts don't match, sequence numbers are non-canonical/out of safe-integer range, an id contains a separator (_ or ~), or identity validation fails.
Properties
count: number— Sum of all part sequence numberslength: number— Number of partsidentity: number— Stable signed 32-bit hash of producer IDs (0 for empty/anonymous sequences). Truncated to int32 so it can round-trip through anInt32Array.
Methods
at(index: number): number— Get the sequence value at index. Throws on out-of-range.idAt(index: number): string— Get the producer id at index. Throws on out-of-range.entries(): IterableIterator<[string, number]>— Iterate[id, sequence]pairs in part order.set(index: number, sequence: number): void— Update sequence value at index. Invalidates cachedtoString()andcount.has(other: string | Sequence, strict?: boolean): boolean— Returnstrueifthishas reached/seenotheron every producer (per-component domination). Whenstrictistrue(default), throws if the producer sets differ.compare(other: string | Sequence, strict?: boolean): number— Deprecated. A lexicographic (first-differing-producer) total order, not domination — it cannot express incomparable sequences. Preferhas().toString(): string— Serialize to string. Result is cached until mutation.
Static Methods
Sequence.has(a, b, strict?): boolean— Returnstrueifadominatesb(either may be null/undefined/string/Sequence).Sequence.compare(a, b, strict?): number— Deprecated. Lexicographic comparison; seecompare()above.Sequence.tryParse(str): Sequence | null— Parse a string, returningnullon failure instead of throwing.
Constants
ID_SEP— The separator character between sequence number and ID (~).
License
MIT
