Skip to main content

oxirs_wasm/
lib.rs

1//! # OxiRS WASM
2//!
3//! [![Version](https://img.shields.io/badge/version-0.4.1-blue)](https://github.com/cool-japan/oxirs/releases)
4//!
5//! **Status**: Development Release (v0.4.1)
6//!
7//! WebAssembly bindings for OxiRS - Run RDF/SPARQL in the browser.
8//!
9//! ## Features
10//!
11//! - **Streaming RDF Parser**: Turtle, N-Triples, N-Quads (incremental chunk processing)
12//! - **Compact Triple Store**: Dictionary-based, 12 bytes per triple, dual sorted indexes
13//! - **JS/TS API**: Clean `wasm_bindgen` surface via `OxiRSStore` and `WasmSparqlStore`
14//! - **SPARQL Queries**: SELECT, ASK, CONSTRUCT (triple-pattern based)
15//! - **SPARQL UPDATE**: INSERT DATA, DELETE DATA, INSERT/DELETE WHERE, CLEAR, DROP
16//! - **SPARQL Enhancements**: OPTIONAL, UNION, FILTER expressions
17//! - **RDFS Inference**: subClassOf/subPropertyOf transitivity, domain/range typing
18//! - **Named Graphs**: Multi-graph storage with GRAPH pattern queries
19//! - **Memory Efficient**: Optimized for WASM's 4 GB address space limit
20//!
21//! ## Example (JavaScript)
22//!
23//! ```javascript
24//! import init, { OxiRSStore } from 'oxirs-wasm';
25//!
26//! await init();
27//!
28//! const store = new OxiRSStore();
29//! await store.loadTurtle(`
30//!     @prefix : <http://example.org/> .
31//!     :alice :knows :bob .
32//!     :bob :name "Bob" .
33//! `);
34//!
35//! const results = store.query('SELECT ?name WHERE { ?person :name ?name }');
36//! console.log(results);
37//! ```
38
39pub mod api;
40pub mod error;
41pub mod inference;
42pub mod named_graph;
43pub mod parser;
44pub mod query;
45pub mod store;
46pub mod update;
47
48// v1.1.0 SPARQL Results CSV/TSV serializer
49pub mod results_csv;
50
51// v1.1.0 round 5: GeoJSON serialization/deserialization for SPARQL geo results
52pub mod geojson_support;
53
54// v1.1.0 round 6: SPARQL query pretty-printer and formatter
55pub mod sparql_formatter;
56
57// v1.1.0 round 7: Namespace/prefix management for RDF serializers
58pub mod prefix_manager;
59
60// v1.1.0 round 11: Streaming / incremental chunk-based RDF document parser
61pub mod streaming_parser;
62
63// v1.1.0 round 12: WASM/JS interop bridge type conversions
64pub mod wasm_bridge;
65
66// v1.1.0 round 13: Client-side SPARQL query validation (syntax/semantic checks)
67pub mod query_validator;
68
69// v1.1.0 round 11: RDF graph visualization with Fruchterman-Reingold layout
70pub mod graph_visualizer;
71
72// v1.1.0 round 12: In-memory indexed triple store for WASM
73pub mod triple_store;
74
75// v1.1.0 round 13: In-memory SPARQL executor (SELECT/ASK/CONSTRUCT/DESCRIBE + FILTER)
76pub mod sparql_executor;
77
78// v1.1.0 round 14: WASM storage abstraction layer (key-value with namespace isolation + TTL)
79pub mod storage_adapter;
80
81// v1.1.0 round 15: WASM event dispatching system (pub/sub for browser events)
82pub mod event_dispatcher;
83
84// v1.1.0 round 16: RDF namespace prefix management for WASM bindings
85pub mod namespace_manager;
86
87// v0.3.0: Web Workers for parallel execution
88pub mod web_worker;
89
90// v0.3.0: ServiceWorker offline cache
91pub mod offline_cache;
92
93// v0.3.0: SHACL validation subset
94pub mod shacl;
95
96// Fluent, programmatic SPARQL SELECT/ASK/COUNT query builder
97pub mod query_builder;
98
99// Structured WASM error codes and an error-history handler
100pub mod error_handler;
101
102// Multi-format (JSON/XML/CSV/TSV/Markdown/HTML) SPARQL result set formatter
103pub mod sparql_result_formatter;
104
105// A deterministic, in-memory *mock* SPARQL endpoint client — no network I/O.
106// Off by default; see the `mock-endpoint-client` feature doc in Cargo.toml.
107#[cfg(feature = "mock-endpoint-client")]
108pub mod endpoint_client;
109
110use wasm_bindgen::prelude::*;
111
112pub use api::WasmSparqlStore;
113pub use error::WasmError;
114pub use store::OxiRSStore;
115
116// Initialize panic hook for better error messages in browser DevTools
117#[wasm_bindgen(start)]
118pub fn init() {
119    console_error_panic_hook::set_once();
120}
121
122/// RDF Triple representation for JavaScript
123#[wasm_bindgen]
124#[derive(Debug, Clone)]
125pub struct Triple {
126    subject: String,
127    predicate: String,
128    object: String,
129}
130
131#[wasm_bindgen]
132impl Triple {
133    #[wasm_bindgen(constructor)]
134    pub fn new(subject: &str, predicate: &str, object: &str) -> Self {
135        Self {
136            subject: subject.to_string(),
137            predicate: predicate.to_string(),
138            object: object.to_string(),
139        }
140    }
141
142    #[wasm_bindgen(getter)]
143    pub fn subject(&self) -> String {
144        self.subject.clone()
145    }
146
147    #[wasm_bindgen(getter)]
148    pub fn predicate(&self) -> String {
149        self.predicate.clone()
150    }
151
152    #[wasm_bindgen(getter)]
153    pub fn object(&self) -> String {
154        self.object.clone()
155    }
156}
157
158/// Query result for JavaScript
159#[wasm_bindgen]
160pub struct QueryResult {
161    bindings: Vec<JsValue>,
162}
163
164#[wasm_bindgen]
165impl QueryResult {
166    #[wasm_bindgen(getter)]
167    pub fn bindings(&self) -> Vec<JsValue> {
168        self.bindings.clone()
169    }
170
171    #[wasm_bindgen(getter)]
172    pub fn length(&self) -> usize {
173        self.bindings.len()
174    }
175}
176
177/// Get OxiRS WASM version
178#[wasm_bindgen]
179pub fn version() -> String {
180    env!("CARGO_PKG_VERSION").to_string()
181}
182
183/// Log a message to the browser console
184#[wasm_bindgen]
185pub fn log(message: &str) {
186    web_sys::console::log_1(&message.into());
187}
188
189#[cfg(test)]
190mod tests {
191    use super::*;
192
193    #[test]
194    fn test_triple() {
195        let triple = Triple::new("http://a", "http://b", "http://c");
196        assert_eq!(triple.subject(), "http://a");
197        assert_eq!(triple.predicate(), "http://b");
198        assert_eq!(triple.object(), "http://c");
199    }
200}