n3 1.7.0 → 1.10.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.
@@ -275,31 +275,47 @@ function termToId(term) {
275
275
  class Quad extends Term {
276
276
  constructor(subject, predicate, object, graph) {
277
277
  super('');
278
- this.subject = subject;
279
- this.predicate = predicate;
280
- this.object = object;
281
- this.graph = graph || DEFAULTGRAPH;
278
+ this._subject = subject;
279
+ this._predicate = predicate;
280
+ this._object = object;
281
+ this._graph = graph || DEFAULTGRAPH;
282
282
  } // ### The term type of this term
283
283
 
284
284
 
285
285
  get termType() {
286
286
  return 'Quad';
287
+ }
288
+
289
+ get subject() {
290
+ return this._subject;
291
+ }
292
+
293
+ get predicate() {
294
+ return this._predicate;
295
+ }
296
+
297
+ get object() {
298
+ return this._object;
299
+ }
300
+
301
+ get graph() {
302
+ return this._graph;
287
303
  } // ### Returns a plain object representation of this quad
288
304
 
289
305
 
290
306
  toJSON() {
291
307
  return {
292
308
  termType: this.termType,
293
- subject: this.subject.toJSON(),
294
- predicate: this.predicate.toJSON(),
295
- object: this.object.toJSON(),
296
- graph: this.graph.toJSON()
309
+ subject: this._subject.toJSON(),
310
+ predicate: this._predicate.toJSON(),
311
+ object: this._object.toJSON(),
312
+ graph: this._graph.toJSON()
297
313
  };
298
314
  } // ### Returns whether this object represents the same quad as the other
299
315
 
300
316
 
301
317
  equals(other) {
302
- return !!other && this.subject.equals(other.subject) && this.predicate.equals(other.predicate) && this.object.equals(other.object) && this.graph.equals(other.graph);
318
+ return !!other && this._subject.equals(other.subject) && this._predicate.equals(other.predicate) && this._object.equals(other.object) && this._graph.equals(other.graph);
303
319
  }
304
320
 
305
321
  }
package/lib/N3Store.js CHANGED
@@ -224,7 +224,15 @@ class N3Store {
224
224
  }
225
225
  };
226
226
  } // ## Public methods
227
- // ### `addQuad` adds a new quad to the store.
227
+ // ### `add` adds the specified quad to the dataset.
228
+ // Returns the dataset instance it was called on.
229
+ // Existing quads, as defined in Quad.equals, will be ignored.
230
+
231
+
232
+ add(quad) {
233
+ this.addQuad(quad);
234
+ return this;
235
+ } // ### `addQuad` adds a new quad to the store.
228
236
  // Returns if the quad index has changed, if the quad did not already exist.
229
237
 
230
238
 
@@ -273,6 +281,20 @@ class N3Store {
273
281
 
274
282
  addQuads(quads) {
275
283
  for (let i = 0; i < quads.length; i++) this.addQuad(quads[i]);
284
+ } // ### `delete` removes the specified quad from the dataset.
285
+ // Returns the dataset instance it was called on.
286
+
287
+
288
+ delete(quad) {
289
+ this.removeQuad(quad);
290
+ return this;
291
+ } // ### `has` determines whether a dataset includes a certain quad.
292
+ // Returns true or false as appropriate.
293
+
294
+
295
+ has(quad) {
296
+ const quads = this.getQuads(quad.subject, quad.predicate, quad.object, quad.graph);
297
+ return quads.length !== 0;
276
298
  } // ### `import` adds a stream of quads to the store
277
299
 
278
300
 
@@ -329,7 +351,17 @@ class N3Store {
329
351
 
330
352
 
331
353
  removeMatches(subject, predicate, object, graph) {
332
- return this.remove(this.match(subject, predicate, object, graph));
354
+ const stream = new _readableStream.Readable({
355
+ objectMode: true
356
+ });
357
+
358
+ stream._read = () => {
359
+ for (const quad of this.getQuads(subject, predicate, object, graph)) stream.push(quad);
360
+
361
+ stream.push(null);
362
+ };
363
+
364
+ return this.remove(stream);
333
365
  } // ### `deleteGraph` removes all triples with the given graph from the store
334
366
 
335
367
 
@@ -370,22 +402,16 @@ class N3Store {
370
402
  }
371
403
 
372
404
  return quads;
373
- } // ### `match` returns a stream of quads matching a pattern.
405
+ } // ### `match` returns a new dataset that is comprised of all quads in the current instance matching the given arguments.
406
+ // The logic described in Quad Matching is applied for each quad in this dataset to check if it should be included in the output dataset.
407
+ // Note: This method always returns a new DatasetCore, even if that dataset contains no quads.
408
+ // Note: Since a DatasetCore is an unordered set, the order of the quads within the returned sequence is arbitrary.
374
409
  // Setting any field to `undefined` or `null` indicates a wildcard.
410
+ // For backwards compatibility, the object return also implements the Readable stream interface.
375
411
 
376
412
 
377
413
  match(subject, predicate, object, graph) {
378
- const stream = new _readableStream.Readable({
379
- objectMode: true
380
- }); // Initialize stream once it is being read
381
-
382
- stream._read = () => {
383
- for (const quad of this.getQuads(subject, predicate, object, graph)) stream.push(quad);
384
-
385
- stream.push(null);
386
- };
387
-
388
- return stream;
414
+ return new DatasetCoreAndReadableStream(this, subject, predicate, object, graph);
389
415
  } // ### `countQuads` returns the number of quads matching a pattern.
390
416
  // Setting any field to `undefined` or `null` indicates a wildcard.
391
417
 
@@ -740,6 +766,13 @@ class N3Store {
740
766
 
741
767
  if (remove) this.removeQuads(toRemove);
742
768
  return lists;
769
+ } // ### Store is an iterable.
770
+ // Can be used where iterables are expected: for...of loops, array spread operator,
771
+ // `yield*`, and destructuring assignment (order is not guaranteed).
772
+
773
+
774
+ *[Symbol.iterator]() {
775
+ yield* this.getQuads();
743
776
  }
744
777
 
745
778
  } // Determines whether the argument is a string
@@ -749,4 +782,68 @@ exports.default = N3Store;
749
782
 
750
783
  function isString(s) {
751
784
  return typeof s === 'string' || s instanceof String;
785
+ }
786
+ /**
787
+ * A class that implements both DatasetCore and Readable.
788
+ */
789
+
790
+
791
+ class DatasetCoreAndReadableStream extends _readableStream.Readable {
792
+ constructor(n3Store, subject, predicate, object, graph) {
793
+ super({
794
+ objectMode: true
795
+ });
796
+ Object.assign(this, {
797
+ n3Store,
798
+ subject,
799
+ predicate,
800
+ object,
801
+ graph
802
+ });
803
+ }
804
+
805
+ get filtered() {
806
+ if (!this._filtered) {
807
+ const {
808
+ n3Store,
809
+ graph,
810
+ object,
811
+ predicate,
812
+ subject
813
+ } = this;
814
+ const quads = n3Store.getQuads(subject, predicate, object, graph);
815
+ this._filtered = new N3Store(quads, {
816
+ factory: n3Store._factory
817
+ });
818
+ }
819
+
820
+ return this._filtered;
821
+ }
822
+
823
+ _read() {
824
+ for (const quad of this.filtered.getQuads()) this.push(quad);
825
+
826
+ this.push(null);
827
+ }
828
+
829
+ add(quad) {
830
+ return this.filtered.add(quad);
831
+ }
832
+
833
+ delete(quad) {
834
+ return this.filtered.delete(quad);
835
+ }
836
+
837
+ has(quad) {
838
+ return this.filtered.has(quad);
839
+ }
840
+
841
+ match(subject, predicate, object, graph) {
842
+ return new DatasetCoreAndReadableStream(this.filtered, subject, predicate, object, graph);
843
+ }
844
+
845
+ *[Symbol.iterator]() {
846
+ yield* this.filtered.getQuads();
847
+ }
848
+
752
849
  }
@@ -16,9 +16,9 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { de
16
16
  class N3StreamWriter extends _readableStream.Transform {
17
17
  constructor(options) {
18
18
  super({
19
- encoding: 'utf8'
20
- });
21
- this._writableState.objectMode = true; // Set up writer with a dummy stream object
19
+ encoding: 'utf8',
20
+ writableObjectMode: true
21
+ }); // Set up writer with a dummy stream object
22
22
 
23
23
  const writer = this._writer = new _N3Writer.default({
24
24
  write: (quad, encoding, callback) => {
package/lib/N3Writer.js CHANGED
@@ -80,6 +80,7 @@ class N3Writer {
80
80
  if (!/triple|quad/i.test(options.format)) {
81
81
  this._lineMode = false;
82
82
  this._graph = DEFAULTGRAPH;
83
+ this._baseIRI = options.baseIRI;
83
84
  this._prefixIRIs = Object.create(null);
84
85
  options.prefixes && this.addPrefixes(options.prefixes);
85
86
  } else {
@@ -155,10 +156,12 @@ class N3Writer {
155
156
  // If it is a list head, pretty-print it
156
157
  if (this._lists && entity.value in this._lists) entity = this.list(this._lists[entity.value]);
157
158
  return 'id' in entity ? entity.id : `_:${entity.value}`;
158
- } // Escape special characters
159
+ }
160
+
161
+ let iri = entity.value; // Use relative IRIs if requested and possible
159
162
 
163
+ if (this._baseIRI && iri.startsWith(this._baseIRI)) iri = iri.substr(this._baseIRI.length); // Escape special characters
160
164
 
161
- let iri = entity.value;
162
165
  if (escape.test(iri)) iri = iri.replace(escapeAll, characterReplacer); // Try to represent the IRI as prefixed name
163
166
 
164
167
  const prefixMatch = this._prefixRegex.exec(iri);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "n3",
3
- "version": "1.7.0",
3
+ "version": "1.10.0",
4
4
  "description": "Lightning fast, asynchronous, streaming Turtle / N3 / RDF library.",
5
5
  "author": "Ruben Verborgh <ruben.verborgh@gmail.com>",
6
6
  "keywords": [
@@ -261,10 +261,10 @@ export function termToId(term) {
261
261
  export class Quad extends Term {
262
262
  constructor(subject, predicate, object, graph) {
263
263
  super('');
264
- this.subject = subject;
265
- this.predicate = predicate;
266
- this.object = object;
267
- this.graph = graph || DEFAULTGRAPH;
264
+ this._subject = subject;
265
+ this._predicate = predicate;
266
+ this._object = object;
267
+ this._graph = graph || DEFAULTGRAPH;
268
268
  }
269
269
 
270
270
  // ### The term type of this term
@@ -272,23 +272,39 @@ export class Quad extends Term {
272
272
  return 'Quad';
273
273
  }
274
274
 
275
+ get subject() {
276
+ return this._subject;
277
+ }
278
+
279
+ get predicate() {
280
+ return this._predicate;
281
+ }
282
+
283
+ get object() {
284
+ return this._object;
285
+ }
286
+
287
+ get graph() {
288
+ return this._graph;
289
+ }
290
+
275
291
  // ### Returns a plain object representation of this quad
276
292
  toJSON() {
277
293
  return {
278
294
  termType: this.termType,
279
- subject: this.subject.toJSON(),
280
- predicate: this.predicate.toJSON(),
281
- object: this.object.toJSON(),
282
- graph: this.graph.toJSON(),
295
+ subject: this._subject.toJSON(),
296
+ predicate: this._predicate.toJSON(),
297
+ object: this._object.toJSON(),
298
+ graph: this._graph.toJSON(),
283
299
  };
284
300
  }
285
301
 
286
302
  // ### Returns whether this object represents the same quad as the other
287
303
  equals(other) {
288
- return !!other && this.subject.equals(other.subject) &&
289
- this.predicate.equals(other.predicate) &&
290
- this.object.equals(other.object) &&
291
- this.graph.equals(other.graph);
304
+ return !!other && this._subject.equals(other.subject) &&
305
+ this._predicate.equals(other.predicate) &&
306
+ this._object.equals(other.object) &&
307
+ this._graph.equals(other.graph);
292
308
  }
293
309
  }
294
310
  export { Quad as Triple };
package/src/N3Store.js CHANGED
@@ -211,6 +211,14 @@ export default class N3Store {
211
211
 
212
212
  // ## Public methods
213
213
 
214
+ // ### `add` adds the specified quad to the dataset.
215
+ // Returns the dataset instance it was called on.
216
+ // Existing quads, as defined in Quad.equals, will be ignored.
217
+ add(quad) {
218
+ this.addQuad(quad);
219
+ return this;
220
+ }
221
+
214
222
  // ### `addQuad` adds a new quad to the store.
215
223
  // Returns if the quad index has changed, if the quad did not already exist.
216
224
  addQuad(subject, predicate, object, graph) {
@@ -259,6 +267,20 @@ export default class N3Store {
259
267
  this.addQuad(quads[i]);
260
268
  }
261
269
 
270
+ // ### `delete` removes the specified quad from the dataset.
271
+ // Returns the dataset instance it was called on.
272
+ delete(quad) {
273
+ this.removeQuad(quad);
274
+ return this;
275
+ }
276
+
277
+ // ### `has` determines whether a dataset includes a certain quad.
278
+ // Returns true or false as appropriate.
279
+ has(quad) {
280
+ const quads = this.getQuads(quad.subject, quad.predicate, quad.object, quad.graph);
281
+ return quads.length !== 0;
282
+ }
283
+
262
284
  // ### `import` adds a stream of quads to the store
263
285
  import(stream) {
264
286
  stream.on('data', quad => { this.addQuad(quad); });
@@ -316,7 +338,15 @@ export default class N3Store {
316
338
  // ### `removeMatches` removes all matching quads from the store
317
339
  // Setting any field to `undefined` or `null` indicates a wildcard.
318
340
  removeMatches(subject, predicate, object, graph) {
319
- return this.remove(this.match(subject, predicate, object, graph));
341
+ const stream = new Readable({ objectMode: true });
342
+
343
+ stream._read = () => {
344
+ for (const quad of this.getQuads(subject, predicate, object, graph))
345
+ stream.push(quad);
346
+ stream.push(null);
347
+ };
348
+
349
+ return this.remove(stream);
320
350
  }
321
351
 
322
352
  // ### `deleteGraph` removes all triples with the given graph from the store
@@ -373,19 +403,14 @@ export default class N3Store {
373
403
  return quads;
374
404
  }
375
405
 
376
- // ### `match` returns a stream of quads matching a pattern.
406
+ // ### `match` returns a new dataset that is comprised of all quads in the current instance matching the given arguments.
407
+ // The logic described in Quad Matching is applied for each quad in this dataset to check if it should be included in the output dataset.
408
+ // Note: This method always returns a new DatasetCore, even if that dataset contains no quads.
409
+ // Note: Since a DatasetCore is an unordered set, the order of the quads within the returned sequence is arbitrary.
377
410
  // Setting any field to `undefined` or `null` indicates a wildcard.
411
+ // For backwards compatibility, the object return also implements the Readable stream interface.
378
412
  match(subject, predicate, object, graph) {
379
- const stream = new Readable({ objectMode: true });
380
-
381
- // Initialize stream once it is being read
382
- stream._read = () => {
383
- for (const quad of this.getQuads(subject, predicate, object, graph))
384
- stream.push(quad);
385
- stream.push(null);
386
- };
387
-
388
- return stream;
413
+ return new DatasetCoreAndReadableStream(this, subject, predicate, object, graph);
389
414
  }
390
415
 
391
416
  // ### `countQuads` returns the number of quads matching a pattern.
@@ -790,9 +815,61 @@ export default class N3Store {
790
815
  this.removeQuads(toRemove);
791
816
  return lists;
792
817
  }
818
+
819
+ // ### Store is an iterable.
820
+ // Can be used where iterables are expected: for...of loops, array spread operator,
821
+ // `yield*`, and destructuring assignment (order is not guaranteed).
822
+ *[Symbol.iterator]() {
823
+ yield* this.getQuads();
824
+ }
793
825
  }
794
826
 
795
827
  // Determines whether the argument is a string
796
828
  function isString(s) {
797
829
  return typeof s === 'string' || s instanceof String;
798
830
  }
831
+
832
+ /**
833
+ * A class that implements both DatasetCore and Readable.
834
+ */
835
+ class DatasetCoreAndReadableStream extends Readable {
836
+ constructor(n3Store, subject, predicate, object, graph) {
837
+ super({ objectMode: true });
838
+ Object.assign(this, { n3Store, subject, predicate, object, graph });
839
+ }
840
+
841
+ get filtered() {
842
+ if (!this._filtered) {
843
+ const { n3Store, graph, object, predicate, subject } = this;
844
+ const quads = n3Store.getQuads(subject, predicate, object, graph);
845
+ this._filtered = new N3Store(quads, { factory: n3Store._factory });
846
+ }
847
+ return this._filtered;
848
+ }
849
+
850
+ _read() {
851
+ for (const quad of this.filtered.getQuads())
852
+ this.push(quad);
853
+ this.push(null);
854
+ }
855
+
856
+ add(quad) {
857
+ return this.filtered.add(quad);
858
+ }
859
+
860
+ delete(quad) {
861
+ return this.filtered.delete(quad);
862
+ }
863
+
864
+ has(quad) {
865
+ return this.filtered.has(quad);
866
+ }
867
+
868
+ match(subject, predicate, object, graph) {
869
+ return new DatasetCoreAndReadableStream(this.filtered, subject, predicate, object, graph);
870
+ }
871
+
872
+ *[Symbol.iterator]() {
873
+ yield* this.filtered.getQuads();
874
+ }
875
+ }
@@ -5,8 +5,7 @@ import N3Writer from './N3Writer';
5
5
  // ## Constructor
6
6
  export default class N3StreamWriter extends Transform {
7
7
  constructor(options) {
8
- super({ encoding: 'utf8' });
9
- this._writableState.objectMode = true;
8
+ super({ encoding: 'utf8', writableObjectMode: true });
10
9
 
11
10
  // Set up writer with a dummy stream object
12
11
  const writer = this._writer = new N3Writer({
package/src/N3Writer.js CHANGED
@@ -55,6 +55,7 @@ export default class N3Writer {
55
55
  if (!(/triple|quad/i).test(options.format)) {
56
56
  this._lineMode = false;
57
57
  this._graph = DEFAULTGRAPH;
58
+ this._baseIRI = options.baseIRI;
58
59
  this._prefixIRIs = Object.create(null);
59
60
  options.prefixes && this.addPrefixes(options.prefixes);
60
61
  }
@@ -145,8 +146,11 @@ export default class N3Writer {
145
146
  entity = this.list(this._lists[entity.value]);
146
147
  return 'id' in entity ? entity.id : `_:${entity.value}`;
147
148
  }
148
- // Escape special characters
149
149
  let iri = entity.value;
150
+ // Use relative IRIs if requested and possible
151
+ if (this._baseIRI && iri.startsWith(this._baseIRI))
152
+ iri = iri.substr(this._baseIRI.length);
153
+ // Escape special characters
150
154
  if (escape.test(iri))
151
155
  iri = iri.replace(escapeAll, characterReplacer);
152
156
  // Try to represent the IRI as prefixed name