UNPKG

unrdf

Version:

Production-ready RDF knowledge graph library with Knowledge Hooks, SPARC methodology, and Knowledge Substrate optimization

1 lines 10.4 kB
{"version":3,"file":"query-BDTu1b1k.mjs","names":[],"sources":["../../src/knowledge-engine/query.mjs"],"sourcesContent":["/**\n * @file SPARQL querying utilities.\n * @module query\n */\n\nimport { QueryEngine } from '@comunica/query-sparql';\nimport { Store } from 'n3';\n\n// Create a new QueryEngine instance for each query to prevent hanging\nfunction createQueryEngine() {\n return new QueryEngine();\n}\n\n/**\n * Run a SPARQL query against a store.\n * @param {Store} store - The store to query against\n * @param {string} sparql - The SPARQL query string\n * @param {Object} [options] - Query options\n * @param {number} [options.limit] - Maximum number of results\n * @param {AbortSignal} [options.signal] - Abort signal for cancellation\n * @param {boolean} [options.deterministic] - Enable deterministic results\n * @returns {Promise<any>} Promise resolving to the query result\n * \n * @throws {Error} If query execution fails\n * \n * @example\n * const store = new Store();\n * // ... add quads to store\n * \n * const results = await query(store, `\n * SELECT ?s ?o WHERE { \n * ?s <http://example.org/knows> ?o \n * }\n * `);\n * console.log(results); // Array of binding objects\n */\nexport async function query(store, sparql, options = {}) {\n if (!store || typeof store.getQuads !== 'function') {\n throw new TypeError('query: store must be a valid Store instance');\n }\n if (typeof sparql !== 'string' || !sparql.trim()) {\n throw new TypeError('query: sparql must be a non-empty string');\n }\n\n try {\n const queryOptions = {\n sources: [store],\n ...options\n };\n\n const comunica = createQueryEngine();\n const res = await comunica.query(sparql, queryOptions);\n \n switch (res.resultType) {\n case 'bindings': {\n const executed = await res.execute();\n const rows = [];\n for await (const binding of executed) {\n rows.push(Object.fromEntries([...binding].map(([k, v]) => [k.value, v.value])));\n }\n return rows;\n }\n case 'boolean':\n return res.booleanResult ?? (await res.execute());\n case 'quads': {\n const executed = await res.execute();\n const quads = [];\n for await (const quad of executed) {\n quads.push(quad);\n }\n return new Store(quads);\n }\n default:\n throw new Error(`Unsupported query type: ${res.resultType}`);\n }\n } catch (error) {\n throw new Error(`SPARQL query failed: ${error.message}`);\n }\n}\n\n/**\n * Execute a SELECT query and return bindings.\n * @param {Store} store - The store to query against\n * @param {string} sparql - The SPARQL SELECT query\n * @param {Object} [options] - Query options\n * @returns {Promise<Array<Object>>} Promise resolving to array of binding objects\n * \n * @throws {Error} If query execution fails\n * \n * @example\n * const bindings = await select(store, `\n * SELECT ?name ?age WHERE {\n * ?person <http://example.org/name> ?name ;\n * <http://example.org/age> ?age .\n * }\n * `);\n */\nexport async function select(store, sparql, options = {}) {\n const result = await query(store, sparql, options);\n if (Array.isArray(result)) {\n return result;\n }\n throw new Error('SELECT query did not return bindings');\n}\n\n/**\n * Execute an ASK query and return boolean result.\n * @param {Store} store - The store to query against\n * @param {string} sparql - The SPARQL ASK query\n * @param {Object} [options] - Query options\n * @returns {Promise<boolean>} Promise resolving to boolean result\n * \n * @throws {Error} If query execution fails\n * \n * @example\n * const hasData = await ask(store, `\n * ASK WHERE {\n * ?s ?p ?o .\n * }\n * `);\n */\nexport async function ask(store, sparql, options = {}) {\n const result = await query(store, sparql, options);\n if (typeof result === 'boolean') {\n return result;\n }\n throw new Error('ASK query did not return boolean result');\n}\n\n/**\n * Execute a CONSTRUCT query and return a new store.\n * @param {Store} store - The store to query against\n * @param {string} sparql - The SPARQL CONSTRUCT query\n * @param {Object} [options] - Query options\n * @returns {Promise<Store>} Promise resolving to a new store with constructed quads\n * \n * @throws {Error} If query execution fails\n * \n * @example\n * const constructed = await construct(store, `\n * CONSTRUCT {\n * ?person <http://example.org/type> <http://example.org/Person> .\n * } WHERE {\n * ?person <http://example.org/name> ?name .\n * }\n * `);\n */\nexport async function construct(store, sparql, options = {}) {\n const result = await query(store, sparql, options);\n if (result && typeof result.getQuads === 'function') {\n return result;\n }\n throw new Error('CONSTRUCT query did not return a store');\n}\n\n/**\n * Execute a DESCRIBE query and return a new store.\n * @param {Store} store - The store to query against\n * @param {string} sparql - The SPARQL DESCRIBE query\n * @param {Object} [options] - Query options\n * @returns {Promise<Store>} Promise resolving to a new store with described quads\n * \n * @throws {Error} If query execution fails\n * \n * @example\n * const described = await describe(store, `\n * DESCRIBE <http://example.org/alice>\n * `);\n */\nexport async function describe(store, sparql, options = {}) {\n const result = await query(store, sparql, options);\n if (result && typeof result.getQuads === 'function') {\n return result;\n }\n throw new Error('DESCRIBE query did not return a store');\n}\n\n/**\n * Execute a SPARQL UPDATE operation (INSERT, DELETE, etc.).\n * @param {Store} store - The store to update\n * @param {string} sparql - The SPARQL UPDATE query\n * @param {Object} [options] - Update options\n * @returns {Promise<Store>} Promise resolving to the updated store\n * \n * @throws {Error} If update execution fails\n * \n * @example\n * const updated = await update(store, `\n * INSERT DATA {\n * <http://example.org/alice> <http://example.org/age> \"30\" .\n * }\n * `);\n */\nexport async function update(store, sparql, options = {}) {\n if (!store || typeof store.getQuads !== 'function') {\n throw new TypeError('update: store must be a valid Store instance');\n }\n if (typeof sparql !== 'string' || !sparql.trim()) {\n throw new TypeError('update: sparql must be a non-empty string');\n }\n\n try {\n const source = { type: 'rdfjsSource', value: store };\n const updateOptions = {\n sources: [source],\n ...options\n };\n\n const comunica = createQueryEngine();\n await comunica.query(sparql, updateOptions);\n \n // Return the updated store\n return store;\n } catch (error) {\n throw new Error(`SPARQL update failed: ${error.message}`);\n }\n}\n\n/**\n * Get query execution statistics.\n * @param {Store} store - The store to query against\n * @param {string} sparql - The SPARQL query\n * @param {Object} [options] - Query options\n * @returns {Promise<Object>} Promise resolving to execution statistics\n * \n * @example\n * const stats = await getQueryStats(store, sparql);\n * console.log(`Execution time: ${stats.duration}ms`);\n * console.log(`Result count: ${stats.resultCount}`);\n */\nexport async function getQueryStats(store, sparql, options = {}) {\n const startTime = Date.now();\n \n try {\n const result = await query(store, sparql, options);\n const endTime = Date.now();\n \n let resultCount = 0;\n if (Array.isArray(result)) {\n resultCount = result.length;\n } else if (result && typeof result.getQuads === 'function') {\n resultCount = result.size;\n } else if (typeof result === 'boolean') {\n resultCount = 1;\n }\n \n return {\n duration: endTime - startTime,\n resultCount,\n success: true\n };\n } catch (error) {\n const endTime = Date.now();\n return {\n duration: endTime - startTime,\n resultCount: 0,\n success: false,\n error: error.message\n };\n }\n}\n"],"mappings":"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"}