n3 2.7.4 → 2.7.6

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/N3Lexer.js CHANGED
@@ -464,6 +464,7 @@ class N3Lexer {
464
464
  // ### `_unescape` replaces N3 escape codes by their corresponding characters,
465
465
  // allowing only the fixed escape sequences from the given replacement table
466
466
  _unescape(item, replacements) {
467
+ if (item.indexOf('\\') < 0) return item;
467
468
  let invalid = false;
468
469
  const replaced = item.replace(escapeSequence, (sequence, unicode4, unicode8, escapedChar) => {
469
470
  // 4-digit unicode character
@@ -555,13 +556,18 @@ class N3Lexer {
555
556
  // ### `tokenize` starts the transformation of an N3 document into an array of tokens.
556
557
  // The input can be a string or a stream.
557
558
  tokenize(input, callback) {
559
+ // Deferred tokenization and stream events can outlive their invocation.
560
+ // Ignore them once a later call takes ownership of the lexer state.
561
+ const tokenization = this._tokenization = {};
558
562
  this._line = 1;
559
563
 
560
564
  // If the input is a string, continuously emit tokens through the callback until the end
561
565
  if (typeof input === 'string') {
562
566
  this._input = this._readStartingBom(input);
563
567
  // If a callback was passed, asynchronously call it
564
- if (typeof callback === 'function') queueMicrotask(() => this._tokenizeToEnd(callback, true));
568
+ if (typeof callback === 'function') queueMicrotask(() => {
569
+ if (this._tokenization === tokenization) this._tokenizeToEnd(callback, true);
570
+ });
565
571
  // If no callback was passed, tokenize synchronously and return
566
572
  else {
567
573
  const tokens = [];
@@ -577,7 +583,7 @@ class N3Lexer {
577
583
  if (typeof input.setEncoding === 'function') input.setEncoding('utf8');
578
584
  // Adds the data chunk to the buffer and parses as far as possible
579
585
  input.on('data', data => {
580
- if (this._input !== null && data.length !== 0) {
586
+ if (this._tokenization === tokenization && this._input !== null && data.length !== 0) {
581
587
  // Prepend any previous pending writes
582
588
  if (this._pendingBuffer) {
583
589
  data = _buffer.Buffer.concat([this._pendingBuffer, data]);
@@ -597,9 +603,11 @@ class N3Lexer {
597
603
  });
598
604
  // Parses until the end
599
605
  input.on('end', () => {
600
- if (typeof this._input === 'string') this._tokenizeToEnd(callback, true);
606
+ if (this._tokenization === tokenization && typeof this._input === 'string') this._tokenizeToEnd(callback, true);
607
+ });
608
+ input.on('error', error => {
609
+ if (this._tokenization === tokenization) callback(error);
601
610
  });
602
- input.on('error', callback);
603
611
  }
604
612
  }
605
613
  }
@@ -59,15 +59,17 @@ class N3StreamParser extends _readableStream.Transform {
59
59
 
60
60
  // ### Parses a stream of strings
61
61
  import(stream) {
62
- stream.on('data', chunk => {
63
- this.write(chunk);
64
- });
65
- stream.on('end', () => {
66
- this.end();
67
- });
68
62
  stream.on('error', error => {
69
63
  this.emit('error', error);
70
64
  });
65
+ if (typeof stream.pipe === 'function') stream.pipe(this);else {
66
+ stream.on('data', chunk => {
67
+ this.write(chunk);
68
+ });
69
+ stream.on('end', () => {
70
+ this.end();
71
+ });
72
+ }
71
73
  return this;
72
74
  }
73
75
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "n3",
3
- "version": "2.7.4",
3
+ "version": "2.7.6",
4
4
  "description": "Lightning fast, asynchronous, streaming Turtle / N3 / RDF library.",
5
5
  "author": "Ruben Verborgh <ruben.verborgh@gmail.com>",
6
6
  "keywords": [
package/src/N3Lexer.js CHANGED
@@ -485,6 +485,8 @@ export default class N3Lexer {
485
485
  // ### `_unescape` replaces N3 escape codes by their corresponding characters,
486
486
  // allowing only the fixed escape sequences from the given replacement table
487
487
  _unescape(item, replacements) {
488
+ if (item.indexOf('\\') < 0)
489
+ return item;
488
490
  let invalid = false;
489
491
  const replaced = item.replace(escapeSequence, (sequence, unicode4, unicode8, escapedChar) => {
490
492
  // 4-digit unicode character
@@ -575,6 +577,9 @@ export default class N3Lexer {
575
577
  // ### `tokenize` starts the transformation of an N3 document into an array of tokens.
576
578
  // The input can be a string or a stream.
577
579
  tokenize(input, callback) {
580
+ // Deferred tokenization and stream events can outlive their invocation.
581
+ // Ignore them once a later call takes ownership of the lexer state.
582
+ const tokenization = this._tokenization = {};
578
583
  this._line = 1;
579
584
 
580
585
  // If the input is a string, continuously emit tokens through the callback until the end
@@ -582,7 +587,10 @@ export default class N3Lexer {
582
587
  this._input = this._readStartingBom(input);
583
588
  // If a callback was passed, asynchronously call it
584
589
  if (typeof callback === 'function')
585
- queueMicrotask(() => this._tokenizeToEnd(callback, true));
590
+ queueMicrotask(() => {
591
+ if (this._tokenization === tokenization)
592
+ this._tokenizeToEnd(callback, true);
593
+ });
586
594
  // If no callback was passed, tokenize synchronously and return
587
595
  else {
588
596
  const tokens = [];
@@ -599,7 +607,7 @@ export default class N3Lexer {
599
607
  input.setEncoding('utf8');
600
608
  // Adds the data chunk to the buffer and parses as far as possible
601
609
  input.on('data', data => {
602
- if (this._input !== null && data.length !== 0) {
610
+ if (this._tokenization === tokenization && this._input !== null && data.length !== 0) {
603
611
  // Prepend any previous pending writes
604
612
  if (this._pendingBuffer) {
605
613
  data = Buffer.concat([this._pendingBuffer, data]);
@@ -622,10 +630,13 @@ export default class N3Lexer {
622
630
  });
623
631
  // Parses until the end
624
632
  input.on('end', () => {
625
- if (typeof this._input === 'string')
633
+ if (this._tokenization === tokenization && typeof this._input === 'string')
626
634
  this._tokenizeToEnd(callback, true);
627
635
  });
628
- input.on('error', callback);
636
+ input.on('error', error => {
637
+ if (this._tokenization === tokenization)
638
+ callback(error);
639
+ });
629
640
  }
630
641
  }
631
642
  }
@@ -38,9 +38,13 @@ export default class N3StreamParser extends Transform {
38
38
 
39
39
  // ### Parses a stream of strings
40
40
  import(stream) {
41
- stream.on('data', chunk => { this.write(chunk); });
42
- stream.on('end', () => { this.end(); });
43
41
  stream.on('error', error => { this.emit('error', error); });
42
+ if (typeof stream.pipe === 'function')
43
+ stream.pipe(this);
44
+ else {
45
+ stream.on('data', chunk => { this.write(chunk); });
46
+ stream.on('end', () => { this.end(); });
47
+ }
44
48
  return this;
45
49
  }
46
50
  }