native-vector-store 0.1.0 → 0.3.0

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.
Files changed (53) hide show
  1. package/README.md +242 -12
  2. package/binding.gyp +22 -10
  3. package/deps/simdjson/simdjson.cpp +56403 -0
  4. package/deps/simdjson/simdjson.h +123534 -0
  5. package/docs/PERFORMANCE_CASE_STUDY.md +130 -0
  6. package/docs/PREBUILDS.md +69 -0
  7. package/docs/VectorStore.html +180 -0
  8. package/docs/VectorStoreWrapper.html +1356 -0
  9. package/docs/fonts/OpenSans-Bold-webfont.eot +0 -0
  10. package/docs/fonts/OpenSans-Bold-webfont.svg +1830 -0
  11. package/docs/fonts/OpenSans-Bold-webfont.woff +0 -0
  12. package/docs/fonts/OpenSans-BoldItalic-webfont.eot +0 -0
  13. package/docs/fonts/OpenSans-BoldItalic-webfont.svg +1830 -0
  14. package/docs/fonts/OpenSans-BoldItalic-webfont.woff +0 -0
  15. package/docs/fonts/OpenSans-Italic-webfont.eot +0 -0
  16. package/docs/fonts/OpenSans-Italic-webfont.svg +1830 -0
  17. package/docs/fonts/OpenSans-Italic-webfont.woff +0 -0
  18. package/docs/fonts/OpenSans-Light-webfont.eot +0 -0
  19. package/docs/fonts/OpenSans-Light-webfont.svg +1831 -0
  20. package/docs/fonts/OpenSans-Light-webfont.woff +0 -0
  21. package/docs/fonts/OpenSans-LightItalic-webfont.eot +0 -0
  22. package/docs/fonts/OpenSans-LightItalic-webfont.svg +1835 -0
  23. package/docs/fonts/OpenSans-LightItalic-webfont.woff +0 -0
  24. package/docs/fonts/OpenSans-Regular-webfont.eot +0 -0
  25. package/docs/fonts/OpenSans-Regular-webfont.svg +1831 -0
  26. package/docs/fonts/OpenSans-Regular-webfont.woff +0 -0
  27. package/docs/global.html +561 -0
  28. package/docs/index.html +570 -0
  29. package/docs/scripts/linenumber.js +25 -0
  30. package/docs/scripts/prettify/Apache-License-2.0.txt +202 -0
  31. package/docs/scripts/prettify/lang-css.js +2 -0
  32. package/docs/scripts/prettify/prettify.js +28 -0
  33. package/docs/styles/jsdoc-default.css +358 -0
  34. package/docs/styles/prettify-jsdoc.css +111 -0
  35. package/docs/styles/prettify-tomorrow.css +132 -0
  36. package/index.js +162 -0
  37. package/package.json +30 -7
  38. package/prebuilds/darwin-arm64/native-vector-store.node +0 -0
  39. package/prebuilds/darwin-x64/native-vector-store.node +0 -0
  40. package/prebuilds/linux-arm64/native-vector-store.node +0 -0
  41. package/prebuilds/linux-x64/native-vector-store.node +0 -0
  42. package/prebuilds/linux-x64-musl/napi-v9/native-vector-store.node +0 -0
  43. package/prebuilds/linux-x64-musl/native-vector-store.node +0 -0
  44. package/prebuilds/win32-x64/native-vector-store.node +0 -0
  45. package/src/Makefile +87 -0
  46. package/src/test_main.cpp +173 -0
  47. package/src/test_stress.cpp +394 -0
  48. package/src/vector_store.cpp +344 -0
  49. package/src/vector_store.h +21 -323
  50. package/native-vector-store-0.1.0.tgz +0 -0
  51. package/scripts/build-prebuilds.sh +0 -23
  52. /package/{src → deps/atomic_queue}/atomic_queue.h +0 -0
  53. /package/{src → deps/atomic_queue}/defs.h +0 -0
package/README.md CHANGED
@@ -2,6 +2,17 @@
2
2
 
3
3
  High-performance vector store with SIMD optimization for MCP servers and local RAG applications.
4
4
 
5
+ ## Design Philosophy
6
+
7
+ This vector store is designed for **immutable, one-time loading** scenarios common in modern cloud deployments:
8
+
9
+ - **📚 Load Once, Query Many**: Documents are loaded at startup and remain immutable during serving
10
+ - **🚀 Optimized for Cold Starts**: Perfect for serverless functions and containerized deployments
11
+ - **📁 File-Based Organization**: Leverages filesystem for natural document organization and versioning
12
+ - **🎯 Focused API**: Does one thing exceptionally well - fast similarity search over focused corpora (sweet spot: <100k documents)
13
+
14
+ This design eliminates complex state management, ensures consistent performance, and aligns perfectly with cloud-native deployment patterns where domain-specific knowledge bases are the norm.
15
+
5
16
  ## Features
6
17
 
7
18
  - **🚀 High Performance**: C++ implementation with OpenMP SIMD optimization
@@ -17,7 +28,7 @@ High-performance vector store with SIMD optimization for MCP servers and local R
17
28
  - **Load Time**: <1 second for 100,000 documents (achieved: ~560ms)
18
29
  - **Search Latency**: <10ms for top-k similarity search (achieved: 1-2ms)
19
30
  - **Memory Efficiency**: Minimal fragmentation via arena allocation
20
- - **Scalability**: Designed for <1M embeddings
31
+ - **Scalability**: Designed for focused corpora (<100k documents optimal, <1M maximum)
21
32
  - **Throughput**: 178k+ documents per second with parallel loading
22
33
 
23
34
  ## Installation
@@ -28,15 +39,22 @@ npm install native-vector-store
28
39
 
29
40
  ### Prerequisites
30
41
 
31
- For most users, **no prerequisites are needed** - prebuilt binaries are included for:
32
- - Linux (x64, arm64)
42
+ **Runtime Requirements:**
43
+ - OpenMP runtime library (for parallel processing)
44
+ - **Linux**: `sudo apt-get install libgomp1` (Ubuntu/Debian) or `dnf install libgomp` (Fedora)
45
+ - **Alpine**: `apk add libgomp`
46
+ - **macOS**: `brew install libomp`
47
+ - **Windows**: Included with Visual C++ runtime
48
+
49
+ Prebuilt binaries are included for:
50
+ - Linux (x64, arm64, musl/Alpine)
33
51
  - macOS (x64, arm64/Apple Silicon)
34
52
  - Windows (x64)
35
53
 
36
54
  If building from source, you'll need:
37
55
  - Node.js ≥14.0.0
38
56
  - C++ compiler with OpenMP support
39
- - simdjson library (automatically handled by node-gyp)
57
+ - simdjson library (vendored, no installation needed)
40
58
 
41
59
  ## Quick Start
42
60
 
@@ -69,6 +87,164 @@ const results = store.search(queryEmbedding, 5); // Top 5 results
69
87
  console.log(results[0]); // { score: 0.95, id: 'doc-1', text: '...', metadata_json: '...' }
70
88
  ```
71
89
 
90
+ ## Usage Patterns
91
+
92
+ ### Serverless Deployment (AWS Lambda, Vercel)
93
+
94
+ ```javascript
95
+ // Initialize once during cold start
96
+ let store;
97
+
98
+ async function initializeStore() {
99
+ if (!store) {
100
+ store = new VectorStore(1536);
101
+ store.loadDir('./knowledge-base'); // Loads and finalizes
102
+ }
103
+ return store;
104
+ }
105
+
106
+ // Handler reuses the store across invocations
107
+ export async function handler(event) {
108
+ const store = await initializeStore();
109
+ const embedding = new Float32Array(event.embedding);
110
+ return store.search(embedding, 10);
111
+ }
112
+ ```
113
+
114
+ ### Local MCP Server
115
+
116
+ ```javascript
117
+ const { VectorStore } = require('native-vector-store');
118
+
119
+ // Load different knowledge domains at startup
120
+ const stores = {
121
+ products: new VectorStore(1536),
122
+ support: new VectorStore(1536),
123
+ general: new VectorStore(1536)
124
+ };
125
+
126
+ stores.products.loadDir('./knowledge/products');
127
+ stores.support.loadDir('./knowledge/support');
128
+ stores.general.loadDir('./knowledge/general');
129
+
130
+ // Route searches to appropriate domain
131
+ server.on('search', (query) => {
132
+ const store = stores[query.domain] || stores.general;
133
+ const results = store.search(query.embedding, 5);
134
+ return results.filter(r => r.score > 0.7);
135
+ });
136
+ ```
137
+
138
+ ### CLI Tool with Persistent Context
139
+
140
+ ```javascript
141
+ #!/usr/bin/env node
142
+ const { VectorStore } = require('native-vector-store');
143
+
144
+ // Load knowledge base once
145
+ const store = new VectorStore(1536);
146
+ store.loadDir(process.env.KNOWLEDGE_PATH || './docs');
147
+
148
+ // Interactive REPL with fast responses
149
+ const repl = require('repl');
150
+ const r = repl.start('> ');
151
+ r.context.search = (embedding, k = 5) => store.search(embedding, k);
152
+ ```
153
+
154
+ ### File Organization Best Practices
155
+
156
+ Structure your documents by category for separate vector stores:
157
+
158
+ ```
159
+ knowledge-base/
160
+ ├── products/ # Product documentation
161
+ │ ├── api-reference.json
162
+ │ └── user-guide.json
163
+ ├── support/ # Support articles
164
+ │ ├── faq.json
165
+ │ └── troubleshooting.json
166
+ └── context/ # Context-specific docs
167
+ ├── company-info.json
168
+ └── policies.json
169
+ ```
170
+
171
+ Load each category into its own VectorStore:
172
+
173
+ ```javascript
174
+ // Create separate stores for different domains
175
+ const productStore = new VectorStore(1536);
176
+ const supportStore = new VectorStore(1536);
177
+ const contextStore = new VectorStore(1536);
178
+
179
+ // Load each category independently
180
+ productStore.loadDir('./knowledge-base/products');
181
+ supportStore.loadDir('./knowledge-base/support');
182
+ contextStore.loadDir('./knowledge-base/context');
183
+
184
+ // Search specific domains
185
+ const productResults = productStore.search(queryEmbedding, 5);
186
+ const supportResults = supportStore.search(queryEmbedding, 5);
187
+ ```
188
+
189
+ Each JSON file contains self-contained documents with embeddings:
190
+
191
+ ```json
192
+ {
193
+ "id": "unique-id",
194
+ "text": "Document content...",
195
+ "metadata": {
196
+ "embedding": [0.1, 0.2, ...],
197
+ "category": "product",
198
+ "lastUpdated": "2024-01-01"
199
+ }
200
+ }
201
+ ```
202
+
203
+ ### Deployment Strategies
204
+
205
+ #### Blue-Green Deployment
206
+
207
+ ```javascript
208
+ // Load new version without downtime
209
+ const newStore = new VectorStore(1536);
210
+ newStore.loadDir('./knowledge-base-v2');
211
+
212
+ // Atomic switch
213
+ app.locals.store = newStore;
214
+ ```
215
+
216
+ #### Versioned Directories
217
+
218
+ ```
219
+ deployments/
220
+ ├── v1.0.0/
221
+ │ └── documents/
222
+ ├── v1.1.0/
223
+ │ └── documents/
224
+ └── current -> v1.1.0 # Symlink to active version
225
+ ```
226
+
227
+ #### Watch for Updates (Development)
228
+
229
+ ```javascript
230
+ const fs = require('fs');
231
+
232
+ function reloadStore() {
233
+ const newStore = new VectorStore(1536);
234
+ newStore.loadDir('./documents');
235
+ global.store = newStore;
236
+ console.log(`Reloaded ${newStore.size()} documents`);
237
+ }
238
+
239
+ // Initial load
240
+ reloadStore();
241
+
242
+ // Watch for changes in development
243
+ if (process.env.NODE_ENV === 'development') {
244
+ fs.watch('./documents', { recursive: true }, reloadStore);
245
+ }
246
+ ```
247
+
72
248
  ## MCP Server Integration
73
249
 
74
250
  Perfect for building local RAG capabilities in MCP servers:
@@ -141,6 +317,60 @@ Check if the store has been finalized and is ready for searching.
141
317
  ##### `size(): number`
142
318
  Get the number of documents in the store.
143
319
 
320
+ ## Performance
321
+
322
+ ### Why It's Fast
323
+
324
+ The native-vector-store achieves exceptional performance through:
325
+
326
+ 1. **Producer-Consumer Loading**: Parallel file I/O and JSON parsing achieve 178k+ documents/second
327
+ 2. **SIMD Optimizations**: OpenMP vectorization for dot product calculations
328
+ 3. **Arena Allocation**: Contiguous memory layout with 64MB chunks for cache efficiency
329
+ 4. **Zero-Copy Design**: String views and pre-allocated buffers minimize allocations
330
+ 5. **Two-Phase Architecture**: Loading phase allows concurrent writes, serving phase optimizes for reads
331
+
332
+ ### Benchmarks
333
+
334
+ Performance on typical hardware (M1 MacBook Pro):
335
+
336
+ | Operation | Documents | Time | Throughput |
337
+ |-----------|-----------|------|------------|
338
+ | Loading (from disk) | 100,000 | ~560ms | 178k docs/sec |
339
+ | Search (k=10) | 10,000 corpus | 1-2ms | 500-1000 queries/sec |
340
+ | Search (k=100) | 100,000 corpus | 8-12ms | 80-125 queries/sec |
341
+ | Normalization | 100,000 | <100ms | 1M+ docs/sec |
342
+
343
+ ### Performance Tips
344
+
345
+ 1. **Optimal File Organization**:
346
+ - Keep 1000-10000 documents per JSON file for best I/O performance
347
+ - Use arrays of documents in each file rather than one file per document
348
+
349
+ 2. **Memory Considerations**:
350
+ - Each document requires: `embedding_size * 4 bytes + metadata_size + text_size`
351
+ - 100k documents with 1536-dim embeddings ≈ 600MB embeddings + metadata
352
+
353
+ 3. **Search Performance**:
354
+ - Scales linearly with corpus size and k value
355
+ - Use smaller k values (5-20) for interactive applications
356
+ - Pre-normalize query embeddings if making multiple searches
357
+
358
+ 4. **Corpus Size Optimization**:
359
+ - Sweet spot: <100k documents for optimal load/search balance
360
+ - Beyond 100k: Consider if your use case truly needs all documents
361
+ - Focus on curated, domain-specific content rather than exhaustive datasets
362
+
363
+ ### Comparison with Alternatives
364
+
365
+ | Feature | native-vector-store | Faiss | ChromaDB | Pinecone |
366
+ |---------|-------------------|--------|----------|----------|
367
+ | Load 100k docs | <1s | 2-5s | 30-60s | N/A (API) |
368
+ | Search latency | 1-2ms | 0.5-1ms | 50-200ms | 50-300ms |
369
+ | Memory efficiency | High | Medium | Low | N/A |
370
+ | Dependencies | Minimal | Heavy | Heavy | None |
371
+ | Deployment | Simple | Complex | Complex | SaaS |
372
+ | Sweet spot | <100k docs | Any size | Any size | Any size |
373
+
144
374
  ## Building from Source
145
375
 
146
376
  ```bash
@@ -181,21 +411,21 @@ npm run example
181
411
 
182
412
  ### MCP Servers
183
413
  Ideal for building local RAG (Retrieval-Augmented Generation) capabilities:
184
- - Fast document loading from knowledge bases
414
+ - Fast document loading from focused knowledge bases
185
415
  - Low-latency similarity search for context retrieval
186
- - Memory-efficient storage for large document collections
416
+ - Memory-efficient storage for domain-specific corpora
187
417
 
188
418
  ### Knowledge Management
189
419
  Perfect for personal knowledge management systems:
190
- - Index personal documents and notes
191
- - Fast semantic search across content
420
+ - Index personal documents and notes (typically <10k documents)
421
+ - Fast semantic search across focused content
192
422
  - Offline operation without external dependencies
193
423
 
194
424
  ### Research Applications
195
- Suitable for academic and research projects:
196
- - Literature review and citation analysis
197
- - Semantic clustering of research papers
198
- - Cross-reference discovery in document collections
425
+ Suitable for academic and research projects with focused datasets:
426
+ - Literature review within specific domains
427
+ - Semantic clustering of curated paper collections
428
+ - Cross-reference discovery in specialized corpora
199
429
 
200
430
  ## Contributing
201
431
 
package/binding.gyp CHANGED
@@ -2,10 +2,12 @@
2
2
  "targets": [
3
3
  {
4
4
  "target_name": "vector_store",
5
- "sources": ["src/binding.cc", "src/vector_store_loader.cpp", "src/vector_store_loader_mmap.cpp", "src/vector_store_loader_adaptive.cpp"],
5
+ "sources": ["src/binding.cc", "src/vector_store.cpp", "src/vector_store_loader.cpp", "src/vector_store_loader_mmap.cpp", "src/vector_store_loader_adaptive.cpp", "deps/simdjson/simdjson.cpp"],
6
6
  "include_dirs": [
7
7
  "<!@(node -p \"require('node-addon-api').include\")",
8
- "src"
8
+ "src",
9
+ "deps/simdjson",
10
+ "deps/atomic_queue"
9
11
  ],
10
12
  "dependencies": ["<!(node -p \"require('node-addon-api').gyp\")"],
11
13
  "cflags_cc": [
@@ -17,27 +19,37 @@
17
19
  "defines": ["NAPI_DISABLE_CPP_EXCEPTIONS"],
18
20
  "conditions": [
19
21
  ["OS=='mac'", {
20
- "include_dirs": ["/opt/homebrew/opt/libomp/include", "/opt/homebrew/include"],
22
+ "include_dirs": [
23
+ "/opt/homebrew/opt/libomp/include",
24
+ "/usr/local/opt/libomp/include"
25
+ ],
21
26
  "xcode_settings": {
22
27
  "GCC_ENABLE_CPP_EXCEPTIONS": "NO",
23
28
  "OTHER_CFLAGS": ["-Xpreprocessor", "-fopenmp"],
24
- "OTHER_CPLUSPLUSFLAGS": ["-Xpreprocessor", "-fopenmp"],
25
- "OTHER_LDFLAGS": ["-L/opt/homebrew/opt/libomp/lib", "-lomp"]
29
+ "OTHER_CPLUSPLUSFLAGS": ["-Xpreprocessor", "-fopenmp", "-std=c++17"],
30
+ "OTHER_LDFLAGS": ["-lomp"],
31
+ "CLANG_CXX_LANGUAGE_STANDARD": "c++17"
26
32
  },
27
- "libraries": ["-L/opt/homebrew/opt/libomp/lib", "-lomp", "-L/opt/homebrew/lib", "-lsimdjson"]
33
+ "libraries": ["-lomp"],
34
+ "library_dirs": [
35
+ "/opt/homebrew/opt/libomp/lib",
36
+ "/usr/local/opt/libomp/lib"
37
+ ]
28
38
  }],
29
39
  ["OS=='linux'", {
30
40
  "cflags_cc": ["-fopenmp"],
31
- "libraries": ["-lgomp", "-lsimdjson"]
41
+ "libraries": ["-lgomp"]
32
42
  }],
33
43
  ["OS=='win'", {
34
44
  "msvs_settings": {
35
45
  "VCCLCompilerTool": {
36
46
  "ExceptionHandling": 0,
37
- "OpenMP": "true"
47
+ "OpenMP": "true",
48
+ "AdditionalOptions": [
49
+ "/openmp:experimental"
50
+ ]
38
51
  }
39
- },
40
- "libraries": ["simdjson.lib"]
52
+ }
41
53
  }]
42
54
  ]
43
55
  }