An open API service indexing awesome lists of open source software.

https://github.com/constraintautomaton/cache-query-triple-project

A TypeScript library for working with remote SPARQL query result caches.
https://github.com/constraintautomaton/cache-query-triple-project

Last synced: about 1 year ago
JSON representation

A TypeScript library for working with remote SPARQL query result caches.

Awesome Lists containing this project

README

          

# sparql-cache-client

![npm version](https://img.shields.io/npm/v/sparql-cache-client)
![Unit Tests Status](https://img.shields.io/github/actions/workflow/status/constraintAutomaton/cache-query-triple-project/ci.yml?label=unit+test
)
![Lint](https://img.shields.io/github/actions/workflow/status/constraintAutomaton/cache-query-triple-project/format.yml?label=linter
)

A TypeScript library for working with remote SPARQL query result caches.

It allows you to:

- Parse and inspect SPARQL query caches
- Define custom cache-hit strategies
- Retrieve cached query results (as URLs or bindings)

## Instalation

```bash
npm i sparql-cache-client
```

## Cache format

The cache is expected to be in an RDF serialization and respect the [vocabulary of the example below](./cache_example.ttl).

```ttl
<#Nu2rZB> a , , ;
;
"SELECT DISTINCT ?p WHERE {\n\t?s ?p ?o .\n}LIMIT 10";
;
<#384404ed-bbc7-4f35-a4e3-efa7c31b518a>;
"2025-04-09T11:17:29.434Z"^^.
<#384404ed-bbc7-4f35-a4e3-efa7c31b518a> ;
.
<#C7ialK> a , , ;
;
"PREFIX rh: \nPREFIX taxon: \nPREFIX up: \nSELECT ?uniprot ?mnemo ?rhea ?accession ?equation \nWHERE {\n\tSERVICE {\n\t\tVALUES (?taxid) { (taxon:83333) }\n\t\tGRAPH {\n\t\t\t?uniprot up:reviewed true .\n\t\t\t?uniprot up:mnemonic ?mnemo .\n\t\t\t?uniprot up:organism ?taxid .\n\t\t\t?uniprot up:annotation/up:catalyticActivity/up:catalyzedReaction ?rhea .\n\t\t}\n\t}\n\t?rhea rh:accession ?accession .\n\t?rhea rh:equation ?equation .\n}";
;
<#1b7d61ea-d142-4be2-8e9b-b3b7f117b9ae>;
"2025-04-09T11:19:23.986Z"^^;
.
<#1b7d61ea-d142-4be2-8e9b-b3b7f117b9ae> ;
.
<#qeSzrD> a , , ;
;
"PREFIX rh: \nPREFIX taxon: \nPREFIX up: \nSELECT ?uniprot ?mnemo ?rhea ?accession ?equation \nWHERE {\n\t{\n\t\tVALUES (?taxid) { (taxon:83333) }\n\t\tGRAPH {\n\t\t\t?uniprot up:reviewed true .\n\t\t\t?uniprot up:mnemonic ?mnemo .\n\t\t\t?uniprot up:organism ?taxid .\n\t\t\t?uniprot up:annotation/up:catalyticActivity/up:catalyzedReaction ?rhea .\n\t\t}\n\t}\n\t?rhea rh:accession ?accession .\n\t?rhea rh:equation ?equation .\n}";
;
<#25892f49-953b-4742-be4f-c2431ee7f758>;
"2025-04-09T11:21:05.649Z"^^.
<#25892f49-953b-4742-be4f-c2431ee7f758> ;
<#a5c4faeb-3f1a-45bb-b246-ccc93e563a61>.
<#a5c4faeb-3f1a-45bb-b246-ccc93e563a61> ;
.
<#385VC2> a , , ;
;
"SELECT DISTINCT ?p WHERE {\n\t?s ?p ?o .\n}LIMIT 10";
;
<#79ab3c14-89ac-4bd1-b45b-bff650405ac0>;
"2025-04-09T11:24:11.307Z"^^.
<#79ab3c14-89ac-4bd1-b45b-bff650405ac0> ;
.
```

## Usage

**We rely on the [`result-interface`](https://www.npmjs.com/package/result-interface) and [`sparqlalgebrajs`](https://www.npmjs.com/package/sparqlalgebrajs) libraries in the examples**

Use `parseCache` to load a Cache file:

```ts
import { parseCache } from 'sparql-cache-client';
import { isError } from 'result-interface';

const cacheUrl = "https://triple.ilabt.imec.be/test/querycache/queries.ttl";

// Retrieve and parse the cache
const response = await parseCache(cacheUrl);

// Handle error response if any
if (isError(response)) {
console.error(`Unable to retrieve cache. Reason: ${response.error}`);
process.exit(1);
}

// Log the entries in the cache
console.log(`The cache contains ${response.value.size} entries:`);

for (const [endpoint, cachedQueries] of response.value) {
console.log(`- ${endpoint}`);
let i = 0;
for (const cacheInfo of cachedQueries.values()) {
console.log(`\t[q${i}]: ${JSON.stringify(cacheInfo)}`);
i++;
}
}
```
Use `getCachedQuads` to query a cache with a custom cache hit algorithm:

```ts
import { Algebra, toSparql, translate } from 'sparqlalgebrajs';
import {
CacheHitFunction,
getCachedQuads,
IOptions,
OutputOption,
type ICacheQueryInput
} from 'sparql-cache-client';
import { isError, SafePromise } from 'result-interface';

const CACHE_URL = 'https://triple.ilabt.imec.be/test/querycache/queries.ttl';

// Query that we looking into the cache
const query = translate(`
PREFIX rh:
PREFIX taxon:
PREFIX up:
SELECT ?uniprot ?mnemo ?rhea ?accession ?equation
WHERE {
SERVICE {
VALUES (?taxid) { (taxon:83333) }
GRAPH {
?uniprot up:reviewed true .
?uniprot up:mnemonic ?mnemo .
?uniprot up:organism ?taxid .
?uniprot up:annotation/up:catalyticActivity/up:catalyzedReaction ?rhea .
}
}
?rhea rh:accession ?accession .
?rhea rh:equation ?equation .
}
`);

// Simple cache hit function: checks structural equality via SPARQL string comparison
const simpleCacheHit: CacheHitFunction = async (
q1: Readonly,
q2: Readonly,
_options?: IOptions
): SafePromise => {
return {
value: toSparql(q1) === toSparql(q2)
};
};

const input: ICacheQueryInput = {
cache: CACHE_URL,
query,
// Only includes non-SERVICE endpoint(s)
endpoints: ['https://sparql.rhea-db.org/sparql/'],
cacheHitAlgorithms: [
{
algorithm: simpleCacheHit,
time_limit: 1_000 // 1 second
}
],
maxConcurentExecCacheHitAlgorithm: undefined,
// Request the URL of the cached result (instead of full result bindings)
outputOption: OutputOption.URL
};

const cacheResult = await getCachedQuads(input);

if (isError(cacheResult)) {
console.error(`Failed to access cache: ${cacheResult.error}`);
process.exit(1);
}

console.log(`Cache result is available at: ${cacheResult.value?.cache}`);

```

## Testing

```
bun test
```
## License

This project is licensed under the MIT License. See the [LICENSE](./LICENSE) file for more information.

## Idea

- Make the parsing of cache work with local files
- Give the option to start reading the cache while it is parsing
- Give the option to use web worker to run the cache hit algorithms