n3 1.20.3 → 1.21.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/README.md +34 -8
- package/browser/n3.min.js +1 -1
- package/lib/N3Lexer.js +3 -3
- package/lib/N3Parser.js +31 -7
- package/lib/N3Store.js +31 -4
- package/lib/N3StreamParser.js +14 -9
- package/package.json +2 -3
- package/src/N3DataFactory.js +1 -1
- package/src/N3Lexer.js +3 -3
- package/src/N3Parser.js +38 -7
- package/src/N3Store.js +32 -5
- package/src/N3StreamParser.js +12 -6
package/lib/N3Lexer.js
CHANGED
|
@@ -97,7 +97,7 @@ class N3Lexer {
|
|
|
97
97
|
this._n3Mode = options.n3 !== false;
|
|
98
98
|
}
|
|
99
99
|
// Don't output comment tokens by default
|
|
100
|
-
this.
|
|
100
|
+
this.comments = !!options.comments;
|
|
101
101
|
// Cache the last tested closing position of long literals
|
|
102
102
|
this._literalClosingPos = 0;
|
|
103
103
|
}
|
|
@@ -114,7 +114,7 @@ class N3Lexer {
|
|
|
114
114
|
let whiteSpaceMatch, comment;
|
|
115
115
|
while (whiteSpaceMatch = this._newline.exec(input)) {
|
|
116
116
|
// Try to find a comment
|
|
117
|
-
if (this.
|
|
117
|
+
if (this.comments && (comment = this._comment.exec(whiteSpaceMatch[0]))) emitToken('comment', comment[1], '', this._line, whiteSpaceMatch[0].length);
|
|
118
118
|
// Advance the input
|
|
119
119
|
input = input.substr(whiteSpaceMatch[0].length, input.length);
|
|
120
120
|
currentLineLength = input.length;
|
|
@@ -128,7 +128,7 @@ class N3Lexer {
|
|
|
128
128
|
// If the input is finished, emit EOF
|
|
129
129
|
if (inputFinished) {
|
|
130
130
|
// Try to find a final comment
|
|
131
|
-
if (this.
|
|
131
|
+
if (this.comments && (comment = this._comment.exec(input))) emitToken('comment', comment[1], '', this._line, input.length);
|
|
132
132
|
input = null;
|
|
133
133
|
emitToken('eof', '', '', this._line, 0);
|
|
134
134
|
}
|
package/lib/N3Parser.js
CHANGED
|
@@ -943,20 +943,31 @@ class N3Parser {
|
|
|
943
943
|
|
|
944
944
|
// ## Public methods
|
|
945
945
|
|
|
946
|
-
// ### `parse` parses the N3 input and emits each parsed quad through the callback
|
|
946
|
+
// ### `parse` parses the N3 input and emits each parsed quad through the onQuad callback.
|
|
947
947
|
parse(input, quadCallback, prefixCallback) {
|
|
948
|
+
// The second parameter accepts an object { onQuad: ..., onPrefix: ..., onComment: ...}
|
|
949
|
+
// As a second and third parameter it still accepts a separate quadCallback and prefixCallback for backward compatibility as well
|
|
950
|
+
let onQuad, onPrefix, onComment;
|
|
951
|
+
if (quadCallback && (quadCallback.onQuad || quadCallback.onPrefix || quadCallback.onComment)) {
|
|
952
|
+
onQuad = quadCallback.onQuad;
|
|
953
|
+
onPrefix = quadCallback.onPrefix;
|
|
954
|
+
onComment = quadCallback.onComment;
|
|
955
|
+
} else {
|
|
956
|
+
onQuad = quadCallback;
|
|
957
|
+
onPrefix = prefixCallback;
|
|
958
|
+
}
|
|
948
959
|
// The read callback is the next function to be executed when a token arrives.
|
|
949
960
|
// We start reading in the top context.
|
|
950
961
|
this._readCallback = this._readInTopContext;
|
|
951
962
|
this._sparqlStyle = false;
|
|
952
963
|
this._prefixes = Object.create(null);
|
|
953
964
|
this._prefixes._ = this._blankNodePrefix ? this._blankNodePrefix.substr(2) : `b${blankNodePrefix++}_`;
|
|
954
|
-
this._prefixCallback =
|
|
965
|
+
this._prefixCallback = onPrefix || noop;
|
|
955
966
|
this._inversePredicate = false;
|
|
956
967
|
this._quantified = Object.create(null);
|
|
957
968
|
|
|
958
969
|
// Parse synchronously if no quad callback is given
|
|
959
|
-
if (!
|
|
970
|
+
if (!onQuad) {
|
|
960
971
|
const quads = [];
|
|
961
972
|
let error;
|
|
962
973
|
this._callback = (e, t) => {
|
|
@@ -968,12 +979,25 @@ class N3Parser {
|
|
|
968
979
|
if (error) throw error;
|
|
969
980
|
return quads;
|
|
970
981
|
}
|
|
982
|
+
let processNextToken = (error, token) => {
|
|
983
|
+
if (error !== null) this._callback(error), this._callback = noop;else if (this._readCallback) this._readCallback = this._readCallback(token);
|
|
984
|
+
};
|
|
985
|
+
|
|
986
|
+
// Enable checking for comments on every token when a commentCallback has been set
|
|
987
|
+
if (onComment) {
|
|
988
|
+
// Enable the lexer to return comments as tokens first (disabled by default)
|
|
989
|
+
this._lexer.comments = true;
|
|
990
|
+
// Patch the processNextToken function
|
|
991
|
+
processNextToken = (error, token) => {
|
|
992
|
+
if (error !== null) this._callback(error), this._callback = noop;else if (this._readCallback) {
|
|
993
|
+
if (token.type === 'comment') onComment(token.value);else this._readCallback = this._readCallback(token);
|
|
994
|
+
}
|
|
995
|
+
};
|
|
996
|
+
}
|
|
971
997
|
|
|
972
998
|
// Parse asynchronously otherwise, executing the read callback when a token arrives
|
|
973
|
-
this._callback =
|
|
974
|
-
this._lexer.tokenize(input,
|
|
975
|
-
if (error !== null) this._callback(error), this._callback = noop;else if (this._readCallback) this._readCallback = this._readCallback(token);
|
|
976
|
-
});
|
|
999
|
+
this._callback = onQuad;
|
|
1000
|
+
this._lexer.tokenize(input, processNextToken);
|
|
977
1001
|
}
|
|
978
1002
|
}
|
|
979
1003
|
|
package/lib/N3Store.js
CHANGED
|
@@ -15,6 +15,11 @@ function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e;
|
|
|
15
15
|
// **N3Store** objects store N3 quads by graph in memory.
|
|
16
16
|
|
|
17
17
|
const ITERATOR = Symbol('iter');
|
|
18
|
+
function merge(target, source, depth = 4) {
|
|
19
|
+
if (depth === 0) return Object.assign(target, source);
|
|
20
|
+
for (const key in source) target[key] = merge(target[key] || Object.create(null), source[key], depth - 1);
|
|
21
|
+
return target;
|
|
22
|
+
}
|
|
18
23
|
|
|
19
24
|
// ## Constructor
|
|
20
25
|
class N3EntityIndex {
|
|
@@ -125,7 +130,7 @@ class N3Store {
|
|
|
125
130
|
const index1 = index0[key0] || (index0[key0] = {});
|
|
126
131
|
const index2 = index1[key1] || (index1[key1] = {});
|
|
127
132
|
// Setting the key to _any_ value signals the presence of the quad
|
|
128
|
-
const existed =
|
|
133
|
+
const existed = key2 in index2;
|
|
129
134
|
if (!existed) index2[key2] = null;
|
|
130
135
|
return !existed;
|
|
131
136
|
}
|
|
@@ -345,7 +350,12 @@ class N3Store {
|
|
|
345
350
|
// ### `removeQuad` removes a quad from the store if it exists
|
|
346
351
|
removeQuad(subject, predicate, object, graph) {
|
|
347
352
|
// Shift arguments if a quad object is given instead of components
|
|
348
|
-
if (!predicate)
|
|
353
|
+
if (!predicate) ({
|
|
354
|
+
subject,
|
|
355
|
+
predicate,
|
|
356
|
+
object,
|
|
357
|
+
graph
|
|
358
|
+
} = subject);
|
|
349
359
|
// Convert terms to internal string representation
|
|
350
360
|
graph = graph ? this._termToNumericId(graph) : 1;
|
|
351
361
|
|
|
@@ -746,7 +756,12 @@ class N3Store {
|
|
|
746
756
|
* Blank Nodes will be normalized.
|
|
747
757
|
*/
|
|
748
758
|
addAll(quads) {
|
|
749
|
-
if (Array.isArray(quads)) this.addQuads(quads);else {
|
|
759
|
+
if (Array.isArray(quads)) this.addQuads(quads);else if (quads instanceof N3Store && quads._entityIndex === this._entityIndex) {
|
|
760
|
+
if (quads._size !== 0) {
|
|
761
|
+
this._graphs = merge(this._graphs, quads._graphs);
|
|
762
|
+
this._size = null; // Invalidate the cached size
|
|
763
|
+
}
|
|
764
|
+
} else {
|
|
750
765
|
for (const quad of quads) this.add(quad);
|
|
751
766
|
}
|
|
752
767
|
return this;
|
|
@@ -759,6 +774,7 @@ class N3Store {
|
|
|
759
774
|
* Blank Nodes will be normalized.
|
|
760
775
|
*/
|
|
761
776
|
contains(other) {
|
|
777
|
+
if (other === this) return true;
|
|
762
778
|
if (!(other instanceof N3Store) || this._entityIndex !== other._entityIndex) return other.every(quad => this.has(quad));
|
|
763
779
|
const g1 = this._graphs,
|
|
764
780
|
g2 = other._graphs;
|
|
@@ -797,6 +813,9 @@ class N3Store {
|
|
|
797
813
|
* Returns a new dataset that contains all quads from the current dataset that are not included in the given dataset.
|
|
798
814
|
*/
|
|
799
815
|
difference(other) {
|
|
816
|
+
if (other === this) return new N3Store({
|
|
817
|
+
entityIndex: this._entityIndex
|
|
818
|
+
});
|
|
800
819
|
return this.filter(quad => !other.has(quad));
|
|
801
820
|
}
|
|
802
821
|
|
|
@@ -826,6 +845,13 @@ class N3Store {
|
|
|
826
845
|
* Returns a new dataset containing all quads from the current dataset that are also included in the given dataset.
|
|
827
846
|
*/
|
|
828
847
|
intersection(other) {
|
|
848
|
+
if (other === this) {
|
|
849
|
+
const store = new N3Store({
|
|
850
|
+
entityIndex: this._entityIndex
|
|
851
|
+
});
|
|
852
|
+
store._graphs = merge(Object.create(null), this._graphs);
|
|
853
|
+
store._size = this._size;
|
|
854
|
+
}
|
|
829
855
|
return this.filter(quad => other.has(quad));
|
|
830
856
|
}
|
|
831
857
|
|
|
@@ -898,7 +924,8 @@ class N3Store {
|
|
|
898
924
|
const store = new N3Store({
|
|
899
925
|
entityIndex: this._entityIndex
|
|
900
926
|
});
|
|
901
|
-
store.
|
|
927
|
+
store._graphs = merge(Object.create(null), this._graphs);
|
|
928
|
+
store._size = this._size;
|
|
902
929
|
store.addAll(quads);
|
|
903
930
|
return store;
|
|
904
931
|
}
|
package/lib/N3StreamParser.js
CHANGED
|
@@ -20,6 +20,19 @@ class N3StreamParser extends _readableStream.Transform {
|
|
|
20
20
|
// Set up parser with dummy stream to obtain `data` and `end` callbacks
|
|
21
21
|
const parser = new _N3Parser.default(options);
|
|
22
22
|
let onData, onEnd;
|
|
23
|
+
const callbacks = {
|
|
24
|
+
// Handle quads by pushing them down the pipeline
|
|
25
|
+
onQuad: (error, quad) => {
|
|
26
|
+
error && this.emit('error', error) || quad && this.push(quad);
|
|
27
|
+
},
|
|
28
|
+
// Emit prefixes through the `prefix` event
|
|
29
|
+
onPrefix: (prefix, uri) => {
|
|
30
|
+
this.emit('prefix', prefix, uri);
|
|
31
|
+
}
|
|
32
|
+
};
|
|
33
|
+
if (options && options.comments) callbacks.onComment = comment => {
|
|
34
|
+
this.emit('comment', comment);
|
|
35
|
+
};
|
|
23
36
|
parser.parse({
|
|
24
37
|
on: (event, callback) => {
|
|
25
38
|
switch (event) {
|
|
@@ -31,15 +44,7 @@ class N3StreamParser extends _readableStream.Transform {
|
|
|
31
44
|
break;
|
|
32
45
|
}
|
|
33
46
|
}
|
|
34
|
-
},
|
|
35
|
-
// Handle quads by pushing them down the pipeline
|
|
36
|
-
(error, quad) => {
|
|
37
|
-
error && this.emit('error', error) || quad && this.push(quad);
|
|
38
|
-
},
|
|
39
|
-
// Emit prefixes through the `prefix` event
|
|
40
|
-
(prefix, uri) => {
|
|
41
|
-
this.emit('prefix', prefix, uri);
|
|
42
|
-
});
|
|
47
|
+
}, callbacks);
|
|
43
48
|
|
|
44
49
|
// Implement Transform methods through parser callbacks
|
|
45
50
|
this._transform = (chunk, encoding, done) => {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "n3",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.21.0",
|
|
4
4
|
"description": "Lightning fast, asynchronous, streaming Turtle / N3 / RDF library.",
|
|
5
5
|
"author": "Ruben Verborgh <ruben.verborgh@gmail.com>",
|
|
6
6
|
"keywords": [
|
|
@@ -36,10 +36,9 @@
|
|
|
36
36
|
"@rdfjs/data-model": "^1",
|
|
37
37
|
"arrayify-stream": "^1.0.0",
|
|
38
38
|
"browserify": "^17.0.0",
|
|
39
|
-
"colors": "^1.1.2",
|
|
40
39
|
"deep-taxonomy-benchmark": "^1.2.0",
|
|
41
40
|
"docco": "^0.9.1",
|
|
42
|
-
"eslint": "^
|
|
41
|
+
"eslint": "^8.57.0",
|
|
43
42
|
"eslint-plugin-import": "^2.29.1",
|
|
44
43
|
"jest": "^29.7.0",
|
|
45
44
|
"pre-commit": "^1.2.2",
|
package/src/N3DataFactory.js
CHANGED
|
@@ -229,7 +229,7 @@ export function termFromId(id, factory, nested) {
|
|
|
229
229
|
termFromId(id[0], factory, true),
|
|
230
230
|
termFromId(id[1], factory, true),
|
|
231
231
|
termFromId(id[2], factory, true),
|
|
232
|
-
id[3] && termFromId(id[3], factory, true)
|
|
232
|
+
id[3] && termFromId(id[3], factory, true),
|
|
233
233
|
);
|
|
234
234
|
}
|
|
235
235
|
|
package/src/N3Lexer.js
CHANGED
|
@@ -68,7 +68,7 @@ export default class N3Lexer {
|
|
|
68
68
|
this._n3Mode = options.n3 !== false;
|
|
69
69
|
}
|
|
70
70
|
// Don't output comment tokens by default
|
|
71
|
-
this.
|
|
71
|
+
this.comments = !!options.comments;
|
|
72
72
|
// Cache the last tested closing position of long literals
|
|
73
73
|
this._literalClosingPos = 0;
|
|
74
74
|
}
|
|
@@ -85,7 +85,7 @@ export default class N3Lexer {
|
|
|
85
85
|
let whiteSpaceMatch, comment;
|
|
86
86
|
while (whiteSpaceMatch = this._newline.exec(input)) {
|
|
87
87
|
// Try to find a comment
|
|
88
|
-
if (this.
|
|
88
|
+
if (this.comments && (comment = this._comment.exec(whiteSpaceMatch[0])))
|
|
89
89
|
emitToken('comment', comment[1], '', this._line, whiteSpaceMatch[0].length);
|
|
90
90
|
// Advance the input
|
|
91
91
|
input = input.substr(whiteSpaceMatch[0].length, input.length);
|
|
@@ -101,7 +101,7 @@ export default class N3Lexer {
|
|
|
101
101
|
// If the input is finished, emit EOF
|
|
102
102
|
if (inputFinished) {
|
|
103
103
|
// Try to find a final comment
|
|
104
|
-
if (this.
|
|
104
|
+
if (this.comments && (comment = this._comment.exec(input)))
|
|
105
105
|
emitToken('comment', comment[1], '', this._line, input.length);
|
|
106
106
|
input = null;
|
|
107
107
|
emitToken('eof', '', '', this._line, 0);
|
package/src/N3Parser.js
CHANGED
|
@@ -1010,8 +1010,20 @@ export default class N3Parser {
|
|
|
1010
1010
|
|
|
1011
1011
|
// ## Public methods
|
|
1012
1012
|
|
|
1013
|
-
// ### `parse` parses the N3 input and emits each parsed quad through the callback
|
|
1013
|
+
// ### `parse` parses the N3 input and emits each parsed quad through the onQuad callback.
|
|
1014
1014
|
parse(input, quadCallback, prefixCallback) {
|
|
1015
|
+
// The second parameter accepts an object { onQuad: ..., onPrefix: ..., onComment: ...}
|
|
1016
|
+
// As a second and third parameter it still accepts a separate quadCallback and prefixCallback for backward compatibility as well
|
|
1017
|
+
let onQuad, onPrefix, onComment;
|
|
1018
|
+
if (quadCallback && (quadCallback.onQuad || quadCallback.onPrefix || quadCallback.onComment)) {
|
|
1019
|
+
onQuad = quadCallback.onQuad;
|
|
1020
|
+
onPrefix = quadCallback.onPrefix;
|
|
1021
|
+
onComment = quadCallback.onComment;
|
|
1022
|
+
}
|
|
1023
|
+
else {
|
|
1024
|
+
onQuad = quadCallback;
|
|
1025
|
+
onPrefix = prefixCallback;
|
|
1026
|
+
}
|
|
1015
1027
|
// The read callback is the next function to be executed when a token arrives.
|
|
1016
1028
|
// We start reading in the top context.
|
|
1017
1029
|
this._readCallback = this._readInTopContext;
|
|
@@ -1019,12 +1031,12 @@ export default class N3Parser {
|
|
|
1019
1031
|
this._prefixes = Object.create(null);
|
|
1020
1032
|
this._prefixes._ = this._blankNodePrefix ? this._blankNodePrefix.substr(2)
|
|
1021
1033
|
: `b${blankNodePrefix++}_`;
|
|
1022
|
-
this._prefixCallback =
|
|
1034
|
+
this._prefixCallback = onPrefix || noop;
|
|
1023
1035
|
this._inversePredicate = false;
|
|
1024
1036
|
this._quantified = Object.create(null);
|
|
1025
1037
|
|
|
1026
1038
|
// Parse synchronously if no quad callback is given
|
|
1027
|
-
if (!
|
|
1039
|
+
if (!onQuad) {
|
|
1028
1040
|
const quads = [];
|
|
1029
1041
|
let error;
|
|
1030
1042
|
this._callback = (e, t) => { e ? (error = e) : t && quads.push(t); };
|
|
@@ -1035,14 +1047,33 @@ export default class N3Parser {
|
|
|
1035
1047
|
return quads;
|
|
1036
1048
|
}
|
|
1037
1049
|
|
|
1038
|
-
|
|
1039
|
-
this._callback = quadCallback;
|
|
1040
|
-
this._lexer.tokenize(input, (error, token) => {
|
|
1050
|
+
let processNextToken = (error, token) => {
|
|
1041
1051
|
if (error !== null)
|
|
1042
1052
|
this._callback(error), this._callback = noop;
|
|
1043
1053
|
else if (this._readCallback)
|
|
1044
1054
|
this._readCallback = this._readCallback(token);
|
|
1045
|
-
}
|
|
1055
|
+
};
|
|
1056
|
+
|
|
1057
|
+
// Enable checking for comments on every token when a commentCallback has been set
|
|
1058
|
+
if (onComment) {
|
|
1059
|
+
// Enable the lexer to return comments as tokens first (disabled by default)
|
|
1060
|
+
this._lexer.comments = true;
|
|
1061
|
+
// Patch the processNextToken function
|
|
1062
|
+
processNextToken = (error, token) => {
|
|
1063
|
+
if (error !== null)
|
|
1064
|
+
this._callback(error), this._callback = noop;
|
|
1065
|
+
else if (this._readCallback) {
|
|
1066
|
+
if (token.type === 'comment')
|
|
1067
|
+
onComment(token.value);
|
|
1068
|
+
else
|
|
1069
|
+
this._readCallback = this._readCallback(token);
|
|
1070
|
+
}
|
|
1071
|
+
};
|
|
1072
|
+
}
|
|
1073
|
+
|
|
1074
|
+
// Parse asynchronously otherwise, executing the read callback when a token arrives
|
|
1075
|
+
this._callback = onQuad;
|
|
1076
|
+
this._lexer.tokenize(input, processNextToken);
|
|
1046
1077
|
}
|
|
1047
1078
|
}
|
|
1048
1079
|
|
package/src/N3Store.js
CHANGED
|
@@ -7,6 +7,16 @@ import N3Writer from './N3Writer';
|
|
|
7
7
|
|
|
8
8
|
const ITERATOR = Symbol('iter');
|
|
9
9
|
|
|
10
|
+
function merge(target, source, depth = 4) {
|
|
11
|
+
if (depth === 0)
|
|
12
|
+
return Object.assign(target, source);
|
|
13
|
+
|
|
14
|
+
for (const key in source)
|
|
15
|
+
target[key] = merge(target[key] || Object.create(null), source[key], depth - 1);
|
|
16
|
+
|
|
17
|
+
return target;
|
|
18
|
+
}
|
|
19
|
+
|
|
10
20
|
// ## Constructor
|
|
11
21
|
export class N3EntityIndex {
|
|
12
22
|
constructor(options = {}) {
|
|
@@ -31,7 +41,7 @@ export class N3EntityIndex {
|
|
|
31
41
|
this._termFromId(entities[terms[1]]),
|
|
32
42
|
this._termFromId(entities[terms[2]]),
|
|
33
43
|
this._termFromId(entities[terms[3]]),
|
|
34
|
-
terms[4] && this._termFromId(entities[terms[4]])
|
|
44
|
+
terms[4] && this._termFromId(entities[terms[4]]),
|
|
35
45
|
);
|
|
36
46
|
return q;
|
|
37
47
|
}
|
|
@@ -346,8 +356,7 @@ export default class N3Store {
|
|
|
346
356
|
removeQuad(subject, predicate, object, graph) {
|
|
347
357
|
// Shift arguments if a quad object is given instead of components
|
|
348
358
|
if (!predicate)
|
|
349
|
-
|
|
350
|
-
predicate = subject.predicate, subject = subject.subject;
|
|
359
|
+
({ subject, predicate, object, graph } = subject);
|
|
351
360
|
// Convert terms to internal string representation
|
|
352
361
|
graph = graph ? this._termToNumericId(graph) : 1;
|
|
353
362
|
|
|
@@ -792,6 +801,12 @@ export default class N3Store {
|
|
|
792
801
|
addAll(quads) {
|
|
793
802
|
if (Array.isArray(quads))
|
|
794
803
|
this.addQuads(quads);
|
|
804
|
+
else if (quads instanceof N3Store && quads._entityIndex === this._entityIndex) {
|
|
805
|
+
if (quads._size !== 0) {
|
|
806
|
+
this._graphs = merge(this._graphs, quads._graphs);
|
|
807
|
+
this._size = null; // Invalidate the cached size
|
|
808
|
+
}
|
|
809
|
+
}
|
|
795
810
|
else {
|
|
796
811
|
for (const quad of quads)
|
|
797
812
|
this.add(quad);
|
|
@@ -799,7 +814,6 @@ export default class N3Store {
|
|
|
799
814
|
return this;
|
|
800
815
|
}
|
|
801
816
|
|
|
802
|
-
|
|
803
817
|
/**
|
|
804
818
|
* Returns `true` if the current dataset is a superset of the given dataset; in other words, returns `true` if
|
|
805
819
|
* the given dataset is a subset of, i.e., is contained within, the current dataset.
|
|
@@ -807,6 +821,9 @@ export default class N3Store {
|
|
|
807
821
|
* Blank Nodes will be normalized.
|
|
808
822
|
*/
|
|
809
823
|
contains(other) {
|
|
824
|
+
if (other === this)
|
|
825
|
+
return true;
|
|
826
|
+
|
|
810
827
|
if (!(other instanceof N3Store) || this._entityIndex !== other._entityIndex)
|
|
811
828
|
return other.every(quad => this.has(quad));
|
|
812
829
|
|
|
@@ -848,6 +865,9 @@ export default class N3Store {
|
|
|
848
865
|
* Returns a new dataset that contains all quads from the current dataset that are not included in the given dataset.
|
|
849
866
|
*/
|
|
850
867
|
difference(other) {
|
|
868
|
+
if (other === this)
|
|
869
|
+
return new N3Store({ entityIndex: this._entityIndex });
|
|
870
|
+
|
|
851
871
|
return this.filter(quad => !other.has(quad));
|
|
852
872
|
}
|
|
853
873
|
|
|
@@ -877,6 +897,11 @@ export default class N3Store {
|
|
|
877
897
|
* Returns a new dataset containing all quads from the current dataset that are also included in the given dataset.
|
|
878
898
|
*/
|
|
879
899
|
intersection(other) {
|
|
900
|
+
if (other === this) {
|
|
901
|
+
const store = new N3Store({ entityIndex: this._entityIndex });
|
|
902
|
+
store._graphs = merge(Object.create(null), this._graphs);
|
|
903
|
+
store._size = this._size;
|
|
904
|
+
}
|
|
880
905
|
return this.filter(quad => other.has(quad));
|
|
881
906
|
}
|
|
882
907
|
|
|
@@ -947,7 +972,9 @@ export default class N3Store {
|
|
|
947
972
|
*/
|
|
948
973
|
union(quads) {
|
|
949
974
|
const store = new N3Store({ entityIndex: this._entityIndex });
|
|
950
|
-
store.
|
|
975
|
+
store._graphs = merge(Object.create(null), this._graphs);
|
|
976
|
+
store._size = this._size;
|
|
977
|
+
|
|
951
978
|
store.addAll(quads);
|
|
952
979
|
return store;
|
|
953
980
|
}
|
package/src/N3StreamParser.js
CHANGED
|
@@ -11,6 +11,17 @@ export default class N3StreamParser extends Transform {
|
|
|
11
11
|
// Set up parser with dummy stream to obtain `data` and `end` callbacks
|
|
12
12
|
const parser = new N3Parser(options);
|
|
13
13
|
let onData, onEnd;
|
|
14
|
+
|
|
15
|
+
const callbacks = {
|
|
16
|
+
// Handle quads by pushing them down the pipeline
|
|
17
|
+
onQuad: (error, quad) => { error && this.emit('error', error) || quad && this.push(quad); },
|
|
18
|
+
// Emit prefixes through the `prefix` event
|
|
19
|
+
onPrefix: (prefix, uri) => { this.emit('prefix', prefix, uri); },
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
if (options && options.comments)
|
|
23
|
+
callbacks.onComment = comment => { this.emit('comment', comment); };
|
|
24
|
+
|
|
14
25
|
parser.parse({
|
|
15
26
|
on: (event, callback) => {
|
|
16
27
|
switch (event) {
|
|
@@ -18,12 +29,7 @@ export default class N3StreamParser extends Transform {
|
|
|
18
29
|
case 'end': onEnd = callback; break;
|
|
19
30
|
}
|
|
20
31
|
},
|
|
21
|
-
},
|
|
22
|
-
// Handle quads by pushing them down the pipeline
|
|
23
|
-
(error, quad) => { error && this.emit('error', error) || quad && this.push(quad); },
|
|
24
|
-
// Emit prefixes through the `prefix` event
|
|
25
|
-
(prefix, uri) => { this.emit('prefix', prefix, uri); }
|
|
26
|
-
);
|
|
32
|
+
}, callbacks);
|
|
27
33
|
|
|
28
34
|
// Implement Transform methods through parser callbacks
|
|
29
35
|
this._transform = (chunk, encoding, done) => { onData(chunk); done(); };
|