ruvector/crates/rvlite/examples/dashboard/scripts/debug-keys.mjs
rUv d2b46c2518 feat(rvlite): Add multi-query language support (SPARQL, SQL, Cypher) (#69)
* fix(rvlite): Resolve getrandom WASM conflict with hnsw_rs patch

Resolves the getrandom version conflict that prevented rvlite from
compiling to WASM. The issue was caused by hnsw_rs 0.3.3 using
rand 0.9 -> getrandom 0.3, while the workspace uses rand 0.8 ->
getrandom 0.2.

Changes:
- Add [patch.crates-io] to workspace Cargo.toml for hnsw_rs
- Include patched hnsw_rs 0.3.3 with rand 0.8 dependency
- Modify hnsw_rs/Cargo.toml: rand = "0.8" (was "0.9")

Note: This patch is applied but not actively used since rvlite
disables the HNSW feature via default-features = false. The patch
ensures compatibility if HNSW is enabled in the future.

Build Status:
 WASM compiles successfully
 Bundle size: 96 KB gzipped (with ruvector-core)
 Full vector operations working
 No getrandom conflicts

Related:
- rvlite uses ruvector-core with memory-only feature
- Avoids hnsw_rs dependency via default-features = false
- Target-specific getrandom dependency enables "js" feature

🤖 Generated with Claude Code

* feat(rvlite): Add multi-query language support (SPARQL, SQL, Cypher)

This comprehensive update adds support for three query languages to rvlite,
making it a versatile WASM-powered vector database with knowledge graph
capabilities. The implementation includes full parsers, AST representations,
and executors for each language.

## SPARQL Implementation
- W3C SPARQL 1.1 compliant query parser
- Triple pattern matching with subject/predicate/object
- SELECT, CONSTRUCT, ASK, and DESCRIBE query forms
- FILTER expressions with comparison and logical operators
- OPTIONAL patterns and UNION support
- ORDER BY, LIMIT, OFFSET modifiers
- Built-in RDF triple store with in-memory indexing

## SQL Implementation
- Standard SQL SELECT with projections and aliases
- WHERE clause with complex boolean expressions
- JOIN support (INNER, LEFT, RIGHT, FULL, CROSS)
- Aggregate functions (COUNT, SUM, AVG, MIN, MAX)
- GROUP BY and HAVING clauses
- ORDER BY with ASC/DESC, LIMIT/OFFSET
- Subqueries and nested expressions
- Vector similarity search via special syntax

## Cypher Implementation
- Neo4j-compatible Cypher query language
- MATCH patterns with node and relationship traversal
- CREATE, MERGE, SET, DELETE operations
- WHERE clause filtering
- RETURN with aliases and expressions
- ORDER BY, SKIP, LIMIT modifiers
- Variable-length path patterns
- Property graph store with adjacency indexing

## Additional Changes
- Interactive React dashboard with visualization
- Supply chain simulation demo
- Graph visualization components
- IndexedDB persistence layer for browser storage
- WASM getrandom conflict resolution for hnsw_rs
- SONA time compatibility for cross-platform builds
- NPM package for rvlite distribution
- Documentation for all query implementations

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-11 13:52:23 -05:00

123 lines
3.9 KiB
JavaScript

#!/usr/bin/env node
/**
* Debug key format mismatch in SPARQL triple store
*/
import { readFile } from 'fs/promises';
import { fileURLToPath } from 'url';
import { dirname, join } from 'path';
const __dirname = dirname(fileURLToPath(import.meta.url));
async function test() {
console.log('=== Debug Key Format Mismatch ===\n');
// Load WASM
const wasmPath = join(__dirname, '../public/pkg/rvlite_bg.wasm');
const wasmBytes = await readFile(wasmPath);
const rvliteModule = await import('../public/pkg/rvlite.js');
const { default: initRvLite, RvLite, RvLiteConfig } = rvliteModule;
await initRvLite(wasmBytes);
const config = new RvLiteConfig(384);
const db = new RvLite(config);
console.log('✓ WASM initialized');
// Test 1: Check what format the add_triple expects
console.log('\n=== Test 1: Adding triples with different formats ===');
// Format A: With angle brackets
try {
db.add_triple('<http://ex.org/a1>', '<http://ex.org/p1>', '<http://ex.org/o1>');
console.log('✓ Format A (with <>) accepted');
} catch (e) {
console.log('✗ Format A (with <>) rejected:', e.message);
}
// Format B: Without angle brackets
try {
db.add_triple('http://ex.org/a2', 'http://ex.org/p2', 'http://ex.org/o2');
console.log('✓ Format B (without <>) accepted');
} catch (e) {
console.log('✗ Format B (without <>) rejected:', e.message);
}
console.log(`Total triples: ${db.triple_count()}`);
// Test 2: Try SPARQL queries that match each format
console.log('\n=== Test 2: SPARQL queries with different predicate formats ===');
const testQueries = [
// Query for triples added with format A
'SELECT ?s WHERE { ?s <http://ex.org/p1> ?o }',
// Query for triples added with format B
'SELECT ?s WHERE { ?s <http://ex.org/p2> ?o }',
// Wildcard predicate (variable)
// 'SELECT ?s ?p WHERE { ?s ?p ?o }', // This fails with "Complex property paths not yet supported"
];
for (const query of testQueries) {
console.log(`\nQuery: ${query}`);
try {
const result = db.sparql(query);
console.log('Result:', JSON.stringify(result, null, 2));
} catch (e) {
console.log('ERROR:', e.message || e);
}
}
// Test 3: Add rdf:type triple and test with actual RDF type query
console.log('\n=== Test 3: RDF type query ===');
db.add_triple(
'<http://example.org/Alice>',
'<http://www.w3.org/1999/02/22-rdf-syntax-ns#type>',
'<http://example.org/Person>'
);
console.log(`Triple count after adding rdf:type: ${db.triple_count()}`);
const typeQuery = 'SELECT ?s WHERE { ?s <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://example.org/Person> }';
console.log(`Query: ${typeQuery}`);
try {
const result = db.sparql(typeQuery);
console.log('Result:', JSON.stringify(result, null, 2));
if (result.bindings && result.bindings.length > 0) {
console.log('✓ SPARQL is working!');
} else {
console.log('✗ No bindings returned - key mismatch suspected');
}
} catch (e) {
console.log('ERROR:', e.message || e);
}
// Test 4: Simple triple with known data
console.log('\n=== Test 4: Minimal test case ===');
db.add_triple('<http://a>', '<http://b>', '<http://c>');
console.log(`Triple count: ${db.triple_count()}`);
const minimalQuery = 'SELECT ?s WHERE { ?s <http://b> ?o }';
console.log(`Query: ${minimalQuery}`);
try {
const result = db.sparql(minimalQuery);
console.log('Result:', JSON.stringify(result, null, 2));
} catch (e) {
console.log('ERROR:', e.message || e);
}
// Test 5: Get all triples using 'a' keyword (rdf:type shortcut)
console.log('\n=== Test 5: Using "a" keyword ===');
const aQuery = 'SELECT ?s WHERE { ?s a <http://example.org/Person> }';
console.log(`Query: ${aQuery}`);
try {
const result = db.sparql(aQuery);
console.log('Result:', JSON.stringify(result, null, 2));
} catch (e) {
console.log('ERROR:', e.message || e);
}
db.free();
}
test().catch(console.error);