@ldhop/core
Version:
Follow your nose through linked data resources - core
139 lines • 4.51 kB
JavaScript
import { NamedNode, Quad, Store } from 'n3';
import {} from './types.js';
class Moves {
constructor() {
this.list = [];
}
add(move) { }
remove(move) { }
}
export class LdhopEngine {
// make Store interface more precise
constructor(query, variables, store = new Store()) {
this.variables = new Map();
this.graphs = new Map();
this.moves = new Moves();
this.match = (step, quad) => {
var _a;
var _b, _c;
const nextVar = quad[step.pick];
const move = {
from: {},
to: {},
step,
};
move.to[step.target] = new Set([nextVar]);
for (const part of rdfParts) {
if (!this.isMatch(step[part], quad[part]))
return undefined;
if (isVariable(step[part])) {
(_a = (_b = move.from)[_c = step[part]]) !== null && _a !== void 0 ? _a : (_b[_c] = new Set());
move.from[step[part]].add(quad[part]);
}
}
return move;
};
this.query = query;
this.store = store;
}
getMissingResources() {
return this.getGraphs(false);
}
/**
* @deprecated use getGraphs instead
*/
getResources(status) {
switch (status) {
case undefined: {
return this.getGraphs();
}
case 'missing': {
return this.getGraphs(false);
}
case 'added': {
throw new Error('ambiguous');
}
case 'failed': {
throw new Error('ambiguous');
}
}
}
getGraphs(added) {
if (typeof added !== 'boolean')
return new Set(this.graphs.keys());
const result = new Set();
this.graphs.forEach((graph, uri) => {
if (graph.added === added)
result.add(uri);
});
return result;
}
/**
* @deprecated use addGraph instead
*/
addResource(resource, quads) {
return this.addGraph({ graphUri: resource, triples: quads });
}
/**
* This is the core of the engine.
*/
addGraph({ graphUri, triples = [], }) {
var _a;
const graph = (_a = this.graphs.get(graphUri)) !== null && _a !== void 0 ? _a : {
uri: graphUri,
term: new NamedNode(graphUri),
added: false,
};
const oldQuads = this.store.getQuads(null, null, null, graph.term);
const newQuads = triples.map(q => new Quad(q.subject, q.predicate, q.object, graph.term));
// get quad additions and deletions of this graph from this.store
const additions = newQuads.filter(nq => !oldQuads.some(oq => nq.equals(oq)));
const deletions = oldQuads.filter(oq => !newQuads.some(nq => oq.equals(nq)));
// then add each addition, and remove each deletion
for (const quad of additions)
this.addQuad(quad);
for (const quad of deletions)
this.removeQuad(quad);
// and update the status of this graph
graph.added = true;
this.graphs.set(graphUri, graph);
return this.getMissingResources();
}
addQuad(quad) {
// 1. add the quad to the store
this.store.addQuad(quad);
// 2. hop the steps
this.query.forEach(step => {
switch (step.type) {
case 'match': {
this.hop(step, quad);
break;
}
}
});
}
hop(step, quad) {
// 1. detect whether the step matches the quad
const move = this.match(step, quad);
// 2. make the jump, save the move, save the variable
// 3. hop from the variable, if new
}
isMatch(a, b) {
var _a;
if (typeof a === 'undefined')
return true;
if (isVariable(a))
return ((_a = this.variables.get(a)) === null || _a === void 0 ? void 0 : _a.has(b)) ? true : false;
if (!isVariable(a))
return a === b.value;
}
removeQuad(quad) { }
getAllVariables() { }
getVariable() { }
}
// type guard for testing variables
function isVariable(value) {
return typeof value === 'string' && value.startsWith('?');
}
const rdfParts = ['subject', 'predicate', 'object', 'graph'];
//# sourceMappingURL=LdhopEngine_.js.map