HashRing.ts
HashRing.ts overview
Section titled “HashRing.ts overview”Assigns string inputs to nodes with weighted consistent hashing.
A hash ring minimizes remapping when nodes are added, removed, or reweighted.
This makes it useful for routing requests, partitioning keys, and
distributing shards across service instances or storage backends. This module
can create rings, add or remove nodes by PrimaryKey, route an input string
to a node, and compute shard assignments.
Since v4.0.0
Exports Grouped by Category
Section titled “Exports Grouped by Category”combinators
Section titled “combinators”Adds a new node to the ring. If the node already exists in the ring, it will be updated. For example, you can use this to update the node’s weight.
When to use
Use to register one node in a HashRing so lookups and shard assignments can
return it, or update that node’s weight.
Details
Nodes are matched by PrimaryKey.value. The weight defaults to 1 and is
clamped to at least 0.1.
Gotchas
This mutates and returns the same ring instance.
See
addManyfor adding or updating several nodesremovefor unregistering a nodehasfor checking primary-key membership
Signature
declare const add: { <A extends PrimaryKey.PrimaryKey>( node: A, options?: { readonly weight?: number | undefined } ): (self: HashRing<A>) => HashRing<A> <A extends PrimaryKey.PrimaryKey>( self: HashRing<A>, node: A, options?: { readonly weight?: number | undefined } ): HashRing<A>}Since v3.19.0
addMany
Section titled “addMany”Adds new nodes to the ring. If a node already exists in the ring, it will be updated. For example, you can use this to update the node’s weight.
When to use
Use to register or update several nodes in a HashRing at the same weight.
Signature
declare const addMany: { <A extends PrimaryKey.PrimaryKey>( nodes: Iterable<A>, options?: { readonly weight?: number | undefined } ): (self: HashRing<A>) => HashRing<A> <A extends PrimaryKey.PrimaryKey>( self: HashRing<A>, nodes: Iterable<A>, options?: { readonly weight?: number | undefined } ): HashRing<A>}Since v3.19.0
Gets the node which should handle the given input. Returns undefined if the hashring has no elements with weight.
When to use
Use to route a single string input key to the current ring member responsible for that key.
See
getShardsfor assigning fixed shard indexes instead of routing one input string at a time
Signature
declare const get: <A extends PrimaryKey.PrimaryKey>(self: HashRing<A>, input: string) => A | undefinedSince v3.19.0
getShards
Section titled “getShards”Computes a balanced shard distribution across the nodes in the ring.
When to use
Use to precompute ownership for a fixed number of shard indexes across the current ring members.
Signature
declare const getShards: <A extends PrimaryKey.PrimaryKey>(self: HashRing<A>, count: number) => Array<A> | undefinedSince v3.19.0
Checks whether the ring contains a node with the same PrimaryKey value.
When to use
Use when you need to know whether registering a node would update an existing ring member because another node already has the same primary-key identity.
Details
Membership is checked with self.nodes.has(PrimaryKey.value(node)), so
matching is by primary key, not object identity or weight.
See
addfor registering or updating nodesremovefor removing nodes by the same primary-key identitygetfor routing an input string to a node
Signature
declare const has: { <A extends PrimaryKey.PrimaryKey>(node: A): (self: HashRing<A>) => boolean <A extends PrimaryKey.PrimaryKey>(self: HashRing<A>, node: A): boolean}Since v3.19.0
remove
Section titled “remove”Removes the node from the ring. No-op’s if the node does not exist.
When to use
Use to remove a node that has left the pool so future lookups and shard assignments stop returning it.
Details
Removal matches by PrimaryKey.value, so any value with the same primary key
removes the same ring member.
Gotchas
This mutates and returns the same ring instance.
See
addfor registering or updating a nodehasfor checking membership by primary key
Signature
declare const remove: { <A extends PrimaryKey.PrimaryKey>(node: A): (self: HashRing<A>) => HashRing<A> <A extends PrimaryKey.PrimaryKey>(self: HashRing<A>, node: A): HashRing<A>}Since v3.19.0
constructors
Section titled “constructors”Creates an empty HashRing.
When to use
Use to create an empty weighted consistent-hashing ring with the default or custom virtual-point density.
Details
baseWeight controls how many virtual points are added for a node with
weight 1; it defaults to 128 and is clamped to at least 1.
See
addfor registering one node after creationaddManyfor registering several nodes after creation
Signature
declare const make: <A extends PrimaryKey.PrimaryKey>(options?: { readonly baseWeight?: number | undefined}) => HashRing<A>Since v3.19.0
guards
Section titled “guards”isHashRing
Section titled “isHashRing”Checks whether a value is a HashRing.
When to use
Use to narrow an unknown value before treating it as a HashRing, such as
values crossing an untyped boundary.
Details
The guard checks for the module’s internal TypeId property and narrows to
HashRing<any>.
Gotchas
This is a structural type-id check; it does not validate the ring’s nodes,
ring, or weight state.
See
HashRingfor the type narrowed by this guardmakefor creating an emptyHashRing
Signature
declare const isHashRing: (u: unknown) => u is HashRing<any>Since v3.19.0
models
Section titled “models”HashRing (interface)
Section titled “HashRing (interface)”A weighted consistent-hashing ring for assigning inputs to nodes with stable remapping as nodes are added or removed.
When to use
Use to maintain a mutable weighted hash ring for routing keys or shards to
nodes identified by PrimaryKey.
Details
Nodes are identified by their PrimaryKey value and can be iterated from the
ring.
Signature
export interface HashRing<A extends PrimaryKey.PrimaryKey> extends Pipeable, Iterable<A> { readonly [TypeId]: typeof TypeId readonly baseWeight: number totalWeightCache: number readonly nodes: Map<string, [node: A, weight: number]> ring: Array<[hash: number, node: string]>}Since v3.19.0