refactor(8.0): rename HNSWIndex class → JsHnswVectorIndex (scaffold step 3)

Step 3 of the brainy 8.0 rename scaffolding. The class name now matches
its role: the JS HNSW implementation of the VectorIndexProvider contract.
Per planning § 2.3: this is NOT cosmetic — leaving HNSWIndex when the
public contract is VectorIndexProvider creates a confusing read at the
implementation layer.

CHANGES

Repo-wide mechanical rename: HNSWIndex → JsHnswVectorIndex across 52
references in src/ + 5 references in tests/ via sed. Class declaration,
imports, JSDoc, comments, and identifiers all updated.

src/index.ts
- Primary public export: JsHnswVectorIndex (the new name).
- Backwards-compat alias: `export const HNSWIndex = JsHnswVectorIndex`
  with @deprecated note. Removed in the final 8.0 cleanup commit.

NO-OP scope

No behavioural change. The class is exactly the same; only the name
moved. Tests + build green.

VERIFICATION

- npx tsc --noEmit: clean
- npm test: 1468 / 1468 unit
This commit is contained in:
David Snelling 2026-06-09 13:07:56 -07:00
parent 8f87b35614
commit f39d420cb4
11 changed files with 80 additions and 70 deletions

View file

@ -31,10 +31,10 @@ const DEFAULT_CONFIG: HNSWConfig = {
/**
* Implements {@link VectorIndexProvider}: the vector-index surface Brainy calls
* on whatever the `'vector'` factory returns (its own `HNSWIndex`, or a native
* on whatever the `'vector'` factory returns (its own `JsHnswVectorIndex`, or a native
* acceleration provider).
*/
export class HNSWIndex implements VectorIndexProvider {
export class JsHnswVectorIndex implements VectorIndexProvider {
private nouns: Map<string, HNSWNoun> = new Map()
private entryPointId: string | null = null
private maxLevel = 0
@ -71,7 +71,7 @@ export class HNSWIndex implements VectorIndexProvider {
// COW (Copy-on-Write) support
private cowEnabled: boolean = false
private cowModifiedNodes: Set<string> = new Set()
private cowParent: HNSWIndex | null = null
private cowParent: JsHnswVectorIndex | null = null
// Deferred HNSW persistence for cloud storage performance
// In deferred mode, HNSW connections are only persisted on flush/close
@ -130,7 +130,7 @@ export class HNSWIndex implements VectorIndexProvider {
* Lifecycle: brainy.ts wires this after plugin activation when (a) the
* `vectorStore:mmap` provider is registered AND (b) the storage adapter
* resolves a real local path via `getBinaryBlobPath()`. Cloud adapters
* leave it null; HNSWIndex's behaviour is then identical to pre-2.4.0.
* leave it null; JsHnswVectorIndex's behaviour is then identical to pre-2.4.0.
*/
public setVectorBackend(backend: MmapVectorBackend | null): void {
this.vectorBackend = backend
@ -340,10 +340,10 @@ export class HNSWIndex implements VectorIndexProvider {
*
* @example
* ```typescript
* const parent = new HNSWIndex(config)
* const parent = new JsHnswVectorIndex(config)
* // ... parent has 1M nodes ...
*
* const fork = new HNSWIndex(config)
* const fork = new JsHnswVectorIndex(config)
* fork.enableCOW(parent) // <10ms - instant!
*
* // Reads share data
@ -353,7 +353,7 @@ export class HNSWIndex implements VectorIndexProvider {
* await fork.addItem(newItem) // Deep copies only modified nodes
* ```
*/
public enableCOW(parent: HNSWIndex): void {
public enableCOW(parent: JsHnswVectorIndex): void {
this.cowEnabled = true
this.cowParent = parent

View file

@ -1,10 +1,10 @@
/**
* @module hnsw/mmapVectorBackend
* @description Disk-resident vector cache backing HNSWIndex, wrapping the
* @description Disk-resident vector cache backing JsHnswVectorIndex, wrapping the
* `vectorStore:mmap` provider (cortex's NativeMmapVectorStore in production).
*
* **Why this exists.** Brainy's per-entity vector storage hits two ceilings as
* datasets grow: (1) every `HNSWIndex.preloadVectors` does a sequential
* datasets grow: (1) every `JsHnswVectorIndex.preloadVectors` does a sequential
* `storage.getNounVector` per id (no batch), and (2) cloud and FS storage both
* serialize each vector through JSON / msgpack, blocking zero-copy reads. An
* mmap-backed single-file vector store, addressed by the stable int from
@ -20,7 +20,7 @@
*
* **Local-FS only in 2.4.0.** Activated when the storage adapter exposes a
* real local path via `getBinaryBlobPath()`. Cloud adapters (S3 / R2 / GCS)
* return null and the backend is not constructed, so HNSWIndex falls back to
* return null and the backend is not constructed, so JsHnswVectorIndex falls back to
* the existing per-entity read path. Chunked vector segments for remote
* storage are the planned 2.4.0 #2 follow-up.
*/
@ -38,7 +38,7 @@ import type {
* @description Bridge between brainy's UUID-keyed vector API and cortex's
* int-slot mmap vector store. Translates UUIDs to stable int slots via the
* `EntityIdMapper`, grows the file on demand, and handles read misses by
* surfacing `null` (HNSWIndex's caller does the lazy storage fallback +
* surfacing `null` (JsHnswVectorIndex's caller does the lazy storage fallback +
* write-back). The class never touches per-entity storage directly it owns
* only the mmap layer.
*/

View file

@ -7,13 +7,13 @@
* - Storage: Already type-first from Phase 1a
*
* Architecture:
* - One HNSWIndex per NounType (42 total)
* - One JsHnswVectorIndex per NounType (42 total)
* - Lazy initialization (indexes created on first use)
* - Type routing for optimal performance
* - Falls back to multi-type search when type unknown
*/
import { HNSWIndex } from './hnswIndex.js'
import { JsHnswVectorIndex } from './hnswIndex.js'
import {
DistanceFunction,
HNSWConfig,
@ -25,7 +25,7 @@ import { euclideanDistance } from '../utils/index.js'
import type { BaseStorage } from '../storage/baseStorage.js'
import { prodLog } from '../utils/logger.js'
// Default HNSW parameters (same as HNSWIndex)
// Default HNSW parameters (same as JsHnswVectorIndex)
const DEFAULT_CONFIG: HNSWConfig = {
M: 16,
efConstruction: 200,
@ -58,7 +58,7 @@ export interface TypeAwareHNSWStats {
*/
export class TypeAwareHNSWIndex {
// One HNSW index per noun type (lazy initialization)
private indexes: Map<NounType, HNSWIndex> = new Map()
private indexes: Map<NounType, JsHnswVectorIndex> = new Map()
// Configuration
private config: HNSWConfig
@ -105,7 +105,7 @@ export class TypeAwareHNSWIndex {
// Enable COW on each underlying type-specific index
for (const [type, parentIndex] of parent.indexes.entries()) {
const childIndex = new HNSWIndex(this.config, this.distanceFunction, {
const childIndex = new JsHnswVectorIndex(this.config, this.distanceFunction, {
useParallelization: this.useParallelization,
storage: this.storage || undefined,
persistMode: this.persistMode
@ -183,9 +183,9 @@ export class TypeAwareHNSWIndex {
* Only types with entities get an index.
*
* @param type The noun type
* @returns HNSWIndex for this type
* @returns JsHnswVectorIndex for this type
*/
private getIndexForType(type: NounType): HNSWIndex {
private getIndexForType(type: NounType): JsHnswVectorIndex {
// Validate type is a valid NounType
const typeIndex = TypeUtils.getNounIndex(type)
if (typeIndex === undefined || typeIndex === null || typeIndex < 0) {
@ -197,7 +197,7 @@ export class TypeAwareHNSWIndex {
if (!this.indexes.has(type)) {
prodLog.info(`Creating HNSW index for type: ${type}`)
const index = new HNSWIndex(this.config, this.distanceFunction, {
const index = new JsHnswVectorIndex(this.config, this.distanceFunction, {
useParallelization: this.useParallelization,
storage: this.storage || undefined,
persistMode: this.persistMode