@ldhop/core
Version:
Follow your nose through linked data resources - core
131 lines (130 loc) • 4.59 kB
TypeScript
import { Quad, Store, type Term } from 'n3';
import type { LdhopQuery, Variable } from './types.js';
type TermId = `${Term['termType']}:${Term['id']}`;
type UriVariables<V extends Variable> = Partial<{
[key in V]: Set<string>;
}>;
type VariableMap<V extends Variable, Value = Term> = Map<V, Map<TermId, Value>>;
interface Move<V extends Variable> {
from: VariableMap<V, Term>;
to: VariableMap<V, Term>;
step: number;
quad?: Quad;
}
declare class Moves<V extends Variable> {
list: Set<Move<V>>;
providedByVariable: VariableMap<V, Set<Move<V>>>;
provideVariable: VariableMap<V, Set<Move<V>>>;
byQuad: {
[key: string]: Set<Move<V>>;
};
add(move: Move<V>): void;
remove(move: Move<V>): void;
print(): string;
private formatVariableMap;
}
/**
* The engine to execute LdhopQuery.
*
* It works in steps. So you give it a resource, and it tells you what to add next, and what's no longer needed (TODO).
*
* Usage:
*
* const engine = new LdhopEngine(query, startingPoints, store?)
*
*
* Internal parts:
*
* store - RDF store that keeps track of the Linked Data
* variables - the map of variables we hop through
* moves -
* graphs -
*
* ## Algorithm:
*
* - add the defined starting variables
*
* ### Add a variable
* - if variable is already in the list of variables, done.
* - add a variable to the list of variables
* - if variable is required in any steps, get its URI without #hash part. If resource is needed, see if it is listed in graphs map already. If not, add it to the graphs map as missing.
* - go through all steps of the query, and if the variable matches any of the Match or TransformVariable steps, make the hop, collect the resulting target variable, save the Move and (Add the variable).
*
* ### Add missing resource/graph:
* - a resource/graph IRI, and all contained triples are provided
* - each added quad will be given a graph, which typically represents the final URL of the resource
* - TODO: keep track of any redirect
* - see which quads should be added and which ones should be removed
* - For each quad to add
* - (Add the quad).
* - For each quad to remove
* - (Remove the quad).
*
* - mark the graph as added or add it
*
* - return missing resources and no-more-needed resources (TODO)
*
* ### Add a quad:
* - add quad to the store
* - for each step:
* - if the quad matches the step, get final variable, save the Move, and (Add the variable).
*
* ### Remove a quad:
* - remove quad from store
* - get all moves that this quad provided and (remove the move)
*
* ### Remove move:
* - remove move from moves.
* - if the move leads to a variable, and it is the last move supporting this variable, (remove the variable).
* - TODO prune in such a way that orphaned cycles get removed
*
* ### Remove variable:
* - remove variable value from variables
* - if the related graph is not supported by any other variable (remove the graph)
* - Remove all moves that this variable leads to
*
* ### Remove graph:
* - remove graph from graphs
* - for each matching quad (remove quad)
*/
export declare class LdhopEngine<V extends Variable = Variable> {
store: Store;
query: LdhopQuery<V>;
moves: Moves<V>;
private variables;
private graphs;
constructor(query: LdhopQuery<V>, startingPoints: UriVariables<V>, store?: Store<import("@rdfjs/types").Quad, Quad, import("@rdfjs/types").Quad, import("@rdfjs/types").Quad>);
getMissingResources(): Set<string>;
addGraph(actualUri: string, quads: Quad[], requestedUri?: string): {
missing: Set<string>;
notNeeded: string;
};
private isVariablePresent;
addQuad(quad: Quad): void;
removeQuad(quad: Quad): void;
private removeMove;
private coloredVariables;
/**
* First iteration: color all variables that follow from the initial variable
* Then see if the resulting colored variables are held by any uncolored variables.
*/
private colorDependents;
private detectAndRemoveOrphans;
private removeVariable;
removeGraph(uri: string): void;
private hopFromVariable;
private addVariable;
/**
* If you provide variable name, this method will return URIs that belong to that variable
*/
getVariable(variableName: V): Set<Term>;
getVariableAsStringSet(variableName: V): Set<string>;
getAllVariables(): {
[k: string]: Set<Term>;
};
getAllVariablesAsStringSets(): {
[k: string]: Set<string>;
};
getGraphs(added?: boolean): Set<string>;
}
export {};