n3 2.0.0-beta.1 → 2.0.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/src/N3Parser.js CHANGED
@@ -27,14 +27,19 @@ export default class N3Parser {
27
27
  this._readPredicateOrNamedGraph = this._readPredicate;
28
28
  // Support triples in other graphs
29
29
  this._supportsQuads = !(isTurtle || isTriG || isNTriples || isN3);
30
+ // Whether the log:isImpliedBy predicate is supported
31
+ this._isImpliedBy = options.isImpliedBy;
30
32
  // Disable relative IRIs in N-Triples or N-Quads mode
31
33
  if (isLineMode)
32
34
  this._resolveRelativeIRI = iri => { return null; };
33
35
  this._blankNodePrefix = typeof options.blankNodePrefix !== 'string' ? '' :
34
36
  options.blankNodePrefix.replace(/^(?!_:)/, '_:');
35
- this._lexer = options.lexer || new N3Lexer({ lineMode: isLineMode, n3: isN3 });
37
+ this._lexer = options.lexer || new N3Lexer({ lineMode: isLineMode, n3: isN3, isImpliedBy: this._isImpliedBy });
36
38
  // Disable explicit quantifiers by default
37
39
  this._explicitQuantifiers = !!options.explicitQuantifiers;
40
+ // Disable parsing of unsupported versions by default
41
+ this._parseUnsupportedVersions = !!options.parseUnsupportedVersions;
42
+ this._version = options.version;
38
43
  }
39
44
 
40
45
  // ## Static class methods
@@ -112,6 +117,13 @@ export default class N3Parser {
112
117
  }
113
118
  }
114
119
 
120
+ // ### `_readBeforeTopContext` is called once only at the start of parsing.
121
+ _readBeforeTopContext(token) {
122
+ if (this._version && !this._isValidVersion(this._version))
123
+ return this._error(`Detected unsupported version as media type parameter: "${this._version}"`, token);
124
+ return this._readInTopContext(token);
125
+ }
126
+
115
127
  // ### `_readInTopContext` reads a token when in the top context
116
128
  _readInTopContext(token) {
117
129
  switch (token.type) {
@@ -304,6 +316,7 @@ export default class N3Parser {
304
316
  if ((this._predicate = this._readEntity(token)) === undefined)
305
317
  return;
306
318
  }
319
+ this._validAnnotation = true;
307
320
  // The next token must be an object
308
321
  return this._readObject;
309
322
  }
@@ -695,6 +708,7 @@ export default class N3Parser {
695
708
  case '{|':
696
709
  // Continue using the last triple as reified triple subject for the predicate-object pairs.
697
710
  this._subject = this._readTripleTerm();
711
+ this._validAnnotation = false;
698
712
  startingAnnotation = true;
699
713
  next = this._readPredicate;
700
714
  break;
@@ -702,6 +716,8 @@ export default class N3Parser {
702
716
  case '|}':
703
717
  if (!this._annotation)
704
718
  return this._error('Unexpected annotation syntax closing', token);
719
+ if (!this._validAnnotation)
720
+ return this._error('Annotation block can not be empty', token);
705
721
  this._subject = null;
706
722
  this._annotation = false;
707
723
  next = this._readPunctuation;
@@ -782,13 +798,20 @@ export default class N3Parser {
782
798
  return this._readDeclarationPunctuation;
783
799
  }
784
800
 
801
+ // ### `_isValidVersion` checks if the given version is valid for this parser to handle.
802
+ _isValidVersion(version) {
803
+ return this._parseUnsupportedVersions || N3Parser.SUPPORTED_VERSIONS.includes(version);
804
+ }
805
+
785
806
  // ### `_readVersion` reads version string declaration
786
807
  _readVersion(token) {
787
808
  if (token.type !== 'literal')
788
809
  return this._error('Expected literal to follow version declaration', token);
789
810
  if ((token.end - token.start) !== token.value.length + 2)
790
811
  return this._error('Version declarations must use single quotes', token);
791
- this._prefixCallback(token.value);
812
+ this._versionCallback(token.value);
813
+ if (!this._isValidVersion(token.value))
814
+ return this._error(`Detected unsupported version: "${token.value}"`, token);
792
815
  return this._readDeclarationPunctuation;
793
816
  }
794
817
 
@@ -1181,7 +1204,7 @@ export default class N3Parser {
1181
1204
  }
1182
1205
  // The read callback is the next function to be executed when a token arrives.
1183
1206
  // We start reading in the top context.
1184
- this._readCallback = this._readInTopContext;
1207
+ this._readCallback = this._readBeforeTopContext;
1185
1208
  this._sparqlStyle = false;
1186
1209
  this._prefixes = Object.create(null);
1187
1210
  this._prefixes._ = this._blankNodePrefix ? this._blankNodePrefix.substr(2)
@@ -1253,7 +1276,13 @@ function initDataFactory(parser, factory) {
1253
1276
  'a': factory.namedNode(namespaces.rdf.type),
1254
1277
  '=': factory.namedNode(namespaces.owl.sameAs),
1255
1278
  '>': factory.namedNode(namespaces.log.implies),
1279
+ '<': factory.namedNode(namespaces.log.isImpliedBy),
1256
1280
  };
1257
1281
  parser.QUANTIFIERS_GRAPH = factory.namedNode('urn:n3:quantifiers');
1258
1282
  }
1283
+ N3Parser.SUPPORTED_VERSIONS = [
1284
+ '1.2',
1285
+ '1.2-basic',
1286
+ '1.1',
1287
+ ];
1259
1288
  initDataFactory(N3Parser.prototype, N3DataFactory);
package/src/N3Store.js CHANGED
@@ -163,7 +163,7 @@ export default class N3Store {
163
163
  this._graphs = Object.create(null);
164
164
 
165
165
  // Shift parameters if `quads` is not given
166
- if (!options && quads && !quads[0])
166
+ if (!options && quads && !quads[0] && !(typeof quads.match === 'function'))
167
167
  options = quads, quads = null;
168
168
  options = options || {};
169
169
  this._factory = options.factory || N3DataFactory;
@@ -175,7 +175,7 @@ export default class N3Store {
175
175
 
176
176
  // Add quads if passed
177
177
  if (quads)
178
- this.addQuads(quads);
178
+ this.addAll(quads);
179
179
  }
180
180
 
181
181
  // ## Public properties
@@ -601,7 +601,7 @@ export default class N3Store {
601
601
  // Setting any field to `undefined` or `null` indicates a wildcard.
602
602
  some(callback, subject, predicate, object, graph) {
603
603
  for (const quad of this.readQuads(subject, predicate, object, graph))
604
- if (callback(quad))
604
+ if (callback(quad, this))
605
605
  return true;
606
606
  return false;
607
607
  }
@@ -1134,27 +1134,28 @@ class DatasetCoreAndReadableStream extends Readable {
1134
1134
 
1135
1135
  const graphs = n3Store._getGraphs(graph);
1136
1136
  for (const graphKey in graphs) {
1137
- let subjects, predicates, objects;
1138
-
1139
- if (!subjectId && predicateId) {
1140
- if (predicates = indexMatch(graphs[graphKey].predicates, [predicateId, objectId, subjectId])) {
1141
- subjects = indexMatch(graphs[graphKey].subjects, [subjectId, predicateId, objectId]);
1142
- objects = indexMatch(graphs[graphKey].objects, [objectId, subjectId, predicateId]);
1137
+ let subjects, predicates, objects, content;
1138
+ if (content = graphs[graphKey]) {
1139
+ if (!subjectId && predicateId) {
1140
+ if (predicates = indexMatch(content.predicates, [predicateId, objectId, subjectId])) {
1141
+ subjects = indexMatch(content.subjects, [subjectId, predicateId, objectId]);
1142
+ objects = indexMatch(content.objects, [objectId, subjectId, predicateId]);
1143
+ }
1143
1144
  }
1144
- }
1145
- else if (objectId) {
1146
- if (objects = indexMatch(graphs[graphKey].objects, [objectId, subjectId, predicateId])) {
1147
- subjects = indexMatch(graphs[graphKey].subjects, [subjectId, predicateId, objectId]);
1148
- predicates = indexMatch(graphs[graphKey].predicates, [predicateId, objectId, subjectId]);
1145
+ else if (objectId) {
1146
+ if (objects = indexMatch(content.objects, [objectId, subjectId, predicateId])) {
1147
+ subjects = indexMatch(content.subjects, [subjectId, predicateId, objectId]);
1148
+ predicates = indexMatch(content.predicates, [predicateId, objectId, subjectId]);
1149
+ }
1150
+ }
1151
+ else if (subjects = indexMatch(content.subjects, [subjectId, predicateId, objectId])) {
1152
+ predicates = indexMatch(content.predicates, [predicateId, objectId, subjectId]);
1153
+ objects = indexMatch(content.objects, [objectId, subjectId, predicateId]);
1149
1154
  }
1150
- }
1151
- else if (subjects = indexMatch(graphs[graphKey].subjects, [subjectId, predicateId, objectId])) {
1152
- predicates = indexMatch(graphs[graphKey].predicates, [predicateId, objectId, subjectId]);
1153
- objects = indexMatch(graphs[graphKey].objects, [objectId, subjectId, predicateId]);
1154
- }
1155
1155
 
1156
- if (subjects)
1157
- newStore._graphs[graphKey] = { subjects, predicates, objects };
1156
+ if (subjects)
1157
+ newStore._graphs[graphKey] = { subjects, predicates, objects };
1158
+ }
1158
1159
  }
1159
1160
  newStore._size = null;
1160
1161
  }
package/src/N3Util.js CHANGED
@@ -22,6 +22,11 @@ export function isVariable(term) {
22
22
  return !!term && term.termType === 'Variable';
23
23
  }
24
24
 
25
+ // Tests whether the given term represents a quad
26
+ export function isQuad(term) {
27
+ return !!term && term.termType === 'Quad';
28
+ }
29
+
25
30
  // Tests whether the given term represents the default graph
26
31
  export function isDefaultGraph(term) {
27
32
  return !!term && term.termType === 'DefaultGraph';
package/src/N3Writer.js CHANGED
@@ -2,6 +2,8 @@
2
2
  import namespaces from './IRIs';
3
3
  import { default as N3DataFactory, Term } from './N3DataFactory';
4
4
  import { isDefaultGraph } from './N3Util';
5
+ import BaseIRI from './BaseIRI';
6
+ import { escapeRegex } from './Util';
5
7
 
6
8
  const DEFAULTGRAPH = N3DataFactory.defaultGraph();
7
9
 
@@ -58,9 +60,7 @@ export default class N3Writer {
58
60
  this._prefixIRIs = Object.create(null);
59
61
  options.prefixes && this.addPrefixes(options.prefixes);
60
62
  if (options.baseIRI) {
61
- this._baseMatcher = new RegExp(`^${escapeRegex(options.baseIRI)
62
- }${options.baseIRI.endsWith('/') ? '' : '[#?]'}`);
63
- this._baseLength = options.baseIRI.length;
63
+ this._baseIri = new BaseIRI(options.baseIRI);
64
64
  }
65
65
  }
66
66
  else {
@@ -153,8 +153,9 @@ export default class N3Writer {
153
153
  }
154
154
  let iri = entity.value;
155
155
  // Use relative IRIs if requested and possible
156
- if (this._baseMatcher && this._baseMatcher.test(iri))
157
- iri = iri.substr(this._baseLength);
156
+ if (this._baseIri) {
157
+ iri = this._baseIri.toRelative(iri);
158
+ }
158
159
  // Escape special characters
159
160
  if (escape.test(iri))
160
161
  iri = iri.replace(escapeAll, characterReplacer);
@@ -229,11 +230,11 @@ export default class N3Writer {
229
230
 
230
231
  // ### `_encodeQuad` encodes an RDF-star quad
231
232
  _encodeQuad({ subject, predicate, object, graph }) {
232
- return `<<${
233
+ return `<<(${
233
234
  this._encodeSubject(subject)} ${
234
235
  this._encodePredicate(predicate)} ${
235
236
  this._encodeObject(object)}${
236
- isDefaultGraph(graph) ? '' : ` ${this._encodeIriOrBlank(graph)}`}>>`;
237
+ isDefaultGraph(graph) ? '' : ` ${this._encodeIriOrBlank(graph)}`})>>`;
237
238
  }
238
239
 
239
240
  // ### `_blockedWrite` replaces `_write` after the writer has been closed
@@ -395,7 +396,3 @@ function characterReplacer(character) {
395
396
  }
396
397
  return result;
397
398
  }
398
-
399
- function escapeRegex(regex) {
400
- return regex.replace(/[\]\/\(\)\*\+\?\.\\\$]/g, '\\$&');
401
- }
package/src/Util.js ADDED
@@ -0,0 +1,3 @@
1
+ export function escapeRegex(regex) {
2
+ return regex.replace(/[\]\/\(\)\*\+\?\.\\\$]/g, '\\$&');
3
+ }
package/src/index.js CHANGED
@@ -7,6 +7,7 @@ import Reasoner, { getRulesFromDataset } from './N3Reasoner';
7
7
  import StreamParser from './N3StreamParser';
8
8
  import StreamWriter from './N3StreamWriter';
9
9
  import * as Util from './N3Util';
10
+ import BaseIRI from './BaseIRI';
10
11
 
11
12
  import {
12
13
  default as DataFactory,
@@ -36,6 +37,7 @@ export {
36
37
  StreamWriter,
37
38
  Util,
38
39
  Reasoner,
40
+ BaseIRI,
39
41
 
40
42
  DataFactory,
41
43
 
@@ -65,6 +67,7 @@ export default {
65
67
  StreamWriter,
66
68
  Util,
67
69
  Reasoner,
70
+ BaseIRI,
68
71
 
69
72
  DataFactory,
70
73