n3 2.7.2 → 2.7.4
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/browser/n3.esm.min.js +4 -4
- package/browser/n3.min.js +7 -7
- package/lib/N3Lexer.js +25 -2
- package/lib/N3Parser.js +41 -7
- package/lib/N3Store.js +3 -0
- package/package.json +1 -1
- package/src/N3Lexer.js +29 -2
- package/src/N3Parser.js +46 -11
- package/src/N3Store.js +3 -0
package/lib/N3Lexer.js
CHANGED
|
@@ -322,11 +322,11 @@ class N3Lexer {
|
|
|
322
322
|
case 'h':
|
|
323
323
|
case 'o':
|
|
324
324
|
// Try to find an N3 verb keyword
|
|
325
|
-
if (this._n3Mode && (match = this.
|
|
325
|
+
if (this._n3Mode && (match = this._matchN3Verb(input, inputFinished))) type = match[0];else inconclusive = true;
|
|
326
326
|
break;
|
|
327
327
|
case 'i':
|
|
328
328
|
// Try to find an IRI property list identifier or N3 verb keyword
|
|
329
|
-
if (this._n3Mode && (match = this._n3Id.exec(input))) type = 'id';else if (this._n3Mode && (match = this.
|
|
329
|
+
if (this._n3Mode && (match = this._n3Id.exec(input))) type = 'id';else if (this._n3Mode && (match = this._matchN3Verb(input, inputFinished))) type = match[0];else inconclusive = true;
|
|
330
330
|
break;
|
|
331
331
|
case '=':
|
|
332
332
|
// Try to find an implication arrow or equals sign
|
|
@@ -438,6 +438,29 @@ class N3Lexer {
|
|
|
438
438
|
}
|
|
439
439
|
}
|
|
440
440
|
|
|
441
|
+
// ### `_matchN3Verb` matches an N3 verb unless the input is a longer prefixed name
|
|
442
|
+
_matchN3Verb(input, inputFinished) {
|
|
443
|
+
const verb = this._n3Verb.exec(input);
|
|
444
|
+
if (!verb) return null;
|
|
445
|
+
|
|
446
|
+
// Most verb boundaries cannot be part of a prefix, so keep the common path fast.
|
|
447
|
+
const next = input[verb[0].length];
|
|
448
|
+
if (next !== '-' && next !== '_' && (next < '0' || next > '9')) return verb;
|
|
449
|
+
|
|
450
|
+
// A prefix can start with a verb and continue with characters that are also
|
|
451
|
+
// valid verb boundaries. Prefer the longer prefixed name when it is complete.
|
|
452
|
+
if (this._prefixed.exec(input) || this._prefixed.exec(`${input} `)) return null;
|
|
453
|
+
|
|
454
|
+
// If a stream chunk ends partway through such a prefix, wait for the colon
|
|
455
|
+
// instead of prematurely emitting the verb. Appending ": " lets the prefix
|
|
456
|
+
// grammar determine whether all input seen so far can be a complete prefix.
|
|
457
|
+
if (!inputFinished) {
|
|
458
|
+
const prefix = this._prefix.exec(`${input}: `);
|
|
459
|
+
if (prefix) return null;
|
|
460
|
+
}
|
|
461
|
+
return verb;
|
|
462
|
+
}
|
|
463
|
+
|
|
441
464
|
// ### `_unescape` replaces N3 escape codes by their corresponding characters,
|
|
442
465
|
// allowing only the fixed escape sequences from the given replacement table
|
|
443
466
|
_unescape(item, replacements) {
|
package/lib/N3Parser.js
CHANGED
|
@@ -31,6 +31,13 @@ class N3Parser {
|
|
|
31
31
|
isNQuads = /quad/.test(format),
|
|
32
32
|
isN3 = this._n3Mode = /n3/.test(format),
|
|
33
33
|
isLineMode = isNTriples || isNQuads;
|
|
34
|
+
// Keep inverse handling off the non-N3 emission path
|
|
35
|
+
this._emitCurrent = this._emit;
|
|
36
|
+
if (isN3) {
|
|
37
|
+
this._createQuad = this._createQuadInDirection;
|
|
38
|
+
this._emit = this._emitInDirection;
|
|
39
|
+
this._emitCurrent = this._emitCurrentInDirection;
|
|
40
|
+
}
|
|
34
41
|
if (!(this._supportsNamedGraphs = !(isTurtle || isN3))) this._readPredicateOrNamedGraph = this._readPredicate;
|
|
35
42
|
// Support triples in other graphs
|
|
36
43
|
this._supportsQuads = !(isTurtle || isTriG || isNTriples || isN3);
|
|
@@ -514,7 +521,7 @@ class N3Parser {
|
|
|
514
521
|
if (token.type !== ']') return this._readBlankNodePunctuation(token);
|
|
515
522
|
|
|
516
523
|
// Store blank node quad
|
|
517
|
-
if (this._subject !== null) this.
|
|
524
|
+
if (this._subject !== null) this._emitCurrent(this._subject, this._predicate, this._object, this._graph);
|
|
518
525
|
|
|
519
526
|
// Restore the parent context containing this blank node
|
|
520
527
|
const empty = this._predicate === null;
|
|
@@ -841,7 +848,7 @@ class N3Parser {
|
|
|
841
848
|
if (token.type !== '}') return this._readPunctuation(token);
|
|
842
849
|
|
|
843
850
|
// Store the last quad of the formula
|
|
844
|
-
if (this._subject !== null) this.
|
|
851
|
+
if (this._subject !== null) this._emitCurrent(this._subject, this._predicate, this._object, this._graph);
|
|
845
852
|
const formula = this._graph,
|
|
846
853
|
empty = this._emptyFormula;
|
|
847
854
|
// Restore the parent context containing this formula
|
|
@@ -882,6 +889,7 @@ class N3Parser {
|
|
|
882
889
|
break;
|
|
883
890
|
// Semicolon means the subject is shared; predicate and object are different
|
|
884
891
|
case ';':
|
|
892
|
+
if (inversePredicate) this._inversePredicate = false;
|
|
885
893
|
next = this._readPredicate;
|
|
886
894
|
break;
|
|
887
895
|
// Comma means both the subject and predicate are shared; the object is different
|
|
@@ -902,6 +910,7 @@ class N3Parser {
|
|
|
902
910
|
// Same staleness rule as ~ above.
|
|
903
911
|
if (subject !== null) this._tripleTerm = null;
|
|
904
912
|
this._subject = this._readTripleTerm();
|
|
913
|
+
this._inversePredicate = false;
|
|
905
914
|
this._validAnnotation = false;
|
|
906
915
|
startingAnnotation = true;
|
|
907
916
|
next = this._readPredicate;
|
|
@@ -912,6 +921,7 @@ class N3Parser {
|
|
|
912
921
|
if (!this._validAnnotation) return this._error('Annotation block can not be empty', token);
|
|
913
922
|
this._subject = null;
|
|
914
923
|
this._annotation = false;
|
|
924
|
+
this._inversePredicate = false;
|
|
915
925
|
next = this._getContextEndReader();
|
|
916
926
|
break;
|
|
917
927
|
default:
|
|
@@ -926,7 +936,7 @@ class N3Parser {
|
|
|
926
936
|
if (subject !== null && (!startingAnnotation || startingAnnotation && !this._annotation)) {
|
|
927
937
|
const predicate = this._predicate,
|
|
928
938
|
object = this._object;
|
|
929
|
-
|
|
939
|
+
this._emit(subject, predicate, object, graph, inversePredicate);
|
|
930
940
|
}
|
|
931
941
|
if (startingAnnotation) {
|
|
932
942
|
this._annotation = true;
|
|
@@ -936,10 +946,12 @@ class N3Parser {
|
|
|
936
946
|
|
|
937
947
|
// ### `_readBlankNodePunctuation` reads punctuation in a blank node
|
|
938
948
|
_readBlankNodePunctuation(token) {
|
|
939
|
-
let next
|
|
949
|
+
let next,
|
|
950
|
+
resetInversePredicate = false;
|
|
940
951
|
switch (token.type) {
|
|
941
952
|
// Semicolon means the subject is shared; predicate and object are different
|
|
942
953
|
case ';':
|
|
954
|
+
resetInversePredicate = this._inversePredicate;
|
|
943
955
|
next = this._readPredicate;
|
|
944
956
|
break;
|
|
945
957
|
// Comma means both the subject and predicate are shared; the object is different
|
|
@@ -961,7 +973,8 @@ class N3Parser {
|
|
|
961
973
|
// nothing left to share with a following predicate-object pair
|
|
962
974
|
if (this._subject === null) return this._error('Expected ] to follow annotation', token);
|
|
963
975
|
// A quad has been completed now, so return it
|
|
964
|
-
this.
|
|
976
|
+
this._emitCurrent(this._subject, this._predicate, this._object, this._graph);
|
|
977
|
+
if (resetInversePredicate) this._inversePredicate = false;
|
|
965
978
|
return next;
|
|
966
979
|
}
|
|
967
980
|
|
|
@@ -1158,7 +1171,7 @@ class N3Parser {
|
|
|
1158
1171
|
_readTripleTermTail(token) {
|
|
1159
1172
|
if (token.type !== ')>>') return this._error(`Expected )>> but got ${token.type}`, token);
|
|
1160
1173
|
// Read the quad and restore the previous context
|
|
1161
|
-
const quad = this.
|
|
1174
|
+
const quad = this._createQuad(this._subject, this._predicate, this._object, this._graph, this._inversePredicate);
|
|
1162
1175
|
this._restoreContext('<<(', token);
|
|
1163
1176
|
|
|
1164
1177
|
// If we're in a list, continue processing that list
|
|
@@ -1257,6 +1270,7 @@ class N3Parser {
|
|
|
1257
1270
|
switch (token.type) {
|
|
1258
1271
|
// The subject stays shared with the next predicate-object pair
|
|
1259
1272
|
case ';':
|
|
1273
|
+
this._inversePredicate = false;
|
|
1260
1274
|
return this._readPredicate;
|
|
1261
1275
|
// The subject and predicate stay shared with the next object
|
|
1262
1276
|
case ',':
|
|
@@ -1274,7 +1288,7 @@ class N3Parser {
|
|
|
1274
1288
|
const parentGraph = parent ? parent.graph : undefined;
|
|
1275
1289
|
const reifier = this._reifier || this._factory.blankNode();
|
|
1276
1290
|
this._reifier = null;
|
|
1277
|
-
this._tripleTerm = this._tripleTerm || this.
|
|
1291
|
+
this._tripleTerm = this._tripleTerm || this._createQuad(this._subject, this._predicate, this._object, null, this._inversePredicate);
|
|
1278
1292
|
this._emit(reifier, this.RDF_REIFIES, this._tripleTerm, parentGraph || this._graph || this.DEFAULTGRAPH);
|
|
1279
1293
|
return reifier;
|
|
1280
1294
|
}
|
|
@@ -1297,6 +1311,26 @@ class N3Parser {
|
|
|
1297
1311
|
}
|
|
1298
1312
|
}
|
|
1299
1313
|
|
|
1314
|
+
// ### `_createQuad` creates a quad
|
|
1315
|
+
_createQuad(subject, predicate, object, graph) {
|
|
1316
|
+
return this._factory.quad(subject, predicate, object, graph || this.DEFAULTGRAPH);
|
|
1317
|
+
}
|
|
1318
|
+
|
|
1319
|
+
// ### `_createQuadInDirection` creates a quad in the active predicate direction
|
|
1320
|
+
_createQuadInDirection(subject, predicate, object, graph, inversePredicate) {
|
|
1321
|
+
return inversePredicate ? this._factory.quad(object, predicate, subject, graph || this.DEFAULTGRAPH) : this._factory.quad(subject, predicate, object, graph || this.DEFAULTGRAPH);
|
|
1322
|
+
}
|
|
1323
|
+
|
|
1324
|
+
// ### `_emitInDirection` sends a quad in the active predicate direction
|
|
1325
|
+
_emitInDirection(subject, predicate, object, graph, inversePredicate) {
|
|
1326
|
+
this._callback(null, this._createQuad(subject, predicate, object, graph, inversePredicate));
|
|
1327
|
+
}
|
|
1328
|
+
|
|
1329
|
+
// ### `_emitCurrentInDirection` sends a quad in the current predicate direction
|
|
1330
|
+
_emitCurrentInDirection(subject, predicate, object, graph) {
|
|
1331
|
+
this._callback(null, this._createQuad(subject, predicate, object, graph, this._inversePredicate));
|
|
1332
|
+
}
|
|
1333
|
+
|
|
1300
1334
|
// ### `_emit` sends a quad through the callback
|
|
1301
1335
|
_emit(subject, predicate, object, graph) {
|
|
1302
1336
|
this._callback(null, this._factory.quad(subject, predicate, object, graph || this.DEFAULTGRAPH));
|
package/lib/N3Store.js
CHANGED
|
@@ -278,12 +278,15 @@ class N3Store {
|
|
|
278
278
|
// A null key list stops after visiting a bound key, avoiding a one-item array.
|
|
279
279
|
const keys0 = key0 ? null : Object.keys(index0);
|
|
280
280
|
for (let i0 = 0, value0 = key0 || keys0[0]; value0; value0 = keys0 && keys0[++i0]) {
|
|
281
|
+
// Mutations can remove keys captured before an earlier yield.
|
|
281
282
|
const index1 = index0[value0];
|
|
283
|
+
if (!index1) continue; // eslint-disable-line no-continue
|
|
282
284
|
parts[name0] = this._termFromId(entityKeys[value0]);
|
|
283
285
|
if (key1 && !(key1 in index1)) return;
|
|
284
286
|
const keys1 = key1 ? null : Object.keys(index1);
|
|
285
287
|
for (let i1 = 0, value1 = key1 || keys1[0]; value1; value1 = keys1 && keys1[++i1]) {
|
|
286
288
|
const index2 = index1[value1];
|
|
289
|
+
if (!index2) continue; // eslint-disable-line no-continue
|
|
287
290
|
parts[name1] = this._termFromId(entityKeys[value1]);
|
|
288
291
|
const values = Object.keys(index2);
|
|
289
292
|
for (let l = 0; l < values.length; l++) {
|
package/package.json
CHANGED
package/src/N3Lexer.js
CHANGED
|
@@ -326,7 +326,7 @@ export default class N3Lexer {
|
|
|
326
326
|
case 'h':
|
|
327
327
|
case 'o':
|
|
328
328
|
// Try to find an N3 verb keyword
|
|
329
|
-
if (this._n3Mode && (match = this.
|
|
329
|
+
if (this._n3Mode && (match = this._matchN3Verb(input, inputFinished)))
|
|
330
330
|
type = match[0];
|
|
331
331
|
else
|
|
332
332
|
inconclusive = true;
|
|
@@ -336,7 +336,7 @@ export default class N3Lexer {
|
|
|
336
336
|
// Try to find an IRI property list identifier or N3 verb keyword
|
|
337
337
|
if (this._n3Mode && (match = this._n3Id.exec(input)))
|
|
338
338
|
type = 'id';
|
|
339
|
-
else if (this._n3Mode && (match = this.
|
|
339
|
+
else if (this._n3Mode && (match = this._matchN3Verb(input, inputFinished)))
|
|
340
340
|
type = match[0];
|
|
341
341
|
else
|
|
342
342
|
inconclusive = true;
|
|
@@ -455,6 +455,33 @@ export default class N3Lexer {
|
|
|
455
455
|
function reportSyntaxError(self) { callback(self._syntaxError(/^\S*/.exec(input)[0])); }
|
|
456
456
|
}
|
|
457
457
|
|
|
458
|
+
// ### `_matchN3Verb` matches an N3 verb unless the input is a longer prefixed name
|
|
459
|
+
_matchN3Verb(input, inputFinished) {
|
|
460
|
+
const verb = this._n3Verb.exec(input);
|
|
461
|
+
if (!verb)
|
|
462
|
+
return null;
|
|
463
|
+
|
|
464
|
+
// Most verb boundaries cannot be part of a prefix, so keep the common path fast.
|
|
465
|
+
const next = input[verb[0].length];
|
|
466
|
+
if (next !== '-' && next !== '_' && (next < '0' || next > '9'))
|
|
467
|
+
return verb;
|
|
468
|
+
|
|
469
|
+
// A prefix can start with a verb and continue with characters that are also
|
|
470
|
+
// valid verb boundaries. Prefer the longer prefixed name when it is complete.
|
|
471
|
+
if (this._prefixed.exec(input) || this._prefixed.exec(`${input} `))
|
|
472
|
+
return null;
|
|
473
|
+
|
|
474
|
+
// If a stream chunk ends partway through such a prefix, wait for the colon
|
|
475
|
+
// instead of prematurely emitting the verb. Appending ": " lets the prefix
|
|
476
|
+
// grammar determine whether all input seen so far can be a complete prefix.
|
|
477
|
+
if (!inputFinished) {
|
|
478
|
+
const prefix = this._prefix.exec(`${input}: `);
|
|
479
|
+
if (prefix)
|
|
480
|
+
return null;
|
|
481
|
+
}
|
|
482
|
+
return verb;
|
|
483
|
+
}
|
|
484
|
+
|
|
458
485
|
// ### `_unescape` replaces N3 escape codes by their corresponding characters,
|
|
459
486
|
// allowing only the fixed escape sequences from the given replacement table
|
|
460
487
|
_unescape(item, replacements) {
|
package/src/N3Parser.js
CHANGED
|
@@ -23,6 +23,13 @@ export default class N3Parser {
|
|
|
23
23
|
isNTriples = /triple/.test(format), isNQuads = /quad/.test(format),
|
|
24
24
|
isN3 = this._n3Mode = /n3/.test(format),
|
|
25
25
|
isLineMode = isNTriples || isNQuads;
|
|
26
|
+
// Keep inverse handling off the non-N3 emission path
|
|
27
|
+
this._emitCurrent = this._emit;
|
|
28
|
+
if (isN3) {
|
|
29
|
+
this._createQuad = this._createQuadInDirection;
|
|
30
|
+
this._emit = this._emitInDirection;
|
|
31
|
+
this._emitCurrent = this._emitCurrentInDirection;
|
|
32
|
+
}
|
|
26
33
|
if (!(this._supportsNamedGraphs = !(isTurtle || isN3)))
|
|
27
34
|
this._readPredicateOrNamedGraph = this._readPredicate;
|
|
28
35
|
// Support triples in other graphs
|
|
@@ -550,7 +557,7 @@ export default class N3Parser {
|
|
|
550
557
|
|
|
551
558
|
// Store blank node quad
|
|
552
559
|
if (this._subject !== null)
|
|
553
|
-
this.
|
|
560
|
+
this._emitCurrent(this._subject, this._predicate, this._object, this._graph);
|
|
554
561
|
|
|
555
562
|
// Restore the parent context containing this blank node
|
|
556
563
|
const empty = this._predicate === null;
|
|
@@ -911,7 +918,7 @@ export default class N3Parser {
|
|
|
911
918
|
|
|
912
919
|
// Store the last quad of the formula
|
|
913
920
|
if (this._subject !== null)
|
|
914
|
-
this.
|
|
921
|
+
this._emitCurrent(this._subject, this._predicate, this._object, this._graph);
|
|
915
922
|
|
|
916
923
|
const formula = this._graph, empty = this._emptyFormula;
|
|
917
924
|
// Restore the parent context containing this formula
|
|
@@ -958,6 +965,7 @@ export default class N3Parser {
|
|
|
958
965
|
break;
|
|
959
966
|
// Semicolon means the subject is shared; predicate and object are different
|
|
960
967
|
case ';':
|
|
968
|
+
if (inversePredicate) this._inversePredicate = false;
|
|
961
969
|
next = this._readPredicate;
|
|
962
970
|
break;
|
|
963
971
|
// Comma means both the subject and predicate are shared; the object is different
|
|
@@ -980,6 +988,7 @@ export default class N3Parser {
|
|
|
980
988
|
if (subject !== null)
|
|
981
989
|
this._tripleTerm = null;
|
|
982
990
|
this._subject = this._readTripleTerm();
|
|
991
|
+
this._inversePredicate = false;
|
|
983
992
|
this._validAnnotation = false;
|
|
984
993
|
startingAnnotation = true;
|
|
985
994
|
next = this._readPredicate;
|
|
@@ -992,6 +1001,7 @@ export default class N3Parser {
|
|
|
992
1001
|
return this._error('Annotation block can not be empty', token);
|
|
993
1002
|
this._subject = null;
|
|
994
1003
|
this._annotation = false;
|
|
1004
|
+
this._inversePredicate = false;
|
|
995
1005
|
next = this._getContextEndReader();
|
|
996
1006
|
break;
|
|
997
1007
|
default:
|
|
@@ -1005,10 +1015,7 @@ export default class N3Parser {
|
|
|
1005
1015
|
// A quad has been completed now, so return it
|
|
1006
1016
|
if (subject !== null && (!startingAnnotation || (startingAnnotation && !this._annotation))) {
|
|
1007
1017
|
const predicate = this._predicate, object = this._object;
|
|
1008
|
-
|
|
1009
|
-
this._emit(subject, predicate, object, graph);
|
|
1010
|
-
else
|
|
1011
|
-
this._emit(object, predicate, subject, graph);
|
|
1018
|
+
this._emit(subject, predicate, object, graph, inversePredicate);
|
|
1012
1019
|
}
|
|
1013
1020
|
if (startingAnnotation) {
|
|
1014
1021
|
this._annotation = true;
|
|
@@ -1018,10 +1025,11 @@ export default class N3Parser {
|
|
|
1018
1025
|
|
|
1019
1026
|
// ### `_readBlankNodePunctuation` reads punctuation in a blank node
|
|
1020
1027
|
_readBlankNodePunctuation(token) {
|
|
1021
|
-
let next;
|
|
1028
|
+
let next, resetInversePredicate = false;
|
|
1022
1029
|
switch (token.type) {
|
|
1023
1030
|
// Semicolon means the subject is shared; predicate and object are different
|
|
1024
1031
|
case ';':
|
|
1032
|
+
resetInversePredicate = this._inversePredicate;
|
|
1025
1033
|
next = this._readPredicate;
|
|
1026
1034
|
break;
|
|
1027
1035
|
// Comma means both the subject and predicate are shared; the object is different
|
|
@@ -1044,7 +1052,9 @@ export default class N3Parser {
|
|
|
1044
1052
|
if (this._subject === null)
|
|
1045
1053
|
return this._error('Expected ] to follow annotation', token);
|
|
1046
1054
|
// A quad has been completed now, so return it
|
|
1047
|
-
this.
|
|
1055
|
+
this._emitCurrent(this._subject, this._predicate, this._object, this._graph);
|
|
1056
|
+
if (resetInversePredicate)
|
|
1057
|
+
this._inversePredicate = false;
|
|
1048
1058
|
return next;
|
|
1049
1059
|
}
|
|
1050
1060
|
|
|
@@ -1269,8 +1279,8 @@ export default class N3Parser {
|
|
|
1269
1279
|
if (token.type !== ')>>')
|
|
1270
1280
|
return this._error(`Expected )>> but got ${token.type}`, token);
|
|
1271
1281
|
// Read the quad and restore the previous context
|
|
1272
|
-
const quad = this.
|
|
1273
|
-
this._graph
|
|
1282
|
+
const quad = this._createQuad(this._subject, this._predicate, this._object,
|
|
1283
|
+
this._graph, this._inversePredicate);
|
|
1274
1284
|
this._restoreContext('<<(', token);
|
|
1275
1285
|
|
|
1276
1286
|
// If we're in a list, continue processing that list
|
|
@@ -1371,6 +1381,7 @@ export default class N3Parser {
|
|
|
1371
1381
|
switch (token.type) {
|
|
1372
1382
|
// The subject stays shared with the next predicate-object pair
|
|
1373
1383
|
case ';':
|
|
1384
|
+
this._inversePredicate = false;
|
|
1374
1385
|
return this._readPredicate;
|
|
1375
1386
|
// The subject and predicate stay shared with the next object
|
|
1376
1387
|
case ',':
|
|
@@ -1388,7 +1399,9 @@ export default class N3Parser {
|
|
|
1388
1399
|
const parentGraph = parent ? parent.graph : undefined;
|
|
1389
1400
|
const reifier = this._reifier || this._factory.blankNode();
|
|
1390
1401
|
this._reifier = null;
|
|
1391
|
-
this._tripleTerm = this._tripleTerm || this.
|
|
1402
|
+
this._tripleTerm = this._tripleTerm || this._createQuad(
|
|
1403
|
+
this._subject, this._predicate, this._object, null, this._inversePredicate,
|
|
1404
|
+
);
|
|
1392
1405
|
this._emit(reifier, this.RDF_REIFIES, this._tripleTerm, parentGraph || this._graph || this.DEFAULTGRAPH);
|
|
1393
1406
|
return reifier;
|
|
1394
1407
|
}
|
|
@@ -1413,6 +1426,28 @@ export default class N3Parser {
|
|
|
1413
1426
|
}
|
|
1414
1427
|
}
|
|
1415
1428
|
|
|
1429
|
+
// ### `_createQuad` creates a quad
|
|
1430
|
+
_createQuad(subject, predicate, object, graph) {
|
|
1431
|
+
return this._factory.quad(subject, predicate, object, graph || this.DEFAULTGRAPH);
|
|
1432
|
+
}
|
|
1433
|
+
|
|
1434
|
+
// ### `_createQuadInDirection` creates a quad in the active predicate direction
|
|
1435
|
+
_createQuadInDirection(subject, predicate, object, graph, inversePredicate) {
|
|
1436
|
+
return inversePredicate ?
|
|
1437
|
+
this._factory.quad(object, predicate, subject, graph || this.DEFAULTGRAPH) :
|
|
1438
|
+
this._factory.quad(subject, predicate, object, graph || this.DEFAULTGRAPH);
|
|
1439
|
+
}
|
|
1440
|
+
|
|
1441
|
+
// ### `_emitInDirection` sends a quad in the active predicate direction
|
|
1442
|
+
_emitInDirection(subject, predicate, object, graph, inversePredicate) {
|
|
1443
|
+
this._callback(null, this._createQuad(subject, predicate, object, graph, inversePredicate));
|
|
1444
|
+
}
|
|
1445
|
+
|
|
1446
|
+
// ### `_emitCurrentInDirection` sends a quad in the current predicate direction
|
|
1447
|
+
_emitCurrentInDirection(subject, predicate, object, graph) {
|
|
1448
|
+
this._callback(null, this._createQuad(subject, predicate, object, graph, this._inversePredicate));
|
|
1449
|
+
}
|
|
1450
|
+
|
|
1416
1451
|
// ### `_emit` sends a quad through the callback
|
|
1417
1452
|
_emit(subject, predicate, object, graph) {
|
|
1418
1453
|
this._callback(null, this._factory.quad(subject, predicate, object, graph || this.DEFAULTGRAPH));
|
package/src/N3Store.js
CHANGED
|
@@ -297,7 +297,9 @@ export default class N3Store {
|
|
|
297
297
|
const keys0 = key0 ? null : Object.keys(index0);
|
|
298
298
|
for (let i0 = 0, value0 = key0 || keys0[0]; value0;
|
|
299
299
|
value0 = keys0 && keys0[++i0]) {
|
|
300
|
+
// Mutations can remove keys captured before an earlier yield.
|
|
300
301
|
const index1 = index0[value0];
|
|
302
|
+
if (!index1) continue; // eslint-disable-line no-continue
|
|
301
303
|
parts[name0] = this._termFromId(entityKeys[value0]);
|
|
302
304
|
|
|
303
305
|
if (key1 && !(key1 in index1))
|
|
@@ -306,6 +308,7 @@ export default class N3Store {
|
|
|
306
308
|
for (let i1 = 0, value1 = key1 || keys1[0]; value1;
|
|
307
309
|
value1 = keys1 && keys1[++i1]) {
|
|
308
310
|
const index2 = index1[value1];
|
|
311
|
+
if (!index2) continue; // eslint-disable-line no-continue
|
|
309
312
|
parts[name1] = this._termFromId(entityKeys[value1]);
|
|
310
313
|
const values = Object.keys(index2);
|
|
311
314
|
for (let l = 0; l < values.length; l++) {
|