@comunica/actor-abstract-path 2.3.1-alpha.27.0 → 2.3.1-alpha.30.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/ActorAbstractPath.d.ts +11 -11
- package/lib/ActorAbstractPath.js +18 -18
- package/lib/PathVariableObjectIterator.d.ts +24 -0
- package/lib/PathVariableObjectIterator.js +117 -0
- package/lib/index.d.ts +1 -0
- package/lib/index.js +1 -0
- package/package.json +7 -7
|
@@ -24,17 +24,17 @@ export declare abstract class ActorAbstractPath extends ActorQueryOperationTyped
|
|
|
24
24
|
}>;
|
|
25
25
|
private predicateStarGraphVariable;
|
|
26
26
|
/**
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
getObjectsPredicateStarEval(subject: RDF.Term,
|
|
27
|
+
* Returns an iterator with Bindings of the query subject predicate* ?o or subject predicate+ ?o
|
|
28
|
+
* If graph is a variable, it will also be in those bindings
|
|
29
|
+
* @param {Term} subject Term of where we start the predicate* search.
|
|
30
|
+
* @param {Algebra.PropertyPathSymbol} predicate Predicate of the *-path.
|
|
31
|
+
* @param {Variable} object Variable of the zeroOrMore-query.
|
|
32
|
+
* @param {Term} graph The graph in which we search for the pattern. (Possibly a variable)
|
|
33
|
+
* @param {ActionContext} context The context to pass to sub-opertations
|
|
34
|
+
* @param emitFirstSubject If the path operation is predicate*, otherwise it is predicate+.
|
|
35
|
+
* @return {Promise<AsyncIterator<Bindings>} Iterator to where all bindings of query should have been pushed.
|
|
36
|
+
*/
|
|
37
|
+
getObjectsPredicateStarEval(subject: RDF.Term, predicate: Algebra.PropertyPathSymbol, object: RDF.Variable, graph: RDF.Term, context: IActionContext, emitFirstSubject: boolean): Promise<IPathResultStream>;
|
|
38
38
|
/**
|
|
39
39
|
* Pushes all terms to iterator `it` that are a solution of object predicate* ?o.
|
|
40
40
|
* @param {Term} object Term of where we start the predicate* search.
|
package/lib/ActorAbstractPath.js
CHANGED
|
@@ -8,6 +8,7 @@ const asynciterator_1 = require("asynciterator");
|
|
|
8
8
|
const rdf_data_factory_1 = require("rdf-data-factory");
|
|
9
9
|
const rdf_string_1 = require("rdf-string");
|
|
10
10
|
const sparqlalgebrajs_1 = require("sparqlalgebrajs");
|
|
11
|
+
const PathVariableObjectIterator_1 = require("./PathVariableObjectIterator");
|
|
11
12
|
const DF = new rdf_data_factory_1.DataFactory();
|
|
12
13
|
const BF = new bindings_factory_1.BindingsFactory();
|
|
13
14
|
/**
|
|
@@ -53,8 +54,10 @@ class ActorAbstractPath extends bus_query_operation_1.ActorQueryOperationTypedMe
|
|
|
53
54
|
return { context, operation: undefined };
|
|
54
55
|
}
|
|
55
56
|
async predicateStarGraphVariable(subject, object, predicate, graph, context) {
|
|
57
|
+
// TODO: refactor this with an iterator just like PathVariableObjectIterator so we handle backpressure correctly
|
|
56
58
|
// Construct path to obtain all graphs where subject exists
|
|
57
|
-
const predVar = this.generateVariable(ActorAbstractPath.FACTORY
|
|
59
|
+
const predVar = this.generateVariable(ActorAbstractPath.FACTORY
|
|
60
|
+
.createPath(subject, predicate, object, graph));
|
|
58
61
|
const findGraphs = ActorAbstractPath.FACTORY.createUnion([
|
|
59
62
|
ActorAbstractPath.FACTORY.createPattern(subject, predVar, object, graph),
|
|
60
63
|
ActorAbstractPath.FACTORY.createPattern(object, predVar, subject, graph),
|
|
@@ -91,26 +94,23 @@ class ActorAbstractPath extends bus_query_operation_1.ActorQueryOperationTypedMe
|
|
|
91
94
|
};
|
|
92
95
|
}
|
|
93
96
|
/**
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
async getObjectsPredicateStarEval(subject,
|
|
97
|
+
* Returns an iterator with Bindings of the query subject predicate* ?o or subject predicate+ ?o
|
|
98
|
+
* If graph is a variable, it will also be in those bindings
|
|
99
|
+
* @param {Term} subject Term of where we start the predicate* search.
|
|
100
|
+
* @param {Algebra.PropertyPathSymbol} predicate Predicate of the *-path.
|
|
101
|
+
* @param {Variable} object Variable of the zeroOrMore-query.
|
|
102
|
+
* @param {Term} graph The graph in which we search for the pattern. (Possibly a variable)
|
|
103
|
+
* @param {ActionContext} context The context to pass to sub-opertations
|
|
104
|
+
* @param emitFirstSubject If the path operation is predicate*, otherwise it is predicate+.
|
|
105
|
+
* @return {Promise<AsyncIterator<Bindings>} Iterator to where all bindings of query should have been pushed.
|
|
106
|
+
*/
|
|
107
|
+
async getObjectsPredicateStarEval(subject, predicate, object, graph, context, emitFirstSubject) {
|
|
105
108
|
if (graph.termType === 'Variable') {
|
|
106
109
|
return this.predicateStarGraphVariable(subject, object, predicate, graph, context);
|
|
107
110
|
}
|
|
108
|
-
const it = new
|
|
109
|
-
// We can safely ignore undefs because termHashes is empty
|
|
110
|
-
// eslint-disable-next-line @typescript-eslint/non-nullable-type-assertion-style
|
|
111
|
-
const metadata = await this
|
|
112
|
-
.getObjectsPredicateStar(subject, predicate, graph, context, {}, it, { count: 0 });
|
|
111
|
+
const it = new PathVariableObjectIterator_1.PathVariableObjectIterator(subject, predicate, graph, context, this.mediatorQueryOperation, emitFirstSubject);
|
|
113
112
|
const bindingsStream = it.transform({
|
|
113
|
+
autoStart: false,
|
|
114
114
|
transform(item, next, push) {
|
|
115
115
|
push(BF.bindings([[object, item]]));
|
|
116
116
|
next();
|
|
@@ -118,7 +118,7 @@ class ActorAbstractPath extends bus_query_operation_1.ActorQueryOperationTypedMe
|
|
|
118
118
|
});
|
|
119
119
|
return {
|
|
120
120
|
bindingsStream,
|
|
121
|
-
metadata,
|
|
121
|
+
metadata: () => new Promise(resolve => it.getProperty('metadata', (metadata) => resolve(metadata()))),
|
|
122
122
|
};
|
|
123
123
|
}
|
|
124
124
|
/**
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { MediatorQueryOperation } from '@comunica/bus-query-operation';
|
|
2
|
+
import type { IActionContext } from '@comunica/types';
|
|
3
|
+
import type * as RDF from '@rdfjs/types';
|
|
4
|
+
import { BufferedIterator } from 'asynciterator';
|
|
5
|
+
import type { Algebra } from 'sparqlalgebrajs';
|
|
6
|
+
/**
|
|
7
|
+
* An iterator that implements the multi-length property path operation (* and +)
|
|
8
|
+
* for a fixed subject and predicate, and a variable object.
|
|
9
|
+
*/
|
|
10
|
+
export declare class PathVariableObjectIterator extends BufferedIterator<RDF.Term> {
|
|
11
|
+
private readonly subject;
|
|
12
|
+
private readonly predicate;
|
|
13
|
+
private readonly graph;
|
|
14
|
+
private readonly context;
|
|
15
|
+
private readonly mediatorQueryOperation;
|
|
16
|
+
private readonly maxRunningOperations;
|
|
17
|
+
private readonly termHashes;
|
|
18
|
+
private readonly runningOperations;
|
|
19
|
+
private readonly pendingOperations;
|
|
20
|
+
constructor(subject: RDF.Term, predicate: Algebra.PropertyPathSymbol, graph: RDF.Term, context: IActionContext, mediatorQueryOperation: MediatorQueryOperation, emitFirstSubject: boolean, maxRunningOperations?: number);
|
|
21
|
+
protected _end(destroy?: boolean): void;
|
|
22
|
+
protected _push(item: RDF.Term, pushAsResult?: boolean): void;
|
|
23
|
+
protected _read(count: number, done: () => void): void;
|
|
24
|
+
}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.PathVariableObjectIterator = void 0;
|
|
4
|
+
const bus_query_operation_1 = require("@comunica/bus-query-operation");
|
|
5
|
+
const asynciterator_1 = require("asynciterator");
|
|
6
|
+
const rdf_data_factory_1 = require("rdf-data-factory");
|
|
7
|
+
const rdf_string_1 = require("rdf-string");
|
|
8
|
+
const sparqlalgebrajs_1 = require("sparqlalgebrajs");
|
|
9
|
+
const DF = new rdf_data_factory_1.DataFactory();
|
|
10
|
+
const FACTORY = new sparqlalgebrajs_1.Factory();
|
|
11
|
+
/**
|
|
12
|
+
* An iterator that implements the multi-length property path operation (* and +)
|
|
13
|
+
* for a fixed subject and predicate, and a variable object.
|
|
14
|
+
*/
|
|
15
|
+
class PathVariableObjectIterator extends asynciterator_1.BufferedIterator {
|
|
16
|
+
constructor(subject, predicate, graph, context, mediatorQueryOperation, emitFirstSubject, maxRunningOperations = 16) {
|
|
17
|
+
// The autoStart flag must be true to kickstart metadata collection
|
|
18
|
+
super({ autoStart: true });
|
|
19
|
+
this.subject = subject;
|
|
20
|
+
this.predicate = predicate;
|
|
21
|
+
this.graph = graph;
|
|
22
|
+
this.context = context;
|
|
23
|
+
this.mediatorQueryOperation = mediatorQueryOperation;
|
|
24
|
+
this.maxRunningOperations = maxRunningOperations;
|
|
25
|
+
this.termHashes = new Map();
|
|
26
|
+
this.runningOperations = [];
|
|
27
|
+
this.pendingOperations = [];
|
|
28
|
+
// Push the subject as starting point
|
|
29
|
+
this._push(this.subject, emitFirstSubject);
|
|
30
|
+
}
|
|
31
|
+
_end(destroy) {
|
|
32
|
+
// Close all running iterators
|
|
33
|
+
for (const it of this.runningOperations) {
|
|
34
|
+
it.destroy();
|
|
35
|
+
}
|
|
36
|
+
super._end(destroy);
|
|
37
|
+
}
|
|
38
|
+
_push(item, pushAsResult = true) {
|
|
39
|
+
let termString;
|
|
40
|
+
if (pushAsResult) {
|
|
41
|
+
// Don't push if this subject was already found
|
|
42
|
+
termString = (0, rdf_string_1.termToString)(item);
|
|
43
|
+
if (this.termHashes.has(termString)) {
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
// Add a pending path operation for this item
|
|
48
|
+
const variable = DF.variable('b');
|
|
49
|
+
this.pendingOperations.push({
|
|
50
|
+
variable,
|
|
51
|
+
operation: FACTORY.createPath(item, this.predicate, variable, this.graph),
|
|
52
|
+
});
|
|
53
|
+
// Otherwise, push the subject
|
|
54
|
+
if (termString) {
|
|
55
|
+
this.termHashes.set(termString, item);
|
|
56
|
+
super._push(item);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
_read(count, done) {
|
|
60
|
+
// eslint-disable-next-line @typescript-eslint/no-this-alias,consistent-this
|
|
61
|
+
const self = this;
|
|
62
|
+
(async function () {
|
|
63
|
+
// Open as many operations as possible
|
|
64
|
+
while (self.runningOperations.length < self.maxRunningOperations) {
|
|
65
|
+
if (self.pendingOperations.length === 0) {
|
|
66
|
+
break;
|
|
67
|
+
}
|
|
68
|
+
const pendingOperation = self.pendingOperations.pop();
|
|
69
|
+
const results = bus_query_operation_1.ActorQueryOperation.getSafeBindings(await self.mediatorQueryOperation.mediate({ operation: pendingOperation.operation, context: self.context }));
|
|
70
|
+
const runningOperation = results.bindingsStream.transform({
|
|
71
|
+
autoStart: false,
|
|
72
|
+
transform(bindings, next, push) {
|
|
73
|
+
const newTerm = bindings.get(pendingOperation.variable);
|
|
74
|
+
push(newTerm);
|
|
75
|
+
next();
|
|
76
|
+
},
|
|
77
|
+
});
|
|
78
|
+
if (!runningOperation.done) {
|
|
79
|
+
self.runningOperations.push(runningOperation);
|
|
80
|
+
runningOperation.on('error', error => self.destroy(error));
|
|
81
|
+
runningOperation.on('readable', () => {
|
|
82
|
+
self.readable = true;
|
|
83
|
+
self._fillBufferAsync();
|
|
84
|
+
});
|
|
85
|
+
runningOperation.on('end', () => {
|
|
86
|
+
self.runningOperations.splice(self.runningOperations.indexOf(runningOperation), 1);
|
|
87
|
+
self.readable = true;
|
|
88
|
+
self._fillBufferAsync();
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
self.setProperty('metadata', results.metadata);
|
|
92
|
+
}
|
|
93
|
+
// Try to read `count` items (based on UnionIterator)
|
|
94
|
+
let lastCount = 0;
|
|
95
|
+
let item;
|
|
96
|
+
// eslint-disable-next-line no-cond-assign
|
|
97
|
+
while (lastCount !== (lastCount = count)) {
|
|
98
|
+
// Prioritize the operations that have been added first
|
|
99
|
+
for (let i = 0; i < self.runningOperations.length && count > 0; i++) {
|
|
100
|
+
// eslint-disable-next-line no-cond-assign
|
|
101
|
+
if ((item = self.runningOperations[i].read()) !== null) {
|
|
102
|
+
count--;
|
|
103
|
+
self._push(item);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
// Close if everything has been read
|
|
108
|
+
if (self.runningOperations.length === 0 && self.pendingOperations.length === 0) {
|
|
109
|
+
self.close();
|
|
110
|
+
}
|
|
111
|
+
})().then(() => {
|
|
112
|
+
done();
|
|
113
|
+
}, error => this.destroy(error));
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
exports.PathVariableObjectIterator = PathVariableObjectIterator;
|
|
117
|
+
//# sourceMappingURL=PathVariableObjectIterator.js.map
|
package/lib/index.d.ts
CHANGED
package/lib/index.js
CHANGED
|
@@ -15,4 +15,5 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
15
15
|
};
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
17
|
__exportStar(require("./ActorAbstractPath"), exports);
|
|
18
|
+
__exportStar(require("./PathVariableObjectIterator"), exports);
|
|
18
19
|
//# sourceMappingURL=index.js.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@comunica/actor-abstract-path",
|
|
3
|
-
"version": "2.3.1-alpha.
|
|
3
|
+
"version": "2.3.1-alpha.30.0",
|
|
4
4
|
"description": "An abstract actor for handling mediatypes",
|
|
5
5
|
"lsd:module": true,
|
|
6
6
|
"main": "lib/index.js",
|
|
@@ -31,11 +31,11 @@
|
|
|
31
31
|
"lib/**/*.js"
|
|
32
32
|
],
|
|
33
33
|
"dependencies": {
|
|
34
|
-
"@comunica/bindings-factory": "2.3.1-alpha.
|
|
35
|
-
"@comunica/bus-query-operation": "2.3.1-alpha.
|
|
36
|
-
"@comunica/context-entries": "2.3.1-alpha.
|
|
37
|
-
"@comunica/core": "2.3.1-alpha.
|
|
38
|
-
"@comunica/types": "2.3.1-alpha.
|
|
34
|
+
"@comunica/bindings-factory": "2.3.1-alpha.30.0",
|
|
35
|
+
"@comunica/bus-query-operation": "2.3.1-alpha.30.0",
|
|
36
|
+
"@comunica/context-entries": "2.3.1-alpha.30.0",
|
|
37
|
+
"@comunica/core": "2.3.1-alpha.30.0",
|
|
38
|
+
"@comunica/types": "2.3.1-alpha.30.0",
|
|
39
39
|
"@rdfjs/types": "*",
|
|
40
40
|
"asynciterator": "^3.4.2",
|
|
41
41
|
"rdf-data-factory": "^1.0.3",
|
|
@@ -47,5 +47,5 @@
|
|
|
47
47
|
"build:ts": "node \"../../node_modules/typescript/bin/tsc\"",
|
|
48
48
|
"build:components": "componentsjs-generator"
|
|
49
49
|
},
|
|
50
|
-
"gitHead": "
|
|
50
|
+
"gitHead": "c6ed42aa75c9be9622fd11a60d2d923f1f092c18"
|
|
51
51
|
}
|