ruvector 0.1.27 → 0.1.29
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.
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
|
-
"startTime":
|
|
3
|
-
"sessionId": "session-
|
|
4
|
-
"lastActivity":
|
|
2
|
+
"startTime": 1764782629252,
|
|
3
|
+
"sessionId": "session-1764782629252",
|
|
4
|
+
"lastActivity": 1764782629252,
|
|
5
5
|
"sessionDuration": 0,
|
|
6
6
|
"totalTasks": 1,
|
|
7
7
|
"successfulTasks": 1,
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
[
|
|
2
2
|
{
|
|
3
|
-
"id": "cmd-hooks-
|
|
3
|
+
"id": "cmd-hooks-1764782629353",
|
|
4
4
|
"type": "hooks",
|
|
5
5
|
"success": true,
|
|
6
|
-
"duration": 6.
|
|
7
|
-
"timestamp":
|
|
6
|
+
"duration": 6.606119999999976,
|
|
7
|
+
"timestamp": 1764782629360,
|
|
8
8
|
"metadata": {}
|
|
9
9
|
}
|
|
10
10
|
]
|
|
@@ -4,9 +4,26 @@
|
|
|
4
4
|
* This wrapper handles the array type conversion automatically, allowing users
|
|
5
5
|
* to pass either regular arrays or Float32Arrays.
|
|
6
6
|
*
|
|
7
|
-
* @ruvector/gnn requires
|
|
8
|
-
* This wrapper
|
|
7
|
+
* The native @ruvector/gnn requires Float32Array for maximum performance.
|
|
8
|
+
* This wrapper converts any input type to Float32Array automatically.
|
|
9
|
+
*
|
|
10
|
+
* Performance Tips:
|
|
11
|
+
* - Pass Float32Array directly for zero-copy performance
|
|
12
|
+
* - Use toFloat32Array/toFloat32ArrayBatch for pre-conversion
|
|
13
|
+
* - Avoid repeated conversions in hot paths
|
|
14
|
+
*/
|
|
15
|
+
/**
|
|
16
|
+
* Convert any array-like input to Float32Array (native requires Float32Array)
|
|
17
|
+
* Optimized paths:
|
|
18
|
+
* - Float32Array: zero-copy return
|
|
19
|
+
* - Float64Array: efficient typed array copy
|
|
20
|
+
* - Array: direct Float32Array construction
|
|
21
|
+
*/
|
|
22
|
+
export declare function toFloat32Array(input: number[] | Float32Array | Float64Array): Float32Array;
|
|
23
|
+
/**
|
|
24
|
+
* Convert array of arrays to array of Float32Arrays
|
|
9
25
|
*/
|
|
26
|
+
export declare function toFloat32ArrayBatch(input: (number[] | Float32Array | Float64Array)[]): Float32Array[];
|
|
10
27
|
/**
|
|
11
28
|
* Search result from differentiable search
|
|
12
29
|
*/
|
|
@@ -31,10 +48,10 @@ export interface DifferentiableSearchResult {
|
|
|
31
48
|
* ```typescript
|
|
32
49
|
* import { differentiableSearch } from 'ruvector/core/gnn-wrapper';
|
|
33
50
|
*
|
|
34
|
-
* // Works with regular arrays
|
|
51
|
+
* // Works with regular arrays (auto-converted to Float32Array)
|
|
35
52
|
* const result1 = differentiableSearch([1, 0, 0], [[1, 0, 0], [0, 1, 0]], 2, 1.0);
|
|
36
53
|
*
|
|
37
|
-
* //
|
|
54
|
+
* // For best performance, use Float32Array directly (zero-copy)
|
|
38
55
|
* const query = new Float32Array([1, 0, 0]);
|
|
39
56
|
* const candidates = [new Float32Array([1, 0, 0]), new Float32Array([0, 1, 0])];
|
|
40
57
|
* const result2 = differentiableSearch(query, candidates, 2, 1.0);
|
|
@@ -61,9 +78,9 @@ export declare class RuvectorLayer {
|
|
|
61
78
|
* @param nodeEmbedding - Current node's embedding
|
|
62
79
|
* @param neighborEmbeddings - Embeddings of neighbor nodes
|
|
63
80
|
* @param edgeWeights - Weights of edges to neighbors
|
|
64
|
-
* @returns Updated node embedding
|
|
81
|
+
* @returns Updated node embedding as Float32Array
|
|
65
82
|
*/
|
|
66
|
-
forward(nodeEmbedding: number[] | Float32Array, neighborEmbeddings: (number[] | Float32Array)[], edgeWeights: number[] | Float32Array):
|
|
83
|
+
forward(nodeEmbedding: number[] | Float32Array, neighborEmbeddings: (number[] | Float32Array)[], edgeWeights: number[] | Float32Array): Float32Array;
|
|
67
84
|
/**
|
|
68
85
|
* Serialize the layer to JSON
|
|
69
86
|
*/
|
|
@@ -101,9 +118,9 @@ export declare class TensorCompress {
|
|
|
101
118
|
* @param query - Query vector
|
|
102
119
|
* @param layerEmbeddings - Embeddings organized by layer
|
|
103
120
|
* @param gnnLayersJson - JSON array of serialized GNN layers
|
|
104
|
-
* @returns Final embedding after hierarchical processing
|
|
121
|
+
* @returns Final embedding after hierarchical processing as Float32Array
|
|
105
122
|
*/
|
|
106
|
-
export declare function hierarchicalForward(query: number[] | Float32Array, layerEmbeddings: (number[] | Float32Array)[][], gnnLayersJson: string[]):
|
|
123
|
+
export declare function hierarchicalForward(query: number[] | Float32Array, layerEmbeddings: (number[] | Float32Array)[][], gnnLayersJson: string[]): Float32Array;
|
|
107
124
|
/**
|
|
108
125
|
* Get compression level for a given access frequency
|
|
109
126
|
*/
|
|
@@ -119,6 +136,8 @@ declare const _default: {
|
|
|
119
136
|
hierarchicalForward: typeof hierarchicalForward;
|
|
120
137
|
getCompressionLevel: typeof getCompressionLevel;
|
|
121
138
|
isGnnAvailable: typeof isGnnAvailable;
|
|
139
|
+
toFloat32Array: typeof toFloat32Array;
|
|
140
|
+
toFloat32ArrayBatch: typeof toFloat32ArrayBatch;
|
|
122
141
|
};
|
|
123
142
|
export default _default;
|
|
124
143
|
//# sourceMappingURL=gnn-wrapper.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gnn-wrapper.d.ts","sourceRoot":"","sources":["../../src/core/gnn-wrapper.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"gnn-wrapper.d.ts","sourceRoot":"","sources":["../../src/core/gnn-wrapper.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAsBH;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,YAAY,GAAG,YAAY,GAAG,YAAY,CAK1F;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,CAAC,MAAM,EAAE,GAAG,YAAY,GAAG,YAAY,CAAC,EAAE,GAAG,YAAY,EAAE,CAMrG;AAED;;GAEG;AACH,MAAM,WAAW,0BAA0B;IACzC,kCAAkC;IAClC,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,wCAAwC;IACxC,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,MAAM,EAAE,GAAG,YAAY,GAAG,YAAY,EAC7C,UAAU,EAAE,CAAC,MAAM,EAAE,GAAG,YAAY,GAAG,YAAY,CAAC,EAAE,EACtD,CAAC,EAAE,MAAM,EACT,WAAW,GAAE,MAAY,GACxB,0BAA0B,CAQ5B;AAED;;GAEG;AACH,qBAAa,aAAa;IACxB,OAAO,CAAC,KAAK,CAAM;IAEnB;;;;;;;OAOG;gBACS,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,GAAE,MAAY;IAKrF;;;;;;;OAOG;IACH,OAAO,CACL,aAAa,EAAE,MAAM,EAAE,GAAG,YAAY,EACtC,kBAAkB,EAAE,CAAC,MAAM,EAAE,GAAG,YAAY,CAAC,EAAE,EAC/C,WAAW,EAAE,MAAM,EAAE,GAAG,YAAY,GACnC,YAAY;IAQf;;OAEG;IACH,MAAM,IAAI,MAAM;IAIhB;;OAEG;IACH,MAAM,CAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,aAAa;CAM7C;AAED;;GAEG;AACH,qBAAa,cAAc;IACzB,OAAO,CAAC,KAAK,CAAM;;IAOnB;;;;;;OAMG;IACH,QAAQ,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,YAAY,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM;IAIxE;;;;;OAKG;IACH,UAAU,CAAC,cAAc,EAAE,MAAM,GAAG,MAAM,EAAE;CAG7C;AAED;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,MAAM,EAAE,GAAG,YAAY,EAC9B,eAAe,EAAE,CAAC,MAAM,EAAE,GAAG,YAAY,CAAC,EAAE,EAAE,EAC9C,aAAa,EAAE,MAAM,EAAE,GACtB,YAAY,CAOd;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAG9D;AAED;;GAEG;AACH,wBAAgB,cAAc,IAAI,OAAO,CAOxC;;;;;;;;;;;AAED,wBAUE"}
|
package/dist/core/gnn-wrapper.js
CHANGED
|
@@ -5,11 +5,18 @@
|
|
|
5
5
|
* This wrapper handles the array type conversion automatically, allowing users
|
|
6
6
|
* to pass either regular arrays or Float32Arrays.
|
|
7
7
|
*
|
|
8
|
-
* @ruvector/gnn requires
|
|
9
|
-
* This wrapper
|
|
8
|
+
* The native @ruvector/gnn requires Float32Array for maximum performance.
|
|
9
|
+
* This wrapper converts any input type to Float32Array automatically.
|
|
10
|
+
*
|
|
11
|
+
* Performance Tips:
|
|
12
|
+
* - Pass Float32Array directly for zero-copy performance
|
|
13
|
+
* - Use toFloat32Array/toFloat32ArrayBatch for pre-conversion
|
|
14
|
+
* - Avoid repeated conversions in hot paths
|
|
10
15
|
*/
|
|
11
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
17
|
exports.TensorCompress = exports.RuvectorLayer = void 0;
|
|
18
|
+
exports.toFloat32Array = toFloat32Array;
|
|
19
|
+
exports.toFloat32ArrayBatch = toFloat32ArrayBatch;
|
|
13
20
|
exports.differentiableSearch = differentiableSearch;
|
|
14
21
|
exports.hierarchicalForward = hierarchicalForward;
|
|
15
22
|
exports.getCompressionLevel = getCompressionLevel;
|
|
@@ -33,19 +40,30 @@ function getGnnModule() {
|
|
|
33
40
|
}
|
|
34
41
|
}
|
|
35
42
|
/**
|
|
36
|
-
* Convert any array-like input to
|
|
43
|
+
* Convert any array-like input to Float32Array (native requires Float32Array)
|
|
44
|
+
* Optimized paths:
|
|
45
|
+
* - Float32Array: zero-copy return
|
|
46
|
+
* - Float64Array: efficient typed array copy
|
|
47
|
+
* - Array: direct Float32Array construction
|
|
37
48
|
*/
|
|
38
|
-
function
|
|
39
|
-
if (
|
|
49
|
+
function toFloat32Array(input) {
|
|
50
|
+
if (input instanceof Float32Array)
|
|
40
51
|
return input;
|
|
41
|
-
|
|
42
|
-
|
|
52
|
+
if (input instanceof Float64Array)
|
|
53
|
+
return new Float32Array(input);
|
|
54
|
+
if (Array.isArray(input))
|
|
55
|
+
return new Float32Array(input);
|
|
56
|
+
return new Float32Array(Array.from(input));
|
|
43
57
|
}
|
|
44
58
|
/**
|
|
45
|
-
* Convert
|
|
59
|
+
* Convert array of arrays to array of Float32Arrays
|
|
46
60
|
*/
|
|
47
|
-
function
|
|
48
|
-
|
|
61
|
+
function toFloat32ArrayBatch(input) {
|
|
62
|
+
const result = new Array(input.length);
|
|
63
|
+
for (let i = 0; i < input.length; i++) {
|
|
64
|
+
result[i] = toFloat32Array(input[i]);
|
|
65
|
+
}
|
|
66
|
+
return result;
|
|
49
67
|
}
|
|
50
68
|
/**
|
|
51
69
|
* Differentiable search using soft attention mechanism
|
|
@@ -62,10 +80,10 @@ function toNestedArray(input) {
|
|
|
62
80
|
* ```typescript
|
|
63
81
|
* import { differentiableSearch } from 'ruvector/core/gnn-wrapper';
|
|
64
82
|
*
|
|
65
|
-
* // Works with regular arrays
|
|
83
|
+
* // Works with regular arrays (auto-converted to Float32Array)
|
|
66
84
|
* const result1 = differentiableSearch([1, 0, 0], [[1, 0, 0], [0, 1, 0]], 2, 1.0);
|
|
67
85
|
*
|
|
68
|
-
* //
|
|
86
|
+
* // For best performance, use Float32Array directly (zero-copy)
|
|
69
87
|
* const query = new Float32Array([1, 0, 0]);
|
|
70
88
|
* const candidates = [new Float32Array([1, 0, 0]), new Float32Array([0, 1, 0])];
|
|
71
89
|
* const result2 = differentiableSearch(query, candidates, 2, 1.0);
|
|
@@ -73,10 +91,10 @@ function toNestedArray(input) {
|
|
|
73
91
|
*/
|
|
74
92
|
function differentiableSearch(query, candidates, k, temperature = 1.0) {
|
|
75
93
|
const gnn = getGnnModule();
|
|
76
|
-
// Convert to
|
|
77
|
-
const
|
|
78
|
-
const
|
|
79
|
-
return gnn.differentiableSearch(
|
|
94
|
+
// Convert to Float32Array (native Rust expects Float32Array for performance)
|
|
95
|
+
const queryFloat32 = toFloat32Array(query);
|
|
96
|
+
const candidatesFloat32 = toFloat32ArrayBatch(candidates);
|
|
97
|
+
return gnn.differentiableSearch(queryFloat32, candidatesFloat32, k, temperature);
|
|
80
98
|
}
|
|
81
99
|
/**
|
|
82
100
|
* GNN Layer for HNSW topology
|
|
@@ -100,10 +118,10 @@ class RuvectorLayer {
|
|
|
100
118
|
* @param nodeEmbedding - Current node's embedding
|
|
101
119
|
* @param neighborEmbeddings - Embeddings of neighbor nodes
|
|
102
120
|
* @param edgeWeights - Weights of edges to neighbors
|
|
103
|
-
* @returns Updated node embedding
|
|
121
|
+
* @returns Updated node embedding as Float32Array
|
|
104
122
|
*/
|
|
105
123
|
forward(nodeEmbedding, neighborEmbeddings, edgeWeights) {
|
|
106
|
-
return this.inner.forward(
|
|
124
|
+
return this.inner.forward(toFloat32Array(nodeEmbedding), toFloat32ArrayBatch(neighborEmbeddings), toFloat32Array(edgeWeights));
|
|
107
125
|
}
|
|
108
126
|
/**
|
|
109
127
|
* Serialize the layer to JSON
|
|
@@ -138,7 +156,7 @@ class TensorCompress {
|
|
|
138
156
|
* @returns Compressed tensor as JSON string
|
|
139
157
|
*/
|
|
140
158
|
compress(embedding, accessFreq) {
|
|
141
|
-
return this.inner.compress(
|
|
159
|
+
return this.inner.compress(toFloat32Array(embedding), accessFreq);
|
|
142
160
|
}
|
|
143
161
|
/**
|
|
144
162
|
* Decompress a compressed tensor
|
|
@@ -157,11 +175,11 @@ exports.TensorCompress = TensorCompress;
|
|
|
157
175
|
* @param query - Query vector
|
|
158
176
|
* @param layerEmbeddings - Embeddings organized by layer
|
|
159
177
|
* @param gnnLayersJson - JSON array of serialized GNN layers
|
|
160
|
-
* @returns Final embedding after hierarchical processing
|
|
178
|
+
* @returns Final embedding after hierarchical processing as Float32Array
|
|
161
179
|
*/
|
|
162
180
|
function hierarchicalForward(query, layerEmbeddings, gnnLayersJson) {
|
|
163
181
|
const gnn = getGnnModule();
|
|
164
|
-
return gnn.hierarchicalForward(
|
|
182
|
+
return gnn.hierarchicalForward(toFloat32Array(query), layerEmbeddings.map(layer => toFloat32ArrayBatch(layer)), gnnLayersJson);
|
|
165
183
|
}
|
|
166
184
|
/**
|
|
167
185
|
* Get compression level for a given access frequency
|
|
@@ -189,4 +207,7 @@ exports.default = {
|
|
|
189
207
|
hierarchicalForward,
|
|
190
208
|
getCompressionLevel,
|
|
191
209
|
isGnnAvailable,
|
|
210
|
+
// Export conversion helpers for performance optimization
|
|
211
|
+
toFloat32Array,
|
|
212
|
+
toFloat32ArrayBatch,
|
|
192
213
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ruvector",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.29",
|
|
4
4
|
"description": "High-performance vector database for Node.js with automatic native/WASM fallback",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -53,13 +53,13 @@
|
|
|
53
53
|
},
|
|
54
54
|
"dependencies": {
|
|
55
55
|
"@ruvector/core": "^0.1.16",
|
|
56
|
-
"@ruvector/gnn": "^0.1.
|
|
56
|
+
"@ruvector/gnn": "^0.1.22",
|
|
57
57
|
"chalk": "^4.1.2",
|
|
58
58
|
"commander": "^11.1.0",
|
|
59
59
|
"ora": "^5.4.1"
|
|
60
60
|
},
|
|
61
61
|
"optionalDependencies": {
|
|
62
|
-
"@ruvector/attention": "^0.1.
|
|
62
|
+
"@ruvector/attention": "^0.1.3",
|
|
63
63
|
"@ruvector/sona": "^0.1.3"
|
|
64
64
|
},
|
|
65
65
|
"devDependencies": {
|