Files
wifi-densepose/npm/packages/ruvbot/tests/mocks/wasm.mock.js
ruv d803bfe2b1 Squashed 'vendor/ruvector/' content from commit b64c2172
git-subtree-dir: vendor/ruvector
git-subtree-split: b64c21726f2bb37286d9ee36a7869fef60cc6900
2026-02-28 14:39:40 -05:00

212 lines
6.1 KiB
JavaScript

"use strict";
/**
* WASM Mock Module
*
* Mock implementations for RuVector WASM bindings
* Used to test code that depends on WASM modules without loading actual binaries
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.mockWasmLoader = exports.MockWasmRouter = exports.MockWasmEmbedder = exports.MockWasmVectorIndex = void 0;
exports.createMockRuVectorBindings = createMockRuVectorBindings;
exports.resetWasmMocks = resetWasmMocks;
const vitest_1 = require("vitest");
// Mock implementations
/**
* Mock WASM Vector Index
*/
class MockWasmVectorIndex {
constructor(dimension = 384) {
this.vectors = new Map();
this.dimension = dimension;
}
add(id, vector) {
if (vector.length !== this.dimension) {
throw new Error(`Vector dimension mismatch: expected ${this.dimension}, got ${vector.length}`);
}
this.vectors.set(id, vector);
}
search(query, topK) {
if (query.length !== this.dimension) {
throw new Error(`Query dimension mismatch: expected ${this.dimension}, got ${query.length}`);
}
const results = [];
for (const [id, vector] of this.vectors) {
const distance = this.cosineSimilarity(query, vector);
results.push({
id,
score: distance,
distance: 1 - distance
});
}
return results
.sort((a, b) => b.score - a.score)
.slice(0, topK);
}
delete(id) {
return this.vectors.delete(id);
}
size() {
return this.vectors.size;
}
clear() {
this.vectors.clear();
}
cosineSimilarity(a, b) {
let dotProduct = 0;
let normA = 0;
let normB = 0;
for (let i = 0; i < a.length; i++) {
dotProduct += a[i] * b[i];
normA += a[i] * a[i];
normB += b[i] * b[i];
}
return dotProduct / (Math.sqrt(normA) * Math.sqrt(normB));
}
}
exports.MockWasmVectorIndex = MockWasmVectorIndex;
/**
* Mock WASM Embedder
*/
class MockWasmEmbedder {
constructor(dimension = 384) {
this.cache = new Map();
this.dim = dimension;
}
embed(text) {
// Check cache first
if (this.cache.has(text)) {
return this.cache.get(text);
}
// Generate deterministic pseudo-random embedding based on text hash
const embedding = new Float32Array(this.dim);
let hash = this.hashCode(text);
for (let i = 0; i < this.dim; i++) {
hash = ((hash * 1103515245) + 12345) & 0x7fffffff;
embedding[i] = (hash / 0x7fffffff) * 2 - 1;
}
// Normalize the embedding
const norm = Math.sqrt(embedding.reduce((sum, val) => sum + val * val, 0));
for (let i = 0; i < this.dim; i++) {
embedding[i] /= norm;
}
this.cache.set(text, embedding);
return embedding;
}
embedBatch(texts) {
return texts.map(text => this.embed(text));
}
dimension() {
return this.dim;
}
hashCode(str) {
let hash = 0;
for (let i = 0; i < str.length; i++) {
const char = str.charCodeAt(i);
hash = ((hash << 5) - hash) + char;
hash = hash & hash;
}
return Math.abs(hash);
}
}
exports.MockWasmEmbedder = MockWasmEmbedder;
/**
* Mock WASM Router
*/
class MockWasmRouter {
constructor() {
this.routes = new Map();
}
route(input, context) {
for (const [key, route] of this.routes) {
if (route.pattern.test(input)) {
return {
handler: route.handler,
confidence: 0.95,
metadata: { matchedPattern: key, context }
};
}
}
// Default fallback
return {
handler: 'default',
confidence: 0.5,
metadata: { fallback: true, context }
};
}
addRoute(pattern, handler) {
this.routes.set(pattern, {
pattern: new RegExp(pattern, 'i'),
handler
});
}
removeRoute(pattern) {
return this.routes.delete(pattern);
}
}
exports.MockWasmRouter = MockWasmRouter;
/**
* Mock WASM Module Loader
*/
exports.mockWasmLoader = {
loadVectorIndex: vitest_1.vi.fn(async (dimension) => {
return new MockWasmVectorIndex(dimension);
}),
loadEmbedder: vitest_1.vi.fn(async (dimension) => {
return new MockWasmEmbedder(dimension);
}),
loadRouter: vitest_1.vi.fn(async () => {
return new MockWasmRouter();
}),
isWasmSupported: vitest_1.vi.fn(() => true),
getWasmMemory: vitest_1.vi.fn(() => ({
used: 1024 * 1024 * 50, // 50MB
total: 1024 * 1024 * 256 // 256MB
}))
};
/**
* Create mock WASM bindings for RuVector
*/
function createMockRuVectorBindings() {
const vectorIndex = new MockWasmVectorIndex(384);
const embedder = new MockWasmEmbedder(384);
const router = new MockWasmRouter();
return {
vectorIndex,
embedder,
router,
// Convenience methods
async search(query, topK = 10) {
const embedding = embedder.embed(query);
return vectorIndex.search(embedding, topK);
},
async index(id, text) {
const embedding = embedder.embed(text);
vectorIndex.add(id, embedding);
},
async batchIndex(items) {
for (const item of items) {
const embedding = embedder.embed(item.text);
vectorIndex.add(item.id, embedding);
}
}
};
}
/**
* Reset all WASM mocks
*/
function resetWasmMocks() {
vitest_1.vi.clearAllMocks();
exports.mockWasmLoader.loadVectorIndex.mockClear();
exports.mockWasmLoader.loadEmbedder.mockClear();
exports.mockWasmLoader.loadRouter.mockClear();
}
// Default export for easy mocking
exports.default = {
MockWasmVectorIndex,
MockWasmEmbedder,
MockWasmRouter,
mockWasmLoader: exports.mockWasmLoader,
createMockRuVectorBindings,
resetWasmMocks
};
//# sourceMappingURL=wasm.mock.js.map