@@ -9,15 +9,24 @@ import {
99import { join , dirname , basename } from "node:path" ;
1010import { log } from "../logger.js" ;
1111import { CONFIG } from "../../config.js" ;
12- import { HierarchicalNSW } from "hnswlib-node" ;
12+
13+ let HNSWLib : any = null ;
14+
15+ async function loadHNSWLib ( ) : Promise < any > {
16+ if ( ! HNSWLib ) {
17+ const module = await import ( "hnswlib-wasm" ) ;
18+ HNSWLib = module ;
19+ }
20+ return HNSWLib ;
21+ }
1322
1423export interface HNSWIndexData {
1524 id : string ;
1625 vector : Float32Array ;
1726}
1827
1928export class HNSWIndex {
20- private index : HierarchicalNSW | null = null ;
29+ private index : any = null ;
2130 private idMap : Map < number , string > = new Map ( ) ;
2231 private reverseMap : Map < string , number > = new Map ( ) ;
2332 private nextId : number = 0 ;
@@ -34,15 +43,17 @@ export class HNSWIndex {
3443 private async ensureInitialized ( ) : Promise < void > {
3544 if ( this . initialized ) return ;
3645
46+ const hnsw = await loadHNSWLib ( ) ;
47+
3748 const dir = dirname ( this . indexPath ) ;
3849 if ( ! existsSync ( dir ) ) {
3950 mkdirSync ( dir , { recursive : true } ) ;
4051 }
4152
4253 if ( existsSync ( this . indexPath ) ) {
4354 try {
44- this . index = new HierarchicalNSW ( "cosine" , this . dimensions ) ;
45- await this . index . readIndex ( this . indexPath ) ;
55+ this . index = new hnsw . HierarchicalNSW ( "cosine" , this . dimensions ) ;
56+ this . index . readIndex ( this . indexPath ) ;
4657
4758 const metaPath = this . indexPath + ".meta" ;
4859 if ( existsSync ( metaPath ) ) {
@@ -60,22 +71,16 @@ export class HNSWIndex {
6071 path : this . indexPath ,
6172 error : String ( error ) ,
6273 } ) ;
63- this . index = new HierarchicalNSW ( "cosine" , this . dimensions ) ;
64- await this . index . initIndex ( this . maxElements ) ;
74+ this . index = new hnsw . HierarchicalNSW ( "cosine" , this . dimensions , this . maxElements ) ;
6575 }
6676 } else {
67- this . index = new HierarchicalNSW ( "cosine" , this . dimensions ) ;
68- await this . index . initIndex ( this . maxElements ) ;
77+ this . index = new hnsw . HierarchicalNSW ( "cosine" , this . dimensions , this . maxElements ) ;
6978 log ( "HNSW index created" , { path : this . indexPath , dimensions : this . dimensions } ) ;
7079 }
7180
7281 this . initialized = true ;
7382 }
7483
75- private vectorToArray ( vector : Float32Array ) : number [ ] {
76- return Array . from ( vector ) ;
77- }
78-
7984 async insert ( id : string , vector : Float32Array ) : Promise < void > {
8085 await this . ensureInitialized ( ) ;
8186
@@ -85,7 +90,7 @@ export class HNSWIndex {
8590 }
8691
8792 const internalId = this . nextId ++ ;
88- await this . index ! . addPoint ( this . vectorToArray ( vector ) , internalId ) ;
93+ this . index ! . addPoint ( vector , internalId ) ;
8994 this . idMap . set ( internalId , id ) ;
9095 this . reverseMap . set ( id , internalId ) ;
9196
@@ -102,7 +107,7 @@ export class HNSWIndex {
102107 }
103108
104109 const internalId = this . nextId ++ ;
105- await this . index ! . addPoint ( this . vectorToArray ( item . vector ) , internalId ) ;
110+ this . index ! . addPoint ( item . vector , internalId ) ;
106111 this . idMap . set ( internalId , item . id ) ;
107112 this . reverseMap . set ( item . id , internalId ) ;
108113 }
@@ -114,7 +119,7 @@ export class HNSWIndex {
114119 await this . ensureInitialized ( ) ;
115120
116121 try {
117- const results = await this . index ! . searchKnn ( this . vectorToArray ( queryVector ) , k ) ;
122+ const results = this . index ! . searchKnn ( queryVector , k ) ;
118123
119124 return results . neighbors
120125 . map ( ( internalId : number , idx : number ) => ( {
@@ -148,7 +153,7 @@ export class HNSWIndex {
148153 mkdirSync ( dir , { recursive : true } ) ;
149154 }
150155
151- await this . index . writeIndex ( this . indexPath ) ;
156+ this . index . writeIndex ( this . indexPath ) ;
152157
153158 const metaPath = this . indexPath + ".meta" ;
154159 const meta = {
0 commit comments