Files
modules/indexes-search/hyper-p2p-bloom-gossip/docs/api.md
T
2026-05-20 23:36:32 -04:00

114 lines
3.6 KiB
Markdown

# API: hyper-p2p-bloom-gossip
**Export:** `{ HyperP2PBloomGossip, PROTOCOL }`
**Protocol:** `bloom-gossip/v1` (`PROTOCOL` constant)
## Overview
`HyperP2PBloomGossip` is a probabilistic set-membership filter backed by a fixed-size bit array and an exact `_keys` set for statistics. When a Hyperswarm `topic` is configured, peers gossip individual key insertions (`bloom-add`) so remote nodes set the same bit positions without shipping the full filter on every update.
The filter answers **“might this key have been added?”** (`mightContain`) with possible false positives and no false negatives for keys that were actually inserted on this node or learned via gossip.
## Constructor
```js
const { HyperP2PBloomGossip } = require('hyper-p2p-bloom-gossip')
const mod = new HyperP2PBloomGossip(opts)
```
| Option | Type | Default | Description |
|--------|------|---------|-------------|
| `topic` | `string` \| `Buffer` \| `null` | `null` | Hyperswarm topic; swarm joins only when set and `ready()` runs |
| `keyPair` | `KeyPair` | `hypercore-crypto.keyPair()` | Swarm identity; `peerHex` derived from public key |
| `bits` | `number` | `2048` | Bloom bit width (`_size`) |
Internal constants: `HASH_COUNT = 4` (independent FNV-derived positions per key).
## Methods
### `add(key)`
- **Parameters:** `key` — non-empty string (via `assertNonEmpty`)
- **Returns:** `true` if newly inserted; `false` if duplicate
- **Side effects:** Sets four bit positions, adds to `_keys`, increments `stats.added`, emits `add`, gossips `bloom-add` when swarm is active
### `mightContain(key)`
- **Returns:** `false` if any required bit is unset; `true` if all four positions are set (may be false positive)
- **Increments:** `stats.queries`
### `exportBits()`
Returns a serializable snapshot:
```js
{ size, hashCount, bits, count }
```
- `bits` — hex-encoded underlying `Uint8Array`
- `count` — exact key count in `_keys`
### `importBits(payload)`
Replaces the in-memory bit array from `payload.bits` (hex). Optionally updates `_size` from `payload.size`. Does not rebuild `_keys` from bits alone.
### `size()`
Exact count of keys tracked in `_keys` (not probabilistic estimate).
### `getStats()`
```js
{
added, queries, gossipIn, gossipOut,
bits, keys, protocol
}
```
### `ready()`
If `topic` is set and swarm not yet created, calls `initModuleSwarm` with protocol `bloom-gossip/v1` and `_onGossip` handler. No-op when `topic` is null.
### `close()`
Clears bits and keys, destroys swarm, emits `closed`.
## Events
| Event | Payload | When |
|-------|---------|------|
| `add` | `{ key }` | Local insert |
| `remote-add` | `{ key, peer }` | Gossip learned new key |
| `closed` | — | After `close()` |
## Gossip wire format
| `type` | Fields | Handler |
|--------|--------|---------|
| `bloom-add` | `key`, `peer`, `at` | `_onGossip` — set bits if key not in `_keys` |
Outbound gossip uses `gossipSend` from `../../_shared/p2p-bare.js` when `_peerMsgs` is wired.
## Hashing
Positions use FNV-1a style hashing (`fnvHash`) with seeds `0x811c9dc5 + i * 31` for `i ∈ [0, HASH_COUNT)`.
## Errors
- `assertNonEmpty` on `add` / `mightContain` for empty keys
- Swarm destroy errors swallowed in `close()`
## Usage notes
- Without `topic`, the module is a local bloom filter only (`_gossip` no-ops).
- For bulk reconciliation, use `exportBits` / `importBits` on a schedule separate from per-key gossip.
- False positives scale with fill ratio; default 2048 bits suits modest key counts.
## Testing
```bash
npm install && npm test
```
See [examples/basic.js](../examples/basic.js) for a minimal local run.