# Metrics

> USearch for JavaScript

### Dense Indexes

A dense index holds equidimensional embeddings.
Only `dimensions` is required, and every other field derives from the geometry when it is left out:

```javascript
const index = usearch.DenseIndex.initRam(
  {
    dimensions: 128,
    metric: usearch.DenseMetric.Inner, // or Angular, the default, Euclidean, Hamming, Jaccard
    quantization: usearch.Scalar.BF16, // the default, or F16, E5M2, E4M3, E3M2, E2M3, I8, I4x2, U8, U4x2, U1x8
    connectivity: 32, // a power of two; absent derives it from the geometry
    valuesPerKey: 2, // absent is unbounded
  },
  [0, 1], // absent spreads the shards over every NUMA node
);
```

`import * as usearch from 'usearch';`

`import { DenseIndex } from 'usearch';`

## DenseMetric

Enumeration representing the metric kinds used to score the dissimilarity of two vectors.

```typescript
enum DenseMetric
```

- `Inner` = `&quot;inner&quot;`: The inner product.
- `Angular` = `&quot;angular&quot;`: The cosine distance.
- `Euclidean` = `&quot;euclidean&quot;`: The L2 distance.
- `Hamming` = `&quot;hamming&quot;`: The count of differing bits.
- `Jaccard` = `&quot;jaccard&quot;`: The bit-level Jaccard distance.

## DenseOptions

The geometry every dense index freezes at initialization, whatever its residency.

```typescript
interface DenseOptions
```

- `dimensions` `number`: Scalars per row, fixed for the life of the index.
- `metric?` `DenseMetric`: How dissimilarity is scored; defaults to `angular`.
- `quantization?` `Scalar`: The scalar kind vectors are stored in; defaults to `bf16`.
- `connectivity?` `number`: Neighbors per node; absent derives it from the geometry.
- `valuesPerKey?` `number`: Entries one key may carry; absent is unbounded.
- `cpuClass?` `string`: The CPU class a host index dispatches as by its canonical name; absent dispatches as the machine.
- `gpuClass?` `string`: The GPU class a device index dispatches as by its canonical name; absent dispatches as the devices.

## DenseIndex

A dense vector index, running every verb on the calling thread.

```typescript
class DenseIndex extends DenseIndexOn implements Disposable
```

`on(executor)` and `deferred(executor)` reach the same verbs on an executor, all but [`attend`](#attend), whose `rowOf` runs here.

## initRam

Creates an empty, mutable index in host memory, one shard per named NUMA node.

```typescript
static initRam(
    options: DenseOptions,
    memoryDomains?: number[],
): DenseIndex
```

- `options`: The geometry.
- `memoryDomains`: NUMA node IDs to shard over; absent spreads the shards over every node.

Throws: Will throw an error if any option is of incorrect type or invalid value.

## initVram

Creates an empty, mutable index in device memory, one shard per named CUDA ordinal.

```typescript
static initVram(
    options: DenseOptions,
    devices?: number[],
): DenseIndex
```

- `options`: The geometry.
- `devices`: CUDA ordinals to shard over; absent takes one free device.

Throws: Will throw an error if any option is of incorrect type or invalid value.

## loadRam

Copies a checkpoint into a new, mutable index in host memory, part `p` loading into shard `p` modulo the shard count.

```typescript
static loadRam(
    path: string,
    config: DenseLoadRamConfig = {},
): DenseIndex
```

The geometry and metric come from the checkpoint itself.

- `path`: The manifest of a sharded checkpoint, or a single monolith.
- `config`: The executor, the memory domains, and `valuesPerKey`.

## loadVram

Copies a checkpoint into a new, mutable index in device memory, with the placement rules of [`DenseIndex.loadRam`](#loadRam).

```typescript
static loadVram(
    path: string,
    config: DenseLoadVramConfig = {},
): DenseIndex
```

- `path`: The manifest of a sharded checkpoint, or a single monolith.
- `config`: The executor, the devices, and `valuesPerKey`.

## loadRamBuffer

Copies a monolith held in memory into a new, mutable index in host memory.

```typescript
static loadRamBuffer(
    buffer: Uint8Array | Monolith,
    config: DenseLoadRamBufferConfig = {},
): DenseIndex
```

- `buffer`: The bytes [`DenseVerbs.saveBuffer`](#saveBuffer) produced.
- `config`: The executor, the memory domains, and `valuesPerKey`.

## loadVramBuffer

Copies a monolith held in memory into a new, mutable index in device memory.

```typescript
static loadVramBuffer(
    buffer: Uint8Array | Monolith,
    config: DenseLoadVramBufferConfig = {},
): DenseIndex
```

- `buffer`: The bytes [`DenseVerbs.saveBuffer`](#saveBuffer) produced.
- `config`: The executor, the devices, and `valuesPerKey`.

## viewRam

Serves a checkpoint in place through a memory mapping, as a read-only index whose mutating verbs throw with [`Status.ReadOnly`](https://www.unum.cloud/docs/usearch/javascript/errors.md#ReadOnly); the files must stay unmodified while it lives.

```typescript
static viewRam(path: string): DenseIndex
```

- `path`: The manifest of a sharded checkpoint, or a single monolith.

## viewNvme

Serves a checkpoint in place from NVMe drives, read through the executor's submission rings, as a read-only index.

```typescript
static viewNvme(
    path: string,
    config: DenseViewNvmeConfig = {},
): DenseIndex
```

- `path`: The manifest of a sharded checkpoint, or a single monolith.
- `config`: The NVMe executor, and the paths to serve the parts from.

## on

The same verbs, each blocking on [`executor`](#executor), after every earlier submission to it.

```typescript
on(executor: Executor): DenseIndexOn
```

Binding-only.

- `executor`: The workers to run on; its residency must match the index's.

## deferred

The same verbs, each submitted to [`executor`](#executor) and answered as a [`Deferred`](https://www.unum.cloud/docs/usearch/javascript/errors.md#Deferred).

```typescript
deferred(executor: Executor): DenseIndexDeferredOn
```

Binding-only.

- `executor`: The workers to run on; its residency must match the index's.

## attend

Softmax attention of every query row over every key its graph walk scores, folded as Flash Attention folds key tiles, writing one attended row per query in `arena`.

```typescript
attend(
    queries: RowsView | Vector,
    values: RowsView | Vector,
    rowOf: ValueRowOf,
    arena: Arena,
    config: DenseAttendConfig = {},
): DenseVectors
```

The index stores no values: every key a walk scores resolves through `rowOf` to a row of
`values`, borrowed for the call, so only the keys a walk scores are ever resolved. The values
must be as wide as the keys and stored in the index's own scalar kind, and a key resolving
outside them refuses the call with [`ShapeMismatch`](https://www.unum.cloud/docs/usearch/javascript/errors.md#ShapeMismatch), since a missing row is a wrong softmax
rather than a smaller one. Row `t * headCount + h` of the queries, outputs and carry is head
`h` of token `t`, every head of a token sharing one walk.

`rowOf` runs on the calling thread, which no executor's thread is, so only the index itself
offers [`attend`](#attend). The first exception it throws stops every later lookup and is rethrown once
the call returns. Being a host function, it serves RAM handles alone: a VRAM walk resolves rows
through a device function, which this binding does not build, so a [`Vram`](https://www.unum.cloud/docs/usearch/javascript/residency.md#Vram) arena refuses with
[`Status.Device`](https://www.unum.cloud/docs/usearch/javascript/errors.md#Device).

- `queries`: One query row, or a run of them, at the index's own width.
- `values`: The value rows the scored keys resolve into, never copied.
- `rowOf`: Answers one 16-byte key with the index of its row of `values`.
- `arena`: The memory the attended rows land in, rewound by the call.
- `config`: Head count, output kind, softmax shape, the carry, and the telemetry sink.

## free

Releases the handle now, waiting for every deferred call naming it; a freed index refuses every later call, and a second [`free`](https://www.unum.cloud/docs/usearch/javascript/retrieval-and-streaming.md#free) does nothing.

```typescript
free(): void
```

## metadataRead

Reads a checkpoint's geometry and metric without loading it.

```typescript
static metadataRead(
    path: string,
    config: DenseMetadataReadConfig = {},
): DenseMetadata
```

- `path`: The manifest of a sharded checkpoint, or a single monolith.
- `config`: The workers the read runs on.

## metadataReadBuffer

Reads the geometry and metric of a monolith held in memory.

```typescript
static metadataReadBuffer(
    buffer: Uint8Array | Monolith,
    config: DenseMetadataReadBufferConfig = {},
): DenseMetadata
```

- `buffer`: The bytes [`DenseVerbs.saveBuffer`](#saveBuffer) produced.
- `config`: The workers the read runs on.

## contains

Verifies the presence of one key in the index.

```typescript
contains(key: KeyLike): boolean
```

Binding-only sugar over [`count`](#count).

- `key`: The identifier to be checked for presence in the index.

## cursor

Opens a walk over the current contents, every pull on this receiver's executor.

```typescript
cursor(starts?: KeysLike): DenseCursor
```

Without `starts` it yields every entry as stored; with them, the start keys' own entries first in order, then the entries those link to breadth-first, each once.

- `starts`: The keys to walk from; absent walks every entry.

## searchStream

Opens a resumable nearest-neighbor walk over one query row, every pull on this receiver's executor.

```typescript
searchStream(
    query: RowsView | Vector,
    config: DenseSearchStreamInitConfig = {},
): DenseSearchStream
```

- `query`: A single query row of the index geometry.
- `config`: The breadth.

## reserve

Claims room for a total entry count ahead of insertion, a hint, since insertions grow the index on demand.

```typescript
reserve(capacity: number): Answer<Receiving, void>
```

- `capacity`: The desired total capacity, the current size included.

## clear

Erases every entry, keeping the reserved capacity and the frozen geometry.

```typescript
clear(): Answer<Receiving, void>
```

## describe

Reports the frozen metadata and the current counters in one call.

```typescript
describe(): Answer<Receiving, DenseIndexDescription>
```

## health

Audits how much of the graph a search reaches from its landmarks.

```typescript
health(): Answer<Receiving, DenseReachability>
```

## count

Counts the entries stored under one key.

```typescript
count(key: KeyLike): Answer<Receiving, number>
```

- `key`: The identifier to be enumerated.

Throws: Will throw an error if the key is spelled in none of the accepted forms.

## insert

Add vectors to the index.

```typescript
insert(
    keys: KeysLike,
    vectors: RowsView | Vector,
    config: DenseInsertConfig = {},
): Answer<Receiving, void>
```

A typed array is one row, and a [`RowsView`](https://www.unum.cloud/docs/usearch/javascript/inputs-and-outputs.md#RowsView) is a batch borrowed in place. A single key
broadcasts across every row. A batch is all-or-nothing: a rejected one leaves the index
untouched.

Rows keep whatever type they arrived in and the engine converts them into the index's own
quantization, so the two are independent - a packed `u1x8` or a `bf16` row travels as
bytes with its [`RowsView`](https://www.unum.cloud/docs/usearch/javascript/inputs-and-outputs.md#RowsView) naming what they mean.

- `keys`: Input identifiers for every vector.
- `vectors`: One row, or a run of rows of the index width.
- `config`: Per-call breadth and telemetry sink.

Throws: Will throw an error if the length of keys doesn't match the number of vectors
or if it's not a single key.

## refine

Re-selects the neighbors of every stored entry against the finished graph.

```typescript
refine(
    config: DenseRefineConfig = {},
): Answer<Receiving, DenseRefineReport>
```

A cheap insertion pass followed by one refinement reaches a better graph, in less total
time, than a single expensive insertion pass - so a wide breadth belongs here.

- `config`: Per-call breadth and telemetry sink.

## search

Searches the index for the nearest neighbours of every query row.

```typescript
search(
    queries: RowsView | Vector,
    wanted: number,
    arena: Arena,
    config: DenseSearchConfig = {},
): Answer<Receiving, Matches>
```

The matches land in `arena` and come back as a view into it, so a recall sweep reusing one
arena allocates once.

- `queries`: One query row, or a run of them, at the index's own width.
- `wanted`: Matches per query, the "k" in "kANN".
- `arena`: The memory the matches land in, rewound by the call.
- `config`: Per-call breadth and telemetry sink.

Throws: Will throw when the queries do not split into whole rows of the index geometry.

## maxsim

Late-interaction scoring of multi-row queries: every query row takes its best match within a key, and those maxima sum to that key's score.

```typescript
maxsim(
    queries: RowsView | Vector,
    rowsPerQuery: number,
    wanted: number,
    arena: Arena,
    config: DenseMaxsimConfig = {},
): Answer<Receiving, DenseProducts>
```

The run is over keys rather than rows, which is what an index built with `valuesPerKey`
above one exists for. Runs on the inner-product kinds alone.

- `queries`: The token rows of every query, end to end.
- `rowsPerQuery`: Rows in every query; uniform, so padded queries apply as is.
- `wanted`: Documents per query, not per token row; zero keeps every document a query scored.
- `arena`: The memory the scored keys land in, rewound by the call.
- `config`: Per-call breadth and telemetry sink.

Throws: Will throw when the token rows do not split into whole queries.

## get

Retrieves the vectors stored under one key, one row per entry, in insertion order.

```typescript
get(
    key: KeyLike,
    arena: Arena,
    config: DenseGetConfig = {},
): Answer<Receiving, DenseVectors>
```

Rows land in `arena` and come back as a view into it, converted into [`scalar`](https://www.unum.cloud/docs/usearch/javascript/retrieval-and-streaming.md#scalar), shaped by the
width and stride the call reports.

- `key`: The identifier whose entries are exported.
- `arena`: The memory the rows land in, rewound by the call.
- `config`: The kind to export as.

## multiply

Multiplies a matrix against the index, sparsely - every pair the walk scored, not only the nearest.

```typescript
multiply(
    left: RowsView | Vector,
    arena: Arena,
    config: DenseMultiplyConfig = {},
): Answer<Receiving, DenseProducts>
```

How many pairs a walk scores is known only once it ends, so the products land in `arena` and
come back as views into it. The scores are unnormalized logits, so the handle must hold the
inner-product kind.

- `left`: One row, or a run of rows, at the index's own width.
- `arena`: The memory the pairs and their offsets land in, rewound by the call.
- `config`: Per-call pair bound, breadth and telemetry sink.

## absorb

Absorbs every donor into this index, one after another, keeping their graphs rather than re-inserting their vectors and linking each in across the appended part.

```typescript
absorb(
    donors: DenseIndex[],
): Answer<Receiving, DenseRefineReport>
```

A donor the library consumed refuses every later verb with [`Status.Uninitialized`](https://www.unum.cloud/docs/usearch/javascript/errors.md#Uninitialized); one it
did not absorb, like a donor of another scalar refused with [`Status.ConfigMismatch`](https://www.unum.cloud/docs/usearch/javascript/errors.md#ConfigMismatch), stays
a live index the caller still owns, though its entries may already have moved here. Until a
deferred absorb is final, every donor it names refuses every verb, and no other absorb can name it.

- `donors`: The indexes to absorb.

## split

Splits this index into the receivers, the inverse of [`absorb`](#absorb): graph-local parts keeping their edges, one per receiver, leaving this index empty but live.

```typescript
split(
    receivers: DenseIndex[],
    config: DenseSplitConfig = {},
): Answer<Receiving, DenseRefineReport>
```

Receivers must be empty and share the index's residency, scalar, class, metric, geometry and
shard count, or the call refuses with [`Status.ConfigMismatch`](https://www.unum.cloud/docs/usearch/javascript/errors.md#ConfigMismatch), moving nothing.

- `receivers`: Two or more empty indexes, each receiving one part.
- `config`: The seed and breadth.

## sample

Draws keys around `config.focus`, or across the whole index, each hanging from a shown or earlier draw and placed in three dimensions beside the shown ones.

```typescript
sample(
    wanted: number,
    arena: Arena,
    config: DenseSampleConfig = {},
): Answer<Receiving, DenseDraws>
```

A larger `wanted` draws a superset, so a view grows one connected sample as it zooms. Only RAM
samples yet.

- `wanted`: The upper bound on draws.
- `arena`: The memory the draws land in, rewound by the call.
- `config`: The shown keys and their coordinates, the focus, the seed and the breadth.

## save

Saves the index in the layout the path extension picks - one `.safegraphs` monolith, or a `.safegraphs.json` manifest beside its shards.

```typescript
save(path: string): Answer<Receiving, void>
```

- `path`: File path to write.

Throws: Will throw an error if `path` is not a string.

## saveBuffer

Writes the index into memory as one monolith.

```typescript
saveBuffer(arena: Arena): Answer<Receiving, Monolith>
```

The bytes are what a checkpoint holds, so a service that keeps its indexes in an object
store never touches the filesystem. They land in `arena` and come back as a view into it.

- `arena`: The memory the monolith lands in, rewound by the call.

## executor

The executor the verbs run on; absent runs them on the calling thread.

```typescript
readonly executor: Executor | undefined
```

