/* tslint:disable */ /* eslint-disable */ /* prettier-ignore */ /* auto-generated by NAPI-RS */ const { existsSync, readFileSync } = require('fs') const { join } = require('path') const { platform, arch } = process let nativeBinding = null let localFileExisted = false let loadError = null function isMusl() { // For Node 10 if (!process.report || typeof process.report.getReport !== 'function') { try { const lddPath = require('child_process').execSync('which ldd').toString().trim() return readFileSync(lddPath, 'utf8').includes('musl') } catch (e) { return true } } else { const { glibcVersionRuntime } = process.report.getReport().header return !glibcVersionRuntime } } switch (platform) { case 'android': switch (arch) { case 'arm64': localFileExisted = existsSync(join(__dirname, 'ruvector-gnn.android-arm64.node')) try { if (localFileExisted) { nativeBinding = require('./ruvector-gnn.android-arm64.node') } else { nativeBinding = require('@ruvector/gnn-android-arm64') } } catch (e) { loadError = e } break case 'arm': localFileExisted = existsSync(join(__dirname, 'ruvector-gnn.android-arm-eabi.node')) try { if (localFileExisted) { nativeBinding = require('./ruvector-gnn.android-arm-eabi.node') } else { nativeBinding = require('@ruvector/gnn-android-arm-eabi') } } catch (e) { loadError = e } break default: throw new Error(`Unsupported architecture on Android ${arch}`) } break case 'win32': switch (arch) { case 'x64': localFileExisted = existsSync( join(__dirname, 'ruvector-gnn.win32-x64-msvc.node') ) try { if (localFileExisted) { nativeBinding = require('./ruvector-gnn.win32-x64-msvc.node') } else { nativeBinding = require('@ruvector/gnn-win32-x64-msvc') } } catch (e) { loadError = e } break case 'ia32': localFileExisted = existsSync( join(__dirname, 'ruvector-gnn.win32-ia32-msvc.node') ) try { if (localFileExisted) { nativeBinding = require('./ruvector-gnn.win32-ia32-msvc.node') } else { nativeBinding = require('@ruvector/gnn-win32-ia32-msvc') } } catch (e) { loadError = e } break case 'arm64': localFileExisted = existsSync( join(__dirname, 'ruvector-gnn.win32-arm64-msvc.node') ) try { if (localFileExisted) { nativeBinding = require('./ruvector-gnn.win32-arm64-msvc.node') } else { nativeBinding = require('@ruvector/gnn-win32-arm64-msvc') } } catch (e) { loadError = e } break default: throw new Error(`Unsupported architecture on Windows: ${arch}`) } break case 'darwin': localFileExisted = existsSync(join(__dirname, 'ruvector-gnn.darwin-universal.node')) try { if (localFileExisted) { nativeBinding = require('./ruvector-gnn.darwin-universal.node') } else { nativeBinding = require('@ruvector/gnn-darwin-universal') } break } catch {} switch (arch) { case 'x64': localFileExisted = existsSync(join(__dirname, 'ruvector-gnn.darwin-x64.node')) try { if (localFileExisted) { nativeBinding = require('./ruvector-gnn.darwin-x64.node') } else { nativeBinding = require('@ruvector/gnn-darwin-x64') } } catch (e) { loadError = e } break case 'arm64': localFileExisted = existsSync( join(__dirname, 'ruvector-gnn.darwin-arm64.node') ) try { if (localFileExisted) { nativeBinding = require('./ruvector-gnn.darwin-arm64.node') } else { nativeBinding = require('@ruvector/gnn-darwin-arm64') } } catch (e) { loadError = e } break default: throw new Error(`Unsupported architecture on macOS: ${arch}`) } break case 'freebsd': if (arch !== 'x64') { throw new Error(`Unsupported architecture on FreeBSD: ${arch}`) } localFileExisted = existsSync(join(__dirname, 'ruvector-gnn.freebsd-x64.node')) try { if (localFileExisted) { nativeBinding = require('./ruvector-gnn.freebsd-x64.node') } else { nativeBinding = require('@ruvector/gnn-freebsd-x64') } } catch (e) { loadError = e } break case 'linux': switch (arch) { case 'x64': if (isMusl()) { localFileExisted = existsSync( join(__dirname, 'ruvector-gnn.linux-x64-musl.node') ) try { if (localFileExisted) { nativeBinding = require('./ruvector-gnn.linux-x64-musl.node') } else { nativeBinding = require('@ruvector/gnn-linux-x64-musl') } } catch (e) { loadError = e } } else { localFileExisted = existsSync( join(__dirname, 'ruvector-gnn.linux-x64-gnu.node') ) try { if (localFileExisted) { nativeBinding = require('./ruvector-gnn.linux-x64-gnu.node') } else { nativeBinding = require('@ruvector/gnn-linux-x64-gnu') } } catch (e) { loadError = e } } break case 'arm64': if (isMusl()) { localFileExisted = existsSync( join(__dirname, 'ruvector-gnn.linux-arm64-musl.node') ) try { if (localFileExisted) { nativeBinding = require('./ruvector-gnn.linux-arm64-musl.node') } else { nativeBinding = require('@ruvector/gnn-linux-arm64-musl') } } catch (e) { loadError = e } } else { localFileExisted = existsSync( join(__dirname, 'ruvector-gnn.linux-arm64-gnu.node') ) try { if (localFileExisted) { nativeBinding = require('./ruvector-gnn.linux-arm64-gnu.node') } else { nativeBinding = require('@ruvector/gnn-linux-arm64-gnu') } } catch (e) { loadError = e } } break case 'arm': if (isMusl()) { localFileExisted = existsSync( join(__dirname, 'ruvector-gnn.linux-arm-musleabihf.node') ) try { if (localFileExisted) { nativeBinding = require('./ruvector-gnn.linux-arm-musleabihf.node') } else { nativeBinding = require('@ruvector/gnn-linux-arm-musleabihf') } } catch (e) { loadError = e } } else { localFileExisted = existsSync( join(__dirname, 'ruvector-gnn.linux-arm-gnueabihf.node') ) try { if (localFileExisted) { nativeBinding = require('./ruvector-gnn.linux-arm-gnueabihf.node') } else { nativeBinding = require('@ruvector/gnn-linux-arm-gnueabihf') } } catch (e) { loadError = e } } break case 'riscv64': if (isMusl()) { localFileExisted = existsSync( join(__dirname, 'ruvector-gnn.linux-riscv64-musl.node') ) try { if (localFileExisted) { nativeBinding = require('./ruvector-gnn.linux-riscv64-musl.node') } else { nativeBinding = require('@ruvector/gnn-linux-riscv64-musl') } } catch (e) { loadError = e } } else { localFileExisted = existsSync( join(__dirname, 'ruvector-gnn.linux-riscv64-gnu.node') ) try { if (localFileExisted) { nativeBinding = require('./ruvector-gnn.linux-riscv64-gnu.node') } else { nativeBinding = require('@ruvector/gnn-linux-riscv64-gnu') } } catch (e) { loadError = e } } break case 's390x': localFileExisted = existsSync( join(__dirname, 'ruvector-gnn.linux-s390x-gnu.node') ) try { if (localFileExisted) { nativeBinding = require('./ruvector-gnn.linux-s390x-gnu.node') } else { nativeBinding = require('@ruvector/gnn-linux-s390x-gnu') } } catch (e) { loadError = e } break default: throw new Error(`Unsupported architecture on Linux: ${arch}`) } break default: throw new Error(`Unsupported OS: ${platform}, architecture: ${arch}`) } if (!nativeBinding) { if (loadError) { throw loadError } throw new Error(`Failed to load native binding`) } const { RuvectorLayer: NativeRuvectorLayer, TensorCompress: NativeTensorCompress, differentiableSearch: nativeDifferentiableSearch, hierarchicalForward: nativeHierarchicalForward, getCompressionLevel, init } = nativeBinding // ============================================================================ // Optimized Type Conversion Helpers // The native Rust code expects Float32Array for maximum performance. // These helpers convert any array-like input to Float32Array efficiently. // ============================================================================ /** * Convert any array-like to Float32Array (native Rust expects Float32Array) * Optimized paths: * - Float32Array: zero-copy return * - Float64Array: efficient typed array copy * - Array: direct Float32Array construction * @param {number[] | Float32Array | Float64Array} input * @returns {Float32Array} */ function toFloat32Array(input) { // Fast path: already Float32Array - zero copy if (input instanceof Float32Array) return input // Float64Array: efficient typed array conversion if (input instanceof Float64Array) return new Float32Array(input) // Regular array: direct construction if (Array.isArray(input)) return new Float32Array(input) // Fallback for other array-likes return new Float32Array(Array.from(input)) } /** * Convert array of arrays to array of Float32Arrays * @param {(number[] | Float32Array | Float64Array)[]} input * @returns {Float32Array[]} */ function toFloat32ArrayBatch(input) { const result = new Array(input.length) for (let i = 0; i < input.length; i++) { result[i] = toFloat32Array(input[i]) } return result } /** * Batch convert with pre-allocated buffer for maximum performance * Use when all vectors have the same dimension * @param {(number[] | Float32Array | Float64Array)[]} input * @param {number} dim - Vector dimension * @returns {Float32Array[]} */ function toFloat32ArrayBatchOptimized(input, dim) { const count = input.length const result = new Array(count) for (let i = 0; i < count; i++) { const arr = input[i] if (arr instanceof Float32Array) { result[i] = arr } else if (arr instanceof Float64Array) { result[i] = new Float32Array(arr) } else { result[i] = new Float32Array(arr) } } return result } // ============================================================================ // Wrapper Functions - Accept any array type, convert to Float32Array // ============================================================================ /** * Differentiable search using soft attention mechanism * Accepts regular arrays or typed arrays, converts to Float32Array internally * @param {number[] | Float32Array} query - Query vector * @param {(number[] | Float32Array)[]} candidateEmbeddings - Candidate vectors * @param {number} k - Number of results * @param {number} temperature - Softmax temperature * @returns {{indices: number[], weights: number[]}} */ function differentiableSearch(query, candidateEmbeddings, k, temperature) { return nativeDifferentiableSearch( toFloat32Array(query), toFloat32ArrayBatch(candidateEmbeddings), k, temperature ) } /** * Hierarchical forward pass through GNN layers * @param {number[] | Float32Array} query - Query vector * @param {(number[] | Float32Array)[][]} layerEmbeddings - Embeddings by layer * @param {string[]} gnnLayersJson - Serialized GNN layers * @returns {Float32Array} */ function hierarchicalForward(query, layerEmbeddings, gnnLayersJson) { return nativeHierarchicalForward( toFloat32Array(query), layerEmbeddings.map(layer => toFloat32ArrayBatch(layer)), gnnLayersJson ) } // ============================================================================ // Wrapped Classes // ============================================================================ /** * Graph Neural Network layer for HNSW topology */ class RuvectorLayer { constructor(inputDim, hiddenDim, heads, dropout) { this._native = new NativeRuvectorLayer(inputDim, hiddenDim, heads, dropout) } /** * Forward pass through the GNN layer * @param {number[] | Float32Array} nodeEmbedding - Node embedding * @param {(number[] | Float32Array)[]} neighborEmbeddings - Neighbor embeddings * @param {number[] | Float32Array} edgeWeights - Edge weights * @returns {Float32Array} */ forward(nodeEmbedding, neighborEmbeddings, edgeWeights) { return this._native.forward( toFloat32Array(nodeEmbedding), toFloat32ArrayBatch(neighborEmbeddings), toFloat32Array(edgeWeights) ) } toJson() { return this._native.toJson() } static fromJson(json) { const layer = Object.create(RuvectorLayer.prototype) layer._native = NativeRuvectorLayer.fromJson(json) return layer } } /** * Tensor compressor with adaptive level selection */ class TensorCompress { constructor() { this._native = new NativeTensorCompress() } /** * Compress embedding based on access frequency * @param {number[] | Float32Array} embedding - Input embedding * @param {number} accessFreq - Access frequency (0.0 - 1.0) * @returns {string} Compressed JSON */ compress(embedding, accessFreq) { return this._native.compress(toFloat32Array(embedding), accessFreq) } /** * Compress with explicit compression level * @param {number[] | Float32Array} embedding - Input embedding * @param {object} level - Compression level config * @returns {string} Compressed JSON */ compressWithLevel(embedding, level) { return this._native.compressWithLevel(toFloat32Array(embedding), level) } /** * Decompress a compressed tensor * @param {string} compressedJson - Compressed JSON * @returns {Float32Array} */ decompress(compressedJson) { return this._native.decompress(compressedJson) } } module.exports.RuvectorLayer = RuvectorLayer module.exports.TensorCompress = TensorCompress module.exports.differentiableSearch = differentiableSearch module.exports.hierarchicalForward = hierarchicalForward module.exports.getCompressionLevel = getCompressionLevel module.exports.init = init // Export conversion helpers for users who want to pre-convert their data module.exports.toFloat32Array = toFloat32Array module.exports.toFloat32ArrayBatch = toFloat32ArrayBatch module.exports.toFloat32ArrayBatchOptimized = toFloat32ArrayBatchOptimized // Also export native versions for advanced users (require Float32Array directly) module.exports.NativeRuvectorLayer = NativeRuvectorLayer module.exports.NativeTensorCompress = NativeTensorCompress module.exports.nativeDifferentiableSearch = nativeDifferentiableSearch module.exports.nativeHierarchicalForward = nativeHierarchicalForward