@faiss-node/native 0.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,551 @@
1
+ # @faiss-node/native
2
+
3
+ [![npm version](https://img.shields.io/npm/v/@faiss-node/native.svg)](https://www.npmjs.com/package/@faiss-node/native)
4
+ [![Node.js Version](https://img.shields.io/node/v/@faiss-node/native)](https://nodejs.org/)
5
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
6
+ [![Documentation](https://img.shields.io/badge/docs-GitHub%20Pages-blue)](https://anupammaurya6767.github.io/faiss-node-native/)
7
+
8
+ High-performance Node.js native bindings for [Facebook FAISS](https://github.com/facebookresearch/faiss) - the industry-standard vector similarity search library. Built for production-ready semantic search, RAG applications, and vector databases.
9
+
10
+ ## Features
11
+
12
+ - ๐Ÿš€ **Async Operations** - Non-blocking Promise-based API that never blocks the event loop
13
+ - ๐Ÿ”’ **Thread-Safe** - Mutex-protected concurrent operations for production workloads
14
+ - ๐Ÿ“ฆ **Multiple Index Types** - FLAT_L2, IVF_FLAT, and HNSW with optimized defaults
15
+ - ๐Ÿ’พ **Persistence** - Save/load indexes to disk or serialize to buffers
16
+ - โšก **High Performance** - Direct C++ bindings with zero-copy data transfer
17
+ - ๐Ÿงช **Well-Tested** - 1000+ comprehensive tests covering edge cases
18
+ - ๐Ÿ“š **TypeScript Support** - Full type definitions included
19
+ - ๐Ÿ”ง **Production-Ready** - Memory-safe, error-handled, and battle-tested
20
+
21
+ ## Installation
22
+
23
+ ### Quick Install
24
+
25
+ ```bash
26
+ npm install @faiss-node/native
27
+ ```
28
+
29
+ ### Prerequisites
30
+
31
+ **macOS:**
32
+ ```bash
33
+ brew install cmake libomp openblas faiss
34
+ ```
35
+
36
+ **Linux (Ubuntu/Debian):**
37
+ ```bash
38
+ sudo apt-get update
39
+ sudo apt-get install -y cmake libopenblas-dev libomp-dev
40
+ # Build FAISS from source (see below)
41
+ ```
42
+
43
+ **Building FAISS from Source (Linux):**
44
+ ```bash
45
+ git clone https://github.com/facebookresearch/faiss.git
46
+ cd faiss
47
+ cmake -B build -DFAISS_ENABLE_GPU=OFF -DFAISS_ENABLE_PYTHON=OFF
48
+ cmake --build build -j$(nproc)
49
+ sudo cmake --install build
50
+ ```
51
+
52
+ ### Build Native Module
53
+
54
+ After installing prerequisites:
55
+
56
+ ```bash
57
+ npm run build
58
+ ```
59
+
60
+ ## Quick Start
61
+
62
+ ```javascript
63
+ const { FaissIndex } = require('@faiss-node/native');
64
+
65
+ // Create an index
66
+ const index = new FaissIndex({ type: 'FLAT_L2', dims: 128 });
67
+
68
+ // Add vectors (single or batch)
69
+ const vectors = new Float32Array([
70
+ 1.0, 0.0, 0.0, 0.0, // Vector 1
71
+ 0.0, 1.0, 0.0, 0.0, // Vector 2
72
+ 0.0, 0.0, 1.0, 0.0 // Vector 3
73
+ ]);
74
+ await index.add(vectors);
75
+
76
+ // Search for nearest neighbors
77
+ const query = new Float32Array([1.0, 0.0, 0.0, 0.0]);
78
+ const results = await index.search(query, 2);
79
+
80
+ console.log('Labels:', results.labels); // Int32Array: [0, 1]
81
+ console.log('Distances:', results.distances); // Float32Array: [0, 2]
82
+
83
+ // Cleanup
84
+ index.dispose();
85
+ ```
86
+
87
+ ## API Reference
88
+
89
+ ### Constructor
90
+
91
+ Create a new FAISS index with the specified configuration.
92
+
93
+ ```javascript
94
+ const index = new FaissIndex(config);
95
+ ```
96
+
97
+ **Parameters:**
98
+ - `config.type` (string, required): Index type - `'FLAT_L2'`, `'IVF_FLAT'`, or `'HNSW'`
99
+ - `config.dims` (number, required): Vector dimensions (must be positive integer)
100
+ - `config.nlist` (number, optional): Number of clusters for IVF_FLAT (default: 100)
101
+ - `config.nprobe` (number, optional): Clusters to search for IVF_FLAT (default: 10)
102
+ - `config.M` (number, optional): Connections per node for HNSW (default: 16)
103
+ - `config.efConstruction` (number, optional): HNSW construction parameter (default: 200)
104
+ - `config.efSearch` (number, optional): HNSW search parameter (default: 50)
105
+
106
+ **Examples:**
107
+
108
+ ```javascript
109
+ // FLAT_L2 - Exact search (best for small datasets < 10k vectors)
110
+ const flatIndex = new FaissIndex({ type: 'FLAT_L2', dims: 128 });
111
+
112
+ // IVF_FLAT - Fast approximate search (best for 10k - 1M vectors)
113
+ const ivfIndex = new FaissIndex({
114
+ type: 'IVF_FLAT',
115
+ dims: 768,
116
+ nlist: 100, // Number of clusters
117
+ nprobe: 10 // Clusters to search (higher = more accurate, slower)
118
+ });
119
+ await ivfIndex.train(trainingVectors); // Must train before adding vectors!
120
+
121
+ // HNSW - State-of-the-art approximate search (best for large datasets)
122
+ const hnswIndex = new FaissIndex({
123
+ type: 'HNSW',
124
+ dims: 1536,
125
+ M: 16, // Connections per node (higher = more accurate, slower)
126
+ efConstruction: 200, // Construction parameter
127
+ efSearch: 50 // Search parameter (higher = more accurate, slower)
128
+ });
129
+ ```
130
+
131
+ ### Methods
132
+
133
+ #### `add(vectors: Float32Array): Promise<void>`
134
+
135
+ Add vectors to the index. Can add a single vector or a batch of vectors.
136
+
137
+ ```javascript
138
+ // Single vector
139
+ await index.add(new Float32Array([1, 2, 3, 4]));
140
+
141
+ // Batch of vectors (4 vectors of 4 dimensions each)
142
+ await index.add(new Float32Array([
143
+ 1, 0, 0, 0, // Vector 1
144
+ 0, 1, 0, 0, // Vector 2
145
+ 0, 0, 1, 0, // Vector 3
146
+ 0, 0, 0, 1 // Vector 4
147
+ ]));
148
+ ```
149
+
150
+ **Note:** For IVF_FLAT indexes, you must call `train()` before adding vectors.
151
+
152
+ #### `search(query: Float32Array, k: number): Promise<SearchResults>`
153
+
154
+ Search for k nearest neighbors.
155
+
156
+ ```javascript
157
+ const query = new Float32Array([1, 0, 0, 0]);
158
+ const results = await index.search(query, 5);
159
+
160
+ // results.distances: Float32Array of L2 distances
161
+ // results.labels: Int32Array of vector indices
162
+ ```
163
+
164
+ **Returns:**
165
+ - `distances` (Float32Array): L2 distances to nearest neighbors
166
+ - `labels` (Int32Array): Indices of nearest neighbors
167
+
168
+ #### `searchBatch(queries: Float32Array, k: number): Promise<SearchResults>`
169
+
170
+ Perform batch search for multiple queries efficiently.
171
+
172
+ ```javascript
173
+ // 3 queries of 4 dimensions each
174
+ const queries = new Float32Array([
175
+ 1, 0, 0, 0, // Query 1
176
+ 0, 1, 0, 0, // Query 2
177
+ 0, 0, 1, 0 // Query 3
178
+ ]);
179
+ const results = await index.searchBatch(queries, 5);
180
+
181
+ // results.distances: Float32Array of shape [3 * 5]
182
+ // results.labels: Int32Array of shape [3 * 5]
183
+ ```
184
+
185
+ #### `train(vectors: Float32Array): Promise<void>`
186
+
187
+ Train an IVF_FLAT index. Required before adding vectors.
188
+
189
+ ```javascript
190
+ // Training vectors (typically 10k-100k vectors)
191
+ const trainingVectors = new Float32Array(/* ... */);
192
+ await ivfIndex.train(trainingVectors);
193
+ await ivfIndex.add(dataVectors); // Now you can add vectors
194
+ ```
195
+
196
+ #### `setNprobe(nprobe: number): Promise<void>`
197
+
198
+ Set the number of clusters to search for IVF_FLAT indexes.
199
+
200
+ ```javascript
201
+ await ivfIndex.setNprobe(20); // Search more clusters (more accurate, slower)
202
+ ```
203
+
204
+ #### `getStats(): IndexStats`
205
+
206
+ Get index statistics.
207
+
208
+ ```javascript
209
+ const stats = index.getStats();
210
+ // {
211
+ // ntotal: number, // Total vectors in index
212
+ // dims: number, // Vector dimensions
213
+ // isTrained: boolean, // Whether index is trained (IVF only)
214
+ // type: string // Index type
215
+ // }
216
+ ```
217
+
218
+ #### `save(filename: string): Promise<void>`
219
+
220
+ Save index to disk.
221
+
222
+ ```javascript
223
+ await index.save('./my-index.faiss');
224
+ ```
225
+
226
+ #### `static load(filename: string): Promise<FaissIndex>`
227
+
228
+ Load index from disk.
229
+
230
+ ```javascript
231
+ const index = await FaissIndex.load('./my-index.faiss');
232
+ ```
233
+
234
+ #### `toBuffer(): Promise<Buffer>`
235
+
236
+ Serialize index to a Node.js Buffer (useful for databases, network transfer, etc.).
237
+
238
+ ```javascript
239
+ const buffer = await index.toBuffer();
240
+ // Store in database, send over network, etc.
241
+ ```
242
+
243
+ #### `static fromBuffer(buffer: Buffer): Promise<FaissIndex>`
244
+
245
+ Deserialize index from Buffer.
246
+
247
+ ```javascript
248
+ const index = await FaissIndex.fromBuffer(buffer);
249
+ ```
250
+
251
+ #### `mergeFrom(otherIndex: FaissIndex): Promise<void>`
252
+
253
+ Merge vectors from another index into this index.
254
+
255
+ ```javascript
256
+ const index1 = new FaissIndex({ type: 'FLAT_L2', dims: 128 });
257
+ const index2 = new FaissIndex({ type: 'FLAT_L2', dims: 128 });
258
+
259
+ await index1.add(vectors1);
260
+ await index2.add(vectors2);
261
+
262
+ await index1.mergeFrom(index2); // index1 now contains vectors from both
263
+ // Note: index2 is now empty (FAISS behavior)
264
+ ```
265
+
266
+ #### `dispose(): void`
267
+
268
+ Explicitly dispose of the index and free resources. Optional - automatic on garbage collection.
269
+
270
+ ```javascript
271
+ index.dispose();
272
+ // Index is now unusable - all operations will throw errors
273
+ ```
274
+
275
+ ## Choosing the Right Index Type
276
+
277
+ ### FLAT_L2 (IndexFlatL2)
278
+ - **Best for:** Small datasets (< 10k vectors), exact search required
279
+ - **Speed:** O(n) per query - linear scan
280
+ - **Accuracy:** 100% recall (exact results)
281
+ - **Memory:** 4 ร— dims ร— n bytes
282
+ - **Use case:** Prototyping, small production datasets, when accuracy is critical
283
+
284
+ ### IVF_FLAT (IndexIVFFlat)
285
+ - **Best for:** Medium datasets (10k - 1M vectors), can tolerate ~90-95% recall
286
+ - **Speed:** O(nprobe ร— n/nlist) per query - much faster than FLAT
287
+ - **Accuracy:** ~90-95% recall (configurable via nprobe)
288
+ - **Memory:** Similar to FLAT + cluster overhead
289
+ - **Requires:** Training on sample data before use
290
+ - **Use case:** Production systems with medium-sized datasets
291
+
292
+ ### HNSW (IndexHNSW)
293
+ - **Best for:** Large datasets (> 100k vectors), best speed/accuracy tradeoff
294
+ - **Speed:** O(log n) per query - logarithmic search
295
+ - **Accuracy:** ~95-99% recall (configurable via efSearch)
296
+ - **Memory:** ~1.5-2ร— more than FLAT
297
+ - **No training required**
298
+ - **Use case:** Large-scale production systems, best overall performance
299
+
300
+ ## Examples
301
+
302
+ ### Basic Semantic Search
303
+
304
+ ```javascript
305
+ const { FaissIndex } = require('@faiss-node/native');
306
+
307
+ // Create index for 768-dimensional embeddings (e.g., OpenAI)
308
+ const index = new FaissIndex({ type: 'HNSW', dims: 768 });
309
+
310
+ // Add document embeddings
311
+ const documents = [
312
+ { id: 0, text: "JavaScript is a programming language" },
313
+ { id: 1, text: "Python is great for data science" },
314
+ { id: 2, text: "Node.js runs JavaScript on the server" }
315
+ ];
316
+
317
+ const embeddings = new Float32Array(/* ... your embeddings ... */);
318
+ await index.add(embeddings);
319
+
320
+ // Search for similar documents
321
+ const queryEmbedding = new Float32Array(/* ... query embedding ... */);
322
+ const results = await index.search(queryEmbedding, 3);
323
+
324
+ console.log('Most similar documents:', results.labels);
325
+ ```
326
+
327
+ ### RAG Pipeline
328
+
329
+ ```javascript
330
+ const { FaissIndex } = require('@faiss-node/native');
331
+
332
+ class RAGSystem {
333
+ constructor() {
334
+ this.index = new FaissIndex({ type: 'HNSW', dims: 1536 });
335
+ this.documents = [];
336
+ }
337
+
338
+ async addDocuments(docs, embeddings) {
339
+ this.documents.push(...docs);
340
+ await this.index.add(embeddings);
341
+ }
342
+
343
+ async search(queryEmbedding, k = 5) {
344
+ const results = await this.index.search(queryEmbedding, k);
345
+ return results.labels.map(idx => this.documents[idx]);
346
+ }
347
+
348
+ async save(path) {
349
+ await this.index.save(path);
350
+ // Also save documents mapping
351
+ }
352
+ }
353
+ ```
354
+
355
+ ### Persistence
356
+
357
+ ```javascript
358
+ const { FaissIndex } = require('@faiss-node/native');
359
+
360
+ // Save to disk
361
+ const index = new FaissIndex({ type: 'HNSW', dims: 128 });
362
+ await index.add(vectors);
363
+ await index.save('./index.faiss');
364
+
365
+ // Load from disk
366
+ const loadedIndex = await FaissIndex.load('./index.faiss');
367
+
368
+ // Or serialize to buffer (for databases)
369
+ const buffer = await index.toBuffer();
370
+ // Store in MongoDB, Redis, etc.
371
+ const restoredIndex = await FaissIndex.fromBuffer(buffer);
372
+ ```
373
+
374
+ ## Performance Tips
375
+
376
+ 1. **Use HNSW for large datasets** - Best overall performance
377
+ 2. **Batch operations** - Use `searchBatch()` for multiple queries
378
+ 3. **Train IVF properly** - Use 10k-100k training vectors
379
+ 4. **Tune parameters** - Increase `nprobe` (IVF) or `efSearch` (HNSW) for accuracy
380
+ 5. **Reuse indexes** - Save/load instead of recreating
381
+
382
+ ## Thread Safety
383
+
384
+ All operations are thread-safe and can be called concurrently:
385
+
386
+ ```javascript
387
+ // Safe to call from multiple async operations
388
+ await Promise.all([
389
+ index.add(vectors1),
390
+ index.add(vectors2),
391
+ index.search(query1),
392
+ index.search(query2)
393
+ ]);
394
+ ```
395
+
396
+ The implementation uses mutex locks to ensure FAISS operations are serialized safely.
397
+
398
+ ## Error Handling
399
+
400
+ All methods throw JavaScript errors (not C++ exceptions):
401
+
402
+ ```javascript
403
+ try {
404
+ await index.add(vectors);
405
+ } catch (error) {
406
+ if (error.message.includes('disposed')) {
407
+ console.error('Index was disposed');
408
+ } else if (error.message.includes('dimensions')) {
409
+ console.error('Vector dimensions mismatch');
410
+ }
411
+ }
412
+ ```
413
+
414
+ ## TypeScript Support
415
+
416
+ Full TypeScript definitions are included:
417
+
418
+ ```typescript
419
+ import { FaissIndex, FaissIndexConfig, SearchResults } from '@faiss-node/native';
420
+
421
+ const config: FaissIndexConfig = {
422
+ type: 'HNSW',
423
+ dims: 768
424
+ };
425
+
426
+ const index = new FaissIndex(config);
427
+ const results: SearchResults = await index.search(query, 10);
428
+ ```
429
+
430
+ ## Updating
431
+
432
+ To update to the latest version:
433
+
434
+ ```bash
435
+ npm update @faiss-node/native
436
+ ```
437
+
438
+ Or install a specific version:
439
+
440
+ ```bash
441
+ npm install @faiss-node/native@0.1.2
442
+ ```
443
+
444
+ ## Development
445
+
446
+ ### Building from Source
447
+
448
+ ```bash
449
+ # Clone repository
450
+ git clone https://github.com/anupammaurya6767/faiss-node-native.git
451
+ cd faiss-node-native
452
+
453
+ # Install dependencies
454
+ npm install
455
+
456
+ # Build native module
457
+ npm run build
458
+
459
+ # Run tests
460
+ npm test
461
+ ```
462
+
463
+ ### Running Tests
464
+
465
+ ```bash
466
+ npm test # All tests
467
+ npm run test:unit # Unit tests only
468
+ npm run test:integration # Integration tests only
469
+ npm run test:ci # CI tests (faster, no manual tests)
470
+ ```
471
+
472
+ ### Generating Documentation
473
+
474
+ ```bash
475
+ npm run docs # Generate Doxygen documentation
476
+ npm run docs:serve # Serve docs locally at http://localhost:8000
477
+ ```
478
+
479
+ ## Documentation
480
+
481
+ - **API Documentation**: [GitHub Pages](https://anupammaurya6767.github.io/faiss-node-native/)
482
+ - **Examples**: See `examples/` directory
483
+ - **Contributing**: See [CONTRIBUTING.md](./CONTRIBUTING.md)
484
+
485
+ ## Comparison with Other Packages
486
+
487
+ ### vs. `faiss-node` (ewfian)
488
+
489
+ | Feature | @faiss-node/native | faiss-node |
490
+ |---------|-------------------|------------|
491
+ | Async Operations | โœ… Promise-based | โŒ Synchronous (blocks event loop) |
492
+ | Thread Safety | โœ… Mutex-protected | โŒ Not thread-safe |
493
+ | API Design | โœ… High-level wrapper | โš ๏ธ Low-level FAISS classes |
494
+ | TypeScript | โœ… Full support | โš ๏ธ Partial |
495
+ | Testing | โœ… 1000+ tests | โš ๏ธ Minimal |
496
+ | Production Ready | โœ… Yes | โš ๏ธ Early stage |
497
+
498
+ ## Troubleshooting
499
+
500
+ ### Build Errors
501
+
502
+ **macOS: "library not found"**
503
+ ```bash
504
+ # Ensure FAISS is installed
505
+ brew install faiss
506
+
507
+ # Check installation
508
+ ls /usr/local/lib/libfaiss*
509
+ ```
510
+
511
+ **Linux: "faiss/Index.h: No such file or directory"**
512
+ ```bash
513
+ # Build and install FAISS from source (see Prerequisites)
514
+ # Ensure CMAKE_INSTALL_PREFIX=/usr/local
515
+ ```
516
+
517
+ ### Runtime Errors
518
+
519
+ **"Index has been disposed"**
520
+ - You called `dispose()` or the index was garbage collected
521
+ - Create a new index or don't dispose until done
522
+
523
+ **"Vector dimensions don't match"**
524
+ - Check that your vectors are the correct size
525
+ - For batch operations: `vectors.length % dims === 0`
526
+
527
+ ## Contributing
528
+
529
+ Contributions are welcome! Please see [CONTRIBUTING.md](./CONTRIBUTING.md) for guidelines.
530
+
531
+ ## License
532
+
533
+ MIT License - see [LICENSE](./LICENSE) file for details.
534
+
535
+ ## Author
536
+
537
+ **Anupam Maurya**
538
+
539
+ - GitHub: [@anupammaurya6767](https://github.com/anupammaurya6767)
540
+ - Email: anupammaurya6767@gmail.com
541
+
542
+ ## Acknowledgments
543
+
544
+ - Built on [Facebook FAISS](https://github.com/facebookresearch/faiss) - the amazing vector similarity search library
545
+ - Inspired by the need for high-performance vector search in Node.js
546
+ - Thanks to the open-source community for feedback and contributions
547
+
548
+ ---
549
+
550
+ Made with โค๏ธ for the Node.js community
551
+
package/binding.gyp ADDED
@@ -0,0 +1,90 @@
1
+ {
2
+ "targets": [
3
+ {
4
+ "target_name": "faiss_node",
5
+ "cflags!": [ "-fno-exceptions" ],
6
+ "cflags_cc!": [ "-fno-exceptions" ],
7
+ "sources": [
8
+ "src/cpp/faiss_index.cpp",
9
+ "src/cpp/napi_bindings.cpp"
10
+ ],
11
+ "include_dirs": [
12
+ "<!@(node -p \"require('node-addon-api').include\")",
13
+ "src/cpp",
14
+ "/opt/homebrew/include",
15
+ "/usr/local/include",
16
+ "/usr/include"
17
+ ],
18
+ "defines": [
19
+ "NAPI_VERSION=8"
20
+ ],
21
+ "conditions": [
22
+ ["OS=='mac'", {
23
+ "xcode_settings": {
24
+ "GCC_ENABLE_CPP_EXCEPTIONS": "YES",
25
+ "CLANG_CXX_LIBRARY": "libc++",
26
+ "MACOSX_DEPLOYMENT_TARGET": "11.0",
27
+ "OTHER_CPLUSPLUSFLAGS": [
28
+ "-std=c++17",
29
+ "-fexceptions",
30
+ "-frtti"
31
+ ],
32
+ "OTHER_LDFLAGS": [
33
+ "-headerpad_max_install_names"
34
+ ]
35
+ },
36
+ "libraries": [
37
+ "-L/opt/homebrew/lib",
38
+ "-L/usr/local/lib",
39
+ "-L/opt/homebrew/opt/libomp/lib",
40
+ "-L/usr/local/opt/libomp/lib",
41
+ "-L/opt/homebrew/Cellar/openblas/0.3.30/lib",
42
+ "-lfaiss",
43
+ "-lopenblas",
44
+ "-lomp"
45
+ ],
46
+ "ldflags": [
47
+ "-L/opt/homebrew/lib",
48
+ "-L/usr/local/lib",
49
+ "-L/opt/homebrew/opt/libomp/lib",
50
+ "-L/usr/local/opt/libomp/lib",
51
+ "-L/opt/homebrew/Cellar/openblas/0.3.30/lib",
52
+ "-headerpad_max_install_names"
53
+ ]
54
+ }],
55
+ ["OS=='linux'", {
56
+ "include_dirs": [
57
+ "<!@(node -p \"require('node-addon-api').include\")",
58
+ "src/cpp",
59
+ "/usr/local/include",
60
+ "/usr/include"
61
+ ],
62
+ "libraries": [
63
+ "-L/usr/local/lib",
64
+ "-L/usr/lib",
65
+ "-lfaiss",
66
+ "-lopenblas",
67
+ "-lgomp"
68
+ ],
69
+ "ldflags": [
70
+ "-L/usr/local/lib",
71
+ "-L/usr/lib",
72
+ "-Wl,-rpath,/usr/local/lib:/usr/lib/x86_64-linux-gnu"
73
+ ],
74
+ "cflags_cc": [
75
+ "-std=c++17",
76
+ "-fexceptions",
77
+ "-frtti",
78
+ "-fopenmp",
79
+ "-I/usr/local/include"
80
+ ]
81
+ }]
82
+ ],
83
+ "cflags_cc": [
84
+ "-std=c++17",
85
+ "-fexceptions",
86
+ "-frtti"
87
+ ]
88
+ }
89
+ ]
90
+ }
package/docs/README.md ADDED
@@ -0,0 +1,31 @@
1
+ # Documentation
2
+
3
+ This directory contains the auto-generated API documentation that I set up using Doxygen.
4
+
5
+ ## Viewing Documentation
6
+
7
+ - **Online**: Visit [GitHub Pages](https://anupammaurya6767.github.io/faiss-node-native/) (automatically deployed)
8
+ - **Local**: Run `npm run docs:serve` and visit http://localhost:8000
9
+
10
+ ## Generating Documentation
11
+
12
+ ```bash
13
+ npm run docs
14
+ ```
15
+
16
+ This generates HTML documentation in `docs/html/` using Doxygen.
17
+
18
+ ## Documentation Structure
19
+
20
+ - **C++ API**: Native bindings and FAISS wrapper classes
21
+ - **JavaScript API**: High-level FaissIndex class
22
+ - **Examples**: Code examples from `examples/` directory
23
+
24
+ ## Auto-Deployment
25
+
26
+ I've set it up so documentation automatically deploys to GitHub Pages when:
27
+ - Code is pushed to `main` branch
28
+ - Source files (`src/**`) or `Doxyfile` are modified
29
+ - I manually trigger it via workflow_dispatch
30
+
31
+ See `.github/workflows/docs.yml` for the deployment workflow I created.