@ruvector/rvf-node 0.1.1 → 0.1.3

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 (2) hide show
  1. package/README.md +252 -33
  2. package/package.json +1 -1
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # @ruvector/rvf-node
2
2
 
3
- Node.js native bindings for the RuVector Format (RVF) cognitive container.
3
+ Native Node.js bindings for the [RuVector Format](https://github.com/ruvnet/ruvector/tree/main/crates/rvf) (RVF) vector database. Built with Rust via N-API for native speed with zero serialization overhead.
4
4
 
5
5
  ## Install
6
6
 
@@ -8,52 +8,271 @@ Node.js native bindings for the RuVector Format (RVF) cognitive container.
8
8
  npm install @ruvector/rvf-node
9
9
  ```
10
10
 
11
- ## Usage
11
+ ## Features
12
+
13
+ - **Native Rust performance** via N-API (napi-rs), no FFI marshaling
14
+ - **Single-file vector database** — crash-safe, no WAL, append-only
15
+ - **k-NN search** with HNSW progressive indexing (recall 0.70 → 0.95)
16
+ - **Metadata filtering** — Eq, Ne, Lt, Gt, Range, In, And, Or, Not
17
+ - **Lineage tracking** — DNA-style parent/child derivation chains
18
+ - **Kernel & eBPF embedding** — embed compute alongside vector data
19
+ - **Segment inspection** — enumerate all segments in the file
20
+ - **Cross-platform** — Linux (x86_64, aarch64), macOS (x86_64, Apple Silicon), Windows (x86_64)
21
+
22
+ ## Quick Start
12
23
 
13
24
  ```javascript
14
25
  const { RvfDatabase } = require('@ruvector/rvf-node');
15
26
 
16
- // Create a vector store
17
- const db = RvfDatabase.create('vectors.rvf', { dimension: 384 });
27
+ // Create a store
28
+ const db = RvfDatabase.create('vectors.rvf', {
29
+ dimension: 384,
30
+ metric: 'cosine',
31
+ });
18
32
 
19
33
  // Insert vectors
20
- db.ingestBatch(new Float32Array(384), [1]);
34
+ const vectors = new Float32Array(384 * 2); // 2 vectors, 384 dims each
35
+ vectors.fill(0.1);
36
+ db.ingestBatch(vectors, [1, 2]);
21
37
 
22
38
  // Query nearest neighbors
23
- const results = db.query(new Float32Array(384), 10);
24
- console.log(results); // [{ id, distance }]
39
+ const query = new Float32Array(384);
40
+ query.fill(0.15);
41
+ const results = db.query(query, 5);
42
+ // [{ id: 1, distance: 0.002 }, { id: 2, distance: 0.002 }]
43
+
44
+ db.close();
45
+ ```
46
+
47
+ ## API Reference
48
+
49
+ ### Store Lifecycle
50
+
51
+ ```typescript
52
+ // Create a new store
53
+ const db = RvfDatabase.create(path: string, options: RvfOptions);
25
54
 
26
- // Inspect segments
27
- console.log(db.fileId()); // unique file UUID
28
- console.log(db.dimension()); // 384
29
- console.log(db.segments()); // [{ type, id, size }]
55
+ // Open existing store (read-write, acquires writer lock)
56
+ const db = RvfDatabase.open(path: string);
30
57
 
58
+ // Open read-only (no lock, concurrent readers allowed)
59
+ const db = RvfDatabase.openReadonly(path: string);
60
+
61
+ // Close and flush
31
62
  db.close();
32
63
  ```
33
64
 
34
- ## Features
65
+ **RvfOptions:**
66
+
67
+ | Field | Type | Default | Description |
68
+ |-------|------|---------|-------------|
69
+ | `dimension` | `number` | required | Vector dimensionality |
70
+ | `metric` | `string` | `"l2"` | `"l2"`, `"cosine"`, or `"inner_product"` |
71
+ | `profile` | `number` | `0` | Hardware profile: 0=Generic, 1=Core, 2=Hot, 3=Full |
72
+ | `signing` | `boolean` | `false` | Enable segment signing |
73
+ | `m` | `number` | `16` | HNSW M parameter (neighbor count) |
74
+ | `efConstruction` | `number` | `200` | HNSW index build quality |
75
+
76
+ ### Ingest Vectors
77
+
78
+ ```typescript
79
+ const result = db.ingestBatch(
80
+ vectors: Float32Array, // flat array of n * dimension floats
81
+ ids: number[], // vector IDs
82
+ metadata?: RvfMetadataEntry[] // optional metadata per vector
83
+ );
84
+ // Returns: { accepted: number, rejected: number, epoch: number }
85
+ ```
86
+
87
+ **Metadata entry format:**
88
+
89
+ ```typescript
90
+ { fieldId: 0, valueType: 'string', value: 'category_a' }
91
+ { fieldId: 1, valueType: 'f64', value: '0.95' }
92
+ { fieldId: 2, valueType: 'u64', value: '42' }
93
+ ```
94
+
95
+ ### Query
96
+
97
+ ```typescript
98
+ const results = db.query(
99
+ vector: Float32Array, // query vector
100
+ k: number, // number of neighbors
101
+ options?: RvfQueryOptions // optional search parameters
102
+ );
103
+ // Returns: [{ id: number, distance: number }, ...]
104
+ ```
105
+
106
+ **RvfQueryOptions:**
107
+
108
+ | Field | Type | Default | Description |
109
+ |-------|------|---------|-------------|
110
+ | `efSearch` | `number` | `100` | HNSW search quality (higher = better recall, slower) |
111
+ | `filter` | `string` | — | Filter expression as JSON string |
112
+ | `timeoutMs` | `number` | `0` | Query timeout in ms (0 = no timeout) |
113
+
114
+ ### Filter Expressions
115
+
116
+ Filters are passed as JSON strings. All leaf filters require `fieldId`, `valueType`, and `value`:
117
+
118
+ ```javascript
119
+ // Equality
120
+ db.query(vec, 10, {
121
+ filter: '{"op":"eq","fieldId":0,"valueType":"string","value":"science"}'
122
+ });
123
+
124
+ // Range
125
+ db.query(vec, 10, {
126
+ filter: '{"op":"range","fieldId":1,"valueType":"f64","low":"0.5","high":"1.0"}'
127
+ });
128
+
129
+ // In-set
130
+ db.query(vec, 10, {
131
+ filter: '{"op":"in","fieldId":0,"valueType":"u64","values":["1","2","5"]}'
132
+ });
133
+
134
+ // Boolean combinations
135
+ db.query(vec, 10, {
136
+ filter: JSON.stringify({
137
+ op: 'and',
138
+ children: [
139
+ { op: 'eq', fieldId: 0, valueType: 'string', value: 'science' },
140
+ { op: 'gt', fieldId: 1, valueType: 'f64', value: '0.8' }
141
+ ]
142
+ })
143
+ });
144
+
145
+ // Negation
146
+ db.query(vec, 10, {
147
+ filter: '{"op":"not","child":{"op":"eq","fieldId":0,"valueType":"string","value":"spam"}}'
148
+ });
149
+ ```
150
+
151
+ **Supported operators:** `eq`, `ne`, `lt`, `le`, `gt`, `ge`, `in`, `range`, `and`, `or`, `not`
152
+
153
+ **Supported value types:** `u64`, `i64`, `f64`, `string`, `bool`
154
+
155
+ ### Delete
156
+
157
+ ```typescript
158
+ // Delete by ID
159
+ const result = db.delete([1, 2, 3]);
160
+ // Returns: { deleted: number, epoch: number }
161
+
162
+ // Delete by filter
163
+ const result = db.deleteByFilter(
164
+ '{"op":"gt","fieldId":1,"valueType":"f64","value":"0.9"}'
165
+ );
166
+ ```
167
+
168
+ ### Compact
169
+
170
+ Reclaims space from deleted vectors:
171
+
172
+ ```typescript
173
+ const result = db.compact();
174
+ // Returns: { segmentsCompacted: number, bytesReclaimed: number, epoch: number }
175
+ ```
176
+
177
+ ### Status
178
+
179
+ ```typescript
180
+ const status = db.status();
181
+ // {
182
+ // totalVectors: number,
183
+ // totalSegments: number,
184
+ // fileSize: number,
185
+ // currentEpoch: number,
186
+ // profileId: number,
187
+ // compactionState: 'idle' | 'running' | 'emergency',
188
+ // deadSpaceRatio: number,
189
+ // readOnly: boolean
190
+ // }
191
+ ```
192
+
193
+ ### Lineage & Derivation
194
+
195
+ RVF tracks parent/child relationships with cryptographic hashes:
196
+
197
+ ```typescript
198
+ db.fileId(); // hex string — unique file identifier
199
+ db.parentId(); // hex string — parent's ID (zeros if root)
200
+ db.lineageDepth(); // 0 for root files
201
+
202
+ // Derive a child store (inherits dimensions and options)
203
+ const child = db.derive('/tmp/child.rvf');
204
+ child.lineageDepth(); // 1
205
+ child.parentId(); // matches parent's fileId()
206
+ ```
207
+
208
+ ### Kernel & eBPF Embedding
209
+
210
+ Embed compute segments alongside vector data:
211
+
212
+ ```typescript
213
+ // Embed a Linux microkernel
214
+ db.embedKernel(
215
+ 1, // arch: 0=x86_64, 1=aarch64
216
+ 0, // kernel type
217
+ 0, // flags
218
+ Buffer.from(kernelImage), // kernel binary
219
+ 8080, // API port
220
+ 'console=ttyS0 quiet' // kernel cmdline (optional)
221
+ );
222
+
223
+ // Extract kernel
224
+ const kernel = db.extractKernel();
225
+ if (kernel) {
226
+ console.log(kernel.header); // Buffer: 128-byte KernelHeader
227
+ console.log(kernel.image); // Buffer: kernel image bytes
228
+ }
229
+
230
+ // Embed an eBPF XDP program
231
+ db.embedEbpf(
232
+ 1, // program type (XDP distance)
233
+ 2, // attach type (XDP ingress)
234
+ 384, // max vector dimension
235
+ Buffer.from(bytecode), // BPF ELF object
236
+ Buffer.from(btf) // optional BTF section
237
+ );
238
+
239
+ // Extract eBPF
240
+ const ebpf = db.extractEbpf();
241
+ if (ebpf) {
242
+ console.log(ebpf.header); // Buffer: 64-byte EbpfHeader
243
+ console.log(ebpf.payload); // Buffer: bytecode + BTF
244
+ }
245
+ ```
246
+
247
+ ### Segment Inspection
248
+
249
+ ```typescript
250
+ const segments = db.segments();
251
+ // [{ id: 1, offset: 0, payloadLength: 4096, segType: 'manifest' },
252
+ // { id: 2, offset: 4160, payloadLength: 51200, segType: 'vec' },
253
+ // { id: 3, offset: 55424, payloadLength: 12288, segType: 'index' }]
254
+
255
+ db.dimension(); // 384
256
+ ```
257
+
258
+ ## Build from Source
259
+
260
+ ```bash
261
+ # Prerequisites: Rust 1.87+, Node.js 18+
262
+ cd crates/rvf/rvf-node
263
+ npm install
264
+ npm run build
265
+ ```
266
+
267
+ ## Related Packages
35
268
 
36
- - Native performance via N-API bindings to Rust `rvf-runtime`
37
- - Full store lifecycle: create, open, ingest, query, delete, compact
38
- - Lineage tracking with FileIdentity derivation chains
39
- - Kernel/eBPF segment inspection
40
- - Cross-platform: Linux x64/arm64, macOS x64/arm64, Windows x64
41
-
42
- ## API
43
-
44
- | Method | Description |
45
- |--------|-------------|
46
- | `RvfDatabase.create(path, options)` | Create a new RVF store |
47
- | `RvfDatabase.open(path)` | Open an existing store |
48
- | `db.ingestBatch(vectors, ids)` | Insert vectors |
49
- | `db.query(vector, k)` | k-NN similarity search |
50
- | `db.delete(ids)` | Delete vectors by ID |
51
- | `db.compact()` | Reclaim deleted space |
52
- | `db.status()` | Get store stats |
53
- | `db.segments()` | List all segments |
54
- | `db.fileId()` | Get unique file UUID |
55
- | `db.close()` | Close and release lock |
269
+ | Package | Description |
270
+ |---------|-------------|
271
+ | [`@ruvector/rvf`](https://www.npmjs.com/package/@ruvector/rvf) | Unified TypeScript SDK |
272
+ | [`@ruvector/rvf-wasm`](https://www.npmjs.com/package/@ruvector/rvf-wasm) | Browser WASM package |
273
+ | [`@ruvector/rvf-mcp-server`](https://www.npmjs.com/package/@ruvector/rvf-mcp-server) | MCP server for AI agents |
274
+ | [`rvf-runtime`](https://crates.io/crates/rvf-runtime) | Rust runtime (powers this package) |
56
275
 
57
276
  ## License
58
277
 
59
- MIT
278
+ MIT OR Apache-2.0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ruvector/rvf-node",
3
- "version": "0.1.1",
3
+ "version": "0.1.3",
4
4
  "description": "RuVector Format Node.js native bindings",
5
5
  "main": "index.js",
6
6
  "types": "index.d.ts",