@ruvector/rvf-node 0.1.3 → 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 +25 -0
- package/index.d.ts +95 -0
- package/index.js +150 -0
- package/package.json +32 -13
- package/rvf-node.linux-x64-gnu.node +0 -0
package/README.md
CHANGED
|
@@ -255,6 +255,31 @@ const segments = db.segments();
|
|
|
255
255
|
db.dimension(); // 384
|
|
256
256
|
```
|
|
257
257
|
|
|
258
|
+
## Self-Booting RVF
|
|
259
|
+
|
|
260
|
+
An `.rvf` file can embed a Linux kernel, eBPF programs, and SSH keys alongside vector data — producing a single file that boots as a microservice.
|
|
261
|
+
|
|
262
|
+
The Claude Code Appliance example builds a complete AI dev environment:
|
|
263
|
+
|
|
264
|
+
```bash
|
|
265
|
+
cd examples/rvf
|
|
266
|
+
cargo run --example claude_code_appliance
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
```
|
|
270
|
+
claude_code_appliance.rvf
|
|
271
|
+
├── KERNEL_SEG Linux 6.8.12 bzImage (5.2 MB, x86_64)
|
|
272
|
+
├── EBPF_SEG Socket filter — ports 2222, 8080 only
|
|
273
|
+
├── VEC_SEG 20 package embeddings (128-dim)
|
|
274
|
+
├── INDEX_SEG HNSW graph for package search
|
|
275
|
+
├── WITNESS_SEG 6-entry tamper-evident audit trail
|
|
276
|
+
└── CRYPTO_SEG 3 Ed25519 SSH user keys
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
Final file: **5.1 MB single `.rvf`** — boots Linux, serves queries, runs Claude Code.
|
|
280
|
+
|
|
281
|
+
See the [full RVF documentation](https://github.com/ruvnet/ruvector/tree/main/crates/rvf) for details.
|
|
282
|
+
|
|
258
283
|
## Build from Source
|
|
259
284
|
|
|
260
285
|
```bash
|
package/index.d.ts
ADDED
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
/* auto-generated: TypeScript declarations for @ruvector/rvf-node */
|
|
2
|
+
|
|
3
|
+
export interface RvfOptions {
|
|
4
|
+
dimension: number;
|
|
5
|
+
metric?: string;
|
|
6
|
+
profile?: number;
|
|
7
|
+
signing?: boolean;
|
|
8
|
+
m?: number;
|
|
9
|
+
efConstruction?: number;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export interface RvfQueryOptions {
|
|
13
|
+
efSearch?: number;
|
|
14
|
+
filter?: string;
|
|
15
|
+
timeoutMs?: number;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export interface RvfSearchResult {
|
|
19
|
+
id: number;
|
|
20
|
+
distance: number;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export interface RvfIngestResult {
|
|
24
|
+
accepted: number;
|
|
25
|
+
rejected: number;
|
|
26
|
+
epoch: number;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export interface RvfDeleteResult {
|
|
30
|
+
deleted: number;
|
|
31
|
+
epoch: number;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export interface RvfCompactionResult {
|
|
35
|
+
segmentsCompacted: number;
|
|
36
|
+
bytesReclaimed: number;
|
|
37
|
+
epoch: number;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export interface RvfStatus {
|
|
41
|
+
totalVectors: number;
|
|
42
|
+
totalSegments: number;
|
|
43
|
+
fileSize: number;
|
|
44
|
+
currentEpoch: number;
|
|
45
|
+
profileId: number;
|
|
46
|
+
compactionState: string;
|
|
47
|
+
deadSpaceRatio: number;
|
|
48
|
+
readOnly: boolean;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export interface RvfMetadataEntry {
|
|
52
|
+
fieldId: number;
|
|
53
|
+
valueType: string;
|
|
54
|
+
value: string;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export interface RvfKernelData {
|
|
58
|
+
header: Buffer;
|
|
59
|
+
image: Buffer;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export interface RvfEbpfData {
|
|
63
|
+
header: Buffer;
|
|
64
|
+
payload: Buffer;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
export interface RvfSegmentInfo {
|
|
68
|
+
id: number;
|
|
69
|
+
offset: number;
|
|
70
|
+
payloadLength: number;
|
|
71
|
+
segType: string;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
export class RvfDatabase {
|
|
75
|
+
static create(path: string, options: RvfOptions): RvfDatabase;
|
|
76
|
+
static open(path: string): RvfDatabase;
|
|
77
|
+
static openReadonly(path: string): RvfDatabase;
|
|
78
|
+
ingestBatch(vectors: Float32Array, ids: number[], metadata?: RvfMetadataEntry[]): RvfIngestResult;
|
|
79
|
+
query(vector: Float32Array, k: number, options?: RvfQueryOptions): RvfSearchResult[];
|
|
80
|
+
delete(ids: number[]): RvfDeleteResult;
|
|
81
|
+
deleteByFilter(filterJson: string): RvfDeleteResult;
|
|
82
|
+
compact(): RvfCompactionResult;
|
|
83
|
+
status(): RvfStatus;
|
|
84
|
+
close(): void;
|
|
85
|
+
fileId(): string;
|
|
86
|
+
parentId(): string;
|
|
87
|
+
lineageDepth(): number;
|
|
88
|
+
derive(childPath: string, options?: RvfOptions): RvfDatabase;
|
|
89
|
+
embedKernel(arch: number, kernelType: number, flags: number, image: Buffer, apiPort: number, cmdline?: string): number;
|
|
90
|
+
extractKernel(): RvfKernelData | null;
|
|
91
|
+
embedEbpf(programType: number, attachType: number, maxDimension: number, bytecode: Buffer, btf?: Buffer): number;
|
|
92
|
+
extractEbpf(): RvfEbpfData | null;
|
|
93
|
+
segments(): RvfSegmentInfo[];
|
|
94
|
+
dimension(): number;
|
|
95
|
+
}
|
package/index.js
ADDED
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
/* eslint-disable */
|
|
2
|
+
/* auto-generated: NAPI-RS platform loader for @ruvector/rvf-node */
|
|
3
|
+
|
|
4
|
+
const { existsSync, readFileSync } = require('fs');
|
|
5
|
+
const { join } = require('path');
|
|
6
|
+
|
|
7
|
+
const { platform, arch } = process;
|
|
8
|
+
|
|
9
|
+
let nativeBinding = null;
|
|
10
|
+
let localFileExisted = false;
|
|
11
|
+
let loadError = null;
|
|
12
|
+
|
|
13
|
+
function isMusl() {
|
|
14
|
+
// For Node 12+, check report.header.glibcVersionRuntime
|
|
15
|
+
if (!process.report || typeof process.report.getReport !== 'function') {
|
|
16
|
+
try {
|
|
17
|
+
const lddPath = require('child_process')
|
|
18
|
+
.execSync('which ldd')
|
|
19
|
+
.toString()
|
|
20
|
+
.trim();
|
|
21
|
+
return readFileSync(lddPath, 'utf8').includes('musl');
|
|
22
|
+
} catch {
|
|
23
|
+
return true;
|
|
24
|
+
}
|
|
25
|
+
} else {
|
|
26
|
+
const report = process.report.getReport();
|
|
27
|
+
const rep = typeof report === 'string' ? JSON.parse(report) : report;
|
|
28
|
+
return !rep.header.glibcVersionRuntime;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
switch (platform) {
|
|
33
|
+
case 'darwin':
|
|
34
|
+
switch (arch) {
|
|
35
|
+
case 'x64':
|
|
36
|
+
localFileExisted = existsSync(join(__dirname, 'rvf-node.darwin-x64.node'));
|
|
37
|
+
try {
|
|
38
|
+
if (localFileExisted) {
|
|
39
|
+
nativeBinding = require('./rvf-node.darwin-x64.node');
|
|
40
|
+
} else {
|
|
41
|
+
nativeBinding = require('@ruvector/rvf-node-darwin-x64');
|
|
42
|
+
}
|
|
43
|
+
} catch (e) {
|
|
44
|
+
loadError = e;
|
|
45
|
+
}
|
|
46
|
+
break;
|
|
47
|
+
case 'arm64':
|
|
48
|
+
localFileExisted = existsSync(join(__dirname, 'rvf-node.darwin-arm64.node'));
|
|
49
|
+
try {
|
|
50
|
+
if (localFileExisted) {
|
|
51
|
+
nativeBinding = require('./rvf-node.darwin-arm64.node');
|
|
52
|
+
} else {
|
|
53
|
+
nativeBinding = require('@ruvector/rvf-node-darwin-arm64');
|
|
54
|
+
}
|
|
55
|
+
} catch (e) {
|
|
56
|
+
loadError = e;
|
|
57
|
+
}
|
|
58
|
+
break;
|
|
59
|
+
default:
|
|
60
|
+
throw new Error(`Unsupported architecture on macOS: ${arch}`);
|
|
61
|
+
}
|
|
62
|
+
break;
|
|
63
|
+
case 'win32':
|
|
64
|
+
switch (arch) {
|
|
65
|
+
case 'x64':
|
|
66
|
+
localFileExisted = existsSync(join(__dirname, 'rvf-node.win32-x64-msvc.node'));
|
|
67
|
+
try {
|
|
68
|
+
if (localFileExisted) {
|
|
69
|
+
nativeBinding = require('./rvf-node.win32-x64-msvc.node');
|
|
70
|
+
} else {
|
|
71
|
+
nativeBinding = require('@ruvector/rvf-node-win32-x64-msvc');
|
|
72
|
+
}
|
|
73
|
+
} catch (e) {
|
|
74
|
+
loadError = e;
|
|
75
|
+
}
|
|
76
|
+
break;
|
|
77
|
+
default:
|
|
78
|
+
throw new Error(`Unsupported architecture on Windows: ${arch}`);
|
|
79
|
+
}
|
|
80
|
+
break;
|
|
81
|
+
case 'linux':
|
|
82
|
+
switch (arch) {
|
|
83
|
+
case 'x64':
|
|
84
|
+
if (isMusl()) {
|
|
85
|
+
localFileExisted = existsSync(join(__dirname, 'rvf-node.linux-x64-musl.node'));
|
|
86
|
+
try {
|
|
87
|
+
if (localFileExisted) {
|
|
88
|
+
nativeBinding = require('./rvf-node.linux-x64-musl.node');
|
|
89
|
+
} else {
|
|
90
|
+
nativeBinding = require('@ruvector/rvf-node-linux-x64-musl');
|
|
91
|
+
}
|
|
92
|
+
} catch (e) {
|
|
93
|
+
loadError = e;
|
|
94
|
+
}
|
|
95
|
+
} else {
|
|
96
|
+
localFileExisted = existsSync(join(__dirname, 'rvf-node.linux-x64-gnu.node'));
|
|
97
|
+
try {
|
|
98
|
+
if (localFileExisted) {
|
|
99
|
+
nativeBinding = require('./rvf-node.linux-x64-gnu.node');
|
|
100
|
+
} else {
|
|
101
|
+
nativeBinding = require('@ruvector/rvf-node-linux-x64-gnu');
|
|
102
|
+
}
|
|
103
|
+
} catch (e) {
|
|
104
|
+
loadError = e;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
break;
|
|
108
|
+
case 'arm64':
|
|
109
|
+
if (isMusl()) {
|
|
110
|
+
localFileExisted = existsSync(join(__dirname, 'rvf-node.linux-arm64-musl.node'));
|
|
111
|
+
try {
|
|
112
|
+
if (localFileExisted) {
|
|
113
|
+
nativeBinding = require('./rvf-node.linux-arm64-musl.node');
|
|
114
|
+
} else {
|
|
115
|
+
nativeBinding = require('@ruvector/rvf-node-linux-arm64-musl');
|
|
116
|
+
}
|
|
117
|
+
} catch (e) {
|
|
118
|
+
loadError = e;
|
|
119
|
+
}
|
|
120
|
+
} else {
|
|
121
|
+
localFileExisted = existsSync(join(__dirname, 'rvf-node.linux-arm64-gnu.node'));
|
|
122
|
+
try {
|
|
123
|
+
if (localFileExisted) {
|
|
124
|
+
nativeBinding = require('./rvf-node.linux-arm64-gnu.node');
|
|
125
|
+
} else {
|
|
126
|
+
nativeBinding = require('@ruvector/rvf-node-linux-arm64-gnu');
|
|
127
|
+
}
|
|
128
|
+
} catch (e) {
|
|
129
|
+
loadError = e;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
break;
|
|
133
|
+
default:
|
|
134
|
+
throw new Error(`Unsupported architecture on Linux: ${arch}`);
|
|
135
|
+
}
|
|
136
|
+
break;
|
|
137
|
+
default:
|
|
138
|
+
throw new Error(`Unsupported OS: ${platform}, architecture: ${arch}`);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
if (!nativeBinding) {
|
|
142
|
+
if (loadError) {
|
|
143
|
+
throw loadError;
|
|
144
|
+
}
|
|
145
|
+
throw new Error('Failed to load native binding');
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
const { RvfDatabase } = nativeBinding;
|
|
149
|
+
|
|
150
|
+
module.exports.RvfDatabase = RvfDatabase;
|
package/package.json
CHANGED
|
@@ -1,25 +1,44 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ruvector/rvf-node",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.4",
|
|
4
4
|
"description": "RuVector Format Node.js native bindings",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"types": "index.d.ts",
|
|
7
|
+
"files": [
|
|
8
|
+
"index.js",
|
|
9
|
+
"index.d.ts",
|
|
10
|
+
"*.node"
|
|
11
|
+
],
|
|
7
12
|
"napi": {
|
|
8
|
-
"
|
|
9
|
-
"
|
|
10
|
-
"
|
|
11
|
-
"
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
13
|
+
"binaryName": "rvf-node",
|
|
14
|
+
"targets": [
|
|
15
|
+
"x86_64-unknown-linux-gnu",
|
|
16
|
+
"x86_64-apple-darwin",
|
|
17
|
+
"aarch64-apple-darwin",
|
|
18
|
+
"x86_64-pc-windows-msvc",
|
|
19
|
+
"aarch64-unknown-linux-gnu"
|
|
20
|
+
]
|
|
16
21
|
},
|
|
17
22
|
"scripts": {
|
|
18
|
-
"build": "napi build --platform --release"
|
|
19
|
-
"test": "jest"
|
|
23
|
+
"build": "napi build --platform --release"
|
|
20
24
|
},
|
|
21
25
|
"license": "MIT",
|
|
22
|
-
"
|
|
23
|
-
"
|
|
26
|
+
"repository": {
|
|
27
|
+
"type": "git",
|
|
28
|
+
"url": "https://github.com/ruvnet/ruvector"
|
|
29
|
+
},
|
|
30
|
+
"engines": {
|
|
31
|
+
"node": ">= 16"
|
|
32
|
+
},
|
|
33
|
+
"publishConfig": {
|
|
34
|
+
"registry": "https://registry.npmjs.org/",
|
|
35
|
+
"access": "public"
|
|
36
|
+
},
|
|
37
|
+
"optionalDependencies": {
|
|
38
|
+
"@ruvector/rvf-node-linux-x64-gnu": "0.1.4",
|
|
39
|
+
"@ruvector/rvf-node-darwin-x64": "0.1.4",
|
|
40
|
+
"@ruvector/rvf-node-darwin-arm64": "0.1.4",
|
|
41
|
+
"@ruvector/rvf-node-win32-x64-msvc": "0.1.4",
|
|
42
|
+
"@ruvector/rvf-node-linux-arm64-gnu": "0.1.4"
|
|
24
43
|
}
|
|
25
44
|
}
|
|
Binary file
|