n3 2.0.0-beta.2 → 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/lib/BaseIRI.js ADDED
@@ -0,0 +1,93 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = void 0;
7
+ var _Util = require("./Util");
8
+ // Do not handle base IRIs without scheme, and currently unsupported cases:
9
+ // - file: IRIs (which could also use backslashes)
10
+ // - IRIs containing /. or /.. or //
11
+ const BASE_UNSUPPORTED = /^:?[^:?#]*(?:[?#]|$)|^file:|^[^:]*:\/*[^?#]+?\/(?:\.\.?(?:\/|$)|\/)/i;
12
+ const SUFFIX_SUPPORTED = /^(?:(?:[^/?#]{3,}|\.?[^/?#.]\.?)(?:\/[^/?#]{3,}|\.?[^/?#.]\.?)*\/?)?(?:[?#]|$)/;
13
+ const CURRENT = './';
14
+ const PARENT = '../';
15
+ const QUERY = '?';
16
+ const FRAGMENT = '#';
17
+ class BaseIRI {
18
+ constructor(base) {
19
+ this.base = base;
20
+ this._baseLength = 0;
21
+ this._baseMatcher = null;
22
+ this._pathReplacements = new Array(base.length + 1);
23
+ }
24
+ static supports(base) {
25
+ return !BASE_UNSUPPORTED.test(base);
26
+ }
27
+ _getBaseMatcher() {
28
+ if (this._baseMatcher) return this._baseMatcher;
29
+ if (!BaseIRI.supports(this.base)) return this._baseMatcher = /.^/;
30
+
31
+ // Extract the scheme
32
+ const scheme = /^[^:]*:\/*/.exec(this.base)[0];
33
+ const regexHead = ['^', (0, _Util.escapeRegex)(scheme)];
34
+ const regexTail = [];
35
+
36
+ // Generate a regex for every path segment
37
+ const segments = [],
38
+ segmenter = /[^/?#]*([/?#])/y;
39
+ let segment,
40
+ query = 0,
41
+ fragment = 0,
42
+ last = segmenter.lastIndex = scheme.length;
43
+ while (!query && !fragment && (segment = segmenter.exec(this.base))) {
44
+ // Truncate base resolution path at fragment start
45
+ if (segment[1] === FRAGMENT) fragment = segmenter.lastIndex - 1;else {
46
+ // Create regex that matches the segment
47
+ regexHead.push((0, _Util.escapeRegex)(segment[0]), '(?:');
48
+ regexTail.push(')?');
49
+
50
+ // Create dedicated query string replacement
51
+ if (segment[1] !== QUERY) segments.push(last = segmenter.lastIndex);else {
52
+ query = last = segmenter.lastIndex;
53
+ fragment = this.base.indexOf(FRAGMENT, query);
54
+ this._pathReplacements[query] = QUERY;
55
+ }
56
+ }
57
+ }
58
+
59
+ // Precalculate parent path substitutions
60
+ for (let i = 0; i < segments.length; i++) this._pathReplacements[segments[i]] = PARENT.repeat(segments.length - i - 1);
61
+ this._pathReplacements[segments[segments.length - 1]] = CURRENT;
62
+
63
+ // Add the remainder of the base IRI (without fragment) to the regex
64
+ this._baseLength = fragment > 0 ? fragment : this.base.length;
65
+ regexHead.push((0, _Util.escapeRegex)(this.base.substring(last, this._baseLength)), query ? '(?:#|$)' : '(?:[?#]|$)');
66
+ return this._baseMatcher = new RegExp([...regexHead, ...regexTail].join(''));
67
+ }
68
+ toRelative(iri) {
69
+ // Unsupported or non-matching base IRI
70
+ const match = this._getBaseMatcher().exec(iri);
71
+ if (!match) return iri;
72
+
73
+ // Exact base IRI match
74
+ const length = match[0].length;
75
+ if (length === this._baseLength && length === iri.length) return '';
76
+
77
+ // Parent path match
78
+ const parentPath = this._pathReplacements[length];
79
+ if (parentPath) {
80
+ const suffix = iri.substring(length);
81
+ // Don't abbreviate unsupported path
82
+ if (parentPath !== QUERY && !SUFFIX_SUPPORTED.test(suffix)) return iri;
83
+ // Omit ./ with fragment or query string
84
+ if (parentPath === CURRENT && /^[^?#]/.test(suffix)) return suffix;
85
+ // Append suffix to relative parent path
86
+ return parentPath + suffix;
87
+ }
88
+
89
+ // Fragment or query string, so include delimiter
90
+ return iri.substring(length - 1);
91
+ }
92
+ }
93
+ exports.default = BaseIRI;
package/lib/IRIs.js CHANGED
@@ -32,6 +32,7 @@ var _default = exports.default = {
32
32
  forAll: `${SWAP}reify#forAll`
33
33
  },
34
34
  log: {
35
- implies: `${SWAP}log#implies`
35
+ implies: `${SWAP}log#implies`,
36
+ isImpliedBy: `${SWAP}log#isImpliedBy`
36
37
  }
37
38
  };
package/lib/N3Lexer.js CHANGED
@@ -5,7 +5,6 @@ Object.defineProperty(exports, "__esModule", {
5
5
  });
6
6
  exports.default = void 0;
7
7
  var _buffer = require("buffer");
8
- var _queueMicrotask = _interopRequireDefault(require("queue-microtask"));
9
8
  var _IRIs = _interopRequireDefault(require("./IRIs"));
10
9
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
11
10
  // **N3Lexer** tokenizes N3 documents.
@@ -86,6 +85,9 @@ class N3Lexer {
86
85
  this._endOfFile = /^(?:#[^\n\r]*)?$/;
87
86
  options = options || {};
88
87
 
88
+ // Whether the log:isImpliedBy predicate is supported
89
+ this._isImpliedBy = options.isImpliedBy;
90
+
89
91
  // In line mode (N-Triples or N-Quads), only simple features may be parsed
90
92
  if (this._lineMode = !!options.lineMode) {
91
93
  this._n3Mode = false;
@@ -183,7 +185,10 @@ class N3Lexer {
183
185
  // Try to find a reified triple
184
186
  else if (!this._lineMode && input.length > (inputFinished ? 1 : 2) && input[1] === '<') type = '<<', matchLength = 2;
185
187
  // Try to find a backwards implication arrow
186
- else if (this._n3Mode && input.length > 1 && input[1] === '=') type = 'inverse', matchLength = 2, value = '>';
188
+ else if (this._n3Mode && input.length > 1 && input[1] === '=') {
189
+ matchLength = 2;
190
+ if (this._isImpliedBy) type = 'abbreviation', value = '<';else type = 'inverse', value = '>';
191
+ }
187
192
  break;
188
193
  case '>':
189
194
  // Try to find a reified triple
@@ -492,7 +497,7 @@ class N3Lexer {
492
497
  if (typeof input === 'string') {
493
498
  this._input = this._readStartingBom(input);
494
499
  // If a callback was passed, asynchronously call it
495
- if (typeof callback === 'function') (0, _queueMicrotask.default)(() => this._tokenizeToEnd(callback, true));
500
+ if (typeof callback === 'function') queueMicrotask(() => this._tokenizeToEnd(callback, true));
496
501
  // If no callback was passed, tokenize synchronously and return
497
502
  else {
498
503
  const tokens = [];
package/lib/N3Parser.js CHANGED
@@ -34,6 +34,8 @@ class N3Parser {
34
34
  if (!(this._supportsNamedGraphs = !(isTurtle || isN3))) this._readPredicateOrNamedGraph = this._readPredicate;
35
35
  // Support triples in other graphs
36
36
  this._supportsQuads = !(isTurtle || isTriG || isNTriples || isN3);
37
+ // Whether the log:isImpliedBy predicate is supported
38
+ this._isImpliedBy = options.isImpliedBy;
37
39
  // Disable relative IRIs in N-Triples or N-Quads mode
38
40
  if (isLineMode) this._resolveRelativeIRI = iri => {
39
41
  return null;
@@ -41,7 +43,8 @@ class N3Parser {
41
43
  this._blankNodePrefix = typeof options.blankNodePrefix !== 'string' ? '' : options.blankNodePrefix.replace(/^(?!_:)/, '_:');
42
44
  this._lexer = options.lexer || new _N3Lexer.default({
43
45
  lineMode: isLineMode,
44
- n3: isN3
46
+ n3: isN3,
47
+ isImpliedBy: this._isImpliedBy
45
48
  });
46
49
  // Disable explicit quantifiers by default
47
50
  this._explicitQuantifiers = !!options.explicitQuantifiers;
@@ -300,6 +303,7 @@ class N3Parser {
300
303
  default:
301
304
  if ((this._predicate = this._readEntity(token)) === undefined) return;
302
305
  }
306
+ this._validAnnotation = true;
303
307
  // The next token must be an object
304
308
  return this._readObject;
305
309
  }
@@ -657,12 +661,14 @@ class N3Parser {
657
661
  case '{|':
658
662
  // Continue using the last triple as reified triple subject for the predicate-object pairs.
659
663
  this._subject = this._readTripleTerm();
664
+ this._validAnnotation = false;
660
665
  startingAnnotation = true;
661
666
  next = this._readPredicate;
662
667
  break;
663
668
  // |} means that the current reified triple in annotation syntax is finalized.
664
669
  case '|}':
665
670
  if (!this._annotation) return this._error('Unexpected annotation syntax closing', token);
671
+ if (!this._validAnnotation) return this._error('Annotation block can not be empty', token);
666
672
  this._subject = null;
667
673
  this._annotation = false;
668
674
  next = this._readPunctuation;
@@ -1184,7 +1190,8 @@ function initDataFactory(parser, factory) {
1184
1190
  parser.ABBREVIATIONS = {
1185
1191
  'a': factory.namedNode(_IRIs.default.rdf.type),
1186
1192
  '=': factory.namedNode(_IRIs.default.owl.sameAs),
1187
- '>': factory.namedNode(_IRIs.default.log.implies)
1193
+ '>': factory.namedNode(_IRIs.default.log.implies),
1194
+ '<': factory.namedNode(_IRIs.default.log.isImpliedBy)
1188
1195
  };
1189
1196
  parser.QUANTIFIERS_GRAPH = factory.namedNode('urn:n3:quantifiers');
1190
1197
  }
package/lib/N3Store.js CHANGED
@@ -10,8 +10,7 @@ var _IRIs = _interopRequireDefault(require("./IRIs"));
10
10
  var _N3Util = require("./N3Util");
11
11
  var _N3Writer = _interopRequireDefault(require("./N3Writer"));
12
12
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
13
- function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
14
- function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
13
+ function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
15
14
  // **N3Store** objects store N3 quads by graph in memory.
16
15
 
17
16
  const ITERATOR = Symbol('iter');
@@ -147,7 +146,7 @@ class N3Store {
147
146
  this._graphs = Object.create(null);
148
147
 
149
148
  // Shift parameters if `quads` is not given
150
- if (!options && quads && !quads[0]) options = quads, quads = null;
149
+ if (!options && quads && !quads[0] && !(typeof quads.match === 'function')) options = quads, quads = null;
151
150
  options = options || {};
152
151
  this._factory = options.factory || _N3DataFactory.default;
153
152
  this._entityIndex = options.entityIndex || new N3EntityIndex({
@@ -159,7 +158,7 @@ class N3Store {
159
158
  this._termToNewNumericId = this._entityIndex._termToNewNumericId.bind(this._entityIndex);
160
159
 
161
160
  // Add quads if passed
162
- if (quads) this.addQuads(quads);
161
+ if (quads) this.addAll(quads);
163
162
  }
164
163
 
165
164
  // ## Public properties
@@ -579,7 +578,7 @@ class N3Store {
579
578
  // and returns `true` if it returns truthy for any of them.
580
579
  // Setting any field to `undefined` or `null` indicates a wildcard.
581
580
  some(callback, subject, predicate, object, graph) {
582
- for (const quad of this.readQuads(subject, predicate, object, graph)) if (callback(quad)) return true;
581
+ for (const quad of this.readQuads(subject, predicate, object, graph)) if (callback(quad, this)) return true;
583
582
  return false;
584
583
  }
585
584
 
@@ -1083,26 +1082,28 @@ class DatasetCoreAndReadableStream extends _readableStream.Readable {
1083
1082
  if (subject && !(subjectId = newStore._termToNumericId(subject)) || predicate && !(predicateId = newStore._termToNumericId(predicate)) || object && !(objectId = newStore._termToNumericId(object))) return newStore;
1084
1083
  const graphs = n3Store._getGraphs(graph);
1085
1084
  for (const graphKey in graphs) {
1086
- let subjects, predicates, objects;
1087
- if (!subjectId && predicateId) {
1088
- if (predicates = indexMatch(graphs[graphKey].predicates, [predicateId, objectId, subjectId])) {
1089
- subjects = indexMatch(graphs[graphKey].subjects, [subjectId, predicateId, objectId]);
1090
- objects = indexMatch(graphs[graphKey].objects, [objectId, subjectId, predicateId]);
1091
- }
1092
- } else if (objectId) {
1093
- if (objects = indexMatch(graphs[graphKey].objects, [objectId, subjectId, predicateId])) {
1094
- subjects = indexMatch(graphs[graphKey].subjects, [subjectId, predicateId, objectId]);
1095
- predicates = indexMatch(graphs[graphKey].predicates, [predicateId, objectId, subjectId]);
1085
+ let subjects, predicates, objects, content;
1086
+ if (content = graphs[graphKey]) {
1087
+ if (!subjectId && predicateId) {
1088
+ if (predicates = indexMatch(content.predicates, [predicateId, objectId, subjectId])) {
1089
+ subjects = indexMatch(content.subjects, [subjectId, predicateId, objectId]);
1090
+ objects = indexMatch(content.objects, [objectId, subjectId, predicateId]);
1091
+ }
1092
+ } else if (objectId) {
1093
+ if (objects = indexMatch(content.objects, [objectId, subjectId, predicateId])) {
1094
+ subjects = indexMatch(content.subjects, [subjectId, predicateId, objectId]);
1095
+ predicates = indexMatch(content.predicates, [predicateId, objectId, subjectId]);
1096
+ }
1097
+ } else if (subjects = indexMatch(content.subjects, [subjectId, predicateId, objectId])) {
1098
+ predicates = indexMatch(content.predicates, [predicateId, objectId, subjectId]);
1099
+ objects = indexMatch(content.objects, [objectId, subjectId, predicateId]);
1096
1100
  }
1097
- } else if (subjects = indexMatch(graphs[graphKey].subjects, [subjectId, predicateId, objectId])) {
1098
- predicates = indexMatch(graphs[graphKey].predicates, [predicateId, objectId, subjectId]);
1099
- objects = indexMatch(graphs[graphKey].objects, [objectId, subjectId, predicateId]);
1101
+ if (subjects) newStore._graphs[graphKey] = {
1102
+ subjects,
1103
+ predicates,
1104
+ objects
1105
+ };
1100
1106
  }
1101
- if (subjects) newStore._graphs[graphKey] = {
1102
- subjects,
1103
- predicates,
1104
- objects
1105
- };
1106
1107
  }
1107
1108
  newStore._size = null;
1108
1109
  }
package/lib/N3Util.js CHANGED
@@ -8,6 +8,7 @@ exports.isBlankNode = isBlankNode;
8
8
  exports.isDefaultGraph = isDefaultGraph;
9
9
  exports.isLiteral = isLiteral;
10
10
  exports.isNamedNode = isNamedNode;
11
+ exports.isQuad = isQuad;
11
12
  exports.isVariable = isVariable;
12
13
  exports.prefix = prefix;
13
14
  exports.prefixes = prefixes;
@@ -35,6 +36,11 @@ function isVariable(term) {
35
36
  return !!term && term.termType === 'Variable';
36
37
  }
37
38
 
39
+ // Tests whether the given term represents a quad
40
+ function isQuad(term) {
41
+ return !!term && term.termType === 'Quad';
42
+ }
43
+
38
44
  // Tests whether the given term represents the default graph
39
45
  function isDefaultGraph(term) {
40
46
  return !!term && term.termType === 'DefaultGraph';
package/lib/N3Writer.js CHANGED
@@ -7,8 +7,9 @@ exports.default = void 0;
7
7
  var _IRIs = _interopRequireDefault(require("./IRIs"));
8
8
  var _N3DataFactory = _interopRequireWildcard(require("./N3DataFactory"));
9
9
  var _N3Util = require("./N3Util");
10
- function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
11
- function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
10
+ var _BaseIRI = _interopRequireDefault(require("./BaseIRI"));
11
+ var _Util = require("./Util");
12
+ function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
12
13
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
13
14
  // **N3Writer** writes N3 documents.
14
15
 
@@ -77,8 +78,7 @@ class N3Writer {
77
78
  this._prefixIRIs = Object.create(null);
78
79
  options.prefixes && this.addPrefixes(options.prefixes);
79
80
  if (options.baseIRI) {
80
- this._baseMatcher = new RegExp(`^${escapeRegex(options.baseIRI)}${options.baseIRI.endsWith('/') ? '' : '[#?]'}`);
81
- this._baseLength = options.baseIRI.length;
81
+ this._baseIri = new _BaseIRI.default(options.baseIRI);
82
82
  }
83
83
  } else {
84
84
  this._lineMode = true;
@@ -156,7 +156,9 @@ class N3Writer {
156
156
  }
157
157
  let iri = entity.value;
158
158
  // Use relative IRIs if requested and possible
159
- if (this._baseMatcher && this._baseMatcher.test(iri)) iri = iri.substr(this._baseLength);
159
+ if (this._baseIri) {
160
+ iri = this._baseIri.toRelative(iri);
161
+ }
160
162
  // Escape special characters
161
163
  if (escape.test(iri)) iri = iri.replace(escapeAll, characterReplacer);
162
164
  // Try to represent the IRI as prefixed name
@@ -226,7 +228,7 @@ class N3Writer {
226
228
  object,
227
229
  graph
228
230
  }) {
229
- return `<<${this._encodeSubject(subject)} ${this._encodePredicate(predicate)} ${this._encodeObject(object)}${(0, _N3Util.isDefaultGraph)(graph) ? '' : ` ${this._encodeIriOrBlank(graph)}`}>>`;
231
+ return `<<(${this._encodeSubject(subject)} ${this._encodePredicate(predicate)} ${this._encodeObject(object)}${(0, _N3Util.isDefaultGraph)(graph) ? '' : ` ${this._encodeIriOrBlank(graph)}`})>>`;
230
232
  }
231
233
 
232
234
  // ### `_blockedWrite` replaces `_write` after the writer has been closed
@@ -284,7 +286,7 @@ class N3Writer {
284
286
  IRIlist += IRIlist ? `|${prefixIRI}` : prefixIRI;
285
287
  prefixList += (prefixList ? '|' : '') + this._prefixIRIs[prefixIRI];
286
288
  }
287
- IRIlist = escapeRegex(IRIlist, /[\]\/\(\)\*\+\?\.\\\$]/g, '\\$&');
289
+ IRIlist = (0, _Util.escapeRegex)(IRIlist, /[\]\/\(\)\*\+\?\.\\\$]/g, '\\$&');
288
290
  this._prefixRegex = new RegExp(`^(?:${prefixList})[^\/]*$|` + `^(${IRIlist})([_a-zA-Z0-9][\\-_a-zA-Z0-9]*)$`);
289
291
  }
290
292
  // End a prefix block with a newline
@@ -380,7 +382,4 @@ function characterReplacer(character) {
380
382
  }
381
383
  }
382
384
  return result;
383
- }
384
- function escapeRegex(regex) {
385
- return regex.replace(/[\]\/\(\)\*\+\?\.\\\$]/g, '\\$&');
386
385
  }
package/lib/Util.js ADDED
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.escapeRegex = escapeRegex;
7
+ function escapeRegex(regex) {
8
+ return regex.replace(/[\]\/\(\)\*\+\?\.\\\$]/g, '\\$&');
9
+ }
package/lib/index.js CHANGED
@@ -3,6 +3,12 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
+ Object.defineProperty(exports, "BaseIRI", {
7
+ enumerable: true,
8
+ get: function () {
9
+ return _BaseIRI.default;
10
+ }
11
+ });
6
12
  Object.defineProperty(exports, "BlankNode", {
7
13
  enumerable: true,
8
14
  get: function () {
@@ -141,9 +147,9 @@ var _N3StreamParser = _interopRequireDefault(require("./N3StreamParser"));
141
147
  var _N3StreamWriter = _interopRequireDefault(require("./N3StreamWriter"));
142
148
  var Util = _interopRequireWildcard(require("./N3Util"));
143
149
  exports.Util = Util;
150
+ var _BaseIRI = _interopRequireDefault(require("./BaseIRI"));
144
151
  var _N3DataFactory = _interopRequireWildcard(require("./N3DataFactory"));
145
- function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
146
- function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
152
+ function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
147
153
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
148
154
  // Named exports
149
155
  // Export all named exports as a default object for backward compatibility
@@ -158,6 +164,7 @@ var _default = exports.default = {
158
164
  StreamWriter: _N3StreamWriter.default,
159
165
  Util,
160
166
  Reasoner: _N3Reasoner.default,
167
+ BaseIRI: _BaseIRI.default,
161
168
  DataFactory: _N3DataFactory.default,
162
169
  Term: _N3DataFactory.Term,
163
170
  NamedNode: _N3DataFactory.NamedNode,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "n3",
3
- "version": "2.0.0-beta.2",
3
+ "version": "2.0.0",
4
4
  "description": "Lightning fast, asynchronous, streaming Turtle / N3 / RDF library.",
5
5
  "author": "Ruben Verborgh <ruben.verborgh@gmail.com>",
6
6
  "keywords": [
@@ -25,7 +25,6 @@
25
25
  ],
26
26
  "dependencies": {
27
27
  "buffer": "^6.0.3",
28
- "queue-microtask": "^1.1.2",
29
28
  "readable-stream": "^4.0.0"
30
29
  },
31
30
  "devDependencies": {
@@ -43,7 +42,7 @@
43
42
  "eslint-plugin-jest": "^28.8.3",
44
43
  "jest": "^29.7.0",
45
44
  "pre-commit": "^1.2.2",
46
- "rdf-isomorphic": "^1.3.1",
45
+ "rdf-isomorphic": "^2.0.0",
47
46
  "rdf-test-suite": "^1.25.0",
48
47
  "streamify-string": "^1.0.1",
49
48
  "uglify-js": "^3.14.3"
@@ -60,8 +59,8 @@
60
59
  "spec-1-1-earl": "npm run spec-1-1-earl-turtle && npm run spec-1-1-earl-ntriples && npm run spec-1-1-earl-nquads && npm run spec-1-1-earl-trig",
61
60
  "spec-1-1-ntriples": "rdf-test-suite spec/parser.js https://w3c.github.io/rdf-tests/rdf/rdf11/rdf-n-triples/manifest.ttl -i '{ \"format\": \"n-triples\" }' -c .rdf-test-suite-cache/",
62
61
  "spec-1-1-nquads": "rdf-test-suite spec/parser.js https://w3c.github.io/rdf-tests/rdf/rdf11/rdf-n-quads/manifest.ttl -i '{ \"format\": \"n-quads\" }' -c .rdf-test-suite-cache/",
63
- "spec-1-1-turtle": "rdf-test-suite spec/parser.js https://w3c.github.io/rdf-tests/rdf/rdf11/rdf-turtle/manifest.ttl -i '{ \"format\": \"turtle\" }' -c .rdf-test-suite-cache/",
64
- "spec-1-1-trig": "rdf-test-suite spec/parser.js https://w3c.github.io/rdf-tests/rdf/rdf11/rdf-trig/manifest.ttl -i '{ \"format\": \"trig\" }' -c .rdf-test-suite-cache/",
62
+ "spec-1-1-turtle": "rdf-test-suite spec/parser.js https://w3c.github.io/rdf-tests/rdf/rdf11/rdf-turtle/manifest.ttl -i '{ \"format\": \"turtle\" }' -c .rdf-test-suite-cache/ --skip \"(bad-numeric-escape|bareword_decimal)\"",
63
+ "spec-1-1-trig": "rdf-test-suite spec/parser.js https://w3c.github.io/rdf-tests/rdf/rdf11/rdf-trig/manifest.ttl -i '{ \"format\": \"trig\" }' -c .rdf-test-suite-cache/ --skip \"(bad-numeric-escape|IRI-resolution-01)\"",
65
64
  "spec-1-1-earl-ntriples": "rdf-test-suite spec/parser.js https://w3c.github.io/rdf-tests/rdf/rdf11/rdf-n-triples/manifest.ttl -i '{ \"format\": \"n-triples\" }' -c .rdf-test-suite-cache/ -o earl -p spec/earl-meta.json > spec/earl-ntriples.ttl",
66
65
  "spec-1-1-earl-nquads": "rdf-test-suite spec/parser.js https://w3c.github.io/rdf-tests/rdf/rdf11/rdf-n-quads/manifest.ttl -i '{ \"format\": \"n-quads\" }' -c .rdf-test-suite-cache/ -o earl -p spec/earl-meta.json > spec/earl-nquads.ttl",
67
66
  "spec-1-1-earl-turtle": "rdf-test-suite spec/parser.js https://w3c.github.io/rdf-tests/rdf/rdf11/rdf-turtle/manifest.ttl -i '{ \"format\": \"turtle\" }' -c .rdf-test-suite-cache/ -o earl -p spec/earl-meta.json > spec/earl-turtle.ttl",
package/src/BaseIRI.js ADDED
@@ -0,0 +1,101 @@
1
+ import { escapeRegex } from './Util';
2
+
3
+ // Do not handle base IRIs without scheme, and currently unsupported cases:
4
+ // - file: IRIs (which could also use backslashes)
5
+ // - IRIs containing /. or /.. or //
6
+ const BASE_UNSUPPORTED = /^:?[^:?#]*(?:[?#]|$)|^file:|^[^:]*:\/*[^?#]+?\/(?:\.\.?(?:\/|$)|\/)/i;
7
+ const SUFFIX_SUPPORTED = /^(?:(?:[^/?#]{3,}|\.?[^/?#.]\.?)(?:\/[^/?#]{3,}|\.?[^/?#.]\.?)*\/?)?(?:[?#]|$)/;
8
+ const CURRENT = './';
9
+ const PARENT = '../';
10
+ const QUERY = '?';
11
+ const FRAGMENT = '#';
12
+
13
+ export default class BaseIRI {
14
+ constructor(base) {
15
+ this.base = base;
16
+ this._baseLength = 0;
17
+ this._baseMatcher = null;
18
+ this._pathReplacements = new Array(base.length + 1);
19
+ }
20
+
21
+ static supports(base) {
22
+ return !BASE_UNSUPPORTED.test(base);
23
+ }
24
+
25
+ _getBaseMatcher() {
26
+ if (this._baseMatcher)
27
+ return this._baseMatcher;
28
+ if (!BaseIRI.supports(this.base))
29
+ return this._baseMatcher = /.^/;
30
+
31
+ // Extract the scheme
32
+ const scheme = /^[^:]*:\/*/.exec(this.base)[0];
33
+ const regexHead = ['^', escapeRegex(scheme)];
34
+ const regexTail = [];
35
+
36
+ // Generate a regex for every path segment
37
+ const segments = [], segmenter = /[^/?#]*([/?#])/y;
38
+ let segment, query = 0, fragment = 0, last = segmenter.lastIndex = scheme.length;
39
+ while (!query && !fragment && (segment = segmenter.exec(this.base))) {
40
+ // Truncate base resolution path at fragment start
41
+ if (segment[1] === FRAGMENT)
42
+ fragment = segmenter.lastIndex - 1;
43
+ else {
44
+ // Create regex that matches the segment
45
+ regexHead.push(escapeRegex(segment[0]), '(?:');
46
+ regexTail.push(')?');
47
+
48
+ // Create dedicated query string replacement
49
+ if (segment[1] !== QUERY)
50
+ segments.push(last = segmenter.lastIndex);
51
+ else {
52
+ query = last = segmenter.lastIndex;
53
+ fragment = this.base.indexOf(FRAGMENT, query);
54
+ this._pathReplacements[query] = QUERY;
55
+ }
56
+ }
57
+ }
58
+
59
+ // Precalculate parent path substitutions
60
+ for (let i = 0; i < segments.length; i++)
61
+ this._pathReplacements[segments[i]] = PARENT.repeat(segments.length - i - 1);
62
+ this._pathReplacements[segments[segments.length - 1]] = CURRENT;
63
+
64
+ // Add the remainder of the base IRI (without fragment) to the regex
65
+ this._baseLength = fragment > 0 ? fragment : this.base.length;
66
+ regexHead.push(
67
+ escapeRegex(this.base.substring(last, this._baseLength)),
68
+ query ? '(?:#|$)' : '(?:[?#]|$)',
69
+ );
70
+ return this._baseMatcher = new RegExp([...regexHead, ...regexTail].join(''));
71
+ }
72
+
73
+ toRelative(iri) {
74
+ // Unsupported or non-matching base IRI
75
+ const match = this._getBaseMatcher().exec(iri);
76
+ if (!match)
77
+ return iri;
78
+
79
+ // Exact base IRI match
80
+ const length = match[0].length;
81
+ if (length === this._baseLength && length === iri.length)
82
+ return '';
83
+
84
+ // Parent path match
85
+ const parentPath = this._pathReplacements[length];
86
+ if (parentPath) {
87
+ const suffix = iri.substring(length);
88
+ // Don't abbreviate unsupported path
89
+ if (parentPath !== QUERY && !SUFFIX_SUPPORTED.test(suffix))
90
+ return iri;
91
+ // Omit ./ with fragment or query string
92
+ if (parentPath === CURRENT && /^[^?#]/.test(suffix))
93
+ return suffix;
94
+ // Append suffix to relative parent path
95
+ return parentPath + suffix;
96
+ }
97
+
98
+ // Fragment or query string, so include delimiter
99
+ return iri.substring(length - 1);
100
+ }
101
+ }
package/src/IRIs.js CHANGED
@@ -28,5 +28,6 @@ export default {
28
28
  },
29
29
  log: {
30
30
  implies: `${SWAP}log#implies`,
31
+ isImpliedBy: `${SWAP}log#isImpliedBy`,
31
32
  },
32
33
  };
package/src/N3Lexer.js CHANGED
@@ -1,6 +1,5 @@
1
1
  // **N3Lexer** tokenizes N3 documents.
2
2
  import { Buffer } from 'buffer';
3
- import queueMicrotask from 'queue-microtask';
4
3
  import namespaces from './IRIs';
5
4
 
6
5
  const { xsd } = namespaces;
@@ -56,6 +55,9 @@ export default class N3Lexer {
56
55
  this._endOfFile = /^(?:#[^\n\r]*)?$/;
57
56
  options = options || {};
58
57
 
58
+ // Whether the log:isImpliedBy predicate is supported
59
+ this._isImpliedBy = options.isImpliedBy;
60
+
59
61
  // In line mode (N-Triples or N-Quads), only simple features may be parsed
60
62
  if (this._lineMode = !!options.lineMode) {
61
63
  this._n3Mode = false;
@@ -157,8 +159,11 @@ export default class N3Lexer {
157
159
  else if (!this._lineMode && input.length > (inputFinished ? 1 : 2) && input[1] === '<')
158
160
  type = '<<', matchLength = 2;
159
161
  // Try to find a backwards implication arrow
160
- else if (this._n3Mode && input.length > 1 && input[1] === '=')
161
- type = 'inverse', matchLength = 2, value = '>';
162
+ else if (this._n3Mode && input.length > 1 && input[1] === '=') {
163
+ matchLength = 2;
164
+ if (this._isImpliedBy) type = 'abbreviation', value = '<';
165
+ else type = 'inverse', value = '>';
166
+ }
162
167
  break;
163
168
 
164
169
  case '>':
package/src/N3Parser.js CHANGED
@@ -27,12 +27,14 @@ 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;
38
40
  // Disable parsing of unsupported versions by default
@@ -314,6 +316,7 @@ export default class N3Parser {
314
316
  if ((this._predicate = this._readEntity(token)) === undefined)
315
317
  return;
316
318
  }
319
+ this._validAnnotation = true;
317
320
  // The next token must be an object
318
321
  return this._readObject;
319
322
  }
@@ -705,6 +708,7 @@ export default class N3Parser {
705
708
  case '{|':
706
709
  // Continue using the last triple as reified triple subject for the predicate-object pairs.
707
710
  this._subject = this._readTripleTerm();
711
+ this._validAnnotation = false;
708
712
  startingAnnotation = true;
709
713
  next = this._readPredicate;
710
714
  break;
@@ -712,6 +716,8 @@ export default class N3Parser {
712
716
  case '|}':
713
717
  if (!this._annotation)
714
718
  return this._error('Unexpected annotation syntax closing', token);
719
+ if (!this._validAnnotation)
720
+ return this._error('Annotation block can not be empty', token);
715
721
  this._subject = null;
716
722
  this._annotation = false;
717
723
  next = this._readPunctuation;
@@ -1270,6 +1276,7 @@ function initDataFactory(parser, factory) {
1270
1276
  'a': factory.namedNode(namespaces.rdf.type),
1271
1277
  '=': factory.namedNode(namespaces.owl.sameAs),
1272
1278
  '>': factory.namedNode(namespaces.log.implies),
1279
+ '<': factory.namedNode(namespaces.log.isImpliedBy),
1273
1280
  };
1274
1281
  parser.QUANTIFIERS_GRAPH = factory.namedNode('urn:n3:quantifiers');
1275
1282
  }