unrdf
Version:
Production-ready RDF knowledge graph library with Knowledge Hooks, SPARC methodology, and Knowledge Substrate optimization
1 lines • 9.71 kB
Source Map (JSON)
{"version":3,"file":"rdf-engine-H5lGYQ__.mjs","names":[],"sources":["../../src/engines/rdf-engine.mjs"],"sourcesContent":["/**\n * @fileoverview Production-grade RDF engine for JavaScript.\n * @version 2.0.0\n * @license MIT\n */\n\nimport { Parser, Store, Writer, DataFactory } from 'n3';\nimport { QueryEngine } from '@comunica/query-sparql';\nimport rdf from 'rdf-ext';\nimport SHACLValidator from 'rdf-validate-shacl';\nimport rdfCanonize from 'rdf-canonize';\nimport { n3reasoner } from 'eyereasoner';\nimport jsonld from 'jsonld';\n\nconst { namedNode, literal, quad, blankNode, defaultGraph } = DataFactory;\n\n/**\n * A comprehensive, production-grade engine for RDF processing in JavaScript.\n * It unifies parsing, serialization, querying, validation, and reasoning.\n */\nexport class RdfEngine {\n /**\n * @param {object} [options] - Configuration options for the engine.\n * @param {string} [options.baseIRI] - The base IRI to use for parsing relative URIs.\n */\n constructor(options = {}) {\n this.baseIRI = options.baseIRI || \"http://example.org/\";\n this.comunicaEngine = new QueryEngine();\n this.store = new Store();\n }\n\n // =================================================================\n // == Core Setup & Store Access\n // =================================================================\n\n /**\n * Returns the underlying N3.js Store instance.\n * @returns {import('n3').Store}\n */\n getStore() {\n return this.store;\n }\n\n /**\n * Clears the internal store, removing all quads.\n */\n clearStore() {\n this.store.removeQuads(this.store.getQuads());\n }\n\n // =================================================================\n // == Term Creation\n // =================================================================\n\n namedNode(value) { return namedNode(value); }\n literal(value, langOrDt) { return literal(value, langOrDt); }\n blankNode(value) { return blankNode(value); }\n quad(s, p, o, g = defaultGraph()) { return quad(s, p, o, g); }\n\n // =================================================================\n // == Parsing & Serialization\n // =================================================================\n\n /**\n * Parses a Turtle string and adds the quads to the internal store.\n * @param {string} ttl - The Turtle string to parse.\n * @returns {import('n3').Store} The engine's store instance.\n */\n parseTurtle(ttl) {\n const quads = new Parser({ baseIRI: this.baseIRI }).parse(ttl);\n this.store.addQuads(quads);\n return this.store;\n }\n \n /**\n * Serializes a store to a Turtle string.\n * @param {import('n3').Store} [store=this.store] - The store to serialize.\n * @param {object} [options] - N3.js Writer options.\n * @returns {string}\n */\n serializeTurtle(store = this.store, options = {}) {\n const writer = new Writer({ ...options, format: 'Turtle' });\n return writer.quadsToString(store.getQuads());\n }\n\n /**\n * Serializes a store to a canonical N-Quads string.\n * @param {import('n3').Store} [store=this.store] - The store to serialize.\n * @returns {string}\n */\n serializeNQuads(store = this.store) {\n const writer = new Writer({ format: 'N-Quads' });\n return writer.quadsToString(store.getQuads());\n }\n\n // =================================================================\n // == SPARQL Querying\n // =================================================================\n\n /**\n * Executes a read-only SPARQL query (SELECT, ASK, CONSTRUCT) against the store.\n * @param {string} sparql - The SPARQL query string.\n * @returns {Promise<Array<object>|boolean|import('n3').Store>} The query result.\n */\n async query(sparql) {\n const queryType = sparql.trim().toUpperCase().split(/\\s+/)[0];\n const source = { type: 'rdfjsSource', value: this.store };\n\n switch (queryType) {\n case 'SELECT':\n const bindingsStream = await this.comunicaEngine.queryBindings(sparql, { sources: [source] });\n const bindings = await bindingsStream.toArray();\n // Convert from RDF/JS terms to simple values\n return bindings.map(b => Object.fromEntries([...b].map(([k, v]) => [k.value, v.value])));\n case 'ASK':\n return this.comunicaEngine.queryBoolean(sparql, { sources: [source] });\n case 'CONSTRUCT':\n const quadStream = await this.comunicaEngine.queryQuads(sparql, { sources: [source] });\n return new Store(await quadStream.toArray());\n default:\n throw new Error(`Query type \"${queryType}\" is not supported. Use the TransactionManager for writes.`);\n }\n }\n\n // =================================================================\n // == SHACL Validation\n // =================================================================\n\n /**\n * Validates a data store against a set of SHACL shapes.\n * @param {import('n3').Store} dataStore - The store containing data to validate.\n * @param {import('n3').Store|string} shapes - The store or Turtle string containing SHACL shapes.\n * @returns {{conforms: boolean, results: Array<object>}} A validation report.\n */\n validateShacl(dataStore, shapes) {\n const shapesStore = typeof shapes === \"string\"\n ? new Store(new Parser().parse(shapes))\n : shapes;\n\n const validator = new SHACLValidator(rdf.dataset([...shapesStore]));\n const report = validator.validate(rdf.dataset([...dataStore]));\n\n return {\n conforms: report.conforms,\n results: (report.results || []).map(r => ({\n message: r.message?.[0]?.value || null,\n path: r.path?.value || null,\n focusNode: r.focusNode?.value || null,\n })),\n };\n }\n\n // =================================================================\n // == Reasoning\n // =================================================================\n \n /**\n * Infers new knowledge by applying N3 Rules to a data store.\n * @param {import('n3').Store} dataStore - The store containing data.\n * @param {import('n3').Store|string} rules - The store or Turtle string containing N3 Rules.\n * @returns {Promise<import('n3').Store>} A new store containing both original and inferred quads.\n */\n async reason(dataStore, rules) {\n const rulesN3 = typeof rules === \"string\" ? rules : this.serializeTurtle(rules);\n const dataN3 = this.serializeTurtle(dataStore);\n const inferredN3 = await n3reasoner(dataN3, rulesN3);\n return new Store(new Parser().parse(inferredN3));\n }\n\n // =================================================================\n // == Canonicalization & Isomorphism\n // =================================================================\n \n /**\n * Produces a canonical representation of a store's quads using URDNA2015.\n * @param {import('n3').Store} store - The store to canonicalize.\n * @returns {string} The canonical N-Quads string.\n */\n canonicalize(store) {\n return rdfCanonize.canonizeSync(store.getQuads(), { algorithm: 'URDNA2015' });\n }\n\n /**\n * Checks if two stores are logically equivalent (isomorphic).\n * @param {import('n3').Store} storeA \n * @param {import('n3').Store} storeB \n * @returns {boolean}\n */\n isIsomorphic(storeA, storeB) {\n if (storeA.size !== storeB.size) return false;\n return this.canonicalize(storeA) === this.canonicalize(storeB);\n }\n}"],"mappings":"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"}