n3 1.21.0 → 1.21.2
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/README.md +3 -5
- package/browser/n3.min.js +1 -1
- package/lib/N3Store.js +78 -2
- package/package.json +3 -3
- package/src/N3Store.js +85 -2
package/lib/N3Store.js
CHANGED
|
@@ -21,6 +21,32 @@ function merge(target, source, depth = 4) {
|
|
|
21
21
|
return target;
|
|
22
22
|
}
|
|
23
23
|
|
|
24
|
+
/**
|
|
25
|
+
* Determines the intersection of the `_graphs` index s1 and s2.
|
|
26
|
+
* s1 and s2 *must* belong to Stores that share an `_entityIndex`.
|
|
27
|
+
*
|
|
28
|
+
* False is returned when there is no intersection; this should
|
|
29
|
+
* *not* be set as the value for an index.
|
|
30
|
+
*/
|
|
31
|
+
function intersect(s1, s2, depth = 4) {
|
|
32
|
+
let target = false;
|
|
33
|
+
for (const key in s1) {
|
|
34
|
+
if (key in s2) {
|
|
35
|
+
const intersection = depth === 0 ? null : intersect(s1[key], s2[key], depth - 1);
|
|
36
|
+
if (intersection !== false) {
|
|
37
|
+
target = target || Object.create(null);
|
|
38
|
+
target[key] = intersection;
|
|
39
|
+
}
|
|
40
|
+
// Depth 3 is the 'subjects', 'predicates' and 'objects' keys.
|
|
41
|
+
// If the 'subjects' index is empty, so will the 'predicates' and 'objects' index.
|
|
42
|
+
else if (depth === 3) {
|
|
43
|
+
return false;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
return target;
|
|
48
|
+
}
|
|
49
|
+
|
|
24
50
|
// ## Constructor
|
|
25
51
|
class N3EntityIndex {
|
|
26
52
|
constructor(options = {}) {
|
|
@@ -851,6 +877,17 @@ class N3Store {
|
|
|
851
877
|
});
|
|
852
878
|
store._graphs = merge(Object.create(null), this._graphs);
|
|
853
879
|
store._size = this._size;
|
|
880
|
+
return store;
|
|
881
|
+
} else if (other instanceof N3Store && this._entityIndex === other._entityIndex) {
|
|
882
|
+
const store = new N3Store({
|
|
883
|
+
entityIndex: this._entityIndex
|
|
884
|
+
});
|
|
885
|
+
const graphs = intersect(other._graphs, this._graphs);
|
|
886
|
+
if (graphs) {
|
|
887
|
+
store._graphs = graphs;
|
|
888
|
+
store._size = null;
|
|
889
|
+
}
|
|
890
|
+
return store;
|
|
854
891
|
}
|
|
855
892
|
return this.filter(quad => other.has(quad));
|
|
856
893
|
}
|
|
@@ -939,9 +976,33 @@ class N3Store {
|
|
|
939
976
|
}
|
|
940
977
|
|
|
941
978
|
/**
|
|
942
|
-
*
|
|
979
|
+
* Returns a subset of the `index` with that part of the index
|
|
980
|
+
* matching the `ids` array. `ids` contains 3 elements that are
|
|
981
|
+
* either numerical ids; or `null`.
|
|
982
|
+
*
|
|
983
|
+
* `false` is returned when there are no matching indices; this should
|
|
984
|
+
* *not* be set as the value for an index.
|
|
943
985
|
*/
|
|
944
986
|
exports.default = N3Store;
|
|
987
|
+
function indexMatch(index, ids, depth = 0) {
|
|
988
|
+
const ind = ids[depth];
|
|
989
|
+
if (ind && !(ind in index)) return false;
|
|
990
|
+
let target = false;
|
|
991
|
+
for (const key in ind ? {
|
|
992
|
+
[ind]: index[ind]
|
|
993
|
+
} : index) {
|
|
994
|
+
const result = depth === 2 ? null : indexMatch(index[key], ids, depth + 1);
|
|
995
|
+
if (result !== false) {
|
|
996
|
+
target = target || Object.create(null);
|
|
997
|
+
target[key] = result;
|
|
998
|
+
}
|
|
999
|
+
}
|
|
1000
|
+
return target;
|
|
1001
|
+
}
|
|
1002
|
+
|
|
1003
|
+
/**
|
|
1004
|
+
* A class that implements both DatasetCore and Readable.
|
|
1005
|
+
*/
|
|
945
1006
|
class DatasetCoreAndReadableStream extends _readableStream.Readable {
|
|
946
1007
|
constructor(n3Store, subject, predicate, object, graph, options) {
|
|
947
1008
|
super({
|
|
@@ -969,7 +1030,22 @@ class DatasetCoreAndReadableStream extends _readableStream.Readable {
|
|
|
969
1030
|
factory: n3Store._factory,
|
|
970
1031
|
entityIndex: this.options.entityIndex
|
|
971
1032
|
});
|
|
972
|
-
|
|
1033
|
+
const graphs = n3Store._getGraphs(graph);
|
|
1034
|
+
let subjectId, predicateId, objectId;
|
|
1035
|
+
|
|
1036
|
+
// Translate IRIs to internal index keys.
|
|
1037
|
+
if (subject && !(subjectId = newStore._termToNumericId(subject)) || predicate && !(predicateId = newStore._termToNumericId(predicate)) || object && !(objectId = newStore._termToNumericId(object))) return newStore;
|
|
1038
|
+
for (const graph in graphs) {
|
|
1039
|
+
const subjects = indexMatch(graphs[graph].subjects, [subjectId, predicateId, objectId]);
|
|
1040
|
+
if (subjects) {
|
|
1041
|
+
newStore._graphs[graph] = {
|
|
1042
|
+
subjects,
|
|
1043
|
+
predicates: indexMatch(graphs[graph].predicates, [predicateId, objectId, subjectId]),
|
|
1044
|
+
objects: indexMatch(graphs[graph].objects, [objectId, subjectId, predicateId])
|
|
1045
|
+
};
|
|
1046
|
+
}
|
|
1047
|
+
}
|
|
1048
|
+
newStore._size = null;
|
|
973
1049
|
}
|
|
974
1050
|
return this._filtered;
|
|
975
1051
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "n3",
|
|
3
|
-
"version": "1.21.
|
|
3
|
+
"version": "1.21.2",
|
|
4
4
|
"description": "Lightning fast, asynchronous, streaming Turtle / N3 / RDF library.",
|
|
5
5
|
"author": "Ruben Verborgh <ruben.verborgh@gmail.com>",
|
|
6
6
|
"keywords": [
|
|
@@ -34,9 +34,9 @@
|
|
|
34
34
|
"@babel/preset-env": "^7.16.0",
|
|
35
35
|
"@babel/register": "^7.16.0",
|
|
36
36
|
"@rdfjs/data-model": "^1",
|
|
37
|
-
"arrayify-stream": "^
|
|
37
|
+
"arrayify-stream": "^3.0.0",
|
|
38
38
|
"browserify": "^17.0.0",
|
|
39
|
-
"deep-taxonomy-benchmark": "^
|
|
39
|
+
"deep-taxonomy-benchmark": "^2.0.0",
|
|
40
40
|
"docco": "^0.9.1",
|
|
41
41
|
"eslint": "^8.57.0",
|
|
42
42
|
"eslint-plugin-import": "^2.29.1",
|
package/src/N3Store.js
CHANGED
|
@@ -17,6 +17,34 @@ function merge(target, source, depth = 4) {
|
|
|
17
17
|
return target;
|
|
18
18
|
}
|
|
19
19
|
|
|
20
|
+
/**
|
|
21
|
+
* Determines the intersection of the `_graphs` index s1 and s2.
|
|
22
|
+
* s1 and s2 *must* belong to Stores that share an `_entityIndex`.
|
|
23
|
+
*
|
|
24
|
+
* False is returned when there is no intersection; this should
|
|
25
|
+
* *not* be set as the value for an index.
|
|
26
|
+
*/
|
|
27
|
+
function intersect(s1, s2, depth = 4) {
|
|
28
|
+
let target = false;
|
|
29
|
+
|
|
30
|
+
for (const key in s1) {
|
|
31
|
+
if (key in s2) {
|
|
32
|
+
const intersection = depth === 0 ? null : intersect(s1[key], s2[key], depth - 1);
|
|
33
|
+
if (intersection !== false) {
|
|
34
|
+
target = target || Object.create(null);
|
|
35
|
+
target[key] = intersection;
|
|
36
|
+
}
|
|
37
|
+
// Depth 3 is the 'subjects', 'predicates' and 'objects' keys.
|
|
38
|
+
// If the 'subjects' index is empty, so will the 'predicates' and 'objects' index.
|
|
39
|
+
else if (depth === 3) {
|
|
40
|
+
return false;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
return target;
|
|
46
|
+
}
|
|
47
|
+
|
|
20
48
|
// ## Constructor
|
|
21
49
|
export class N3EntityIndex {
|
|
22
50
|
constructor(options = {}) {
|
|
@@ -901,7 +929,18 @@ export default class N3Store {
|
|
|
901
929
|
const store = new N3Store({ entityIndex: this._entityIndex });
|
|
902
930
|
store._graphs = merge(Object.create(null), this._graphs);
|
|
903
931
|
store._size = this._size;
|
|
932
|
+
return store;
|
|
933
|
+
}
|
|
934
|
+
else if ((other instanceof N3Store) && this._entityIndex === other._entityIndex) {
|
|
935
|
+
const store = new N3Store({ entityIndex: this._entityIndex });
|
|
936
|
+
const graphs = intersect(other._graphs, this._graphs);
|
|
937
|
+
if (graphs) {
|
|
938
|
+
store._graphs = graphs;
|
|
939
|
+
store._size = null;
|
|
940
|
+
}
|
|
941
|
+
return store;
|
|
904
942
|
}
|
|
943
|
+
|
|
905
944
|
return this.filter(quad => other.has(quad));
|
|
906
945
|
}
|
|
907
946
|
|
|
@@ -987,6 +1026,31 @@ export default class N3Store {
|
|
|
987
1026
|
}
|
|
988
1027
|
}
|
|
989
1028
|
|
|
1029
|
+
/**
|
|
1030
|
+
* Returns a subset of the `index` with that part of the index
|
|
1031
|
+
* matching the `ids` array. `ids` contains 3 elements that are
|
|
1032
|
+
* either numerical ids; or `null`.
|
|
1033
|
+
*
|
|
1034
|
+
* `false` is returned when there are no matching indices; this should
|
|
1035
|
+
* *not* be set as the value for an index.
|
|
1036
|
+
*/
|
|
1037
|
+
function indexMatch(index, ids, depth = 0) {
|
|
1038
|
+
const ind = ids[depth];
|
|
1039
|
+
if (ind && !(ind in index))
|
|
1040
|
+
return false;
|
|
1041
|
+
|
|
1042
|
+
let target = false;
|
|
1043
|
+
for (const key in (ind ? { [ind]: index[ind] } : index)) {
|
|
1044
|
+
const result = depth === 2 ? null : indexMatch(index[key], ids, depth + 1);
|
|
1045
|
+
|
|
1046
|
+
if (result !== false) {
|
|
1047
|
+
target = target || Object.create(null);
|
|
1048
|
+
target[key] = result;
|
|
1049
|
+
}
|
|
1050
|
+
}
|
|
1051
|
+
return target;
|
|
1052
|
+
}
|
|
1053
|
+
|
|
990
1054
|
/**
|
|
991
1055
|
* A class that implements both DatasetCore and Readable.
|
|
992
1056
|
*/
|
|
@@ -1000,8 +1064,27 @@ class DatasetCoreAndReadableStream extends Readable {
|
|
|
1000
1064
|
if (!this._filtered) {
|
|
1001
1065
|
const { n3Store, graph, object, predicate, subject } = this;
|
|
1002
1066
|
const newStore = this._filtered = new N3Store({ factory: n3Store._factory, entityIndex: this.options.entityIndex });
|
|
1003
|
-
|
|
1004
|
-
|
|
1067
|
+
const graphs = n3Store._getGraphs(graph);
|
|
1068
|
+
|
|
1069
|
+
let subjectId, predicateId, objectId;
|
|
1070
|
+
|
|
1071
|
+
// Translate IRIs to internal index keys.
|
|
1072
|
+
if (subject && !(subjectId = newStore._termToNumericId(subject)) ||
|
|
1073
|
+
predicate && !(predicateId = newStore._termToNumericId(predicate)) ||
|
|
1074
|
+
object && !(objectId = newStore._termToNumericId(object)))
|
|
1075
|
+
return newStore;
|
|
1076
|
+
|
|
1077
|
+
for (const graph in graphs) {
|
|
1078
|
+
const subjects = indexMatch(graphs[graph].subjects, [subjectId, predicateId, objectId]);
|
|
1079
|
+
if (subjects) {
|
|
1080
|
+
newStore._graphs[graph] = {
|
|
1081
|
+
subjects,
|
|
1082
|
+
predicates: indexMatch(graphs[graph].predicates, [predicateId, objectId, subjectId]),
|
|
1083
|
+
objects: indexMatch(graphs[graph].objects, [objectId, subjectId, predicateId]),
|
|
1084
|
+
};
|
|
1085
|
+
}
|
|
1086
|
+
}
|
|
1087
|
+
newStore._size = null;
|
|
1005
1088
|
}
|
|
1006
1089
|
return this._filtered;
|
|
1007
1090
|
}
|