@ruvector/rvf-node 0.2.0 → 0.2.1
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 +0 -75
- package/index.d.ts +259 -73
- package/index.js +229 -64
- package/package.json +11 -19
- package/rvf-node.darwin-arm64.node +0 -0
- package/rvf-node.darwin-x64.node +0 -0
- package/rvf-node.linux-arm64-gnu.node +0 -0
- package/rvf-node.linux-x64-gnu.node +0 -0
- package/rvf-node.win32-x64-msvc.node +0 -0
package/README.md
CHANGED
|
@@ -18,56 +18,6 @@ npm install @ruvector/rvf-node
|
|
|
18
18
|
- **Kernel & eBPF embedding** — embed compute alongside vector data
|
|
19
19
|
- **Segment inspection** — enumerate all segments in the file
|
|
20
20
|
- **Cross-platform** — Linux (x86_64, aarch64), macOS (x86_64, Apple Silicon), Windows (x86_64)
|
|
21
|
-
- **AGI methods** — HNSW index stats, witness chain verification, state freeze, metric introspection
|
|
22
|
-
|
|
23
|
-
## AGI Methods
|
|
24
|
-
|
|
25
|
-
Four introspection and integrity methods for advanced use cases.
|
|
26
|
-
|
|
27
|
-
### `db.indexStats()` → `RvfIndexStats`
|
|
28
|
-
|
|
29
|
-
Returns HNSW index statistics.
|
|
30
|
-
|
|
31
|
-
| Field | Type | Description |
|
|
32
|
-
|-------|------|-------------|
|
|
33
|
-
| `indexedVectors` | `number` | Number of indexed vectors |
|
|
34
|
-
| `layers` | `number` | Number of HNSW layers |
|
|
35
|
-
| `m` | `number` | M parameter (max edges per node per layer) |
|
|
36
|
-
| `efConstruction` | `number` | ef_construction parameter |
|
|
37
|
-
| `needsRebuild` | `boolean` | Whether index needs rebuilding (dead_space_ratio > 0.3) |
|
|
38
|
-
|
|
39
|
-
### `db.verifyWitness()` → `RvfWitnessResult`
|
|
40
|
-
|
|
41
|
-
Verifies SHAKE-256 witness chain integrity.
|
|
42
|
-
|
|
43
|
-
| Field | Type | Description |
|
|
44
|
-
|-------|------|-------------|
|
|
45
|
-
| `valid` | `boolean` | Whether the chain is valid |
|
|
46
|
-
| `entries` | `number` | Number of entries in the chain |
|
|
47
|
-
| `error` | `string?` | Error message if invalid |
|
|
48
|
-
|
|
49
|
-
### `db.freeze()` → `number`
|
|
50
|
-
|
|
51
|
-
Snapshot-freeze current state. Returns the epoch number.
|
|
52
|
-
|
|
53
|
-
### `db.metric()` → `string`
|
|
54
|
-
|
|
55
|
-
Returns the distance metric name (`"l2"`, `"cosine"`, or `"inner_product"`).
|
|
56
|
-
|
|
57
|
-
### Usage Example
|
|
58
|
-
|
|
59
|
-
```javascript
|
|
60
|
-
const stats = db.indexStats();
|
|
61
|
-
console.log(`Indexed: ${stats.indexedVectors}, HNSW layers: ${stats.layers}`);
|
|
62
|
-
|
|
63
|
-
const witness = db.verifyWitness();
|
|
64
|
-
console.log(`Witness chain: ${witness.entries} entries, valid: ${witness.valid}`);
|
|
65
|
-
|
|
66
|
-
console.log(`Distance metric: ${db.metric()}`);
|
|
67
|
-
|
|
68
|
-
const epoch = db.freeze();
|
|
69
|
-
console.log(`State frozen at epoch ${epoch}`);
|
|
70
|
-
```
|
|
71
21
|
|
|
72
22
|
## Quick Start
|
|
73
23
|
|
|
@@ -305,31 +255,6 @@ const segments = db.segments();
|
|
|
305
255
|
db.dimension(); // 384
|
|
306
256
|
```
|
|
307
257
|
|
|
308
|
-
## Self-Booting RVF
|
|
309
|
-
|
|
310
|
-
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.
|
|
311
|
-
|
|
312
|
-
The Claude Code Appliance example builds a complete AI dev environment:
|
|
313
|
-
|
|
314
|
-
```bash
|
|
315
|
-
cd examples/rvf
|
|
316
|
-
cargo run --example claude_code_appliance
|
|
317
|
-
```
|
|
318
|
-
|
|
319
|
-
```
|
|
320
|
-
claude_code_appliance.rvf
|
|
321
|
-
├── KERNEL_SEG Linux 6.8.12 bzImage (5.2 MB, x86_64)
|
|
322
|
-
├── EBPF_SEG Socket filter — ports 2222, 8080 only
|
|
323
|
-
├── VEC_SEG 20 package embeddings (128-dim)
|
|
324
|
-
├── INDEX_SEG HNSW graph for package search
|
|
325
|
-
├── WITNESS_SEG 6-entry tamper-evident audit trail
|
|
326
|
-
└── CRYPTO_SEG 3 Ed25519 SSH user keys
|
|
327
|
-
```
|
|
328
|
-
|
|
329
|
-
Final file: **5.1 MB single `.rvf`** — boots Linux, serves queries, runs Claude Code.
|
|
330
|
-
|
|
331
|
-
See the [full RVF documentation](https://github.com/ruvnet/ruvector/tree/main/crates/rvf) for details.
|
|
332
|
-
|
|
333
258
|
## Build from Source
|
|
334
259
|
|
|
335
260
|
```bash
|
package/index.d.ts
CHANGED
|
@@ -1,95 +1,281 @@
|
|
|
1
|
-
/*
|
|
1
|
+
/* tslint:disable */
|
|
2
|
+
/* eslint-disable */
|
|
2
3
|
|
|
4
|
+
/* auto-generated by NAPI-RS */
|
|
5
|
+
|
|
6
|
+
/** Options for creating a new RVF store. */
|
|
3
7
|
export interface RvfOptions {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
8
|
+
/** Vector dimensionality (required). */
|
|
9
|
+
dimension: number
|
|
10
|
+
/** Distance metric: "l2" | "inner_product" | "cosine". Defaults to "l2". */
|
|
11
|
+
metric?: string
|
|
12
|
+
/** Hardware profile: 0=Generic, 1=Core, 2=Hot, 3=Full. Defaults to 0. */
|
|
13
|
+
profile?: number
|
|
14
|
+
/** Compression profile: "None" | "Scalar" | "Product". Defaults to "None". */
|
|
15
|
+
compression?: string
|
|
16
|
+
/** Whether segment signing is enabled. Defaults to false. */
|
|
17
|
+
signing?: boolean
|
|
18
|
+
/** HNSW M parameter. Defaults to 16. */
|
|
19
|
+
m?: number
|
|
20
|
+
/** HNSW ef_construction parameter. Defaults to 200. */
|
|
21
|
+
efConstruction?: number
|
|
10
22
|
}
|
|
11
|
-
|
|
23
|
+
/**
|
|
24
|
+
* Options for a query operation.
|
|
25
|
+
*
|
|
26
|
+
* The `filter` field accepts a JSON string encoding a recursive filter tree.
|
|
27
|
+
* See `RvfDatabase.query()` for the filter expression format.
|
|
28
|
+
*/
|
|
12
29
|
export interface RvfQueryOptions {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
30
|
+
/** HNSW ef_search parameter. Defaults to 100. */
|
|
31
|
+
efSearch?: number
|
|
32
|
+
/**
|
|
33
|
+
* Optional filter expression as a JSON string.
|
|
34
|
+
*
|
|
35
|
+
* Format examples:
|
|
36
|
+
* `{"op":"eq","fieldId":0,"valueType":"string","value":"cat_a"}`
|
|
37
|
+
* `{"op":"and","children":[...]}`
|
|
38
|
+
* `{"op":"not","child":{...}}`
|
|
39
|
+
*/
|
|
40
|
+
filter?: string
|
|
41
|
+
/** Query timeout in milliseconds. 0 = no timeout. */
|
|
42
|
+
timeoutMs?: number
|
|
16
43
|
}
|
|
17
|
-
|
|
44
|
+
/** A single search result returned from a query. */
|
|
18
45
|
export interface RvfSearchResult {
|
|
19
|
-
|
|
20
|
-
|
|
46
|
+
/** The vector's unique identifier. */
|
|
47
|
+
id: number
|
|
48
|
+
/** Distance from the query vector (lower = more similar). */
|
|
49
|
+
distance: number
|
|
21
50
|
}
|
|
22
|
-
|
|
51
|
+
/** Result of a batch ingest operation. */
|
|
23
52
|
export interface RvfIngestResult {
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
53
|
+
/** Number of vectors successfully ingested. */
|
|
54
|
+
accepted: number
|
|
55
|
+
/** Number of vectors rejected (dimension mismatch, etc.). */
|
|
56
|
+
rejected: number
|
|
57
|
+
/** Manifest epoch after commit. */
|
|
58
|
+
epoch: number
|
|
27
59
|
}
|
|
28
|
-
|
|
60
|
+
/** Result of a delete operation. */
|
|
29
61
|
export interface RvfDeleteResult {
|
|
30
|
-
deleted
|
|
31
|
-
|
|
62
|
+
/** Number of vectors deleted. */
|
|
63
|
+
deleted: number
|
|
64
|
+
/** Manifest epoch after commit. */
|
|
65
|
+
epoch: number
|
|
32
66
|
}
|
|
33
|
-
|
|
34
|
-
export interface RvfCompactionResult {
|
|
35
|
-
segmentsCompacted: number;
|
|
36
|
-
bytesReclaimed: number;
|
|
37
|
-
epoch: number;
|
|
38
|
-
}
|
|
39
|
-
|
|
67
|
+
/** Current store status snapshot. */
|
|
40
68
|
export interface RvfStatus {
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
69
|
+
/** Total number of live (non-deleted) vectors. */
|
|
70
|
+
totalVectors: number
|
|
71
|
+
/** Total number of segments in the file. */
|
|
72
|
+
totalSegments: number
|
|
73
|
+
/** Total file size in bytes. */
|
|
74
|
+
fileSize: number
|
|
75
|
+
/** Current manifest epoch. */
|
|
76
|
+
currentEpoch: number
|
|
77
|
+
/** Hardware profile identifier. */
|
|
78
|
+
profileId: number
|
|
79
|
+
/** Current compaction state: "idle" | "running" | "emergency". */
|
|
80
|
+
compactionState: string
|
|
81
|
+
/** Ratio of dead (deleted) space to total (0.0 - 1.0). */
|
|
82
|
+
deadSpaceRatio: number
|
|
83
|
+
/** Whether the store is open in read-only mode. */
|
|
84
|
+
readOnly: boolean
|
|
49
85
|
}
|
|
50
|
-
|
|
86
|
+
/** Result of a compaction operation. */
|
|
87
|
+
export interface RvfCompactionResult {
|
|
88
|
+
/** Number of segments compacted. */
|
|
89
|
+
segmentsCompacted: number
|
|
90
|
+
/** Bytes of dead space reclaimed. */
|
|
91
|
+
bytesReclaimed: number
|
|
92
|
+
/** Manifest epoch after compaction. */
|
|
93
|
+
epoch: number
|
|
94
|
+
}
|
|
95
|
+
/** A metadata entry for ingest: { fieldId, valueType, value }. */
|
|
51
96
|
export interface RvfMetadataEntry {
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
97
|
+
/** Metadata field identifier. */
|
|
98
|
+
fieldId: number
|
|
99
|
+
/** Value type: "u64" | "i64" | "f64" | "string". */
|
|
100
|
+
valueType: string
|
|
101
|
+
/** The value as a string representation (parsed based on value_type). */
|
|
102
|
+
value: string
|
|
55
103
|
}
|
|
56
|
-
|
|
104
|
+
/** Data returned from kernel extraction. */
|
|
57
105
|
export interface RvfKernelData {
|
|
58
|
-
|
|
59
|
-
|
|
106
|
+
/** Serialized 128-byte KernelHeader. */
|
|
107
|
+
header: Buffer
|
|
108
|
+
/** Raw kernel image bytes. */
|
|
109
|
+
image: Buffer
|
|
60
110
|
}
|
|
61
|
-
|
|
111
|
+
/** Data returned from eBPF extraction. */
|
|
62
112
|
export interface RvfEbpfData {
|
|
63
|
-
|
|
64
|
-
|
|
113
|
+
/** Serialized 64-byte EbpfHeader. */
|
|
114
|
+
header: Buffer
|
|
115
|
+
/** Program bytecode + optional BTF. */
|
|
116
|
+
payload: Buffer
|
|
65
117
|
}
|
|
66
|
-
|
|
118
|
+
/** Information about a segment in the store. */
|
|
67
119
|
export interface RvfSegmentInfo {
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
120
|
+
/** Segment ID. */
|
|
121
|
+
id: number
|
|
122
|
+
/** File offset of the segment. */
|
|
123
|
+
offset: number
|
|
124
|
+
/** Payload length in bytes. */
|
|
125
|
+
payloadLength: number
|
|
126
|
+
/** Segment type as a string (e.g. "vec", "manifest", "kernel"). */
|
|
127
|
+
segType: string
|
|
72
128
|
}
|
|
73
|
-
|
|
74
|
-
export
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
129
|
+
/** HNSW index statistics. */
|
|
130
|
+
export interface RvfIndexStats {
|
|
131
|
+
/** Number of indexed vectors. */
|
|
132
|
+
indexedVectors: number
|
|
133
|
+
/** Number of HNSW layers. */
|
|
134
|
+
layers: number
|
|
135
|
+
/** M parameter (max edges per node per layer). */
|
|
136
|
+
m: number
|
|
137
|
+
/** ef_construction parameter. */
|
|
138
|
+
efConstruction: number
|
|
139
|
+
/** Whether the index needs rebuilding. */
|
|
140
|
+
needsRebuild: boolean
|
|
141
|
+
}
|
|
142
|
+
/** Result of witness chain verification. */
|
|
143
|
+
export interface RvfWitnessResult {
|
|
144
|
+
/** Whether the witness chain is valid. */
|
|
145
|
+
valid: boolean
|
|
146
|
+
/** Number of entries in the chain. */
|
|
147
|
+
entries: number
|
|
148
|
+
/** Error message if invalid. */
|
|
149
|
+
error?: string
|
|
150
|
+
}
|
|
151
|
+
/** Quantization configuration. */
|
|
152
|
+
export interface RvfQuantConfig {
|
|
153
|
+
/** Quantization mode: "none" | "scalar" | "product" | "binary". */
|
|
154
|
+
mode: string
|
|
155
|
+
/** Number of subquantizers (for product quantization). */
|
|
156
|
+
numSubquantizers?: number
|
|
157
|
+
/** Number of centroids per subquantizer. */
|
|
158
|
+
numCentroids?: number
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* The main RVF database handle exposed to Node.js.
|
|
162
|
+
*
|
|
163
|
+
* All mutating methods acquire an internal mutex so the handle is safe
|
|
164
|
+
* to share across async operations (though RVF itself is single-writer).
|
|
165
|
+
*/
|
|
166
|
+
export declare class RvfDatabase {
|
|
167
|
+
/** Create a new RVF store at the given file path. */
|
|
168
|
+
static create(path: string, options: RvfOptions): RvfDatabase
|
|
169
|
+
/** Open an existing RVF store for read-write access. */
|
|
170
|
+
static open(path: string): RvfDatabase
|
|
171
|
+
/** Open an existing RVF store for read-only access (no lock required). */
|
|
172
|
+
static openReadonly(path: string): RvfDatabase
|
|
173
|
+
/**
|
|
174
|
+
* Ingest a batch of vectors.
|
|
175
|
+
*
|
|
176
|
+
* `vectors` is a flat Float32Array of length `n * dimension`.
|
|
177
|
+
* `ids` is a number[] of vector IDs.
|
|
178
|
+
* `metadata` is an optional array of metadata entries.
|
|
179
|
+
*/
|
|
180
|
+
ingestBatch(vectors: Float32Array, ids: Array<number>, metadata?: Array<RvfMetadataEntry> | undefined | null): RvfIngestResult
|
|
181
|
+
/**
|
|
182
|
+
* Query for the k nearest neighbors of the given vector.
|
|
183
|
+
*
|
|
184
|
+
* `vector` is a Float32Array of length `dimension`.
|
|
185
|
+
* `k` is the number of neighbors to return.
|
|
186
|
+
* `options` provides optional filter (as JSON string) and search parameters.
|
|
187
|
+
*
|
|
188
|
+
* Filter expression JSON format:
|
|
189
|
+
* - Leaf: `{"op":"eq","fieldId":0,"valueType":"string","value":"cat_a"}`
|
|
190
|
+
* - Boolean: `{"op":"and","children":[...]}`
|
|
191
|
+
* - Not: `{"op":"not","child":{...}}`
|
|
192
|
+
* - In: `{"op":"in","fieldId":0,"valueType":"u64","values":["1","2"]}`
|
|
193
|
+
* - Range: `{"op":"range","fieldId":1,"valueType":"u64","low":"10","high":"50"}`
|
|
194
|
+
*/
|
|
195
|
+
query(vector: Float32Array, k: number, options?: RvfQueryOptions | undefined | null): Array<RvfSearchResult>
|
|
196
|
+
/** Soft-delete vectors by ID. */
|
|
197
|
+
delete(ids: Array<number>): RvfDeleteResult
|
|
198
|
+
/**
|
|
199
|
+
* Soft-delete vectors matching a filter expression (passed as JSON string).
|
|
200
|
+
*
|
|
201
|
+
* See `query()` for the filter expression JSON format.
|
|
202
|
+
*/
|
|
203
|
+
deleteByFilter(filterJson: string): RvfDeleteResult
|
|
204
|
+
/** Run compaction to reclaim dead space from deleted vectors. */
|
|
205
|
+
compact(): RvfCompactionResult
|
|
206
|
+
/** Get a snapshot of the current store status. */
|
|
207
|
+
status(): RvfStatus
|
|
208
|
+
/**
|
|
209
|
+
* Close the store, releasing the writer lock and flushing data.
|
|
210
|
+
*
|
|
211
|
+
* After calling close(), all other methods will return an error.
|
|
212
|
+
*/
|
|
213
|
+
close(): void
|
|
214
|
+
/** Get this file's unique identifier as a hex string. */
|
|
215
|
+
fileId(): string
|
|
216
|
+
/** Get the parent file's identifier as a hex string (all zeros if root). */
|
|
217
|
+
parentId(): string
|
|
218
|
+
/** Get the lineage depth (0 for root files). */
|
|
219
|
+
lineageDepth(): number
|
|
220
|
+
/** Derive a child store from this parent. */
|
|
221
|
+
derive(childPath: string, options?: RvfOptions | undefined | null): RvfDatabase
|
|
222
|
+
/**
|
|
223
|
+
* Create a **queryable** copy-on-write branch of this store.
|
|
224
|
+
*
|
|
225
|
+
* Unlike [`derive`](Self::derive) — which records lineage only and
|
|
226
|
+
* produces a child that can see just its own edits — `branch` wires a
|
|
227
|
+
* real COW engine and membership filter so the child inherits the
|
|
228
|
+
* parent's vectors. Querying the child returns `parent ∪ child-edits`:
|
|
229
|
+
* the child's re-ingested vectors override the parent on an id
|
|
230
|
+
* collision, and deletes in the child hide inherited vectors. The
|
|
231
|
+
* branch stores only its own edits on disk, so it stays small
|
|
232
|
+
* regardless of the parent's size.
|
|
233
|
+
*
|
|
234
|
+
* The parent should be frozen (see [`freeze`](Self::freeze)) before
|
|
235
|
+
* branching to guarantee immutability of the inherited data.
|
|
236
|
+
*/
|
|
237
|
+
branch(childPath: string): RvfDatabase
|
|
238
|
+
/**
|
|
239
|
+
* Embed a kernel image into this RVF file.
|
|
240
|
+
* Returns the segment ID of the new kernel segment.
|
|
241
|
+
*/
|
|
242
|
+
embedKernel(arch: number, kernelType: number, flags: number, image: Buffer, apiPort: number, cmdline?: string | undefined | null): number
|
|
243
|
+
/**
|
|
244
|
+
* Extract the kernel image from this RVF file.
|
|
245
|
+
* Returns null if no kernel segment is present.
|
|
246
|
+
*/
|
|
247
|
+
extractKernel(): RvfKernelData | null
|
|
248
|
+
/**
|
|
249
|
+
* Embed an eBPF program into this RVF file.
|
|
250
|
+
* Returns the segment ID of the new eBPF segment.
|
|
251
|
+
*/
|
|
252
|
+
embedEbpf(programType: number, attachType: number, maxDimension: number, bytecode: Buffer, btf?: Buffer | undefined | null): number
|
|
253
|
+
/**
|
|
254
|
+
* Extract the eBPF program from this RVF file.
|
|
255
|
+
* Returns null if no eBPF segment is present.
|
|
256
|
+
*/
|
|
257
|
+
extractEbpf(): RvfEbpfData | null
|
|
258
|
+
/** Get the list of segments in the store. */
|
|
259
|
+
segments(): Array<RvfSegmentInfo>
|
|
260
|
+
/** Get the vector dimensionality of this store. */
|
|
261
|
+
dimension(): number
|
|
262
|
+
/** Get HNSW index statistics for this store. */
|
|
263
|
+
indexStats(): RvfIndexStats
|
|
264
|
+
/**
|
|
265
|
+
* Verify the tamper-evident witness chain in this store.
|
|
266
|
+
*
|
|
267
|
+
* Counts the witness segments present in the segment directory and
|
|
268
|
+
* checks whether the chain has been initialised (non-zero terminal
|
|
269
|
+
* hash). Returns the number of witness entries and validity status.
|
|
270
|
+
*/
|
|
271
|
+
verifyWitness(): RvfWitnessResult
|
|
272
|
+
/**
|
|
273
|
+
* Snapshot-freeze the current state of the store.
|
|
274
|
+
*
|
|
275
|
+
* Sets the store to read-only mode, preventing further writes.
|
|
276
|
+
* Returns the manifest epoch at freeze time.
|
|
277
|
+
*/
|
|
278
|
+
freeze(): number
|
|
279
|
+
/** Get the distance metric used by this store. */
|
|
280
|
+
metric(): string
|
|
95
281
|
}
|
package/index.js
CHANGED
|
@@ -1,150 +1,315 @@
|
|
|
1
|
+
/* tslint:disable */
|
|
1
2
|
/* eslint-disable */
|
|
2
|
-
/*
|
|
3
|
+
/* prettier-ignore */
|
|
3
4
|
|
|
4
|
-
|
|
5
|
-
const { join } = require('path');
|
|
5
|
+
/* auto-generated by NAPI-RS */
|
|
6
6
|
|
|
7
|
-
const {
|
|
7
|
+
const { existsSync, readFileSync } = require('fs')
|
|
8
|
+
const { join } = require('path')
|
|
8
9
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
let
|
|
10
|
+
const { platform, arch } = process
|
|
11
|
+
|
|
12
|
+
let nativeBinding = null
|
|
13
|
+
let localFileExisted = false
|
|
14
|
+
let loadError = null
|
|
12
15
|
|
|
13
16
|
function isMusl() {
|
|
14
|
-
// For Node
|
|
17
|
+
// For Node 10
|
|
15
18
|
if (!process.report || typeof process.report.getReport !== 'function') {
|
|
16
19
|
try {
|
|
17
|
-
const lddPath = require('child_process')
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
return readFileSync(lddPath, 'utf8').includes('musl');
|
|
22
|
-
} catch {
|
|
23
|
-
return true;
|
|
20
|
+
const lddPath = require('child_process').execSync('which ldd').toString().trim()
|
|
21
|
+
return readFileSync(lddPath, 'utf8').includes('musl')
|
|
22
|
+
} catch (e) {
|
|
23
|
+
return true
|
|
24
24
|
}
|
|
25
25
|
} else {
|
|
26
|
-
const
|
|
27
|
-
|
|
28
|
-
return !rep.header.glibcVersionRuntime;
|
|
26
|
+
const { glibcVersionRuntime } = process.report.getReport().header
|
|
27
|
+
return !glibcVersionRuntime
|
|
29
28
|
}
|
|
30
29
|
}
|
|
31
30
|
|
|
32
31
|
switch (platform) {
|
|
33
|
-
case '
|
|
32
|
+
case 'android':
|
|
33
|
+
switch (arch) {
|
|
34
|
+
case 'arm64':
|
|
35
|
+
localFileExisted = existsSync(join(__dirname, 'index.android-arm64.node'))
|
|
36
|
+
try {
|
|
37
|
+
if (localFileExisted) {
|
|
38
|
+
nativeBinding = require('./index.android-arm64.node')
|
|
39
|
+
} else {
|
|
40
|
+
nativeBinding = require('@ruvector/rvf-node-android-arm64')
|
|
41
|
+
}
|
|
42
|
+
} catch (e) {
|
|
43
|
+
loadError = e
|
|
44
|
+
}
|
|
45
|
+
break
|
|
46
|
+
case 'arm':
|
|
47
|
+
localFileExisted = existsSync(join(__dirname, 'index.android-arm-eabi.node'))
|
|
48
|
+
try {
|
|
49
|
+
if (localFileExisted) {
|
|
50
|
+
nativeBinding = require('./index.android-arm-eabi.node')
|
|
51
|
+
} else {
|
|
52
|
+
nativeBinding = require('@ruvector/rvf-node-android-arm-eabi')
|
|
53
|
+
}
|
|
54
|
+
} catch (e) {
|
|
55
|
+
loadError = e
|
|
56
|
+
}
|
|
57
|
+
break
|
|
58
|
+
default:
|
|
59
|
+
throw new Error(`Unsupported architecture on Android ${arch}`)
|
|
60
|
+
}
|
|
61
|
+
break
|
|
62
|
+
case 'win32':
|
|
34
63
|
switch (arch) {
|
|
35
64
|
case 'x64':
|
|
36
|
-
localFileExisted = existsSync(
|
|
65
|
+
localFileExisted = existsSync(
|
|
66
|
+
join(__dirname, 'index.win32-x64-msvc.node')
|
|
67
|
+
)
|
|
37
68
|
try {
|
|
38
69
|
if (localFileExisted) {
|
|
39
|
-
nativeBinding = require('./
|
|
70
|
+
nativeBinding = require('./index.win32-x64-msvc.node')
|
|
40
71
|
} else {
|
|
41
|
-
nativeBinding = require('@ruvector/rvf-node-
|
|
72
|
+
nativeBinding = require('@ruvector/rvf-node-win32-x64-msvc')
|
|
42
73
|
}
|
|
43
74
|
} catch (e) {
|
|
44
|
-
loadError = e
|
|
75
|
+
loadError = e
|
|
45
76
|
}
|
|
46
|
-
break
|
|
77
|
+
break
|
|
78
|
+
case 'ia32':
|
|
79
|
+
localFileExisted = existsSync(
|
|
80
|
+
join(__dirname, 'index.win32-ia32-msvc.node')
|
|
81
|
+
)
|
|
82
|
+
try {
|
|
83
|
+
if (localFileExisted) {
|
|
84
|
+
nativeBinding = require('./index.win32-ia32-msvc.node')
|
|
85
|
+
} else {
|
|
86
|
+
nativeBinding = require('@ruvector/rvf-node-win32-ia32-msvc')
|
|
87
|
+
}
|
|
88
|
+
} catch (e) {
|
|
89
|
+
loadError = e
|
|
90
|
+
}
|
|
91
|
+
break
|
|
47
92
|
case 'arm64':
|
|
48
|
-
localFileExisted = existsSync(
|
|
93
|
+
localFileExisted = existsSync(
|
|
94
|
+
join(__dirname, 'index.win32-arm64-msvc.node')
|
|
95
|
+
)
|
|
49
96
|
try {
|
|
50
97
|
if (localFileExisted) {
|
|
51
|
-
nativeBinding = require('./
|
|
98
|
+
nativeBinding = require('./index.win32-arm64-msvc.node')
|
|
52
99
|
} else {
|
|
53
|
-
nativeBinding = require('@ruvector/rvf-node-
|
|
100
|
+
nativeBinding = require('@ruvector/rvf-node-win32-arm64-msvc')
|
|
54
101
|
}
|
|
55
102
|
} catch (e) {
|
|
56
|
-
loadError = e
|
|
103
|
+
loadError = e
|
|
57
104
|
}
|
|
58
|
-
break
|
|
105
|
+
break
|
|
59
106
|
default:
|
|
60
|
-
throw new Error(`Unsupported architecture on
|
|
107
|
+
throw new Error(`Unsupported architecture on Windows: ${arch}`)
|
|
61
108
|
}
|
|
62
|
-
break
|
|
63
|
-
case '
|
|
109
|
+
break
|
|
110
|
+
case 'darwin':
|
|
111
|
+
localFileExisted = existsSync(join(__dirname, 'index.darwin-universal.node'))
|
|
112
|
+
try {
|
|
113
|
+
if (localFileExisted) {
|
|
114
|
+
nativeBinding = require('./index.darwin-universal.node')
|
|
115
|
+
} else {
|
|
116
|
+
nativeBinding = require('@ruvector/rvf-node-darwin-universal')
|
|
117
|
+
}
|
|
118
|
+
break
|
|
119
|
+
} catch {}
|
|
64
120
|
switch (arch) {
|
|
65
121
|
case 'x64':
|
|
66
|
-
localFileExisted = existsSync(join(__dirname, '
|
|
122
|
+
localFileExisted = existsSync(join(__dirname, 'index.darwin-x64.node'))
|
|
67
123
|
try {
|
|
68
124
|
if (localFileExisted) {
|
|
69
|
-
nativeBinding = require('./
|
|
125
|
+
nativeBinding = require('./index.darwin-x64.node')
|
|
70
126
|
} else {
|
|
71
|
-
nativeBinding = require('@ruvector/rvf-node-
|
|
127
|
+
nativeBinding = require('@ruvector/rvf-node-darwin-x64')
|
|
72
128
|
}
|
|
73
129
|
} catch (e) {
|
|
74
|
-
loadError = e
|
|
130
|
+
loadError = e
|
|
75
131
|
}
|
|
76
|
-
break
|
|
132
|
+
break
|
|
133
|
+
case 'arm64':
|
|
134
|
+
localFileExisted = existsSync(
|
|
135
|
+
join(__dirname, 'index.darwin-arm64.node')
|
|
136
|
+
)
|
|
137
|
+
try {
|
|
138
|
+
if (localFileExisted) {
|
|
139
|
+
nativeBinding = require('./index.darwin-arm64.node')
|
|
140
|
+
} else {
|
|
141
|
+
nativeBinding = require('@ruvector/rvf-node-darwin-arm64')
|
|
142
|
+
}
|
|
143
|
+
} catch (e) {
|
|
144
|
+
loadError = e
|
|
145
|
+
}
|
|
146
|
+
break
|
|
77
147
|
default:
|
|
78
|
-
throw new Error(`Unsupported architecture on
|
|
148
|
+
throw new Error(`Unsupported architecture on macOS: ${arch}`)
|
|
149
|
+
}
|
|
150
|
+
break
|
|
151
|
+
case 'freebsd':
|
|
152
|
+
if (arch !== 'x64') {
|
|
153
|
+
throw new Error(`Unsupported architecture on FreeBSD: ${arch}`)
|
|
154
|
+
}
|
|
155
|
+
localFileExisted = existsSync(join(__dirname, 'index.freebsd-x64.node'))
|
|
156
|
+
try {
|
|
157
|
+
if (localFileExisted) {
|
|
158
|
+
nativeBinding = require('./index.freebsd-x64.node')
|
|
159
|
+
} else {
|
|
160
|
+
nativeBinding = require('@ruvector/rvf-node-freebsd-x64')
|
|
161
|
+
}
|
|
162
|
+
} catch (e) {
|
|
163
|
+
loadError = e
|
|
79
164
|
}
|
|
80
|
-
break
|
|
165
|
+
break
|
|
81
166
|
case 'linux':
|
|
82
167
|
switch (arch) {
|
|
83
168
|
case 'x64':
|
|
84
169
|
if (isMusl()) {
|
|
85
|
-
localFileExisted = existsSync(
|
|
170
|
+
localFileExisted = existsSync(
|
|
171
|
+
join(__dirname, 'index.linux-x64-musl.node')
|
|
172
|
+
)
|
|
86
173
|
try {
|
|
87
174
|
if (localFileExisted) {
|
|
88
|
-
nativeBinding = require('./
|
|
175
|
+
nativeBinding = require('./index.linux-x64-musl.node')
|
|
89
176
|
} else {
|
|
90
|
-
nativeBinding = require('@ruvector/rvf-node-linux-x64-musl')
|
|
177
|
+
nativeBinding = require('@ruvector/rvf-node-linux-x64-musl')
|
|
91
178
|
}
|
|
92
179
|
} catch (e) {
|
|
93
|
-
loadError = e
|
|
180
|
+
loadError = e
|
|
94
181
|
}
|
|
95
182
|
} else {
|
|
96
|
-
localFileExisted = existsSync(
|
|
183
|
+
localFileExisted = existsSync(
|
|
184
|
+
join(__dirname, 'index.linux-x64-gnu.node')
|
|
185
|
+
)
|
|
97
186
|
try {
|
|
98
187
|
if (localFileExisted) {
|
|
99
|
-
nativeBinding = require('./
|
|
188
|
+
nativeBinding = require('./index.linux-x64-gnu.node')
|
|
100
189
|
} else {
|
|
101
|
-
nativeBinding = require('@ruvector/rvf-node-linux-x64-gnu')
|
|
190
|
+
nativeBinding = require('@ruvector/rvf-node-linux-x64-gnu')
|
|
102
191
|
}
|
|
103
192
|
} catch (e) {
|
|
104
|
-
loadError = e
|
|
193
|
+
loadError = e
|
|
105
194
|
}
|
|
106
195
|
}
|
|
107
|
-
break
|
|
196
|
+
break
|
|
108
197
|
case 'arm64':
|
|
109
198
|
if (isMusl()) {
|
|
110
|
-
localFileExisted = existsSync(
|
|
199
|
+
localFileExisted = existsSync(
|
|
200
|
+
join(__dirname, 'index.linux-arm64-musl.node')
|
|
201
|
+
)
|
|
111
202
|
try {
|
|
112
203
|
if (localFileExisted) {
|
|
113
|
-
nativeBinding = require('./
|
|
204
|
+
nativeBinding = require('./index.linux-arm64-musl.node')
|
|
114
205
|
} else {
|
|
115
|
-
nativeBinding = require('@ruvector/rvf-node-linux-arm64-musl')
|
|
206
|
+
nativeBinding = require('@ruvector/rvf-node-linux-arm64-musl')
|
|
116
207
|
}
|
|
117
208
|
} catch (e) {
|
|
118
|
-
loadError = e
|
|
209
|
+
loadError = e
|
|
119
210
|
}
|
|
120
211
|
} else {
|
|
121
|
-
localFileExisted = existsSync(
|
|
212
|
+
localFileExisted = existsSync(
|
|
213
|
+
join(__dirname, 'index.linux-arm64-gnu.node')
|
|
214
|
+
)
|
|
215
|
+
try {
|
|
216
|
+
if (localFileExisted) {
|
|
217
|
+
nativeBinding = require('./index.linux-arm64-gnu.node')
|
|
218
|
+
} else {
|
|
219
|
+
nativeBinding = require('@ruvector/rvf-node-linux-arm64-gnu')
|
|
220
|
+
}
|
|
221
|
+
} catch (e) {
|
|
222
|
+
loadError = e
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
break
|
|
226
|
+
case 'arm':
|
|
227
|
+
if (isMusl()) {
|
|
228
|
+
localFileExisted = existsSync(
|
|
229
|
+
join(__dirname, 'index.linux-arm-musleabihf.node')
|
|
230
|
+
)
|
|
122
231
|
try {
|
|
123
232
|
if (localFileExisted) {
|
|
124
|
-
nativeBinding = require('./
|
|
233
|
+
nativeBinding = require('./index.linux-arm-musleabihf.node')
|
|
125
234
|
} else {
|
|
126
|
-
nativeBinding = require('@ruvector/rvf-node-linux-
|
|
235
|
+
nativeBinding = require('@ruvector/rvf-node-linux-arm-musleabihf')
|
|
127
236
|
}
|
|
128
237
|
} catch (e) {
|
|
129
|
-
loadError = e
|
|
238
|
+
loadError = e
|
|
130
239
|
}
|
|
240
|
+
} else {
|
|
241
|
+
localFileExisted = existsSync(
|
|
242
|
+
join(__dirname, 'index.linux-arm-gnueabihf.node')
|
|
243
|
+
)
|
|
244
|
+
try {
|
|
245
|
+
if (localFileExisted) {
|
|
246
|
+
nativeBinding = require('./index.linux-arm-gnueabihf.node')
|
|
247
|
+
} else {
|
|
248
|
+
nativeBinding = require('@ruvector/rvf-node-linux-arm-gnueabihf')
|
|
249
|
+
}
|
|
250
|
+
} catch (e) {
|
|
251
|
+
loadError = e
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
break
|
|
255
|
+
case 'riscv64':
|
|
256
|
+
if (isMusl()) {
|
|
257
|
+
localFileExisted = existsSync(
|
|
258
|
+
join(__dirname, 'index.linux-riscv64-musl.node')
|
|
259
|
+
)
|
|
260
|
+
try {
|
|
261
|
+
if (localFileExisted) {
|
|
262
|
+
nativeBinding = require('./index.linux-riscv64-musl.node')
|
|
263
|
+
} else {
|
|
264
|
+
nativeBinding = require('@ruvector/rvf-node-linux-riscv64-musl')
|
|
265
|
+
}
|
|
266
|
+
} catch (e) {
|
|
267
|
+
loadError = e
|
|
268
|
+
}
|
|
269
|
+
} else {
|
|
270
|
+
localFileExisted = existsSync(
|
|
271
|
+
join(__dirname, 'index.linux-riscv64-gnu.node')
|
|
272
|
+
)
|
|
273
|
+
try {
|
|
274
|
+
if (localFileExisted) {
|
|
275
|
+
nativeBinding = require('./index.linux-riscv64-gnu.node')
|
|
276
|
+
} else {
|
|
277
|
+
nativeBinding = require('@ruvector/rvf-node-linux-riscv64-gnu')
|
|
278
|
+
}
|
|
279
|
+
} catch (e) {
|
|
280
|
+
loadError = e
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
break
|
|
284
|
+
case 's390x':
|
|
285
|
+
localFileExisted = existsSync(
|
|
286
|
+
join(__dirname, 'index.linux-s390x-gnu.node')
|
|
287
|
+
)
|
|
288
|
+
try {
|
|
289
|
+
if (localFileExisted) {
|
|
290
|
+
nativeBinding = require('./index.linux-s390x-gnu.node')
|
|
291
|
+
} else {
|
|
292
|
+
nativeBinding = require('@ruvector/rvf-node-linux-s390x-gnu')
|
|
293
|
+
}
|
|
294
|
+
} catch (e) {
|
|
295
|
+
loadError = e
|
|
131
296
|
}
|
|
132
|
-
break
|
|
297
|
+
break
|
|
133
298
|
default:
|
|
134
|
-
throw new Error(`Unsupported architecture on Linux: ${arch}`)
|
|
299
|
+
throw new Error(`Unsupported architecture on Linux: ${arch}`)
|
|
135
300
|
}
|
|
136
|
-
break
|
|
301
|
+
break
|
|
137
302
|
default:
|
|
138
|
-
throw new Error(`Unsupported OS: ${platform}, architecture: ${arch}`)
|
|
303
|
+
throw new Error(`Unsupported OS: ${platform}, architecture: ${arch}`)
|
|
139
304
|
}
|
|
140
305
|
|
|
141
306
|
if (!nativeBinding) {
|
|
142
307
|
if (loadError) {
|
|
143
|
-
throw loadError
|
|
308
|
+
throw loadError
|
|
144
309
|
}
|
|
145
|
-
throw new Error(
|
|
310
|
+
throw new Error(`Failed to load native binding`)
|
|
146
311
|
}
|
|
147
312
|
|
|
148
|
-
const { RvfDatabase } = nativeBinding
|
|
313
|
+
const { RvfDatabase } = nativeBinding
|
|
149
314
|
|
|
150
|
-
module.exports.RvfDatabase = RvfDatabase
|
|
315
|
+
module.exports.RvfDatabase = RvfDatabase
|
package/package.json
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ruvector/rvf-node",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.1",
|
|
4
4
|
"description": "RuVector Format Node.js native bindings",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"types": "index.d.ts",
|
|
7
7
|
"files": [
|
|
8
8
|
"index.js",
|
|
9
9
|
"index.d.ts",
|
|
10
|
-
"
|
|
10
|
+
"README.md",
|
|
11
|
+
"package.json"
|
|
11
12
|
],
|
|
12
13
|
"napi": {
|
|
13
14
|
"binaryName": "rvf-node",
|
|
@@ -20,25 +21,16 @@
|
|
|
20
21
|
]
|
|
21
22
|
},
|
|
22
23
|
"scripts": {
|
|
23
|
-
"build": "napi build --platform --release"
|
|
24
|
+
"build": "napi build --platform --release",
|
|
25
|
+
"prepublishOnly": "napi prepublish -t npm"
|
|
24
26
|
},
|
|
25
27
|
"license": "MIT",
|
|
26
|
-
"
|
|
27
|
-
"
|
|
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"
|
|
28
|
+
"devDependencies": {
|
|
29
|
+
"@napi-rs/cli": "^2.18.0"
|
|
36
30
|
},
|
|
37
31
|
"optionalDependencies": {
|
|
38
|
-
"@ruvector/rvf-node-
|
|
39
|
-
"@ruvector/rvf-node-darwin-x64": "0.1
|
|
40
|
-
"@ruvector/rvf-node-
|
|
41
|
-
"@ruvector/rvf-node-win32-x64-msvc": "0.1.7",
|
|
42
|
-
"@ruvector/rvf-node-linux-arm64-gnu": "0.1.7"
|
|
32
|
+
"@ruvector/rvf-node-win32-x64-msvc": "0.2.1",
|
|
33
|
+
"@ruvector/rvf-node-darwin-x64": "0.2.1",
|
|
34
|
+
"@ruvector/rvf-node-linux-x64-gnu": "0.2.1"
|
|
43
35
|
}
|
|
44
|
-
}
|
|
36
|
+
}
|
|
Binary file
|
package/rvf-node.darwin-x64.node
DELETED
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|